summaryrefslogtreecommitdiffstats
path: root/Python/Python-ast.c
blob: 84bce59e271471bc2774d1feaa7930508f91bcb2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
7244
7245
7246
7247
7248
7249
7250
7251
7252
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
7388
7389
7390
7391
7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
7599
7600
7601
7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
7612
7613
7614
7615
7616
7617
7618
7619
7620
7621
7622
7623
7624
7625
7626
7627
7628
7629
7630
7631
7632
7633
7634
7635
7636
7637
7638
7639
7640
7641
7642
7643
7644
7645
7646
7647
7648
7649
7650
7651
7652
7653
7654
7655
7656
7657
7658
7659
7660
7661
7662
7663
7664
7665
7666
7667
7668
7669
7670
7671
7672
7673
7674
7675
7676
7677
7678
7679
7680
7681
7682
7683
7684
7685
7686
7687
7688
7689
7690
7691
7692
7693
7694
7695
7696
7697
7698
7699
7700
7701
7702
7703
7704
7705
7706
7707
7708
7709
7710
7711
7712
7713
7714
7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735
7736
7737
7738
7739
7740
7741
7742
7743
7744
7745
7746
7747
7748
7749
7750
7751
7752
7753
7754
7755
7756
7757
7758
7759
7760
7761
7762
7763
7764
7765
7766
7767
7768
7769
7770
7771
7772
7773
7774
7775
7776
7777
7778
7779
7780
7781
7782
7783
7784
7785
7786
7787
7788
7789
7790
7791
7792
7793
7794
7795
7796
7797
7798
7799
7800
7801
7802
7803
7804
7805
7806
7807
7808
7809
7810
7811
7812
7813
7814
7815
7816
7817
7818
7819
7820
7821
7822
7823
7824
7825
7826
7827
7828
7829
7830
7831
7832
7833
7834
7835
7836
7837
7838
7839
7840
7841
7842
7843
7844
7845
7846
7847
7848
7849
7850
7851
7852
7853
7854
7855
7856
7857
7858
7859
7860
7861
7862
7863
7864
7865
7866
7867
7868
7869
7870
7871
7872
7873
7874
7875
7876
7877
7878
7879
7880
7881
7882
7883
7884
7885
7886
7887
7888
7889
7890
7891
7892
7893
7894
7895
7896
7897
7898
7899
7900
7901
7902
7903
7904
7905
7906
7907
7908
7909
7910
7911
7912
7913
7914
7915
7916
7917
7918
7919
7920
7921
7922
7923
7924
7925
7926
7927
7928
7929
7930
7931
7932
7933
7934
7935
7936
7937
7938
7939
7940
7941
7942
7943
7944
7945
7946
7947
7948
7949
7950
7951
7952
7953
7954
7955
7956
7957
7958
7959
7960
7961
7962
7963
7964
7965
7966
7967
7968
7969
7970
7971
7972
7973
7974
7975
7976
7977
7978
7979
7980
7981
7982
7983
7984
7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
7995
7996
7997
7998
7999
8000
8001
8002
8003
8004
8005
8006
8007
8008
8009
8010
8011
8012
8013
8014
8015
8016
8017
8018
8019
8020
8021
8022
8023
8024
8025
8026
8027
8028
8029
8030
8031
8032
8033
8034
8035
8036
8037
8038
8039
8040
8041
8042
8043
8044
8045
8046
8047
8048
8049
8050
8051
8052
8053
8054
8055
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065
8066
8067
8068
8069
8070
8071
8072
8073
8074
8075
8076
8077
8078
8079
8080
8081
8082
8083
8084
8085
8086
8087
8088
8089
8090
8091
8092
8093
8094
8095
8096
8097
8098
8099
8100
8101
8102
8103
8104
8105
8106
8107
8108
8109
8110
8111
8112
8113
8114
8115
8116
8117
8118
8119
8120
8121
8122
8123
8124
8125
8126
8127
8128
8129
8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140
8141
8142
8143
8144
8145
8146
8147
8148
8149
8150
8151
8152
8153
8154
8155
8156
8157
8158
8159
8160
8161
8162
8163
8164
8165
8166
8167
8168
8169
8170
8171
8172
8173
8174
8175
8176
8177
8178
8179
8180
8181
8182
8183
8184
8185
8186
8187
8188
8189
8190
8191
8192
8193
8194
8195
8196
8197
8198
8199
8200
8201
8202
8203
8204
8205
8206
8207
8208
8209
8210
8211
8212
8213
8214
8215
8216
8217
8218
8219
8220
8221
8222
8223
8224
8225
8226
8227
8228
8229
8230
8231
8232
8233
8234
8235
8236
8237
8238
8239
8240
8241
8242
8243
8244
8245
8246
8247
8248
8249
8250
8251
8252
8253
8254
8255
8256
8257
8258
8259
8260
8261
8262
8263
8264
8265
8266
8267
8268
8269
8270
8271
8272
8273
8274
8275
8276
8277
8278
8279
8280
8281
8282
8283
8284
8285
8286
8287
8288
8289
8290
8291
8292
8293
8294
8295
8296
8297
8298
8299
8300
8301
8302
8303
8304
8305
8306
8307
8308
8309
8310
8311
8312
8313
8314
8315
8316
8317
8318
8319
8320
8321
8322
8323
8324
8325
8326
8327
8328
8329
8330
8331
8332
8333
8334
8335
8336
8337
8338
8339
8340
8341
8342
8343
8344
8345
8346
8347
8348
8349
8350
8351
8352
8353
8354
8355
8356
8357
8358
8359
8360
8361
8362
8363
8364
8365
8366
8367
8368
8369
8370
8371
8372
8373
8374
8375
8376
8377
8378
8379
8380
8381
8382
8383
8384
8385
8386
8387
8388
8389
8390
8391
8392
8393
8394
8395
8396
8397
8398
8399
8400
8401
8402
8403
8404
8405
8406
8407
8408
8409
8410
8411
8412
8413
8414
8415
8416
8417
8418
8419
8420
8421
8422
8423
8424
8425
8426
8427
8428
8429
8430
8431
8432
8433
8434
8435
8436
8437
8438
8439
8440
8441
8442
8443
8444
8445
8446
8447
8448
8449
8450
8451
8452
8453
8454
8455
8456
8457
8458
8459
8460
8461
8462
8463
8464
8465
8466
8467
8468
8469
8470
8471
8472
8473
8474
8475
8476
8477
8478
8479
8480
8481
8482
8483
8484
8485
8486
8487
8488
8489
8490
8491
8492
8493
8494
8495
8496
8497
8498
8499
8500
8501
8502
8503
8504
8505
8506
8507
8508
8509
8510
8511
8512
8513
8514
8515
8516
8517
8518
8519
8520
8521
8522
8523
8524
8525
8526
8527
8528
8529
8530
8531
8532
8533
8534
8535
8536
8537
8538
8539
8540
8541
8542
8543
8544
8545
8546
8547
8548
8549
8550
8551
8552
8553
8554
8555
8556
8557
8558
8559
8560
8561
8562
8563
8564
8565
8566
8567
8568
8569
8570
8571
8572
8573
8574
8575
8576
8577
8578
8579
8580
8581
8582
8583
8584
8585
8586
8587
8588
8589
8590
8591
8592
8593
8594
8595
8596
8597
8598
8599
8600
8601
8602
8603
8604
8605
8606
8607
8608
8609
8610
8611
8612
8613
8614
8615
8616
8617
8618
8619
8620
8621
8622
8623
8624
8625
8626
8627
8628
8629
8630
8631
8632
8633
8634
8635
8636
8637
8638
8639
8640
8641
8642
8643
8644
8645
8646
8647
8648
8649
8650
8651
8652
8653
8654
8655
8656
8657
8658
8659
8660
8661
8662
8663
8664
8665
8666
8667
8668
8669
8670
8671
8672
8673
8674
8675
8676
8677
8678
8679
8680
8681
8682
8683
8684
8685
8686
8687
8688
8689
8690
8691
8692
8693
8694
8695
8696
8697
8698
8699
8700
8701
8702
8703
8704
8705
8706
8707
8708
8709
8710
8711
8712
8713
8714
8715
8716
8717
8718
8719
8720
8721
8722
8723
8724
8725
8726
8727
8728
8729
8730
8731
8732
8733
8734
8735
8736
8737
8738
8739
8740
8741
8742
8743
8744
8745
8746
8747
8748
8749
8750
8751
8752
8753
8754
8755
8756
8757
8758
8759
8760
8761
8762
8763
8764
8765
8766
8767
8768
8769
8770
8771
8772
8773
8774
8775
8776
8777
8778
8779
8780
8781
8782
8783
8784
8785
8786
8787
8788
8789
8790
8791
8792
8793
8794
8795
8796
8797
8798
8799
8800
8801
8802
8803
8804
8805
8806
8807
8808
8809
8810
8811
8812
8813
8814
8815
8816
8817
8818
8819
8820
8821
8822
8823
8824
8825
8826
8827
8828
8829
8830
8831
8832
8833
8834
8835
8836
8837
8838
8839
8840
8841
8842
8843
8844
8845
8846
8847
8848
8849
8850
8851
8852
8853
8854
8855
8856
8857
8858
8859
8860
8861
8862
8863
8864
8865
8866
8867
8868
8869
8870
8871
8872
8873
8874
8875
8876
8877
8878
8879
8880
8881
8882
8883
8884
8885
8886
8887
8888
8889
8890
8891
8892
8893
8894
8895
8896
8897
8898
8899
8900
8901
8902
8903
8904
8905
8906
8907
8908
8909
8910
8911
8912
8913
8914
8915
8916
8917
8918
8919
8920
8921
8922
8923
8924
8925
8926
8927
8928
8929
8930
8931
8932
8933
8934
8935
8936
8937
8938
8939
8940
8941
8942
8943
8944
8945
8946
8947
8948
8949
8950
8951
8952
8953
8954
8955
8956
8957
8958
8959
8960
8961
8962
8963
8964
8965
8966
8967
8968
8969
8970
8971
8972
8973
8974
8975
8976
8977
8978
8979
8980
8981
8982
8983
8984
8985
8986
8987
8988
8989
8990
8991
8992
8993
8994
8995
8996
8997
8998
8999
9000
9001
9002
9003
9004
9005
9006
9007
9008
9009
9010
9011
9012
9013
9014
9015
9016
9017
9018
9019
9020
9021
9022
9023
9024
9025
9026
9027
9028
9029
9030
9031
9032
9033
9034
9035
9036
9037
9038
9039
9040
9041
9042
9043
9044
9045
9046
9047
9048
9049
9050
9051
9052
9053
9054
9055
9056
9057
9058
9059
9060
9061
9062
9063
9064
9065
9066
9067
9068
9069
9070
9071
9072
9073
9074
9075
9076
9077
9078
9079
9080
9081
9082
9083
9084
9085
9086
9087
9088
9089
9090
9091
9092
9093
9094
9095
9096
9097
9098
9099
9100
9101
9102
9103
9104
9105
9106
9107
9108
9109
9110
9111
9112
9113
9114
9115
9116
9117
9118
9119
9120
9121
9122
9123
9124
9125
9126
9127
9128
9129
9130
9131
9132
9133
9134
9135
9136
9137
9138
9139
9140
9141
9142
9143
9144
9145
9146
9147
9148
9149
9150
9151
9152
9153
9154
9155
9156
9157
9158
9159
9160
9161
9162
9163
9164
9165
9166
9167
9168
9169
9170
9171
9172
9173
9174
9175
9176
9177
9178
9179
9180
9181
9182
9183
9184
9185
9186
9187
9188
9189
9190
9191
9192
9193
9194
9195
9196
9197
9198
9199
9200
9201
9202
9203
9204
9205
9206
9207
9208
9209
9210
9211
9212
9213
9214
9215
9216
9217
9218
9219
9220
9221
9222
9223
9224
9225
9226
9227
9228
9229
9230
9231
9232
9233
9234
9235
9236
9237
9238
9239
9240
9241
9242
9243
9244
9245
9246
9247
9248
9249
9250
9251
9252
9253
9254
9255
9256
9257
9258
9259
9260
9261
9262
9263
9264
9265
9266
9267
9268
9269
9270
9271
9272
9273
9274
9275
9276
9277
9278
9279
9280
9281
9282
9283
9284
9285
9286
9287
9288
9289
9290
9291
9292
9293
9294
9295
9296
9297
9298
9299
9300
9301
9302
9303
9304
9305
9306
9307
9308
9309
9310
9311
9312
9313
9314
9315
9316
9317
9318
9319
9320
9321
9322
9323
9324
9325
9326
9327
9328
9329
9330
9331
9332
9333
9334
9335
9336
9337
9338
9339
9340
9341
9342
9343
9344
9345
9346
9347
9348
9349
9350
9351
9352
9353
9354
9355
9356
9357
9358
9359
9360
9361
9362
9363
9364
9365
9366
9367
9368
9369
9370
9371
9372
9373
9374
9375
9376
9377
9378
9379
9380
9381
9382
9383
9384
9385
9386
9387
9388
9389
9390
9391
9392
9393
9394
9395
9396
9397
9398
9399
9400
9401
9402
9403
9404
9405
9406
9407
9408
9409
9410
9411
9412
9413
9414
9415
9416
9417
9418
9419
9420
9421
9422
9423
9424
9425
9426
9427
9428
9429
9430
9431
9432
9433
9434
9435
9436
9437
9438
9439
9440
9441
9442
9443
9444
9445
9446
9447
9448
9449
9450
9451
9452
9453
9454
9455
9456
9457
9458
9459
9460
9461
9462
9463
9464
9465
9466
9467
9468
9469
9470
9471
9472
9473
9474
9475
9476
9477
9478
9479
9480
9481
9482
9483
9484
9485
9486
9487
9488
9489
9490
9491
9492
9493
9494
9495
9496
9497
9498
9499
9500
9501
9502
9503
9504
9505
9506
9507
9508
9509
9510
9511
9512
9513
9514
9515
9516
9517
9518
9519
9520
9521
9522
9523
9524
9525
9526
9527
9528
9529
9530
9531
9532
9533
9534
9535
9536
9537
9538
9539
9540
9541
9542
9543
9544
9545
9546
9547
9548
9549
9550
9551
9552
9553
9554
9555
9556
9557
9558
9559
9560
9561
9562
9563
9564
9565
9566
9567
9568
9569
9570
9571
9572
9573
9574
9575
9576
9577
9578
9579
9580
9581
9582
9583
9584
9585
9586
9587
9588
9589
9590
9591
9592
9593
9594
9595
9596
9597
9598
9599
9600
9601
9602
9603
9604
9605
9606
9607
9608
9609
9610
9611
9612
9613
9614
9615
9616
9617
9618
9619
9620
9621
9622
9623
9624
9625
9626
9627
9628
9629
9630
9631
9632
9633
9634
9635
9636
9637
9638
9639
9640
9641
9642
9643
9644
9645
9646
9647
9648
9649
9650
9651
9652
9653
9654
9655
9656
9657
9658
9659
9660
9661
9662
9663
9664
9665
9666
9667
9668
9669
9670
9671
9672
9673
9674
9675
9676
9677
9678
9679
9680
9681
9682
9683
9684
9685
9686
9687
9688
9689
9690
9691
9692
9693
9694
9695
9696
9697
9698
9699
9700
9701
9702
9703
9704
9705
9706
9707
9708
9709
9710
9711
9712
9713
9714
9715
9716
9717
9718
9719
9720
9721
9722
9723
9724
9725
9726
9727
9728
9729
9730
9731
9732
9733
9734
9735
9736
9737
9738
9739
9740
9741
9742
9743
9744
9745
9746
9747
9748
9749
9750
9751
9752
9753
9754
9755
9756
9757
9758
9759
9760
9761
9762
9763
9764
9765
9766
9767
9768
9769
9770
9771
9772
9773
9774
9775
9776
9777
9778
9779
9780
9781
9782
9783
9784
9785
9786
9787
9788
9789
9790
9791
9792
9793
9794
9795
9796
9797
9798
9799
9800
9801
9802
9803
9804
9805
9806
9807
9808
9809
9810
9811
9812
9813
9814
9815
9816
9817
9818
9819
9820
9821
9822
9823
9824
9825
9826
9827
9828
9829
9830
9831
9832
9833
9834
9835
9836
9837
9838
9839
9840
9841
9842
9843
9844
9845
9846
9847
9848
9849
9850
9851
9852
9853
9854
9855
9856
9857
9858
9859
9860
9861
9862
9863
9864
9865
9866
9867
9868
9869
9870
9871
9872
9873
9874
9875
9876
9877
9878
9879
9880
9881
9882
9883
9884
9885
9886
9887
9888
9889
9890
9891
9892
9893
9894
9895
9896
9897
9898
9899
9900
9901
9902
9903
9904
9905
9906
9907
9908
9909
9910
9911
9912
9913
9914
9915
9916
9917
9918
9919
9920
9921
9922
9923
9924
9925
9926
9927
9928
9929
9930
9931
9932
9933
9934
9935
9936
9937
9938
9939
9940
9941
9942
9943
9944
9945
9946
9947
9948
9949
9950
9951
9952
9953
9954
9955
9956
9957
9958
9959
9960
9961
9962
9963
9964
9965
9966
9967
9968
9969
9970
9971
9972
9973
9974
9975
9976
9977
9978
9979
9980
9981
9982
9983
9984
9985
9986
9987
9988
9989
9990
9991
9992
9993
9994
9995
9996
9997
9998
9999
10000
10001
10002
10003
10004
10005
10006
10007
10008
10009
10010
10011
10012
10013
10014
10015
10016
10017
10018
10019
10020
10021
10022
10023
10024
10025
10026
10027
10028
10029
10030
10031
10032
10033
10034
10035
10036
10037
10038
10039
10040
10041
10042
10043
10044
10045
10046
10047
10048
10049
10050
10051
10052
10053
10054
10055
10056
10057
10058
10059
10060
10061
10062
10063
10064
10065
10066
10067
10068
10069
10070
10071
10072
10073
10074
10075
10076
10077
10078
10079
10080
10081
10082
10083
10084
10085
10086
10087
10088
10089
10090
10091
10092
10093
10094
10095
10096
10097
10098
10099
10100
10101
10102
10103
10104
10105
10106
10107
10108
10109
10110
10111
10112
10113
10114
10115
10116
10117
10118
10119
10120
10121
10122
10123
10124
10125
10126
10127
10128
10129
10130
10131
10132
10133
10134
10135
10136
10137
10138
10139
10140
10141
10142
10143
10144
10145
10146
10147
10148
10149
10150
10151
10152
10153
10154
10155
10156
10157
10158
10159
10160
10161
10162
10163
10164
10165
10166
10167
10168
10169
10170
10171
10172
10173
10174
10175
10176
10177
10178
10179
10180
10181
10182
10183
10184
10185
10186
10187
10188
10189
10190
10191
10192
10193
10194
10195
10196
10197
10198
10199
10200
10201
10202
10203
10204
10205
10206
10207
10208
10209
10210
10211
10212
10213
10214
10215
10216
10217
10218
10219
10220
10221
10222
10223
10224
10225
10226
10227
10228
10229
10230
10231
10232
10233
10234
10235
10236
10237
10238
10239
10240
10241
10242
10243
10244
10245
10246
10247
10248
10249
10250
10251
10252
10253
10254
10255
10256
10257
10258
10259
10260
10261
10262
10263
10264
10265
10266
10267
10268
10269
10270
10271
10272
10273
10274
10275
10276
10277
10278
10279
10280
10281
10282
10283
10284
10285
10286
10287
10288
10289
10290
10291
10292
10293
10294
10295
10296
10297
10298
10299
10300
10301
10302
10303
10304
10305
10306
10307
10308
10309
10310
10311
10312
10313
10314
10315
10316
10317
10318
10319
10320
10321
10322
10323
10324
10325
10326
10327
10328
10329
10330
10331
10332
10333
10334
10335
10336
10337
10338
10339
10340
10341
10342
10343
10344
10345
10346
10347
10348
10349
10350
10351
10352
10353
10354
10355
10356
10357
10358
10359
10360
10361
10362
10363
10364
10365
10366
10367
10368
10369
10370
10371
10372
10373
10374
10375
10376
10377
10378
10379
10380
10381
10382
10383
10384
10385
10386
10387
10388
10389
10390
10391
10392
10393
10394
10395
10396
10397
10398
10399
10400
10401
10402
10403
10404
10405
10406
10407
10408
10409
10410
10411
10412
10413
10414
10415
10416
10417
10418
10419
10420
10421
10422
10423
10424
10425
10426
10427
10428
10429
10430
10431
10432
10433
10434
10435
10436
10437
10438
10439
10440
10441
10442
10443
10444
10445
10446
10447
10448
10449
10450
10451
10452
10453
10454
10455
10456
10457
10458
10459
10460
10461
10462
10463
10464
10465
10466
10467
10468
10469
10470
10471
10472
10473
10474
10475
10476
10477
10478
10479
10480
10481
10482
10483
10484
10485
10486
10487
10488
10489
10490
10491
10492
10493
10494
10495
10496
10497
10498
10499
10500
10501
10502
10503
10504
10505
10506
10507
10508
10509
10510
10511
10512
10513
10514
10515
10516
10517
10518
10519
10520
10521
10522
10523
10524
10525
10526
10527
10528
10529
10530
10531
10532
10533
10534
10535
10536
10537
10538
10539
10540
10541
10542
10543
10544
10545
10546
10547
10548
10549
10550
10551
10552
10553
10554
10555
10556
10557
10558
10559
10560
10561
10562
10563
10564
10565
10566
10567
10568
10569
10570
10571
10572
10573
10574
10575
10576
10577
10578
10579
10580
10581
10582
10583
10584
10585
10586
10587
10588
10589
10590
10591
10592
10593
10594
10595
10596
10597
10598
10599
10600
10601
10602
10603
10604
10605
10606
10607
10608
10609
10610
10611
10612
10613
10614
10615
10616
10617
10618
10619
10620
10621
10622
10623
10624
10625
10626
10627
10628
10629
10630
10631
10632
10633
10634
10635
10636
10637
10638
10639
10640
10641
10642
10643
10644
10645
10646
10647
10648
10649
10650
10651
10652
10653
10654
10655
10656
10657
10658
10659
10660
10661
10662
10663
10664
10665
10666
10667
10668
10669
10670
10671
10672
10673
10674
10675
10676
10677
10678
10679
10680
10681
10682
10683
10684
10685
10686
10687
10688
10689
10690
10691
10692
10693
10694
10695
10696
10697
10698
10699
10700
10701
10702
10703
10704
10705
10706
10707
10708
10709
10710
10711
10712
10713
10714
10715
10716
10717
10718
10719
10720
10721
10722
10723
10724
10725
10726
10727
10728
10729
10730
10731
10732
10733
10734
10735
10736
10737
10738
10739
10740
10741
10742
10743
10744
10745
10746
10747
10748
10749
10750
10751
10752
10753
10754
10755
10756
10757
10758
10759
10760
10761
10762
10763
10764
10765
10766
10767
10768
10769
10770
10771
10772
10773
10774
10775
10776
10777
10778
10779
10780
10781
10782
10783
10784
10785
10786
10787
10788
10789
10790
10791
10792
10793
10794
10795
10796
10797
10798
10799
10800
10801
10802
10803
10804
10805
10806
10807
10808
10809
10810
10811
10812
10813
10814
10815
10816
10817
10818
10819
10820
10821
10822
10823
10824
10825
10826
10827
10828
10829
10830
10831
10832
10833
10834
10835
10836
10837
10838
10839
10840
10841
10842
10843
10844
10845
10846
10847
10848
10849
10850
10851
10852
10853
10854
10855
10856
10857
10858
10859
10860
10861
10862
10863
10864
10865
10866
10867
10868
10869
10870
10871
10872
10873
10874
10875
10876
10877
10878
10879
10880
10881
10882
10883
10884
10885
10886
10887
10888
10889
10890
10891
10892
10893
10894
10895
10896
10897
10898
10899
10900
10901
10902
10903
10904
10905
10906
10907
10908
10909
10910
10911
10912
10913
10914
10915
10916
10917
10918
10919
10920
10921
10922
10923
10924
10925
10926
10927
10928
10929
10930
10931
10932
10933
10934
10935
10936
10937
10938
10939
10940
10941
10942
10943
10944
10945
10946
10947
10948
10949
10950
10951
10952
10953
10954
10955
10956
10957
10958
10959
10960
10961
10962
10963
10964
10965
10966
10967
10968
10969
10970
10971
10972
10973
10974
10975
10976
10977
10978
10979
10980
10981
10982
10983
10984
10985
10986
10987
10988
10989
10990
10991
10992
10993
10994
10995
10996
10997
10998
10999
11000
11001
11002
11003
11004
11005
11006
11007
11008
11009
11010
11011
11012
11013
11014
11015
11016
11017
11018
11019
11020
11021
11022
11023
11024
11025
11026
11027
11028
11029
11030
11031
11032
11033
11034
11035
11036
11037
11038
11039
11040
11041
11042
11043
11044
11045
11046
11047
11048
11049
11050
11051
11052
11053
11054
11055
11056
11057
11058
11059
11060
11061
11062
11063
11064
11065
11066
11067
11068
11069
11070
11071
11072
11073
11074
11075
11076
11077
11078
11079
11080
11081
11082
11083
11084
11085
11086
11087
11088
11089
11090
11091
11092
11093
11094
11095
11096
11097
11098
11099
11100
11101
11102
11103
11104
11105
11106
11107
11108
11109
11110
11111
11112
11113
11114
11115
11116
11117
11118
11119
11120
11121
11122
11123
11124
11125
11126
11127
11128
11129
11130
11131
11132
11133
11134
11135
11136
11137
11138
11139
11140
11141
11142
11143
11144
11145
11146
11147
11148
11149
11150
11151
11152
11153
11154
11155
11156
11157
11158
11159
11160
11161
11162
11163
11164
11165
11166
11167
11168
11169
11170
11171
11172
11173
11174
11175
11176
11177
11178
11179
11180
11181
11182
11183
11184
11185
11186
11187
11188
11189
11190
11191
11192
11193
11194
11195
11196
11197
11198
11199
11200
11201
11202
11203
11204
11205
11206
11207
11208
11209
11210
11211
11212
11213
11214
11215
11216
11217
11218
11219
11220
11221
11222
11223
11224
11225
11226
11227
11228
11229
11230
11231
11232
11233
11234
11235
11236
11237
11238
11239
11240
11241
11242
11243
11244
11245
11246
11247
11248
11249
11250
11251
11252
11253
11254
11255
11256
11257
11258
11259
11260
11261
11262
11263
11264
11265
11266
11267
11268
11269
11270
11271
11272
11273
11274
11275
11276
11277
11278
11279
11280
11281
11282
11283
11284
11285
11286
11287
11288
11289
11290
11291
11292
11293
11294
11295
11296
11297
11298
11299
11300
11301
11302
11303
11304
11305
11306
11307
11308
11309
11310
11311
11312
11313
11314
11315
11316
11317
11318
11319
11320
11321
11322
11323
11324
11325
11326
11327
11328
11329
11330
11331
11332
11333
11334
11335
11336
11337
11338
11339
11340
11341
11342
11343
11344
11345
11346
11347
11348
11349
11350
11351
11352
11353
11354
11355
11356
11357
11358
11359
11360
11361
11362
11363
11364
11365
11366
11367
11368
11369
11370
11371
11372
11373
11374
11375
11376
11377
11378
11379
11380
11381
11382
11383
11384
11385
11386
11387
11388
11389
11390
11391
11392
11393
11394
11395
11396
11397
11398
11399
11400
11401
11402
11403
11404
11405
11406
11407
11408
11409
11410
11411
11412
11413
11414
11415
11416
11417
11418
11419
11420
11421
11422
11423
11424
11425
11426
11427
11428
11429
11430
11431
11432
11433
11434
11435
11436
11437
11438
11439
11440
11441
11442
11443
11444
11445
11446
11447
11448
11449
11450
11451
11452
11453
11454
11455
11456
11457
11458
11459
11460
11461
11462
11463
11464
11465
11466
11467
11468
11469
11470
11471
11472
11473
11474
11475
11476
11477
11478
11479
11480
11481
11482
11483
11484
11485
11486
11487
11488
11489
11490
11491
11492
11493
11494
11495
11496
11497
11498
11499
11500
11501
11502
11503
11504
11505
11506
11507
11508
11509
11510
11511
11512
11513
11514
11515
11516
11517
11518
11519
11520
11521
11522
11523
11524
11525
11526
11527
11528
11529
11530
11531
11532
11533
11534
11535
11536
11537
11538
11539
11540
11541
11542
11543
11544
11545
11546
11547
11548
11549
11550
11551
11552
11553
11554
11555
11556
11557
11558
11559
11560
11561
11562
11563
11564
11565
11566
11567
11568
11569
11570
11571
11572
11573
11574
11575
11576
11577
11578
11579
11580
11581
11582
11583
11584
11585
11586
11587
11588
11589
11590
11591
11592
11593
11594
11595
11596
11597
11598
11599
11600
11601
11602
11603
11604
11605
11606
11607
11608
11609
11610
11611
11612
11613
11614
11615
11616
11617
11618
11619
11620
11621
11622
11623
11624
11625
11626
11627
11628
11629
11630
11631
11632
11633
11634
11635
11636
11637
11638
11639
11640
11641
11642
11643
11644
11645
11646
11647
11648
11649
11650
11651
11652
11653
11654
11655
11656
11657
11658
11659
11660
11661
11662
11663
11664
11665
11666
11667
11668
11669
11670
11671
11672
11673
11674
11675
11676
11677
11678
11679
11680
11681
11682
11683
11684
11685
11686
11687
11688
11689
11690
11691
11692
11693
11694
11695
11696
11697
11698
11699
11700
11701
11702
11703
11704
11705
11706
11707
11708
11709
11710
11711
11712
11713
11714
11715
11716
11717
11718
11719
11720
11721
11722
11723
11724
11725
11726
11727
11728
11729
11730
11731
11732
11733
11734
11735
11736
11737
11738
11739
11740
11741
11742
11743
11744
11745
11746
11747
11748
11749
11750
11751
11752
11753
11754
11755
11756
11757
11758
11759
11760
11761
11762
11763
11764
11765
11766
11767
11768
11769
11770
11771
11772
11773
11774
11775
11776
11777
11778
11779
11780
11781
11782
11783
11784
11785
11786
11787
11788
11789
11790
11791
11792
11793
11794
11795
11796
11797
11798
11799
11800
11801
11802
11803
11804
11805
11806
11807
11808
11809
11810
11811
11812
11813
11814
11815
11816
11817
11818
11819
11820
11821
11822
11823
11824
11825
11826
11827
11828
11829
11830
11831
11832
11833
11834
11835
11836
11837
11838
11839
11840
11841
11842
11843
11844
11845
11846
11847
11848
11849
11850
11851
11852
11853
11854
11855
11856
11857
11858
11859
11860
11861
11862
11863
11864
11865
11866
11867
11868
11869
11870
11871
11872
11873
11874
11875
11876
11877
11878
11879
11880
11881
11882
11883
11884
11885
11886
11887
11888
11889
11890
11891
11892
11893
11894
11895
11896
11897
11898
11899
11900
11901
11902
11903
11904
11905
11906
11907
11908
11909
11910
11911
11912
11913
11914
11915
11916
11917
11918
11919
11920
11921
11922
11923
11924
11925
11926
11927
11928
11929
11930
11931
11932
11933
11934
11935
11936
11937
11938
11939
11940
11941
11942
11943
11944
11945
11946
11947
11948
11949
11950
11951
11952
11953
11954
11955
11956
11957
11958
11959
11960
11961
11962
11963
11964
11965
11966
11967
11968
11969
11970
11971
11972
11973
11974
11975
11976
11977
11978
11979
11980
11981
11982
11983
11984
11985
11986
11987
11988
11989
11990
11991
11992
11993
11994
11995
11996
11997
11998
11999
12000
12001
12002
12003
12004
12005
12006
12007
12008
12009
12010
12011
12012
12013
12014
12015
12016
12017
12018
12019
12020
12021
12022
12023
12024
12025
12026
12027
12028
12029
12030
12031
12032
12033
12034
12035
12036
12037
12038
12039
12040
12041
12042
12043
12044
12045
12046
12047
12048
12049
12050
12051
12052
12053
12054
12055
12056
12057
12058
12059
12060
12061
12062
12063
12064
12065
12066
12067
12068
12069
12070
12071
12072
12073
12074
12075
12076
12077
12078
12079
12080
12081
12082
12083
12084
12085
12086
12087
12088
12089
12090
12091
12092
12093
12094
12095
12096
12097
12098
12099
12100
12101
12102
12103
12104
12105
12106
12107
12108
12109
12110
12111
12112
12113
12114
12115
12116
12117
12118
12119
12120
12121
12122
12123
12124
12125
12126
12127
12128
12129
12130
12131
12132
12133
12134
12135
12136
12137
12138
12139
12140
12141
12142
12143
12144
12145
12146
12147
12148
12149
12150
12151
12152
12153
12154
12155
12156
12157
12158
12159
12160
12161
12162
12163
12164
12165
12166
12167
12168
12169
12170
12171
12172
12173
12174
12175
12176
12177
12178
12179
12180
12181
12182
12183
12184
12185
12186
12187
12188
12189
12190
12191
12192
12193
12194
12195
12196
12197
12198
12199
12200
12201
12202
12203
12204
12205
12206
12207
12208
12209
12210
12211
12212
12213
12214
12215
12216
12217
12218
12219
12220
12221
12222
12223
12224
12225
12226
12227
12228
12229
12230
12231
12232
12233
12234
12235
12236
12237
12238
12239
12240
12241
12242
12243
12244
12245
12246
12247
12248
12249
12250
12251
12252
12253
12254
12255
12256
12257
12258
12259
12260
12261
12262
12263
12264
12265
12266
12267
12268
12269
12270
12271
12272
12273
12274
12275
12276
12277
12278
12279
12280
12281
12282
12283
12284
12285
12286
12287
12288
12289
12290
12291
12292
12293
12294
12295
12296
12297
12298
12299
12300
12301
12302
12303
12304
12305
12306
12307
12308
12309
12310
12311
12312
12313
12314
12315
12316
12317
12318
12319
12320
12321
12322
12323
12324
12325
12326
12327
12328
12329
12330
12331
12332
12333
12334
12335
12336
12337
12338
12339
12340
12341
12342
12343
12344
12345
12346
12347
12348
12349
12350
12351
12352
12353
12354
12355
12356
12357
12358
12359
12360
12361
12362
12363
12364
12365
12366
12367
12368
12369
12370
12371
12372
12373
12374
12375
12376
12377
12378
12379
12380
12381
12382
12383
12384
12385
12386
12387
12388
12389
12390
12391
12392
12393
12394
12395
12396
12397
12398
12399
12400
12401
12402
12403
12404
12405
12406
12407
12408
12409
12410
12411
12412
12413
12414
12415
12416
12417
12418
12419
12420
12421
12422
12423
12424
12425
12426
12427
12428
12429
12430
12431
12432
12433
12434
12435
12436
12437
12438
12439
12440
12441
12442
12443
12444
12445
12446
12447
12448
12449
12450
12451
12452
12453
12454
12455
12456
12457
12458
12459
12460
12461
12462
12463
12464
12465
12466
12467
12468
12469
12470
12471
12472
12473
12474
12475
12476
12477
12478
12479
12480
12481
12482
12483
12484
12485
12486
12487
12488
12489
12490
12491
12492
12493
12494
12495
12496
12497
12498
12499
12500
12501
12502
12503
12504
12505
12506
12507
12508
12509
12510
12511
12512
12513
12514
12515
12516
12517
12518
12519
12520
12521
12522
12523
12524
12525
12526
12527
12528
12529
12530
12531
12532
12533
12534
12535
12536
12537
12538
12539
12540
12541
12542
12543
12544
12545
12546
12547
12548
12549
12550
12551
12552
12553
12554
12555
12556
12557
12558
12559
12560
12561
12562
12563
12564
12565
12566
12567
12568
12569
12570
12571
12572
12573
12574
12575
12576
12577
12578
12579
12580
12581
12582
12583
12584
12585
12586
12587
12588
12589
12590
12591
12592
12593
12594
12595
12596
12597
12598
12599
12600
12601
12602
12603
12604
12605
12606
12607
12608
12609
12610
12611
12612
12613
12614
12615
12616
12617
12618
12619
12620
12621
12622
12623
12624
12625
12626
12627
12628
12629
12630
12631
12632
12633
12634
12635
12636
12637
12638
12639
12640
12641
12642
12643
12644
12645
12646
12647
12648
12649
12650
12651
12652
12653
12654
12655
12656
12657
12658
12659
12660
12661
12662
12663
12664
12665
12666
12667
12668
12669
12670
12671
12672
12673
12674
12675
12676
12677
12678
12679
12680
12681
12682
12683
12684
12685
12686
12687
12688
12689
12690
12691
12692
12693
12694
12695
12696
12697
12698
12699
12700
12701
12702
12703
12704
12705
12706
12707
12708
12709
12710
12711
12712
12713
12714
12715
12716
12717
12718
12719
12720
12721
12722
12723
12724
12725
12726
12727
12728
12729
12730
12731
12732
12733
12734
12735
12736
12737
12738
12739
12740
12741
12742
12743
12744
12745
12746
12747
12748
12749
12750
12751
12752
12753
12754
12755
12756
12757
12758
12759
12760
12761
12762
12763
12764
12765
12766
12767
12768
12769
12770
12771
12772
12773
12774
12775
12776
12777
12778
12779
12780
12781
12782
12783
12784
12785
12786
12787
12788
12789
12790
12791
12792
12793
12794
12795
12796
12797
12798
12799
12800
12801
12802
12803
12804
12805
12806
12807
12808
12809
12810
12811
12812
12813
12814
12815
12816
12817
12818
12819
12820
12821
12822
12823
12824
12825
12826
12827
12828
12829
12830
12831
12832
12833
12834
12835
12836
12837
12838
12839
12840
12841
12842
12843
12844
12845
12846
12847
12848
12849
12850
12851
12852
12853
12854
12855
12856
12857
12858
12859
12860
12861
12862
12863
12864
12865
12866
12867
12868
12869
12870
12871
12872
12873
12874
12875
12876
12877
12878
12879
12880
12881
12882
12883
12884
12885
12886
12887
12888
12889
12890
12891
12892
12893
12894
12895
12896
12897
12898
12899
12900
12901
12902
12903
12904
12905
12906
12907
12908
12909
12910
12911
12912
12913
12914
12915
12916
12917
12918
12919
12920
12921
12922
12923
12924
12925
12926
12927
12928
12929
12930
12931
12932
12933
12934
12935
12936
12937
12938
12939
12940
12941
12942
12943
12944
12945
12946
12947
12948
12949
12950
12951
12952
12953
12954
12955
12956
12957
12958
12959
12960
12961
12962
12963
12964
12965
12966
12967
12968
12969
12970
12971
12972
12973
12974
12975
12976
12977
12978
12979
12980
12981
12982
12983
12984
12985
12986
12987
12988
12989
12990
12991
12992
12993
12994
12995
12996
12997
12998
12999
13000
13001
13002
13003
13004
13005
13006
13007
13008
13009
13010
13011
13012
13013
13014
13015
13016
13017
13018
13019
13020
13021
13022
13023
13024
13025
13026
13027
13028
13029
13030
13031
13032
13033
13034
13035
13036
13037
13038
13039
13040
13041
13042
13043
13044
13045
13046
13047
13048
13049
13050
13051
13052
13053
13054
13055
13056
13057
13058
13059
13060
13061
13062
13063
13064
13065
13066
13067
13068
13069
13070
13071
13072
13073
13074
13075
13076
13077
13078
13079
13080
13081
13082
13083
13084
13085
13086
13087
13088
13089
13090
13091
13092
13093
13094
13095
13096
13097
13098
13099
13100
13101
13102
13103
13104
13105
13106
13107
13108
13109
13110
13111
13112
13113
13114
13115
13116
13117
13118
13119
13120
13121
13122
13123
13124
13125
13126
13127
13128
13129
13130
13131
13132
13133
13134
13135
13136
13137
13138
13139
13140
13141
13142
13143
13144
13145
// File automatically generated by Parser/asdl_c.py.

#include "Python.h"
#include "pycore_ast.h"
#include "pycore_ast_state.h"     // struct ast_state
#include "pycore_ceval.h"         // _Py_EnterRecursiveCall
#include "pycore_interp.h"        // _PyInterpreterState.ast
#include "pycore_pystate.h"       // _PyInterpreterState_GET()
#include "structmember.h"
#include <stddef.h>

// Forward declaration
static int init_types(struct ast_state *state);

static struct ast_state*
get_ast_state(void)
{
    PyInterpreterState *interp = _PyInterpreterState_GET();
    struct ast_state *state = &interp->ast;
    if (!init_types(state)) {
        return NULL;
    }
    return state;
}

void _PyAST_Fini(PyInterpreterState *interp)
{
    struct ast_state *state = &interp->ast;

    Py_CLEAR(state->AST_type);
    Py_CLEAR(state->Add_singleton);
    Py_CLEAR(state->Add_type);
    Py_CLEAR(state->And_singleton);
    Py_CLEAR(state->And_type);
    Py_CLEAR(state->AnnAssign_type);
    Py_CLEAR(state->Assert_type);
    Py_CLEAR(state->Assign_type);
    Py_CLEAR(state->AsyncFor_type);
    Py_CLEAR(state->AsyncFunctionDef_type);
    Py_CLEAR(state->AsyncWith_type);
    Py_CLEAR(state->Attribute_type);
    Py_CLEAR(state->AugAssign_type);
    Py_CLEAR(state->Await_type);
    Py_CLEAR(state->BinOp_type);
    Py_CLEAR(state->BitAnd_singleton);
    Py_CLEAR(state->BitAnd_type);
    Py_CLEAR(state->BitOr_singleton);
    Py_CLEAR(state->BitOr_type);
    Py_CLEAR(state->BitXor_singleton);
    Py_CLEAR(state->BitXor_type);
    Py_CLEAR(state->BoolOp_type);
    Py_CLEAR(state->Break_type);
    Py_CLEAR(state->Call_type);
    Py_CLEAR(state->ClassDef_type);
    Py_CLEAR(state->Compare_type);
    Py_CLEAR(state->Constant_type);
    Py_CLEAR(state->Continue_type);
    Py_CLEAR(state->Del_singleton);
    Py_CLEAR(state->Del_type);
    Py_CLEAR(state->Delete_type);
    Py_CLEAR(state->DictComp_type);
    Py_CLEAR(state->Dict_type);
    Py_CLEAR(state->Div_singleton);
    Py_CLEAR(state->Div_type);
    Py_CLEAR(state->Eq_singleton);
    Py_CLEAR(state->Eq_type);
    Py_CLEAR(state->ExceptHandler_type);
    Py_CLEAR(state->Expr_type);
    Py_CLEAR(state->Expression_type);
    Py_CLEAR(state->FloorDiv_singleton);
    Py_CLEAR(state->FloorDiv_type);
    Py_CLEAR(state->For_type);
    Py_CLEAR(state->FormattedValue_type);
    Py_CLEAR(state->FunctionDef_type);
    Py_CLEAR(state->FunctionType_type);
    Py_CLEAR(state->GeneratorExp_type);
    Py_CLEAR(state->Global_type);
    Py_CLEAR(state->GtE_singleton);
    Py_CLEAR(state->GtE_type);
    Py_CLEAR(state->Gt_singleton);
    Py_CLEAR(state->Gt_type);
    Py_CLEAR(state->IfExp_type);
    Py_CLEAR(state->If_type);
    Py_CLEAR(state->ImportFrom_type);
    Py_CLEAR(state->Import_type);
    Py_CLEAR(state->In_singleton);
    Py_CLEAR(state->In_type);
    Py_CLEAR(state->Interactive_type);
    Py_CLEAR(state->Invert_singleton);
    Py_CLEAR(state->Invert_type);
    Py_CLEAR(state->IsNot_singleton);
    Py_CLEAR(state->IsNot_type);
    Py_CLEAR(state->Is_singleton);
    Py_CLEAR(state->Is_type);
    Py_CLEAR(state->JoinedStr_type);
    Py_CLEAR(state->LShift_singleton);
    Py_CLEAR(state->LShift_type);
    Py_CLEAR(state->Lambda_type);
    Py_CLEAR(state->ListComp_type);
    Py_CLEAR(state->List_type);
    Py_CLEAR(state->Load_singleton);
    Py_CLEAR(state->Load_type);
    Py_CLEAR(state->LtE_singleton);
    Py_CLEAR(state->LtE_type);
    Py_CLEAR(state->Lt_singleton);
    Py_CLEAR(state->Lt_type);
    Py_CLEAR(state->MatMult_singleton);
    Py_CLEAR(state->MatMult_type);
    Py_CLEAR(state->MatchAs_type);
    Py_CLEAR(state->MatchClass_type);
    Py_CLEAR(state->MatchMapping_type);
    Py_CLEAR(state->MatchOr_type);
    Py_CLEAR(state->MatchSequence_type);
    Py_CLEAR(state->MatchSingleton_type);
    Py_CLEAR(state->MatchStar_type);
    Py_CLEAR(state->MatchValue_type);
    Py_CLEAR(state->Match_type);
    Py_CLEAR(state->Mod_singleton);
    Py_CLEAR(state->Mod_type);
    Py_CLEAR(state->Module_type);
    Py_CLEAR(state->Mult_singleton);
    Py_CLEAR(state->Mult_type);
    Py_CLEAR(state->Name_type);
    Py_CLEAR(state->NamedExpr_type);
    Py_CLEAR(state->Nonlocal_type);
    Py_CLEAR(state->NotEq_singleton);
    Py_CLEAR(state->NotEq_type);
    Py_CLEAR(state->NotIn_singleton);
    Py_CLEAR(state->NotIn_type);
    Py_CLEAR(state->Not_singleton);
    Py_CLEAR(state->Not_type);
    Py_CLEAR(state->Or_singleton);
    Py_CLEAR(state->Or_type);
    Py_CLEAR(state->ParamSpec_type);
    Py_CLEAR(state->Pass_type);
    Py_CLEAR(state->Pow_singleton);
    Py_CLEAR(state->Pow_type);
    Py_CLEAR(state->RShift_singleton);
    Py_CLEAR(state->RShift_type);
    Py_CLEAR(state->Raise_type);
    Py_CLEAR(state->Return_type);
    Py_CLEAR(state->SetComp_type);
    Py_CLEAR(state->Set_type);
    Py_CLEAR(state->Slice_type);
    Py_CLEAR(state->Starred_type);
    Py_CLEAR(state->Store_singleton);
    Py_CLEAR(state->Store_type);
    Py_CLEAR(state->Sub_singleton);
    Py_CLEAR(state->Sub_type);
    Py_CLEAR(state->Subscript_type);
    Py_CLEAR(state->TryStar_type);
    Py_CLEAR(state->Try_type);
    Py_CLEAR(state->Tuple_type);
    Py_CLEAR(state->TypeAlias_type);
    Py_CLEAR(state->TypeIgnore_type);
    Py_CLEAR(state->TypeVarTuple_type);
    Py_CLEAR(state->TypeVar_type);
    Py_CLEAR(state->UAdd_singleton);
    Py_CLEAR(state->UAdd_type);
    Py_CLEAR(state->USub_singleton);
    Py_CLEAR(state->USub_type);
    Py_CLEAR(state->UnaryOp_type);
    Py_CLEAR(state->While_type);
    Py_CLEAR(state->With_type);
    Py_CLEAR(state->YieldFrom_type);
    Py_CLEAR(state->Yield_type);
    Py_CLEAR(state->__dict__);
    Py_CLEAR(state->__doc__);
    Py_CLEAR(state->__match_args__);
    Py_CLEAR(state->__module__);
    Py_CLEAR(state->_attributes);
    Py_CLEAR(state->_fields);
    Py_CLEAR(state->alias_type);
    Py_CLEAR(state->annotation);
    Py_CLEAR(state->arg);
    Py_CLEAR(state->arg_type);
    Py_CLEAR(state->args);
    Py_CLEAR(state->argtypes);
    Py_CLEAR(state->arguments_type);
    Py_CLEAR(state->asname);
    Py_CLEAR(state->ast);
    Py_CLEAR(state->attr);
    Py_CLEAR(state->bases);
    Py_CLEAR(state->body);
    Py_CLEAR(state->boolop_type);
    Py_CLEAR(state->bound);
    Py_CLEAR(state->cases);
    Py_CLEAR(state->cause);
    Py_CLEAR(state->cls);
    Py_CLEAR(state->cmpop_type);
    Py_CLEAR(state->col_offset);
    Py_CLEAR(state->comparators);
    Py_CLEAR(state->comprehension_type);
    Py_CLEAR(state->context_expr);
    Py_CLEAR(state->conversion);
    Py_CLEAR(state->ctx);
    Py_CLEAR(state->decorator_list);
    Py_CLEAR(state->defaults);
    Py_CLEAR(state->elt);
    Py_CLEAR(state->elts);
    Py_CLEAR(state->end_col_offset);
    Py_CLEAR(state->end_lineno);
    Py_CLEAR(state->exc);
    Py_CLEAR(state->excepthandler_type);
    Py_CLEAR(state->expr_context_type);
    Py_CLEAR(state->expr_type);
    Py_CLEAR(state->finalbody);
    Py_CLEAR(state->format_spec);
    Py_CLEAR(state->func);
    Py_CLEAR(state->generators);
    Py_CLEAR(state->guard);
    Py_CLEAR(state->handlers);
    Py_CLEAR(state->id);
    Py_CLEAR(state->ifs);
    Py_CLEAR(state->is_async);
    Py_CLEAR(state->items);
    Py_CLEAR(state->iter);
    Py_CLEAR(state->key);
    Py_CLEAR(state->keys);
    Py_CLEAR(state->keyword_type);
    Py_CLEAR(state->keywords);
    Py_CLEAR(state->kind);
    Py_CLEAR(state->kw_defaults);
    Py_CLEAR(state->kwarg);
    Py_CLEAR(state->kwd_attrs);
    Py_CLEAR(state->kwd_patterns);
    Py_CLEAR(state->kwonlyargs);
    Py_CLEAR(state->left);
    Py_CLEAR(state->level);
    Py_CLEAR(state->lineno);
    Py_CLEAR(state->lower);
    Py_CLEAR(state->match_case_type);
    Py_CLEAR(state->mod_type);
    Py_CLEAR(state->module);
    Py_CLEAR(state->msg);
    Py_CLEAR(state->name);
    Py_CLEAR(state->names);
    Py_CLEAR(state->op);
    Py_CLEAR(state->operand);
    Py_CLEAR(state->operator_type);
    Py_CLEAR(state->ops);
    Py_CLEAR(state->optional_vars);
    Py_CLEAR(state->orelse);
    Py_CLEAR(state->pattern);
    Py_CLEAR(state->pattern_type);
    Py_CLEAR(state->patterns);
    Py_CLEAR(state->posonlyargs);
    Py_CLEAR(state->rest);
    Py_CLEAR(state->returns);
    Py_CLEAR(state->right);
    Py_CLEAR(state->simple);
    Py_CLEAR(state->slice);
    Py_CLEAR(state->step);
    Py_CLEAR(state->stmt_type);
    Py_CLEAR(state->subject);
    Py_CLEAR(state->tag);
    Py_CLEAR(state->target);
    Py_CLEAR(state->targets);
    Py_CLEAR(state->test);
    Py_CLEAR(state->type);
    Py_CLEAR(state->type_comment);
    Py_CLEAR(state->type_ignore_type);
    Py_CLEAR(state->type_ignores);
    Py_CLEAR(state->type_param_type);
    Py_CLEAR(state->type_params);
    Py_CLEAR(state->unaryop_type);
    Py_CLEAR(state->upper);
    Py_CLEAR(state->value);
    Py_CLEAR(state->values);
    Py_CLEAR(state->vararg);
    Py_CLEAR(state->withitem_type);

    Py_CLEAR(_Py_INTERP_CACHED_OBJECT(interp, str_replace_inf));

#if !defined(NDEBUG)
    state->initialized = -1;
#else
    state->initialized = 0;
#endif
}

static int init_identifiers(struct ast_state *state)
{
    if ((state->__dict__ = PyUnicode_InternFromString("__dict__")) == NULL) return 0;
    if ((state->__doc__ = PyUnicode_InternFromString("__doc__")) == NULL) return 0;
    if ((state->__match_args__ = PyUnicode_InternFromString("__match_args__")) == NULL) return 0;
    if ((state->__module__ = PyUnicode_InternFromString("__module__")) == NULL) return 0;
    if ((state->_attributes = PyUnicode_InternFromString("_attributes")) == NULL) return 0;
    if ((state->_fields = PyUnicode_InternFromString("_fields")) == NULL) return 0;
    if ((state->annotation = PyUnicode_InternFromString("annotation")) == NULL) return 0;
    if ((state->arg = PyUnicode_InternFromString("arg")) == NULL) return 0;
    if ((state->args = PyUnicode_InternFromString("args")) == NULL) return 0;
    if ((state->argtypes = PyUnicode_InternFromString("argtypes")) == NULL) return 0;
    if ((state->asname = PyUnicode_InternFromString("asname")) == NULL) return 0;
    if ((state->ast = PyUnicode_InternFromString("ast")) == NULL) return 0;
    if ((state->attr = PyUnicode_InternFromString("attr")) == NULL) return 0;
    if ((state->bases = PyUnicode_InternFromString("bases")) == NULL) return 0;
    if ((state->body = PyUnicode_InternFromString("body")) == NULL) return 0;
    if ((state->bound = PyUnicode_InternFromString("bound")) == NULL) return 0;
    if ((state->cases = PyUnicode_InternFromString("cases")) == NULL) return 0;
    if ((state->cause = PyUnicode_InternFromString("cause")) == NULL) return 0;
    if ((state->cls = PyUnicode_InternFromString("cls")) == NULL) return 0;
    if ((state->col_offset = PyUnicode_InternFromString("col_offset")) == NULL) return 0;
    if ((state->comparators = PyUnicode_InternFromString("comparators")) == NULL) return 0;
    if ((state->context_expr = PyUnicode_InternFromString("context_expr")) == NULL) return 0;
    if ((state->conversion = PyUnicode_InternFromString("conversion")) == NULL) return 0;
    if ((state->ctx = PyUnicode_InternFromString("ctx")) == NULL) return 0;
    if ((state->decorator_list = PyUnicode_InternFromString("decorator_list")) == NULL) return 0;
    if ((state->defaults = PyUnicode_InternFromString("defaults")) == NULL) return 0;
    if ((state->elt = PyUnicode_InternFromString("elt")) == NULL) return 0;
    if ((state->elts = PyUnicode_InternFromString("elts")) == NULL) return 0;
    if ((state->end_col_offset = PyUnicode_InternFromString("end_col_offset")) == NULL) return 0;
    if ((state->end_lineno = PyUnicode_InternFromString("end_lineno")) == NULL) return 0;
    if ((state->exc = PyUnicode_InternFromString("exc")) == NULL) return 0;
    if ((state->finalbody = PyUnicode_InternFromString("finalbody")) == NULL) return 0;
    if ((state->format_spec = PyUnicode_InternFromString("format_spec")) == NULL) return 0;
    if ((state->func = PyUnicode_InternFromString("func")) == NULL) return 0;
    if ((state->generators = PyUnicode_InternFromString("generators")) == NULL) return 0;
    if ((state->guard = PyUnicode_InternFromString("guard")) == NULL) return 0;
    if ((state->handlers = PyUnicode_InternFromString("handlers")) == NULL) return 0;
    if ((state->id = PyUnicode_InternFromString("id")) == NULL) return 0;
    if ((state->ifs = PyUnicode_InternFromString("ifs")) == NULL) return 0;
    if ((state->is_async = PyUnicode_InternFromString("is_async")) == NULL) return 0;
    if ((state->items = PyUnicode_InternFromString("items")) == NULL) return 0;
    if ((state->iter = PyUnicode_InternFromString("iter")) == NULL) return 0;
    if ((state->key = PyUnicode_InternFromString("key")) == NULL) return 0;
    if ((state->keys = PyUnicode_InternFromString("keys")) == NULL) return 0;
    if ((state->keywords = PyUnicode_InternFromString("keywords")) == NULL) return 0;
    if ((state->kind = PyUnicode_InternFromString("kind")) == NULL) return 0;
    if ((state->kw_defaults = PyUnicode_InternFromString("kw_defaults")) == NULL) return 0;
    if ((state->kwarg = PyUnicode_InternFromString("kwarg")) == NULL) return 0;
    if ((state->kwd_attrs = PyUnicode_InternFromString("kwd_attrs")) == NULL) return 0;
    if ((state->kwd_patterns = PyUnicode_InternFromString("kwd_patterns")) == NULL) return 0;
    if ((state->kwonlyargs = PyUnicode_InternFromString("kwonlyargs")) == NULL) return 0;
    if ((state->left = PyUnicode_InternFromString("left")) == NULL) return 0;
    if ((state->level = PyUnicode_InternFromString("level")) == NULL) return 0;
    if ((state->lineno = PyUnicode_InternFromString("lineno")) == NULL) return 0;
    if ((state->lower = PyUnicode_InternFromString("lower")) == NULL) return 0;
    if ((state->module = PyUnicode_InternFromString("module")) == NULL) return 0;
    if ((state->msg = PyUnicode_InternFromString("msg")) == NULL) return 0;
    if ((state->name = PyUnicode_InternFromString("name")) == NULL) return 0;
    if ((state->names = PyUnicode_InternFromString("names")) == NULL) return 0;
    if ((state->op = PyUnicode_InternFromString("op")) == NULL) return 0;
    if ((state->operand = PyUnicode_InternFromString("operand")) == NULL) return 0;
    if ((state->ops = PyUnicode_InternFromString("ops")) == NULL) return 0;
    if ((state->optional_vars = PyUnicode_InternFromString("optional_vars")) == NULL) return 0;
    if ((state->orelse = PyUnicode_InternFromString("orelse")) == NULL) return 0;
    if ((state->pattern = PyUnicode_InternFromString("pattern")) == NULL) return 0;
    if ((state->patterns = PyUnicode_InternFromString("patterns")) == NULL) return 0;
    if ((state->posonlyargs = PyUnicode_InternFromString("posonlyargs")) == NULL) return 0;
    if ((state->rest = PyUnicode_InternFromString("rest")) == NULL) return 0;
    if ((state->returns = PyUnicode_InternFromString("returns")) == NULL) return 0;
    if ((state->right = PyUnicode_InternFromString("right")) == NULL) return 0;
    if ((state->simple = PyUnicode_InternFromString("simple")) == NULL) return 0;
    if ((state->slice = PyUnicode_InternFromString("slice")) == NULL) return 0;
    if ((state->step = PyUnicode_InternFromString("step")) == NULL) return 0;
    if ((state->subject = PyUnicode_InternFromString("subject")) == NULL) return 0;
    if ((state->tag = PyUnicode_InternFromString("tag")) == NULL) return 0;
    if ((state->target = PyUnicode_InternFromString("target")) == NULL) return 0;
    if ((state->targets = PyUnicode_InternFromString("targets")) == NULL) return 0;
    if ((state->test = PyUnicode_InternFromString("test")) == NULL) return 0;
    if ((state->type = PyUnicode_InternFromString("type")) == NULL) return 0;
    if ((state->type_comment = PyUnicode_InternFromString("type_comment")) == NULL) return 0;
    if ((state->type_ignores = PyUnicode_InternFromString("type_ignores")) == NULL) return 0;
    if ((state->type_params = PyUnicode_InternFromString("type_params")) == NULL) return 0;
    if ((state->upper = PyUnicode_InternFromString("upper")) == NULL) return 0;
    if ((state->value = PyUnicode_InternFromString("value")) == NULL) return 0;
    if ((state->values = PyUnicode_InternFromString("values")) == NULL) return 0;
    if ((state->vararg = PyUnicode_InternFromString("vararg")) == NULL) return 0;
    return 1;
};

GENERATE_ASDL_SEQ_CONSTRUCTOR(mod, mod_ty)
GENERATE_ASDL_SEQ_CONSTRUCTOR(stmt, stmt_ty)
GENERATE_ASDL_SEQ_CONSTRUCTOR(expr, expr_ty)
GENERATE_ASDL_SEQ_CONSTRUCTOR(comprehension, comprehension_ty)
GENERATE_ASDL_SEQ_CONSTRUCTOR(excepthandler, excepthandler_ty)
GENERATE_ASDL_SEQ_CONSTRUCTOR(arguments, arguments_ty)
GENERATE_ASDL_SEQ_CONSTRUCTOR(arg, arg_ty)
GENERATE_ASDL_SEQ_CONSTRUCTOR(keyword, keyword_ty)
GENERATE_ASDL_SEQ_CONSTRUCTOR(alias, alias_ty)
GENERATE_ASDL_SEQ_CONSTRUCTOR(withitem, withitem_ty)
GENERATE_ASDL_SEQ_CONSTRUCTOR(match_case, match_case_ty)
GENERATE_ASDL_SEQ_CONSTRUCTOR(pattern, pattern_ty)
GENERATE_ASDL_SEQ_CONSTRUCTOR(type_ignore, type_ignore_ty)
GENERATE_ASDL_SEQ_CONSTRUCTOR(type_param, type_param_ty)

static PyObject* ast2obj_mod(struct ast_state *state, void*);
static const char * const Module_fields[]={
    "body",
    "type_ignores",
};
static const char * const Interactive_fields[]={
    "body",
};
static const char * const Expression_fields[]={
    "body",
};
static const char * const FunctionType_fields[]={
    "argtypes",
    "returns",
};
static const char * const stmt_attributes[] = {
    "lineno",
    "col_offset",
    "end_lineno",
    "end_col_offset",
};
static PyObject* ast2obj_stmt(struct ast_state *state, void*);
static const char * const FunctionDef_fields[]={
    "name",
    "args",
    "body",
    "decorator_list",
    "returns",
    "type_comment",
    "type_params",
};
static const char * const AsyncFunctionDef_fields[]={
    "name",
    "args",
    "body",
    "decorator_list",
    "returns",
    "type_comment",
    "type_params",
};
static const char * const ClassDef_fields[]={
    "name",
    "bases",
    "keywords",
    "body",
    "decorator_list",
    "type_params",
};
static const char * const Return_fields[]={
    "value",
};
static const char * const Delete_fields[]={
    "targets",
};
static const char * const Assign_fields[]={
    "targets",
    "value",
    "type_comment",
};
static const char * const TypeAlias_fields[]={
    "name",
    "type_params",
    "value",
};
static const char * const AugAssign_fields[]={
    "target",
    "op",
    "value",
};
static const char * const AnnAssign_fields[]={
    "target",
    "annotation",
    "value",
    "simple",
};
static const char * const For_fields[]={
    "target",
    "iter",
    "body",
    "orelse",
    "type_comment",
};
static const char * const AsyncFor_fields[]={
    "target",
    "iter",
    "body",
    "orelse",
    "type_comment",
};
static const char * const While_fields[]={
    "test",
    "body",
    "orelse",
};
static const char * const If_fields[]={
    "test",
    "body",
    "orelse",
};
static const char * const With_fields[]={
    "items",
    "body",
    "type_comment",
};
static const char * const AsyncWith_fields[]={
    "items",
    "body",
    "type_comment",
};
static const char * const Match_fields[]={
    "subject",
    "cases",
};
static const char * const Raise_fields[]={
    "exc",
    "cause",
};
static const char * const Try_fields[]={
    "body",
    "handlers",
    "orelse",
    "finalbody",
};
static const char * const TryStar_fields[]={
    "body",
    "handlers",
    "orelse",
    "finalbody",
};
static const char * const Assert_fields[]={
    "test",
    "msg",
};
static const char * const Import_fields[]={
    "names",
};
static const char * const ImportFrom_fields[]={
    "module",
    "names",
    "level",
};
static const char * const Global_fields[]={
    "names",
};
static const char * const Nonlocal_fields[]={
    "names",
};
static const char * const Expr_fields[]={
    "value",
};
static const char * const expr_attributes[] = {
    "lineno",
    "col_offset",
    "end_lineno",
    "end_col_offset",
};
static PyObject* ast2obj_expr(struct ast_state *state, void*);
static const char * const BoolOp_fields[]={
    "op",
    "values",
};
static const char * const NamedExpr_fields[]={
    "target",
    "value",
};
static const char * const BinOp_fields[]={
    "left",
    "op",
    "right",
};
static const char * const UnaryOp_fields[]={
    "op",
    "operand",
};
static const char * const Lambda_fields[]={
    "args",
    "body",
};
static const char * const IfExp_fields[]={
    "test",
    "body",
    "orelse",
};
static const char * const Dict_fields[]={
    "keys",
    "values",
};
static const char * const Set_fields[]={
    "elts",
};
static const char * const ListComp_fields[]={
    "elt",
    "generators",
};
static const char * const SetComp_fields[]={
    "elt",
    "generators",
};
static const char * const DictComp_fields[]={
    "key",
    "value",
    "generators",
};
static const char * const GeneratorExp_fields[]={
    "elt",
    "generators",
};
static const char * const Await_fields[]={
    "value",
};
static const char * const Yield_fields[]={
    "value",
};
static const char * const YieldFrom_fields[]={
    "value",
};
static const char * const Compare_fields[]={
    "left",
    "ops",
    "comparators",
};
static const char * const Call_fields[]={
    "func",
    "args",
    "keywords",
};
static const char * const FormattedValue_fields[]={
    "value",
    "conversion",
    "format_spec",
};
static const char * const JoinedStr_fields[]={
    "values",
};
static const char * const Constant_fields[]={
    "value",
    "kind",
};
static const char * const Attribute_fields[]={
    "value",
    "attr",
    "ctx",
};
static const char * const Subscript_fields[]={
    "value",
    "slice",
    "ctx",
};
static const char * const Starred_fields[]={
    "value",
    "ctx",
};
static const char * const Name_fields[]={
    "id",
    "ctx",
};
static const char * const List_fields[]={
    "elts",
    "ctx",
};
static const char * const Tuple_fields[]={
    "elts",
    "ctx",
};
static const char * const Slice_fields[]={
    "lower",
    "upper",
    "step",
};
static PyObject* ast2obj_expr_context(struct ast_state *state, expr_context_ty);
static PyObject* ast2obj_boolop(struct ast_state *state, boolop_ty);
static PyObject* ast2obj_operator(struct ast_state *state, operator_ty);
static PyObject* ast2obj_unaryop(struct ast_state *state, unaryop_ty);
static PyObject* ast2obj_cmpop(struct ast_state *state, cmpop_ty);
static PyObject* ast2obj_comprehension(struct ast_state *state, void*);
static const char * const comprehension_fields[]={
    "target",
    "iter",
    "ifs",
    "is_async",
};
static const char * const excepthandler_attributes[] = {
    "lineno",
    "col_offset",
    "end_lineno",
    "end_col_offset",
};
static PyObject* ast2obj_excepthandler(struct ast_state *state, void*);
static const char * const ExceptHandler_fields[]={
    "type",
    "name",
    "body",
};
static PyObject* ast2obj_arguments(struct ast_state *state, void*);
static const char * const arguments_fields[]={
    "posonlyargs",
    "args",
    "vararg",
    "kwonlyargs",
    "kw_defaults",
    "kwarg",
    "defaults",
};
static PyObject* ast2obj_arg(struct ast_state *state, void*);
static const char * const arg_attributes[] = {
    "lineno",
    "col_offset",
    "end_lineno",
    "end_col_offset",
};
static const char * const arg_fields[]={
    "arg",
    "annotation",
    "type_comment",
};
static PyObject* ast2obj_keyword(struct ast_state *state, void*);
static const char * const keyword_attributes[] = {
    "lineno",
    "col_offset",
    "end_lineno",
    "end_col_offset",
};
static const char * const keyword_fields[]={
    "arg",
    "value",
};
static PyObject* ast2obj_alias(struct ast_state *state, void*);
static const char * const alias_attributes[] = {
    "lineno",
    "col_offset",
    "end_lineno",
    "end_col_offset",
};
static const char * const alias_fields[]={
    "name",
    "asname",
};
static PyObject* ast2obj_withitem(struct ast_state *state, void*);
static const char * const withitem_fields[]={
    "context_expr",
    "optional_vars",
};
static PyObject* ast2obj_match_case(struct ast_state *state, void*);
static const char * const match_case_fields[]={
    "pattern",
    "guard",
    "body",
};
static const char * const pattern_attributes[] = {
    "lineno",
    "col_offset",
    "end_lineno",
    "end_col_offset",
};
static PyObject* ast2obj_pattern(struct ast_state *state, void*);
static const char * const MatchValue_fields[]={
    "value",
};
static const char * const MatchSingleton_fields[]={
    "value",
};
static const char * const MatchSequence_fields[]={
    "patterns",
};
static const char * const MatchMapping_fields[]={
    "keys",
    "patterns",
    "rest",
};
static const char * const MatchClass_fields[]={
    "cls",
    "patterns",
    "kwd_attrs",
    "kwd_patterns",
};
static const char * const MatchStar_fields[]={
    "name",
};
static const char * const MatchAs_fields[]={
    "pattern",
    "name",
};
static const char * const MatchOr_fields[]={
    "patterns",
};
static PyObject* ast2obj_type_ignore(struct ast_state *state, void*);
static const char * const TypeIgnore_fields[]={
    "lineno",
    "tag",
};
static const char * const type_param_attributes[] = {
    "lineno",
    "col_offset",
    "end_lineno",
    "end_col_offset",
};
static PyObject* ast2obj_type_param(struct ast_state *state, void*);
static const char * const TypeVar_fields[]={
    "name",
    "bound",
};
static const char * const ParamSpec_fields[]={
    "name",
};
static const char * const TypeVarTuple_fields[]={
    "name",
};



typedef struct {
    PyObject_HEAD
    PyObject *dict;
} AST_object;

static void
ast_dealloc(AST_object *self)
{
    /* bpo-31095: UnTrack is needed before calling any callbacks */
    PyTypeObject *tp = Py_TYPE(self);
    PyObject_GC_UnTrack(self);
    Py_CLEAR(self->dict);
    freefunc free_func = PyType_GetSlot(tp, Py_tp_free);
    assert(free_func != NULL);
    free_func(self);
    Py_DECREF(tp);
}

static int
ast_traverse(AST_object *self, visitproc visit, void *arg)
{
    Py_VISIT(Py_TYPE(self));
    Py_VISIT(self->dict);
    return 0;
}

static int
ast_clear(AST_object *self)
{
    Py_CLEAR(self->dict);
    return 0;
}

static int
ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
{
    struct ast_state *state = get_ast_state();
    if (state == NULL) {
        return -1;
    }

    Py_ssize_t i, numfields = 0;
    int res = -1;
    PyObject *key, *value, *fields;
    if (_PyObject_LookupAttr((PyObject*)Py_TYPE(self), state->_fields, &fields) < 0) {
        goto cleanup;
    }
    if (fields) {
        numfields = PySequence_Size(fields);
        if (numfields == -1) {
            goto cleanup;
        }
    }

    res = 0; /* if no error occurs, this stays 0 to the end */
    if (numfields < PyTuple_GET_SIZE(args)) {
        PyErr_Format(PyExc_TypeError, "%.400s constructor takes at most "
                     "%zd positional argument%s",
                     _PyType_Name(Py_TYPE(self)),
                     numfields, numfields == 1 ? "" : "s");
        res = -1;
        goto cleanup;
    }
    for (i = 0; i < PyTuple_GET_SIZE(args); i++) {
        /* cannot be reached when fields is NULL */
        PyObject *name = PySequence_GetItem(fields, i);
        if (!name) {
            res = -1;
            goto cleanup;
        }
        res = PyObject_SetAttr(self, name, PyTuple_GET_ITEM(args, i));
        Py_DECREF(name);
        if (res < 0) {
            goto cleanup;
        }
    }
    if (kw) {
        i = 0;  /* needed by PyDict_Next */
        while (PyDict_Next(kw, &i, &key, &value)) {
            int contains = PySequence_Contains(fields, key);
            if (contains == -1) {
                res = -1;
                goto cleanup;
            } else if (contains == 1) {
                Py_ssize_t p = PySequence_Index(fields, key);
                if (p == -1) {
                    res = -1;
                    goto cleanup;
                }
                if (p < PyTuple_GET_SIZE(args)) {
                    PyErr_Format(PyExc_TypeError,
                        "%.400s got multiple values for argument '%U'",
                        Py_TYPE(self)->tp_name, key);
                    res = -1;
                    goto cleanup;
                }
            }
            res = PyObject_SetAttr(self, key, value);
            if (res < 0) {
                goto cleanup;
            }
        }
    }
  cleanup:
    Py_XDECREF(fields);
    return res;
}

/* Pickling support */
static PyObject *
ast_type_reduce(PyObject *self, PyObject *unused)
{
    struct ast_state *state = get_ast_state();
    if (state == NULL) {
        return NULL;
    }

    PyObject *dict;
    if (_PyObject_LookupAttr(self, state->__dict__, &dict) < 0) {
        return NULL;
    }
    if (dict) {
        return Py_BuildValue("O()N", Py_TYPE(self), dict);
    }
    return Py_BuildValue("O()", Py_TYPE(self));
}

static PyMemberDef ast_type_members[] = {
    {"__dictoffset__", T_PYSSIZET, offsetof(AST_object, dict), READONLY},
    {NULL}  /* Sentinel */
};

static PyMethodDef ast_type_methods[] = {
    {"__reduce__", ast_type_reduce, METH_NOARGS, NULL},
    {NULL}
};

static PyGetSetDef ast_type_getsets[] = {
    {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
    {NULL}
};

static PyType_Slot AST_type_slots[] = {
    {Py_tp_dealloc, ast_dealloc},
    {Py_tp_getattro, PyObject_GenericGetAttr},
    {Py_tp_setattro, PyObject_GenericSetAttr},
    {Py_tp_traverse, ast_traverse},
    {Py_tp_clear, ast_clear},
    {Py_tp_members, ast_type_members},
    {Py_tp_methods, ast_type_methods},
    {Py_tp_getset, ast_type_getsets},
    {Py_tp_init, ast_type_init},
    {Py_tp_alloc, PyType_GenericAlloc},
    {Py_tp_new, PyType_GenericNew},
    {Py_tp_free, PyObject_GC_Del},
    {0, 0},
};

static PyType_Spec AST_type_spec = {
    "ast.AST",
    sizeof(AST_object),
    0,
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
    AST_type_slots
};

static PyObject *
make_type(struct ast_state *state, const char *type, PyObject* base,
          const char* const* fields, int num_fields, const char *doc)
{
    PyObject *fnames, *result;
    int i;
    fnames = PyTuple_New(num_fields);
    if (!fnames) return NULL;
    for (i = 0; i < num_fields; i++) {
        PyObject *field = PyUnicode_InternFromString(fields[i]);
        if (!field) {
            Py_DECREF(fnames);
            return NULL;
        }
        PyTuple_SET_ITEM(fnames, i, field);
    }
    result = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){OOOOOOOs}",
                    type, base,
                    state->_fields, fnames,
                    state->__match_args__, fnames,
                    state->__module__,
                    state->ast,
                    state->__doc__, doc);
    Py_DECREF(fnames);
    return result;
}

static int
add_attributes(struct ast_state *state, PyObject *type, const char * const *attrs, int num_fields)
{
    int i, result;
    PyObject *s, *l = PyTuple_New(num_fields);
    if (!l)
        return 0;
    for (i = 0; i < num_fields; i++) {
        s = PyUnicode_InternFromString(attrs[i]);
        if (!s) {
            Py_DECREF(l);
            return 0;
        }
        PyTuple_SET_ITEM(l, i, s);
    }
    result = PyObject_SetAttr(type, state->_attributes, l) >= 0;
    Py_DECREF(l);
    return result;
}

/* Conversion AST -> Python */

static PyObject* ast2obj_list(struct ast_state *state, asdl_seq *seq, PyObject* (*func)(struct ast_state *state, void*))
{
    Py_ssize_t i, n = asdl_seq_LEN(seq);
    PyObject *result = PyList_New(n);
    PyObject *value;
    if (!result)
        return NULL;
    for (i = 0; i < n; i++) {
        value = func(state, asdl_seq_GET_UNTYPED(seq, i));
        if (!value) {
            Py_DECREF(result);
            return NULL;
        }
        PyList_SET_ITEM(result, i, value);
    }
    return result;
}

static PyObject* ast2obj_object(struct ast_state *Py_UNUSED(state), void *o)
{
    PyObject *op = (PyObject*)o;
    if (!op) {
        op = Py_None;
    }
    return Py_NewRef(op);
}
#define ast2obj_constant ast2obj_object
#define ast2obj_identifier ast2obj_object
#define ast2obj_string ast2obj_object

static PyObject* ast2obj_int(struct ast_state *Py_UNUSED(state), long b)
{
    return PyLong_FromLong(b);
}

/* Conversion Python -> AST */

static int obj2ast_object(struct ast_state *Py_UNUSED(state), PyObject* obj, PyObject** out, PyArena* arena)
{
    if (obj == Py_None)
        obj = NULL;
    if (obj) {
        if (_PyArena_AddPyObject(arena, obj) < 0) {
            *out = NULL;
            return -1;
        }
        *out = Py_NewRef(obj);
    }
    else {
        *out = NULL;
    }
    return 0;
}

static int obj2ast_constant(struct ast_state *Py_UNUSED(state), PyObject* obj, PyObject** out, PyArena* arena)
{
    if (_PyArena_AddPyObject(arena, obj) < 0) {
        *out = NULL;
        return -1;
    }
    *out = Py_NewRef(obj);
    return 0;
}

static int obj2ast_identifier(struct ast_state *state, PyObject* obj, PyObject** out, PyArena* arena)
{
    if (!PyUnicode_CheckExact(obj) && obj != Py_None) {
        PyErr_SetString(PyExc_TypeError, "AST identifier must be of type str");
        return 1;
    }
    return obj2ast_object(state, obj, out, arena);
}

static int obj2ast_string(struct ast_state *state, PyObject* obj, PyObject** out, PyArena* arena)
{
    if (!PyUnicode_CheckExact(obj) && !PyBytes_CheckExact(obj)) {
        PyErr_SetString(PyExc_TypeError, "AST string must be of type str");
        return 1;
    }
    return obj2ast_object(state, obj, out, arena);
}

static int obj2ast_int(struct ast_state* Py_UNUSED(state), PyObject* obj, int* out, PyArena* arena)
{
    int i;
    if (!PyLong_Check(obj)) {
        PyErr_Format(PyExc_ValueError, "invalid integer value: %R", obj);
        return 1;
    }

    i = _PyLong_AsInt(obj);
    if (i == -1 && PyErr_Occurred())
        return 1;
    *out = i;
    return 0;
}

static int add_ast_fields(struct ast_state *state)
{
    PyObject *empty_tuple;
    empty_tuple = PyTuple_New(0);
    if (!empty_tuple ||
        PyObject_SetAttrString(state->AST_type, "_fields", empty_tuple) < 0 ||
        PyObject_SetAttrString(state->AST_type, "__match_args__", empty_tuple) < 0 ||
        PyObject_SetAttrString(state->AST_type, "_attributes", empty_tuple) < 0) {
        Py_XDECREF(empty_tuple);
        return -1;
    }
    Py_DECREF(empty_tuple);
    return 0;
}



static int
init_types(struct ast_state *state)
{
    // init_types() must not be called after _PyAST_Fini()
    // has been called
    assert(state->initialized >= 0);

    if (state->initialized) {
        return 1;
    }
    if (init_identifiers(state) < 0) {
        return 0;
    }
    state->AST_type = PyType_FromSpec(&AST_type_spec);
    if (!state->AST_type) {
        return 0;
    }
    if (add_ast_fields(state) < 0) {
        return 0;
    }
    state->mod_type = make_type(state, "mod", state->AST_type, NULL, 0,
        "mod = Module(stmt* body, type_ignore* type_ignores)\n"
        "    | Interactive(stmt* body)\n"
        "    | Expression(expr body)\n"
        "    | FunctionType(expr* argtypes, expr returns)");
    if (!state->mod_type) return 0;
    if (!add_attributes(state, state->mod_type, NULL, 0)) return 0;
    state->Module_type = make_type(state, "Module", state->mod_type,
                                   Module_fields, 2,
        "Module(stmt* body, type_ignore* type_ignores)");
    if (!state->Module_type) return 0;
    state->Interactive_type = make_type(state, "Interactive", state->mod_type,
                                        Interactive_fields, 1,
        "Interactive(stmt* body)");
    if (!state->Interactive_type) return 0;
    state->Expression_type = make_type(state, "Expression", state->mod_type,
                                       Expression_fields, 1,
        "Expression(expr body)");
    if (!state->Expression_type) return 0;
    state->FunctionType_type = make_type(state, "FunctionType",
                                         state->mod_type, FunctionType_fields,
                                         2,
        "FunctionType(expr* argtypes, expr returns)");
    if (!state->FunctionType_type) return 0;
    state->stmt_type = make_type(state, "stmt", state->AST_type, NULL, 0,
        "stmt = FunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment, type_param* type_params)\n"
        "     | AsyncFunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment, type_param* type_params)\n"
        "     | ClassDef(identifier name, expr* bases, keyword* keywords, stmt* body, expr* decorator_list, type_param* type_params)\n"
        "     | Return(expr? value)\n"
        "     | Delete(expr* targets)\n"
        "     | Assign(expr* targets, expr value, string? type_comment)\n"
        "     | TypeAlias(expr name, type_param* type_params, expr value)\n"
        "     | AugAssign(expr target, operator op, expr value)\n"
        "     | AnnAssign(expr target, expr annotation, expr? value, int simple)\n"
        "     | For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)\n"
        "     | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)\n"
        "     | While(expr test, stmt* body, stmt* orelse)\n"
        "     | If(expr test, stmt* body, stmt* orelse)\n"
        "     | With(withitem* items, stmt* body, string? type_comment)\n"
        "     | AsyncWith(withitem* items, stmt* body, string? type_comment)\n"
        "     | Match(expr subject, match_case* cases)\n"
        "     | Raise(expr? exc, expr? cause)\n"
        "     | Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)\n"
        "     | TryStar(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)\n"
        "     | Assert(expr test, expr? msg)\n"
        "     | Import(alias* names)\n"
        "     | ImportFrom(identifier? module, alias* names, int? level)\n"
        "     | Global(identifier* names)\n"
        "     | Nonlocal(identifier* names)\n"
        "     | Expr(expr value)\n"
        "     | Pass\n"
        "     | Break\n"
        "     | Continue");
    if (!state->stmt_type) return 0;
    if (!add_attributes(state, state->stmt_type, stmt_attributes, 4)) return 0;
    if (PyObject_SetAttr(state->stmt_type, state->end_lineno, Py_None) == -1)
        return 0;
    if (PyObject_SetAttr(state->stmt_type, state->end_col_offset, Py_None) ==
        -1)
        return 0;
    state->FunctionDef_type = make_type(state, "FunctionDef", state->stmt_type,
                                        FunctionDef_fields, 7,
        "FunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment, type_param* type_params)");
    if (!state->FunctionDef_type) return 0;
    if (PyObject_SetAttr(state->FunctionDef_type, state->returns, Py_None) ==
        -1)
        return 0;
    if (PyObject_SetAttr(state->FunctionDef_type, state->type_comment, Py_None)
        == -1)
        return 0;
    state->AsyncFunctionDef_type = make_type(state, "AsyncFunctionDef",
                                             state->stmt_type,
                                             AsyncFunctionDef_fields, 7,
        "AsyncFunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment, type_param* type_params)");
    if (!state->AsyncFunctionDef_type) return 0;
    if (PyObject_SetAttr(state->AsyncFunctionDef_type, state->returns, Py_None)
        == -1)
        return 0;
    if (PyObject_SetAttr(state->AsyncFunctionDef_type, state->type_comment,
        Py_None) == -1)
        return 0;
    state->ClassDef_type = make_type(state, "ClassDef", state->stmt_type,
                                     ClassDef_fields, 6,
        "ClassDef(identifier name, expr* bases, keyword* keywords, stmt* body, expr* decorator_list, type_param* type_params)");
    if (!state->ClassDef_type) return 0;
    state->Return_type = make_type(state, "Return", state->stmt_type,
                                   Return_fields, 1,
        "Return(expr? value)");
    if (!state->Return_type) return 0;
    if (PyObject_SetAttr(state->Return_type, state->value, Py_None) == -1)
        return 0;
    state->Delete_type = make_type(state, "Delete", state->stmt_type,
                                   Delete_fields, 1,
        "Delete(expr* targets)");
    if (!state->Delete_type) return 0;
    state->Assign_type = make_type(state, "Assign", state->stmt_type,
                                   Assign_fields, 3,
        "Assign(expr* targets, expr value, string? type_comment)");
    if (!state->Assign_type) return 0;
    if (PyObject_SetAttr(state->Assign_type, state->type_comment, Py_None) ==
        -1)
        return 0;
    state->TypeAlias_type = make_type(state, "TypeAlias", state->stmt_type,
                                      TypeAlias_fields, 3,
        "TypeAlias(expr name, type_param* type_params, expr value)");
    if (!state->TypeAlias_type) return 0;
    state->AugAssign_type = make_type(state, "AugAssign", state->stmt_type,
                                      AugAssign_fields, 3,
        "AugAssign(expr target, operator op, expr value)");
    if (!state->AugAssign_type) return 0;
    state->AnnAssign_type = make_type(state, "AnnAssign", state->stmt_type,
                                      AnnAssign_fields, 4,
        "AnnAssign(expr target, expr annotation, expr? value, int simple)");
    if (!state->AnnAssign_type) return 0;
    if (PyObject_SetAttr(state->AnnAssign_type, state->value, Py_None) == -1)
        return 0;
    state->For_type = make_type(state, "For", state->stmt_type, For_fields, 5,
        "For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)");
    if (!state->For_type) return 0;
    if (PyObject_SetAttr(state->For_type, state->type_comment, Py_None) == -1)
        return 0;
    state->AsyncFor_type = make_type(state, "AsyncFor", state->stmt_type,
                                     AsyncFor_fields, 5,
        "AsyncFor(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)");
    if (!state->AsyncFor_type) return 0;
    if (PyObject_SetAttr(state->AsyncFor_type, state->type_comment, Py_None) ==
        -1)
        return 0;
    state->While_type = make_type(state, "While", state->stmt_type,
                                  While_fields, 3,
        "While(expr test, stmt* body, stmt* orelse)");
    if (!state->While_type) return 0;
    state->If_type = make_type(state, "If", state->stmt_type, If_fields, 3,
        "If(expr test, stmt* body, stmt* orelse)");
    if (!state->If_type) return 0;
    state->With_type = make_type(state, "With", state->stmt_type, With_fields,
                                 3,
        "With(withitem* items, stmt* body, string? type_comment)");
    if (!state->With_type) return 0;
    if (PyObject_SetAttr(state->With_type, state->type_comment, Py_None) == -1)
        return 0;
    state->AsyncWith_type = make_type(state, "AsyncWith", state->stmt_type,
                                      AsyncWith_fields, 3,
        "AsyncWith(withitem* items, stmt* body, string? type_comment)");
    if (!state->AsyncWith_type) return 0;
    if (PyObject_SetAttr(state->AsyncWith_type, state->type_comment, Py_None)
        == -1)
        return 0;
    state->Match_type = make_type(state, "Match", state->stmt_type,
                                  Match_fields, 2,
        "Match(expr subject, match_case* cases)");
    if (!state->Match_type) return 0;
    state->Raise_type = make_type(state, "Raise", state->stmt_type,
                                  Raise_fields, 2,
        "Raise(expr? exc, expr? cause)");
    if (!state->Raise_type) return 0;
    if (PyObject_SetAttr(state->Raise_type, state->exc, Py_None) == -1)
        return 0;
    if (PyObject_SetAttr(state->Raise_type, state->cause, Py_None) == -1)
        return 0;
    state->Try_type = make_type(state, "Try", state->stmt_type, Try_fields, 4,
        "Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)");
    if (!state->Try_type) return 0;
    state->TryStar_type = make_type(state, "TryStar", state->stmt_type,
                                    TryStar_fields, 4,
        "TryStar(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)");
    if (!state->TryStar_type) return 0;
    state->Assert_type = make_type(state, "Assert", state->stmt_type,
                                   Assert_fields, 2,
        "Assert(expr test, expr? msg)");
    if (!state->Assert_type) return 0;
    if (PyObject_SetAttr(state->Assert_type, state->msg, Py_None) == -1)
        return 0;
    state->Import_type = make_type(state, "Import", state->stmt_type,
                                   Import_fields, 1,
        "Import(alias* names)");
    if (!state->Import_type) return 0;
    state->ImportFrom_type = make_type(state, "ImportFrom", state->stmt_type,
                                       ImportFrom_fields, 3,
        "ImportFrom(identifier? module, alias* names, int? level)");
    if (!state->ImportFrom_type) return 0;
    if (PyObject_SetAttr(state->ImportFrom_type, state->module, Py_None) == -1)
        return 0;
    if (PyObject_SetAttr(state->ImportFrom_type, state->level, Py_None) == -1)
        return 0;
    state->Global_type = make_type(state, "Global", state->stmt_type,
                                   Global_fields, 1,
        "Global(identifier* names)");
    if (!state->Global_type) return 0;
    state->Nonlocal_type = make_type(state, "Nonlocal", state->stmt_type,
                                     Nonlocal_fields, 1,
        "Nonlocal(identifier* names)");
    if (!state->Nonlocal_type) return 0;
    state->Expr_type = make_type(state, "Expr", state->stmt_type, Expr_fields,
                                 1,
        "Expr(expr value)");
    if (!state->Expr_type) return 0;
    state->Pass_type = make_type(state, "Pass", state->stmt_type, NULL, 0,
        "Pass");
    if (!state->Pass_type) return 0;
    state->Break_type = make_type(state, "Break", state->stmt_type, NULL, 0,
        "Break");
    if (!state->Break_type) return 0;
    state->Continue_type = make_type(state, "Continue", state->stmt_type, NULL,
                                     0,
        "Continue");
    if (!state->Continue_type) return 0;
    state->expr_type = make_type(state, "expr", state->AST_type, NULL, 0,
        "expr = BoolOp(boolop op, expr* values)\n"
        "     | NamedExpr(expr target, expr value)\n"
        "     | BinOp(expr left, operator op, expr right)\n"
        "     | UnaryOp(unaryop op, expr operand)\n"
        "     | Lambda(arguments args, expr body)\n"
        "     | IfExp(expr test, expr body, expr orelse)\n"
        "     | Dict(expr* keys, expr* values)\n"
        "     | Set(expr* elts)\n"
        "     | ListComp(expr elt, comprehension* generators)\n"
        "     | SetComp(expr elt, comprehension* generators)\n"
        "     | DictComp(expr key, expr value, comprehension* generators)\n"
        "     | GeneratorExp(expr elt, comprehension* generators)\n"
        "     | Await(expr value)\n"
        "     | Yield(expr? value)\n"
        "     | YieldFrom(expr value)\n"
        "     | Compare(expr left, cmpop* ops, expr* comparators)\n"
        "     | Call(expr func, expr* args, keyword* keywords)\n"
        "     | FormattedValue(expr value, int conversion, expr? format_spec)\n"
        "     | JoinedStr(expr* values)\n"
        "     | Constant(constant value, string? kind)\n"
        "     | Attribute(expr value, identifier attr, expr_context ctx)\n"
        "     | Subscript(expr value, expr slice, expr_context ctx)\n"
        "     | Starred(expr value, expr_context ctx)\n"
        "     | Name(identifier id, expr_context ctx)\n"
        "     | List(expr* elts, expr_context ctx)\n"
        "     | Tuple(expr* elts, expr_context ctx)\n"
        "     | Slice(expr? lower, expr? upper, expr? step)");
    if (!state->expr_type) return 0;
    if (!add_attributes(state, state->expr_type, expr_attributes, 4)) return 0;
    if (PyObject_SetAttr(state->expr_type, state->end_lineno, Py_None) == -1)
        return 0;
    if (PyObject_SetAttr(state->expr_type, state->end_col_offset, Py_None) ==
        -1)
        return 0;
    state->BoolOp_type = make_type(state, "BoolOp", state->expr_type,
                                   BoolOp_fields, 2,
        "BoolOp(boolop op, expr* values)");
    if (!state->BoolOp_type) return 0;
    state->NamedExpr_type = make_type(state, "NamedExpr", state->expr_type,
                                      NamedExpr_fields, 2,
        "NamedExpr(expr target, expr value)");
    if (!state->NamedExpr_type) return 0;
    state->BinOp_type = make_type(state, "BinOp", state->expr_type,
                                  BinOp_fields, 3,
        "BinOp(expr left, operator op, expr right)");
    if (!state->BinOp_type) return 0;
    state->UnaryOp_type = make_type(state, "UnaryOp", state->expr_type,
                                    UnaryOp_fields, 2,
        "UnaryOp(unaryop op, expr operand)");
    if (!state->UnaryOp_type) return 0;
    state->Lambda_type = make_type(state, "Lambda", state->expr_type,
                                   Lambda_fields, 2,
        "Lambda(arguments args, expr body)");
    if (!state->Lambda_type) return 0;
    state->IfExp_type = make_type(state, "IfExp", state->expr_type,
                                  IfExp_fields, 3,
        "IfExp(expr test, expr body, expr orelse)");
    if (!state->IfExp_type) return 0;
    state->Dict_type = make_type(state, "Dict", state->expr_type, Dict_fields,
                                 2,
        "Dict(expr* keys, expr* values)");
    if (!state->Dict_type) return 0;
    state->Set_type = make_type(state, "Set", state->expr_type, Set_fields, 1,
        "Set(expr* elts)");
    if (!state->Set_type) return 0;
    state->ListComp_type = make_type(state, "ListComp", state->expr_type,
                                     ListComp_fields, 2,
        "ListComp(expr elt, comprehension* generators)");
    if (!state->ListComp_type) return 0;
    state->SetComp_type = make_type(state, "SetComp", state->expr_type,
                                    SetComp_fields, 2,
        "SetComp(expr elt, comprehension* generators)");
    if (!state->SetComp_type) return 0;
    state->DictComp_type = make_type(state, "DictComp", state->expr_type,
                                     DictComp_fields, 3,
        "DictComp(expr key, expr value, comprehension* generators)");
    if (!state->DictComp_type) return 0;
    state->GeneratorExp_type = make_type(state, "GeneratorExp",
                                         state->expr_type, GeneratorExp_fields,
                                         2,
        "GeneratorExp(expr elt, comprehension* generators)");
    if (!state->GeneratorExp_type) return 0;
    state->Await_type = make_type(state, "Await", state->expr_type,
                                  Await_fields, 1,
        "Await(expr value)");
    if (!state->Await_type) return 0;
    state->Yield_type = make_type(state, "Yield", state->expr_type,
                                  Yield_fields, 1,
        "Yield(expr? value)");
    if (!state->Yield_type) return 0;
    if (PyObject_SetAttr(state->Yield_type, state->value, Py_None) == -1)
        return 0;
    state->YieldFrom_type = make_type(state, "YieldFrom", state->expr_type,
                                      YieldFrom_fields, 1,
        "YieldFrom(expr value)");
    if (!state->YieldFrom_type) return 0;
    state->Compare_type = make_type(state, "Compare", state->expr_type,
                                    Compare_fields, 3,
        "Compare(expr left, cmpop* ops, expr* comparators)");
    if (!state->Compare_type) return 0;
    state->Call_type = make_type(state, "Call", state->expr_type, Call_fields,
                                 3,
        "Call(expr func, expr* args, keyword* keywords)");
    if (!state->Call_type) return 0;
    state->FormattedValue_type = make_type(state, "FormattedValue",
                                           state->expr_type,
                                           FormattedValue_fields, 3,
        "FormattedValue(expr value, int conversion, expr? format_spec)");
    if (!state->FormattedValue_type) return 0;
    if (PyObject_SetAttr(state->FormattedValue_type, state->format_spec,
        Py_None) == -1)
        return 0;
    state->JoinedStr_type = make_type(state, "JoinedStr", state->expr_type,
                                      JoinedStr_fields, 1,
        "JoinedStr(expr* values)");
    if (!state->JoinedStr_type) return 0;
    state->Constant_type = make_type(state, "Constant", state->expr_type,
                                     Constant_fields, 2,
        "Constant(constant value, string? kind)");
    if (!state->Constant_type) return 0;
    if (PyObject_SetAttr(state->Constant_type, state->kind, Py_None) == -1)
        return 0;
    state->Attribute_type = make_type(state, "Attribute", state->expr_type,
                                      Attribute_fields, 3,
        "Attribute(expr value, identifier attr, expr_context ctx)");
    if (!state->Attribute_type) return 0;
    state->Subscript_type = make_type(state, "Subscript", state->expr_type,
                                      Subscript_fields, 3,
        "Subscript(expr value, expr slice, expr_context ctx)");
    if (!state->Subscript_type) return 0;
    state->Starred_type = make_type(state, "Starred", state->expr_type,
                                    Starred_fields, 2,
        "Starred(expr value, expr_context ctx)");
    if (!state->Starred_type) return 0;
    state->Name_type = make_type(state, "Name", state->expr_type, Name_fields,
                                 2,
        "Name(identifier id, expr_context ctx)");
    if (!state->Name_type) return 0;
    state->List_type = make_type(state, "List", state->expr_type, List_fields,
                                 2,
        "List(expr* elts, expr_context ctx)");
    if (!state->List_type) return 0;
    state->Tuple_type = make_type(state, "Tuple", state->expr_type,
                                  Tuple_fields, 2,
        "Tuple(expr* elts, expr_context ctx)");
    if (!state->Tuple_type) return 0;
    state->Slice_type = make_type(state, "Slice", state->expr_type,
                                  Slice_fields, 3,
        "Slice(expr? lower, expr? upper, expr? step)");
    if (!state->Slice_type) return 0;
    if (PyObject_SetAttr(state->Slice_type, state->lower, Py_None) == -1)
        return 0;
    if (PyObject_SetAttr(state->Slice_type, state->upper, Py_None) == -1)
        return 0;
    if (PyObject_SetAttr(state->Slice_type, state->step, Py_None) == -1)
        return 0;
    state->expr_context_type = make_type(state, "expr_context",
                                         state->AST_type, NULL, 0,
        "expr_context = Load | Store | Del");
    if (!state->expr_context_type) return 0;
    if (!add_attributes(state, state->expr_context_type, NULL, 0)) return 0;
    state->Load_type = make_type(state, "Load", state->expr_context_type, NULL,
                                 0,
        "Load");
    if (!state->Load_type) return 0;
    state->Load_singleton = PyType_GenericNew((PyTypeObject *)state->Load_type,
                                              NULL, NULL);
    if (!state->Load_singleton) return 0;
    state->Store_type = make_type(state, "Store", state->expr_context_type,
                                  NULL, 0,
        "Store");
    if (!state->Store_type) return 0;
    state->Store_singleton = PyType_GenericNew((PyTypeObject
                                               *)state->Store_type, NULL, NULL);
    if (!state->Store_singleton) return 0;
    state->Del_type = make_type(state, "Del", state->expr_context_type, NULL, 0,
        "Del");
    if (!state->Del_type) return 0;
    state->Del_singleton = PyType_GenericNew((PyTypeObject *)state->Del_type,
                                             NULL, NULL);
    if (!state->Del_singleton) return 0;
    state->boolop_type = make_type(state, "boolop", state->AST_type, NULL, 0,
        "boolop = And | Or");
    if (!state->boolop_type) return 0;
    if (!add_attributes(state, state->boolop_type, NULL, 0)) return 0;
    state->And_type = make_type(state, "And", state->boolop_type, NULL, 0,
        "And");
    if (!state->And_type) return 0;
    state->And_singleton = PyType_GenericNew((PyTypeObject *)state->And_type,
                                             NULL, NULL);
    if (!state->And_singleton) return 0;
    state->Or_type = make_type(state, "Or", state->boolop_type, NULL, 0,
        "Or");
    if (!state->Or_type) return 0;
    state->Or_singleton = PyType_GenericNew((PyTypeObject *)state->Or_type,
                                            NULL, NULL);
    if (!state->Or_singleton) return 0;
    state->operator_type = make_type(state, "operator", state->AST_type, NULL,
                                     0,
        "operator = Add | Sub | Mult | MatMult | Div | Mod | Pow | LShift | RShift | BitOr | BitXor | BitAnd | FloorDiv");
    if (!state->operator_type) return 0;
    if (!add_attributes(state, state->operator_type, NULL, 0)) return 0;
    state->Add_type = make_type(state, "Add", state->operator_type, NULL, 0,
        "Add");
    if (!state->Add_type) return 0;
    state->Add_singleton = PyType_GenericNew((PyTypeObject *)state->Add_type,
                                             NULL, NULL);
    if (!state->Add_singleton) return 0;
    state->Sub_type = make_type(state, "Sub", state->operator_type, NULL, 0,
        "Sub");
    if (!state->Sub_type) return 0;
    state->Sub_singleton = PyType_GenericNew((PyTypeObject *)state->Sub_type,
                                             NULL, NULL);
    if (!state->Sub_singleton) return 0;
    state->Mult_type = make_type(state, "Mult", state->operator_type, NULL, 0,
        "Mult");
    if (!state->Mult_type) return 0;
    state->Mult_singleton = PyType_GenericNew((PyTypeObject *)state->Mult_type,
                                              NULL, NULL);
    if (!state->Mult_singleton) return 0;
    state->MatMult_type = make_type(state, "MatMult", state->operator_type,
                                    NULL, 0,
        "MatMult");
    if (!state->MatMult_type) return 0;
    state->MatMult_singleton = PyType_GenericNew((PyTypeObject
                                                 *)state->MatMult_type, NULL,
                                                 NULL);
    if (!state->MatMult_singleton) return 0;
    state->Div_type = make_type(state, "Div", state->operator_type, NULL, 0,
        "Div");
    if (!state->Div_type) return 0;
    state->Div_singleton = PyType_GenericNew((PyTypeObject *)state->Div_type,
                                             NULL, NULL);
    if (!state->Div_singleton) return 0;
    state->Mod_type = make_type(state, "Mod", state->operator_type, NULL, 0,
        "Mod");
    if (!state->Mod_type) return 0;
    state->Mod_singleton = PyType_GenericNew((PyTypeObject *)state->Mod_type,
                                             NULL, NULL);
    if (!state->Mod_singleton) return 0;
    state->Pow_type = make_type(state, "Pow", state->operator_type, NULL, 0,
        "Pow");
    if (!state->Pow_type) return 0;
    state->Pow_singleton = PyType_GenericNew((PyTypeObject *)state->Pow_type,
                                             NULL, NULL);
    if (!state->Pow_singleton) return 0;
    state->LShift_type = make_type(state, "LShift", state->operator_type, NULL,
                                   0,
        "LShift");
    if (!state->LShift_type) return 0;
    state->LShift_singleton = PyType_GenericNew((PyTypeObject
                                                *)state->LShift_type, NULL,
                                                NULL);
    if (!state->LShift_singleton) return 0;
    state->RShift_type = make_type(state, "RShift", state->operator_type, NULL,
                                   0,
        "RShift");
    if (!state->RShift_type) return 0;
    state->RShift_singleton = PyType_GenericNew((PyTypeObject
                                                *)state->RShift_type, NULL,
                                                NULL);
    if (!state->RShift_singleton) return 0;
    state->BitOr_type = make_type(state, "BitOr", state->operator_type, NULL, 0,
        "BitOr");
    if (!state->BitOr_type) return 0;
    state->BitOr_singleton = PyType_GenericNew((PyTypeObject
                                               *)state->BitOr_type, NULL, NULL);
    if (!state->BitOr_singleton) return 0;
    state->BitXor_type = make_type(state, "BitXor", state->operator_type, NULL,
                                   0,
        "BitXor");
    if (!state->BitXor_type) return 0;
    state->BitXor_singleton = PyType_GenericNew((PyTypeObject
                                                *)state->BitXor_type, NULL,
                                                NULL);
    if (!state->BitXor_singleton) return 0;
    state->BitAnd_type = make_type(state, "BitAnd", state->operator_type, NULL,
                                   0,
        "BitAnd");
    if (!state->BitAnd_type) return 0;
    state->BitAnd_singleton = PyType_GenericNew((PyTypeObject
                                                *)state->BitAnd_type, NULL,
                                                NULL);
    if (!state->BitAnd_singleton) return 0;
    state->FloorDiv_type = make_type(state, "FloorDiv", state->operator_type,
                                     NULL, 0,
        "FloorDiv");
    if (!state->FloorDiv_type) return 0;
    state->FloorDiv_singleton = PyType_GenericNew((PyTypeObject
                                                  *)state->FloorDiv_type, NULL,
                                                  NULL);
    if (!state->FloorDiv_singleton) return 0;
    state->unaryop_type = make_type(state, "unaryop", state->AST_type, NULL, 0,
        "unaryop = Invert | Not | UAdd | USub");
    if (!state->unaryop_type) return 0;
    if (!add_attributes(state, state->unaryop_type, NULL, 0)) return 0;
    state->Invert_type = make_type(state, "Invert", state->unaryop_type, NULL,
                                   0,
        "Invert");
    if (!state->Invert_type) return 0;
    state->Invert_singleton = PyType_GenericNew((PyTypeObject
                                                *)state->Invert_type, NULL,
                                                NULL);
    if (!state->Invert_singleton) return 0;
    state->Not_type = make_type(state, "Not", state->unaryop_type, NULL, 0,
        "Not");
    if (!state->Not_type) return 0;
    state->Not_singleton = PyType_GenericNew((PyTypeObject *)state->Not_type,
                                             NULL, NULL);
    if (!state->Not_singleton) return 0;
    state->UAdd_type = make_type(state, "UAdd", state->unaryop_type, NULL, 0,
        "UAdd");
    if (!state->UAdd_type) return 0;
    state->UAdd_singleton = PyType_GenericNew((PyTypeObject *)state->UAdd_type,
                                              NULL, NULL);
    if (!state->UAdd_singleton) return 0;
    state->USub_type = make_type(state, "USub", state->unaryop_type, NULL, 0,
        "USub");
    if (!state->USub_type) return 0;
    state->USub_singleton = PyType_GenericNew((PyTypeObject *)state->USub_type,
                                              NULL, NULL);
    if (!state->USub_singleton) return 0;
    state->cmpop_type = make_type(state, "cmpop", state->AST_type, NULL, 0,
        "cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn");
    if (!state->cmpop_type) return 0;
    if (!add_attributes(state, state->cmpop_type, NULL, 0)) return 0;
    state->Eq_type = make_type(state, "Eq", state->cmpop_type, NULL, 0,
        "Eq");
    if (!state->Eq_type) return 0;
    state->Eq_singleton = PyType_GenericNew((PyTypeObject *)state->Eq_type,
                                            NULL, NULL);
    if (!state->Eq_singleton) return 0;
    state->NotEq_type = make_type(state, "NotEq", state->cmpop_type, NULL, 0,
        "NotEq");
    if (!state->NotEq_type) return 0;
    state->NotEq_singleton = PyType_GenericNew((PyTypeObject
                                               *)state->NotEq_type, NULL, NULL);
    if (!state->NotEq_singleton) return 0;
    state->Lt_type = make_type(state, "Lt", state->cmpop_type, NULL, 0,
        "Lt");
    if (!state->Lt_type) return 0;
    state->Lt_singleton = PyType_GenericNew((PyTypeObject *)state->Lt_type,
                                            NULL, NULL);
    if (!state->Lt_singleton) return 0;
    state->LtE_type = make_type(state, "LtE", state->cmpop_type, NULL, 0,
        "LtE");
    if (!state->LtE_type) return 0;
    state->LtE_singleton = PyType_GenericNew((PyTypeObject *)state->LtE_type,
                                             NULL, NULL);
    if (!state->LtE_singleton) return 0;
    state->Gt_type = make_type(state, "Gt", state->cmpop_type, NULL, 0,
        "Gt");
    if (!state->Gt_type) return 0;
    state->Gt_singleton = PyType_GenericNew((PyTypeObject *)state->Gt_type,
                                            NULL, NULL);
    if (!state->Gt_singleton) return 0;
    state->GtE_type = make_type(state, "GtE", state->cmpop_type, NULL, 0,
        "GtE");
    if (!state->GtE_type) return 0;
    state->GtE_singleton = PyType_GenericNew((PyTypeObject *)state->GtE_type,
                                             NULL, NULL);
    if (!state->GtE_singleton) return 0;
    state->Is_type = make_type(state, "Is", state->cmpop_type, NULL, 0,
        "Is");
    if (!state->Is_type) return 0;
    state->Is_singleton = PyType_GenericNew((PyTypeObject *)state->Is_type,
                                            NULL, NULL);
    if (!state->Is_singleton) return 0;
    state->IsNot_type = make_type(state, "IsNot", state->cmpop_type, NULL, 0,
        "IsNot");
    if (!state->IsNot_type) return 0;
    state->IsNot_singleton = PyType_GenericNew((PyTypeObject
                                               *)state->IsNot_type, NULL, NULL);
    if (!state->IsNot_singleton) return 0;
    state->In_type = make_type(state, "In", state->cmpop_type, NULL, 0,
        "In");
    if (!state->In_type) return 0;
    state->In_singleton = PyType_GenericNew((PyTypeObject *)state->In_type,
                                            NULL, NULL);
    if (!state->In_singleton) return 0;
    state->NotIn_type = make_type(state, "NotIn", state->cmpop_type, NULL, 0,
        "NotIn");
    if (!state->NotIn_type) return 0;
    state->NotIn_singleton = PyType_GenericNew((PyTypeObject
                                               *)state->NotIn_type, NULL, NULL);
    if (!state->NotIn_singleton) return 0;
    state->comprehension_type = make_type(state, "comprehension",
                                          state->AST_type,
                                          comprehension_fields, 4,
        "comprehension(expr target, expr iter, expr* ifs, int is_async)");
    if (!state->comprehension_type) return 0;
    if (!add_attributes(state, state->comprehension_type, NULL, 0)) return 0;
    state->excepthandler_type = make_type(state, "excepthandler",
                                          state->AST_type, NULL, 0,
        "excepthandler = ExceptHandler(expr? type, identifier? name, stmt* body)");
    if (!state->excepthandler_type) return 0;
    if (!add_attributes(state, state->excepthandler_type,
        excepthandler_attributes, 4)) return 0;
    if (PyObject_SetAttr(state->excepthandler_type, state->end_lineno, Py_None)
        == -1)
        return 0;
    if (PyObject_SetAttr(state->excepthandler_type, state->end_col_offset,
        Py_None) == -1)
        return 0;
    state->ExceptHandler_type = make_type(state, "ExceptHandler",
                                          state->excepthandler_type,
                                          ExceptHandler_fields, 3,
        "ExceptHandler(expr? type, identifier? name, stmt* body)");
    if (!state->ExceptHandler_type) return 0;
    if (PyObject_SetAttr(state->ExceptHandler_type, state->type, Py_None) == -1)
        return 0;
    if (PyObject_SetAttr(state->ExceptHandler_type, state->name, Py_None) == -1)
        return 0;
    state->arguments_type = make_type(state, "arguments", state->AST_type,
                                      arguments_fields, 7,
        "arguments(arg* posonlyargs, arg* args, arg? vararg, arg* kwonlyargs, expr* kw_defaults, arg? kwarg, expr* defaults)");
    if (!state->arguments_type) return 0;
    if (!add_attributes(state, state->arguments_type, NULL, 0)) return 0;
    if (PyObject_SetAttr(state->arguments_type, state->vararg, Py_None) == -1)
        return 0;
    if (PyObject_SetAttr(state->arguments_type, state->kwarg, Py_None) == -1)
        return 0;
    state->arg_type = make_type(state, "arg", state->AST_type, arg_fields, 3,
        "arg(identifier arg, expr? annotation, string? type_comment)");
    if (!state->arg_type) return 0;
    if (!add_attributes(state, state->arg_type, arg_attributes, 4)) return 0;
    if (PyObject_SetAttr(state->arg_type, state->annotation, Py_None) == -1)
        return 0;
    if (PyObject_SetAttr(state->arg_type, state->type_comment, Py_None) == -1)
        return 0;
    if (PyObject_SetAttr(state->arg_type, state->end_lineno, Py_None) == -1)
        return 0;
    if (PyObject_SetAttr(state->arg_type, state->end_col_offset, Py_None) == -1)
        return 0;
    state->keyword_type = make_type(state, "keyword", state->AST_type,
                                    keyword_fields, 2,
        "keyword(identifier? arg, expr value)");
    if (!state->keyword_type) return 0;
    if (!add_attributes(state, state->keyword_type, keyword_attributes, 4))
        return 0;
    if (PyObject_SetAttr(state->keyword_type, state->arg, Py_None) == -1)
        return 0;
    if (PyObject_SetAttr(state->keyword_type, state->end_lineno, Py_None) == -1)
        return 0;
    if (PyObject_SetAttr(state->keyword_type, state->end_col_offset, Py_None)
        == -1)
        return 0;
    state->alias_type = make_type(state, "alias", state->AST_type,
                                  alias_fields, 2,
        "alias(identifier name, identifier? asname)");
    if (!state->alias_type) return 0;
    if (!add_attributes(state, state->alias_type, alias_attributes, 4)) return
        0;
    if (PyObject_SetAttr(state->alias_type, state->asname, Py_None) == -1)
        return 0;
    if (PyObject_SetAttr(state->alias_type, state->end_lineno, Py_None) == -1)
        return 0;
    if (PyObject_SetAttr(state->alias_type, state->end_col_offset, Py_None) ==
        -1)
        return 0;
    state->withitem_type = make_type(state, "withitem", state->AST_type,
                                     withitem_fields, 2,
        "withitem(expr context_expr, expr? optional_vars)");
    if (!state->withitem_type) return 0;
    if (!add_attributes(state, state->withitem_type, NULL, 0)) return 0;
    if (PyObject_SetAttr(state->withitem_type, state->optional_vars, Py_None)
        == -1)
        return 0;
    state->match_case_type = make_type(state, "match_case", state->AST_type,
                                       match_case_fields, 3,
        "match_case(pattern pattern, expr? guard, stmt* body)");
    if (!state->match_case_type) return 0;
    if (!add_attributes(state, state->match_case_type, NULL, 0)) return 0;
    if (PyObject_SetAttr(state->match_case_type, state->guard, Py_None) == -1)
        return 0;
    state->pattern_type = make_type(state, "pattern", state->AST_type, NULL, 0,
        "pattern = MatchValue(expr value)\n"
        "        | MatchSingleton(constant value)\n"
        "        | MatchSequence(pattern* patterns)\n"
        "        | MatchMapping(expr* keys, pattern* patterns, identifier? rest)\n"
        "        | MatchClass(expr cls, pattern* patterns, identifier* kwd_attrs, pattern* kwd_patterns)\n"
        "        | MatchStar(identifier? name)\n"
        "        | MatchAs(pattern? pattern, identifier? name)\n"
        "        | MatchOr(pattern* patterns)");
    if (!state->pattern_type) return 0;
    if (!add_attributes(state, state->pattern_type, pattern_attributes, 4))
        return 0;
    state->MatchValue_type = make_type(state, "MatchValue",
                                       state->pattern_type, MatchValue_fields,
                                       1,
        "MatchValue(expr value)");
    if (!state->MatchValue_type) return 0;
    state->MatchSingleton_type = make_type(state, "MatchSingleton",
                                           state->pattern_type,
                                           MatchSingleton_fields, 1,
        "MatchSingleton(constant value)");
    if (!state->MatchSingleton_type) return 0;
    state->MatchSequence_type = make_type(state, "MatchSequence",
                                          state->pattern_type,
                                          MatchSequence_fields, 1,
        "MatchSequence(pattern* patterns)");
    if (!state->MatchSequence_type) return 0;
    state->MatchMapping_type = make_type(state, "MatchMapping",
                                         state->pattern_type,
                                         MatchMapping_fields, 3,
        "MatchMapping(expr* keys, pattern* patterns, identifier? rest)");
    if (!state->MatchMapping_type) return 0;
    if (PyObject_SetAttr(state->MatchMapping_type, state->rest, Py_None) == -1)
        return 0;
    state->MatchClass_type = make_type(state, "MatchClass",
                                       state->pattern_type, MatchClass_fields,
                                       4,
        "MatchClass(expr cls, pattern* patterns, identifier* kwd_attrs, pattern* kwd_patterns)");
    if (!state->MatchClass_type) return 0;
    state->MatchStar_type = make_type(state, "MatchStar", state->pattern_type,
                                      MatchStar_fields, 1,
        "MatchStar(identifier? name)");
    if (!state->MatchStar_type) return 0;
    if (PyObject_SetAttr(state->MatchStar_type, state->name, Py_None) == -1)
        return 0;
    state->MatchAs_type = make_type(state, "MatchAs", state->pattern_type,
                                    MatchAs_fields, 2,
        "MatchAs(pattern? pattern, identifier? name)");
    if (!state->MatchAs_type) return 0;
    if (PyObject_SetAttr(state->MatchAs_type, state->pattern, Py_None) == -1)
        return 0;
    if (PyObject_SetAttr(state->MatchAs_type, state->name, Py_None) == -1)
        return 0;
    state->MatchOr_type = make_type(state, "MatchOr", state->pattern_type,
                                    MatchOr_fields, 1,
        "MatchOr(pattern* patterns)");
    if (!state->MatchOr_type) return 0;
    state->type_ignore_type = make_type(state, "type_ignore", state->AST_type,
                                        NULL, 0,
        "type_ignore = TypeIgnore(int lineno, string tag)");
    if (!state->type_ignore_type) return 0;
    if (!add_attributes(state, state->type_ignore_type, NULL, 0)) return 0;
    state->TypeIgnore_type = make_type(state, "TypeIgnore",
                                       state->type_ignore_type,
                                       TypeIgnore_fields, 2,
        "TypeIgnore(int lineno, string tag)");
    if (!state->TypeIgnore_type) return 0;
    state->type_param_type = make_type(state, "type_param", state->AST_type,
                                       NULL, 0,
        "type_param = TypeVar(identifier name, expr? bound)\n"
        "           | ParamSpec(identifier name)\n"
        "           | TypeVarTuple(identifier name)");
    if (!state->type_param_type) return 0;
    if (!add_attributes(state, state->type_param_type, type_param_attributes,
        4)) return 0;
    if (PyObject_SetAttr(state->type_param_type, state->end_lineno, Py_None) ==
        -1)
        return 0;
    if (PyObject_SetAttr(state->type_param_type, state->end_col_offset,
        Py_None) == -1)
        return 0;
    state->TypeVar_type = make_type(state, "TypeVar", state->type_param_type,
                                    TypeVar_fields, 2,
        "TypeVar(identifier name, expr? bound)");
    if (!state->TypeVar_type) return 0;
    if (PyObject_SetAttr(state->TypeVar_type, state->bound, Py_None) == -1)
        return 0;
    state->ParamSpec_type = make_type(state, "ParamSpec",
                                      state->type_param_type, ParamSpec_fields,
                                      1,
        "ParamSpec(identifier name)");
    if (!state->ParamSpec_type) return 0;
    state->TypeVarTuple_type = make_type(state, "TypeVarTuple",
                                         state->type_param_type,
                                         TypeVarTuple_fields, 1,
        "TypeVarTuple(identifier name)");
    if (!state->TypeVarTuple_type) return 0;

    state->recursion_depth = 0;
    state->recursion_limit = 0;
    state->initialized = 1;
    return 1;
}

static int obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out,
                       PyArena* arena);
static int obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out,
                        PyArena* arena);
static int obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out,
                        PyArena* arena);
static int obj2ast_expr_context(struct ast_state *state, PyObject* obj,
                                expr_context_ty* out, PyArena* arena);
static int obj2ast_boolop(struct ast_state *state, PyObject* obj, boolop_ty*
                          out, PyArena* arena);
static int obj2ast_operator(struct ast_state *state, PyObject* obj,
                            operator_ty* out, PyArena* arena);
static int obj2ast_unaryop(struct ast_state *state, PyObject* obj, unaryop_ty*
                           out, PyArena* arena);
static int obj2ast_cmpop(struct ast_state *state, PyObject* obj, cmpop_ty* out,
                         PyArena* arena);
static int obj2ast_comprehension(struct ast_state *state, PyObject* obj,
                                 comprehension_ty* out, PyArena* arena);
static int obj2ast_excepthandler(struct ast_state *state, PyObject* obj,
                                 excepthandler_ty* out, PyArena* arena);
static int obj2ast_arguments(struct ast_state *state, PyObject* obj,
                             arguments_ty* out, PyArena* arena);
static int obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out,
                       PyArena* arena);
static int obj2ast_keyword(struct ast_state *state, PyObject* obj, keyword_ty*
                           out, PyArena* arena);
static int obj2ast_alias(struct ast_state *state, PyObject* obj, alias_ty* out,
                         PyArena* arena);
static int obj2ast_withitem(struct ast_state *state, PyObject* obj,
                            withitem_ty* out, PyArena* arena);
static int obj2ast_match_case(struct ast_state *state, PyObject* obj,
                              match_case_ty* out, PyArena* arena);
static int obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty*
                           out, PyArena* arena);
static int obj2ast_type_ignore(struct ast_state *state, PyObject* obj,
                               type_ignore_ty* out, PyArena* arena);
static int obj2ast_type_param(struct ast_state *state, PyObject* obj,
                              type_param_ty* out, PyArena* arena);

mod_ty
_PyAST_Module(asdl_stmt_seq * body, asdl_type_ignore_seq * type_ignores,
              PyArena *arena)
{
    mod_ty p;
    p = (mod_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Module_kind;
    p->v.Module.body = body;
    p->v.Module.type_ignores = type_ignores;
    return p;
}

mod_ty
_PyAST_Interactive(asdl_stmt_seq * body, PyArena *arena)
{
    mod_ty p;
    p = (mod_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Interactive_kind;
    p->v.Interactive.body = body;
    return p;
}

mod_ty
_PyAST_Expression(expr_ty body, PyArena *arena)
{
    mod_ty p;
    if (!body) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'body' is required for Expression");
        return NULL;
    }
    p = (mod_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Expression_kind;
    p->v.Expression.body = body;
    return p;
}

mod_ty
_PyAST_FunctionType(asdl_expr_seq * argtypes, expr_ty returns, PyArena *arena)
{
    mod_ty p;
    if (!returns) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'returns' is required for FunctionType");
        return NULL;
    }
    p = (mod_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = FunctionType_kind;
    p->v.FunctionType.argtypes = argtypes;
    p->v.FunctionType.returns = returns;
    return p;
}

stmt_ty
_PyAST_FunctionDef(identifier name, arguments_ty args, asdl_stmt_seq * body,
                   asdl_expr_seq * decorator_list, expr_ty returns, string
                   type_comment, asdl_type_param_seq * type_params, int lineno,
                   int col_offset, int end_lineno, int end_col_offset, PyArena
                   *arena)
{
    stmt_ty p;
    if (!name) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'name' is required for FunctionDef");
        return NULL;
    }
    if (!args) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'args' is required for FunctionDef");
        return NULL;
    }
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = FunctionDef_kind;
    p->v.FunctionDef.name = name;
    p->v.FunctionDef.args = args;
    p->v.FunctionDef.body = body;
    p->v.FunctionDef.decorator_list = decorator_list;
    p->v.FunctionDef.returns = returns;
    p->v.FunctionDef.type_comment = type_comment;
    p->v.FunctionDef.type_params = type_params;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_AsyncFunctionDef(identifier name, arguments_ty args, asdl_stmt_seq *
                        body, asdl_expr_seq * decorator_list, expr_ty returns,
                        string type_comment, asdl_type_param_seq * type_params,
                        int lineno, int col_offset, int end_lineno, int
                        end_col_offset, PyArena *arena)
{
    stmt_ty p;
    if (!name) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'name' is required for AsyncFunctionDef");
        return NULL;
    }
    if (!args) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'args' is required for AsyncFunctionDef");
        return NULL;
    }
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = AsyncFunctionDef_kind;
    p->v.AsyncFunctionDef.name = name;
    p->v.AsyncFunctionDef.args = args;
    p->v.AsyncFunctionDef.body = body;
    p->v.AsyncFunctionDef.decorator_list = decorator_list;
    p->v.AsyncFunctionDef.returns = returns;
    p->v.AsyncFunctionDef.type_comment = type_comment;
    p->v.AsyncFunctionDef.type_params = type_params;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_ClassDef(identifier name, asdl_expr_seq * bases, asdl_keyword_seq *
                keywords, asdl_stmt_seq * body, asdl_expr_seq * decorator_list,
                asdl_type_param_seq * type_params, int lineno, int col_offset,
                int end_lineno, int end_col_offset, PyArena *arena)
{
    stmt_ty p;
    if (!name) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'name' is required for ClassDef");
        return NULL;
    }
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = ClassDef_kind;
    p->v.ClassDef.name = name;
    p->v.ClassDef.bases = bases;
    p->v.ClassDef.keywords = keywords;
    p->v.ClassDef.body = body;
    p->v.ClassDef.decorator_list = decorator_list;
    p->v.ClassDef.type_params = type_params;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_Return(expr_ty value, int lineno, int col_offset, int end_lineno, int
              end_col_offset, PyArena *arena)
{
    stmt_ty p;
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Return_kind;
    p->v.Return.value = value;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_Delete(asdl_expr_seq * targets, int lineno, int col_offset, int
              end_lineno, int end_col_offset, PyArena *arena)
{
    stmt_ty p;
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Delete_kind;
    p->v.Delete.targets = targets;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_Assign(asdl_expr_seq * targets, expr_ty value, string type_comment, int
              lineno, int col_offset, int end_lineno, int end_col_offset,
              PyArena *arena)
{
    stmt_ty p;
    if (!value) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'value' is required for Assign");
        return NULL;
    }
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Assign_kind;
    p->v.Assign.targets = targets;
    p->v.Assign.value = value;
    p->v.Assign.type_comment = type_comment;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_TypeAlias(expr_ty name, asdl_type_param_seq * type_params, expr_ty
                 value, int lineno, int col_offset, int end_lineno, int
                 end_col_offset, PyArena *arena)
{
    stmt_ty p;
    if (!name) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'name' is required for TypeAlias");
        return NULL;
    }
    if (!value) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'value' is required for TypeAlias");
        return NULL;
    }
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = TypeAlias_kind;
    p->v.TypeAlias.name = name;
    p->v.TypeAlias.type_params = type_params;
    p->v.TypeAlias.value = value;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno, int
                 col_offset, int end_lineno, int end_col_offset, PyArena *arena)
{
    stmt_ty p;
    if (!target) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'target' is required for AugAssign");
        return NULL;
    }
    if (!op) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'op' is required for AugAssign");
        return NULL;
    }
    if (!value) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'value' is required for AugAssign");
        return NULL;
    }
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = AugAssign_kind;
    p->v.AugAssign.target = target;
    p->v.AugAssign.op = op;
    p->v.AugAssign.value = value;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int simple,
                 int lineno, int col_offset, int end_lineno, int
                 end_col_offset, PyArena *arena)
{
    stmt_ty p;
    if (!target) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'target' is required for AnnAssign");
        return NULL;
    }
    if (!annotation) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'annotation' is required for AnnAssign");
        return NULL;
    }
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = AnnAssign_kind;
    p->v.AnnAssign.target = target;
    p->v.AnnAssign.annotation = annotation;
    p->v.AnnAssign.value = value;
    p->v.AnnAssign.simple = simple;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_For(expr_ty target, expr_ty iter, asdl_stmt_seq * body, asdl_stmt_seq *
           orelse, string type_comment, int lineno, int col_offset, int
           end_lineno, int end_col_offset, PyArena *arena)
{
    stmt_ty p;
    if (!target) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'target' is required for For");
        return NULL;
    }
    if (!iter) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'iter' is required for For");
        return NULL;
    }
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = For_kind;
    p->v.For.target = target;
    p->v.For.iter = iter;
    p->v.For.body = body;
    p->v.For.orelse = orelse;
    p->v.For.type_comment = type_comment;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_AsyncFor(expr_ty target, expr_ty iter, asdl_stmt_seq * body,
                asdl_stmt_seq * orelse, string type_comment, int lineno, int
                col_offset, int end_lineno, int end_col_offset, PyArena *arena)
{
    stmt_ty p;
    if (!target) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'target' is required for AsyncFor");
        return NULL;
    }
    if (!iter) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'iter' is required for AsyncFor");
        return NULL;
    }
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = AsyncFor_kind;
    p->v.AsyncFor.target = target;
    p->v.AsyncFor.iter = iter;
    p->v.AsyncFor.body = body;
    p->v.AsyncFor.orelse = orelse;
    p->v.AsyncFor.type_comment = type_comment;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_While(expr_ty test, asdl_stmt_seq * body, asdl_stmt_seq * orelse, int
             lineno, int col_offset, int end_lineno, int end_col_offset,
             PyArena *arena)
{
    stmt_ty p;
    if (!test) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'test' is required for While");
        return NULL;
    }
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = While_kind;
    p->v.While.test = test;
    p->v.While.body = body;
    p->v.While.orelse = orelse;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_If(expr_ty test, asdl_stmt_seq * body, asdl_stmt_seq * orelse, int
          lineno, int col_offset, int end_lineno, int end_col_offset, PyArena
          *arena)
{
    stmt_ty p;
    if (!test) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'test' is required for If");
        return NULL;
    }
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = If_kind;
    p->v.If.test = test;
    p->v.If.body = body;
    p->v.If.orelse = orelse;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_With(asdl_withitem_seq * items, asdl_stmt_seq * body, string
            type_comment, int lineno, int col_offset, int end_lineno, int
            end_col_offset, PyArena *arena)
{
    stmt_ty p;
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = With_kind;
    p->v.With.items = items;
    p->v.With.body = body;
    p->v.With.type_comment = type_comment;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_AsyncWith(asdl_withitem_seq * items, asdl_stmt_seq * body, string
                 type_comment, int lineno, int col_offset, int end_lineno, int
                 end_col_offset, PyArena *arena)
{
    stmt_ty p;
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = AsyncWith_kind;
    p->v.AsyncWith.items = items;
    p->v.AsyncWith.body = body;
    p->v.AsyncWith.type_comment = type_comment;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_Match(expr_ty subject, asdl_match_case_seq * cases, int lineno, int
             col_offset, int end_lineno, int end_col_offset, PyArena *arena)
{
    stmt_ty p;
    if (!subject) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'subject' is required for Match");
        return NULL;
    }
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Match_kind;
    p->v.Match.subject = subject;
    p->v.Match.cases = cases;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset, int
             end_lineno, int end_col_offset, PyArena *arena)
{
    stmt_ty p;
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Raise_kind;
    p->v.Raise.exc = exc;
    p->v.Raise.cause = cause;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_Try(asdl_stmt_seq * body, asdl_excepthandler_seq * handlers,
           asdl_stmt_seq * orelse, asdl_stmt_seq * finalbody, int lineno, int
           col_offset, int end_lineno, int end_col_offset, PyArena *arena)
{
    stmt_ty p;
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Try_kind;
    p->v.Try.body = body;
    p->v.Try.handlers = handlers;
    p->v.Try.orelse = orelse;
    p->v.Try.finalbody = finalbody;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_TryStar(asdl_stmt_seq * body, asdl_excepthandler_seq * handlers,
               asdl_stmt_seq * orelse, asdl_stmt_seq * finalbody, int lineno,
               int col_offset, int end_lineno, int end_col_offset, PyArena
               *arena)
{
    stmt_ty p;
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = TryStar_kind;
    p->v.TryStar.body = body;
    p->v.TryStar.handlers = handlers;
    p->v.TryStar.orelse = orelse;
    p->v.TryStar.finalbody = finalbody;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, int
              end_lineno, int end_col_offset, PyArena *arena)
{
    stmt_ty p;
    if (!test) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'test' is required for Assert");
        return NULL;
    }
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Assert_kind;
    p->v.Assert.test = test;
    p->v.Assert.msg = msg;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_Import(asdl_alias_seq * names, int lineno, int col_offset, int
              end_lineno, int end_col_offset, PyArena *arena)
{
    stmt_ty p;
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Import_kind;
    p->v.Import.names = names;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_ImportFrom(identifier module, asdl_alias_seq * names, int level, int
                  lineno, int col_offset, int end_lineno, int end_col_offset,
                  PyArena *arena)
{
    stmt_ty p;
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = ImportFrom_kind;
    p->v.ImportFrom.module = module;
    p->v.ImportFrom.names = names;
    p->v.ImportFrom.level = level;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_Global(asdl_identifier_seq * names, int lineno, int col_offset, int
              end_lineno, int end_col_offset, PyArena *arena)
{
    stmt_ty p;
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Global_kind;
    p->v.Global.names = names;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_Nonlocal(asdl_identifier_seq * names, int lineno, int col_offset, int
                end_lineno, int end_col_offset, PyArena *arena)
{
    stmt_ty p;
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Nonlocal_kind;
    p->v.Nonlocal.names = names;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_Expr(expr_ty value, int lineno, int col_offset, int end_lineno, int
            end_col_offset, PyArena *arena)
{
    stmt_ty p;
    if (!value) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'value' is required for Expr");
        return NULL;
    }
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Expr_kind;
    p->v.Expr.value = value;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_Pass(int lineno, int col_offset, int end_lineno, int end_col_offset,
            PyArena *arena)
{
    stmt_ty p;
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Pass_kind;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_Break(int lineno, int col_offset, int end_lineno, int end_col_offset,
             PyArena *arena)
{
    stmt_ty p;
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Break_kind;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

stmt_ty
_PyAST_Continue(int lineno, int col_offset, int end_lineno, int end_col_offset,
                PyArena *arena)
{
    stmt_ty p;
    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Continue_kind;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_BoolOp(boolop_ty op, asdl_expr_seq * values, int lineno, int col_offset,
              int end_lineno, int end_col_offset, PyArena *arena)
{
    expr_ty p;
    if (!op) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'op' is required for BoolOp");
        return NULL;
    }
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = BoolOp_kind;
    p->v.BoolOp.op = op;
    p->v.BoolOp.values = values;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_NamedExpr(expr_ty target, expr_ty value, int lineno, int col_offset, int
                 end_lineno, int end_col_offset, PyArena *arena)
{
    expr_ty p;
    if (!target) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'target' is required for NamedExpr");
        return NULL;
    }
    if (!value) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'value' is required for NamedExpr");
        return NULL;
    }
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = NamedExpr_kind;
    p->v.NamedExpr.target = target;
    p->v.NamedExpr.value = value;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int
             col_offset, int end_lineno, int end_col_offset, PyArena *arena)
{
    expr_ty p;
    if (!left) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'left' is required for BinOp");
        return NULL;
    }
    if (!op) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'op' is required for BinOp");
        return NULL;
    }
    if (!right) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'right' is required for BinOp");
        return NULL;
    }
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = BinOp_kind;
    p->v.BinOp.left = left;
    p->v.BinOp.op = op;
    p->v.BinOp.right = right;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset, int
               end_lineno, int end_col_offset, PyArena *arena)
{
    expr_ty p;
    if (!op) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'op' is required for UnaryOp");
        return NULL;
    }
    if (!operand) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'operand' is required for UnaryOp");
        return NULL;
    }
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = UnaryOp_kind;
    p->v.UnaryOp.op = op;
    p->v.UnaryOp.operand = operand;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset, int
              end_lineno, int end_col_offset, PyArena *arena)
{
    expr_ty p;
    if (!args) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'args' is required for Lambda");
        return NULL;
    }
    if (!body) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'body' is required for Lambda");
        return NULL;
    }
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Lambda_kind;
    p->v.Lambda.args = args;
    p->v.Lambda.body = body;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int
             col_offset, int end_lineno, int end_col_offset, PyArena *arena)
{
    expr_ty p;
    if (!test) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'test' is required for IfExp");
        return NULL;
    }
    if (!body) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'body' is required for IfExp");
        return NULL;
    }
    if (!orelse) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'orelse' is required for IfExp");
        return NULL;
    }
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = IfExp_kind;
    p->v.IfExp.test = test;
    p->v.IfExp.body = body;
    p->v.IfExp.orelse = orelse;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_Dict(asdl_expr_seq * keys, asdl_expr_seq * values, int lineno, int
            col_offset, int end_lineno, int end_col_offset, PyArena *arena)
{
    expr_ty p;
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Dict_kind;
    p->v.Dict.keys = keys;
    p->v.Dict.values = values;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_Set(asdl_expr_seq * elts, int lineno, int col_offset, int end_lineno,
           int end_col_offset, PyArena *arena)
{
    expr_ty p;
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Set_kind;
    p->v.Set.elts = elts;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_ListComp(expr_ty elt, asdl_comprehension_seq * generators, int lineno,
                int col_offset, int end_lineno, int end_col_offset, PyArena
                *arena)
{
    expr_ty p;
    if (!elt) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'elt' is required for ListComp");
        return NULL;
    }
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = ListComp_kind;
    p->v.ListComp.elt = elt;
    p->v.ListComp.generators = generators;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_SetComp(expr_ty elt, asdl_comprehension_seq * generators, int lineno,
               int col_offset, int end_lineno, int end_col_offset, PyArena
               *arena)
{
    expr_ty p;
    if (!elt) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'elt' is required for SetComp");
        return NULL;
    }
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = SetComp_kind;
    p->v.SetComp.elt = elt;
    p->v.SetComp.generators = generators;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_DictComp(expr_ty key, expr_ty value, asdl_comprehension_seq *
                generators, int lineno, int col_offset, int end_lineno, int
                end_col_offset, PyArena *arena)
{
    expr_ty p;
    if (!key) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'key' is required for DictComp");
        return NULL;
    }
    if (!value) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'value' is required for DictComp");
        return NULL;
    }
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = DictComp_kind;
    p->v.DictComp.key = key;
    p->v.DictComp.value = value;
    p->v.DictComp.generators = generators;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_GeneratorExp(expr_ty elt, asdl_comprehension_seq * generators, int
                    lineno, int col_offset, int end_lineno, int end_col_offset,
                    PyArena *arena)
{
    expr_ty p;
    if (!elt) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'elt' is required for GeneratorExp");
        return NULL;
    }
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = GeneratorExp_kind;
    p->v.GeneratorExp.elt = elt;
    p->v.GeneratorExp.generators = generators;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_Await(expr_ty value, int lineno, int col_offset, int end_lineno, int
             end_col_offset, PyArena *arena)
{
    expr_ty p;
    if (!value) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'value' is required for Await");
        return NULL;
    }
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Await_kind;
    p->v.Await.value = value;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_Yield(expr_ty value, int lineno, int col_offset, int end_lineno, int
             end_col_offset, PyArena *arena)
{
    expr_ty p;
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Yield_kind;
    p->v.Yield.value = value;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_YieldFrom(expr_ty value, int lineno, int col_offset, int end_lineno, int
                 end_col_offset, PyArena *arena)
{
    expr_ty p;
    if (!value) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'value' is required for YieldFrom");
        return NULL;
    }
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = YieldFrom_kind;
    p->v.YieldFrom.value = value;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_Compare(expr_ty left, asdl_int_seq * ops, asdl_expr_seq * comparators,
               int lineno, int col_offset, int end_lineno, int end_col_offset,
               PyArena *arena)
{
    expr_ty p;
    if (!left) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'left' is required for Compare");
        return NULL;
    }
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Compare_kind;
    p->v.Compare.left = left;
    p->v.Compare.ops = ops;
    p->v.Compare.comparators = comparators;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_Call(expr_ty func, asdl_expr_seq * args, asdl_keyword_seq * keywords,
            int lineno, int col_offset, int end_lineno, int end_col_offset,
            PyArena *arena)
{
    expr_ty p;
    if (!func) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'func' is required for Call");
        return NULL;
    }
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Call_kind;
    p->v.Call.func = func;
    p->v.Call.args = args;
    p->v.Call.keywords = keywords;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_FormattedValue(expr_ty value, int conversion, expr_ty format_spec, int
                      lineno, int col_offset, int end_lineno, int
                      end_col_offset, PyArena *arena)
{
    expr_ty p;
    if (!value) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'value' is required for FormattedValue");
        return NULL;
    }
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = FormattedValue_kind;
    p->v.FormattedValue.value = value;
    p->v.FormattedValue.conversion = conversion;
    p->v.FormattedValue.format_spec = format_spec;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_JoinedStr(asdl_expr_seq * values, int lineno, int col_offset, int
                 end_lineno, int end_col_offset, PyArena *arena)
{
    expr_ty p;
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = JoinedStr_kind;
    p->v.JoinedStr.values = values;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_Constant(constant value, string kind, int lineno, int col_offset, int
                end_lineno, int end_col_offset, PyArena *arena)
{
    expr_ty p;
    if (!value) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'value' is required for Constant");
        return NULL;
    }
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Constant_kind;
    p->v.Constant.value = value;
    p->v.Constant.kind = kind;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int
                 lineno, int col_offset, int end_lineno, int end_col_offset,
                 PyArena *arena)
{
    expr_ty p;
    if (!value) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'value' is required for Attribute");
        return NULL;
    }
    if (!attr) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'attr' is required for Attribute");
        return NULL;
    }
    if (!ctx) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'ctx' is required for Attribute");
        return NULL;
    }
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Attribute_kind;
    p->v.Attribute.value = value;
    p->v.Attribute.attr = attr;
    p->v.Attribute.ctx = ctx;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_Subscript(expr_ty value, expr_ty slice, expr_context_ty ctx, int lineno,
                 int col_offset, int end_lineno, int end_col_offset, PyArena
                 *arena)
{
    expr_ty p;
    if (!value) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'value' is required for Subscript");
        return NULL;
    }
    if (!slice) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'slice' is required for Subscript");
        return NULL;
    }
    if (!ctx) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'ctx' is required for Subscript");
        return NULL;
    }
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Subscript_kind;
    p->v.Subscript.value = value;
    p->v.Subscript.slice = slice;
    p->v.Subscript.ctx = ctx;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_Starred(expr_ty value, expr_context_ty ctx, int lineno, int col_offset,
               int end_lineno, int end_col_offset, PyArena *arena)
{
    expr_ty p;
    if (!value) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'value' is required for Starred");
        return NULL;
    }
    if (!ctx) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'ctx' is required for Starred");
        return NULL;
    }
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Starred_kind;
    p->v.Starred.value = value;
    p->v.Starred.ctx = ctx;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_Name(identifier id, expr_context_ty ctx, int lineno, int col_offset, int
            end_lineno, int end_col_offset, PyArena *arena)
{
    expr_ty p;
    if (!id) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'id' is required for Name");
        return NULL;
    }
    if (!ctx) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'ctx' is required for Name");
        return NULL;
    }
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Name_kind;
    p->v.Name.id = id;
    p->v.Name.ctx = ctx;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_List(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int
            col_offset, int end_lineno, int end_col_offset, PyArena *arena)
{
    expr_ty p;
    if (!ctx) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'ctx' is required for List");
        return NULL;
    }
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = List_kind;
    p->v.List.elts = elts;
    p->v.List.ctx = ctx;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_Tuple(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int
             col_offset, int end_lineno, int end_col_offset, PyArena *arena)
{
    expr_ty p;
    if (!ctx) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'ctx' is required for Tuple");
        return NULL;
    }
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Tuple_kind;
    p->v.Tuple.elts = elts;
    p->v.Tuple.ctx = ctx;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

expr_ty
_PyAST_Slice(expr_ty lower, expr_ty upper, expr_ty step, int lineno, int
             col_offset, int end_lineno, int end_col_offset, PyArena *arena)
{
    expr_ty p;
    p = (expr_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = Slice_kind;
    p->v.Slice.lower = lower;
    p->v.Slice.upper = upper;
    p->v.Slice.step = step;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

comprehension_ty
_PyAST_comprehension(expr_ty target, expr_ty iter, asdl_expr_seq * ifs, int
                     is_async, PyArena *arena)
{
    comprehension_ty p;
    if (!target) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'target' is required for comprehension");
        return NULL;
    }
    if (!iter) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'iter' is required for comprehension");
        return NULL;
    }
    p = (comprehension_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->target = target;
    p->iter = iter;
    p->ifs = ifs;
    p->is_async = is_async;
    return p;
}

excepthandler_ty
_PyAST_ExceptHandler(expr_ty type, identifier name, asdl_stmt_seq * body, int
                     lineno, int col_offset, int end_lineno, int
                     end_col_offset, PyArena *arena)
{
    excepthandler_ty p;
    p = (excepthandler_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = ExceptHandler_kind;
    p->v.ExceptHandler.type = type;
    p->v.ExceptHandler.name = name;
    p->v.ExceptHandler.body = body;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

arguments_ty
_PyAST_arguments(asdl_arg_seq * posonlyargs, asdl_arg_seq * args, arg_ty
                 vararg, asdl_arg_seq * kwonlyargs, asdl_expr_seq *
                 kw_defaults, arg_ty kwarg, asdl_expr_seq * defaults, PyArena
                 *arena)
{
    arguments_ty p;
    p = (arguments_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->posonlyargs = posonlyargs;
    p->args = args;
    p->vararg = vararg;
    p->kwonlyargs = kwonlyargs;
    p->kw_defaults = kw_defaults;
    p->kwarg = kwarg;
    p->defaults = defaults;
    return p;
}

arg_ty
_PyAST_arg(identifier arg, expr_ty annotation, string type_comment, int lineno,
           int col_offset, int end_lineno, int end_col_offset, PyArena *arena)
{
    arg_ty p;
    if (!arg) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'arg' is required for arg");
        return NULL;
    }
    p = (arg_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->arg = arg;
    p->annotation = annotation;
    p->type_comment = type_comment;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

keyword_ty
_PyAST_keyword(identifier arg, expr_ty value, int lineno, int col_offset, int
               end_lineno, int end_col_offset, PyArena *arena)
{
    keyword_ty p;
    if (!value) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'value' is required for keyword");
        return NULL;
    }
    p = (keyword_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->arg = arg;
    p->value = value;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

alias_ty
_PyAST_alias(identifier name, identifier asname, int lineno, int col_offset,
             int end_lineno, int end_col_offset, PyArena *arena)
{
    alias_ty p;
    if (!name) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'name' is required for alias");
        return NULL;
    }
    p = (alias_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->name = name;
    p->asname = asname;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

withitem_ty
_PyAST_withitem(expr_ty context_expr, expr_ty optional_vars, PyArena *arena)
{
    withitem_ty p;
    if (!context_expr) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'context_expr' is required for withitem");
        return NULL;
    }
    p = (withitem_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->context_expr = context_expr;
    p->optional_vars = optional_vars;
    return p;
}

match_case_ty
_PyAST_match_case(pattern_ty pattern, expr_ty guard, asdl_stmt_seq * body,
                  PyArena *arena)
{
    match_case_ty p;
    if (!pattern) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'pattern' is required for match_case");
        return NULL;
    }
    p = (match_case_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->pattern = pattern;
    p->guard = guard;
    p->body = body;
    return p;
}

pattern_ty
_PyAST_MatchValue(expr_ty value, int lineno, int col_offset, int end_lineno,
                  int end_col_offset, PyArena *arena)
{
    pattern_ty p;
    if (!value) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'value' is required for MatchValue");
        return NULL;
    }
    p = (pattern_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = MatchValue_kind;
    p->v.MatchValue.value = value;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

pattern_ty
_PyAST_MatchSingleton(constant value, int lineno, int col_offset, int
                      end_lineno, int end_col_offset, PyArena *arena)
{
    pattern_ty p;
    if (!value) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'value' is required for MatchSingleton");
        return NULL;
    }
    p = (pattern_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = MatchSingleton_kind;
    p->v.MatchSingleton.value = value;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

pattern_ty
_PyAST_MatchSequence(asdl_pattern_seq * patterns, int lineno, int col_offset,
                     int end_lineno, int end_col_offset, PyArena *arena)
{
    pattern_ty p;
    p = (pattern_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = MatchSequence_kind;
    p->v.MatchSequence.patterns = patterns;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

pattern_ty
_PyAST_MatchMapping(asdl_expr_seq * keys, asdl_pattern_seq * patterns,
                    identifier rest, int lineno, int col_offset, int
                    end_lineno, int end_col_offset, PyArena *arena)
{
    pattern_ty p;
    p = (pattern_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = MatchMapping_kind;
    p->v.MatchMapping.keys = keys;
    p->v.MatchMapping.patterns = patterns;
    p->v.MatchMapping.rest = rest;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

pattern_ty
_PyAST_MatchClass(expr_ty cls, asdl_pattern_seq * patterns, asdl_identifier_seq
                  * kwd_attrs, asdl_pattern_seq * kwd_patterns, int lineno, int
                  col_offset, int end_lineno, int end_col_offset, PyArena
                  *arena)
{
    pattern_ty p;
    if (!cls) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'cls' is required for MatchClass");
        return NULL;
    }
    p = (pattern_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = MatchClass_kind;
    p->v.MatchClass.cls = cls;
    p->v.MatchClass.patterns = patterns;
    p->v.MatchClass.kwd_attrs = kwd_attrs;
    p->v.MatchClass.kwd_patterns = kwd_patterns;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

pattern_ty
_PyAST_MatchStar(identifier name, int lineno, int col_offset, int end_lineno,
                 int end_col_offset, PyArena *arena)
{
    pattern_ty p;
    p = (pattern_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = MatchStar_kind;
    p->v.MatchStar.name = name;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

pattern_ty
_PyAST_MatchAs(pattern_ty pattern, identifier name, int lineno, int col_offset,
               int end_lineno, int end_col_offset, PyArena *arena)
{
    pattern_ty p;
    p = (pattern_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = MatchAs_kind;
    p->v.MatchAs.pattern = pattern;
    p->v.MatchAs.name = name;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

pattern_ty
_PyAST_MatchOr(asdl_pattern_seq * patterns, int lineno, int col_offset, int
               end_lineno, int end_col_offset, PyArena *arena)
{
    pattern_ty p;
    p = (pattern_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = MatchOr_kind;
    p->v.MatchOr.patterns = patterns;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

type_ignore_ty
_PyAST_TypeIgnore(int lineno, string tag, PyArena *arena)
{
    type_ignore_ty p;
    if (!tag) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'tag' is required for TypeIgnore");
        return NULL;
    }
    p = (type_ignore_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = TypeIgnore_kind;
    p->v.TypeIgnore.lineno = lineno;
    p->v.TypeIgnore.tag = tag;
    return p;
}

type_param_ty
_PyAST_TypeVar(identifier name, expr_ty bound, int lineno, int col_offset, int
               end_lineno, int end_col_offset, PyArena *arena)
{
    type_param_ty p;
    if (!name) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'name' is required for TypeVar");
        return NULL;
    }
    p = (type_param_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = TypeVar_kind;
    p->v.TypeVar.name = name;
    p->v.TypeVar.bound = bound;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

type_param_ty
_PyAST_ParamSpec(identifier name, int lineno, int col_offset, int end_lineno,
                 int end_col_offset, PyArena *arena)
{
    type_param_ty p;
    if (!name) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'name' is required for ParamSpec");
        return NULL;
    }
    p = (type_param_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = ParamSpec_kind;
    p->v.ParamSpec.name = name;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}

type_param_ty
_PyAST_TypeVarTuple(identifier name, int lineno, int col_offset, int
                    end_lineno, int end_col_offset, PyArena *arena)
{
    type_param_ty p;
    if (!name) {
        PyErr_SetString(PyExc_ValueError,
                        "field 'name' is required for TypeVarTuple");
        return NULL;
    }
    p = (type_param_ty)_PyArena_Malloc(arena, sizeof(*p));
    if (!p)
        return NULL;
    p->kind = TypeVarTuple_kind;
    p->v.TypeVarTuple.name = name;
    p->lineno = lineno;
    p->col_offset = col_offset;
    p->end_lineno = end_lineno;
    p->end_col_offset = end_col_offset;
    return p;
}


PyObject*
ast2obj_mod(struct ast_state *state, void* _o)
{
    mod_ty o = (mod_ty)_o;
    PyObject *result = NULL, *value = NULL;
    PyTypeObject *tp;
    if (!o) {
        Py_RETURN_NONE;
    }
    if (++state->recursion_depth > state->recursion_limit) {
        PyErr_SetString(PyExc_RecursionError,
            "maximum recursion depth exceeded during ast construction");
        return 0;
    }
    switch (o->kind) {
    case Module_kind:
        tp = (PyTypeObject *)state->Module_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_list(state, (asdl_seq*)o->v.Module.body, ast2obj_stmt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->body, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.Module.type_ignores,
                             ast2obj_type_ignore);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->type_ignores, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Interactive_kind:
        tp = (PyTypeObject *)state->Interactive_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_list(state, (asdl_seq*)o->v.Interactive.body,
                             ast2obj_stmt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->body, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Expression_kind:
        tp = (PyTypeObject *)state->Expression_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.Expression.body);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->body, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case FunctionType_kind:
        tp = (PyTypeObject *)state->FunctionType_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_list(state, (asdl_seq*)o->v.FunctionType.argtypes,
                             ast2obj_expr);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->argtypes, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr(state, o->v.FunctionType.returns);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->returns, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    }
    state->recursion_depth--;
    return result;
failed:
    Py_XDECREF(value);
    Py_XDECREF(result);
    return NULL;
}

PyObject*
ast2obj_stmt(struct ast_state *state, void* _o)
{
    stmt_ty o = (stmt_ty)_o;
    PyObject *result = NULL, *value = NULL;
    PyTypeObject *tp;
    if (!o) {
        Py_RETURN_NONE;
    }
    if (++state->recursion_depth > state->recursion_limit) {
        PyErr_SetString(PyExc_RecursionError,
            "maximum recursion depth exceeded during ast construction");
        return 0;
    }
    switch (o->kind) {
    case FunctionDef_kind:
        tp = (PyTypeObject *)state->FunctionDef_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_identifier(state, o->v.FunctionDef.name);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->name, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_arguments(state, o->v.FunctionDef.args);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->args, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.FunctionDef.body,
                             ast2obj_stmt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->body, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.FunctionDef.decorator_list,
                             ast2obj_expr);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->decorator_list, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr(state, o->v.FunctionDef.returns);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->returns, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_string(state, o->v.FunctionDef.type_comment);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->type_comment, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.FunctionDef.type_params,
                             ast2obj_type_param);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->type_params, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case AsyncFunctionDef_kind:
        tp = (PyTypeObject *)state->AsyncFunctionDef_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_identifier(state, o->v.AsyncFunctionDef.name);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->name, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_arguments(state, o->v.AsyncFunctionDef.args);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->args, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.AsyncFunctionDef.body,
                             ast2obj_stmt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->body, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state,
                             (asdl_seq*)o->v.AsyncFunctionDef.decorator_list,
                             ast2obj_expr);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->decorator_list, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr(state, o->v.AsyncFunctionDef.returns);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->returns, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_string(state, o->v.AsyncFunctionDef.type_comment);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->type_comment, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state,
                             (asdl_seq*)o->v.AsyncFunctionDef.type_params,
                             ast2obj_type_param);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->type_params, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case ClassDef_kind:
        tp = (PyTypeObject *)state->ClassDef_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_identifier(state, o->v.ClassDef.name);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->name, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.bases,
                             ast2obj_expr);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->bases, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.keywords,
                             ast2obj_keyword);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->keywords, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.body,
                             ast2obj_stmt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->body, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.decorator_list,
                             ast2obj_expr);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->decorator_list, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.type_params,
                             ast2obj_type_param);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->type_params, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Return_kind:
        tp = (PyTypeObject *)state->Return_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.Return.value);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->value, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Delete_kind:
        tp = (PyTypeObject *)state->Delete_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_list(state, (asdl_seq*)o->v.Delete.targets,
                             ast2obj_expr);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->targets, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Assign_kind:
        tp = (PyTypeObject *)state->Assign_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_list(state, (asdl_seq*)o->v.Assign.targets,
                             ast2obj_expr);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->targets, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr(state, o->v.Assign.value);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->value, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_string(state, o->v.Assign.type_comment);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->type_comment, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case TypeAlias_kind:
        tp = (PyTypeObject *)state->TypeAlias_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.TypeAlias.name);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->name, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.TypeAlias.type_params,
                             ast2obj_type_param);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->type_params, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr(state, o->v.TypeAlias.value);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->value, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case AugAssign_kind:
        tp = (PyTypeObject *)state->AugAssign_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.AugAssign.target);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->target, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_operator(state, o->v.AugAssign.op);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->op, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr(state, o->v.AugAssign.value);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->value, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case AnnAssign_kind:
        tp = (PyTypeObject *)state->AnnAssign_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.AnnAssign.target);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->target, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr(state, o->v.AnnAssign.annotation);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->annotation, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr(state, o->v.AnnAssign.value);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->value, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_int(state, o->v.AnnAssign.simple);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->simple, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case For_kind:
        tp = (PyTypeObject *)state->For_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.For.target);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->target, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr(state, o->v.For.iter);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->iter, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.For.body, ast2obj_stmt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->body, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.For.orelse, ast2obj_stmt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->orelse, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_string(state, o->v.For.type_comment);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->type_comment, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case AsyncFor_kind:
        tp = (PyTypeObject *)state->AsyncFor_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.AsyncFor.target);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->target, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr(state, o->v.AsyncFor.iter);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->iter, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.AsyncFor.body,
                             ast2obj_stmt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->body, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.AsyncFor.orelse,
                             ast2obj_stmt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->orelse, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_string(state, o->v.AsyncFor.type_comment);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->type_comment, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case While_kind:
        tp = (PyTypeObject *)state->While_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.While.test);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->test, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.While.body, ast2obj_stmt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->body, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.While.orelse, ast2obj_stmt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->orelse, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case If_kind:
        tp = (PyTypeObject *)state->If_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.If.test);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->test, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.If.body, ast2obj_stmt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->body, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.If.orelse, ast2obj_stmt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->orelse, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case With_kind:
        tp = (PyTypeObject *)state->With_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_list(state, (asdl_seq*)o->v.With.items,
                             ast2obj_withitem);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->items, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.With.body, ast2obj_stmt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->body, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_string(state, o->v.With.type_comment);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->type_comment, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case AsyncWith_kind:
        tp = (PyTypeObject *)state->AsyncWith_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_list(state, (asdl_seq*)o->v.AsyncWith.items,
                             ast2obj_withitem);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->items, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.AsyncWith.body,
                             ast2obj_stmt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->body, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_string(state, o->v.AsyncWith.type_comment);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->type_comment, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Match_kind:
        tp = (PyTypeObject *)state->Match_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.Match.subject);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->subject, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.Match.cases,
                             ast2obj_match_case);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->cases, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Raise_kind:
        tp = (PyTypeObject *)state->Raise_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.Raise.exc);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->exc, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr(state, o->v.Raise.cause);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->cause, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Try_kind:
        tp = (PyTypeObject *)state->Try_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_list(state, (asdl_seq*)o->v.Try.body, ast2obj_stmt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->body, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.Try.handlers,
                             ast2obj_excepthandler);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->handlers, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.Try.orelse, ast2obj_stmt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->orelse, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.Try.finalbody,
                             ast2obj_stmt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->finalbody, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case TryStar_kind:
        tp = (PyTypeObject *)state->TryStar_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_list(state, (asdl_seq*)o->v.TryStar.body, ast2obj_stmt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->body, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.TryStar.handlers,
                             ast2obj_excepthandler);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->handlers, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.TryStar.orelse,
                             ast2obj_stmt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->orelse, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.TryStar.finalbody,
                             ast2obj_stmt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->finalbody, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Assert_kind:
        tp = (PyTypeObject *)state->Assert_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.Assert.test);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->test, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr(state, o->v.Assert.msg);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->msg, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Import_kind:
        tp = (PyTypeObject *)state->Import_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_list(state, (asdl_seq*)o->v.Import.names,
                             ast2obj_alias);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->names, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case ImportFrom_kind:
        tp = (PyTypeObject *)state->ImportFrom_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_identifier(state, o->v.ImportFrom.module);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->module, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.ImportFrom.names,
                             ast2obj_alias);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->names, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_int(state, o->v.ImportFrom.level);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->level, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Global_kind:
        tp = (PyTypeObject *)state->Global_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_list(state, (asdl_seq*)o->v.Global.names,
                             ast2obj_identifier);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->names, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Nonlocal_kind:
        tp = (PyTypeObject *)state->Nonlocal_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_list(state, (asdl_seq*)o->v.Nonlocal.names,
                             ast2obj_identifier);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->names, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Expr_kind:
        tp = (PyTypeObject *)state->Expr_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.Expr.value);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->value, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Pass_kind:
        tp = (PyTypeObject *)state->Pass_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        break;
    case Break_kind:
        tp = (PyTypeObject *)state->Break_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        break;
    case Continue_kind:
        tp = (PyTypeObject *)state->Continue_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        break;
    }
    value = ast2obj_int(state, o->lineno);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->lineno, value) < 0)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->col_offset);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->col_offset, value) < 0)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->end_lineno);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->end_lineno, value) < 0)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->end_col_offset);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->end_col_offset, value) < 0)
        goto failed;
    Py_DECREF(value);
    state->recursion_depth--;
    return result;
failed:
    Py_XDECREF(value);
    Py_XDECREF(result);
    return NULL;
}

PyObject*
ast2obj_expr(struct ast_state *state, void* _o)
{
    expr_ty o = (expr_ty)_o;
    PyObject *result = NULL, *value = NULL;
    PyTypeObject *tp;
    if (!o) {
        Py_RETURN_NONE;
    }
    if (++state->recursion_depth > state->recursion_limit) {
        PyErr_SetString(PyExc_RecursionError,
            "maximum recursion depth exceeded during ast construction");
        return 0;
    }
    switch (o->kind) {
    case BoolOp_kind:
        tp = (PyTypeObject *)state->BoolOp_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_boolop(state, o->v.BoolOp.op);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->op, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.BoolOp.values,
                             ast2obj_expr);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->values, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case NamedExpr_kind:
        tp = (PyTypeObject *)state->NamedExpr_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.NamedExpr.target);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->target, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr(state, o->v.NamedExpr.value);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->value, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case BinOp_kind:
        tp = (PyTypeObject *)state->BinOp_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.BinOp.left);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->left, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_operator(state, o->v.BinOp.op);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->op, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr(state, o->v.BinOp.right);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->right, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case UnaryOp_kind:
        tp = (PyTypeObject *)state->UnaryOp_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_unaryop(state, o->v.UnaryOp.op);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->op, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr(state, o->v.UnaryOp.operand);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->operand, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Lambda_kind:
        tp = (PyTypeObject *)state->Lambda_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_arguments(state, o->v.Lambda.args);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->args, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr(state, o->v.Lambda.body);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->body, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case IfExp_kind:
        tp = (PyTypeObject *)state->IfExp_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.IfExp.test);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->test, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr(state, o->v.IfExp.body);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->body, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr(state, o->v.IfExp.orelse);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->orelse, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Dict_kind:
        tp = (PyTypeObject *)state->Dict_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_list(state, (asdl_seq*)o->v.Dict.keys, ast2obj_expr);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->keys, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.Dict.values, ast2obj_expr);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->values, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Set_kind:
        tp = (PyTypeObject *)state->Set_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_list(state, (asdl_seq*)o->v.Set.elts, ast2obj_expr);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->elts, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case ListComp_kind:
        tp = (PyTypeObject *)state->ListComp_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.ListComp.elt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->elt, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.ListComp.generators,
                             ast2obj_comprehension);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->generators, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case SetComp_kind:
        tp = (PyTypeObject *)state->SetComp_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.SetComp.elt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->elt, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.SetComp.generators,
                             ast2obj_comprehension);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->generators, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case DictComp_kind:
        tp = (PyTypeObject *)state->DictComp_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.DictComp.key);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->key, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr(state, o->v.DictComp.value);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->value, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.DictComp.generators,
                             ast2obj_comprehension);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->generators, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case GeneratorExp_kind:
        tp = (PyTypeObject *)state->GeneratorExp_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.GeneratorExp.elt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->elt, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.GeneratorExp.generators,
                             ast2obj_comprehension);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->generators, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Await_kind:
        tp = (PyTypeObject *)state->Await_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.Await.value);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->value, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Yield_kind:
        tp = (PyTypeObject *)state->Yield_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.Yield.value);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->value, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case YieldFrom_kind:
        tp = (PyTypeObject *)state->YieldFrom_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.YieldFrom.value);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->value, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Compare_kind:
        tp = (PyTypeObject *)state->Compare_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.Compare.left);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->left, value) == -1)
            goto failed;
        Py_DECREF(value);
        {
            Py_ssize_t i, n = asdl_seq_LEN(o->v.Compare.ops);
            value = PyList_New(n);
            if (!value) goto failed;
            for(i = 0; i < n; i++)
                PyList_SET_ITEM(value, i, ast2obj_cmpop(state, (cmpop_ty)asdl_seq_GET(o->v.Compare.ops, i)));
        }
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->ops, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.Compare.comparators,
                             ast2obj_expr);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->comparators, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Call_kind:
        tp = (PyTypeObject *)state->Call_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.Call.func);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->func, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.Call.args, ast2obj_expr);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->args, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.Call.keywords,
                             ast2obj_keyword);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->keywords, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case FormattedValue_kind:
        tp = (PyTypeObject *)state->FormattedValue_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.FormattedValue.value);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->value, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_int(state, o->v.FormattedValue.conversion);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->conversion, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr(state, o->v.FormattedValue.format_spec);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->format_spec, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case JoinedStr_kind:
        tp = (PyTypeObject *)state->JoinedStr_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_list(state, (asdl_seq*)o->v.JoinedStr.values,
                             ast2obj_expr);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->values, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Constant_kind:
        tp = (PyTypeObject *)state->Constant_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_constant(state, o->v.Constant.value);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->value, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_string(state, o->v.Constant.kind);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->kind, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Attribute_kind:
        tp = (PyTypeObject *)state->Attribute_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.Attribute.value);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->value, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_identifier(state, o->v.Attribute.attr);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->attr, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr_context(state, o->v.Attribute.ctx);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->ctx, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Subscript_kind:
        tp = (PyTypeObject *)state->Subscript_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.Subscript.value);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->value, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr(state, o->v.Subscript.slice);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->slice, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr_context(state, o->v.Subscript.ctx);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->ctx, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Starred_kind:
        tp = (PyTypeObject *)state->Starred_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.Starred.value);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->value, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr_context(state, o->v.Starred.ctx);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->ctx, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Name_kind:
        tp = (PyTypeObject *)state->Name_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_identifier(state, o->v.Name.id);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->id, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr_context(state, o->v.Name.ctx);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->ctx, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case List_kind:
        tp = (PyTypeObject *)state->List_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_list(state, (asdl_seq*)o->v.List.elts, ast2obj_expr);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->elts, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr_context(state, o->v.List.ctx);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->ctx, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Tuple_kind:
        tp = (PyTypeObject *)state->Tuple_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_list(state, (asdl_seq*)o->v.Tuple.elts, ast2obj_expr);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->elts, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr_context(state, o->v.Tuple.ctx);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->ctx, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case Slice_kind:
        tp = (PyTypeObject *)state->Slice_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.Slice.lower);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->lower, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr(state, o->v.Slice.upper);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->upper, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr(state, o->v.Slice.step);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->step, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    }
    value = ast2obj_int(state, o->lineno);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->lineno, value) < 0)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->col_offset);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->col_offset, value) < 0)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->end_lineno);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->end_lineno, value) < 0)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->end_col_offset);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->end_col_offset, value) < 0)
        goto failed;
    Py_DECREF(value);
    state->recursion_depth--;
    return result;
failed:
    Py_XDECREF(value);
    Py_XDECREF(result);
    return NULL;
}

PyObject* ast2obj_expr_context(struct ast_state *state, expr_context_ty o)
{
    switch(o) {
        case Load:
            return Py_NewRef(state->Load_singleton);
        case Store:
            return Py_NewRef(state->Store_singleton);
        case Del:
            return Py_NewRef(state->Del_singleton);
    }
    Py_UNREACHABLE();
}
PyObject* ast2obj_boolop(struct ast_state *state, boolop_ty o)
{
    switch(o) {
        case And:
            return Py_NewRef(state->And_singleton);
        case Or:
            return Py_NewRef(state->Or_singleton);
    }
    Py_UNREACHABLE();
}
PyObject* ast2obj_operator(struct ast_state *state, operator_ty o)
{
    switch(o) {
        case Add:
            return Py_NewRef(state->Add_singleton);
        case Sub:
            return Py_NewRef(state->Sub_singleton);
        case Mult:
            return Py_NewRef(state->Mult_singleton);
        case MatMult:
            return Py_NewRef(state->MatMult_singleton);
        case Div:
            return Py_NewRef(state->Div_singleton);
        case Mod:
            return Py_NewRef(state->Mod_singleton);
        case Pow:
            return Py_NewRef(state->Pow_singleton);
        case LShift:
            return Py_NewRef(state->LShift_singleton);
        case RShift:
            return Py_NewRef(state->RShift_singleton);
        case BitOr:
            return Py_NewRef(state->BitOr_singleton);
        case BitXor:
            return Py_NewRef(state->BitXor_singleton);
        case BitAnd:
            return Py_NewRef(state->BitAnd_singleton);
        case FloorDiv:
            return Py_NewRef(state->FloorDiv_singleton);
    }
    Py_UNREACHABLE();
}
PyObject* ast2obj_unaryop(struct ast_state *state, unaryop_ty o)
{
    switch(o) {
        case Invert:
            return Py_NewRef(state->Invert_singleton);
        case Not:
            return Py_NewRef(state->Not_singleton);
        case UAdd:
            return Py_NewRef(state->UAdd_singleton);
        case USub:
            return Py_NewRef(state->USub_singleton);
    }
    Py_UNREACHABLE();
}
PyObject* ast2obj_cmpop(struct ast_state *state, cmpop_ty o)
{
    switch(o) {
        case Eq:
            return Py_NewRef(state->Eq_singleton);
        case NotEq:
            return Py_NewRef(state->NotEq_singleton);
        case Lt:
            return Py_NewRef(state->Lt_singleton);
        case LtE:
            return Py_NewRef(state->LtE_singleton);
        case Gt:
            return Py_NewRef(state->Gt_singleton);
        case GtE:
            return Py_NewRef(state->GtE_singleton);
        case Is:
            return Py_NewRef(state->Is_singleton);
        case IsNot:
            return Py_NewRef(state->IsNot_singleton);
        case In:
            return Py_NewRef(state->In_singleton);
        case NotIn:
            return Py_NewRef(state->NotIn_singleton);
    }
    Py_UNREACHABLE();
}
PyObject*
ast2obj_comprehension(struct ast_state *state, void* _o)
{
    comprehension_ty o = (comprehension_ty)_o;
    PyObject *result = NULL, *value = NULL;
    PyTypeObject *tp;
    if (!o) {
        Py_RETURN_NONE;
    }
    if (++state->recursion_depth > state->recursion_limit) {
        PyErr_SetString(PyExc_RecursionError,
            "maximum recursion depth exceeded during ast construction");
        return 0;
    }
    tp = (PyTypeObject *)state->comprehension_type;
    result = PyType_GenericNew(tp, NULL, NULL);
    if (!result) return NULL;
    value = ast2obj_expr(state, o->target);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->target, value) == -1)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_expr(state, o->iter);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->iter, value) == -1)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_list(state, (asdl_seq*)o->ifs, ast2obj_expr);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->ifs, value) == -1)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->is_async);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->is_async, value) == -1)
        goto failed;
    Py_DECREF(value);
    state->recursion_depth--;
    return result;
failed:
    Py_XDECREF(value);
    Py_XDECREF(result);
    return NULL;
}

PyObject*
ast2obj_excepthandler(struct ast_state *state, void* _o)
{
    excepthandler_ty o = (excepthandler_ty)_o;
    PyObject *result = NULL, *value = NULL;
    PyTypeObject *tp;
    if (!o) {
        Py_RETURN_NONE;
    }
    if (++state->recursion_depth > state->recursion_limit) {
        PyErr_SetString(PyExc_RecursionError,
            "maximum recursion depth exceeded during ast construction");
        return 0;
    }
    switch (o->kind) {
    case ExceptHandler_kind:
        tp = (PyTypeObject *)state->ExceptHandler_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.ExceptHandler.type);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->type, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_identifier(state, o->v.ExceptHandler.name);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->name, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.ExceptHandler.body,
                             ast2obj_stmt);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->body, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    }
    value = ast2obj_int(state, o->lineno);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->lineno, value) < 0)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->col_offset);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->col_offset, value) < 0)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->end_lineno);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->end_lineno, value) < 0)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->end_col_offset);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->end_col_offset, value) < 0)
        goto failed;
    Py_DECREF(value);
    state->recursion_depth--;
    return result;
failed:
    Py_XDECREF(value);
    Py_XDECREF(result);
    return NULL;
}

PyObject*
ast2obj_arguments(struct ast_state *state, void* _o)
{
    arguments_ty o = (arguments_ty)_o;
    PyObject *result = NULL, *value = NULL;
    PyTypeObject *tp;
    if (!o) {
        Py_RETURN_NONE;
    }
    if (++state->recursion_depth > state->recursion_limit) {
        PyErr_SetString(PyExc_RecursionError,
            "maximum recursion depth exceeded during ast construction");
        return 0;
    }
    tp = (PyTypeObject *)state->arguments_type;
    result = PyType_GenericNew(tp, NULL, NULL);
    if (!result) return NULL;
    value = ast2obj_list(state, (asdl_seq*)o->posonlyargs, ast2obj_arg);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->posonlyargs, value) == -1)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_list(state, (asdl_seq*)o->args, ast2obj_arg);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->args, value) == -1)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_arg(state, o->vararg);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->vararg, value) == -1)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_list(state, (asdl_seq*)o->kwonlyargs, ast2obj_arg);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->kwonlyargs, value) == -1)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_list(state, (asdl_seq*)o->kw_defaults, ast2obj_expr);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->kw_defaults, value) == -1)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_arg(state, o->kwarg);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->kwarg, value) == -1)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_list(state, (asdl_seq*)o->defaults, ast2obj_expr);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->defaults, value) == -1)
        goto failed;
    Py_DECREF(value);
    state->recursion_depth--;
    return result;
failed:
    Py_XDECREF(value);
    Py_XDECREF(result);
    return NULL;
}

PyObject*
ast2obj_arg(struct ast_state *state, void* _o)
{
    arg_ty o = (arg_ty)_o;
    PyObject *result = NULL, *value = NULL;
    PyTypeObject *tp;
    if (!o) {
        Py_RETURN_NONE;
    }
    if (++state->recursion_depth > state->recursion_limit) {
        PyErr_SetString(PyExc_RecursionError,
            "maximum recursion depth exceeded during ast construction");
        return 0;
    }
    tp = (PyTypeObject *)state->arg_type;
    result = PyType_GenericNew(tp, NULL, NULL);
    if (!result) return NULL;
    value = ast2obj_identifier(state, o->arg);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->arg, value) == -1)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_expr(state, o->annotation);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->annotation, value) == -1)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_string(state, o->type_comment);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->type_comment, value) == -1)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->lineno);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->lineno, value) < 0)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->col_offset);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->col_offset, value) < 0)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->end_lineno);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->end_lineno, value) < 0)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->end_col_offset);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->end_col_offset, value) < 0)
        goto failed;
    Py_DECREF(value);
    state->recursion_depth--;
    return result;
failed:
    Py_XDECREF(value);
    Py_XDECREF(result);
    return NULL;
}

PyObject*
ast2obj_keyword(struct ast_state *state, void* _o)
{
    keyword_ty o = (keyword_ty)_o;
    PyObject *result = NULL, *value = NULL;
    PyTypeObject *tp;
    if (!o) {
        Py_RETURN_NONE;
    }
    if (++state->recursion_depth > state->recursion_limit) {
        PyErr_SetString(PyExc_RecursionError,
            "maximum recursion depth exceeded during ast construction");
        return 0;
    }
    tp = (PyTypeObject *)state->keyword_type;
    result = PyType_GenericNew(tp, NULL, NULL);
    if (!result) return NULL;
    value = ast2obj_identifier(state, o->arg);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->arg, value) == -1)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_expr(state, o->value);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->value, value) == -1)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->lineno);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->lineno, value) < 0)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->col_offset);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->col_offset, value) < 0)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->end_lineno);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->end_lineno, value) < 0)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->end_col_offset);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->end_col_offset, value) < 0)
        goto failed;
    Py_DECREF(value);
    state->recursion_depth--;
    return result;
failed:
    Py_XDECREF(value);
    Py_XDECREF(result);
    return NULL;
}

PyObject*
ast2obj_alias(struct ast_state *state, void* _o)
{
    alias_ty o = (alias_ty)_o;
    PyObject *result = NULL, *value = NULL;
    PyTypeObject *tp;
    if (!o) {
        Py_RETURN_NONE;
    }
    if (++state->recursion_depth > state->recursion_limit) {
        PyErr_SetString(PyExc_RecursionError,
            "maximum recursion depth exceeded during ast construction");
        return 0;
    }
    tp = (PyTypeObject *)state->alias_type;
    result = PyType_GenericNew(tp, NULL, NULL);
    if (!result) return NULL;
    value = ast2obj_identifier(state, o->name);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->name, value) == -1)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_identifier(state, o->asname);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->asname, value) == -1)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->lineno);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->lineno, value) < 0)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->col_offset);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->col_offset, value) < 0)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->end_lineno);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->end_lineno, value) < 0)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->end_col_offset);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->end_col_offset, value) < 0)
        goto failed;
    Py_DECREF(value);
    state->recursion_depth--;
    return result;
failed:
    Py_XDECREF(value);
    Py_XDECREF(result);
    return NULL;
}

PyObject*
ast2obj_withitem(struct ast_state *state, void* _o)
{
    withitem_ty o = (withitem_ty)_o;
    PyObject *result = NULL, *value = NULL;
    PyTypeObject *tp;
    if (!o) {
        Py_RETURN_NONE;
    }
    if (++state->recursion_depth > state->recursion_limit) {
        PyErr_SetString(PyExc_RecursionError,
            "maximum recursion depth exceeded during ast construction");
        return 0;
    }
    tp = (PyTypeObject *)state->withitem_type;
    result = PyType_GenericNew(tp, NULL, NULL);
    if (!result) return NULL;
    value = ast2obj_expr(state, o->context_expr);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->context_expr, value) == -1)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_expr(state, o->optional_vars);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->optional_vars, value) == -1)
        goto failed;
    Py_DECREF(value);
    state->recursion_depth--;
    return result;
failed:
    Py_XDECREF(value);
    Py_XDECREF(result);
    return NULL;
}

PyObject*
ast2obj_match_case(struct ast_state *state, void* _o)
{
    match_case_ty o = (match_case_ty)_o;
    PyObject *result = NULL, *value = NULL;
    PyTypeObject *tp;
    if (!o) {
        Py_RETURN_NONE;
    }
    if (++state->recursion_depth > state->recursion_limit) {
        PyErr_SetString(PyExc_RecursionError,
            "maximum recursion depth exceeded during ast construction");
        return 0;
    }
    tp = (PyTypeObject *)state->match_case_type;
    result = PyType_GenericNew(tp, NULL, NULL);
    if (!result) return NULL;
    value = ast2obj_pattern(state, o->pattern);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->pattern, value) == -1)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_expr(state, o->guard);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->guard, value) == -1)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_list(state, (asdl_seq*)o->body, ast2obj_stmt);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->body, value) == -1)
        goto failed;
    Py_DECREF(value);
    state->recursion_depth--;
    return result;
failed:
    Py_XDECREF(value);
    Py_XDECREF(result);
    return NULL;
}

PyObject*
ast2obj_pattern(struct ast_state *state, void* _o)
{
    pattern_ty o = (pattern_ty)_o;
    PyObject *result = NULL, *value = NULL;
    PyTypeObject *tp;
    if (!o) {
        Py_RETURN_NONE;
    }
    if (++state->recursion_depth > state->recursion_limit) {
        PyErr_SetString(PyExc_RecursionError,
            "maximum recursion depth exceeded during ast construction");
        return 0;
    }
    switch (o->kind) {
    case MatchValue_kind:
        tp = (PyTypeObject *)state->MatchValue_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.MatchValue.value);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->value, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case MatchSingleton_kind:
        tp = (PyTypeObject *)state->MatchSingleton_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_constant(state, o->v.MatchSingleton.value);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->value, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case MatchSequence_kind:
        tp = (PyTypeObject *)state->MatchSequence_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_list(state, (asdl_seq*)o->v.MatchSequence.patterns,
                             ast2obj_pattern);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->patterns, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case MatchMapping_kind:
        tp = (PyTypeObject *)state->MatchMapping_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_list(state, (asdl_seq*)o->v.MatchMapping.keys,
                             ast2obj_expr);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->keys, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.MatchMapping.patterns,
                             ast2obj_pattern);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->patterns, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_identifier(state, o->v.MatchMapping.rest);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->rest, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case MatchClass_kind:
        tp = (PyTypeObject *)state->MatchClass_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_expr(state, o->v.MatchClass.cls);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->cls, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.MatchClass.patterns,
                             ast2obj_pattern);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->patterns, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.MatchClass.kwd_attrs,
                             ast2obj_identifier);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->kwd_attrs, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_list(state, (asdl_seq*)o->v.MatchClass.kwd_patterns,
                             ast2obj_pattern);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->kwd_patterns, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case MatchStar_kind:
        tp = (PyTypeObject *)state->MatchStar_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_identifier(state, o->v.MatchStar.name);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->name, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case MatchAs_kind:
        tp = (PyTypeObject *)state->MatchAs_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_pattern(state, o->v.MatchAs.pattern);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->pattern, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_identifier(state, o->v.MatchAs.name);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->name, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case MatchOr_kind:
        tp = (PyTypeObject *)state->MatchOr_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_list(state, (asdl_seq*)o->v.MatchOr.patterns,
                             ast2obj_pattern);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->patterns, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    }
    value = ast2obj_int(state, o->lineno);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->lineno, value) < 0)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->col_offset);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->col_offset, value) < 0)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->end_lineno);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->end_lineno, value) < 0)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->end_col_offset);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->end_col_offset, value) < 0)
        goto failed;
    Py_DECREF(value);
    state->recursion_depth--;
    return result;
failed:
    Py_XDECREF(value);
    Py_XDECREF(result);
    return NULL;
}

PyObject*
ast2obj_type_ignore(struct ast_state *state, void* _o)
{
    type_ignore_ty o = (type_ignore_ty)_o;
    PyObject *result = NULL, *value = NULL;
    PyTypeObject *tp;
    if (!o) {
        Py_RETURN_NONE;
    }
    if (++state->recursion_depth > state->recursion_limit) {
        PyErr_SetString(PyExc_RecursionError,
            "maximum recursion depth exceeded during ast construction");
        return 0;
    }
    switch (o->kind) {
    case TypeIgnore_kind:
        tp = (PyTypeObject *)state->TypeIgnore_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_int(state, o->v.TypeIgnore.lineno);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->lineno, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_string(state, o->v.TypeIgnore.tag);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->tag, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    }
    state->recursion_depth--;
    return result;
failed:
    Py_XDECREF(value);
    Py_XDECREF(result);
    return NULL;
}

PyObject*
ast2obj_type_param(struct ast_state *state, void* _o)
{
    type_param_ty o = (type_param_ty)_o;
    PyObject *result = NULL, *value = NULL;
    PyTypeObject *tp;
    if (!o) {
        Py_RETURN_NONE;
    }
    if (++state->recursion_depth > state->recursion_limit) {
        PyErr_SetString(PyExc_RecursionError,
            "maximum recursion depth exceeded during ast construction");
        return 0;
    }
    switch (o->kind) {
    case TypeVar_kind:
        tp = (PyTypeObject *)state->TypeVar_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_identifier(state, o->v.TypeVar.name);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->name, value) == -1)
            goto failed;
        Py_DECREF(value);
        value = ast2obj_expr(state, o->v.TypeVar.bound);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->bound, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case ParamSpec_kind:
        tp = (PyTypeObject *)state->ParamSpec_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_identifier(state, o->v.ParamSpec.name);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->name, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    case TypeVarTuple_kind:
        tp = (PyTypeObject *)state->TypeVarTuple_type;
        result = PyType_GenericNew(tp, NULL, NULL);
        if (!result) goto failed;
        value = ast2obj_identifier(state, o->v.TypeVarTuple.name);
        if (!value) goto failed;
        if (PyObject_SetAttr(result, state->name, value) == -1)
            goto failed;
        Py_DECREF(value);
        break;
    }
    value = ast2obj_int(state, o->lineno);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->lineno, value) < 0)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->col_offset);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->col_offset, value) < 0)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->end_lineno);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->end_lineno, value) < 0)
        goto failed;
    Py_DECREF(value);
    value = ast2obj_int(state, o->end_col_offset);
    if (!value) goto failed;
    if (PyObject_SetAttr(result, state->end_col_offset, value) < 0)
        goto failed;
    Py_DECREF(value);
    state->recursion_depth--;
    return result;
failed:
    Py_XDECREF(value);
    Py_XDECREF(result);
    return NULL;
}


int
obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena)
{
    int isinstance;

    PyObject *tmp = NULL;
    PyObject *tp;

    if (obj == Py_None) {
        *out = NULL;
        return 0;
    }
    tp = state->Module_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        asdl_stmt_seq* body;
        asdl_type_ignore_seq* type_ignores;

        if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "Module field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            body = _Py_asdl_stmt_seq_new(len, arena);
            if (body == NULL) goto failed;
            for (i = 0; i < len; i++) {
                stmt_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'Module' node")) {
                    goto failed;
                }
                res = obj2ast_stmt(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "Module field \"body\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(body, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->type_ignores, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "Module field \"type_ignores\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            type_ignores = _Py_asdl_type_ignore_seq_new(len, arena);
            if (type_ignores == NULL) goto failed;
            for (i = 0; i < len; i++) {
                type_ignore_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'Module' node")) {
                    goto failed;
                }
                res = obj2ast_type_ignore(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "Module field \"type_ignores\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(type_ignores, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Module(body, type_ignores, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Interactive_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        asdl_stmt_seq* body;

        if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "Interactive field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            body = _Py_asdl_stmt_seq_new(len, arena);
            if (body == NULL) goto failed;
            for (i = 0; i < len; i++) {
                stmt_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'Interactive' node")) {
                    goto failed;
                }
                res = obj2ast_stmt(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "Interactive field \"body\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(body, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Interactive(body, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Expression_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty body;

        if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Expression");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Expression' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &body, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Expression(body, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->FunctionType_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        asdl_expr_seq* argtypes;
        expr_ty returns;

        if (_PyObject_LookupAttr(obj, state->argtypes, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "FunctionType field \"argtypes\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            argtypes = _Py_asdl_expr_seq_new(len, arena);
            if (argtypes == NULL) goto failed;
            for (i = 0; i < len; i++) {
                expr_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'FunctionType' node")) {
                    goto failed;
                }
                res = obj2ast_expr(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "FunctionType field \"argtypes\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(argtypes, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->returns, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"returns\" missing from FunctionType");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'FunctionType' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &returns, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_FunctionType(argtypes, returns, arena);
        if (*out == NULL) goto failed;
        return 0;
    }

    PyErr_Format(PyExc_TypeError, "expected some sort of mod, but got %R", obj);
    failed:
    Py_XDECREF(tmp);
    return 1;
}

int
obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena*
             arena)
{
    int isinstance;

    PyObject *tmp = NULL;
    PyObject *tp;
    int lineno;
    int col_offset;
    int end_lineno;
    int end_col_offset;

    if (obj == Py_None) {
        *out = NULL;
        return 0;
    }
    if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from stmt");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'stmt' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &lineno, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->col_offset, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from stmt");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'stmt' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &col_offset, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->end_lineno, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL || tmp == Py_None) {
        Py_CLEAR(tmp);
        end_lineno = lineno;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'stmt' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &end_lineno, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->end_col_offset, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL || tmp == Py_None) {
        Py_CLEAR(tmp);
        end_col_offset = col_offset;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'stmt' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &end_col_offset, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    tp = state->FunctionDef_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        identifier name;
        arguments_ty args;
        asdl_stmt_seq* body;
        asdl_expr_seq* decorator_list;
        expr_ty returns;
        string type_comment;
        asdl_type_param_seq* type_params;

        if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from FunctionDef");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) {
                goto failed;
            }
            res = obj2ast_identifier(state, tmp, &name, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->args, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from FunctionDef");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) {
                goto failed;
            }
            res = obj2ast_arguments(state, tmp, &args, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "FunctionDef field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            body = _Py_asdl_stmt_seq_new(len, arena);
            if (body == NULL) goto failed;
            for (i = 0; i < len; i++) {
                stmt_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) {
                    goto failed;
                }
                res = obj2ast_stmt(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "FunctionDef field \"body\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(body, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->decorator_list, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "FunctionDef field \"decorator_list\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            decorator_list = _Py_asdl_expr_seq_new(len, arena);
            if (decorator_list == NULL) goto failed;
            for (i = 0; i < len; i++) {
                expr_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) {
                    goto failed;
                }
                res = obj2ast_expr(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "FunctionDef field \"decorator_list\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(decorator_list, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->returns, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            returns = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &returns, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->type_comment, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            type_comment = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) {
                goto failed;
            }
            res = obj2ast_string(state, tmp, &type_comment, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->type_params, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "FunctionDef field \"type_params\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            type_params = _Py_asdl_type_param_seq_new(len, arena);
            if (type_params == NULL) goto failed;
            for (i = 0; i < len; i++) {
                type_param_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) {
                    goto failed;
                }
                res = obj2ast_type_param(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "FunctionDef field \"type_params\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(type_params, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_FunctionDef(name, args, body, decorator_list, returns,
                                  type_comment, type_params, lineno,
                                  col_offset, end_lineno, end_col_offset,
                                  arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->AsyncFunctionDef_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        identifier name;
        arguments_ty args;
        asdl_stmt_seq* body;
        asdl_expr_seq* decorator_list;
        expr_ty returns;
        string type_comment;
        asdl_type_param_seq* type_params;

        if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from AsyncFunctionDef");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) {
                goto failed;
            }
            res = obj2ast_identifier(state, tmp, &name, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->args, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from AsyncFunctionDef");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) {
                goto failed;
            }
            res = obj2ast_arguments(state, tmp, &args, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "AsyncFunctionDef field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            body = _Py_asdl_stmt_seq_new(len, arena);
            if (body == NULL) goto failed;
            for (i = 0; i < len; i++) {
                stmt_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) {
                    goto failed;
                }
                res = obj2ast_stmt(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "AsyncFunctionDef field \"body\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(body, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->decorator_list, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "AsyncFunctionDef field \"decorator_list\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            decorator_list = _Py_asdl_expr_seq_new(len, arena);
            if (decorator_list == NULL) goto failed;
            for (i = 0; i < len; i++) {
                expr_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) {
                    goto failed;
                }
                res = obj2ast_expr(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "AsyncFunctionDef field \"decorator_list\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(decorator_list, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->returns, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            returns = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &returns, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->type_comment, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            type_comment = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) {
                goto failed;
            }
            res = obj2ast_string(state, tmp, &type_comment, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->type_params, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "AsyncFunctionDef field \"type_params\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            type_params = _Py_asdl_type_param_seq_new(len, arena);
            if (type_params == NULL) goto failed;
            for (i = 0; i < len; i++) {
                type_param_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) {
                    goto failed;
                }
                res = obj2ast_type_param(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "AsyncFunctionDef field \"type_params\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(type_params, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_AsyncFunctionDef(name, args, body, decorator_list,
                                       returns, type_comment, type_params,
                                       lineno, col_offset, end_lineno,
                                       end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->ClassDef_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        identifier name;
        asdl_expr_seq* bases;
        asdl_keyword_seq* keywords;
        asdl_stmt_seq* body;
        asdl_expr_seq* decorator_list;
        asdl_type_param_seq* type_params;

        if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from ClassDef");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) {
                goto failed;
            }
            res = obj2ast_identifier(state, tmp, &name, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->bases, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "ClassDef field \"bases\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            bases = _Py_asdl_expr_seq_new(len, arena);
            if (bases == NULL) goto failed;
            for (i = 0; i < len; i++) {
                expr_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) {
                    goto failed;
                }
                res = obj2ast_expr(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "ClassDef field \"bases\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(bases, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->keywords, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "ClassDef field \"keywords\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            keywords = _Py_asdl_keyword_seq_new(len, arena);
            if (keywords == NULL) goto failed;
            for (i = 0; i < len; i++) {
                keyword_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) {
                    goto failed;
                }
                res = obj2ast_keyword(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "ClassDef field \"keywords\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(keywords, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "ClassDef field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            body = _Py_asdl_stmt_seq_new(len, arena);
            if (body == NULL) goto failed;
            for (i = 0; i < len; i++) {
                stmt_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) {
                    goto failed;
                }
                res = obj2ast_stmt(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "ClassDef field \"body\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(body, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->decorator_list, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "ClassDef field \"decorator_list\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            decorator_list = _Py_asdl_expr_seq_new(len, arena);
            if (decorator_list == NULL) goto failed;
            for (i = 0; i < len; i++) {
                expr_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) {
                    goto failed;
                }
                res = obj2ast_expr(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "ClassDef field \"decorator_list\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(decorator_list, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->type_params, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "ClassDef field \"type_params\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            type_params = _Py_asdl_type_param_seq_new(len, arena);
            if (type_params == NULL) goto failed;
            for (i = 0; i < len; i++) {
                type_param_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) {
                    goto failed;
                }
                res = obj2ast_type_param(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "ClassDef field \"type_params\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(type_params, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_ClassDef(name, bases, keywords, body, decorator_list,
                               type_params, lineno, col_offset, end_lineno,
                               end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Return_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty value;

        if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            value = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Return' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &value, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Return(value, lineno, col_offset, end_lineno,
                             end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Delete_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        asdl_expr_seq* targets;

        if (_PyObject_LookupAttr(obj, state->targets, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "Delete field \"targets\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            targets = _Py_asdl_expr_seq_new(len, arena);
            if (targets == NULL) goto failed;
            for (i = 0; i < len; i++) {
                expr_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'Delete' node")) {
                    goto failed;
                }
                res = obj2ast_expr(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "Delete field \"targets\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(targets, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Delete(targets, lineno, col_offset, end_lineno,
                             end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Assign_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        asdl_expr_seq* targets;
        expr_ty value;
        string type_comment;

        if (_PyObject_LookupAttr(obj, state->targets, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "Assign field \"targets\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            targets = _Py_asdl_expr_seq_new(len, arena);
            if (targets == NULL) goto failed;
            for (i = 0; i < len; i++) {
                expr_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'Assign' node")) {
                    goto failed;
                }
                res = obj2ast_expr(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "Assign field \"targets\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(targets, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Assign");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Assign' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &value, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->type_comment, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            type_comment = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Assign' node")) {
                goto failed;
            }
            res = obj2ast_string(state, tmp, &type_comment, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Assign(targets, value, type_comment, lineno, col_offset,
                             end_lineno, end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->TypeAlias_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty name;
        asdl_type_param_seq* type_params;
        expr_ty value;

        if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from TypeAlias");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'TypeAlias' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &name, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->type_params, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "TypeAlias field \"type_params\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            type_params = _Py_asdl_type_param_seq_new(len, arena);
            if (type_params == NULL) goto failed;
            for (i = 0; i < len; i++) {
                type_param_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'TypeAlias' node")) {
                    goto failed;
                }
                res = obj2ast_type_param(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "TypeAlias field \"type_params\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(type_params, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from TypeAlias");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'TypeAlias' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &value, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_TypeAlias(name, type_params, value, lineno, col_offset,
                                end_lineno, end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->AugAssign_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty target;
        operator_ty op;
        expr_ty value;

        if (_PyObject_LookupAttr(obj, state->target, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from AugAssign");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'AugAssign' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &target, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->op, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from AugAssign");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'AugAssign' node")) {
                goto failed;
            }
            res = obj2ast_operator(state, tmp, &op, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from AugAssign");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'AugAssign' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &value, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_AugAssign(target, op, value, lineno, col_offset,
                                end_lineno, end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->AnnAssign_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty target;
        expr_ty annotation;
        expr_ty value;
        int simple;

        if (_PyObject_LookupAttr(obj, state->target, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from AnnAssign");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'AnnAssign' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &target, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->annotation, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"annotation\" missing from AnnAssign");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'AnnAssign' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &annotation, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            value = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'AnnAssign' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &value, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->simple, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"simple\" missing from AnnAssign");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'AnnAssign' node")) {
                goto failed;
            }
            res = obj2ast_int(state, tmp, &simple, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_AnnAssign(target, annotation, value, simple, lineno,
                                col_offset, end_lineno, end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->For_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty target;
        expr_ty iter;
        asdl_stmt_seq* body;
        asdl_stmt_seq* orelse;
        string type_comment;

        if (_PyObject_LookupAttr(obj, state->target, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from For");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'For' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &target, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->iter, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"iter\" missing from For");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'For' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &iter, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "For field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            body = _Py_asdl_stmt_seq_new(len, arena);
            if (body == NULL) goto failed;
            for (i = 0; i < len; i++) {
                stmt_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'For' node")) {
                    goto failed;
                }
                res = obj2ast_stmt(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "For field \"body\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(body, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->orelse, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "For field \"orelse\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            orelse = _Py_asdl_stmt_seq_new(len, arena);
            if (orelse == NULL) goto failed;
            for (i = 0; i < len; i++) {
                stmt_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'For' node")) {
                    goto failed;
                }
                res = obj2ast_stmt(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "For field \"orelse\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(orelse, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->type_comment, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            type_comment = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'For' node")) {
                goto failed;
            }
            res = obj2ast_string(state, tmp, &type_comment, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_For(target, iter, body, orelse, type_comment, lineno,
                          col_offset, end_lineno, end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->AsyncFor_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty target;
        expr_ty iter;
        asdl_stmt_seq* body;
        asdl_stmt_seq* orelse;
        string type_comment;

        if (_PyObject_LookupAttr(obj, state->target, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from AsyncFor");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &target, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->iter, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"iter\" missing from AsyncFor");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &iter, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "AsyncFor field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            body = _Py_asdl_stmt_seq_new(len, arena);
            if (body == NULL) goto failed;
            for (i = 0; i < len; i++) {
                stmt_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) {
                    goto failed;
                }
                res = obj2ast_stmt(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "AsyncFor field \"body\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(body, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->orelse, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "AsyncFor field \"orelse\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            orelse = _Py_asdl_stmt_seq_new(len, arena);
            if (orelse == NULL) goto failed;
            for (i = 0; i < len; i++) {
                stmt_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) {
                    goto failed;
                }
                res = obj2ast_stmt(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "AsyncFor field \"orelse\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(orelse, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->type_comment, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            type_comment = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) {
                goto failed;
            }
            res = obj2ast_string(state, tmp, &type_comment, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_AsyncFor(target, iter, body, orelse, type_comment,
                               lineno, col_offset, end_lineno, end_col_offset,
                               arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->While_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty test;
        asdl_stmt_seq* body;
        asdl_stmt_seq* orelse;

        if (_PyObject_LookupAttr(obj, state->test, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from While");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'While' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &test, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "While field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            body = _Py_asdl_stmt_seq_new(len, arena);
            if (body == NULL) goto failed;
            for (i = 0; i < len; i++) {
                stmt_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'While' node")) {
                    goto failed;
                }
                res = obj2ast_stmt(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "While field \"body\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(body, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->orelse, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "While field \"orelse\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            orelse = _Py_asdl_stmt_seq_new(len, arena);
            if (orelse == NULL) goto failed;
            for (i = 0; i < len; i++) {
                stmt_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'While' node")) {
                    goto failed;
                }
                res = obj2ast_stmt(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "While field \"orelse\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(orelse, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_While(test, body, orelse, lineno, col_offset, end_lineno,
                            end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->If_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty test;
        asdl_stmt_seq* body;
        asdl_stmt_seq* orelse;

        if (_PyObject_LookupAttr(obj, state->test, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from If");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'If' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &test, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "If field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            body = _Py_asdl_stmt_seq_new(len, arena);
            if (body == NULL) goto failed;
            for (i = 0; i < len; i++) {
                stmt_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'If' node")) {
                    goto failed;
                }
                res = obj2ast_stmt(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "If field \"body\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(body, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->orelse, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "If field \"orelse\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            orelse = _Py_asdl_stmt_seq_new(len, arena);
            if (orelse == NULL) goto failed;
            for (i = 0; i < len; i++) {
                stmt_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'If' node")) {
                    goto failed;
                }
                res = obj2ast_stmt(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "If field \"orelse\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(orelse, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_If(test, body, orelse, lineno, col_offset, end_lineno,
                         end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->With_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        asdl_withitem_seq* items;
        asdl_stmt_seq* body;
        string type_comment;

        if (_PyObject_LookupAttr(obj, state->items, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "With field \"items\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            items = _Py_asdl_withitem_seq_new(len, arena);
            if (items == NULL) goto failed;
            for (i = 0; i < len; i++) {
                withitem_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'With' node")) {
                    goto failed;
                }
                res = obj2ast_withitem(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "With field \"items\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(items, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "With field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            body = _Py_asdl_stmt_seq_new(len, arena);
            if (body == NULL) goto failed;
            for (i = 0; i < len; i++) {
                stmt_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'With' node")) {
                    goto failed;
                }
                res = obj2ast_stmt(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "With field \"body\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(body, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->type_comment, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            type_comment = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'With' node")) {
                goto failed;
            }
            res = obj2ast_string(state, tmp, &type_comment, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_With(items, body, type_comment, lineno, col_offset,
                           end_lineno, end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->AsyncWith_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        asdl_withitem_seq* items;
        asdl_stmt_seq* body;
        string type_comment;

        if (_PyObject_LookupAttr(obj, state->items, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "AsyncWith field \"items\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            items = _Py_asdl_withitem_seq_new(len, arena);
            if (items == NULL) goto failed;
            for (i = 0; i < len; i++) {
                withitem_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'AsyncWith' node")) {
                    goto failed;
                }
                res = obj2ast_withitem(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "AsyncWith field \"items\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(items, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "AsyncWith field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            body = _Py_asdl_stmt_seq_new(len, arena);
            if (body == NULL) goto failed;
            for (i = 0; i < len; i++) {
                stmt_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'AsyncWith' node")) {
                    goto failed;
                }
                res = obj2ast_stmt(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "AsyncWith field \"body\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(body, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->type_comment, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            type_comment = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'AsyncWith' node")) {
                goto failed;
            }
            res = obj2ast_string(state, tmp, &type_comment, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_AsyncWith(items, body, type_comment, lineno, col_offset,
                                end_lineno, end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Match_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty subject;
        asdl_match_case_seq* cases;

        if (_PyObject_LookupAttr(obj, state->subject, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"subject\" missing from Match");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Match' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &subject, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->cases, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "Match field \"cases\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            cases = _Py_asdl_match_case_seq_new(len, arena);
            if (cases == NULL) goto failed;
            for (i = 0; i < len; i++) {
                match_case_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'Match' node")) {
                    goto failed;
                }
                res = obj2ast_match_case(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "Match field \"cases\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(cases, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Match(subject, cases, lineno, col_offset, end_lineno,
                            end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Raise_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty exc;
        expr_ty cause;

        if (_PyObject_LookupAttr(obj, state->exc, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            exc = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Raise' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &exc, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->cause, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            cause = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Raise' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &cause, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Raise(exc, cause, lineno, col_offset, end_lineno,
                            end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Try_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        asdl_stmt_seq* body;
        asdl_excepthandler_seq* handlers;
        asdl_stmt_seq* orelse;
        asdl_stmt_seq* finalbody;

        if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "Try field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            body = _Py_asdl_stmt_seq_new(len, arena);
            if (body == NULL) goto failed;
            for (i = 0; i < len; i++) {
                stmt_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'Try' node")) {
                    goto failed;
                }
                res = obj2ast_stmt(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "Try field \"body\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(body, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->handlers, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "Try field \"handlers\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            handlers = _Py_asdl_excepthandler_seq_new(len, arena);
            if (handlers == NULL) goto failed;
            for (i = 0; i < len; i++) {
                excepthandler_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'Try' node")) {
                    goto failed;
                }
                res = obj2ast_excepthandler(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "Try field \"handlers\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(handlers, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->orelse, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "Try field \"orelse\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            orelse = _Py_asdl_stmt_seq_new(len, arena);
            if (orelse == NULL) goto failed;
            for (i = 0; i < len; i++) {
                stmt_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'Try' node")) {
                    goto failed;
                }
                res = obj2ast_stmt(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "Try field \"orelse\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(orelse, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->finalbody, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "Try field \"finalbody\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            finalbody = _Py_asdl_stmt_seq_new(len, arena);
            if (finalbody == NULL) goto failed;
            for (i = 0; i < len; i++) {
                stmt_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'Try' node")) {
                    goto failed;
                }
                res = obj2ast_stmt(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "Try field \"finalbody\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(finalbody, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Try(body, handlers, orelse, finalbody, lineno,
                          col_offset, end_lineno, end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->TryStar_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        asdl_stmt_seq* body;
        asdl_excepthandler_seq* handlers;
        asdl_stmt_seq* orelse;
        asdl_stmt_seq* finalbody;

        if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "TryStar field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            body = _Py_asdl_stmt_seq_new(len, arena);
            if (body == NULL) goto failed;
            for (i = 0; i < len; i++) {
                stmt_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'TryStar' node")) {
                    goto failed;
                }
                res = obj2ast_stmt(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "TryStar field \"body\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(body, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->handlers, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "TryStar field \"handlers\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            handlers = _Py_asdl_excepthandler_seq_new(len, arena);
            if (handlers == NULL) goto failed;
            for (i = 0; i < len; i++) {
                excepthandler_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'TryStar' node")) {
                    goto failed;
                }
                res = obj2ast_excepthandler(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "TryStar field \"handlers\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(handlers, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->orelse, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "TryStar field \"orelse\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            orelse = _Py_asdl_stmt_seq_new(len, arena);
            if (orelse == NULL) goto failed;
            for (i = 0; i < len; i++) {
                stmt_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'TryStar' node")) {
                    goto failed;
                }
                res = obj2ast_stmt(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "TryStar field \"orelse\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(orelse, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->finalbody, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "TryStar field \"finalbody\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            finalbody = _Py_asdl_stmt_seq_new(len, arena);
            if (finalbody == NULL) goto failed;
            for (i = 0; i < len; i++) {
                stmt_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'TryStar' node")) {
                    goto failed;
                }
                res = obj2ast_stmt(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "TryStar field \"finalbody\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(finalbody, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_TryStar(body, handlers, orelse, finalbody, lineno,
                              col_offset, end_lineno, end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Assert_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty test;
        expr_ty msg;

        if (_PyObject_LookupAttr(obj, state->test, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from Assert");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Assert' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &test, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->msg, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            msg = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Assert' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &msg, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Assert(test, msg, lineno, col_offset, end_lineno,
                             end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Import_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        asdl_alias_seq* names;

        if (_PyObject_LookupAttr(obj, state->names, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "Import field \"names\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            names = _Py_asdl_alias_seq_new(len, arena);
            if (names == NULL) goto failed;
            for (i = 0; i < len; i++) {
                alias_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'Import' node")) {
                    goto failed;
                }
                res = obj2ast_alias(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "Import field \"names\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(names, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Import(names, lineno, col_offset, end_lineno,
                             end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->ImportFrom_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        identifier module;
        asdl_alias_seq* names;
        int level;

        if (_PyObject_LookupAttr(obj, state->module, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            module = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'ImportFrom' node")) {
                goto failed;
            }
            res = obj2ast_identifier(state, tmp, &module, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->names, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "ImportFrom field \"names\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            names = _Py_asdl_alias_seq_new(len, arena);
            if (names == NULL) goto failed;
            for (i = 0; i < len; i++) {
                alias_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'ImportFrom' node")) {
                    goto failed;
                }
                res = obj2ast_alias(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "ImportFrom field \"names\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(names, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->level, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            level = 0;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'ImportFrom' node")) {
                goto failed;
            }
            res = obj2ast_int(state, tmp, &level, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_ImportFrom(module, names, level, lineno, col_offset,
                                 end_lineno, end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Global_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        asdl_identifier_seq* names;

        if (_PyObject_LookupAttr(obj, state->names, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "Global field \"names\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            names = _Py_asdl_identifier_seq_new(len, arena);
            if (names == NULL) goto failed;
            for (i = 0; i < len; i++) {
                identifier val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'Global' node")) {
                    goto failed;
                }
                res = obj2ast_identifier(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "Global field \"names\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(names, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Global(names, lineno, col_offset, end_lineno,
                             end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Nonlocal_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        asdl_identifier_seq* names;

        if (_PyObject_LookupAttr(obj, state->names, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "Nonlocal field \"names\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            names = _Py_asdl_identifier_seq_new(len, arena);
            if (names == NULL) goto failed;
            for (i = 0; i < len; i++) {
                identifier val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'Nonlocal' node")) {
                    goto failed;
                }
                res = obj2ast_identifier(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "Nonlocal field \"names\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(names, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Nonlocal(names, lineno, col_offset, end_lineno,
                               end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Expr_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty value;

        if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Expr");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Expr' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &value, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Expr(value, lineno, col_offset, end_lineno,
                           end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Pass_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {

        *out = _PyAST_Pass(lineno, col_offset, end_lineno, end_col_offset,
                           arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Break_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {

        *out = _PyAST_Break(lineno, col_offset, end_lineno, end_col_offset,
                            arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Continue_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {

        *out = _PyAST_Continue(lineno, col_offset, end_lineno, end_col_offset,
                               arena);
        if (*out == NULL) goto failed;
        return 0;
    }

    PyErr_Format(PyExc_TypeError, "expected some sort of stmt, but got %R", obj);
    failed:
    Py_XDECREF(tmp);
    return 1;
}

int
obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena*
             arena)
{
    int isinstance;

    PyObject *tmp = NULL;
    PyObject *tp;
    int lineno;
    int col_offset;
    int end_lineno;
    int end_col_offset;

    if (obj == Py_None) {
        *out = NULL;
        return 0;
    }
    if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from expr");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'expr' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &lineno, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->col_offset, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from expr");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'expr' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &col_offset, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->end_lineno, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL || tmp == Py_None) {
        Py_CLEAR(tmp);
        end_lineno = lineno;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'expr' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &end_lineno, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->end_col_offset, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL || tmp == Py_None) {
        Py_CLEAR(tmp);
        end_col_offset = col_offset;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'expr' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &end_col_offset, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    tp = state->BoolOp_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        boolop_ty op;
        asdl_expr_seq* values;

        if (_PyObject_LookupAttr(obj, state->op, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from BoolOp");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'BoolOp' node")) {
                goto failed;
            }
            res = obj2ast_boolop(state, tmp, &op, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->values, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "BoolOp field \"values\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            values = _Py_asdl_expr_seq_new(len, arena);
            if (values == NULL) goto failed;
            for (i = 0; i < len; i++) {
                expr_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'BoolOp' node")) {
                    goto failed;
                }
                res = obj2ast_expr(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "BoolOp field \"values\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(values, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_BoolOp(op, values, lineno, col_offset, end_lineno,
                             end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->NamedExpr_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty target;
        expr_ty value;

        if (_PyObject_LookupAttr(obj, state->target, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from NamedExpr");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'NamedExpr' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &target, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from NamedExpr");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'NamedExpr' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &value, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_NamedExpr(target, value, lineno, col_offset, end_lineno,
                                end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->BinOp_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty left;
        operator_ty op;
        expr_ty right;

        if (_PyObject_LookupAttr(obj, state->left, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"left\" missing from BinOp");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'BinOp' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &left, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->op, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from BinOp");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'BinOp' node")) {
                goto failed;
            }
            res = obj2ast_operator(state, tmp, &op, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->right, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"right\" missing from BinOp");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'BinOp' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &right, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_BinOp(left, op, right, lineno, col_offset, end_lineno,
                            end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->UnaryOp_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        unaryop_ty op;
        expr_ty operand;

        if (_PyObject_LookupAttr(obj, state->op, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from UnaryOp");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'UnaryOp' node")) {
                goto failed;
            }
            res = obj2ast_unaryop(state, tmp, &op, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->operand, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"operand\" missing from UnaryOp");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'UnaryOp' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &operand, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_UnaryOp(op, operand, lineno, col_offset, end_lineno,
                              end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Lambda_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        arguments_ty args;
        expr_ty body;

        if (_PyObject_LookupAttr(obj, state->args, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from Lambda");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Lambda' node")) {
                goto failed;
            }
            res = obj2ast_arguments(state, tmp, &args, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Lambda");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Lambda' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &body, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Lambda(args, body, lineno, col_offset, end_lineno,
                             end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->IfExp_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty test;
        expr_ty body;
        expr_ty orelse;

        if (_PyObject_LookupAttr(obj, state->test, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from IfExp");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'IfExp' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &test, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from IfExp");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'IfExp' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &body, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->orelse, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from IfExp");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'IfExp' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &orelse, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_IfExp(test, body, orelse, lineno, col_offset, end_lineno,
                            end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Dict_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        asdl_expr_seq* keys;
        asdl_expr_seq* values;

        if (_PyObject_LookupAttr(obj, state->keys, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "Dict field \"keys\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            keys = _Py_asdl_expr_seq_new(len, arena);
            if (keys == NULL) goto failed;
            for (i = 0; i < len; i++) {
                expr_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'Dict' node")) {
                    goto failed;
                }
                res = obj2ast_expr(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "Dict field \"keys\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(keys, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->values, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "Dict field \"values\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            values = _Py_asdl_expr_seq_new(len, arena);
            if (values == NULL) goto failed;
            for (i = 0; i < len; i++) {
                expr_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'Dict' node")) {
                    goto failed;
                }
                res = obj2ast_expr(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "Dict field \"values\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(values, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Dict(keys, values, lineno, col_offset, end_lineno,
                           end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Set_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        asdl_expr_seq* elts;

        if (_PyObject_LookupAttr(obj, state->elts, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "Set field \"elts\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            elts = _Py_asdl_expr_seq_new(len, arena);
            if (elts == NULL) goto failed;
            for (i = 0; i < len; i++) {
                expr_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'Set' node")) {
                    goto failed;
                }
                res = obj2ast_expr(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "Set field \"elts\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(elts, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Set(elts, lineno, col_offset, end_lineno, end_col_offset,
                          arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->ListComp_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty elt;
        asdl_comprehension_seq* generators;

        if (_PyObject_LookupAttr(obj, state->elt, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"elt\" missing from ListComp");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'ListComp' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &elt, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->generators, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "ListComp field \"generators\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            generators = _Py_asdl_comprehension_seq_new(len, arena);
            if (generators == NULL) goto failed;
            for (i = 0; i < len; i++) {
                comprehension_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'ListComp' node")) {
                    goto failed;
                }
                res = obj2ast_comprehension(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "ListComp field \"generators\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(generators, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_ListComp(elt, generators, lineno, col_offset, end_lineno,
                               end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->SetComp_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty elt;
        asdl_comprehension_seq* generators;

        if (_PyObject_LookupAttr(obj, state->elt, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"elt\" missing from SetComp");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'SetComp' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &elt, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->generators, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "SetComp field \"generators\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            generators = _Py_asdl_comprehension_seq_new(len, arena);
            if (generators == NULL) goto failed;
            for (i = 0; i < len; i++) {
                comprehension_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'SetComp' node")) {
                    goto failed;
                }
                res = obj2ast_comprehension(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "SetComp field \"generators\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(generators, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_SetComp(elt, generators, lineno, col_offset, end_lineno,
                              end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->DictComp_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty key;
        expr_ty value;
        asdl_comprehension_seq* generators;

        if (_PyObject_LookupAttr(obj, state->key, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"key\" missing from DictComp");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'DictComp' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &key, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from DictComp");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'DictComp' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &value, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->generators, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "DictComp field \"generators\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            generators = _Py_asdl_comprehension_seq_new(len, arena);
            if (generators == NULL) goto failed;
            for (i = 0; i < len; i++) {
                comprehension_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'DictComp' node")) {
                    goto failed;
                }
                res = obj2ast_comprehension(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "DictComp field \"generators\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(generators, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_DictComp(key, value, generators, lineno, col_offset,
                               end_lineno, end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->GeneratorExp_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty elt;
        asdl_comprehension_seq* generators;

        if (_PyObject_LookupAttr(obj, state->elt, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"elt\" missing from GeneratorExp");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'GeneratorExp' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &elt, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->generators, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "GeneratorExp field \"generators\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            generators = _Py_asdl_comprehension_seq_new(len, arena);
            if (generators == NULL) goto failed;
            for (i = 0; i < len; i++) {
                comprehension_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'GeneratorExp' node")) {
                    goto failed;
                }
                res = obj2ast_comprehension(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "GeneratorExp field \"generators\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(generators, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_GeneratorExp(elt, generators, lineno, col_offset,
                                   end_lineno, end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Await_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty value;

        if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Await");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Await' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &value, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Await(value, lineno, col_offset, end_lineno,
                            end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Yield_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty value;

        if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            value = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Yield' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &value, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Yield(value, lineno, col_offset, end_lineno,
                            end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->YieldFrom_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty value;

        if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from YieldFrom");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'YieldFrom' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &value, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_YieldFrom(value, lineno, col_offset, end_lineno,
                                end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Compare_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty left;
        asdl_int_seq* ops;
        asdl_expr_seq* comparators;

        if (_PyObject_LookupAttr(obj, state->left, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"left\" missing from Compare");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Compare' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &left, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->ops, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "Compare field \"ops\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            ops = _Py_asdl_int_seq_new(len, arena);
            if (ops == NULL) goto failed;
            for (i = 0; i < len; i++) {
                cmpop_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'Compare' node")) {
                    goto failed;
                }
                res = obj2ast_cmpop(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "Compare field \"ops\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(ops, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->comparators, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "Compare field \"comparators\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            comparators = _Py_asdl_expr_seq_new(len, arena);
            if (comparators == NULL) goto failed;
            for (i = 0; i < len; i++) {
                expr_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'Compare' node")) {
                    goto failed;
                }
                res = obj2ast_expr(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "Compare field \"comparators\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(comparators, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Compare(left, ops, comparators, lineno, col_offset,
                              end_lineno, end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Call_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty func;
        asdl_expr_seq* args;
        asdl_keyword_seq* keywords;

        if (_PyObject_LookupAttr(obj, state->func, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"func\" missing from Call");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Call' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &func, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->args, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "Call field \"args\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            args = _Py_asdl_expr_seq_new(len, arena);
            if (args == NULL) goto failed;
            for (i = 0; i < len; i++) {
                expr_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'Call' node")) {
                    goto failed;
                }
                res = obj2ast_expr(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "Call field \"args\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(args, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->keywords, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "Call field \"keywords\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            keywords = _Py_asdl_keyword_seq_new(len, arena);
            if (keywords == NULL) goto failed;
            for (i = 0; i < len; i++) {
                keyword_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'Call' node")) {
                    goto failed;
                }
                res = obj2ast_keyword(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "Call field \"keywords\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(keywords, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Call(func, args, keywords, lineno, col_offset,
                           end_lineno, end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->FormattedValue_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty value;
        int conversion;
        expr_ty format_spec;

        if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from FormattedValue");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'FormattedValue' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &value, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->conversion, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"conversion\" missing from FormattedValue");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'FormattedValue' node")) {
                goto failed;
            }
            res = obj2ast_int(state, tmp, &conversion, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->format_spec, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            format_spec = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'FormattedValue' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &format_spec, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_FormattedValue(value, conversion, format_spec, lineno,
                                     col_offset, end_lineno, end_col_offset,
                                     arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->JoinedStr_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        asdl_expr_seq* values;

        if (_PyObject_LookupAttr(obj, state->values, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "JoinedStr field \"values\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            values = _Py_asdl_expr_seq_new(len, arena);
            if (values == NULL) goto failed;
            for (i = 0; i < len; i++) {
                expr_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'JoinedStr' node")) {
                    goto failed;
                }
                res = obj2ast_expr(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "JoinedStr field \"values\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(values, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_JoinedStr(values, lineno, col_offset, end_lineno,
                                end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Constant_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        constant value;
        string kind;

        if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Constant");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Constant' node")) {
                goto failed;
            }
            res = obj2ast_constant(state, tmp, &value, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->kind, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            kind = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Constant' node")) {
                goto failed;
            }
            res = obj2ast_string(state, tmp, &kind, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Constant(value, kind, lineno, col_offset, end_lineno,
                               end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Attribute_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty value;
        identifier attr;
        expr_context_ty ctx;

        if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Attribute");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Attribute' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &value, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->attr, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"attr\" missing from Attribute");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Attribute' node")) {
                goto failed;
            }
            res = obj2ast_identifier(state, tmp, &attr, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->ctx, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Attribute");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Attribute' node")) {
                goto failed;
            }
            res = obj2ast_expr_context(state, tmp, &ctx, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Attribute(value, attr, ctx, lineno, col_offset,
                                end_lineno, end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Subscript_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty value;
        expr_ty slice;
        expr_context_ty ctx;

        if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Subscript");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Subscript' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &value, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->slice, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"slice\" missing from Subscript");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Subscript' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &slice, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->ctx, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Subscript");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Subscript' node")) {
                goto failed;
            }
            res = obj2ast_expr_context(state, tmp, &ctx, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Subscript(value, slice, ctx, lineno, col_offset,
                                end_lineno, end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Starred_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty value;
        expr_context_ty ctx;

        if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Starred");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Starred' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &value, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->ctx, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Starred");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Starred' node")) {
                goto failed;
            }
            res = obj2ast_expr_context(state, tmp, &ctx, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Starred(value, ctx, lineno, col_offset, end_lineno,
                              end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Name_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        identifier id;
        expr_context_ty ctx;

        if (_PyObject_LookupAttr(obj, state->id, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"id\" missing from Name");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Name' node")) {
                goto failed;
            }
            res = obj2ast_identifier(state, tmp, &id, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->ctx, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Name");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Name' node")) {
                goto failed;
            }
            res = obj2ast_expr_context(state, tmp, &ctx, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Name(id, ctx, lineno, col_offset, end_lineno,
                           end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->List_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        asdl_expr_seq* elts;
        expr_context_ty ctx;

        if (_PyObject_LookupAttr(obj, state->elts, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "List field \"elts\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            elts = _Py_asdl_expr_seq_new(len, arena);
            if (elts == NULL) goto failed;
            for (i = 0; i < len; i++) {
                expr_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'List' node")) {
                    goto failed;
                }
                res = obj2ast_expr(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "List field \"elts\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(elts, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->ctx, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from List");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'List' node")) {
                goto failed;
            }
            res = obj2ast_expr_context(state, tmp, &ctx, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_List(elts, ctx, lineno, col_offset, end_lineno,
                           end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Tuple_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        asdl_expr_seq* elts;
        expr_context_ty ctx;

        if (_PyObject_LookupAttr(obj, state->elts, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "Tuple field \"elts\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            elts = _Py_asdl_expr_seq_new(len, arena);
            if (elts == NULL) goto failed;
            for (i = 0; i < len; i++) {
                expr_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'Tuple' node")) {
                    goto failed;
                }
                res = obj2ast_expr(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "Tuple field \"elts\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(elts, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->ctx, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"ctx\" missing from Tuple");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Tuple' node")) {
                goto failed;
            }
            res = obj2ast_expr_context(state, tmp, &ctx, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Tuple(elts, ctx, lineno, col_offset, end_lineno,
                            end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->Slice_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty lower;
        expr_ty upper;
        expr_ty step;

        if (_PyObject_LookupAttr(obj, state->lower, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            lower = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Slice' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &lower, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->upper, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            upper = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Slice' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &upper, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->step, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            step = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'Slice' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &step, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_Slice(lower, upper, step, lineno, col_offset, end_lineno,
                            end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }

    PyErr_Format(PyExc_TypeError, "expected some sort of expr, but got %R", obj);
    failed:
    Py_XDECREF(tmp);
    return 1;
}

int
obj2ast_expr_context(struct ast_state *state, PyObject* obj, expr_context_ty*
                     out, PyArena* arena)
{
    int isinstance;

    isinstance = PyObject_IsInstance(obj, state->Load_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = Load;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->Store_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = Store;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->Del_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = Del;
        return 0;
    }

    PyErr_Format(PyExc_TypeError, "expected some sort of expr_context, but got %R", obj);
    return 1;
}

int
obj2ast_boolop(struct ast_state *state, PyObject* obj, boolop_ty* out, PyArena*
               arena)
{
    int isinstance;

    isinstance = PyObject_IsInstance(obj, state->And_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = And;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->Or_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = Or;
        return 0;
    }

    PyErr_Format(PyExc_TypeError, "expected some sort of boolop, but got %R", obj);
    return 1;
}

int
obj2ast_operator(struct ast_state *state, PyObject* obj, operator_ty* out,
                 PyArena* arena)
{
    int isinstance;

    isinstance = PyObject_IsInstance(obj, state->Add_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = Add;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->Sub_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = Sub;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->Mult_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = Mult;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->MatMult_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = MatMult;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->Div_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = Div;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->Mod_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = Mod;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->Pow_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = Pow;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->LShift_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = LShift;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->RShift_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = RShift;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->BitOr_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = BitOr;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->BitXor_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = BitXor;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->BitAnd_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = BitAnd;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->FloorDiv_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = FloorDiv;
        return 0;
    }

    PyErr_Format(PyExc_TypeError, "expected some sort of operator, but got %R", obj);
    return 1;
}

int
obj2ast_unaryop(struct ast_state *state, PyObject* obj, unaryop_ty* out,
                PyArena* arena)
{
    int isinstance;

    isinstance = PyObject_IsInstance(obj, state->Invert_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = Invert;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->Not_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = Not;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->UAdd_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = UAdd;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->USub_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = USub;
        return 0;
    }

    PyErr_Format(PyExc_TypeError, "expected some sort of unaryop, but got %R", obj);
    return 1;
}

int
obj2ast_cmpop(struct ast_state *state, PyObject* obj, cmpop_ty* out, PyArena*
              arena)
{
    int isinstance;

    isinstance = PyObject_IsInstance(obj, state->Eq_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = Eq;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->NotEq_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = NotEq;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->Lt_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = Lt;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->LtE_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = LtE;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->Gt_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = Gt;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->GtE_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = GtE;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->Is_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = Is;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->IsNot_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = IsNot;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->In_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = In;
        return 0;
    }
    isinstance = PyObject_IsInstance(obj, state->NotIn_type);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        *out = NotIn;
        return 0;
    }

    PyErr_Format(PyExc_TypeError, "expected some sort of cmpop, but got %R", obj);
    return 1;
}

int
obj2ast_comprehension(struct ast_state *state, PyObject* obj, comprehension_ty*
                      out, PyArena* arena)
{
    PyObject* tmp = NULL;
    expr_ty target;
    expr_ty iter;
    asdl_expr_seq* ifs;
    int is_async;

    if (_PyObject_LookupAttr(obj, state->target, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from comprehension");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'comprehension' node")) {
            goto failed;
        }
        res = obj2ast_expr(state, tmp, &target, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->iter, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"iter\" missing from comprehension");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'comprehension' node")) {
            goto failed;
        }
        res = obj2ast_expr(state, tmp, &iter, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->ifs, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        tmp = PyList_New(0);
        if (tmp == NULL) {
            return 1;
        }
    }
    {
        int res;
        Py_ssize_t len;
        Py_ssize_t i;
        if (!PyList_Check(tmp)) {
            PyErr_Format(PyExc_TypeError, "comprehension field \"ifs\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
            goto failed;
        }
        len = PyList_GET_SIZE(tmp);
        ifs = _Py_asdl_expr_seq_new(len, arena);
        if (ifs == NULL) goto failed;
        for (i = 0; i < len; i++) {
            expr_ty val;
            PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
            if (_Py_EnterRecursiveCall(" while traversing 'comprehension' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp2, &val, arena);
            _Py_LeaveRecursiveCall();
            Py_DECREF(tmp2);
            if (res != 0) goto failed;
            if (len != PyList_GET_SIZE(tmp)) {
                PyErr_SetString(PyExc_RuntimeError, "comprehension field \"ifs\" changed size during iteration");
                goto failed;
            }
            asdl_seq_SET(ifs, i, val);
        }
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->is_async, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"is_async\" missing from comprehension");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'comprehension' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &is_async, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    *out = _PyAST_comprehension(target, iter, ifs, is_async, arena);
    return 0;
failed:
    Py_XDECREF(tmp);
    return 1;
}

int
obj2ast_excepthandler(struct ast_state *state, PyObject* obj, excepthandler_ty*
                      out, PyArena* arena)
{
    int isinstance;

    PyObject *tmp = NULL;
    PyObject *tp;
    int lineno;
    int col_offset;
    int end_lineno;
    int end_col_offset;

    if (obj == Py_None) {
        *out = NULL;
        return 0;
    }
    if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from excepthandler");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'excepthandler' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &lineno, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->col_offset, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from excepthandler");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'excepthandler' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &col_offset, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->end_lineno, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL || tmp == Py_None) {
        Py_CLEAR(tmp);
        end_lineno = lineno;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'excepthandler' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &end_lineno, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->end_col_offset, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL || tmp == Py_None) {
        Py_CLEAR(tmp);
        end_col_offset = col_offset;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'excepthandler' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &end_col_offset, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    tp = state->ExceptHandler_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty type;
        identifier name;
        asdl_stmt_seq* body;

        if (_PyObject_LookupAttr(obj, state->type, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            type = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'ExceptHandler' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &type, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            name = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'ExceptHandler' node")) {
                goto failed;
            }
            res = obj2ast_identifier(state, tmp, &name, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "ExceptHandler field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            body = _Py_asdl_stmt_seq_new(len, arena);
            if (body == NULL) goto failed;
            for (i = 0; i < len; i++) {
                stmt_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'ExceptHandler' node")) {
                    goto failed;
                }
                res = obj2ast_stmt(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "ExceptHandler field \"body\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(body, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_ExceptHandler(type, name, body, lineno, col_offset,
                                    end_lineno, end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }

    PyErr_Format(PyExc_TypeError, "expected some sort of excepthandler, but got %R", obj);
    failed:
    Py_XDECREF(tmp);
    return 1;
}

int
obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out,
                  PyArena* arena)
{
    PyObject* tmp = NULL;
    asdl_arg_seq* posonlyargs;
    asdl_arg_seq* args;
    arg_ty vararg;
    asdl_arg_seq* kwonlyargs;
    asdl_expr_seq* kw_defaults;
    arg_ty kwarg;
    asdl_expr_seq* defaults;

    if (_PyObject_LookupAttr(obj, state->posonlyargs, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        tmp = PyList_New(0);
        if (tmp == NULL) {
            return 1;
        }
    }
    {
        int res;
        Py_ssize_t len;
        Py_ssize_t i;
        if (!PyList_Check(tmp)) {
            PyErr_Format(PyExc_TypeError, "arguments field \"posonlyargs\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
            goto failed;
        }
        len = PyList_GET_SIZE(tmp);
        posonlyargs = _Py_asdl_arg_seq_new(len, arena);
        if (posonlyargs == NULL) goto failed;
        for (i = 0; i < len; i++) {
            arg_ty val;
            PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
            if (_Py_EnterRecursiveCall(" while traversing 'arguments' node")) {
                goto failed;
            }
            res = obj2ast_arg(state, tmp2, &val, arena);
            _Py_LeaveRecursiveCall();
            Py_DECREF(tmp2);
            if (res != 0) goto failed;
            if (len != PyList_GET_SIZE(tmp)) {
                PyErr_SetString(PyExc_RuntimeError, "arguments field \"posonlyargs\" changed size during iteration");
                goto failed;
            }
            asdl_seq_SET(posonlyargs, i, val);
        }
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->args, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        tmp = PyList_New(0);
        if (tmp == NULL) {
            return 1;
        }
    }
    {
        int res;
        Py_ssize_t len;
        Py_ssize_t i;
        if (!PyList_Check(tmp)) {
            PyErr_Format(PyExc_TypeError, "arguments field \"args\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
            goto failed;
        }
        len = PyList_GET_SIZE(tmp);
        args = _Py_asdl_arg_seq_new(len, arena);
        if (args == NULL) goto failed;
        for (i = 0; i < len; i++) {
            arg_ty val;
            PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
            if (_Py_EnterRecursiveCall(" while traversing 'arguments' node")) {
                goto failed;
            }
            res = obj2ast_arg(state, tmp2, &val, arena);
            _Py_LeaveRecursiveCall();
            Py_DECREF(tmp2);
            if (res != 0) goto failed;
            if (len != PyList_GET_SIZE(tmp)) {
                PyErr_SetString(PyExc_RuntimeError, "arguments field \"args\" changed size during iteration");
                goto failed;
            }
            asdl_seq_SET(args, i, val);
        }
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->vararg, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL || tmp == Py_None) {
        Py_CLEAR(tmp);
        vararg = NULL;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'arguments' node")) {
            goto failed;
        }
        res = obj2ast_arg(state, tmp, &vararg, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->kwonlyargs, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        tmp = PyList_New(0);
        if (tmp == NULL) {
            return 1;
        }
    }
    {
        int res;
        Py_ssize_t len;
        Py_ssize_t i;
        if (!PyList_Check(tmp)) {
            PyErr_Format(PyExc_TypeError, "arguments field \"kwonlyargs\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
            goto failed;
        }
        len = PyList_GET_SIZE(tmp);
        kwonlyargs = _Py_asdl_arg_seq_new(len, arena);
        if (kwonlyargs == NULL) goto failed;
        for (i = 0; i < len; i++) {
            arg_ty val;
            PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
            if (_Py_EnterRecursiveCall(" while traversing 'arguments' node")) {
                goto failed;
            }
            res = obj2ast_arg(state, tmp2, &val, arena);
            _Py_LeaveRecursiveCall();
            Py_DECREF(tmp2);
            if (res != 0) goto failed;
            if (len != PyList_GET_SIZE(tmp)) {
                PyErr_SetString(PyExc_RuntimeError, "arguments field \"kwonlyargs\" changed size during iteration");
                goto failed;
            }
            asdl_seq_SET(kwonlyargs, i, val);
        }
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->kw_defaults, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        tmp = PyList_New(0);
        if (tmp == NULL) {
            return 1;
        }
    }
    {
        int res;
        Py_ssize_t len;
        Py_ssize_t i;
        if (!PyList_Check(tmp)) {
            PyErr_Format(PyExc_TypeError, "arguments field \"kw_defaults\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
            goto failed;
        }
        len = PyList_GET_SIZE(tmp);
        kw_defaults = _Py_asdl_expr_seq_new(len, arena);
        if (kw_defaults == NULL) goto failed;
        for (i = 0; i < len; i++) {
            expr_ty val;
            PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
            if (_Py_EnterRecursiveCall(" while traversing 'arguments' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp2, &val, arena);
            _Py_LeaveRecursiveCall();
            Py_DECREF(tmp2);
            if (res != 0) goto failed;
            if (len != PyList_GET_SIZE(tmp)) {
                PyErr_SetString(PyExc_RuntimeError, "arguments field \"kw_defaults\" changed size during iteration");
                goto failed;
            }
            asdl_seq_SET(kw_defaults, i, val);
        }
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->kwarg, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL || tmp == Py_None) {
        Py_CLEAR(tmp);
        kwarg = NULL;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'arguments' node")) {
            goto failed;
        }
        res = obj2ast_arg(state, tmp, &kwarg, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->defaults, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        tmp = PyList_New(0);
        if (tmp == NULL) {
            return 1;
        }
    }
    {
        int res;
        Py_ssize_t len;
        Py_ssize_t i;
        if (!PyList_Check(tmp)) {
            PyErr_Format(PyExc_TypeError, "arguments field \"defaults\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
            goto failed;
        }
        len = PyList_GET_SIZE(tmp);
        defaults = _Py_asdl_expr_seq_new(len, arena);
        if (defaults == NULL) goto failed;
        for (i = 0; i < len; i++) {
            expr_ty val;
            PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
            if (_Py_EnterRecursiveCall(" while traversing 'arguments' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp2, &val, arena);
            _Py_LeaveRecursiveCall();
            Py_DECREF(tmp2);
            if (res != 0) goto failed;
            if (len != PyList_GET_SIZE(tmp)) {
                PyErr_SetString(PyExc_RuntimeError, "arguments field \"defaults\" changed size during iteration");
                goto failed;
            }
            asdl_seq_SET(defaults, i, val);
        }
        Py_CLEAR(tmp);
    }
    *out = _PyAST_arguments(posonlyargs, args, vararg, kwonlyargs, kw_defaults,
                            kwarg, defaults, arena);
    return 0;
failed:
    Py_XDECREF(tmp);
    return 1;
}

int
obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out, PyArena* arena)
{
    PyObject* tmp = NULL;
    identifier arg;
    expr_ty annotation;
    string type_comment;
    int lineno;
    int col_offset;
    int end_lineno;
    int end_col_offset;

    if (_PyObject_LookupAttr(obj, state->arg, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"arg\" missing from arg");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'arg' node")) {
            goto failed;
        }
        res = obj2ast_identifier(state, tmp, &arg, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->annotation, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL || tmp == Py_None) {
        Py_CLEAR(tmp);
        annotation = NULL;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'arg' node")) {
            goto failed;
        }
        res = obj2ast_expr(state, tmp, &annotation, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->type_comment, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL || tmp == Py_None) {
        Py_CLEAR(tmp);
        type_comment = NULL;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'arg' node")) {
            goto failed;
        }
        res = obj2ast_string(state, tmp, &type_comment, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from arg");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'arg' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &lineno, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->col_offset, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from arg");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'arg' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &col_offset, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->end_lineno, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL || tmp == Py_None) {
        Py_CLEAR(tmp);
        end_lineno = lineno;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'arg' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &end_lineno, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->end_col_offset, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL || tmp == Py_None) {
        Py_CLEAR(tmp);
        end_col_offset = col_offset;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'arg' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &end_col_offset, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    *out = _PyAST_arg(arg, annotation, type_comment, lineno, col_offset,
                      end_lineno, end_col_offset, arena);
    return 0;
failed:
    Py_XDECREF(tmp);
    return 1;
}

int
obj2ast_keyword(struct ast_state *state, PyObject* obj, keyword_ty* out,
                PyArena* arena)
{
    PyObject* tmp = NULL;
    identifier arg;
    expr_ty value;
    int lineno;
    int col_offset;
    int end_lineno;
    int end_col_offset;

    if (_PyObject_LookupAttr(obj, state->arg, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL || tmp == Py_None) {
        Py_CLEAR(tmp);
        arg = NULL;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'keyword' node")) {
            goto failed;
        }
        res = obj2ast_identifier(state, tmp, &arg, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from keyword");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'keyword' node")) {
            goto failed;
        }
        res = obj2ast_expr(state, tmp, &value, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from keyword");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'keyword' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &lineno, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->col_offset, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from keyword");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'keyword' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &col_offset, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->end_lineno, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL || tmp == Py_None) {
        Py_CLEAR(tmp);
        end_lineno = lineno;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'keyword' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &end_lineno, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->end_col_offset, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL || tmp == Py_None) {
        Py_CLEAR(tmp);
        end_col_offset = col_offset;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'keyword' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &end_col_offset, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    *out = _PyAST_keyword(arg, value, lineno, col_offset, end_lineno,
                          end_col_offset, arena);
    return 0;
failed:
    Py_XDECREF(tmp);
    return 1;
}

int
obj2ast_alias(struct ast_state *state, PyObject* obj, alias_ty* out, PyArena*
              arena)
{
    PyObject* tmp = NULL;
    identifier name;
    identifier asname;
    int lineno;
    int col_offset;
    int end_lineno;
    int end_col_offset;

    if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from alias");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'alias' node")) {
            goto failed;
        }
        res = obj2ast_identifier(state, tmp, &name, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->asname, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL || tmp == Py_None) {
        Py_CLEAR(tmp);
        asname = NULL;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'alias' node")) {
            goto failed;
        }
        res = obj2ast_identifier(state, tmp, &asname, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from alias");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'alias' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &lineno, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->col_offset, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from alias");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'alias' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &col_offset, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->end_lineno, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL || tmp == Py_None) {
        Py_CLEAR(tmp);
        end_lineno = lineno;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'alias' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &end_lineno, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->end_col_offset, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL || tmp == Py_None) {
        Py_CLEAR(tmp);
        end_col_offset = col_offset;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'alias' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &end_col_offset, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    *out = _PyAST_alias(name, asname, lineno, col_offset, end_lineno,
                        end_col_offset, arena);
    return 0;
failed:
    Py_XDECREF(tmp);
    return 1;
}

int
obj2ast_withitem(struct ast_state *state, PyObject* obj, withitem_ty* out,
                 PyArena* arena)
{
    PyObject* tmp = NULL;
    expr_ty context_expr;
    expr_ty optional_vars;

    if (_PyObject_LookupAttr(obj, state->context_expr, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"context_expr\" missing from withitem");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'withitem' node")) {
            goto failed;
        }
        res = obj2ast_expr(state, tmp, &context_expr, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->optional_vars, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL || tmp == Py_None) {
        Py_CLEAR(tmp);
        optional_vars = NULL;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'withitem' node")) {
            goto failed;
        }
        res = obj2ast_expr(state, tmp, &optional_vars, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    *out = _PyAST_withitem(context_expr, optional_vars, arena);
    return 0;
failed:
    Py_XDECREF(tmp);
    return 1;
}

int
obj2ast_match_case(struct ast_state *state, PyObject* obj, match_case_ty* out,
                   PyArena* arena)
{
    PyObject* tmp = NULL;
    pattern_ty pattern;
    expr_ty guard;
    asdl_stmt_seq* body;

    if (_PyObject_LookupAttr(obj, state->pattern, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"pattern\" missing from match_case");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'match_case' node")) {
            goto failed;
        }
        res = obj2ast_pattern(state, tmp, &pattern, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->guard, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL || tmp == Py_None) {
        Py_CLEAR(tmp);
        guard = NULL;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'match_case' node")) {
            goto failed;
        }
        res = obj2ast_expr(state, tmp, &guard, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        tmp = PyList_New(0);
        if (tmp == NULL) {
            return 1;
        }
    }
    {
        int res;
        Py_ssize_t len;
        Py_ssize_t i;
        if (!PyList_Check(tmp)) {
            PyErr_Format(PyExc_TypeError, "match_case field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
            goto failed;
        }
        len = PyList_GET_SIZE(tmp);
        body = _Py_asdl_stmt_seq_new(len, arena);
        if (body == NULL) goto failed;
        for (i = 0; i < len; i++) {
            stmt_ty val;
            PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
            if (_Py_EnterRecursiveCall(" while traversing 'match_case' node")) {
                goto failed;
            }
            res = obj2ast_stmt(state, tmp2, &val, arena);
            _Py_LeaveRecursiveCall();
            Py_DECREF(tmp2);
            if (res != 0) goto failed;
            if (len != PyList_GET_SIZE(tmp)) {
                PyErr_SetString(PyExc_RuntimeError, "match_case field \"body\" changed size during iteration");
                goto failed;
            }
            asdl_seq_SET(body, i, val);
        }
        Py_CLEAR(tmp);
    }
    *out = _PyAST_match_case(pattern, guard, body, arena);
    return 0;
failed:
    Py_XDECREF(tmp);
    return 1;
}

int
obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out,
                PyArena* arena)
{
    int isinstance;

    PyObject *tmp = NULL;
    PyObject *tp;
    int lineno;
    int col_offset;
    int end_lineno;
    int end_col_offset;

    if (obj == Py_None) {
        *out = NULL;
        return 0;
    }
    if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from pattern");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'pattern' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &lineno, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->col_offset, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from pattern");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'pattern' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &col_offset, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->end_lineno, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"end_lineno\" missing from pattern");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'pattern' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &end_lineno, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->end_col_offset, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"end_col_offset\" missing from pattern");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'pattern' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &end_col_offset, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    tp = state->MatchValue_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty value;

        if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from MatchValue");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'MatchValue' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &value, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_MatchValue(value, lineno, col_offset, end_lineno,
                                 end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->MatchSingleton_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        constant value;

        if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from MatchSingleton");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'MatchSingleton' node")) {
                goto failed;
            }
            res = obj2ast_constant(state, tmp, &value, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_MatchSingleton(value, lineno, col_offset, end_lineno,
                                     end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->MatchSequence_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        asdl_pattern_seq* patterns;

        if (_PyObject_LookupAttr(obj, state->patterns, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "MatchSequence field \"patterns\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            patterns = _Py_asdl_pattern_seq_new(len, arena);
            if (patterns == NULL) goto failed;
            for (i = 0; i < len; i++) {
                pattern_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'MatchSequence' node")) {
                    goto failed;
                }
                res = obj2ast_pattern(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "MatchSequence field \"patterns\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(patterns, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_MatchSequence(patterns, lineno, col_offset, end_lineno,
                                    end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->MatchMapping_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        asdl_expr_seq* keys;
        asdl_pattern_seq* patterns;
        identifier rest;

        if (_PyObject_LookupAttr(obj, state->keys, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "MatchMapping field \"keys\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            keys = _Py_asdl_expr_seq_new(len, arena);
            if (keys == NULL) goto failed;
            for (i = 0; i < len; i++) {
                expr_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'MatchMapping' node")) {
                    goto failed;
                }
                res = obj2ast_expr(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "MatchMapping field \"keys\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(keys, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->patterns, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "MatchMapping field \"patterns\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            patterns = _Py_asdl_pattern_seq_new(len, arena);
            if (patterns == NULL) goto failed;
            for (i = 0; i < len; i++) {
                pattern_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'MatchMapping' node")) {
                    goto failed;
                }
                res = obj2ast_pattern(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "MatchMapping field \"patterns\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(patterns, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->rest, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            rest = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'MatchMapping' node")) {
                goto failed;
            }
            res = obj2ast_identifier(state, tmp, &rest, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_MatchMapping(keys, patterns, rest, lineno, col_offset,
                                   end_lineno, end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->MatchClass_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        expr_ty cls;
        asdl_pattern_seq* patterns;
        asdl_identifier_seq* kwd_attrs;
        asdl_pattern_seq* kwd_patterns;

        if (_PyObject_LookupAttr(obj, state->cls, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"cls\" missing from MatchClass");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'MatchClass' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &cls, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->patterns, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "MatchClass field \"patterns\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            patterns = _Py_asdl_pattern_seq_new(len, arena);
            if (patterns == NULL) goto failed;
            for (i = 0; i < len; i++) {
                pattern_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'MatchClass' node")) {
                    goto failed;
                }
                res = obj2ast_pattern(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "MatchClass field \"patterns\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(patterns, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->kwd_attrs, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "MatchClass field \"kwd_attrs\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            kwd_attrs = _Py_asdl_identifier_seq_new(len, arena);
            if (kwd_attrs == NULL) goto failed;
            for (i = 0; i < len; i++) {
                identifier val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'MatchClass' node")) {
                    goto failed;
                }
                res = obj2ast_identifier(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "MatchClass field \"kwd_attrs\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(kwd_attrs, i, val);
            }
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->kwd_patterns, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "MatchClass field \"kwd_patterns\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            kwd_patterns = _Py_asdl_pattern_seq_new(len, arena);
            if (kwd_patterns == NULL) goto failed;
            for (i = 0; i < len; i++) {
                pattern_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'MatchClass' node")) {
                    goto failed;
                }
                res = obj2ast_pattern(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "MatchClass field \"kwd_patterns\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(kwd_patterns, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_MatchClass(cls, patterns, kwd_attrs, kwd_patterns,
                                 lineno, col_offset, end_lineno,
                                 end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->MatchStar_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        identifier name;

        if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            name = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'MatchStar' node")) {
                goto failed;
            }
            res = obj2ast_identifier(state, tmp, &name, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_MatchStar(name, lineno, col_offset, end_lineno,
                                end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->MatchAs_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        pattern_ty pattern;
        identifier name;

        if (_PyObject_LookupAttr(obj, state->pattern, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            pattern = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'MatchAs' node")) {
                goto failed;
            }
            res = obj2ast_pattern(state, tmp, &pattern, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            name = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'MatchAs' node")) {
                goto failed;
            }
            res = obj2ast_identifier(state, tmp, &name, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_MatchAs(pattern, name, lineno, col_offset, end_lineno,
                              end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->MatchOr_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        asdl_pattern_seq* patterns;

        if (_PyObject_LookupAttr(obj, state->patterns, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            tmp = PyList_New(0);
            if (tmp == NULL) {
                return 1;
            }
        }
        {
            int res;
            Py_ssize_t len;
            Py_ssize_t i;
            if (!PyList_Check(tmp)) {
                PyErr_Format(PyExc_TypeError, "MatchOr field \"patterns\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
                goto failed;
            }
            len = PyList_GET_SIZE(tmp);
            patterns = _Py_asdl_pattern_seq_new(len, arena);
            if (patterns == NULL) goto failed;
            for (i = 0; i < len; i++) {
                pattern_ty val;
                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
                if (_Py_EnterRecursiveCall(" while traversing 'MatchOr' node")) {
                    goto failed;
                }
                res = obj2ast_pattern(state, tmp2, &val, arena);
                _Py_LeaveRecursiveCall();
                Py_DECREF(tmp2);
                if (res != 0) goto failed;
                if (len != PyList_GET_SIZE(tmp)) {
                    PyErr_SetString(PyExc_RuntimeError, "MatchOr field \"patterns\" changed size during iteration");
                    goto failed;
                }
                asdl_seq_SET(patterns, i, val);
            }
            Py_CLEAR(tmp);
        }
        *out = _PyAST_MatchOr(patterns, lineno, col_offset, end_lineno,
                              end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }

    PyErr_Format(PyExc_TypeError, "expected some sort of pattern, but got %R", obj);
    failed:
    Py_XDECREF(tmp);
    return 1;
}

int
obj2ast_type_ignore(struct ast_state *state, PyObject* obj, type_ignore_ty*
                    out, PyArena* arena)
{
    int isinstance;

    PyObject *tmp = NULL;
    PyObject *tp;

    if (obj == Py_None) {
        *out = NULL;
        return 0;
    }
    tp = state->TypeIgnore_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        int lineno;
        string tag;

        if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from TypeIgnore");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'TypeIgnore' node")) {
                goto failed;
            }
            res = obj2ast_int(state, tmp, &lineno, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->tag, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"tag\" missing from TypeIgnore");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'TypeIgnore' node")) {
                goto failed;
            }
            res = obj2ast_string(state, tmp, &tag, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_TypeIgnore(lineno, tag, arena);
        if (*out == NULL) goto failed;
        return 0;
    }

    PyErr_Format(PyExc_TypeError, "expected some sort of type_ignore, but got %R", obj);
    failed:
    Py_XDECREF(tmp);
    return 1;
}

int
obj2ast_type_param(struct ast_state *state, PyObject* obj, type_param_ty* out,
                   PyArena* arena)
{
    int isinstance;

    PyObject *tmp = NULL;
    PyObject *tp;
    int lineno;
    int col_offset;
    int end_lineno;
    int end_col_offset;

    if (obj == Py_None) {
        *out = NULL;
        return 0;
    }
    if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from type_param");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'type_param' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &lineno, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->col_offset, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL) {
        PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from type_param");
        return 1;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'type_param' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &col_offset, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->end_lineno, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL || tmp == Py_None) {
        Py_CLEAR(tmp);
        end_lineno = lineno;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'type_param' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &end_lineno, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    if (_PyObject_LookupAttr(obj, state->end_col_offset, &tmp) < 0) {
        return 1;
    }
    if (tmp == NULL || tmp == Py_None) {
        Py_CLEAR(tmp);
        end_col_offset = col_offset;
    }
    else {
        int res;
        if (_Py_EnterRecursiveCall(" while traversing 'type_param' node")) {
            goto failed;
        }
        res = obj2ast_int(state, tmp, &end_col_offset, arena);
        _Py_LeaveRecursiveCall();
        if (res != 0) goto failed;
        Py_CLEAR(tmp);
    }
    tp = state->TypeVar_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        identifier name;
        expr_ty bound;

        if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from TypeVar");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'TypeVar' node")) {
                goto failed;
            }
            res = obj2ast_identifier(state, tmp, &name, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        if (_PyObject_LookupAttr(obj, state->bound, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL || tmp == Py_None) {
            Py_CLEAR(tmp);
            bound = NULL;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'TypeVar' node")) {
                goto failed;
            }
            res = obj2ast_expr(state, tmp, &bound, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_TypeVar(name, bound, lineno, col_offset, end_lineno,
                              end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->ParamSpec_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        identifier name;

        if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from ParamSpec");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'ParamSpec' node")) {
                goto failed;
            }
            res = obj2ast_identifier(state, tmp, &name, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_ParamSpec(name, lineno, col_offset, end_lineno,
                                end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }
    tp = state->TypeVarTuple_type;
    isinstance = PyObject_IsInstance(obj, tp);
    if (isinstance == -1) {
        return 1;
    }
    if (isinstance) {
        identifier name;

        if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) {
            return 1;
        }
        if (tmp == NULL) {
            PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from TypeVarTuple");
            return 1;
        }
        else {
            int res;
            if (_Py_EnterRecursiveCall(" while traversing 'TypeVarTuple' node")) {
                goto failed;
            }
            res = obj2ast_identifier(state, tmp, &name, arena);
            _Py_LeaveRecursiveCall();
            if (res != 0) goto failed;
            Py_CLEAR(tmp);
        }
        *out = _PyAST_TypeVarTuple(name, lineno, col_offset, end_lineno,
                                   end_col_offset, arena);
        if (*out == NULL) goto failed;
        return 0;
    }

    PyErr_Format(PyExc_TypeError, "expected some sort of type_param, but got %R", obj);
    failed:
    Py_XDECREF(tmp);
    return 1;
}


static int
astmodule_exec(PyObject *m)
{
    struct ast_state *state = get_ast_state();
    if (state == NULL) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "AST", state->AST_type) < 0) {
        return -1;
    }
    if (PyModule_AddIntMacro(m, PyCF_ALLOW_TOP_LEVEL_AWAIT) < 0) {
        return -1;
    }
    if (PyModule_AddIntMacro(m, PyCF_ONLY_AST) < 0) {
        return -1;
    }
    if (PyModule_AddIntMacro(m, PyCF_TYPE_COMMENTS) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "mod", state->mod_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Module", state->Module_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Interactive", state->Interactive_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Expression", state->Expression_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "FunctionType", state->FunctionType_type) < 0)
        {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "stmt", state->stmt_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "FunctionDef", state->FunctionDef_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "AsyncFunctionDef",
        state->AsyncFunctionDef_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "ClassDef", state->ClassDef_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Return", state->Return_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Delete", state->Delete_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Assign", state->Assign_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "TypeAlias", state->TypeAlias_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "AugAssign", state->AugAssign_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "AnnAssign", state->AnnAssign_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "For", state->For_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "AsyncFor", state->AsyncFor_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "While", state->While_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "If", state->If_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "With", state->With_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "AsyncWith", state->AsyncWith_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Match", state->Match_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Raise", state->Raise_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Try", state->Try_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "TryStar", state->TryStar_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Assert", state->Assert_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Import", state->Import_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "ImportFrom", state->ImportFrom_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Global", state->Global_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Nonlocal", state->Nonlocal_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Expr", state->Expr_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Pass", state->Pass_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Break", state->Break_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Continue", state->Continue_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "expr", state->expr_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "BoolOp", state->BoolOp_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "NamedExpr", state->NamedExpr_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "BinOp", state->BinOp_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "UnaryOp", state->UnaryOp_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Lambda", state->Lambda_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "IfExp", state->IfExp_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Dict", state->Dict_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Set", state->Set_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "ListComp", state->ListComp_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "SetComp", state->SetComp_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "DictComp", state->DictComp_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "GeneratorExp", state->GeneratorExp_type) < 0)
        {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Await", state->Await_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Yield", state->Yield_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "YieldFrom", state->YieldFrom_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Compare", state->Compare_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Call", state->Call_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "FormattedValue", state->FormattedValue_type)
        < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "JoinedStr", state->JoinedStr_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Constant", state->Constant_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Attribute", state->Attribute_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Subscript", state->Subscript_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Starred", state->Starred_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Name", state->Name_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "List", state->List_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Tuple", state->Tuple_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Slice", state->Slice_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "expr_context", state->expr_context_type) < 0)
        {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Load", state->Load_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Store", state->Store_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Del", state->Del_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "boolop", state->boolop_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "And", state->And_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Or", state->Or_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "operator", state->operator_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Add", state->Add_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Sub", state->Sub_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Mult", state->Mult_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "MatMult", state->MatMult_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Div", state->Div_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Mod", state->Mod_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Pow", state->Pow_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "LShift", state->LShift_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "RShift", state->RShift_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "BitOr", state->BitOr_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "BitXor", state->BitXor_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "BitAnd", state->BitAnd_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "FloorDiv", state->FloorDiv_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "unaryop", state->unaryop_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Invert", state->Invert_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Not", state->Not_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "UAdd", state->UAdd_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "USub", state->USub_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "cmpop", state->cmpop_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Eq", state->Eq_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "NotEq", state->NotEq_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Lt", state->Lt_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "LtE", state->LtE_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Gt", state->Gt_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "GtE", state->GtE_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "Is", state->Is_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "IsNot", state->IsNot_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "In", state->In_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "NotIn", state->NotIn_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "comprehension", state->comprehension_type) <
        0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "excepthandler", state->excepthandler_type) <
        0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "ExceptHandler", state->ExceptHandler_type) <
        0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "arguments", state->arguments_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "arg", state->arg_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "keyword", state->keyword_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "alias", state->alias_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "withitem", state->withitem_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "match_case", state->match_case_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "pattern", state->pattern_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "MatchValue", state->MatchValue_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "MatchSingleton", state->MatchSingleton_type)
        < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "MatchSequence", state->MatchSequence_type) <
        0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "MatchMapping", state->MatchMapping_type) < 0)
        {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "MatchClass", state->MatchClass_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "MatchStar", state->MatchStar_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "MatchAs", state->MatchAs_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "MatchOr", state->MatchOr_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "type_ignore", state->type_ignore_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "TypeIgnore", state->TypeIgnore_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "type_param", state->type_param_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "TypeVar", state->TypeVar_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "ParamSpec", state->ParamSpec_type) < 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "TypeVarTuple", state->TypeVarTuple_type) < 0)
        {
        return -1;
    }
    return 0;
}

static PyModuleDef_Slot astmodule_slots[] = {
    {Py_mod_exec, astmodule_exec},
    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
    {0, NULL}
};

static struct PyModuleDef _astmodule = {
    PyModuleDef_HEAD_INIT,
    .m_name = "_ast",
    // The _ast module uses a per-interpreter state (PyInterpreterState.ast)
    .m_size = 0,
    .m_slots = astmodule_slots,
};

PyMODINIT_FUNC
PyInit__ast(void)
{
    return PyModuleDef_Init(&_astmodule);
}


PyObject* PyAST_mod2obj(mod_ty t)
{
    struct ast_state *state = get_ast_state();
    if (state == NULL) {
        return NULL;
    }

    int starting_recursion_depth;
    /* Be careful here to prevent overflow. */
    int COMPILER_STACK_FRAME_SCALE = 3;
    PyThreadState *tstate = _PyThreadState_GET();
    if (!tstate) {
        return 0;
    }
    state->recursion_limit = C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE;
    int recursion_depth = C_RECURSION_LIMIT - tstate->c_recursion_remaining;
    starting_recursion_depth = recursion_depth * COMPILER_STACK_FRAME_SCALE;
    state->recursion_depth = starting_recursion_depth;

    PyObject *result = ast2obj_mod(state, t);

    /* Check that the recursion depth counting balanced correctly */
    if (result && state->recursion_depth != starting_recursion_depth) {
        PyErr_Format(PyExc_SystemError,
            "AST constructor recursion depth mismatch (before=%d, after=%d)",
            starting_recursion_depth, state->recursion_depth);
        return 0;
    }
    return result;
}

/* mode is 0 for "exec", 1 for "eval" and 2 for "single" input */
mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode)
{
    const char * const req_name[] = {"Module", "Expression", "Interactive"};
    int isinstance;

    if (PySys_Audit("compile", "OO", ast, Py_None) < 0) {
        return NULL;
    }

    struct ast_state *state = get_ast_state();
    if (state == NULL) {
        return NULL;
    }

    PyObject *req_type[3];
    req_type[0] = state->Module_type;
    req_type[1] = state->Expression_type;
    req_type[2] = state->Interactive_type;

    assert(0 <= mode && mode <= 2);

    isinstance = PyObject_IsInstance(ast, req_type[mode]);
    if (isinstance == -1)
        return NULL;
    if (!isinstance) {
        PyErr_Format(PyExc_TypeError, "expected %s node, got %.400s",
                     req_name[mode], _PyType_Name(Py_TYPE(ast)));
        return NULL;
    }

    mod_ty res = NULL;
    if (obj2ast_mod(state, ast, &res, arena) != 0)
        return NULL;
    else
        return res;
}

int PyAST_Check(PyObject* obj)
{
    struct ast_state *state = get_ast_state();
    if (state == NULL) {
        return -1;
    }
    return PyObject_IsInstance(obj, state->AST_type);
}


"pass"/> \ No newline at end of file diff --git a/tests/auto/xmlpatternsschemats/TESTSUITE/.gitignore b/tests/auto/xmlpatternsschemats/TESTSUITE/.gitignore new file mode 100644 index 0000000..35cb85e --- /dev/null +++ b/tests/auto/xmlpatternsschemats/TESTSUITE/.gitignore @@ -0,0 +1,3 @@ +testSuites.xml +xmlschema2006-11-06 +xmlschema2006-11-06-new diff --git a/tests/auto/xmlpatternsschemats/TESTSUITE/unifyCatalog.xsl b/tests/auto/xmlpatternsschemats/TESTSUITE/unifyCatalog.xsl new file mode 100644 index 0000000..325f626 --- /dev/null +++ b/tests/auto/xmlpatternsschemats/TESTSUITE/unifyCatalog.xsl @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/xmlpatternsschemats/TESTSUITE/updateSuite.sh b/tests/auto/xmlpatternsschemats/TESTSUITE/updateSuite.sh new file mode 100755 index 0000000..1770f1e --- /dev/null +++ b/tests/auto/xmlpatternsschemats/TESTSUITE/updateSuite.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# This script updates the suite from W3C's server. +# +# NOTE: the files checked out CANNOT be added to Trolltech's +# repository at the moment, due to legal complications. + +DIRECTORY_NAME="xmlschema2006-11-06" +ARCHIVE_NAME="xsts-2007-06-20.tar.gz" + +rm -Rf $DIRECTORY_NAME + +wget http://www.w3.org/XML/2004/xml-schema-test-suite/xmlschema2006-11-06/$ARCHIVE_NAME +tar -xzf $ARCHIVE_NAME +rm $ARCHIVE_NAME + +CVSROOT=:pserver:anonymous@dev.w3.org:/sources/public cvs login +CVSROOT=:pserver:anonymous@dev.w3.org:/sources/public cvs checkout -d xmlschema2006-11-06-new XML/xml-schema-test-suite/2004-01-14/xmlschema2006-11-06 + +java net.sf.saxon.Transform -xsl:unifyCatalog.xsl $DIRECTORY_NAME/suite.xml > testSuites.xml diff --git a/tests/auto/xmlpatternsschemats/tst_xmlpatternsschemats.cpp b/tests/auto/xmlpatternsschemats/tst_xmlpatternsschemats.cpp new file mode 100644 index 0000000..7a6f4c8 --- /dev/null +++ b/tests/auto/xmlpatternsschemats/tst_xmlpatternsschemats.cpp @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +****************************************************************************/ + +#include + +#ifdef QTEST_XMLPATTERNS + +#include "tst_suitetest.h" + +/*! + \internal + \brief Test QXsdSchemaParser against W3C's XSD test suite. + */ +class tst_XmlPatternsSchemaTS : public tst_SuiteTest +{ + Q_OBJECT +public: + tst_XmlPatternsSchemaTS(); +protected: + virtual void catalogPath(QString &write) const; +}; + +tst_XmlPatternsSchemaTS::tst_XmlPatternsSchemaTS() + : tst_SuiteTest(tst_SuiteTest::XsdSuite) +{ +} + +void tst_XmlPatternsSchemaTS::catalogPath(QString &write) const +{ + write = QLatin1String("TESTSUITE/testSuites.xml"); +} + +QTEST_MAIN(tst_XmlPatternsSchemaTS) + +#include "tst_xmlpatternsschemats.moc" +#else +QTEST_NOOP_MAIN +#endif + +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternsschemats/xmlpatternsschemats.pro b/tests/auto/xmlpatternsschemats/xmlpatternsschemats.pro new file mode 100644 index 0000000..4978c35 --- /dev/null +++ b/tests/auto/xmlpatternsschemats/xmlpatternsschemats.pro @@ -0,0 +1,23 @@ +load(qttest_p4) +SOURCES += tst_xmlpatternsschemats.cpp \ + ../qxmlquery/TestFundament.cpp + +include (../xmlpatterns.pri) + +contains(QT_CONFIG,xmlpatterns) { +HEADERS += ../xmlpatternsxqts/test/tst_suitetest.h +SOURCES += ../xmlpatternsxqts/test/tst_suitetest.cpp +} + +PATTERNIST_SDK = QtXmlPatternsSDK +if(!debug_and_release|build_pass):CONFIG(debug, debug|release) { + win32:PATTERNIST_SDK = $${PATTERNIST_SDK}d + else: PATTERNIST_SDK = $${PATTERNIST_SDK}_debug +} +LIBS += -l$$PATTERNIST_SDK + +INCLUDEPATH += $$QT_SOURCE_TREE/tests/auto/xmlpatternsxqts/lib/ \ + $$QT_BUILD_TREE/include/QtXmlPatterns/private \ + $$QT_SOURCE_TREE/tests/auto/xmlpatternsxqts/test \ + ../xmlpatternsxqts/test \ + ../xmlpatternsxqts/lib diff --git a/tests/auto/xmlpatternsvalidator/files/instance.xml b/tests/auto/xmlpatternsvalidator/files/instance.xml new file mode 100644 index 0000000..544ff8c --- /dev/null +++ b/tests/auto/xmlpatternsvalidator/files/instance.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/tests/auto/xmlpatternsvalidator/files/invalid_schema.xsd b/tests/auto/xmlpatternsvalidator/files/invalid_schema.xsd new file mode 100644 index 0000000..99e3525 --- /dev/null +++ b/tests/auto/xmlpatternsvalidator/files/invalid_schema.xsd @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/tests/auto/xmlpatternsvalidator/files/other_valid_schema.xsd b/tests/auto/xmlpatternsvalidator/files/other_valid_schema.xsd new file mode 100644 index 0000000..850ed92 --- /dev/null +++ b/tests/auto/xmlpatternsvalidator/files/other_valid_schema.xsd @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/tests/auto/xmlpatternsvalidator/files/sa_invalid_instance.xml b/tests/auto/xmlpatternsvalidator/files/sa_invalid_instance.xml new file mode 100644 index 0000000..1804e88 --- /dev/null +++ b/tests/auto/xmlpatternsvalidator/files/sa_invalid_instance.xml @@ -0,0 +1,3 @@ + + + diff --git a/tests/auto/xmlpatternsvalidator/files/sa_valid_instance.xml b/tests/auto/xmlpatternsvalidator/files/sa_valid_instance.xml new file mode 100644 index 0000000..47c980e --- /dev/null +++ b/tests/auto/xmlpatternsvalidator/files/sa_valid_instance.xml @@ -0,0 +1,3 @@ + + + diff --git a/tests/auto/xmlpatternsvalidator/files/valid_schema.xsd b/tests/auto/xmlpatternsvalidator/files/valid_schema.xsd new file mode 100644 index 0000000..a1b765a --- /dev/null +++ b/tests/auto/xmlpatternsvalidator/files/valid_schema.xsd @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/tests/auto/xmlpatternsvalidator/tst_xmlpatternsvalidator.cpp b/tests/auto/xmlpatternsvalidator/tst_xmlpatternsvalidator.cpp new file mode 100644 index 0000000..9643e56 --- /dev/null +++ b/tests/auto/xmlpatternsvalidator/tst_xmlpatternsvalidator.cpp @@ -0,0 +1,174 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +****************************************************************************/ + +#include +#include + +#ifdef QTEST_XMLPATTERNS + +#include "../qxmlquery/TestFundament.h" +#include "../network-settings.h" + +/*! + \class tst_XmlPatterns + \internal + \since 4.6 + \brief Tests the command line interface, \c xmlpatternsvalidator, for the XML validation code. + */ +class tst_XmlPatternsValidator : public QObject + , private TestFundament +{ + Q_OBJECT + +public: + tst_XmlPatternsValidator(); + +private Q_SLOTS: + void initTestCase(); + void xsdSupport(); + void xsdSupport_data() const; + +private: + const QString m_command; + bool m_dontRun; +}; + +tst_XmlPatternsValidator::tst_XmlPatternsValidator() + : m_command(QLatin1String("xmlpatternsvalidator")) + , m_dontRun(false) +{ +} + +void tst_XmlPatternsValidator::initTestCase() +{ + QProcess process; + process.start(m_command); + + if(!process.waitForFinished()) + { + m_dontRun = true; + QEXPECT_FAIL("", "The command line tool is not in the path, most likely because Qt " + "has been partically built, such as only the sub-src rule. No tests will be run.", Abort); + QVERIFY(false); + } +} + +void tst_XmlPatternsValidator::xsdSupport() +{ + if(m_dontRun) + QSKIP("The command line utility is not in the path.", SkipAll); + +#ifdef Q_OS_WINCE + QSKIP("WinCE: This test uses unsupported WinCE functionality", SkipAll); +#endif + + QFETCH(int, expectedExitCode); + QFETCH(QStringList, arguments); + QFETCH(QString, cwd); + + QProcess process; + + if(!cwd.isEmpty()) + process.setWorkingDirectory(inputFile(cwd)); + + process.start(m_command, arguments); + + QCOMPARE(process.exitStatus(), QProcess::NormalExit); + QVERIFY(process.waitForFinished()); + + if(process.exitCode() != expectedExitCode) + QTextStream(stderr) << "foo:" << process.readAllStandardError(); + + QCOMPARE(process.exitCode(), expectedExitCode); +} + +void tst_XmlPatternsValidator::xsdSupport_data() const +{ +#ifdef Q_OS_WINCE + return; +#endif + + QTest::addColumn("expectedExitCode"); + QTest::addColumn("arguments"); + QTest::addColumn("cwd"); + + QTest::newRow("No arguments") + << 2 + << QStringList() + << QString(); + + QTest::newRow("A valid schema") + << 0 + << QStringList(QLatin1String("files/valid_schema.xsd")) + << QString(); + + QTest::newRow("An invalid schema") + << 1 + << QStringList(QLatin1String("files/invalid_schema.xsd")) + << QString(); + + QTest::newRow("An instance and valid schema") + << 0 + << (QStringList() << QLatin1String("files/instance.xml") + << QLatin1String("files/valid_schema.xsd")) + << QString(); + + QTest::newRow("An instance and invalid schema") + << 1 + << (QStringList() << QLatin1String("files/instance.xml") + << QLatin1String("files/invalid_schema.xsd")) + << QString(); + + QTest::newRow("An instance and not matching schema") + << 1 + << (QStringList() << QLatin1String("files/instance.xml") + << QLatin1String("files/other_valid_schema.xsd")) + << QString(); + + QTest::newRow("Two instance documents") + << 1 + << (QStringList() << QLatin1String("files/instance.xml") + << QLatin1String("files/instance.xml")) + << QString(); + + QTest::newRow("Three instance documents") + << 2 + << (QStringList() << QLatin1String("files/instance.xml") + << QLatin1String("files/instance.xml") + << QLatin1String("files/instance.xml")) + << QString(); + + QTest::newRow("Two schema documents") + << 1 + << (QStringList() << QLatin1String("files/valid_schema.xsd") + << QLatin1String("files/valid_schema.xsd")) + << QString(); + + QTest::newRow("A schema aware valid instance document") + << 0 + << (QStringList() << QLatin1String("files/sa_valid_instance.xml")) + << QString(); + + QTest::newRow("A schema aware invalid instance document") + << 1 + << (QStringList() << QLatin1String("files/sa_invalid_instance.xml")) + << QString(); + + QTest::newRow("A non-schema aware instance document") + << 1 + << (QStringList() << QLatin1String("files/instance.xml")) + << QString(); +} + +QTEST_MAIN(tst_XmlPatternsValidator) + +#include "tst_xmlpatternsvalidator.moc" +#else +QTEST_NOOP_MAIN +#endif + +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternsvalidator/xmlpatternsvalidator.pro b/tests/auto/xmlpatternsvalidator/xmlpatternsvalidator.pro new file mode 100644 index 0000000..7091840 --- /dev/null +++ b/tests/auto/xmlpatternsvalidator/xmlpatternsvalidator.pro @@ -0,0 +1,5 @@ +load(qttest_p4) +SOURCES += tst_xmlpatternsvalidator.cpp \ + ../qxmlquery/TestFundament.cpp + +include (../xmlpatterns.pri) diff --git a/tests/auto/xmlpatternsview/view/MainWindow.cpp b/tests/auto/xmlpatternsview/view/MainWindow.cpp index 57aaca0..b5424a3 100644 --- a/tests/auto/xmlpatternsview/view/MainWindow.cpp +++ b/tests/auto/xmlpatternsview/view/MainWindow.cpp @@ -220,7 +220,8 @@ void MainWindow::on_actionOpen_triggered() if(fileName.isNull()) return; - openCatalog(QUrl::fromLocalFile(fileName), true, false); + m_currentSuiteType = TestSuite::XQuerySuite; + openCatalog(QUrl::fromLocalFile(fileName), true, TestSuite::XQuerySuite); } void MainWindow::on_actionOpenXSLTSCatalog_triggered() @@ -234,18 +235,34 @@ void MainWindow::on_actionOpenXSLTSCatalog_triggered() if(fileName.isNull()) return; - openCatalog(QUrl::fromLocalFile(fileName), true, true); + m_currentSuiteType = TestSuite::XsltSuite; + openCatalog(QUrl::fromLocalFile(fileName), true, TestSuite::XsltSuite); +} + +void MainWindow::on_actionOpenXSDTSCatalog_triggered() +{ + const QString fileName(QFileDialog::getOpenFileName(this, + QLatin1String("Open Test Suite Catalog"), + m_previousOpenedCatalog.toLocalFile(), + QLatin1String("Test Suite Catalog file (*.xml)"))); + + /* "If the user presses Cancel, it returns a null string." */ + if(fileName.isNull()) + return; + + m_currentSuiteType = TestSuite::XsdSuite; + openCatalog(QUrl::fromLocalFile(fileName), true, TestSuite::XsdSuite); } void MainWindow::openCatalog(const QUrl &fileName, const bool reportError, - const bool isXSLT) + const TestSuite::SuiteType suiteType) { setCurrentFile(fileName); m_previousOpenedCatalog = fileName; QString errorMsg; - TestSuite *const loadedSuite = TestSuite::openCatalog(fileName, errorMsg, false, isXSLT); + TestSuite *const loadedSuite = TestSuite::openCatalog(fileName, errorMsg, false, suiteType); if(!loadedSuite) { @@ -334,12 +351,12 @@ void MainWindow::readSettings() focusURI->setText(settings.value(QLatin1String("focusURI")).toString()); isXSLT20->setChecked(settings.value(QLatin1String("isXSLT20")).toBool()); compileOnly->setChecked(settings.value(QLatin1String("compileOnly")).toBool()); + m_currentSuiteType = (TestSuite::SuiteType)settings.value(QLatin1String("PreviousSuiteType"), isXSLT20->isChecked() ? TestSuite::XsltSuite : TestSuite::XQuerySuite).toInt(); /* Open the previously opened catalog. */ if(!m_previousOpenedCatalog.isEmpty()) { - /* We don't know what kind of catalog it is, so we just take a chance. */ - openCatalog(m_previousOpenedCatalog, false, isXSLT20->isChecked()); + openCatalog(m_previousOpenedCatalog, false, m_currentSuiteType); } sourceInput->setPlainText(settings.value(QLatin1String("sourceInput")).toString()); @@ -393,6 +410,7 @@ void MainWindow::writeSettings() settings.setValue(QLatin1String("size"), size()); settings.setValue(QLatin1String("sourceInput"), sourceInput->toPlainText()); settings.setValue(QLatin1String("PreviousOpenedCatalogFile"), m_previousOpenedCatalog); + settings.setValue(QLatin1String("PreviousSuiteType"), m_currentSuiteType); settings.setValue(QLatin1String("SelectedTab"), sourceTab->currentIndex()); settings.setValue(QLatin1String("ResultViewMethod"), testResultView->resultViewSelection->currentIndex()); @@ -470,7 +488,7 @@ void MainWindow::openRecentFile() { const QAction *const action = qobject_cast(sender()); if(action) - openCatalog(action->data().toUrl(), true, false); + openCatalog(action->data().toUrl(), true, TestSuite::XQuerySuite); } void MainWindow::closeEvent(QCloseEvent *ev) diff --git a/tests/auto/xmlpatternsview/view/MainWindow.h b/tests/auto/xmlpatternsview/view/MainWindow.h index 1d14f41..778d7cd 100644 --- a/tests/auto/xmlpatternsview/view/MainWindow.h +++ b/tests/auto/xmlpatternsview/view/MainWindow.h @@ -88,6 +88,7 @@ #include "ui_ui_MainWindow.h" #include "DebugExpressionFactory.h" +#include "TestSuite.h" QT_BEGIN_HEADER @@ -142,6 +143,8 @@ namespace QPatternistSDK void on_actionOpenXSLTSCatalog_triggered(); + void on_actionOpenXSDTSCatalog_triggered(); + /** * Executes the selected test case or test group. */ @@ -153,7 +156,7 @@ namespace QPatternistSDK * an informative message box will be displayed, if any errors occurred. */ void openCatalog(const QUrl &file, const bool reportError, - const bool isXSLT); + const TestSuite::SuiteType suitType); void openRecentFile(); @@ -205,6 +208,7 @@ namespace QPatternistSDK TestCaseView * testCaseView; TestResultView * testResultView; FunctionSignaturesView * functionView; + TestSuite::SuiteType m_currentSuiteType; }; } QT_END_NAMESPACE diff --git a/tests/auto/xmlpatternsview/view/ui_MainWindow.ui b/tests/auto/xmlpatternsview/view/ui_MainWindow.ui index 5d74331..0240350 100644 --- a/tests/auto/xmlpatternsview/view/ui_MainWindow.ui +++ b/tests/auto/xmlpatternsview/view/ui_MainWindow.ui @@ -234,6 +234,7 @@ + @@ -304,6 +305,14 @@ Ctrl+L + + + O&pen XSDTS Catalog... + + + Ctrl+S + + diff --git a/tests/auto/xmlpatternsxqts/lib/TestBaseLine.cpp b/tests/auto/xmlpatternsxqts/lib/TestBaseLine.cpp index b699ead..841266c 100644 --- a/tests/auto/xmlpatternsxqts/lib/TestBaseLine.cpp +++ b/tests/auto/xmlpatternsxqts/lib/TestBaseLine.cpp @@ -178,6 +178,7 @@ void TestBaseLine::toXML(XMLWriter &receiver) const { case XML: /* Fallthrough. */ case Fragment: /* Fallthrough. */ + case SchemaIsValid: /* Fallthrough. */ case Text: { QXmlAttributes inspectAtts; @@ -343,6 +344,8 @@ TestResult::Status TestBaseLine::verify(const QString &serializedInput) const { switch(m_type) { + case SchemaIsValid: + /* Fall through. */ case Text: { if(serializedInput == details()) @@ -491,6 +494,8 @@ QString TestBaseLine::displayName(const Type id) return QLatin1String("Inspect"); case ExpectedError: return QLatin1String("ExpectedError"); + case SchemaIsValid: + return QLatin1String("SchemaIsValid"); } Q_ASSERT(false); @@ -503,6 +508,8 @@ QString TestBaseLine::details() const return QString(); if(m_type == ExpectedError) /* We're an error code. */ return m_details; + if(m_type == SchemaIsValid) /* We're a schema validation information . */ + return m_details; if(m_details.isEmpty()) return m_details; diff --git a/tests/auto/xmlpatternsxqts/lib/TestBaseLine.h b/tests/auto/xmlpatternsxqts/lib/TestBaseLine.h index 577c4b1..b5dc46e 100644 --- a/tests/auto/xmlpatternsxqts/lib/TestBaseLine.h +++ b/tests/auto/xmlpatternsxqts/lib/TestBaseLine.h @@ -168,7 +168,14 @@ namespace QPatternistSDK * because an implementation does not support the feature is not * considered a correct result. */ - ExpectedError + ExpectedError, + + /** + * A special comparison for the schema validation tests. The details + * can only be 'true' or 'false' depending on whether it is a valid + * schema or not. + */ + SchemaIsValid }; /** diff --git a/tests/auto/xmlpatternsxqts/lib/TestGroup.cpp b/tests/auto/xmlpatternsxqts/lib/TestGroup.cpp index 060f993..e59e4b4 100644 --- a/tests/auto/xmlpatternsxqts/lib/TestGroup.cpp +++ b/tests/auto/xmlpatternsxqts/lib/TestGroup.cpp @@ -94,7 +94,7 @@ TestGroup::TestGroup(TreeItem *p) : m_parent(p) QVariant TestGroup::data(const Qt::ItemDataRole role, int column) const { - if(role != Qt::DisplayRole && role != Qt::BackgroundRole) + if(role != Qt::DisplayRole && role != Qt::BackgroundRole && role != Qt::ToolTipRole) return QVariant(); /* In ResultSummary, the first is the amount of passes and the second is the total. */ @@ -154,6 +154,10 @@ QVariant TestGroup::data(const Qt::ItemDataRole role, int column) const return QVariant(); } } + case Qt::ToolTipRole: + { + return description(); + } default: { Q_ASSERT_X(false, Q_FUNC_INFO, "This shouldn't be reached"); diff --git a/tests/auto/xmlpatternsxqts/lib/TestSuite.cpp b/tests/auto/xmlpatternsxqts/lib/TestSuite.cpp index 3bca281..13d5880 100644 --- a/tests/auto/xmlpatternsxqts/lib/TestSuite.cpp +++ b/tests/auto/xmlpatternsxqts/lib/TestSuite.cpp @@ -91,6 +91,7 @@ #include "TestSuiteResult.h" #include "XMLWriter.h" #include "XSLTTestSuiteHandler.h" +#include "XSDTestSuiteHandler.h" #include "qdebug_p.h" #include "TestSuite.h" @@ -132,7 +133,7 @@ TestSuiteResult *TestSuite::runSuite() TestSuite *TestSuite::openCatalog(const QUrl &catalogURI, QString &errorMsg, const bool useExclusionList, - const bool isXSLTCatalog) + SuiteType suiteType) { pDebug() << "Opening catalog:" << catalogURI.toString(); QFile ts(catalogURI.toLocalFile()); @@ -167,14 +168,14 @@ TestSuite *TestSuite::openCatalog(const QUrl &catalogURI, return 0; } - return openCatalog(&ts, errorMsg, catalogURI, useExclusionList, isXSLTCatalog); + return openCatalog(&ts, errorMsg, catalogURI, useExclusionList, suiteType); } TestSuite *TestSuite::openCatalog(QIODevice *input, QString &errorMsg, const QUrl &fileName, const bool useExclusionList, - const bool isXSLTCatalog) + SuiteType suiteType) { Q_ASSERT(input); @@ -183,10 +184,12 @@ TestSuite *TestSuite::openCatalog(QIODevice *input, HandlerPtr loader; - if(isXSLTCatalog) - loader = HandlerPtr(new XSLTTestSuiteHandler(fileName)); - else - loader = HandlerPtr(new TestSuiteHandler(fileName, useExclusionList)); + switch (suiteType) { + case XQuerySuite: loader = HandlerPtr(new TestSuiteHandler(fileName, useExclusionList)); break; + case XsltSuite: loader = HandlerPtr(new XSLTTestSuiteHandler(fileName)); break; + case XsdSuite: loader = HandlerPtr(new XSDTestSuiteHandler(fileName)); break; + default: Q_ASSERT(false); break; + } reader.setContentHandler(loader.data()); @@ -198,8 +201,13 @@ TestSuite *TestSuite::openCatalog(QIODevice *input, return 0; } - TestSuite *const suite = isXSLTCatalog ? static_cast(loader.data())->testSuite() - : static_cast(loader.data())->testSuite(); + TestSuite *suite = 0; + switch (suiteType) { + case XQuerySuite: suite = static_cast(loader.data())->testSuite(); break; + case XsltSuite: suite = static_cast(loader.data())->testSuite(); break; + case XsdSuite: suite = static_cast(loader.data())->testSuite(); break; + default: Q_ASSERT(false); break; + } if(suite) return suite; diff --git a/tests/auto/xmlpatternsxqts/lib/TestSuite.h b/tests/auto/xmlpatternsxqts/lib/TestSuite.h index cdd511f..5141886 100644 --- a/tests/auto/xmlpatternsxqts/lib/TestSuite.h +++ b/tests/auto/xmlpatternsxqts/lib/TestSuite.h @@ -112,6 +112,16 @@ namespace QPatternistSDK class Q_PATTERNISTSDK_EXPORT TestSuite : public TestContainer { public: + /** + * Describes the type of test suite. + */ + enum SuiteType + { + XQuerySuite, ///< The test suite for XQuery + XsltSuite, ///< The test suite for XSLT + XsdSuite ///< The test suite for XML Schema + }; + TestSuite(); virtual QVariant data(const Qt::ItemDataRole role, int column) const; @@ -148,7 +158,7 @@ namespace QPatternistSDK static TestSuite *openCatalog(const QUrl &catalogFile, QString &errorMsg, const bool useExclusionList, - const bool isXSLTCatalog = false); + SuiteType type); void toXML(XMLWriter &receiver, TestCase *const tc) const; @@ -177,7 +187,7 @@ namespace QPatternistSDK QString &errorMsg, const QUrl &fileName, const bool useExclusionList, - const bool isXSLTCatalog); + SuiteType type); QString m_version; QDate m_designDate; }; diff --git a/tests/auto/xmlpatternsxqts/lib/TreeModel.cpp b/tests/auto/xmlpatternsxqts/lib/TreeModel.cpp index d9ba200..4991b26 100644 --- a/tests/auto/xmlpatternsxqts/lib/TreeModel.cpp +++ b/tests/auto/xmlpatternsxqts/lib/TreeModel.cpp @@ -118,9 +118,14 @@ QVariant TreeModel::headerData(int section, Qt::Orientation orientation, int rol return QVariant(); } -void TreeModel::childChanged(TreeItem *) +void TreeModel::childChanged(TreeItem *item) { - layoutChanged(); + if (item) { + const QModelIndex index = createIndex(item->row(), 0, item); + dataChanged(index, index); + } else { + layoutChanged(); + } } QModelIndex TreeModel::index(int row, int column, const QModelIndex &p) const diff --git a/tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.cpp b/tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.cpp new file mode 100644 index 0000000..b19eb91 --- /dev/null +++ b/tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.cpp @@ -0,0 +1,346 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Patternist project on Trolltech Labs. +** +** $TROLLTECH_GPL_LICENSE$ +** +*************************************************************************** +*/ + +#include +#include +#include +#include +#include + +#include "XSDTSTestCase.h" + +#include "qxmlschema.h" +#include "qxmlschemavalidator.h" + +using namespace QPatternistSDK; +using namespace QPatternist; + +XSDTSTestCase::XSDTSTestCase(const Scenario scen, TreeItem *p, TestType testType) + : m_scenario(scen) + , m_parent(p) + , m_testType(testType) +{ +} + +XSDTSTestCase::~XSDTSTestCase() +{ + qDeleteAll(m_baseLines); +} + +TestResult::List XSDTSTestCase::execute(const ExecutionStage, TestSuite*) +{ + ErrorHandler errHandler; + ErrorHandler::installQtMessageHandler(&errHandler); + + TestResult::List retval; + TestResult::Status resultStatus = TestResult::Unknown; + QString serialized; + + if (m_testType == SchemaTest) { + executeSchemaTest(resultStatus, serialized, &errHandler); + } else { + executeInstanceTest(resultStatus, serialized, &errHandler); + } + + resultStatus = TestBaseLine::scan(serialized, baseLines()); + Q_ASSERT(resultStatus != TestResult::Unknown); + + m_result = new TestResult(name(), resultStatus, 0, errHandler.messages(), + QPatternist::Item::List(), serialized); + retval.append(m_result); + ErrorHandler::installQtMessageHandler(0); + changed(this); + return retval; +} + +void XSDTSTestCase::executeSchemaTest(TestResult::Status &resultStatus, QString &serialized, QAbstractMessageHandler *handler) +{ + QFile file(m_schemaUri.path()); + if (!file.open(QIODevice::ReadOnly)) { + resultStatus = TestResult::Fail; + serialized = QString(); + return; + } + + QXmlSchema schema; + schema.setMessageHandler(handler); + schema.load(&file, m_schemaUri); + + if (schema.isValid()) { + resultStatus = TestResult::Pass; + serialized = QString::fromLatin1("true"); + } else { + resultStatus = TestResult::Pass; + serialized = QString::fromLatin1("false"); + } +} + +void XSDTSTestCase::executeInstanceTest(TestResult::Status &resultStatus, QString &serialized, QAbstractMessageHandler *handler) +{ + QFile instanceFile(m_instanceUri.path()); + if (!instanceFile.open(QIODevice::ReadOnly)) { + resultStatus = TestResult::Fail; + serialized = QString(); + return; + } + + QXmlSchema schema; + if (m_schemaUri.isValid()) { + QFile file(m_schemaUri.path()); + if (!file.open(QIODevice::ReadOnly)) { + resultStatus = TestResult::Fail; + serialized = QString(); + return; + } + + schema.setMessageHandler(handler); + schema.load(&file, m_schemaUri); + + if (!schema.isValid()) { + resultStatus = TestResult::Pass; + serialized = QString::fromLatin1("false"); + return; + } + } + + QXmlSchemaValidator validator(schema); + validator.setMessageHandler(handler); + + qDebug("check %s", qPrintable(m_instanceUri.path())); + if (validator.validate(&instanceFile, m_instanceUri)) { + resultStatus = TestResult::Pass; + serialized = QString::fromLatin1("true"); + } else { + resultStatus = TestResult::Pass; + serialized = QString::fromLatin1("false"); + } +} + +QVariant XSDTSTestCase::data(const Qt::ItemDataRole role, int column) const +{ + if(role == Qt::DisplayRole) + { + if(column == 0) + return title(); + + const TestResult *const tr = testResult(); + if(!tr) + { + if(column == 1) + return TestResult::displayName(TestResult::NotTested); + else + return QString(); + } + const TestResult::Status status = tr->status(); + + switch(column) + { + case 1: + return status == TestResult::Pass ? QString(QChar::fromLatin1('1')) + : QString(QChar::fromLatin1('0')); + case 2: + return status == TestResult::Fail ? QString(QChar::fromLatin1('1')) + : QString(QChar::fromLatin1('0')); + default: + return QString(); + } + } + + if(role != Qt::BackgroundRole) + return QVariant(); + + const TestResult *const tr = testResult(); + + if(!tr) + { + if(column == 0) + return Qt::yellow; + else + return QVariant(); + } + + const TestResult::Status status = tr->status(); + + if(status == TestResult::NotTested || status == TestResult::Unknown) + return Qt::yellow; + + switch(column) + { + case 1: + return status == TestResult::Pass ? Qt::green : QVariant(); + case 2: + return status == TestResult::Fail ? Qt::red : QVariant(); + default: + return QVariant(); + } +} + +QString XSDTSTestCase::sourceCode(bool &ok) const +{ + QFile file((m_testType == SchemaTest ? m_schemaUri : m_instanceUri).toLocalFile()); + + QString err; + + if(!file.exists()) + err = QString::fromLatin1("Error: %1 does not exist.").arg(file.fileName()); + else if(!QFileInfo(file.fileName()).isFile()) + err = QString::fromLatin1("Error: %1 is not a file, cannot display it.").arg(file.fileName()); + else if(!file.open(QIODevice::ReadOnly)) + err = QString::fromLatin1("Error: Could not open %1. Likely a permission error.") + .arg(file.fileName()); + + if(err.isNull()) /* No errors. */ + { + ok = true; + /* Scary, we assume the query is stored in UTF-8. */ + return QString::fromUtf8(file.readAll()); + } + else + { + ok = false; + return err; + } +} + +int XSDTSTestCase::columnCount() const +{ + return 2; +} + +void XSDTSTestCase::addBaseLine(TestBaseLine *line) +{ + m_baseLines.append(line); +} + +QString XSDTSTestCase::name() const +{ + return m_name; +} + +QString XSDTSTestCase::creator() const +{ + return m_creator; +} + +QString XSDTSTestCase::description() const +{ + return m_description; +} + +QDate XSDTSTestCase::lastModified() const +{ + return m_lastModified; +} + +bool XSDTSTestCase::isXPath() const +{ + return false; +} + +TestCase::Scenario XSDTSTestCase::scenario() const +{ + return m_scenario; +} + +void XSDTSTestCase::setName(const QString &n) +{ + m_name = n; +} + +void XSDTSTestCase::setCreator(const QString &ctor) +{ + m_creator = ctor; +} + +void XSDTSTestCase::setDescription(const QString &descriptionP) +{ + m_description = descriptionP; +} + +void XSDTSTestCase::setLastModified(const QDate &date) +{ + m_lastModified = date; +} + +void XSDTSTestCase::setSchemaUri(const QUrl &uri) +{ + m_schemaUri = uri; +} + +void XSDTSTestCase::setInstanceUri(const QUrl &uri) +{ + m_instanceUri = uri; +} + +TreeItem *XSDTSTestCase::parent() const +{ + return m_parent; +} + +QString XSDTSTestCase::title() const +{ + return m_name; +} + +TestBaseLine::List XSDTSTestCase::baseLines() const +{ + Q_ASSERT_X(!m_baseLines.isEmpty(), Q_FUNC_INFO, + qPrintable(QString::fromLatin1("The test %1 has no base lines, it should have at least one.").arg(name()))); + return m_baseLines; +} + +QUrl XSDTSTestCase::schemaUri() const +{ + return m_schemaUri; +} + +QUrl XSDTSTestCase::instanceUri() const +{ + return m_instanceUri; +} + +void XSDTSTestCase::setContextItemSource(const QUrl &uri) +{ + m_contextItemSource = uri; +} + +QUrl XSDTSTestCase::contextItemSource() const +{ + return m_contextItemSource; +} + +void XSDTSTestCase::setParent(TreeItem *const p) +{ + m_parent = p; +} + +QPatternist::ExternalVariableLoader::Ptr XSDTSTestCase::externalVariableLoader() const +{ + return QPatternist::ExternalVariableLoader::Ptr(); +} + +TestResult *XSDTSTestCase::testResult() const +{ + return m_result; +} + +TestItem::ResultSummary XSDTSTestCase::resultSummary() const +{ + if(m_result) + return ResultSummary(m_result->status() == TestResult::Pass ? 1 : 0, + 1); + + return ResultSummary(0, 1); +} + +// vim: et:ts=4:sw=4:sts=4 + diff --git a/tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.h b/tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.h new file mode 100644 index 0000000..ce84988 --- /dev/null +++ b/tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.h @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Patternist project on Trolltech Labs. +** +** $TROLLTECH_GPL_LICENSE$ +** +*************************************************************************** +*/ + +#ifndef PatternistSDK_XSDTSTestCase_H +#define PatternistSDK_XSDTSTestCase_H + +#include +#include +#include + +#include "TestBaseLine.h" +#include "TestCase.h" + +QT_BEGIN_HEADER + +namespace QPatternistSDK +{ + /** + * @short Represents a test case in a test suite in the XML Query Test Suite. + * + * TestCase is a memory representation of a test case, and maps + * to the @c test-case element in the XQuery Test Suite test + * case catalog. + * + * @ingroup PatternistSDK + * @author Frans Englich + */ + class Q_PATTERNISTSDK_EXPORT XSDTSTestCase : public TestCase + { + public: + enum TestType + { + SchemaTest, + InstanceTest + }; + + XSDTSTestCase(const Scenario scen, TreeItem *parent, TestType testType); + virtual ~XSDTSTestCase(); + + /** + * Executes the test, and returns the result. The returned list + * will always contain exactly one TestResult. + * + * @p stage is ignored when running out-of-process. + */ + virtual TestResult::List execute(const ExecutionStage stage, + TestSuite *ts); + /** + * The identifier, the name of the test. For example, "Literals034". + * The name of a test case must be unique. + */ + virtual QString name() const; + virtual QString creator() const; + virtual QString description() const; + /** + * @returns the query inside the file, specified by testCasePath(). Loading + * of the file is not cached in order to avoid complications. + * @param ok is set to @c false if loading the query file fails + */ + virtual QString sourceCode(bool &ok) const; + virtual QUrl schemaUri() const; + virtual QUrl instanceUri() const; + virtual QUrl testCasePath() const {return QUrl();} + virtual QDate lastModified() const; + + bool isXPath() const; + + /** + * What kind of test case this is, what kind of scenario it takes part + * of. For example, whether the test case should evaluate normally or fail. + */ + Scenario scenario() const; + + void setCreator(const QString &creator); + void setLastModified(const QDate &date); + void setDescription(const QString &description); + void setName(const QString &name); + void setSchemaUri(const QUrl &uri); + void setInstanceUri(const QUrl &uri); + void setTestCasePath(const QUrl &uri) {} + void setContextItemSource(const QUrl &uri); + void addBaseLine(TestBaseLine *lines); + + virtual TreeItem *parent() const; + + virtual QVariant data(const Qt::ItemDataRole role, int column) const; + + virtual QString title() const; + virtual TestBaseLine::List baseLines() const; + + virtual int columnCount() const; + + virtual QUrl contextItemSource() const; + void setParent(TreeItem *const parent); + virtual QPatternist::ExternalVariableLoader::Ptr externalVariableLoader() const; + virtual TestResult *testResult() const; + virtual ResultSummary resultSummary() const; + + private: + void executeSchemaTest(TestResult::Status &resultStatus, QString &serialized, QAbstractMessageHandler *handler); + void executeInstanceTest(TestResult::Status &resultStatus, QString &serialized, QAbstractMessageHandler *handler); + + QString m_name; + QString m_creator; + QString m_description; + QUrl m_schemaUri; + QUrl m_instanceUri; + QDate m_lastModified; + const Scenario m_scenario; + TreeItem * m_parent; + TestBaseLine::List m_baseLines; + QUrl m_contextItemSource; + TestType m_testType; + QPointer m_result; + }; +} + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternsxqts/lib/XSDTestSuiteHandler.cpp b/tests/auto/xmlpatternsxqts/lib/XSDTestSuiteHandler.cpp new file mode 100644 index 0000000..b6ee379 --- /dev/null +++ b/tests/auto/xmlpatternsxqts/lib/XSDTestSuiteHandler.cpp @@ -0,0 +1,881 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Patternist project on Trolltech Labs. +** +** $TROLLTECH_GPL_LICENSE$ +** +*************************************************************************** +*/ + +#include + +#include "qacceltreeresourceloader_p.h" +#include "qnetworkaccessdelegator_p.h" + +#include "Global.h" +#include "TestBaseLine.h" +#include "TestGroup.h" + +#include "XSDTestSuiteHandler.h" +#include "XSDTSTestCase.h" + +using namespace QPatternistSDK; + +extern QNetworkAccessManager s_networkManager; + +XSDTestSuiteHandler::XSDTestSuiteHandler(const QUrl &catalogFile) : m_ts(0) + , m_catalogFile(catalogFile) + , m_inSchemaTest(false) + , m_inInstanceTest(false) + , m_inTestGroup(false) + , m_inDescription(false) + , m_schemaBlacklisted(false) + , m_counter(0) +{ + Q_ASSERT(!m_catalogFile.isRelative()); + m_ts = new TestSuite(); + m_topLevelGroup = new TestGroup(m_ts); + m_topLevelGroup->setTitle("XML Schema Test Suite"); + m_ts->appendChild(m_topLevelGroup); + + // exclude these test cases, as they break our current state machine + m_blackList << QLatin1String("addB099") + << QLatin1String("addB118") + << QLatin1String("elemJ003") + << QLatin1String("elemJ011") + << QLatin1String("elemZ004") + << QLatin1String("elemZ020") + << QLatin1String("groupH021v") + << QLatin1String("groupJ009v") + << QLatin1String("name00101m2") + << QLatin1String("schL5") + << QLatin1String("ste110") + << QLatin1String("stZ007") + << QLatin1String("stZ047") + << QLatin1String("stZ055") + << QLatin1String("addB049") + << QLatin1String("addB068") + << QLatin1String("addB078") + << QLatin1String("addB078A") + << QLatin1String("addB078B") + << QLatin1String("addB167") + << QLatin1String("addB191") + << QLatin1String("isDefault060_2") + << QLatin1String("isDefault069") + << QLatin1String("annotB025") + << QLatin1String("base64Binary_enumeration003_1321") + << QLatin1String("anyURI_a001_1336") + << QLatin1String("anyURI_a001_1336") + << QLatin1String("anyURI_a003_1338") + << QLatin1String("anyURI_a004_1339") + << QLatin1String("anyURI_b004_1354") + << QLatin1String("anyURI_b004_1354") + << QLatin1String("anyURI_b006_1356") + << QLatin1String("QName_length001_1357") + << QLatin1String("QName_length003_1359") + << QLatin1String("QName_minLength003_1362") + << QLatin1String("QName_maxLength001_1364") + << QLatin1String("NOTATION_length001_1372") + << QLatin1String("NOTATION_length003_1374") + << QLatin1String("NOTATION_minLength003_1377") + << QLatin1String("NOTATION_maxLength001_1379") + << QLatin1String("hexBinary003_2069") + << QLatin1String("QName009_2092") + << QLatin1String("dtZ107447_a_2245") + << QLatin1String("elemE001") + << QLatin1String("elemE002") + << QLatin1String("elemE003") + << QLatin1String("elemE004") + << QLatin1String("elemE005") + << QLatin1String("elemT026") + << QLatin1String("elemT027") + << QLatin1String("elemT028") + << QLatin1String("elemT029") + << QLatin1String("elemT054") + << QLatin1String("elemT055") + << QLatin1String("elemT056") + << QLatin1String("elemT057") + << QLatin1String("elemZ006") + << QLatin1String("elemZ007") + << QLatin1String("elemZ026") + << QLatin1String("elemZ027_c") + << QLatin1String("elemZ028c") + << QLatin1String("elemZ028d") + << QLatin1String("elemZ028f1") + << QLatin1String("elemZ028f1") + << QLatin1String("elemZ028f2") + << QLatin1String("elemZ028f2") + << QLatin1String("elemZ028f3") + << QLatin1String("elemZ028f3") + << QLatin1String("elemZ031") + << QLatin1String("errF001") + << QLatin1String("idC019") + << QLatin1String("idL100") + << QLatin1String("idZ011") + << QLatin1String("idZ015") + << QLatin1String("mgO013") + << QLatin1String("particlesA012") + << QLatin1String("particlesA013") + << QLatin1String("particlesA014") + << QLatin1String("particlesA015") + << QLatin1String("particlesHa161") + << QLatin1String("particlesHb008") + << QLatin1String("particlesHb011") + << QLatin1String("particlesIe003") + << QLatin1String("particlesIg003") + << QLatin1String("particlesIg004") + << QLatin1String("particlesJb003") + << QLatin1String("particlesJd003") + << QLatin1String("particlesJf003") + << QLatin1String("particlesJk003") + << QLatin1String("particlesOb001") + << QLatin1String("particlesOb002") + << QLatin1String("particlesOb004") + << QLatin1String("particlesOb008") + << QLatin1String("particlesOb009") + << QLatin1String("particlesOb013") + << QLatin1String("particlesOb018") + << QLatin1String("particlesQ005") + << QLatin1String("particlesS002") + << QLatin1String("particlesT002") + << QLatin1String("particlesT009") + << QLatin1String("particlesT014") + << QLatin1String("particlesV001") + << QLatin1String("particlesV002") + << QLatin1String("particlesV020") + << QLatin1String("particlesZ001") + << QLatin1String("particlesZ005") + << QLatin1String("particlesZ007") + << QLatin1String("particlesZ023") + << QLatin1String("particlesZ024") + << QLatin1String("particlesZ026") + << QLatin1String("particlesZ028") + << QLatin1String("particlesZ033_c") + << QLatin1String("particlesZ033_d") + << QLatin1String("particlesZ033_e") + << QLatin1String("particlesZ033_f") + << QLatin1String("particlesZ033_g") + << QLatin1String("particlesZ034_a1") + << QLatin1String("particlesZ034_a2") + << QLatin1String("particlesZ034_a3") + << QLatin1String("particlesZ034_b") + << QLatin1String("particlesZ035_a") + << QLatin1String("particlesZ035_b") + << QLatin1String("particlesZ036_a") + << QLatin1String("particlesZ036_b1") + << QLatin1String("particlesZ036_b2") + << QLatin1String("particlesZ036_c") +/* + << QLatin1String("reC65") + << QLatin1String("reC66") + << QLatin1String("reC67") + << QLatin1String("reC68") + << QLatin1String("reF58") + << QLatin1String("reG50") + << QLatin1String("reJ11") + << QLatin1String("reJ13") + << QLatin1String("reJ19") + << QLatin1String("reJ21") + << QLatin1String("reJ23") + << QLatin1String("reJ25") + << QLatin1String("reJ29") + << QLatin1String("reJ31") + << QLatin1String("reJ33") + << QLatin1String("reJ35") + << QLatin1String("reJ61") + << QLatin1String("reJ69") + << QLatin1String("reJ75") + << QLatin1String("reJ77") + << QLatin1String("reL98") + << QLatin1String("reL99") + << QLatin1String("reM98") + << QLatin1String("reN99") + << QLatin1String("reS21") + << QLatin1String("reS42") + << QLatin1String("reT63") + << QLatin1String("reT84") + << QLatin1String("reDG2") + << QLatin1String("RegexTest_9") + << QLatin1String("RegexTest_11") + << QLatin1String("RegexTest_14") + << QLatin1String("RegexTest_15") + << QLatin1String("RegexTest_16") + << QLatin1String("RegexTest_17") + << QLatin1String("RegexTest_23") + << QLatin1String("RegexTest_24") + << QLatin1String("RegexTest_25") + << QLatin1String("RegexTest_26") + << QLatin1String("RegexTest_27") + << QLatin1String("RegexTest_28") + << QLatin1String("RegexTest_30") + << QLatin1String("RegexTest_30") + << QLatin1String("RegexTest_33") + << QLatin1String("RegexTest_34") + << QLatin1String("RegexTest_34") + << QLatin1String("RegexTest_43") + << QLatin1String("RegexTest_44") + << QLatin1String("RegexTest_45") + << QLatin1String("RegexTest_46") + << QLatin1String("RegexTest_47") + << QLatin1String("RegexTest_48") + << QLatin1String("RegexTest_49") + << QLatin1String("RegexTest_50") + << QLatin1String("RegexTest_51") + << QLatin1String("RegexTest_52") + << QLatin1String("RegexTest_53") + << QLatin1String("RegexTest_54") + << QLatin1String("RegexTest_55") + << QLatin1String("RegexTest_56") + << QLatin1String("RegexTest_57") + << QLatin1String("RegexTest_57") + << QLatin1String("RegexTest_58") + << QLatin1String("RegexTest_58") + << QLatin1String("RegexTest_65") + << QLatin1String("RegexTest_113") + << QLatin1String("RegexTest_116") + << QLatin1String("RegexTest_119") + << QLatin1String("RegexTest_120") + << QLatin1String("RegexTest_121") + << QLatin1String("RegexTest_141") + << QLatin1String("RegexTest_142") + << QLatin1String("RegexTest_143") + << QLatin1String("RegexTest_145") + << QLatin1String("RegexTest_146") + << QLatin1String("RegexTest_147") + << QLatin1String("RegexTest_148") + << QLatin1String("RegexTest_149") + << QLatin1String("RegexTest_150") + << QLatin1String("RegexTest_151") + << QLatin1String("RegexTest_152") + << QLatin1String("RegexTest_154") + << QLatin1String("RegexTest_155") + << QLatin1String("RegexTest_156") + << QLatin1String("RegexTest_157") + << QLatin1String("RegexTest_158") + << QLatin1String("RegexTest_163") + << QLatin1String("RegexTest_164") + << QLatin1String("RegexTest_165") + << QLatin1String("RegexTest_166") + << QLatin1String("RegexTest_167") + << QLatin1String("RegexTest_168") + << QLatin1String("RegexTest_169") + << QLatin1String("RegexTest_170") + << QLatin1String("RegexTest_171") + << QLatin1String("RegexTest_172") + << QLatin1String("RegexTest_173") + << QLatin1String("RegexTest_174") + << QLatin1String("RegexTest_178") + << QLatin1String("RegexTest_194") + << QLatin1String("RegexTest_194") + << QLatin1String("RegexTest_195") + << QLatin1String("RegexTest_195") + << QLatin1String("RegexTest_196") + << QLatin1String("RegexTest_196") + << QLatin1String("RegexTest_197") + << QLatin1String("RegexTest_198") + << QLatin1String("RegexTest_199") + << QLatin1String("RegexTest_200") + << QLatin1String("RegexTest_200") + << QLatin1String("RegexTest_201") + << QLatin1String("RegexTest_201") + << QLatin1String("RegexTest_202") + << QLatin1String("RegexTest_202") + << QLatin1String("RegexTest_203") + << QLatin1String("RegexTest_204") + << QLatin1String("RegexTest_205") + << QLatin1String("RegexTest_206") + << QLatin1String("RegexTest_207") + << QLatin1String("RegexTest_208") + << QLatin1String("RegexTest_209") + << QLatin1String("RegexTest_209") + << QLatin1String("RegexTest_210") + << QLatin1String("RegexTest_210") + << QLatin1String("RegexTest_211") + << QLatin1String("RegexTest_211") + << QLatin1String("RegexTest_212") + << QLatin1String("RegexTest_213") + << QLatin1String("RegexTest_214") + << QLatin1String("RegexTest_215") + << QLatin1String("RegexTest_216") + << QLatin1String("RegexTest_217") + << QLatin1String("RegexTest_218") + << QLatin1String("RegexTest_220") + << QLatin1String("RegexTest_221") + << QLatin1String("RegexTest_222") + << QLatin1String("RegexTest_226") + << QLatin1String("RegexTest_230") + << QLatin1String("RegexTest_232") + << QLatin1String("RegexTest_233") + << QLatin1String("RegexTest_294") + << QLatin1String("RegexTest_294") + << QLatin1String("RegexTest_295") + << QLatin1String("RegexTest_295") + << QLatin1String("RegexTest_299") + << QLatin1String("RegexTest_300") + << QLatin1String("RegexTest_301") + << QLatin1String("RegexTest_302") + << QLatin1String("RegexTest_303") + << QLatin1String("RegexTest_304") + << QLatin1String("RegexTest_305") + << QLatin1String("RegexTest_306") + << QLatin1String("RegexTest_307") + << QLatin1String("RegexTest_308") + << QLatin1String("RegexTest_309") + << QLatin1String("RegexTest_310") + << QLatin1String("RegexTest_311") + << QLatin1String("RegexTest_312") + << QLatin1String("RegexTest_313") + << QLatin1String("RegexTest_314") + << QLatin1String("RegexTest_315") + << QLatin1String("RegexTest_315") + << QLatin1String("RegexTest_316") + << QLatin1String("RegexTest_316") + << QLatin1String("RegexTest_317") + << QLatin1String("RegexTest_317") + << QLatin1String("RegexTest_440") + << QLatin1String("RegexTest_441") + << QLatin1String("RegexTest_442") + << QLatin1String("RegexTest_443") + << QLatin1String("RegexTest_448") + << QLatin1String("RegexTest_449") + << QLatin1String("RegexTest_450") + << QLatin1String("RegexTest_451") + << QLatin1String("RegexTest_458") + << QLatin1String("RegexTest_464") + << QLatin1String("RegexTest_464") + << QLatin1String("RegexTest_465") + << QLatin1String("RegexTest_469") + << QLatin1String("RegexTest_470") + << QLatin1String("RegexTest_471") + << QLatin1String("RegexTest_472") + << QLatin1String("RegexTest_473") + << QLatin1String("RegexTest_477") + << QLatin1String("RegexTest_478") + << QLatin1String("RegexTest_478") + << QLatin1String("RegexTest_479") + << QLatin1String("RegexTest_480") + << QLatin1String("RegexTest_481") + << QLatin1String("RegexTest_482") + << QLatin1String("RegexTest_482") + << QLatin1String("RegexTest_483") + << QLatin1String("RegexTest_483") + << QLatin1String("RegexTest_484") + << QLatin1String("RegexTest_487") + << QLatin1String("RegexTest_516") + << QLatin1String("RegexTest_516") + << QLatin1String("RegexTest_517") + << QLatin1String("RegexTest_517") + << QLatin1String("RegexTest_518") + << QLatin1String("RegexTest_518") + << QLatin1String("RegexTest_519") + << QLatin1String("RegexTest_519") + << QLatin1String("RegexTest_521") + << QLatin1String("RegexTest_523") + << QLatin1String("RegexTest_524") + << QLatin1String("RegexTest_524") + << QLatin1String("RegexTest_586") + << QLatin1String("RegexTest_587") + << QLatin1String("RegexTest_592") + << QLatin1String("RegexTest_593") + << QLatin1String("RegexTest_594") + << QLatin1String("RegexTest_595") + << QLatin1String("RegexTest_596") + << QLatin1String("RegexTest_597") + << QLatin1String("RegexTest_598") + << QLatin1String("RegexTest_599") + << QLatin1String("RegexTest_600") + << QLatin1String("RegexTest_601") + << QLatin1String("RegexTest_602") + << QLatin1String("RegexTest_603") + << QLatin1String("RegexTest_604") + << QLatin1String("RegexTest_605") + << QLatin1String("RegexTest_648") + << QLatin1String("RegexTest_655") + << QLatin1String("RegexTest_688") + << QLatin1String("RegexTest_696") + << QLatin1String("RegexTest_697") + << QLatin1String("RegexTest_698") + << QLatin1String("RegexTest_700") + << QLatin1String("RegexTest_701") + << QLatin1String("RegexTest_702") + << QLatin1String("RegexTest_703") + << QLatin1String("RegexTest_704") + << QLatin1String("RegexTest_705") + << QLatin1String("RegexTest_706") + << QLatin1String("RegexTest_707") + << QLatin1String("RegexTest_717") + << QLatin1String("RegexTest_718") + << QLatin1String("RegexTest_719") + << QLatin1String("RegexTest_724") + << QLatin1String("RegexTest_725") + << QLatin1String("RegexTest_726") + << QLatin1String("RegexTest_727") + << QLatin1String("RegexTest_728") + << QLatin1String("RegexTest_729") + << QLatin1String("RegexTest_730") + << QLatin1String("RegexTest_731") + << QLatin1String("RegexTest_732") + << QLatin1String("RegexTest_733") + << QLatin1String("RegexTest_743") + << QLatin1String("RegexTest_755") + << QLatin1String("RegexTest_756") + << QLatin1String("RegexTest_761") + << QLatin1String("RegexTest_762") + << QLatin1String("RegexTest_781") + << QLatin1String("RegexTest_782") + << QLatin1String("RegexTest_783") + << QLatin1String("RegexTest_790") + << QLatin1String("RegexTest_791") + << QLatin1String("RegexTest_824") + << QLatin1String("RegexTest_826") + << QLatin1String("RegexTest_827") + << QLatin1String("RegexTest_836") + << QLatin1String("RegexTest_837") + << QLatin1String("RegexTest_841") + << QLatin1String("RegexTest_842") + << QLatin1String("RegexTest_843") + << QLatin1String("RegexTest_844") + << QLatin1String("RegexTest_845") + << QLatin1String("RegexTest_846") + << QLatin1String("RegexTest_847") + << QLatin1String("RegexTest_848") + << QLatin1String("RegexTest_851") + << QLatin1String("RegexTest_852") + << QLatin1String("RegexTest_853") + << QLatin1String("RegexTest_854") + << QLatin1String("RegexTest_855") + << QLatin1String("RegexTest_856") + << QLatin1String("RegexTest_857") + << QLatin1String("RegexTest_861") + << QLatin1String("RegexTest_862") + << QLatin1String("RegexTest_863") + << QLatin1String("RegexTest_864") + << QLatin1String("RegexTest_865") + << QLatin1String("RegexTest_866") + << QLatin1String("RegexTest_870") + << QLatin1String("RegexTest_879") + << QLatin1String("RegexTest_880") + << QLatin1String("RegexTest_888") + << QLatin1String("RegexTest_889") + << QLatin1String("RegexTest_890") + << QLatin1String("RegexTest_891") + << QLatin1String("RegexTest_892") + << QLatin1String("RegexTest_893") + << QLatin1String("RegexTest_894") + << QLatin1String("RegexTest_895") + << QLatin1String("RegexTest_896") + << QLatin1String("RegexTest_897") + << QLatin1String("RegexTest_898") + << QLatin1String("RegexTest_899") + << QLatin1String("RegexTest_900") + << QLatin1String("RegexTest_901") + << QLatin1String("RegexTest_902") + << QLatin1String("RegexTest_903") + << QLatin1String("RegexTest_904") + << QLatin1String("RegexTest_905") + << QLatin1String("RegexTest_906") + << QLatin1String("RegexTest_907") + << QLatin1String("RegexTest_908") + << QLatin1String("RegexTest_909") + << QLatin1String("RegexTest_910") + << QLatin1String("RegexTest_911") + << QLatin1String("RegexTest_912") + << QLatin1String("RegexTest_913") + << QLatin1String("RegexTest_914") + << QLatin1String("RegexTest_915") + << QLatin1String("RegexTest_916") + << QLatin1String("RegexTest_917") + << QLatin1String("RegexTest_918") + << QLatin1String("RegexTest_919") + << QLatin1String("RegexTest_920") + << QLatin1String("RegexTest_921") + << QLatin1String("RegexTest_922") + << QLatin1String("RegexTest_923") + << QLatin1String("RegexTest_924") + << QLatin1String("RegexTest_925") + << QLatin1String("RegexTest_926") + << QLatin1String("RegexTest_928") + << QLatin1String("RegexTest_929") + << QLatin1String("RegexTest_930") + << QLatin1String("RegexTest_936") + << QLatin1String("RegexTest_937") + << QLatin1String("RegexTest_938") + << QLatin1String("RegexTest_939") + << QLatin1String("RegexTest_940") + << QLatin1String("RegexTest_941") + << QLatin1String("RegexTest_942") + << QLatin1String("RegexTest_943") + << QLatin1String("RegexTest_944") + << QLatin1String("RegexTest_945") + << QLatin1String("RegexTest_946") + << QLatin1String("RegexTest_949") + << QLatin1String("RegexTest_950") + << QLatin1String("RegexTest_951") + << QLatin1String("RegexTest_952") + << QLatin1String("RegexTest_953") + << QLatin1String("RegexTest_954") + << QLatin1String("RegexTest_955") + << QLatin1String("RegexTest_956") + << QLatin1String("RegexTest_957") + << QLatin1String("RegexTest_958") + << QLatin1String("RegexTest_959") + << QLatin1String("RegexTest_960") + << QLatin1String("RegexTest_961") + << QLatin1String("RegexTest_962") + << QLatin1String("RegexTest_963") + << QLatin1String("RegexTest_964") + << QLatin1String("RegexTest_976") + << QLatin1String("RegexTest_977") + << QLatin1String("RegexTest_988") + << QLatin1String("RegexTest_989") + << QLatin1String("RegexTest_990") + << QLatin1String("RegexTest_991") + << QLatin1String("RegexTest_994") + << QLatin1String("RegexTest_995") + << QLatin1String("RegexTest_996") + << QLatin1String("RegexTest_997") + << QLatin1String("RegexTest_1000") + << QLatin1String("RegexTest_1001") + << QLatin1String("RegexTest_1002") + << QLatin1String("RegexTest_1003") + << QLatin1String("RegexTest_1004") + << QLatin1String("RegexTest_1007") + << QLatin1String("RegexTest_1008") + << QLatin1String("RegexTest_1009") + << QLatin1String("RegexTest_1010") + << QLatin1String("RegexTest_1011") + << QLatin1String("RegexTest_1012") + << QLatin1String("RegexTest_1013") + << QLatin1String("RegexTest_1014") + << QLatin1String("RegexTest_1015") + << QLatin1String("RegexTest_1016") + << QLatin1String("RegexTest_1017") + << QLatin1String("RegexTest_1018") + << QLatin1String("RegexTest_1019") + << QLatin1String("RegexTest_1070") + << QLatin1String("RegexTest_1071") + << QLatin1String("RegexTest_1076") + << QLatin1String("RegexTest_1077") + << QLatin1String("RegexTest_1078") + << QLatin1String("RegexTest_1079") + << QLatin1String("RegexTest_1080") + << QLatin1String("RegexTest_1081") + << QLatin1String("RegexTest_1082") + << QLatin1String("RegexTest_1083") + << QLatin1String("RegexTest_1084") + << QLatin1String("RegexTest_1085") + << QLatin1String("RegexTest_1086") + << QLatin1String("RegexTest_1087") + << QLatin1String("RegexTest_1088") + << QLatin1String("RegexTest_1089") + << QLatin1String("RegexTest_1132") + << QLatin1String("RegexTest_1139") + << QLatin1String("RegexTest_1172") + << QLatin1String("RegexTest_1180") + << QLatin1String("RegexTest_1181") + << QLatin1String("RegexTest_1182") + << QLatin1String("RegexTest_1184") + << QLatin1String("RegexTest_1185") + << QLatin1String("RegexTest_1186") + << QLatin1String("RegexTest_1187") + << QLatin1String("RegexTest_1188") + << QLatin1String("RegexTest_1189") + << QLatin1String("RegexTest_1190") + << QLatin1String("RegexTest_1191") + << QLatin1String("RegexTest_1201") + << QLatin1String("RegexTest_1202") + << QLatin1String("RegexTest_1203") + << QLatin1String("RegexTest_1208") + << QLatin1String("RegexTest_1209") + << QLatin1String("RegexTest_1210") + << QLatin1String("RegexTest_1211") + << QLatin1String("RegexTest_1212") + << QLatin1String("RegexTest_1213") + << QLatin1String("RegexTest_1214") + << QLatin1String("RegexTest_1215") + << QLatin1String("RegexTest_1216") + << QLatin1String("RegexTest_1217") + << QLatin1String("RegexTest_1227") + << QLatin1String("RegexTest_1239") + << QLatin1String("RegexTest_1240") + << QLatin1String("RegexTest_1245") + << QLatin1String("RegexTest_1246") + << QLatin1String("RegexTest_1265") + << QLatin1String("RegexTest_1266") + << QLatin1String("RegexTest_1267") + << QLatin1String("RegexTest_1274") + << QLatin1String("RegexTest_1275") + << QLatin1String("RegexTest_1308") + << QLatin1String("RegexTest_1310") + << QLatin1String("RegexTest_1311") + << QLatin1String("RegexTest_1320") + << QLatin1String("RegexTest_1321") + << QLatin1String("RegexTest_1322") + << QLatin1String("RegexTest_1323") + << QLatin1String("RegexTest_1324") + << QLatin1String("RegexTest_1325") + << QLatin1String("RegexTest_1326") + << QLatin1String("RegexTest_1327") + << QLatin1String("RegexTest_1328") + << QLatin1String("RegexTest_1329") + << QLatin1String("RegexTest_1330") + << QLatin1String("RegexTest_1331") + << QLatin1String("RegexTest_1332") + << QLatin1String("RegexTest_1335") + << QLatin1String("RegexTest_1336") + << QLatin1String("RegexTest_1337") + << QLatin1String("RegexTest_1338") + << QLatin1String("RegexTest_1339") + << QLatin1String("RegexTest_1340") + << QLatin1String("RegexTest_1341") + << QLatin1String("RegexTest_1345") + << QLatin1String("RegexTest_1346") + << QLatin1String("RegexTest_1347") + << QLatin1String("RegexTest_1348") + << QLatin1String("RegexTest_1349") + << QLatin1String("RegexTest_1350") + << QLatin1String("RegexTest_1354") + << QLatin1String("RegexTest_1363") + << QLatin1String("RegexTest_1364") + << QLatin1String("RegexTest_1365") + << QLatin1String("RegexTest_1372") + << QLatin1String("RegexTest_1373") + << QLatin1String("RegexTest_1374") + << QLatin1String("RegexTest_1375") + << QLatin1String("RegexTest_1376") + << QLatin1String("RegexTest_1377") + << QLatin1String("RegexTest_1378") + << QLatin1String("RegexTest_1379") + << QLatin1String("RegexTest_1380") + << QLatin1String("RegexTest_1381") + << QLatin1String("RegexTest_1382") + << QLatin1String("RegexTest_1383") + << QLatin1String("RegexTest_1384") + << QLatin1String("RegexTest_1385") + << QLatin1String("RegexTest_1386") + << QLatin1String("RegexTest_1387") + << QLatin1String("RegexTest_1388") + << QLatin1String("RegexTest_1389") + << QLatin1String("RegexTest_1390") + << QLatin1String("RegexTest_1391") + << QLatin1String("RegexTest_1392") + << QLatin1String("RegexTest_1393") + << QLatin1String("RegexTest_1394") + << QLatin1String("RegexTest_1395") + << QLatin1String("RegexTest_1396") + << QLatin1String("RegexTest_1397") + << QLatin1String("RegexTest_1398") + << QLatin1String("RegexTest_1399") + << QLatin1String("RegexTest_1400") + << QLatin1String("RegexTest_1401") + << QLatin1String("RegexTest_1402") + << QLatin1String("RegexTest_1403") + << QLatin1String("RegexTest_1404") + << QLatin1String("RegexTest_1405") + << QLatin1String("RegexTest_1406") + << QLatin1String("RegexTest_1407") + << QLatin1String("RegexTest_1408") + << QLatin1String("RegexTest_1409") + << QLatin1String("RegexTest_1410") + << QLatin1String("RegexTest_1412") + << QLatin1String("RegexTest_1413") + << QLatin1String("RegexTest_1414") + << QLatin1String("RegexTest_1420") + << QLatin1String("RegexTest_1421") + << QLatin1String("RegexTest_1422") + << QLatin1String("RegexTest_1423") + << QLatin1String("RegexTest_1424") + << QLatin1String("RegexTest_1425") + << QLatin1String("RegexTest_1426") + << QLatin1String("RegexTest_1427") + << QLatin1String("RegexTest_1428") + << QLatin1String("RegexTest_1429") + << QLatin1String("RegexTest_1430") + << QLatin1String("RegexTest_1433") + << QLatin1String("RegexTest_1434") + << QLatin1String("RegexTest_1435") + << QLatin1String("RegexTest_1436") + << QLatin1String("RegexTest_1437") + << QLatin1String("RegexTest_1438") + << QLatin1String("RegexTest_1439") + << QLatin1String("RegexTest_1440") + << QLatin1String("RegexTest_1441") + << QLatin1String("RegexTest_1442") + << QLatin1String("RegexTest_1443") + << QLatin1String("RegexTest_1444") + << QLatin1String("RegexTest_1445") + << QLatin1String("RegexTest_1446") + << QLatin1String("RegexTest_1447") + << QLatin1String("RegexTest_1448") + << QLatin1String("RegexTest_1451") + << QLatin1String("RegexTest_1452") + << QLatin1String("RegexTest_1453") + << QLatin1String("RegexTest_1454") + << QLatin1String("RegexTest_1455") + << QLatin1String("RegexTest_1456") + << QLatin1String("RegexTest_1472") + << QLatin1String("RegexTest_1473") + << QLatin1String("RegexTest_1474") + << QLatin1String("RegexTest_1475") + << QLatin1String("RegexTest_1478") + << QLatin1String("RegexTest_1479") + << QLatin1String("RegexTest_1480") + << QLatin1String("RegexTest_1481") + << QLatin1String("RegexTest_1484") + << QLatin1String("RegexTest_1485") + << QLatin1String("RegexTest_1486") + << QLatin1String("RegexTest_1487") + << QLatin1String("RegexTest_1488") + << QLatin1String("RegexTest_1491") + << QLatin1String("RegexTest_1492") + << QLatin1String("RegexTest_1493") + << QLatin1String("RegexTest_1494") + << QLatin1String("RegexTest_1495") + << QLatin1String("RegexTest_1496") + << QLatin1String("RegexTest_1497") + << QLatin1String("RegexTest_1498") + << QLatin1String("RegexTest_1499") + << QLatin1String("RegexTest_1500") + << QLatin1String("RegexTest_1501") + << QLatin1String("RegexTest_1502") + << QLatin1String("RegexTest_1503") + << QLatin1String("RegexTest_1543") + << QLatin1String("RegexTest_1544") + << QLatin1String("reZ001") +*/ + << QLatin1String("schA2") + << QLatin1String("schA5") + << QLatin1String("schA7") + << QLatin1String("schD8") + << QLatin1String("schG3") + << QLatin1String("schG6") + << QLatin1String("schG9") + << QLatin1String("schG11") + << QLatin1String("schG12") + << QLatin1String("schU1") + << QLatin1String("schU3") + << QLatin1String("schU4") + << QLatin1String("schU5") + << QLatin1String("schZ004") + << QLatin1String("schZ005") + << QLatin1String("schZ012_a") + << QLatin1String("stZ041") + << QLatin1String("wildZ010"); +} + +bool XSDTestSuiteHandler::startElement(const QString &namespaceURI, + const QString &localName, + const QString &/*qName*/, + const QXmlAttributes &atts) +{ + if(namespaceURI != QString::fromLatin1("http://www.w3.org/XML/2004/xml-schema-test-suite/")) + return true; + + if (localName == QLatin1String("testSet")) { + m_currentTestSet = new TestGroup(m_topLevelGroup); + Q_ASSERT(m_currentTestSet); + m_currentTestSet->setTitle(atts.value("name")); + m_topLevelGroup->appendChild(m_currentTestSet); + } else if (localName == QLatin1String("testGroup")) { + m_currentTestGroup = new TestGroup(m_currentTestSet); + Q_ASSERT(m_currentTestGroup); + m_currentTestGroup->setTitle(atts.value("name")); + m_currentTestSet->appendChild(m_currentTestGroup); + m_inTestGroup = true; + } else if (localName == QLatin1String("schemaTest")) { + if (m_blackList.contains(atts.value("name"))) { + m_currentTestCase = 0; + m_schemaBlacklisted = true; + return true; + } + m_schemaBlacklisted = false; + + m_currentTestCase = new XSDTSTestCase(TestCase::Standard, m_currentTestGroup, XSDTSTestCase::SchemaTest); + Q_ASSERT(m_currentTestCase); + m_counter++; + m_currentTestCase->setName(QString::number(m_counter) + atts.value("name")); + m_currentTestGroup->appendChild(m_currentTestCase); + m_currentTestCase->setParent(m_currentTestGroup); + + m_inSchemaTest = true; + } else if (localName == QLatin1String("instanceTest")) { + if (m_schemaBlacklisted) { + m_currentTestCase = 0; + return true; + } + + m_currentTestCase = new XSDTSTestCase(TestCase::Standard, m_currentTestGroup, XSDTSTestCase::InstanceTest); + Q_ASSERT(m_currentTestCase); + m_counter++; + m_currentTestCase->setName(QString::number(m_counter) + atts.value("name")); + m_currentTestGroup->appendChild(m_currentTestCase); + + m_inInstanceTest = true; + } else if (localName == QLatin1String("schemaDocument") || localName == QLatin1String("instanceDocument")) { + if (m_inSchemaTest) { + m_currentTestCase->setSchemaUri(QUrl(atts.value("xlink:href"))); + if (m_currentSchemaLink.isEmpty()) // we only use the first schema document for validation + m_currentSchemaLink = atts.value("xlink:href"); + } + if (m_inInstanceTest) { + m_currentTestCase->setInstanceUri(QUrl(atts.value("xlink:href"))); + m_currentTestCase->setSchemaUri(QUrl(m_currentSchemaLink)); + } + } else if (localName == QLatin1String("expected") && (m_inSchemaTest || m_inInstanceTest)) { + TestBaseLine *baseLine = new TestBaseLine(TestBaseLine::SchemaIsValid); + if (atts.value("validity") == QLatin1String("valid")) { + baseLine->setDetails(QLatin1String("true")); + m_currentTestCase->setName(m_currentTestCase->name() + QLatin1String(" tokoe:valid")); + } else { + baseLine->setDetails(QLatin1String("false")); + m_currentTestCase->setName(m_currentTestCase->name() + QLatin1String(" tokoe:invalid")); + } + + m_currentTestCase->addBaseLine(baseLine); + } else if (localName == QLatin1String("documentation") && m_inTestGroup) { + m_inDescription = true; + } + + return true; +} + +bool XSDTestSuiteHandler::endElement(const QString &namespaceURI, + const QString &localName, + const QString &/*qName*/) +{ + if (localName == QLatin1String("testGroup")) { + m_inTestGroup = false; + m_currentTestGroup->setDescription(m_documentation); + m_documentation.clear(); + m_currentSchemaLink.clear(); + + if (m_currentTestGroup->childCount() == 0) + m_currentTestSet->removeLast(); + } else if (localName == QLatin1String("schemaTest")) + m_inSchemaTest = false; + else if (localName == QLatin1String("instanceTest")) + m_inInstanceTest = false; + else if (localName == QLatin1String("documentation")) + m_inDescription = false; + + return true; +} + +bool XSDTestSuiteHandler::characters(const QString &ch) +{ + if (m_inDescription) + m_documentation += ch; + + return true; +} + +TestSuite *XSDTestSuiteHandler::testSuite() const +{ + return m_ts; +} + +// vim: et:ts=4:sw=4:sts=4 + diff --git a/tests/auto/xmlpatternsxqts/lib/XSDTestSuiteHandler.h b/tests/auto/xmlpatternsxqts/lib/XSDTestSuiteHandler.h new file mode 100644 index 0000000..8c57e82 --- /dev/null +++ b/tests/auto/xmlpatternsxqts/lib/XSDTestSuiteHandler.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Patternist project on Trolltech Labs. +** +** $TROLLTECH_GPL_LICENSE$ +** +*************************************************************************** +*/ + +#ifndef PatternistSDK_XSDTestSuiteHandler_H +#define PatternistSDK_XSDTestSuiteHandler_H + +#include +#include + +#include "ExternalSourceLoader.h" +#include "TestSuite.h" +#include "XQTSTestCase.h" + +QT_BEGIN_HEADER + +namespace QPatternistSDK +{ + class TestBaseLine; + class TestGroup; + class XSDTSTestCase; + + /** + * @short Creates a TestSuite from the XSD Test Suite. + * + * The created TestSuite can be retrieved via testSuite(). + * + * @note XSDTestSuiteHandler assumes the XML is valid by having been validated + * against the W3C XML Schema. It has no safety checks for that the XML format + * is correct but is hard coded for it. Thus, the behavior is undefined if + * the XML is invalid. + * + * @ingroup PatternistSDK + * @author Tobias Koenig + */ + class Q_PATTERNISTSDK_EXPORT XSDTestSuiteHandler : public QXmlDefaultHandler + { + public: + /** + * @param catalogFile the URI for the catalog file being parsed. This + * URI is used for creating absolute URIs for files mentioned in + * the catalog with relative URIs. + * @param useExclusionList whether excludeTestGroups.txt should be used to ignore + * test groups when loading + */ + XSDTestSuiteHandler(const QUrl &catalogFile); + virtual bool characters(const QString &ch); + + virtual bool endElement(const QString &namespaceURI, + const QString &localName, + const QString &qName); + virtual bool startElement(const QString &namespaceURI, + const QString &localName, + const QString &qName, + const QXmlAttributes &atts); + + virtual TestSuite *testSuite() const; + + private: + TestSuite* m_ts; + const QUrl m_catalogFile; + + TestGroup* m_topLevelGroup; + TestGroup* m_currentTestSet; + TestGroup* m_currentTestGroup; + XSDTSTestCase* m_currentTestCase; + bool m_inSchemaTest; + bool m_inInstanceTest; + bool m_inTestGroup; + bool m_inDescription; + bool m_schemaBlacklisted; + QString m_documentation; + QString m_currentSchemaLink; + int m_counter; + QSet m_blackList; + }; +} + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternsxqts/lib/lib.pro b/tests/auto/xmlpatternsxqts/lib/lib.pro index 5b12d63..cb9453a 100644 --- a/tests/auto/xmlpatternsxqts/lib/lib.pro +++ b/tests/auto/xmlpatternsxqts/lib/lib.pro @@ -50,6 +50,8 @@ HEADERS = ASTItem.h \ Worker.h \ XMLWriter.h \ XQTSTestCase.h \ + XSDTestSuiteHandler.h \ + XSDTSTestCase.h \ XSLTTestSuiteHandler.h SOURCES = ASTItem.cpp \ @@ -75,4 +77,6 @@ SOURCES = ASTItem.cpp \ Worker.cpp \ XMLWriter.cpp \ XQTSTestCase.cpp \ + XSDTestSuiteHandler.cpp \ + XSDTSTestCase.cpp \ XSLTTestSuiteHandler.cpp diff --git a/tests/auto/xmlpatternsxqts/test/tst_suitetest.cpp b/tests/auto/xmlpatternsxqts/test/tst_suitetest.cpp index 1f9e396..71abbb9 100644 --- a/tests/auto/xmlpatternsxqts/test/tst_suitetest.cpp +++ b/tests/auto/xmlpatternsxqts/test/tst_suitetest.cpp @@ -55,11 +55,11 @@ using namespace QPatternistSDK; -tst_SuiteTest::tst_SuiteTest(const bool isXSLT, +tst_SuiteTest::tst_SuiteTest(const SuiteType suiteType, const bool alwaysRun) : m_existingBaseline(inputFile(QLatin1String("Baseline.xml"))) , m_candidateBaseline(inputFile(QLatin1String("CandidateBaseline.xml"))) , m_abortRun(!alwaysRun && !QFile::exists(QLatin1String("runTests"))) - , m_isXSLT(isXSLT) + , m_suiteType(suiteType) { } @@ -86,7 +86,16 @@ void tst_SuiteTest::runTestSuite() const QString errMsg; const QFileInfo fi(m_catalogPath); const QUrl catalogPath(QUrl::fromLocalFile(fi.absoluteFilePath())); - TestSuite *const ts = TestSuite::openCatalog(catalogPath, errMsg, true, m_isXSLT); + + TestSuite::SuiteType suiteType; + switch (m_suiteType) { + case XQuerySuite: suiteType = TestSuite::XQuerySuite; + case XsltSuite: suiteType = TestSuite::XsltSuite; + case XsdSuite: suiteType = TestSuite::XsdSuite; + default: break; + } + + TestSuite *const ts = TestSuite::openCatalog(catalogPath, errMsg, true, suiteType); QVERIFY2(ts, qPrintable(QString::fromLatin1("Failed to open the catalog, maybe it doesn't exist or is broken: %1").arg(errMsg))); diff --git a/tests/auto/xmlpatternsxqts/test/tst_suitetest.h b/tests/auto/xmlpatternsxqts/test/tst_suitetest.h index 922f645..05bf6cb 100644 --- a/tests/auto/xmlpatternsxqts/test/tst_suitetest.h +++ b/tests/auto/xmlpatternsxqts/test/tst_suitetest.h @@ -50,13 +50,21 @@ \class tst_SuiteTest \internal \since 4.5 - \brief Base class for tst_XmlPatternsXQTS and tst_XmlPatternsXSLTS. + \brief Base class for tst_XmlPatternsXQTS, tst_XmlPatternsXSLTS and tst_XmlPatternsXSDTS. */ class tst_SuiteTest : public QObject , private TestFundament { Q_OBJECT +public: + enum SuiteType + { + XQuerySuite, + XsltSuite, + XsdSuite + }; + protected: /** * @p isXSLT is @c true if the catalog opened is an @@ -65,7 +73,7 @@ protected: * @p alwaysRun is @c true if the test should always be run, * regardless of if the file runTests exists. */ - tst_SuiteTest(const bool isXSLT, + tst_SuiteTest(SuiteType type, const bool alwaysRun = false); /** @@ -91,7 +99,7 @@ private: const QString m_existingBaseline; const QString m_candidateBaseline; const bool m_abortRun; - const bool m_isXSLT; + const SuiteType m_suiteType; }; #endif diff --git a/tests/auto/xmlpatternsxqts/test/tst_xmlpatternsxqts.cpp b/tests/auto/xmlpatternsxqts/test/tst_xmlpatternsxqts.cpp index 6d9502d..1193372 100644 --- a/tests/auto/xmlpatternsxqts/test/tst_xmlpatternsxqts.cpp +++ b/tests/auto/xmlpatternsxqts/test/tst_xmlpatternsxqts.cpp @@ -61,7 +61,7 @@ public: virtual void catalogPath(QString &write) const; }; -tst_XmlPatternsXQTS::tst_XmlPatternsXQTS() : tst_SuiteTest(false) +tst_XmlPatternsXQTS::tst_XmlPatternsXQTS() : tst_SuiteTest(tst_SuiteTest::XQuerySuite) { } diff --git a/tests/auto/xmlpatternsxslts/tst_xmlpatternsxslts.cpp b/tests/auto/xmlpatternsxslts/tst_xmlpatternsxslts.cpp index 6f1d217..f9b1c76 100644 --- a/tests/auto/xmlpatternsxslts/tst_xmlpatternsxslts.cpp +++ b/tests/auto/xmlpatternsxslts/tst_xmlpatternsxslts.cpp @@ -61,7 +61,7 @@ protected: virtual void catalogPath(QString &write) const; }; -tst_XmlPatternsXSLTS::tst_XmlPatternsXSLTS() : tst_SuiteTest(true) +tst_XmlPatternsXSLTS::tst_XmlPatternsXSLTS() : tst_SuiteTest(tst_SuiteTest::XsltSuite) { } diff --git a/tools/tools.pro b/tools/tools.pro index 0a56cfb..e7f7b03 100644 --- a/tools/tools.pro +++ b/tools/tools.pro @@ -25,7 +25,7 @@ mac { SUBDIRS += kmap2qmap contains(QT_CONFIG, dbus):SUBDIRS += qdbus -!wince*:contains(QT_CONFIG, xmlpatterns): SUBDIRS += xmlpatterns +!wince*:contains(QT_CONFIG, xmlpatterns): SUBDIRS += xmlpatterns xmlpatternsvalidator embedded: SUBDIRS += makeqpf CONFIG+=ordered diff --git a/tools/xmlpatternsvalidator/main.cpp b/tools/xmlpatternsvalidator/main.cpp new file mode 100644 index 0000000..032afc0 --- /dev/null +++ b/tools/xmlpatternsvalidator/main.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Patternist project on Trolltech Labs. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "main.h" + +#include +#include +#include +#include +#include + +QT_USE_NAMESPACE + +enum ExecutionMode +{ + InvalidMode, + SchemaOnlyMode, + SchemaAndInstanceMode, + InstanceOnlyMode +}; + +int main(int argc, char **argv) +{ + const QCoreApplication app(argc, argv); + QCoreApplication::setApplicationName(QLatin1String("xmlpatternsvalidator")); + + if (argc != 2 && argc != 3) { + qDebug() << QXmlPatternistCLI::tr("usage: xmlpatternsvalidator ( | | )"); + return 2; + } + + // parse command line arguments + ExecutionMode mode = InvalidMode; + + if (argc == 2) { + // either it is a schema or instance document + + QString url = QFile::decodeName(argv[1]); + if (url.toLower().endsWith(QLatin1String(".xsd"))) { + mode = SchemaOnlyMode; + } else { + // as we could validate all types of xml documents, don't check the extension here + mode = InstanceOnlyMode; + } + } else if (argc == 3) { + mode = SchemaAndInstanceMode; + } + + // do validation + QXmlSchema schema; + + if (mode == SchemaOnlyMode) { + const QString schemaUri = QFile::decodeName(argv[1]); + + schema.load(QUrl(schemaUri)); + + if (schema.isValid()) + return 0; + else + return 1; + } else if (mode == SchemaAndInstanceMode) { + const QString instanceUri = QFile::decodeName(argv[1]); + const QString schemaUri = QFile::decodeName(argv[2]); + + schema.load(QUrl(schemaUri)); + + if (!schema.isValid()) + return 1; + + QXmlSchemaValidator validator(schema); + if (validator.validate(QUrl(instanceUri))) + return 0; + else + return 1; + } else if (mode == InstanceOnlyMode) { + const QString instanceUri = QFile::decodeName(argv[1]); + + QXmlSchemaValidator validator(schema); + if (validator.validate(QUrl(instanceUri))) + return 0; + else + return 1; + } + + Q_ASSERT(false); + + return 1; +} diff --git a/tools/xmlpatternsvalidator/main.h b/tools/xmlpatternsvalidator/main.h new file mode 100644 index 0000000..477a45a --- /dev/null +++ b/tools/xmlpatternsvalidator/main.h @@ -0,0 +1,46 @@ +/**************************************************************************** + ** + ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + ** Contact: Qt Software Information (qt-info@nokia.com) + ** + ** This file is part of the Patternist project on Trolltech Labs. * ** + ** $TROLLTECH_DUAL_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. + ** + ****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_main_h +#define Patternist_main_h + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QXmlPatternistCLI +{ +public: + Q_DECLARE_TR_FUNCTIONS(QXmlPatternistCLI) +private: + inline QXmlPatternistCLI(); + Q_DISABLE_COPY(QXmlPatternistCLI) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/tools/xmlpatternsvalidator/xmlpatternsvalidator.pro b/tools/xmlpatternsvalidator/xmlpatternsvalidator.pro new file mode 100644 index 0000000..dd5bd37 --- /dev/null +++ b/tools/xmlpatternsvalidator/xmlpatternsvalidator.pro @@ -0,0 +1,19 @@ +TEMPLATE = app +TARGET = xmlpatternsvalidator +DESTDIR = ../../bin +QT -= gui +QT += xmlpatterns + +target.path = $$[QT_INSTALL_BINS] +INSTALLS += target + +# This ensures we get stderr and stdout on Windows. +CONFIG += console + +# This ensures that this is a command-line program on OS X and not a GUI application. +CONFIG -= app_bundle + +SOURCES = main.cpp +HEADERS = main.h + +include(../src/common.pri) -- cgit v0.12 From 456463169c6d00b9938f0d975dbd7f398edea39d Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Sat, 16 May 2009 12:30:25 +0200 Subject: Various api, documentation and code cleanups --- src/xmlpatterns/api/qxmlquery.cpp | 6 +- src/xmlpatterns/api/qxmlquery_p.h | 13 -- src/xmlpatterns/api/qxmlschema.cpp | 19 +- src/xmlpatterns/api/qxmlschema.h | 11 +- src/xmlpatterns/api/qxmlschema_p.cpp | 8 +- src/xmlpatterns/api/qxmlschema_p.h | 6 +- src/xmlpatterns/api/qxmlschemavalidator.cpp | 38 +++- src/xmlpatterns/api/qxmlschemavalidator.h | 13 +- src/xmlpatterns/api/qxmlschemavalidator_p.h | 5 +- src/xmlpatterns/schema/qnamespacesupport.cpp | 4 +- src/xmlpatterns/schema/qxsdparticlechecker.cpp | 6 +- src/xmlpatterns/schema/qxsdschemacontext.cpp | 2 +- src/xmlpatterns/schema/qxsdschemacontext_p.h | 4 +- src/xmlpatterns/schema/qxsdschemadebugger_p.h | 2 +- src/xmlpatterns/schema/qxsdschemahelper.cpp | 4 +- src/xmlpatterns/schema/qxsdschemahelper_p.h | 63 +++++-- src/xmlpatterns/schema/qxsdschemaparser.cpp | 46 +++-- src/xmlpatterns/schema/qxsdstatemachine.cpp | 16 +- src/xmlpatterns/schema/qxsdstatemachine_p.h | 6 + .../schema/qxsdvalidatedxmlnodemodel.cpp | 2 +- .../schema/qxsdvalidatedxmlnodemodel_p.h | 10 +- .../schema/qxsdvalidatinginstancereader.cpp | 15 +- .../schema/qxsdvalidatinginstancereader_p.h | 2 +- src/xmlpatterns/utils/qxpathhelper.cpp | 12 ++ src/xmlpatterns/utils/qxpathhelper_p.h | 5 + .../patternistheaders/tst_patternistheaders.cpp | 8 + tests/auto/qxmlschema/tst_qxmlschema.cpp | 195 ++++++++++++++++++--- .../tst_qxmlschemavalidator.cpp | 145 +++++++++++---- tools/xmlpatternsvalidator/main.cpp | 41 +++-- 29 files changed, 521 insertions(+), 186 deletions(-) diff --git a/src/xmlpatterns/api/qxmlquery.cpp b/src/xmlpatterns/api/qxmlquery.cpp index 423da3e..1cf0a2e 100644 --- a/src/xmlpatterns/api/qxmlquery.cpp +++ b/src/xmlpatterns/api/qxmlquery.cpp @@ -427,7 +427,7 @@ void QXmlQuery::setQuery(QIODevice *sourceCode, const QUrl &documentURI) return; } - d->queryURI = QXmlQueryPrivate::normalizeQueryURI(documentURI); + d->queryURI = QPatternist::XPathHelper::normalizeQueryURI(documentURI); d->expression(sourceCode); } @@ -475,12 +475,12 @@ void QXmlQuery::setQuery(const QUrl &queryURI, const QUrl &baseURI) { Q_ASSERT_X(queryURI.isValid(), Q_FUNC_INFO, "The passed URI must be valid."); - const QUrl canonicalURI(QXmlQueryPrivate::normalizeQueryURI(queryURI)); + const QUrl canonicalURI(QPatternist::XPathHelper::normalizeQueryURI(queryURI)); Q_ASSERT(canonicalURI.isValid()); Q_ASSERT(!canonicalURI.isRelative()); Q_ASSERT(baseURI.isValid() || baseURI.isEmpty()); - d->queryURI = QXmlQueryPrivate::normalizeQueryURI(baseURI.isEmpty() ? queryURI : baseURI); + d->queryURI = QPatternist::XPathHelper::normalizeQueryURI(baseURI.isEmpty() ? queryURI : baseURI); QPatternist::AutoPtr result; diff --git a/src/xmlpatterns/api/qxmlquery_p.h b/src/xmlpatterns/api/qxmlquery_p.h index 7f58f97..486d885 100644 --- a/src/xmlpatterns/api/qxmlquery_p.h +++ b/src/xmlpatterns/api/qxmlquery_p.h @@ -212,19 +212,6 @@ public: return m_resourceLoader; } - - static inline QUrl normalizeQueryURI(const QUrl &uri) - { - Q_ASSERT_X(uri.isEmpty() || uri.isValid(), Q_FUNC_INFO, - "The URI passed to QXmlQuery::setQuery() must be valid or empty."); - if(uri.isEmpty()) - return QUrl::fromLocalFile(QCoreApplication::applicationFilePath()); - else if(uri.isRelative()) - return QUrl::fromLocalFile(QCoreApplication::applicationFilePath()).resolved(uri); - else - return uri; - } - void setRequiredType(const QPatternist::SequenceType::Ptr &seqType) { Q_ASSERT(seqType); diff --git a/src/xmlpatterns/api/qxmlschema.cpp b/src/xmlpatterns/api/qxmlschema.cpp index 55b96cd..108212e 100644 --- a/src/xmlpatterns/api/qxmlschema.cpp +++ b/src/xmlpatterns/api/qxmlschema.cpp @@ -21,7 +21,7 @@ \brief The QXmlSchema class provides loading and validation of a W3C XML Schema. \reentrant - \since 4.X + \since 4.6 \ingroup xml-tools The QXmlSchema class loads, compiles and validates W3C XML Schema files @@ -31,7 +31,7 @@ /*! Constructs an invalid, empty schema that cannot be used until - setSchema() is called. + load() is called. */ QXmlSchema::QXmlSchema() : d(new QXmlSchemaPrivate(QXmlNamePool())) @@ -59,9 +59,10 @@ QXmlSchema::~QXmlSchema() Sets this QXmlSchema to a schema loaded from the \a source URI. */ -void QXmlSchema::load(const QUrl &source) +bool QXmlSchema::load(const QUrl &source) { d->load(source, QString()); + return d->isValid(); } /*! @@ -78,9 +79,10 @@ void QXmlSchema::load(const QUrl &source) a valid URI, behavior is undefined. \sa isValid() */ -void QXmlSchema::load(QIODevice *source, const QUrl &documentUri) +bool QXmlSchema::load(QIODevice *source, const QUrl &documentUri) { d->load(source, documentUri, QString()); + return d->isValid(); } /*! @@ -94,9 +96,10 @@ void QXmlSchema::load(QIODevice *source, const QUrl &documentUri) If \a documentUri is not a valid URI, behavior is undefined. \sa isValid() */ -void QXmlSchema::load(const QByteArray &data, const QUrl &documentUri) +bool QXmlSchema::load(const QByteArray &data, const QUrl &documentUri) { d->load(data, documentUri, QString()); + return d->isValid(); } /*! @@ -183,14 +186,14 @@ QAbstractMessageHandler *QXmlSchema::messageHandler() const \sa uriResolver() */ -void QXmlSchema::setUriResolver(QAbstractUriResolver *resolver) +void QXmlSchema::setUriResolver(const QAbstractUriResolver *resolver) { d->setUriResolver(resolver); } /*! Returns the schema's URI resolver. If no URI resolver has been set, - QtXmlPatterns will use the URIs in queries as they are. + QtXmlPatterns will use the URIs in schemas as they are. The URI resolver provides a level of abstraction, or \e{polymorphic URIs}. A resolver can rewrite \e{logical} URIs to physical ones, or @@ -202,7 +205,7 @@ void QXmlSchema::setUriResolver(QAbstractUriResolver *resolver) \sa setUriResolver() */ -QAbstractUriResolver *QXmlSchema::uriResolver() const +const QAbstractUriResolver *QXmlSchema::uriResolver() const { return d->uriResolver(); } diff --git a/src/xmlpatterns/api/qxmlschema.h b/src/xmlpatterns/api/qxmlschema.h index 225cce2..cf56b1e 100644 --- a/src/xmlpatterns/api/qxmlschema.h +++ b/src/xmlpatterns/api/qxmlschema.h @@ -13,6 +13,7 @@ #define QXMLSCHEMA_H #include +#include #include QT_BEGIN_HEADER @@ -37,9 +38,9 @@ class Q_XMLPATTERNS_EXPORT QXmlSchema QXmlSchema(const QXmlSchema &other); ~QXmlSchema(); - void load(const QUrl &source); - void load(QIODevice *source, const QUrl &documentUri); - void load(const QByteArray &data, const QUrl &documentUri); + bool load(const QUrl &source); + bool load(QIODevice *source, const QUrl &documentUri = QUrl()); + bool load(const QByteArray &data, const QUrl &documentUri = QUrl()); bool isValid() const; @@ -49,8 +50,8 @@ class Q_XMLPATTERNS_EXPORT QXmlSchema void setMessageHandler(QAbstractMessageHandler *handler); QAbstractMessageHandler *messageHandler() const; - void setUriResolver(QAbstractUriResolver *resolver); - QAbstractUriResolver *uriResolver() const; + void setUriResolver(const QAbstractUriResolver *resolver); + const QAbstractUriResolver *uriResolver() const; void setNetworkAccessManager(QNetworkAccessManager *networkmanager); QNetworkAccessManager *networkAccessManager() const; diff --git a/src/xmlpatterns/api/qxmlschema_p.cpp b/src/xmlpatterns/api/qxmlschema_p.cpp index ebcccee..21dc04a 100644 --- a/src/xmlpatterns/api/qxmlschema_p.cpp +++ b/src/xmlpatterns/api/qxmlschema_p.cpp @@ -61,7 +61,7 @@ QXmlSchemaPrivate::QXmlSchemaPrivate(const QXmlSchemaPrivate &other) void QXmlSchemaPrivate::load(const QUrl &source, const QString &targetNamespace) { - m_documentUri = source; + m_documentUri = QPatternist::XPathHelper::normalizeQueryURI(source); m_schemaContext->setMessageHandler(messageHandler()); m_schemaContext->setUriResolver(uriResolver()); @@ -98,7 +98,7 @@ void QXmlSchemaPrivate::load(QIODevice *source, const QUrl &documentUri, const Q return; } - m_documentUri = documentUri; + m_documentUri = QPatternist::XPathHelper::normalizeQueryURI(documentUri); m_schemaContext->setMessageHandler(messageHandler()); m_schemaContext->setUriResolver(uriResolver()); m_schemaContext->setNetworkAccessManager(networkAccessManager()); @@ -145,12 +145,12 @@ QAbstractMessageHandler *QXmlSchemaPrivate::messageHandler() const return m_messageHandler.data()->value; } -void QXmlSchemaPrivate::setUriResolver(QAbstractUriResolver *resolver) +void QXmlSchemaPrivate::setUriResolver(const QAbstractUriResolver *resolver) { m_uriResolver = resolver; } -QAbstractUriResolver *QXmlSchemaPrivate::uriResolver() const +const QAbstractUriResolver *QXmlSchemaPrivate::uriResolver() const { return m_uriResolver; } diff --git a/src/xmlpatterns/api/qxmlschema_p.h b/src/xmlpatterns/api/qxmlschema_p.h index e625f1e..efba256 100644 --- a/src/xmlpatterns/api/qxmlschema_p.h +++ b/src/xmlpatterns/api/qxmlschema_p.h @@ -54,14 +54,14 @@ class QXmlSchemaPrivate : public QSharedData QUrl documentUri() const; void setMessageHandler(QAbstractMessageHandler *handler); QAbstractMessageHandler *messageHandler() const; - void setUriResolver(QAbstractUriResolver *resolver); - QAbstractUriResolver *uriResolver() const; + void setUriResolver(const QAbstractUriResolver *resolver); + const QAbstractUriResolver *uriResolver() const; void setNetworkAccessManager(QNetworkAccessManager *networkmanager); QNetworkAccessManager *networkAccessManager() const; QXmlNamePool m_namePool; QAbstractMessageHandler* m_userMessageHandler; - QAbstractUriResolver* m_uriResolver; + const QAbstractUriResolver* m_uriResolver; QNetworkAccessManager* m_userNetworkAccessManager; QPatternist::ReferenceCountedValue::Ptr m_messageHandler; QPatternist::ReferenceCountedValue::Ptr m_networkAccessManager; diff --git a/src/xmlpatterns/api/qxmlschemavalidator.cpp b/src/xmlpatterns/api/qxmlschemavalidator.cpp index aa80537..fcde49c 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator.cpp +++ b/src/xmlpatterns/api/qxmlschemavalidator.cpp @@ -27,7 +27,7 @@ \brief The QXmlSchemaValidator class validates XML instance documents against a W3C XML Schema. \reentrant - \since 4.X + \since 4.6 \ingroup xml-tools The QXmlSchemaValidator class loads, parses an XML instance document and validates it @@ -35,6 +35,16 @@ */ /*! + Constructs a schema validator. + The schema used for validation must be referenced in the XML instance document + via the xsi:schemaLocation attribute. + */ +QXmlSchemaValidator::QXmlSchemaValidator() + : d(new QXmlSchemaValidatorPrivate(QXmlSchema())) +{ +} + +/*! Constructs a schema validator that will use \a schema for validation. */ QXmlSchemaValidator::QXmlSchemaValidator(const QXmlSchema &schema) @@ -65,7 +75,7 @@ void QXmlSchemaValidator::setSchema(const QXmlSchema &schema) Returns \c true if the XML instance document is valid according the schema, \c false otherwise. */ -bool QXmlSchemaValidator::validate(const QByteArray &data, const QUrl &documentUri) +bool QXmlSchemaValidator::validate(const QByteArray &data, const QUrl &documentUri) const { QByteArray localData(data); @@ -81,7 +91,7 @@ bool QXmlSchemaValidator::validate(const QByteArray &data, const QUrl &documentU Returns \c true if the XML instance document is valid according the schema, \c false otherwise. */ -bool QXmlSchemaValidator::validate(const QUrl &source) +bool QXmlSchemaValidator::validate(const QUrl &source) const { d->m_context->setMessageHandler(messageHandler()); d->m_context->setUriResolver(uriResolver()); @@ -102,7 +112,7 @@ bool QXmlSchemaValidator::validate(const QUrl &source) Returns \c true if the XML instance document is valid according the schema, \c false otherwise. */ -bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri) +bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri) const { if (!source) { qWarning("A null QIODevice pointer cannot be passed."); @@ -114,6 +124,8 @@ bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri) return false; } + const QUrl normalizedUri = QPatternist::XPathHelper::normalizeQueryURI(documentUri); + d->m_context->setMessageHandler(messageHandler()); d->m_context->setUriResolver(uriResolver()); d->m_context->setNetworkAccessManager(networkAccessManager()); @@ -125,7 +137,7 @@ bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri) QPatternist::Item item; try { - item = loader.openDocument(source, documentUri, d->m_context); + item = loader.openDocument(source, normalizedUri, d->m_context); } catch (QPatternist::Exception exception) { return false; } @@ -135,7 +147,7 @@ bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri) QPatternist::XsdValidatedXmlNodeModel *validatedModel = new QPatternist::XsdValidatedXmlNodeModel(model); - QPatternist::XsdValidatingInstanceReader reader(validatedModel, documentUri, d->m_context); + QPatternist::XsdValidatingInstanceReader reader(validatedModel, normalizedUri, d->m_context); if (d->m_schema) reader.addSchema(d->m_schema, d->m_schemaDocumentUri); try { @@ -158,6 +170,14 @@ QXmlNamePool QXmlSchemaValidator::namePool() const } /*! + Returns the schema that is used for validation. + */ +QXmlSchema QXmlSchemaValidator::schema() const +{ + return d->m_originalSchema; +} + +/*! Changes the \l {QAbstractMessageHandler}{message handler} for this QXmlSchemaValidator to \a handler. The schema validator sends all parsing and validation messages to this message handler. QXmlSchemaValidator does not take @@ -215,14 +235,14 @@ QAbstractMessageHandler *QXmlSchemaValidator::messageHandler() const \sa uriResolver() */ -void QXmlSchemaValidator::setUriResolver(QAbstractUriResolver *resolver) +void QXmlSchemaValidator::setUriResolver(const QAbstractUriResolver *resolver) { d->m_uriResolver = resolver; } /*! Returns the schema's URI resolver. If no URI resolver has been set, - QtXmlPatterns will use the URIs in queries as they are. + QtXmlPatterns will use the URIs in instance documents as they are. The URI resolver provides a level of abstraction, or \e{polymorphic URIs}. A resolver can rewrite \e{logical} URIs to physical ones, or @@ -234,7 +254,7 @@ void QXmlSchemaValidator::setUriResolver(QAbstractUriResolver *resolver) \sa setUriResolver() */ -QAbstractUriResolver *QXmlSchemaValidator::uriResolver() const +const QAbstractUriResolver *QXmlSchemaValidator::uriResolver() const { return d->m_uriResolver; } diff --git a/src/xmlpatterns/api/qxmlschemavalidator.h b/src/xmlpatterns/api/qxmlschemavalidator.h index e643995..c82c522 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator.h +++ b/src/xmlpatterns/api/qxmlschemavalidator.h @@ -12,6 +12,7 @@ #ifndef QXMLSCHEMAVALIDATOR_H #define QXMLSCHEMAVALIDATOR_H +#include #include QT_BEGIN_HEADER @@ -31,22 +32,24 @@ class QXmlSchemaValidatorPrivate; class Q_XMLPATTERNS_EXPORT QXmlSchemaValidator { public: + QXmlSchemaValidator(); QXmlSchemaValidator(const QXmlSchema &schema); ~QXmlSchemaValidator(); void setSchema(const QXmlSchema &schema); - bool validate(const QUrl &source); - bool validate(QIODevice *source, const QUrl &documentUri); - bool validate(const QByteArray &data, const QUrl &documentUri); + bool validate(const QUrl &source) const; + bool validate(QIODevice *source, const QUrl &documentUri = QUrl()) const; + bool validate(const QByteArray &data, const QUrl &documentUri = QUrl()) const; QXmlNamePool namePool() const; + QXmlSchema schema() const; void setMessageHandler(QAbstractMessageHandler *handler); QAbstractMessageHandler *messageHandler() const; - void setUriResolver(QAbstractUriResolver *resolver); - QAbstractUriResolver *uriResolver() const; + void setUriResolver(const QAbstractUriResolver *resolver); + const QAbstractUriResolver *uriResolver() const; void setNetworkAccessManager(QNetworkAccessManager *networkmanager); QNetworkAccessManager *networkAccessManager() const; diff --git a/src/xmlpatterns/api/qxmlschemavalidator_p.h b/src/xmlpatterns/api/qxmlschemavalidator_p.h index 0990f73..9910f6e 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator_p.h +++ b/src/xmlpatterns/api/qxmlschemavalidator_p.h @@ -77,15 +77,18 @@ public: m_context = QPatternist::XsdSchemaContext::Ptr(new QPatternist::XsdSchemaContext(m_namePool.d)); m_context->m_schemaTypeFactory = schema.d->m_schemaContext->m_schemaTypeFactory; m_context->m_builtinTypesFacetList = schema.d->m_schemaContext->m_builtinTypesFacetList; + + m_originalSchema = schema; } QXmlNamePool m_namePool; QAbstractMessageHandler* m_userMessageHandler; - QAbstractUriResolver* m_uriResolver; + const QAbstractUriResolver* m_uriResolver; QNetworkAccessManager* m_userNetworkAccessManager; QPatternist::ReferenceCountedValue::Ptr m_messageHandler; QPatternist::ReferenceCountedValue::Ptr m_networkAccessManager; + QXmlSchema m_originalSchema; QPatternist::XsdSchemaContext::Ptr m_context; QPatternist::XsdSchema::Ptr m_schema; QUrl m_schemaDocumentUri; diff --git a/src/xmlpatterns/schema/qnamespacesupport.cpp b/src/xmlpatterns/schema/qnamespacesupport.cpp index 00698d6..349f451 100644 --- a/src/xmlpatterns/schema/qnamespacesupport.cpp +++ b/src/xmlpatterns/schema/qnamespacesupport.cpp @@ -33,9 +33,7 @@ NamespaceSupport::NamespaceSupport(const NamePool::Ptr &namePool) : m_namePool(namePool) { // the XML namespace - const QXmlName binding = namePool->allocateBinding(QLatin1String("xml"), - QLatin1String("http://www.w3.org/XML/1998/namespace")); - m_ns.insert(binding.prefix(), binding.namespaceURI()); + m_ns.insert(StandardPrefixes::xml, StandardNamespaces::xml); } void NamespaceSupport::setPrefix(const QXmlName::PrefixCode prefixCode, const QXmlName::NamespaceCode namespaceCode) diff --git a/src/xmlpatterns/schema/qxsdparticlechecker.cpp b/src/xmlpatterns/schema/qxsdparticlechecker.cpp index 1bdef00..7a09f8a 100644 --- a/src/xmlpatterns/schema/qxsdparticlechecker.cpp +++ b/src/xmlpatterns/schema/qxsdparticlechecker.cpp @@ -180,9 +180,9 @@ static bool derivedTermValid(const XsdTerm::Ptr &baseTerm, const XsdTerm::Ptr &d // check that the constraints of the derived element are more strict then the constraints of the base element const XsdElement::BlockingConstraints baseConstraints = element->disallowedSubstitutions(); const XsdElement::BlockingConstraints derivedConstraints = derivedElement->disallowedSubstitutions(); - if ((baseConstraints & XsdElement::RestrictionConstraint) && !(derivedConstraints & XsdElement::RestrictionConstraint) || - (baseConstraints & XsdElement::ExtensionConstraint) && !(derivedConstraints & XsdElement::ExtensionConstraint) || - (baseConstraints & XsdElement::SubstitutionConstraint) && !(derivedConstraints & XsdElement::SubstitutionConstraint)) { + if (((baseConstraints & XsdElement::RestrictionConstraint) && !(derivedConstraints & XsdElement::RestrictionConstraint)) || + ((baseConstraints & XsdElement::ExtensionConstraint) && !(derivedConstraints & XsdElement::ExtensionConstraint)) || + ((baseConstraints & XsdElement::SubstitutionConstraint) && !(derivedConstraints & XsdElement::SubstitutionConstraint))) { errorMsg = QtXmlPatterns::tr("block constraints of derived element %1 must not be more weaker than in the base element").arg(formatKeyword(derivedElement->displayName(namePool))); return false; } diff --git a/src/xmlpatterns/schema/qxsdschemacontext.cpp b/src/xmlpatterns/schema/qxsdschemacontext.cpp index 57736bd..65b2e52 100644 --- a/src/xmlpatterns/schema/qxsdschemacontext.cpp +++ b/src/xmlpatterns/schema/qxsdschemacontext.cpp @@ -67,7 +67,7 @@ QSourceLocation XsdSchemaContext::locationFor(const SourceLocationReflection *co return QSourceLocation(); } -void XsdSchemaContext::setUriResolver(QAbstractUriResolver *uriResolver) +void XsdSchemaContext::setUriResolver(const QAbstractUriResolver *uriResolver) { m_uriResolver = uriResolver; } diff --git a/src/xmlpatterns/schema/qxsdschemacontext_p.h b/src/xmlpatterns/schema/qxsdschemacontext_p.h index cf52028..c3a9f15 100644 --- a/src/xmlpatterns/schema/qxsdschemacontext_p.h +++ b/src/xmlpatterns/schema/qxsdschemacontext_p.h @@ -115,7 +115,7 @@ namespace QPatternist * Sets the uri @p resolver that is used for resolving URIs in the * schema parser. */ - void setUriResolver(QAbstractUriResolver *resolver); + void setUriResolver(const QAbstractUriResolver *resolver); /** * Returns the uri resolver that is used for resolving URIs in the @@ -145,7 +145,7 @@ namespace QPatternist NamePool::Ptr m_namePool; QNetworkAccessManager* m_networkAccessManager; QUrl m_baseURI; - QAbstractUriResolver* m_uriResolver; + const QAbstractUriResolver* m_uriResolver; QAbstractMessageHandler* m_messageHandler; }; } diff --git a/src/xmlpatterns/schema/qxsdschemadebugger_p.h b/src/xmlpatterns/schema/qxsdschemadebugger_p.h index 8c12f0f..8966963 100644 --- a/src/xmlpatterns/schema/qxsdschemadebugger_p.h +++ b/src/xmlpatterns/schema/qxsdschemadebugger_p.h @@ -85,7 +85,7 @@ namespace QPatternist void dumpSchema(const XsdSchema::Ptr &schema); private: - NamePool::Ptr m_namePool; + const NamePool::Ptr m_namePool; }; } diff --git a/src/xmlpatterns/schema/qxsdschemahelper.cpp b/src/xmlpatterns/schema/qxsdschemahelper.cpp index 752af89..ff169f7 100644 --- a/src/xmlpatterns/schema/qxsdschemahelper.cpp +++ b/src/xmlpatterns/schema/qxsdschemahelper.cpp @@ -409,7 +409,7 @@ bool XsdSchemaHelper::isValidlySubstitutable(const SchemaType::Ptr &type, const return false; } -bool XsdSchemaHelper::isSimpleDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr baseType, const SchemaType::DerivationConstraints &constraints) +bool XsdSchemaHelper::isSimpleDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr &baseType, const SchemaType::DerivationConstraints &constraints) { // @see http://www.w3.org/TR/xmlschema11-1/#cos-st-derived-ok @@ -453,7 +453,7 @@ bool XsdSchemaHelper::isSimpleDerivationOk(const SchemaType::Ptr &derivedType, c return false; } -bool XsdSchemaHelper::isComplexDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr baseType, const SchemaType::DerivationConstraints &constraints) +bool XsdSchemaHelper::isComplexDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr &baseType, const SchemaType::DerivationConstraints &constraints) { if (!derivedType) return false; diff --git a/src/xmlpatterns/schema/qxsdschemahelper_p.h b/src/xmlpatterns/schema/qxsdschemahelper_p.h index 1722b4c..918664e 100644 --- a/src/xmlpatterns/schema/qxsdschemahelper_p.h +++ b/src/xmlpatterns/schema/qxsdschemahelper_p.h @@ -55,12 +55,15 @@ namespace QPatternist /** * Checks whether the given @p nameSpace is allowed by the given namespace @p constraint. */ - static bool wildcardAllowsNamespaceName(const QString &nameSpace, const XsdWildcard::NamespaceConstraint::Ptr &constraint); + static bool wildcardAllowsNamespaceName(const QString &nameSpace, + const XsdWildcard::NamespaceConstraint::Ptr &constraint); /** * Checks whether the given @p name is allowed by the namespace constraint of the given @p wildcard. */ - static bool wildcardAllowsExpandedName(const QXmlName &name, const XsdWildcard::Ptr &wildcard, const NamePool::Ptr &namePool); + static bool wildcardAllowsExpandedName(const QXmlName &name, + const XsdWildcard::Ptr &wildcard, + const NamePool::Ptr &namePool); /** * Checks whether the @p wildcard is a subset of @p otherWildcard. @@ -75,25 +78,32 @@ namespace QPatternist /** * Returns the intersection of the given @p wildcard and @p otherWildcard. */ - static XsdWildcard::Ptr wildcardIntersection(const XsdWildcard::Ptr &wildcard, const XsdWildcard::Ptr &otherWildcard); + static XsdWildcard::Ptr wildcardIntersection(const XsdWildcard::Ptr &wildcard, + const XsdWildcard::Ptr &otherWildcard); /** * Returns whether the given @p type is validly substitutable for an @p otherType * under the given @p constraints. */ - static bool isValidlySubstitutable(const SchemaType::Ptr &type, const SchemaType::Ptr &otherType, const SchemaType::DerivationConstraints &constraints); + static bool isValidlySubstitutable(const SchemaType::Ptr &type, + const SchemaType::Ptr &otherType, + const SchemaType::DerivationConstraints &constraints); /** * Returns whether the simple @p derivedType can be derived from the simple @p baseType * under the given @p constraints. */ - static bool isSimpleDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr baseType, const SchemaType::DerivationConstraints &constraints); + static bool isSimpleDerivationOk(const SchemaType::Ptr &derivedType, + const SchemaType::Ptr &baseType, + const SchemaType::DerivationConstraints &constraints); /** * Returns whether the complex @p derivedType can be derived from the complex @p baseType * under the given @p constraints. */ - static bool isComplexDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr baseType, const SchemaType::DerivationConstraints &constraints); + static bool isComplexDerivationOk(const SchemaType::Ptr &derivedType, + const SchemaType::Ptr &baseType, + const SchemaType::DerivationConstraints &constraints); /** * This method takes the two string based operands @p operand1 and @p operand2 and converts them to instances of type @p type. @@ -111,41 +121,62 @@ namespace QPatternist * Returns whether the process content property of the @p derivedWildcard is valid * according to the process content property of its @p baseWildcard. */ - static bool checkWildcardProcessContents(const XsdWildcard::Ptr &baseWildcard, const XsdWildcard::Ptr &derivedWildcard); + static bool checkWildcardProcessContents(const XsdWildcard::Ptr &baseWildcard, + const XsdWildcard::Ptr &derivedWildcard); /** * Checks whether @[ member is a member of the substitution group with the given @p head. */ - static bool foundSubstitutionGroupTransitive(const XsdElement::Ptr &head, const XsdElement::Ptr &member, QSet &visitedElements); + static bool foundSubstitutionGroupTransitive(const XsdElement::Ptr &head, + const XsdElement::Ptr &member, + QSet &visitedElements); /** * A helper method that iterates over the type hierarchy from @p memberType up to @p headType and collects all * @p derivationSet and @p blockSet constraints that exists on the way there. */ - static void foundSubstitutionGroupTypeInheritance(const SchemaType::Ptr &headType, const SchemaType::Ptr &memberType, - QSet &derivationSet, NamedSchemaComponent::BlockingConstraints &blockSet); + static void foundSubstitutionGroupTypeInheritance(const SchemaType::Ptr &headType, + const SchemaType::Ptr &memberType, + QSet &derivationSet, + NamedSchemaComponent::BlockingConstraints &blockSet); /** * Checks if the @p member is transitive to @p head. */ - static bool substitutionGroupOkTransitive(const XsdElement::Ptr &head, const XsdElement::Ptr &member, const NamePool::Ptr &namePool); + static bool substitutionGroupOkTransitive(const XsdElement::Ptr &head, + const XsdElement::Ptr &member, + const NamePool::Ptr &namePool); /** * Checks if @p derivedAttributeGroup is a valid restriction for @p attributeGroup. */ - static bool isValidAttributeGroupRestriction(const XsdAttributeGroup::Ptr &derivedAttributeGroup, const XsdAttributeGroup::Ptr &attributeGroup, const XsdSchemaContext::Ptr &context, QString &errorMsg); + static bool isValidAttributeGroupRestriction(const XsdAttributeGroup::Ptr &derivedAttributeGroup, + const XsdAttributeGroup::Ptr &attributeGroup, + const XsdSchemaContext::Ptr &context, + QString &errorMsg); /** * Checks if @p derivedAttributeUses are a valid restriction for @p attributeUses. */ - static bool isValidAttributeUsesRestriction(const XsdAttributeUse::List &derivedAttributeUses, const XsdAttributeUse::List &attributeUses, - const XsdWildcard::Ptr &derivedWildcard, const XsdWildcard::Ptr &wildcard, const XsdSchemaContext::Ptr &context, QString &errorMsg); + static bool isValidAttributeUsesRestriction(const XsdAttributeUse::List &derivedAttributeUses, + const XsdAttributeUse::List &attributeUses, + const XsdWildcard::Ptr &derivedWildcard, + const XsdWildcard::Ptr &wildcard, + const XsdSchemaContext::Ptr &context, + QString &errorMsg); /** * Checks if @p derivedAttributeUses are a valid extension for @p attributeUses. */ - static bool isValidAttributeUsesExtension(const XsdAttributeUse::List &derivedAttributeUses, const XsdAttributeUse::List &attributeUses, - const XsdWildcard::Ptr &derivedWildcard, const XsdWildcard::Ptr &wildcard, const XsdSchemaContext::Ptr &context, QString &errorMsg); + static bool isValidAttributeUsesExtension(const XsdAttributeUse::List &derivedAttributeUses, + const XsdAttributeUse::List &attributeUses, + const XsdWildcard::Ptr &derivedWildcard, + const XsdWildcard::Ptr &wildcard, + const XsdSchemaContext::Ptr &context, + QString &errorMsg); + + private: + Q_DISABLE_COPY(XsdSchemaHelper) }; } diff --git a/src/xmlpatterns/schema/qxsdschemaparser.cpp b/src/xmlpatterns/schema/qxsdschemaparser.cpp index 9f1e75d..cabc12e 100644 --- a/src/xmlpatterns/schema/qxsdschemaparser.cpp +++ b/src/xmlpatterns/schema/qxsdschemaparser.cpp @@ -5,6 +5,7 @@ #include "qacceltreeresourceloader_p.h" #include "qautoptr_p.h" #include "qboolean_p.h" +#include "qcommonnamespaces_p.h" #include "qderivedinteger_p.h" #include "qderivedstring_p.h" #include "qqnamevalue_p.h" @@ -119,12 +120,28 @@ class TagValidationHandler void validate(XsdSchemaToken::NodeName token) { if (token == XsdSchemaToken::NoKeyword) { - m_parser->error(QtXmlPatterns::tr("can not process unknown element %1").arg(formatElement(m_parser->name().toString()))); + const QList tokens = m_machine.possibleTransitions(); + + QStringList elementNames; + for (int i = 0; i < tokens.count(); ++i) + elementNames.append(formatElement(XsdSchemaToken::toString(tokens.at(i)))); + + m_parser->error(QtXmlPatterns::tr("can not process unknown element %1, expected elements are: %2") + .arg(formatElement(m_parser->name().toString())) + .arg(elementNames.join(QLatin1String(", ")))); return; } if (!m_machine.proceed(token)) { - m_parser->error(QtXmlPatterns::tr("element %1 is not allowed in this scope").arg(formatElement(XsdSchemaToken::toString(token)))); + const QList tokens = m_machine.possibleTransitions(); + + QStringList elementNames; + for (int i = 0; i < tokens.count(); ++i) + elementNames.append(formatElement(XsdSchemaToken::toString(tokens.at(i)))); + + m_parser->error(QtXmlPatterns::tr("element %1 is not allowed in this scope, possible elements are: %2") + .arg(formatElement(XsdSchemaToken::toString(token))) + .arg(elementNames.join(QLatin1String(", ")))); return; } } @@ -132,7 +149,14 @@ class TagValidationHandler void finalize() const { if (!m_machine.inEndState()) { - m_parser->error(QtXmlPatterns::tr("child element is missing in that scope")); + const QList tokens = m_machine.possibleTransitions(); + + QStringList elementNames; + for (int i = 0; i < tokens.count(); ++i) + elementNames.append(formatElement(XsdSchemaToken::toString(tokens.at(i)))); + + m_parser->error(QtXmlPatterns::tr("child element is missing in that scope, possible child elements are: %1") + .arg(elementNames.join(QLatin1String(", ")))); } } @@ -425,8 +449,8 @@ void XsdSchemaParser::parseSchema(ParserType parserType) const QString version = readAttribute(QString::fromLatin1("version")); } - if (hasAttribute(QString::fromLatin1("http://www.w3.org/XML/1998/namespace"), QString::fromLatin1("lang"))) { - const QString value = readAttribute(QString::fromLatin1("lang"), QString::fromLatin1("http://www.w3.org/XML/1998/namespace")); + if (hasAttribute(CommonNamespaces::XML, QString::fromLatin1("lang"))) { + const QString value = readAttribute(QString::fromLatin1("lang"), CommonNamespaces::XML); const QRegExp exp(QString::fromLatin1("[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*")); if (!exp.exactMatch(value)) { @@ -750,7 +774,7 @@ void XsdSchemaParser::parseRedefine() if (url.isRelative()) { Q_ASSERT(m_documentURI.isValid()); - url = m_documentURI.resolved(url); + url = m_documentURI.resolved(url); } // we parse the schema given in the redefine tag into its own context @@ -1176,8 +1200,8 @@ XsdDocumentation::Ptr XsdSchemaParser::parseDocumentation() } } - if (hasAttribute(QString::fromLatin1("http://www.w3.org/XML/1998/namespace"), QString::fromLatin1("lang"))) { - const QString value = readAttribute(QString::fromLatin1("lang"), QString::fromLatin1("http://www.w3.org/XML/1998/namespace")); + if (hasAttribute(CommonNamespaces::XML, QString::fromLatin1("lang"))) { + const QString value = readAttribute(QString::fromLatin1("lang"), CommonNamespaces::XML); const QRegExp exp(QString::fromLatin1("[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*")); if (!exp.exactMatch(value)) { @@ -3948,7 +3972,7 @@ XsdAttribute::Ptr XsdSchemaParser::parseGlobalAttribute() error(QtXmlPatterns::tr("content of %1 attribute of %2 element must not be from namespace %3") .arg(formatAttribute("name")) .arg(formatElement("attribute")) - .arg(formatURI(QLatin1String("http://www.w3.org/2001/XMLSchema-instance")))); + .arg(formatURI(CommonNamespaces::XSI))); return attribute; } if (m_namePool->stringForLocalName(objectName.localName()) == QString::fromLatin1("xmlns")) { @@ -4170,7 +4194,7 @@ XsdAttributeUse::Ptr XsdSchemaParser::parseLocalAttribute(const NamedSchemaCompo error(QtXmlPatterns::tr("content of %1 attribute of %2 element must not be from namespace %3") .arg(formatAttribute("name")) .arg(formatElement("attribute")) - .arg(formatURI(QLatin1String("http://www.w3.org/2001/XMLSchema-instance")))); + .arg(formatURI(CommonNamespaces::XSI))); return attributeUse; } if (m_namePool->stringForLocalName(objectName.localName()) == QString::fromLatin1("xmlns")) { @@ -5858,7 +5882,7 @@ QString XsdSchemaParser::readXPathAttribute(const QString &attributeName, XPathT QXmlNamePool namePool(m_namePool.data()); - QXmlQuery::QueryLanguage language; + QXmlQuery::QueryLanguage language = QXmlQuery::XPath20; switch (type) { case XPath20: language = QXmlQuery::XPath20; break; case XPathSelector: language = QXmlQuery::XmlSchema11IdentityConstraintSelector; break; diff --git a/src/xmlpatterns/schema/qxsdstatemachine.cpp b/src/xmlpatterns/schema/qxsdstatemachine.cpp index e40e55b..4f36f22 100644 --- a/src/xmlpatterns/schema/qxsdstatemachine.cpp +++ b/src/xmlpatterns/schema/qxsdstatemachine.cpp @@ -114,6 +114,20 @@ bool XsdStateMachine::proceed(TransitionType transition) } template +QList XsdStateMachine::possibleTransitions() const +{ + // check that we are not in an invalid state + if (!m_transitions.contains(m_currentState)) { + return QList(); + } + + // fetch the transition entry for the current state + const QHash > &entry = m_transitions[m_currentState]; + + return entry.keys(); +} + +template template bool XsdStateMachine::proceed(InputType input) { @@ -259,7 +273,7 @@ typename XsdStateMachine::StateId XsdStateMachine it(nfaState); diff --git a/src/xmlpatterns/schema/qxsdstatemachine_p.h b/src/xmlpatterns/schema/qxsdstatemachine_p.h index 7988335..f0cf99d 100644 --- a/src/xmlpatterns/schema/qxsdstatemachine_p.h +++ b/src/xmlpatterns/schema/qxsdstatemachine_p.h @@ -113,6 +113,12 @@ namespace QPatternist bool proceed(TransitionType transition); /** + * Returns the list of transitions that are reachable from the current + * state. + */ + QList possibleTransitions() const; + + /** * Continues execution of the machine with the given @p input. * * @note To use this method, inputEqualsTransition must be implemented diff --git a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp index 8e1645a..33bca4e 100644 --- a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp +++ b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp @@ -20,7 +20,7 @@ QT_BEGIN_NAMESPACE using namespace QPatternist; XsdValidatedXmlNodeModel::XsdValidatedXmlNodeModel(const QAbstractXmlNodeModel *model) - : m_internalModel(const_cast(model)) + : m_internalModel(model) { } diff --git a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h index 579f41a..d52e369 100644 --- a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h +++ b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h @@ -134,11 +134,11 @@ namespace QPatternist virtual QVector attributes(const QXmlNodeModelIndex &element) const; private: - QAbstractXmlNodeModel::Ptr m_internalModel; - QHash m_assignedElements; - QHash m_assignedAttributes; - QHash m_assignedTypes; - QHash > m_idIdRefBindings; + QExplicitlySharedDataPointer m_internalModel; + QHash m_assignedElements; + QHash m_assignedAttributes; + QHash m_assignedTypes; + QHash > m_idIdRefBindings; }; } diff --git a/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp b/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp index 12fc477..8cb34d4 100644 --- a/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp +++ b/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp @@ -15,6 +15,7 @@ #include "qacceltreeresourceloader_p.h" #include "qbase64binary_p.h" #include "qboolean_p.h" +#include "qcommonnamespaces_p.h" #include "qderivedinteger_p.h" #include "qduration_p.h" #include "qgenericstaticcontext_p.h" @@ -64,14 +65,14 @@ namespace QPatternist } } -XsdValidatingInstanceReader::XsdValidatingInstanceReader(const XsdValidatedXmlNodeModel *model, const QUrl &documentUri, const XsdSchemaContext::Ptr &context) +XsdValidatingInstanceReader::XsdValidatingInstanceReader(XsdValidatedXmlNodeModel *model, const QUrl &documentUri, const XsdSchemaContext::Ptr &context) : XsdInstanceReader(model, context) - , m_model(const_cast(model)) + , m_model(model) , m_namePool(m_context->namePool()) - , m_xsiNilName(m_namePool->allocateQName(QLatin1String("http://www.w3.org/2001/XMLSchema-instance"), QLatin1String("nil"))) - , m_xsiTypeName(m_namePool->allocateQName(QLatin1String("http://www.w3.org/2001/XMLSchema-instance"), QLatin1String("type"))) - , m_xsiSchemaLocationName(m_namePool->allocateQName(QLatin1String("http://www.w3.org/2001/XMLSchema-instance"), QLatin1String("schemaLocation"))) - , m_xsiNoNamespaceSchemaLocationName(m_namePool->allocateQName(QLatin1String("http://www.w3.org/2001/XMLSchema-instance"), QLatin1String("noNamespaceSchemaLocation"))) + , m_xsiNilName(m_namePool->allocateQName(CommonNamespaces::XSI, QLatin1String("nil"))) + , m_xsiTypeName(m_namePool->allocateQName(CommonNamespaces::XSI, QLatin1String("type"))) + , m_xsiSchemaLocationName(m_namePool->allocateQName(CommonNamespaces::XSI, QLatin1String("schemaLocation"))) + , m_xsiNoNamespaceSchemaLocationName(m_namePool->allocateQName(CommonNamespaces::XSI, QLatin1String("noNamespaceSchemaLocation"))) , m_documentUri(documentUri) { m_idRefsType = m_context->schemaTypeFactory()->createSchemaType(m_namePool->allocateQName(CommonNamespaces::WXS, QLatin1String("IDREFS"))); @@ -152,7 +153,7 @@ bool XsdValidatingInstanceReader::read() void XsdValidatingInstanceReader::error(const QString &msg) const { - const_cast(m_context.data())->error(msg, XsdSchemaContext::XSDError, sourceLocation()); + m_context.data()->error(msg, XsdSchemaContext::XSDError, sourceLocation()); } bool XsdValidatingInstanceReader::loadSchema(const QString &targetNamespace, const QUrl &location) diff --git a/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h b/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h index 799ab44..28f3c3f 100644 --- a/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h +++ b/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h @@ -59,7 +59,7 @@ namespace QPatternist * @param documentUri The uri of the document the model is from. * @param context The context that is used to report errors etc. */ - XsdValidatingInstanceReader(const XsdValidatedXmlNodeModel *model, const QUrl &documentUri, const XsdSchemaContext::Ptr &context); + XsdValidatingInstanceReader(XsdValidatedXmlNodeModel *model, const QUrl &documentUri, const XsdSchemaContext::Ptr &context); /** * Adds a new @p schema to the pool of schemas that shall be used diff --git a/src/xmlpatterns/utils/qxpathhelper.cpp b/src/xmlpatterns/utils/qxpathhelper.cpp index 127e21f..5b32906 100644 --- a/src/xmlpatterns/utils/qxpathhelper.cpp +++ b/src/xmlpatterns/utils/qxpathhelper.cpp @@ -125,4 +125,16 @@ ItemType::Ptr XPathHelper::typeFromKind(const QXmlNodeModelIndex::NodeKind nodeK } } +QUrl XPathHelper::normalizeQueryURI(const QUrl &uri) +{ + Q_ASSERT_X(uri.isEmpty() || uri.isValid(), Q_FUNC_INFO, + "The URI passed to QXmlQuery::setQuery() must be valid or empty."); + if(uri.isEmpty()) + return QUrl::fromLocalFile(QCoreApplication::applicationFilePath()); + else if(uri.isRelative()) + return QUrl::fromLocalFile(QCoreApplication::applicationFilePath()).resolved(uri); + else + return uri; +} + QT_END_NAMESPACE diff --git a/src/xmlpatterns/utils/qxpathhelper_p.h b/src/xmlpatterns/utils/qxpathhelper_p.h index 7bf33e6..e36b8cb 100644 --- a/src/xmlpatterns/utils/qxpathhelper_p.h +++ b/src/xmlpatterns/utils/qxpathhelper_p.h @@ -128,6 +128,11 @@ namespace QPatternist static QPatternist::ItemTypePtr typeFromKind(const QXmlNodeModelIndex::NodeKind nodeKind); /** + * Normalizes an @p uri by resolving it to the application directory if empty. + */ + static QUrl normalizeQueryURI(const QUrl &uri); + + /** * @short Determines whether @p consists only of whitespace. Characters * considered whitespace are the ones for which QChar::isSpace() returns @c true for. * diff --git a/tests/auto/patternistheaders/tst_patternistheaders.cpp b/tests/auto/patternistheaders/tst_patternistheaders.cpp index ba7623e..3352a58 100644 --- a/tests/auto/patternistheaders/tst_patternistheaders.cpp +++ b/tests/auto/patternistheaders/tst_patternistheaders.cpp @@ -94,6 +94,10 @@ void tst_PatternistHeaders::run() const #include #include #include +#include +#include +#include +#include #include #include @@ -122,6 +126,10 @@ void tst_PatternistHeaders::run() const #include #include #include +#include +#include +#include +#include #include #include diff --git a/tests/auto/qxmlschema/tst_qxmlschema.cpp b/tests/auto/qxmlschema/tst_qxmlschema.cpp index 64012c1..7fc59bb 100644 --- a/tests/auto/qxmlschema/tst_qxmlschema.cpp +++ b/tests/auto/qxmlschema/tst_qxmlschema.cpp @@ -15,33 +15,8 @@ #include #include -class DummyMessageHandler : public QAbstractMessageHandler -{ - public: - DummyMessageHandler(QObject *parent = 0) - : QAbstractMessageHandler(parent) - { - } - - protected: - virtual void handleMessage(QtMsgType, const QString&, const QUrl&, const QSourceLocation&) - { - } -}; - -class DummyUriResolver : public QAbstractUriResolver -{ - public: - DummyUriResolver(QObject *parent = 0) - : QAbstractUriResolver(parent) - { - } - - virtual QUrl resolve(const QUrl&, const QUrl&) const - { - return QUrl(); - } -}; +#include "../qabstracturiresolver/TestURIResolver.h" +#include "../qxmlquery/MessageSilencer.h" /*! \class tst_QXmlSchema @@ -59,6 +34,17 @@ private Q_SLOTS: void defaultConstructor() const; void copyConstructor() const; void constructorQXmlNamePool() const; + void copyMutationTest() const; + + void isValid() const; + void documentUri() const; + + void loadSchemaUrlSuccess() const; + void loadSchemaUrlFail() const; + void loadSchemaDeviceSuccess() const; + void loadSchemaDeviceFail() const; + void loadSchemaDataSuccess() const; + void loadSchemaDataFail() const; void networkAccessManagerSignature() const; void networkAccessManagerDefaultValue() const; @@ -134,6 +120,150 @@ void tst_QXmlSchema::constructorQXmlNamePool() const QCOMPARE(name.prefix(np2), QString::fromLatin1("prefix")); } +void tst_QXmlSchema::copyMutationTest() const +{ + QXmlSchema schema1; + QXmlSchema schema2(schema1); + + // check that everything is equal + QVERIFY(schema2.messageHandler() == schema1.messageHandler()); + QVERIFY(schema2.uriResolver() == schema1.uriResolver()); + QVERIFY(schema2.networkAccessManager() == schema1.networkAccessManager()); + + MessageSilencer handler; + const TestURIResolver resolver; + QNetworkAccessManager manager; + + // modify schema1 + schema1.setMessageHandler(&handler); + schema1.setUriResolver(&resolver); + schema1.setNetworkAccessManager(&manager); + + // check that schema2 is not effected by the modifications of schema1 + QVERIFY(schema2.messageHandler() != schema1.messageHandler()); + QVERIFY(schema2.uriResolver() != schema1.uriResolver()); + QVERIFY(schema2.networkAccessManager() != schema1.networkAccessManager()); + + // modify schema1 further + const QByteArray data( "" + "" + "" ); + + const QUrl documentUri("http://www.qtsoftware.com/xmlschematest"); + schema1.load(data, documentUri); + + QVERIFY(schema2.isValid() != schema1.isValid()); +} + +void tst_QXmlSchema::isValid() const +{ + /* Check default value. */ + QXmlSchema schema; + QVERIFY(!schema.isValid()); +} + +void tst_QXmlSchema::documentUri() const +{ + const QByteArray data( "" + "" + "" ); + + const QUrl documentUri("http://www.qtsoftware.com/xmlschematest"); + QXmlSchema schema; + schema.load(data, documentUri); + + QCOMPARE(documentUri, schema.documentUri()); +} + +void tst_QXmlSchema::loadSchemaUrlSuccess() const +{ +/** + TODO: put valid schema file on given url and enable test + const QUrl url("http://notavailable/"); + + QXmlSchema schema; + QVERIFY(!schema.load(url)); +*/ +} + +void tst_QXmlSchema::loadSchemaUrlFail() const +{ + const QUrl url("http://notavailable/"); + + QXmlSchema schema; + QVERIFY(!schema.load(url)); +} + +void tst_QXmlSchema::loadSchemaDeviceSuccess() const +{ + QByteArray data( "" + "" + "" ); + + QBuffer buffer(&data); + buffer.open(QIODevice::ReadOnly); + + QXmlSchema schema; + QVERIFY(schema.load(&buffer)); +} + +void tst_QXmlSchema::loadSchemaDeviceFail() const +{ + QByteArray data( "" + "" + "" ); + + QBuffer buffer(&data); + // a closed device can not be loaded + + QXmlSchema schema; + QVERIFY(!schema.load(&buffer)); +} + +void tst_QXmlSchema::loadSchemaDataSuccess() const +{ + const QByteArray data( "" + "" + "" ); + QXmlSchema schema; + QVERIFY(schema.load(data)); +} + +void tst_QXmlSchema::loadSchemaDataFail() const +{ + // empty schema can not be loaded + const QByteArray data; + + QXmlSchema schema; + QVERIFY(!schema.load(data)); +} + + void tst_QXmlSchema::networkAccessManagerSignature() const { /* Const object. */ @@ -185,7 +315,7 @@ void tst_QXmlSchema::messageHandler() const { /* Test that we return the message handler that was set. */ { - DummyMessageHandler handler; + MessageSilencer handler; QXmlSchema schema; schema.setMessageHandler(&handler); @@ -200,6 +330,13 @@ void tst_QXmlSchema::uriResolverSignature() const /* The function should be const. */ schema.uriResolver(); + + /* Const object. */ + const TestURIResolver resolver; + + /* This should compile */ + QXmlSchema schema2; + schema2.setUriResolver(&resolver); } void tst_QXmlSchema::uriResolverDefaultValue() const @@ -215,7 +352,7 @@ void tst_QXmlSchema::uriResolver() const { /* Test that we return the uri resolver that was set. */ { - DummyUriResolver resolver; + TestURIResolver resolver; QXmlSchema schema; schema.setUriResolver(&resolver); diff --git a/tests/auto/qxmlschemavalidator/tst_qxmlschemavalidator.cpp b/tests/auto/qxmlschemavalidator/tst_qxmlschemavalidator.cpp index b021b08..3bbf506 100644 --- a/tests/auto/qxmlschemavalidator/tst_qxmlschemavalidator.cpp +++ b/tests/auto/qxmlschemavalidator/tst_qxmlschemavalidator.cpp @@ -16,33 +16,8 @@ #include #include -class DummyMessageHandler : public QAbstractMessageHandler -{ - public: - DummyMessageHandler(QObject *parent = 0) - : QAbstractMessageHandler(parent) - { - } - - protected: - virtual void handleMessage(QtMsgType, const QString&, const QUrl&, const QSourceLocation&) - { - } -}; - -class DummyUriResolver : public QAbstractUriResolver -{ - public: - DummyUriResolver(QObject *parent = 0) - : QAbstractUriResolver(parent) - { - } - - virtual QUrl resolve(const QUrl&, const QUrl&) const - { - return QUrl(); - } -}; +#include "../qabstracturiresolver/TestURIResolver.h" +#include "../qxmlquery/MessageSilencer.h" /*! \class tst_QXmlSchemaValidatorValidator @@ -60,6 +35,13 @@ private Q_SLOTS: void defaultConstructor() const; void propertyInitialization() const; + void loadInstanceUrlSuccess() const; + void loadInstanceUrlFail() const; + void loadInstanceDeviceSuccess() const; + void loadInstanceDeviceFail() const; + void loadInstanceDataSuccess() const; + void loadInstanceDataFail() const; + void networkAccessManagerSignature() const; void networkAccessManagerDefaultValue() const; void networkAccessManager() const; @@ -73,6 +55,26 @@ private Q_SLOTS: void uriResolver() const; }; +static QXmlSchema createValidSchema() +{ + const QByteArray data( "" + "" + " " + "" ); + + const QUrl documentUri("http://www.qtsoftware.com/xmlschematest"); + + QXmlSchema schema; + schema.load(data, documentUri); + + return schema; +} + void tst_QXmlSchemaValidator::defaultConstructor() const { /* Allocate instance in different orders. */ @@ -101,8 +103,8 @@ void tst_QXmlSchemaValidator::propertyInitialization() const { /* Verify that properties set in the schema are used as default values for the validator */ { - DummyMessageHandler handler; - DummyUriResolver resolver; + MessageSilencer handler; + TestURIResolver resolver; QNetworkAccessManager manager; QXmlSchema schema; @@ -117,6 +119,72 @@ void tst_QXmlSchemaValidator::propertyInitialization() const } } +void tst_QXmlSchemaValidator::loadInstanceUrlSuccess() const +{ +/* + TODO: put valid schema file on given url and enable test + const QXmlSchema schema(createValidSchema()); + const QUrl url("http://notavailable/"); + + QXmlSchemaValidator validator(schema); + QVERIFY(!validator.validate(url)); +*/ +} + +void tst_QXmlSchemaValidator::loadInstanceUrlFail() const +{ + const QXmlSchema schema(createValidSchema()); + const QUrl url("http://notavailable/"); + + QXmlSchemaValidator validator(schema); + QVERIFY(!validator.validate(url)); +} + +void tst_QXmlSchemaValidator::loadInstanceDeviceSuccess() const +{ + const QXmlSchema schema(createValidSchema()); + + QByteArray data( "Testme" ); + QBuffer buffer(&data); + buffer.open(QIODevice::ReadOnly); + + QXmlSchemaValidator validator(schema); + QVERIFY(validator.validate(&buffer)); +} + +void tst_QXmlSchemaValidator::loadInstanceDeviceFail() const +{ + const QXmlSchema schema(createValidSchema()); + + QByteArray data( "Testme" ); + QBuffer buffer(&data); + // a closed device can not be loaded + + QXmlSchemaValidator validator(schema); + QVERIFY(!validator.validate(&buffer)); +} + +void tst_QXmlSchemaValidator::loadInstanceDataSuccess() const +{ + const QXmlSchema schema(createValidSchema()); + + const QByteArray data( "Testme" ); + + QXmlSchemaValidator validator(schema); + QVERIFY(validator.validate(data)); +} + +void tst_QXmlSchemaValidator::loadInstanceDataFail() const +{ + const QXmlSchema schema(createValidSchema()); + + // empty instance can not be loaded + const QByteArray data; + + QXmlSchemaValidator validator(schema); + QVERIFY(!validator.validate(data)); +} + void tst_QXmlSchemaValidator::networkAccessManagerSignature() const { const QXmlSchema schema; @@ -202,7 +270,7 @@ void tst_QXmlSchemaValidator::messageHandlerDefaultValue() const { QXmlSchema schema; - DummyMessageHandler handler; + MessageSilencer handler; schema.setMessageHandler(&handler); const QXmlSchemaValidator validator(schema); @@ -214,7 +282,7 @@ void tst_QXmlSchemaValidator::messageHandler() const { /* Test that we return the message handler that was set. */ { - DummyMessageHandler handler; + MessageSilencer handler; const QXmlSchema schema; QXmlSchemaValidator validator(schema); @@ -225,7 +293,7 @@ void tst_QXmlSchemaValidator::messageHandler() const /* Test that we return the message handler that was set, even if the schema changed in between. */ { - DummyMessageHandler handler; + MessageSilencer handler; const QXmlSchema schema; QXmlSchemaValidator validator(schema); @@ -248,6 +316,13 @@ void tst_QXmlSchemaValidator::uriResolverSignature() const /* The function should be const. */ validator.uriResolver(); + + /* Const object. */ + const TestURIResolver resolver; + + /* This should compile */ + QXmlSchema schema2; + schema2.setUriResolver(&resolver); } void tst_QXmlSchemaValidator::uriResolverDefaultValue() const @@ -263,7 +338,7 @@ void tst_QXmlSchemaValidator::uriResolverDefaultValue() const { QXmlSchema schema; - DummyUriResolver resolver; + TestURIResolver resolver; schema.setUriResolver(&resolver); const QXmlSchemaValidator validator(schema); @@ -275,7 +350,7 @@ void tst_QXmlSchemaValidator::uriResolver() const { /* Test that we return the uri resolver that was set. */ { - DummyUriResolver resolver; + TestURIResolver resolver; const QXmlSchema schema; QXmlSchemaValidator validator(schema); @@ -286,7 +361,7 @@ void tst_QXmlSchemaValidator::uriResolver() const /* Test that we return the uri resolver that was set, even if the schema changed in between. */ { - DummyUriResolver resolver; + TestURIResolver resolver; const QXmlSchema schema; QXmlSchemaValidator validator(schema); diff --git a/tools/xmlpatternsvalidator/main.cpp b/tools/xmlpatternsvalidator/main.cpp index 032afc0..0ccbcfc 100644 --- a/tools/xmlpatternsvalidator/main.cpp +++ b/tools/xmlpatternsvalidator/main.cpp @@ -19,22 +19,29 @@ QT_USE_NAMESPACE -enum ExecutionMode -{ - InvalidMode, - SchemaOnlyMode, - SchemaAndInstanceMode, - InstanceOnlyMode -}; - int main(int argc, char **argv) { + enum ExitCode + { + Valid = 0, + Invalid, + ParseError + }; + + enum ExecutionMode + { + InvalidMode, + SchemaOnlyMode, + SchemaAndInstanceMode, + InstanceOnlyMode + }; + const QCoreApplication app(argc, argv); QCoreApplication::setApplicationName(QLatin1String("xmlpatternsvalidator")); if (argc != 2 && argc != 3) { qDebug() << QXmlPatternistCLI::tr("usage: xmlpatternsvalidator ( | | )"); - return 2; + return ParseError; } // parse command line arguments @@ -63,9 +70,9 @@ int main(int argc, char **argv) schema.load(QUrl(schemaUri)); if (schema.isValid()) - return 0; + return Valid; else - return 1; + return Invalid; } else if (mode == SchemaAndInstanceMode) { const QString instanceUri = QFile::decodeName(argv[1]); const QString schemaUri = QFile::decodeName(argv[2]); @@ -73,24 +80,24 @@ int main(int argc, char **argv) schema.load(QUrl(schemaUri)); if (!schema.isValid()) - return 1; + return Invalid; QXmlSchemaValidator validator(schema); if (validator.validate(QUrl(instanceUri))) - return 0; + return Valid; else - return 1; + return Invalid; } else if (mode == InstanceOnlyMode) { const QString instanceUri = QFile::decodeName(argv[1]); QXmlSchemaValidator validator(schema); if (validator.validate(QUrl(instanceUri))) - return 0; + return Valid; else - return 1; + return Invalid; } Q_ASSERT(false); - return 1; + return Invalid; } -- cgit v0.12 From 017fd8ebb129947603eeea5474a067d45a33eccb Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Sat, 16 May 2009 20:45:26 +0200 Subject: Adapt license headers to LGPL --- examples/xmlpatterns/schema/main.cpp | 34 ++++++++++++++++++++-- examples/xmlpatterns/schema/mainwindow.cpp | 34 ++++++++++++++++++++-- examples/xmlpatterns/schema/mainwindow.h | 34 ++++++++++++++++++++-- src/xmlpatterns/api/qabstractxmlpullprovider.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/api/qabstractxmlpullprovider_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/api/qpullbridge.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/api/qpullbridge_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/api/qxmlschema.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/api/qxmlschema.h | 34 ++++++++++++++++++++-- src/xmlpatterns/api/qxmlschema_p.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/api/qxmlschema_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/api/qxmlschemavalidator.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/api/qxmlschemavalidator.h | 34 ++++++++++++++++++++-- src/xmlpatterns/api/qxmlschemavalidator_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/data/qcomparisonfactory.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/data/qcomparisonfactory_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/data/qvaluefactory.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/data/qvaluefactory_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/parser/qquerytransformparser_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qnamespacesupport.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qnamespacesupport_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdalternative.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdalternative_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdannotated.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdannotated_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdannotation.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdannotation_p.h | 34 ++++++++++++++++++++-- .../schema/qxsdapplicationinformation.cpp | 34 ++++++++++++++++++++-- .../schema/qxsdapplicationinformation_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdassertion.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdassertion_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdattribute.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdattribute_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdattributegroup.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdattributegroup_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdattributereference.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdattributereference_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdattributeterm.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdattributeterm_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdattributeuse.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdattributeuse_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdcomplextype.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdcomplextype_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsddocumentation.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsddocumentation_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdelement.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdelement_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdfacet.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdfacet_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdidcache.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdidcache_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdidchelper.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdidchelper_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdidentityconstraint.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdidentityconstraint_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdinstancereader.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdinstancereader_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdmodelgroup.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdmodelgroup_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdnotation.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdnotation_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdparticle.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdparticle_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdparticlechecker.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdparticlechecker_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdreference.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdreference_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschema.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschema_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemachecker.cpp | 34 ++++++++++++++++++++-- .../schema/qxsdschemachecker_helper.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemachecker_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemacontext.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemacontext_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemadebugger.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemadebugger_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemahelper.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemahelper_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemamerger.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemamerger_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemaparser_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemaparsercontext.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemaparsercontext_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemaresolver.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemaresolver_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschematoken.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschematoken_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschematypesfactory.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschematypesfactory_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdsimpletype.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdsimpletype_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdstatemachine.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdstatemachine_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdterm.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdterm_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdtypechecker.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdtypechecker_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsduserschematype.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsduserschematype_p.h | 34 ++++++++++++++++++++-- .../schema/qxsdvalidatedxmlnodemodel.cpp | 34 ++++++++++++++++++++-- .../schema/qxsdvalidatedxmlnodemodel_p.h | 34 ++++++++++++++++++++-- .../schema/qxsdvalidatinginstancereader.cpp | 34 ++++++++++++++++++++-- .../schema/qxsdvalidatinginstancereader_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdwildcard.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdwildcard_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdxpathexpression.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdxpathexpression_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/tokens.xml | 34 ++++++++++++++++++++-- src/xmlpatterns/type/qnamedschemacomponent.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/type/qnamedschemacomponent_p.h | 34 ++++++++++++++++++++-- tools/xmlpatternsvalidator/main.cpp | 32 +++++++++++++++++++- tools/xmlpatternsvalidator/main.h | 32 +++++++++++++++++++- 114 files changed, 3646 insertions(+), 226 deletions(-) diff --git a/examples/xmlpatterns/schema/main.cpp b/examples/xmlpatterns/schema/main.cpp index 9537a87..50e1139 100644 --- a/examples/xmlpatterns/schema/main.cpp +++ b/examples/xmlpatterns/schema/main.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the examples of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/examples/xmlpatterns/schema/mainwindow.cpp b/examples/xmlpatterns/schema/mainwindow.cpp index 807a65b..6b43d7b 100644 --- a/examples/xmlpatterns/schema/mainwindow.cpp +++ b/examples/xmlpatterns/schema/mainwindow.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the examples of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/examples/xmlpatterns/schema/mainwindow.h b/examples/xmlpatterns/schema/mainwindow.h index e5dc2df..5f56afc 100644 --- a/examples/xmlpatterns/schema/mainwindow.h +++ b/examples/xmlpatterns/schema/mainwindow.h @@ -3,9 +3,39 @@ ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the examples of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/api/qabstractxmlpullprovider.cpp b/src/xmlpatterns/api/qabstractxmlpullprovider.cpp index a80604b..7a7d87d 100644 --- a/src/xmlpatterns/api/qabstractxmlpullprovider.cpp +++ b/src/xmlpatterns/api/qabstractxmlpullprovider.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/api/qabstractxmlpullprovider_p.h b/src/xmlpatterns/api/qabstractxmlpullprovider_p.h index d05e649..99fb280 100644 --- a/src/xmlpatterns/api/qabstractxmlpullprovider_p.h +++ b/src/xmlpatterns/api/qabstractxmlpullprovider_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/api/qpullbridge.cpp b/src/xmlpatterns/api/qpullbridge.cpp index f347339..1456b32 100644 --- a/src/xmlpatterns/api/qpullbridge.cpp +++ b/src/xmlpatterns/api/qpullbridge.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/api/qpullbridge_p.h b/src/xmlpatterns/api/qpullbridge_p.h index 823d27b..14aa29a 100644 --- a/src/xmlpatterns/api/qpullbridge_p.h +++ b/src/xmlpatterns/api/qpullbridge_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/api/qxmlschema.cpp b/src/xmlpatterns/api/qxmlschema.cpp index 108212e..aa5b77c 100644 --- a/src/xmlpatterns/api/qxmlschema.cpp +++ b/src/xmlpatterns/api/qxmlschema.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/api/qxmlschema.h b/src/xmlpatterns/api/qxmlschema.h index cf56b1e..d057b2c 100644 --- a/src/xmlpatterns/api/qxmlschema.h +++ b/src/xmlpatterns/api/qxmlschema.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/api/qxmlschema_p.cpp b/src/xmlpatterns/api/qxmlschema_p.cpp index 21dc04a..7b96f82 100644 --- a/src/xmlpatterns/api/qxmlschema_p.cpp +++ b/src/xmlpatterns/api/qxmlschema_p.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/api/qxmlschema_p.h b/src/xmlpatterns/api/qxmlschema_p.h index efba256..b54d88f 100644 --- a/src/xmlpatterns/api/qxmlschema_p.h +++ b/src/xmlpatterns/api/qxmlschema_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/api/qxmlschemavalidator.cpp b/src/xmlpatterns/api/qxmlschemavalidator.cpp index fcde49c..7a4ce03 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator.cpp +++ b/src/xmlpatterns/api/qxmlschemavalidator.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/api/qxmlschemavalidator.h b/src/xmlpatterns/api/qxmlschemavalidator.h index c82c522..e6683a5 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator.h +++ b/src/xmlpatterns/api/qxmlschemavalidator.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/api/qxmlschemavalidator_p.h b/src/xmlpatterns/api/qxmlschemavalidator_p.h index 9910f6e..fbf7b1c 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator_p.h +++ b/src/xmlpatterns/api/qxmlschemavalidator_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/data/qcomparisonfactory.cpp b/src/xmlpatterns/data/qcomparisonfactory.cpp index 7fe298b..79ff105 100644 --- a/src/xmlpatterns/data/qcomparisonfactory.cpp +++ b/src/xmlpatterns/data/qcomparisonfactory.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/data/qcomparisonfactory_p.h b/src/xmlpatterns/data/qcomparisonfactory_p.h index 09fc50b..88c587e 100644 --- a/src/xmlpatterns/data/qcomparisonfactory_p.h +++ b/src/xmlpatterns/data/qcomparisonfactory_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/data/qvaluefactory.cpp b/src/xmlpatterns/data/qvaluefactory.cpp index 04df29d..6c8fbec 100644 --- a/src/xmlpatterns/data/qvaluefactory.cpp +++ b/src/xmlpatterns/data/qvaluefactory.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/data/qvaluefactory_p.h b/src/xmlpatterns/data/qvaluefactory_p.h index 80b6207..0efe247 100644 --- a/src/xmlpatterns/data/qvaluefactory_p.h +++ b/src/xmlpatterns/data/qvaluefactory_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/parser/qquerytransformparser_p.h b/src/xmlpatterns/parser/qquerytransformparser_p.h index 759c39f..fb3ff72 100644 --- a/src/xmlpatterns/parser/qquerytransformparser_p.h +++ b/src/xmlpatterns/parser/qquerytransformparser_p.h @@ -54,9 +54,39 @@ ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qnamespacesupport.cpp b/src/xmlpatterns/schema/qnamespacesupport.cpp index 349f451..dc76a6f 100644 --- a/src/xmlpatterns/schema/qnamespacesupport.cpp +++ b/src/xmlpatterns/schema/qnamespacesupport.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qnamespacesupport_p.h b/src/xmlpatterns/schema/qnamespacesupport_p.h index d338eae..1f8f955 100644 --- a/src/xmlpatterns/schema/qnamespacesupport_p.h +++ b/src/xmlpatterns/schema/qnamespacesupport_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdalternative.cpp b/src/xmlpatterns/schema/qxsdalternative.cpp index f3f589a..6e4a7ab 100644 --- a/src/xmlpatterns/schema/qxsdalternative.cpp +++ b/src/xmlpatterns/schema/qxsdalternative.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdalternative_p.h b/src/xmlpatterns/schema/qxsdalternative_p.h index 451441e..2b1c75d 100644 --- a/src/xmlpatterns/schema/qxsdalternative_p.h +++ b/src/xmlpatterns/schema/qxsdalternative_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdannotated.cpp b/src/xmlpatterns/schema/qxsdannotated.cpp index a29b5c4..6674180 100644 --- a/src/xmlpatterns/schema/qxsdannotated.cpp +++ b/src/xmlpatterns/schema/qxsdannotated.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdannotated_p.h b/src/xmlpatterns/schema/qxsdannotated_p.h index 251b252..18f0612 100644 --- a/src/xmlpatterns/schema/qxsdannotated_p.h +++ b/src/xmlpatterns/schema/qxsdannotated_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdannotation.cpp b/src/xmlpatterns/schema/qxsdannotation.cpp index 0a9dc04..37ec09f 100644 --- a/src/xmlpatterns/schema/qxsdannotation.cpp +++ b/src/xmlpatterns/schema/qxsdannotation.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdannotation_p.h b/src/xmlpatterns/schema/qxsdannotation_p.h index 8c23bae..1f2cd14 100644 --- a/src/xmlpatterns/schema/qxsdannotation_p.h +++ b/src/xmlpatterns/schema/qxsdannotation_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdapplicationinformation.cpp b/src/xmlpatterns/schema/qxsdapplicationinformation.cpp index 5669220..3b4da24 100644 --- a/src/xmlpatterns/schema/qxsdapplicationinformation.cpp +++ b/src/xmlpatterns/schema/qxsdapplicationinformation.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdapplicationinformation_p.h b/src/xmlpatterns/schema/qxsdapplicationinformation_p.h index 30839d3..224b511 100644 --- a/src/xmlpatterns/schema/qxsdapplicationinformation_p.h +++ b/src/xmlpatterns/schema/qxsdapplicationinformation_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdassertion.cpp b/src/xmlpatterns/schema/qxsdassertion.cpp index f6cbf81..5a97385 100644 --- a/src/xmlpatterns/schema/qxsdassertion.cpp +++ b/src/xmlpatterns/schema/qxsdassertion.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdassertion_p.h b/src/xmlpatterns/schema/qxsdassertion_p.h index 0ae5ff6..58f6073 100644 --- a/src/xmlpatterns/schema/qxsdassertion_p.h +++ b/src/xmlpatterns/schema/qxsdassertion_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdattribute.cpp b/src/xmlpatterns/schema/qxsdattribute.cpp index 6cf60ec..bf640e7 100644 --- a/src/xmlpatterns/schema/qxsdattribute.cpp +++ b/src/xmlpatterns/schema/qxsdattribute.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdattribute_p.h b/src/xmlpatterns/schema/qxsdattribute_p.h index 46d7355..e0ff854 100644 --- a/src/xmlpatterns/schema/qxsdattribute_p.h +++ b/src/xmlpatterns/schema/qxsdattribute_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdattributegroup.cpp b/src/xmlpatterns/schema/qxsdattributegroup.cpp index 8f2a47e..b6549eb 100644 --- a/src/xmlpatterns/schema/qxsdattributegroup.cpp +++ b/src/xmlpatterns/schema/qxsdattributegroup.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdattributegroup_p.h b/src/xmlpatterns/schema/qxsdattributegroup_p.h index 7a3bd79..4fe9c37 100644 --- a/src/xmlpatterns/schema/qxsdattributegroup_p.h +++ b/src/xmlpatterns/schema/qxsdattributegroup_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdattributereference.cpp b/src/xmlpatterns/schema/qxsdattributereference.cpp index 3c36a4e..6e5809c 100644 --- a/src/xmlpatterns/schema/qxsdattributereference.cpp +++ b/src/xmlpatterns/schema/qxsdattributereference.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdattributereference_p.h b/src/xmlpatterns/schema/qxsdattributereference_p.h index be48b3a..6500109 100644 --- a/src/xmlpatterns/schema/qxsdattributereference_p.h +++ b/src/xmlpatterns/schema/qxsdattributereference_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdattributeterm.cpp b/src/xmlpatterns/schema/qxsdattributeterm.cpp index a9c3898..6463e35 100644 --- a/src/xmlpatterns/schema/qxsdattributeterm.cpp +++ b/src/xmlpatterns/schema/qxsdattributeterm.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdattributeterm_p.h b/src/xmlpatterns/schema/qxsdattributeterm_p.h index 507df32..6e49cfc 100644 --- a/src/xmlpatterns/schema/qxsdattributeterm_p.h +++ b/src/xmlpatterns/schema/qxsdattributeterm_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdattributeuse.cpp b/src/xmlpatterns/schema/qxsdattributeuse.cpp index 96d81bc..0f7ed9f 100644 --- a/src/xmlpatterns/schema/qxsdattributeuse.cpp +++ b/src/xmlpatterns/schema/qxsdattributeuse.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdattributeuse_p.h b/src/xmlpatterns/schema/qxsdattributeuse_p.h index 86021e1..bf2eac5 100644 --- a/src/xmlpatterns/schema/qxsdattributeuse_p.h +++ b/src/xmlpatterns/schema/qxsdattributeuse_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdcomplextype.cpp b/src/xmlpatterns/schema/qxsdcomplextype.cpp index ddc9110..6f5a240 100644 --- a/src/xmlpatterns/schema/qxsdcomplextype.cpp +++ b/src/xmlpatterns/schema/qxsdcomplextype.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdcomplextype_p.h b/src/xmlpatterns/schema/qxsdcomplextype_p.h index 078c8f0..4333d24 100644 --- a/src/xmlpatterns/schema/qxsdcomplextype_p.h +++ b/src/xmlpatterns/schema/qxsdcomplextype_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsddocumentation.cpp b/src/xmlpatterns/schema/qxsddocumentation.cpp index 4994143..b2490f6 100644 --- a/src/xmlpatterns/schema/qxsddocumentation.cpp +++ b/src/xmlpatterns/schema/qxsddocumentation.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsddocumentation_p.h b/src/xmlpatterns/schema/qxsddocumentation_p.h index c44a2bb..35463da 100644 --- a/src/xmlpatterns/schema/qxsddocumentation_p.h +++ b/src/xmlpatterns/schema/qxsddocumentation_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdelement.cpp b/src/xmlpatterns/schema/qxsdelement.cpp index 2b8ccab..c344799 100644 --- a/src/xmlpatterns/schema/qxsdelement.cpp +++ b/src/xmlpatterns/schema/qxsdelement.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdelement_p.h b/src/xmlpatterns/schema/qxsdelement_p.h index e571687..70ecb7e 100644 --- a/src/xmlpatterns/schema/qxsdelement_p.h +++ b/src/xmlpatterns/schema/qxsdelement_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdfacet.cpp b/src/xmlpatterns/schema/qxsdfacet.cpp index 513eee8..b49d530 100644 --- a/src/xmlpatterns/schema/qxsdfacet.cpp +++ b/src/xmlpatterns/schema/qxsdfacet.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdfacet_p.h b/src/xmlpatterns/schema/qxsdfacet_p.h index f1f8110..fe845d0 100644 --- a/src/xmlpatterns/schema/qxsdfacet_p.h +++ b/src/xmlpatterns/schema/qxsdfacet_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdidcache.cpp b/src/xmlpatterns/schema/qxsdidcache.cpp index d4a7b64..2d4adc9 100644 --- a/src/xmlpatterns/schema/qxsdidcache.cpp +++ b/src/xmlpatterns/schema/qxsdidcache.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdidcache_p.h b/src/xmlpatterns/schema/qxsdidcache_p.h index b1d3c0f..c81e4dc 100644 --- a/src/xmlpatterns/schema/qxsdidcache_p.h +++ b/src/xmlpatterns/schema/qxsdidcache_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdidchelper.cpp b/src/xmlpatterns/schema/qxsdidchelper.cpp index 70980cb..0442f26 100644 --- a/src/xmlpatterns/schema/qxsdidchelper.cpp +++ b/src/xmlpatterns/schema/qxsdidchelper.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdidchelper_p.h b/src/xmlpatterns/schema/qxsdidchelper_p.h index 3034292..d25d713 100644 --- a/src/xmlpatterns/schema/qxsdidchelper_p.h +++ b/src/xmlpatterns/schema/qxsdidchelper_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdidentityconstraint.cpp b/src/xmlpatterns/schema/qxsdidentityconstraint.cpp index e72a005..eec1235 100644 --- a/src/xmlpatterns/schema/qxsdidentityconstraint.cpp +++ b/src/xmlpatterns/schema/qxsdidentityconstraint.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdidentityconstraint_p.h b/src/xmlpatterns/schema/qxsdidentityconstraint_p.h index 6870b1e..712ea98 100644 --- a/src/xmlpatterns/schema/qxsdidentityconstraint_p.h +++ b/src/xmlpatterns/schema/qxsdidentityconstraint_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdinstancereader.cpp b/src/xmlpatterns/schema/qxsdinstancereader.cpp index 81c40c9..9d2dc60 100644 --- a/src/xmlpatterns/schema/qxsdinstancereader.cpp +++ b/src/xmlpatterns/schema/qxsdinstancereader.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdinstancereader_p.h b/src/xmlpatterns/schema/qxsdinstancereader_p.h index 9df02d6..1896ad9 100644 --- a/src/xmlpatterns/schema/qxsdinstancereader_p.h +++ b/src/xmlpatterns/schema/qxsdinstancereader_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdmodelgroup.cpp b/src/xmlpatterns/schema/qxsdmodelgroup.cpp index 1245822..a791284 100644 --- a/src/xmlpatterns/schema/qxsdmodelgroup.cpp +++ b/src/xmlpatterns/schema/qxsdmodelgroup.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdmodelgroup_p.h b/src/xmlpatterns/schema/qxsdmodelgroup_p.h index b7b59ac..eae46b0 100644 --- a/src/xmlpatterns/schema/qxsdmodelgroup_p.h +++ b/src/xmlpatterns/schema/qxsdmodelgroup_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdnotation.cpp b/src/xmlpatterns/schema/qxsdnotation.cpp index cfa0cd3..6c1d7c0 100644 --- a/src/xmlpatterns/schema/qxsdnotation.cpp +++ b/src/xmlpatterns/schema/qxsdnotation.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdnotation_p.h b/src/xmlpatterns/schema/qxsdnotation_p.h index dc1d597..6af3f0c 100644 --- a/src/xmlpatterns/schema/qxsdnotation_p.h +++ b/src/xmlpatterns/schema/qxsdnotation_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdparticle.cpp b/src/xmlpatterns/schema/qxsdparticle.cpp index a2671fa..3e5be44 100644 --- a/src/xmlpatterns/schema/qxsdparticle.cpp +++ b/src/xmlpatterns/schema/qxsdparticle.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdparticle_p.h b/src/xmlpatterns/schema/qxsdparticle_p.h index 61e3eb3..491cb47 100644 --- a/src/xmlpatterns/schema/qxsdparticle_p.h +++ b/src/xmlpatterns/schema/qxsdparticle_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdparticlechecker.cpp b/src/xmlpatterns/schema/qxsdparticlechecker.cpp index 7a09f8a..fa26b8b 100644 --- a/src/xmlpatterns/schema/qxsdparticlechecker.cpp +++ b/src/xmlpatterns/schema/qxsdparticlechecker.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdparticlechecker_p.h b/src/xmlpatterns/schema/qxsdparticlechecker_p.h index 16a8d95..739eca0 100644 --- a/src/xmlpatterns/schema/qxsdparticlechecker_p.h +++ b/src/xmlpatterns/schema/qxsdparticlechecker_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdreference.cpp b/src/xmlpatterns/schema/qxsdreference.cpp index 0a934dd..e7fc409 100644 --- a/src/xmlpatterns/schema/qxsdreference.cpp +++ b/src/xmlpatterns/schema/qxsdreference.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdreference_p.h b/src/xmlpatterns/schema/qxsdreference_p.h index afcca25..d6a1693 100644 --- a/src/xmlpatterns/schema/qxsdreference_p.h +++ b/src/xmlpatterns/schema/qxsdreference_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschema.cpp b/src/xmlpatterns/schema/qxsdschema.cpp index 260b06b..b9b9e99 100644 --- a/src/xmlpatterns/schema/qxsdschema.cpp +++ b/src/xmlpatterns/schema/qxsdschema.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschema_p.h b/src/xmlpatterns/schema/qxsdschema_p.h index b41a2d5..9954f56 100644 --- a/src/xmlpatterns/schema/qxsdschema_p.h +++ b/src/xmlpatterns/schema/qxsdschema_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemachecker.cpp b/src/xmlpatterns/schema/qxsdschemachecker.cpp index 2a64327..42cfff6 100644 --- a/src/xmlpatterns/schema/qxsdschemachecker.cpp +++ b/src/xmlpatterns/schema/qxsdschemachecker.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemachecker_helper.cpp b/src/xmlpatterns/schema/qxsdschemachecker_helper.cpp index 98c4c63..850b17b 100644 --- a/src/xmlpatterns/schema/qxsdschemachecker_helper.cpp +++ b/src/xmlpatterns/schema/qxsdschemachecker_helper.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemachecker_p.h b/src/xmlpatterns/schema/qxsdschemachecker_p.h index 65fb87f..1ec85f9 100644 --- a/src/xmlpatterns/schema/qxsdschemachecker_p.h +++ b/src/xmlpatterns/schema/qxsdschemachecker_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemacontext.cpp b/src/xmlpatterns/schema/qxsdschemacontext.cpp index 65b2e52..4648864 100644 --- a/src/xmlpatterns/schema/qxsdschemacontext.cpp +++ b/src/xmlpatterns/schema/qxsdschemacontext.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemacontext_p.h b/src/xmlpatterns/schema/qxsdschemacontext_p.h index c3a9f15..3aad656 100644 --- a/src/xmlpatterns/schema/qxsdschemacontext_p.h +++ b/src/xmlpatterns/schema/qxsdschemacontext_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemadebugger.cpp b/src/xmlpatterns/schema/qxsdschemadebugger.cpp index 850192c..629333c 100644 --- a/src/xmlpatterns/schema/qxsdschemadebugger.cpp +++ b/src/xmlpatterns/schema/qxsdschemadebugger.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemadebugger_p.h b/src/xmlpatterns/schema/qxsdschemadebugger_p.h index 8966963..a88f432 100644 --- a/src/xmlpatterns/schema/qxsdschemadebugger_p.h +++ b/src/xmlpatterns/schema/qxsdschemadebugger_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemahelper.cpp b/src/xmlpatterns/schema/qxsdschemahelper.cpp index ff169f7..f31ebd6 100644 --- a/src/xmlpatterns/schema/qxsdschemahelper.cpp +++ b/src/xmlpatterns/schema/qxsdschemahelper.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemahelper_p.h b/src/xmlpatterns/schema/qxsdschemahelper_p.h index 918664e..1335691 100644 --- a/src/xmlpatterns/schema/qxsdschemahelper_p.h +++ b/src/xmlpatterns/schema/qxsdschemahelper_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemamerger.cpp b/src/xmlpatterns/schema/qxsdschemamerger.cpp index a924c9c..a0f22a2 100644 --- a/src/xmlpatterns/schema/qxsdschemamerger.cpp +++ b/src/xmlpatterns/schema/qxsdschemamerger.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemamerger_p.h b/src/xmlpatterns/schema/qxsdschemamerger_p.h index 54cc0f2..8154689 100644 --- a/src/xmlpatterns/schema/qxsdschemamerger_p.h +++ b/src/xmlpatterns/schema/qxsdschemamerger_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemaparser_p.h b/src/xmlpatterns/schema/qxsdschemaparser_p.h index 960fb86..c52702b 100644 --- a/src/xmlpatterns/schema/qxsdschemaparser_p.h +++ b/src/xmlpatterns/schema/qxsdschemaparser_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemaparsercontext.cpp b/src/xmlpatterns/schema/qxsdschemaparsercontext.cpp index 896619e..e4dc348 100644 --- a/src/xmlpatterns/schema/qxsdschemaparsercontext.cpp +++ b/src/xmlpatterns/schema/qxsdschemaparsercontext.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemaparsercontext_p.h b/src/xmlpatterns/schema/qxsdschemaparsercontext_p.h index 616aff3..f95f571 100644 --- a/src/xmlpatterns/schema/qxsdschemaparsercontext_p.h +++ b/src/xmlpatterns/schema/qxsdschemaparsercontext_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemaresolver.cpp b/src/xmlpatterns/schema/qxsdschemaresolver.cpp index 4c6910f..46d0c69 100644 --- a/src/xmlpatterns/schema/qxsdschemaresolver.cpp +++ b/src/xmlpatterns/schema/qxsdschemaresolver.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemaresolver_p.h b/src/xmlpatterns/schema/qxsdschemaresolver_p.h index 1222619..79d2a2d 100644 --- a/src/xmlpatterns/schema/qxsdschemaresolver_p.h +++ b/src/xmlpatterns/schema/qxsdschemaresolver_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschematoken.cpp b/src/xmlpatterns/schema/qxsdschematoken.cpp index b527de6..e383b16 100644 --- a/src/xmlpatterns/schema/qxsdschematoken.cpp +++ b/src/xmlpatterns/schema/qxsdschematoken.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschematoken_p.h b/src/xmlpatterns/schema/qxsdschematoken_p.h index 8cb1e76..58d1f4d 100644 --- a/src/xmlpatterns/schema/qxsdschematoken_p.h +++ b/src/xmlpatterns/schema/qxsdschematoken_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschematypesfactory.cpp b/src/xmlpatterns/schema/qxsdschematypesfactory.cpp index 6cac0ff..b8f92a6 100644 --- a/src/xmlpatterns/schema/qxsdschematypesfactory.cpp +++ b/src/xmlpatterns/schema/qxsdschematypesfactory.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschematypesfactory_p.h b/src/xmlpatterns/schema/qxsdschematypesfactory_p.h index 4fcd5fb..874a701 100644 --- a/src/xmlpatterns/schema/qxsdschematypesfactory_p.h +++ b/src/xmlpatterns/schema/qxsdschematypesfactory_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdsimpletype.cpp b/src/xmlpatterns/schema/qxsdsimpletype.cpp index 2e5b7f5..0365e5e 100644 --- a/src/xmlpatterns/schema/qxsdsimpletype.cpp +++ b/src/xmlpatterns/schema/qxsdsimpletype.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdsimpletype_p.h b/src/xmlpatterns/schema/qxsdsimpletype_p.h index 9ba34b6..d9f84c7 100644 --- a/src/xmlpatterns/schema/qxsdsimpletype_p.h +++ b/src/xmlpatterns/schema/qxsdsimpletype_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdstatemachine.cpp b/src/xmlpatterns/schema/qxsdstatemachine.cpp index 4f36f22..0672e1a 100644 --- a/src/xmlpatterns/schema/qxsdstatemachine.cpp +++ b/src/xmlpatterns/schema/qxsdstatemachine.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdstatemachine_p.h b/src/xmlpatterns/schema/qxsdstatemachine_p.h index f0cf99d..81fb853 100644 --- a/src/xmlpatterns/schema/qxsdstatemachine_p.h +++ b/src/xmlpatterns/schema/qxsdstatemachine_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp b/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp index 866e010..a9e1d98 100644 --- a/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp +++ b/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h b/src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h index 011153a..82eeea8 100644 --- a/src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h +++ b/src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdterm.cpp b/src/xmlpatterns/schema/qxsdterm.cpp index 1dbe34b..92ea006 100644 --- a/src/xmlpatterns/schema/qxsdterm.cpp +++ b/src/xmlpatterns/schema/qxsdterm.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdterm_p.h b/src/xmlpatterns/schema/qxsdterm_p.h index f45d791..278b74d 100644 --- a/src/xmlpatterns/schema/qxsdterm_p.h +++ b/src/xmlpatterns/schema/qxsdterm_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdtypechecker.cpp b/src/xmlpatterns/schema/qxsdtypechecker.cpp index ab971a9..aabfcf6 100644 --- a/src/xmlpatterns/schema/qxsdtypechecker.cpp +++ b/src/xmlpatterns/schema/qxsdtypechecker.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdtypechecker_p.h b/src/xmlpatterns/schema/qxsdtypechecker_p.h index 2af20db..4b3f7c2 100644 --- a/src/xmlpatterns/schema/qxsdtypechecker_p.h +++ b/src/xmlpatterns/schema/qxsdtypechecker_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsduserschematype.cpp b/src/xmlpatterns/schema/qxsduserschematype.cpp index b8bf7e7..a985ba4 100644 --- a/src/xmlpatterns/schema/qxsduserschematype.cpp +++ b/src/xmlpatterns/schema/qxsduserschematype.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsduserschematype_p.h b/src/xmlpatterns/schema/qxsduserschematype_p.h index ab70f91..842fb00 100644 --- a/src/xmlpatterns/schema/qxsduserschematype_p.h +++ b/src/xmlpatterns/schema/qxsduserschematype_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp index 33bca4e..e7a1503 100644 --- a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp +++ b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h index d52e369..77fc8f4 100644 --- a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h +++ b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp b/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp index 8cb34d4..1505152 100644 --- a/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp +++ b/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h b/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h index 28f3c3f..0402e99 100644 --- a/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h +++ b/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdwildcard.cpp b/src/xmlpatterns/schema/qxsdwildcard.cpp index 6efb996..55eb4ba 100644 --- a/src/xmlpatterns/schema/qxsdwildcard.cpp +++ b/src/xmlpatterns/schema/qxsdwildcard.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdwildcard_p.h b/src/xmlpatterns/schema/qxsdwildcard_p.h index 8fbecb3..15fc159 100644 --- a/src/xmlpatterns/schema/qxsdwildcard_p.h +++ b/src/xmlpatterns/schema/qxsdwildcard_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdxpathexpression.cpp b/src/xmlpatterns/schema/qxsdxpathexpression.cpp index ba9d0a4..64bd687 100644 --- a/src/xmlpatterns/schema/qxsdxpathexpression.cpp +++ b/src/xmlpatterns/schema/qxsdxpathexpression.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdxpathexpression_p.h b/src/xmlpatterns/schema/qxsdxpathexpression_p.h index e57f7b7..e4f5427 100644 --- a/src/xmlpatterns/schema/qxsdxpathexpression_p.h +++ b/src/xmlpatterns/schema/qxsdxpathexpression_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/tokens.xml b/src/xmlpatterns/schema/tokens.xml index 7ec9752..6736ad75 100644 --- a/src/xmlpatterns/schema/tokens.xml +++ b/src/xmlpatterns/schema/tokens.xml @@ -112,9 +112,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/type/qnamedschemacomponent.cpp b/src/xmlpatterns/type/qnamedschemacomponent.cpp index e45b9b6..71b7519 100644 --- a/src/xmlpatterns/type/qnamedschemacomponent.cpp +++ b/src/xmlpatterns/type/qnamedschemacomponent.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/type/qnamedschemacomponent_p.h b/src/xmlpatterns/type/qnamedschemacomponent_p.h index bc3121b..70da093 100644 --- a/src/xmlpatterns/type/qnamedschemacomponent_p.h +++ b/src/xmlpatterns/type/qnamedschemacomponent_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/tools/xmlpatternsvalidator/main.cpp b/tools/xmlpatternsvalidator/main.cpp index 0ccbcfc..d53c783 100644 --- a/tools/xmlpatternsvalidator/main.cpp +++ b/tools/xmlpatternsvalidator/main.cpp @@ -5,7 +5,37 @@ ** ** This file is part of the Patternist project on Trolltech Labs. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/tools/xmlpatternsvalidator/main.h b/tools/xmlpatternsvalidator/main.h index 477a45a..85a4561 100644 --- a/tools/xmlpatternsvalidator/main.h +++ b/tools/xmlpatternsvalidator/main.h @@ -4,7 +4,37 @@ ** Contact: Qt Software Information (qt-info@nokia.com) ** ** This file is part of the Patternist project on Trolltech Labs. * ** - ** $TROLLTECH_DUAL_LICENSE$ + ** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -- cgit v0.12 From fa26e5759c645c9ed9c81a86dba72881dd1d776c Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Tue, 19 May 2009 16:17:18 +0200 Subject: Add missing example files --- examples/xmlpatterns/schema/files/contact.xsd | 25 ++++++++++++++ .../xmlpatterns/schema/files/invalid_contact.xml | 11 ++++++ .../xmlpatterns/schema/files/invalid_order.xml | 13 +++++++ .../xmlpatterns/schema/files/invalid_recipe.xml | 14 ++++++++ examples/xmlpatterns/schema/files/order.xsd | 23 +++++++++++++ examples/xmlpatterns/schema/files/recipe.xsd | 40 ++++++++++++++++++++++ .../xmlpatterns/schema/files/valid_contact.xml | 11 ++++++ examples/xmlpatterns/schema/files/valid_order.xml | 18 ++++++++++ examples/xmlpatterns/schema/files/valid_recipe.xml | 13 +++++++ 9 files changed, 168 insertions(+) create mode 100644 examples/xmlpatterns/schema/files/contact.xsd create mode 100644 examples/xmlpatterns/schema/files/invalid_contact.xml create mode 100644 examples/xmlpatterns/schema/files/invalid_order.xml create mode 100644 examples/xmlpatterns/schema/files/invalid_recipe.xml create mode 100644 examples/xmlpatterns/schema/files/order.xsd create mode 100644 examples/xmlpatterns/schema/files/recipe.xsd create mode 100644 examples/xmlpatterns/schema/files/valid_contact.xml create mode 100644 examples/xmlpatterns/schema/files/valid_order.xml create mode 100644 examples/xmlpatterns/schema/files/valid_recipe.xml diff --git a/examples/xmlpatterns/schema/files/contact.xsd b/examples/xmlpatterns/schema/files/contact.xsd new file mode 100644 index 0000000..3e1b570 --- /dev/null +++ b/examples/xmlpatterns/schema/files/contact.xsd @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/xmlpatterns/schema/files/invalid_contact.xml b/examples/xmlpatterns/schema/files/invalid_contact.xml new file mode 100644 index 0000000..42f1edd --- /dev/null +++ b/examples/xmlpatterns/schema/files/invalid_contact.xml @@ -0,0 +1,11 @@ + + John + Doe + Prof. + + Sandakerveien 116 + N-0550 + Oslo + Norway + + diff --git a/examples/xmlpatterns/schema/files/invalid_order.xml b/examples/xmlpatterns/schema/files/invalid_order.xml new file mode 100644 index 0000000..8ffc5fd --- /dev/null +++ b/examples/xmlpatterns/schema/files/invalid_order.xml @@ -0,0 +1,13 @@ + + 234219 +
+ 21692 + 3 +
+
+ 24749 + 9 +
+ 2009-01-23 + yes +
diff --git a/examples/xmlpatterns/schema/files/invalid_recipe.xml b/examples/xmlpatterns/schema/files/invalid_recipe.xml new file mode 100644 index 0000000..4d75af6 --- /dev/null +++ b/examples/xmlpatterns/schema/files/invalid_recipe.xml @@ -0,0 +1,14 @@ + + Cheese on Toast + + + diff --git a/examples/xmlpatterns/schema/files/order.xsd b/examples/xmlpatterns/schema/files/order.xsd new file mode 100644 index 0000000..405cafe --- /dev/null +++ b/examples/xmlpatterns/schema/files/order.xsd @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/xmlpatterns/schema/files/recipe.xsd b/examples/xmlpatterns/schema/files/recipe.xsd new file mode 100644 index 0000000..bbbafd9 --- /dev/null +++ b/examples/xmlpatterns/schema/files/recipe.xsd @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/xmlpatterns/schema/files/valid_contact.xml b/examples/xmlpatterns/schema/files/valid_contact.xml new file mode 100644 index 0000000..53c04d4 --- /dev/null +++ b/examples/xmlpatterns/schema/files/valid_contact.xml @@ -0,0 +1,11 @@ + + John + Doe + 1977-12-25 + + Sandakerveien 116 + N-0550 + Oslo + Norway + + diff --git a/examples/xmlpatterns/schema/files/valid_order.xml b/examples/xmlpatterns/schema/files/valid_order.xml new file mode 100644 index 0000000..f83c36c --- /dev/null +++ b/examples/xmlpatterns/schema/files/valid_order.xml @@ -0,0 +1,18 @@ + + 194223 +
+ 22242 + 5 +
+
+ 32372 + 12 + without stripes +
+
+ 23649 + 2 +
+ 2009-01-23 + true +
diff --git a/examples/xmlpatterns/schema/files/valid_recipe.xml b/examples/xmlpatterns/schema/files/valid_recipe.xml new file mode 100644 index 0000000..f6499ba --- /dev/null +++ b/examples/xmlpatterns/schema/files/valid_recipe.xml @@ -0,0 +1,13 @@ + + Cheese on Toast + + + -- cgit v0.12 From adad01b142a0839a9c6e59275844f0c38924c25d Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Tue, 19 May 2009 16:18:07 +0200 Subject: Remove unneeded qDebug statement --- src/xmlpatterns/schema/qxsdschemaparser.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/xmlpatterns/schema/qxsdschemaparser.cpp b/src/xmlpatterns/schema/qxsdschemaparser.cpp index cabc12e..3cd21af 100644 --- a/src/xmlpatterns/schema/qxsdschemaparser.cpp +++ b/src/xmlpatterns/schema/qxsdschemaparser.cpp @@ -251,7 +251,6 @@ void XsdSchemaParser::setTargetNamespaceExtended(const QString &targetNamespace) void XsdSchemaParser::setDocumentURI(const QUrl &uri) { - qDebug("%s", qPrintable(uri.toString())); m_documentURI = uri; // prevent to get included/imported/redefined twice -- cgit v0.12 From 317ab44d0c99fbc8b0a9f4136a107ad5d17e4539 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Tue, 19 May 2009 18:24:22 +0200 Subject: Extend auto tests for namepool checks --- tests/auto/qxmlschema/tst_qxmlschema.cpp | 4 ++ .../tst_qxmlschemavalidator.cpp | 62 ++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/tests/auto/qxmlschema/tst_qxmlschema.cpp b/tests/auto/qxmlschema/tst_qxmlschema.cpp index 7fc59bb..33978e8 100644 --- a/tests/auto/qxmlschema/tst_qxmlschema.cpp +++ b/tests/auto/qxmlschema/tst_qxmlschema.cpp @@ -118,6 +118,10 @@ void tst_QXmlSchema::constructorQXmlNamePool() const QCOMPARE(name.namespaceUri(np2), QString::fromLatin1("http://example.com/")); QCOMPARE(name.localName(np2), QString::fromLatin1("localName")); QCOMPARE(name.prefix(np2), QString::fromLatin1("prefix")); + + // make sure namePool() is const + const QXmlSchema constSchema; + np = constSchema.namePool(); } void tst_QXmlSchema::copyMutationTest() const diff --git a/tests/auto/qxmlschemavalidator/tst_qxmlschemavalidator.cpp b/tests/auto/qxmlschemavalidator/tst_qxmlschemavalidator.cpp index 3bbf506..0f15bc8 100644 --- a/tests/auto/qxmlschemavalidator/tst_qxmlschemavalidator.cpp +++ b/tests/auto/qxmlschemavalidator/tst_qxmlschemavalidator.cpp @@ -33,7 +33,9 @@ class tst_QXmlSchemaValidator : public QObject private Q_SLOTS: void defaultConstructor() const; + void constructorQXmlNamePool() const; void propertyInitialization() const; + void resetSchemaNamePool() const; void loadInstanceUrlSuccess() const; void loadInstanceUrlFail() const; @@ -119,6 +121,66 @@ void tst_QXmlSchemaValidator::propertyInitialization() const } } +void tst_QXmlSchemaValidator::constructorQXmlNamePool() const +{ + // test that the name pool from the schema is used by + // the schema validator as well + QXmlSchema schema; + + QXmlNamePool np = schema.namePool(); + + const QXmlName name(np, QLatin1String("localName"), + QLatin1String("http://example.com/"), + QLatin1String("prefix")); + + QXmlSchemaValidator validator(schema); + + QXmlNamePool np2(validator.namePool()); + QCOMPARE(name.namespaceUri(np2), QString::fromLatin1("http://example.com/")); + QCOMPARE(name.localName(np2), QString::fromLatin1("localName")); + QCOMPARE(name.prefix(np2), QString::fromLatin1("prefix")); + + // make sure namePool() is const + const QXmlSchemaValidator constValidator(schema); + np = constValidator.namePool(); +} + +void tst_QXmlSchemaValidator::resetSchemaNamePool() const +{ + QXmlSchema schema1; + QXmlNamePool np1 = schema1.namePool(); + + const QXmlName name1(np1, QLatin1String("localName"), + QLatin1String("http://example.com/"), + QLatin1String("prefix")); + + QXmlSchemaValidator validator(schema1); + + { + QXmlNamePool compNamePool(validator.namePool()); + QCOMPARE(name1.namespaceUri(compNamePool), QString::fromLatin1("http://example.com/")); + QCOMPARE(name1.localName(compNamePool), QString::fromLatin1("localName")); + QCOMPARE(name1.prefix(compNamePool), QString::fromLatin1("prefix")); + } + + QXmlSchema schema2; + QXmlNamePool np2 = schema2.namePool(); + + const QXmlName name2(np2, QLatin1String("remoteName"), + QLatin1String("http://trolltech.com/"), + QLatin1String("suffix")); + + // make sure that after re-setting the schema, the new namepool is used + validator.setSchema(schema2); + + { + QXmlNamePool compNamePool(validator.namePool()); + QCOMPARE(name2.namespaceUri(compNamePool), QString::fromLatin1("http://trolltech.com/")); + QCOMPARE(name2.localName(compNamePool), QString::fromLatin1("remoteName")); + QCOMPARE(name2.prefix(compNamePool), QString::fromLatin1("suffix")); + } +} + void tst_QXmlSchemaValidator::loadInstanceUrlSuccess() const { /* -- cgit v0.12 From ab5833178307fa9370868f61ff4cc7b18eb51fc0 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Tue, 19 May 2009 18:59:30 +0200 Subject: Forward errors from QXmlStreamReader to XsdSchemaParser (missed this commit on the first merge, autotest works again) --- src/xmlpatterns/schema/qxsdschemaparser.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/xmlpatterns/schema/qxsdschemaparser.cpp b/src/xmlpatterns/schema/qxsdschemaparser.cpp index 3cd21af..b74964d 100644 --- a/src/xmlpatterns/schema/qxsdschemaparser.cpp +++ b/src/xmlpatterns/schema/qxsdschemaparser.cpp @@ -290,6 +290,9 @@ bool XsdSchemaParser::parse(ParserType parserType) m_schemaResolver->addComponentLocationHash(m_componentLocationHash); m_schemaResolver->setDefaultOpenContent(m_defaultOpenContent, m_defaultOpenContentAppliesToEmpty); + if (QXmlStreamReader::error() != QXmlStreamReader::NoError) + error(errorString()); + return true; } -- cgit v0.12 From 9519f3ee67c8ab2de8d1ab5e584f8d3adb8875bd Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Tue, 19 May 2009 20:04:10 +0200 Subject: Document xml schema enum in QRegExp --- src/corelib/tools/qregexp.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp index f69a99f..664dfc0 100644 --- a/src/corelib/tools/qregexp.cpp +++ b/src/corelib/tools/qregexp.cpp @@ -3700,6 +3700,9 @@ static void invalidateEngine(QRegExpPrivate *priv) equivalent to using the RegExp pattern on a string in which all metacharacters are escaped using escape(). + \value W3CXmlSchema11 The pattern is a regular expression as + defined by the W3C XML Schema 1.1 specification. + \sa setPatternSyntax() */ -- cgit v0.12 From f66a475a236649c94a47f668ba3461bdc325c308 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Tue, 19 May 2009 20:09:09 +0200 Subject: First version of documentation for schema example --- doc/src/examples.qdoc | 1 + doc/src/examples/schema.qdoc | 58 +++++++++++++++++++++++++++++ doc/src/images/schema-example.png | Bin 0 -> 84320 bytes examples/xmlpatterns/schema/mainwindow.cpp | 19 ++++++---- examples/xmlpatterns/schema/schema.ui | 2 +- src/xmlpatterns/api/qxmlschema.cpp | 10 +++++ 6 files changed, 81 insertions(+), 9 deletions(-) create mode 100644 doc/src/examples/schema.qdoc create mode 100644 doc/src/images/schema-example.png diff --git a/doc/src/examples.qdoc b/doc/src/examples.qdoc index 29c6c0b..a0e9b23 100644 --- a/doc/src/examples.qdoc +++ b/doc/src/examples.qdoc @@ -398,6 +398,7 @@ \o \l{xmlpatterns/qobjectxmlmodel}{QObject XML Model Example} \o \l{xmlpatterns/xquery/globalVariables}{C++ Source Code Analyzer Example} \o \l{xmlpatterns/trafficinfo}{Traffic Info}\raisedaster + \o \l{xmlpatterns/schema}{XML Schema Validation}\raisedaster \endlist \section1 Inter-Process Communication diff --git a/doc/src/examples/schema.qdoc b/doc/src/examples/schema.qdoc new file mode 100644 index 0000000..2287796 --- /dev/null +++ b/doc/src/examples/schema.qdoc @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example xmlpatterns/schema + \title XML Schema Validation Example + + This example shows how to use QtXmlPatterns to validate XML with + a W3C XML Schema. + + \section1 Introduction + + The example application shows different XML schema definitions and + for every definition two XML instance documents, one that is valid + according to the schema and one that is not. + The user can select the valid or invalid instance document, change + it and validate it again. + + \image schema-example.png +*/ diff --git a/doc/src/images/schema-example.png b/doc/src/images/schema-example.png new file mode 100644 index 0000000..5e95bf5 Binary files /dev/null and b/doc/src/images/schema-example.png differ diff --git a/examples/xmlpatterns/schema/mainwindow.cpp b/examples/xmlpatterns/schema/mainwindow.cpp index 6b43d7b..98276a3 100644 --- a/examples/xmlpatterns/schema/mainwindow.cpp +++ b/examples/xmlpatterns/schema/mainwindow.cpp @@ -69,7 +69,8 @@ class MessageHandler : public QAbstractMessageHandler } protected: - virtual void handleMessage(QtMsgType type, const QString &description, const QUrl &identifier, const QSourceLocation &sourceLocation) + virtual void handleMessage(QtMsgType type, const QString &description, + const QUrl &identifier, const QSourceLocation &sourceLocation) { Q_UNUSED(type); Q_UNUSED(identifier); @@ -127,7 +128,7 @@ void MainWindow::schemaSelected(int index) QFile schemaFile(QString(":/schema_%1.xsd").arg(index)); schemaFile.open(QIODevice::ReadOnly); - const QString schemaText(QString::fromLatin1(schemaFile.readAll())); + const QString schemaText(QString::fromUtf8(schemaFile.readAll())); schemaView->setPlainText(schemaText); validate(); @@ -137,7 +138,7 @@ void MainWindow::instanceSelected(int index) { QFile instanceFile(QString(":/instance_%1.xml").arg((2*schemaSelection->currentIndex()) + index)); instanceFile.open(QIODevice::ReadOnly); - const QString instanceText(QString::fromLatin1(instanceFile.readAll())); + const QString instanceText(QString::fromUtf8(instanceFile.readAll())); instanceEdit->setPlainText(instanceText); validate(); @@ -145,22 +146,22 @@ void MainWindow::instanceSelected(int index) void MainWindow::validate() { - const QByteArray schemaData = schemaView->toPlainText().toLatin1(); - const QByteArray instanceData = instanceEdit->toPlainText().toLatin1(); + const QByteArray schemaData = schemaView->toPlainText().toUtf8(); + const QByteArray instanceData = instanceEdit->toPlainText().toUtf8(); MessageHandler messageHandler; QXmlSchema schema; schema.setMessageHandler(&messageHandler); - schema.load(schemaData, QUrl("http://dummySchemaUrl/")); + schema.load(schemaData); bool errorOccurred = false; if (!schema.isValid()) { errorOccurred = true; } else { QXmlSchemaValidator validator(schema); - if (!validator.validate(instanceData, QUrl("http://dummyInstanceUrl"))) + if (!validator.validate(instanceData)) errorOccurred = true; } @@ -171,7 +172,9 @@ void MainWindow::validate() validationStatus->setText(tr("validation successful")); } - QString styleSheet = QString("QLabel {background: %1; padding: 3px}").arg(errorOccurred ? QColor(Qt::red).lighter(160).name() : QColor(Qt::green).lighter(160).name()); + const QString styleSheet = QString("QLabel {background: %1; padding: 3px}") + .arg(errorOccurred ? QColor(Qt::red).lighter(160).name() : + QColor(Qt::green).lighter(160).name()); validationStatus->setStyleSheet(styleSheet); } diff --git a/examples/xmlpatterns/schema/schema.ui b/examples/xmlpatterns/schema/schema.ui index af7020a..b67f444 100644 --- a/examples/xmlpatterns/schema/schema.ui +++ b/examples/xmlpatterns/schema/schema.ui @@ -11,7 +11,7 @@ - MainWindow + XML Schema Validation diff --git a/src/xmlpatterns/api/qxmlschema.cpp b/src/xmlpatterns/api/qxmlschema.cpp index aa5b77c..8e14f3f 100644 --- a/src/xmlpatterns/api/qxmlschema.cpp +++ b/src/xmlpatterns/api/qxmlschema.cpp @@ -88,6 +88,9 @@ QXmlSchema::~QXmlSchema() /*! Sets this QXmlSchema to a schema loaded from the \a source URI. + + If the schema \l {isValid()} {is invalid}, \c{false} is returned + and the behavior is undefined. */ bool QXmlSchema::load(const QUrl &source) { @@ -107,6 +110,10 @@ bool QXmlSchema::load(const QUrl &source) If \a source is \c null or not readable, or if \a documentUri is not a valid URI, behavior is undefined. + + If the schema \l {isValid()} {is invalid}, \c{false} is returned + and the behavior is undefined. + \sa isValid() */ bool QXmlSchema::load(QIODevice *source, const QUrl &documentUri) @@ -125,6 +132,9 @@ bool QXmlSchema::load(QIODevice *source, const QUrl &documentUri) If \a documentUri is not a valid URI, behavior is undefined. \sa isValid() + + If the schema \l {isValid()} {is invalid}, \c{false} is returned + and the behavior is undefined. */ bool QXmlSchema::load(const QByteArray &data, const QUrl &documentUri) { -- cgit v0.12 From 676d97d56a96c46cd9b9a2d6ba5d5f535f974d42 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Wed, 20 May 2009 21:11:14 +0200 Subject: Complete documentation of schema example and reference it from api docs --- doc/src/examples/schema.qdoc | 85 +++++++++++++++++++++++++++++ examples/xmlpatterns/schema/mainwindow.cpp | 10 ++++ src/xmlpatterns/api/qxmlschema.cpp | 2 + src/xmlpatterns/api/qxmlschemavalidator.cpp | 2 + 4 files changed, 99 insertions(+) diff --git a/doc/src/examples/schema.qdoc b/doc/src/examples/schema.qdoc index 2287796..80d158b 100644 --- a/doc/src/examples/schema.qdoc +++ b/doc/src/examples/schema.qdoc @@ -46,6 +46,8 @@ This example shows how to use QtXmlPatterns to validate XML with a W3C XML Schema. + \tableofcontents + \section1 Introduction The example application shows different XML schema definitions and @@ -54,5 +56,88 @@ The user can select the valid or invalid instance document, change it and validate it again. + \section2 The User Interface + + The UI for this example was created using \l{Qt Designer Manual} {Qt + Designer}: + \image schema-example.png + + The UI consists of three parts, at the top the XML schema \l{QComboBox} {selection} + and the schema \l{QTextBrowser} {viewer}, below the XML instance \l{QComboBox} {selection} + and the instance \l{QTextEdit} {editor} and at the bottom the validation status \l{QLabel} {label} + next to the validation \l{QPushButton} {button}. + + \section2 Validating XML Instance Documents + + You can select one of the three predefined XML schemas and for each schema + an valid or invalid instance document. A click on the 'Validate' button will + validate the content of the XML instance editor against the schema from the + XML schema viewer. As you can modify the content of the instance editor, different + instances can be tested and validation error messages analysed. + + \section1 Code Walk-Through + + The example's main() function creates the standard instance of + QApplication. Then it creates an instance of the mainwindow class, shows it, + and starts the Qt event loop: + + \snippet examples/xmlpatterns/schema/main.cpp 0 + + \section2 The UI Class: MainWindow + + The example's UI is a conventional Qt GUI application inheriting + QMainWindow and the class generated by \l{Qt Designer Manual} {Qt + Designer}: + + \snippet examples/xmlpatterns/schema/mainwindow.h 0 + + The constructor fills the schema and instance \l{QComboBox} selections with the predefined + schemas and instances and connects their \l{QComboBox::currentIndexChanged()} {currentIndexChanged()} + signals to the window's \c{schemaSelected()} resp. \c{instanceSelected()} slot. + Furthermore the signal-slot connections for the validation \l{QPushButton} {button} + and the instance \l{QTextEdit} {editor} are set up. + + The call to \c{schemaSelected(0)} and \c{instanceSelected(0)} will trigger the validation + of the initial Contact Schema example. + + \snippet examples/xmlpatterns/schema/mainwindow.cpp 0 + + In the \c{schemaSelected()} slot the content of the instance \l{QComboBox} {selection} + is adapted to the selected schema and the corresponding schema is loaded from the + \l{The Qt Resource System} {resource file} and displayed in the schema \l{QTextBrowser} {viewer}. + At the end of the method a revalidation is triggered. + + \snippet examples/xmlpatterns/schema/mainwindow.cpp 1 + + In the \c{instanceSelected()} slot the selected instance is loaded from the + \l{The Qt Resource System} {resource file} and loaded into the instance \l{QTextEdit} {editor} + an the revalidation is triggered again. + + \snippet examples/xmlpatterns/schema/mainwindow.cpp 2 + + The \c{validate()} slot does the actual work in this example. + At first it stores the content of the schema \l{QTextBrowser} {viewer} and the + \l{QTextEdit} {editor} into temporary \l{QByteArray} {variables}. + Then it instanciates a \c{MessageHandler} object which inherits from + \l{QAbstractMessageHandler} {QAbstractMessageHandler} and is a convenience + class to store error messages from the XmlPatterns system. + + \snippet examples/xmlpatterns/schema/mainwindow.cpp 4 + + After the \l{QXmlSchema} {QXmlSchema} is instanciated and the message handler set + on it, the \l{QXmlSchema::load()} {load()} method is called with the schema data as argument. + If the schema is invalid or a parsing error has occured, \l{QXmlSchema::isValid()} {isValid()} + returns \c{false} and the error is flagged in \c{errorOccurred}. + If the loading was successful, a \l{QXmlSchemaValidator} {QXmlSchemaValidator} is + instanciated and the schema passed in the constructor. + A call to \l{QXmlSchemaValidator::validate()} {validate()} will validate the passed + XML instance data against the XML schema. The return value of that method signals + whether the validation was successful. + Depending on the success the status \l{QLabel} {label} is set to 'validation successful' + or the error message stored in the \c{MessageHandler} + + The rest of the code does only some fancy coloring and eyecandy. + + \snippet examples/xmlpatterns/schema/mainwindow.cpp 3 */ diff --git a/examples/xmlpatterns/schema/mainwindow.cpp b/examples/xmlpatterns/schema/mainwindow.cpp index 98276a3..bee7407 100644 --- a/examples/xmlpatterns/schema/mainwindow.cpp +++ b/examples/xmlpatterns/schema/mainwindow.cpp @@ -45,6 +45,7 @@ #include "mainwindow.h" #include "xmlsyntaxhighlighter.h" +//! [4] class MessageHandler : public QAbstractMessageHandler { public: @@ -85,7 +86,9 @@ class MessageHandler : public QAbstractMessageHandler QString m_description; QSourceLocation m_sourceLocation; }; +//! [4] +//! [0] MainWindow::MainWindow() { setupUi(this); @@ -110,7 +113,9 @@ MainWindow::MainWindow() schemaSelected(0); instanceSelected(0); } +//! [0] +//! [1] void MainWindow::schemaSelected(int index) { instanceSelection->clear(); @@ -133,7 +138,9 @@ void MainWindow::schemaSelected(int index) validate(); } +//! [1] +//! [2] void MainWindow::instanceSelected(int index) { QFile instanceFile(QString(":/instance_%1.xml").arg((2*schemaSelection->currentIndex()) + index)); @@ -143,7 +150,9 @@ void MainWindow::instanceSelected(int index) validate(); } +//! [2] +//! [3] void MainWindow::validate() { const QByteArray schemaData = schemaView->toPlainText().toUtf8(); @@ -177,6 +186,7 @@ void MainWindow::validate() QColor(Qt::green).lighter(160).name()); validationStatus->setStyleSheet(styleSheet); } +//! [3] void MainWindow::textChanged() { diff --git a/src/xmlpatterns/api/qxmlschema.cpp b/src/xmlpatterns/api/qxmlschema.cpp index 8e14f3f..62b6a0e 100644 --- a/src/xmlpatterns/api/qxmlschema.cpp +++ b/src/xmlpatterns/api/qxmlschema.cpp @@ -57,6 +57,8 @@ The QXmlSchema class loads, compiles and validates W3C XML Schema files that can be used further for validation of XML instance documents via \l{QXmlSchemaValidator}. + + \sa QXmlSchemaValidator, {xmlpatterns/schema}{XML Schema Validation Example} */ /*! diff --git a/src/xmlpatterns/api/qxmlschemavalidator.cpp b/src/xmlpatterns/api/qxmlschemavalidator.cpp index 7a4ce03..a69b081 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator.cpp +++ b/src/xmlpatterns/api/qxmlschemavalidator.cpp @@ -62,6 +62,8 @@ The QXmlSchemaValidator class loads, parses an XML instance document and validates it against a W3C XML Schema that has been compiled with \l{QXmlSchema}. + + \sa QXmlSchema, {xmlpatterns/schema}{XML Schema Validation Example} */ /*! -- cgit v0.12 From be0285b193d23fcf28ad84a73895ad15ece18e4c Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Thu, 21 May 2009 12:25:00 +0200 Subject: Added code snippets for QXmlSchema and referenced them from api docs --- doc/src/snippets/qxmlschema/main.cpp | 118 +++++++++++++++++++++++++++++ doc/src/snippets/qxmlschema/qxmlschema.pro | 3 + doc/src/snippets/snippets.pro | 1 + src/xmlpatterns/api/qxmlschema.cpp | 16 ++++ 4 files changed, 138 insertions(+) create mode 100644 doc/src/snippets/qxmlschema/main.cpp create mode 100644 doc/src/snippets/qxmlschema/qxmlschema.pro diff --git a/doc/src/snippets/qxmlschema/main.cpp b/doc/src/snippets/qxmlschema/main.cpp new file mode 100644 index 0000000..9e72f40 --- /dev/null +++ b/doc/src/snippets/qxmlschema/main.cpp @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +class Schema +{ + public: + void loadFromUrl() const; + void loadFromFile() const; + void loadFromData() const; +}; + +void Schema::loadFromUrl() const +{ +//! [0] + QUrl url("http://www.schema-example.org/myschema.xsd"); + + QXmlSchema schema; + if (schema.load(url) == true) + qDebug() << "schema is valid"; + else + qDebug() << "schema is invalid"; +//! [0] +} + +void Schema::loadFromFile() const +{ +//! [1] + QFile file("myschema.xsd"); + file.open(QIODevice::ReadOnly); + + QXmlSchema schema; + schema.load(&file, QUrl::fromLocalFile(file.fileName())); + + if (schema.isValid()) + qDebug() << "schema is valid"; + else + qDebug() << "schema is invalid"; +//! [1] +} + +void Schema::loadFromData() const +{ +//! [2] + QByteArray data( "" + "" + "" ); + + QBuffer buffer(&data); + buffer.open(QIODevice::ReadOnly); + + QXmlSchema schema; + schema.load(&buffer); + + if (schema.isValid()) + qDebug() << "schema is valid"; + else + qDebug() << "schema is invalid"; +//! [2] +} + +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + + Schema schema; + + schema.loadFromUrl(); + schema.loadFromFile(); + schema.loadFromData(); + + return 0; +} diff --git a/doc/src/snippets/qxmlschema/qxmlschema.pro b/doc/src/snippets/qxmlschema/qxmlschema.pro new file mode 100644 index 0000000..7e8782a --- /dev/null +++ b/doc/src/snippets/qxmlschema/qxmlschema.pro @@ -0,0 +1,3 @@ +SOURCES += main.cpp + +QT += xmlpatterns diff --git a/doc/src/snippets/snippets.pro b/doc/src/snippets/snippets.pro index 50e33b3..e7219a6 100644 --- a/doc/src/snippets/snippets.pro +++ b/doc/src/snippets/snippets.pro @@ -73,6 +73,7 @@ SUBDIRS = brush \ quiloader \ qx11embedcontainer \ qx11embedwidget \ + qxmlschema \ reading-selections \ scribe-overview \ separations \ diff --git a/src/xmlpatterns/api/qxmlschema.cpp b/src/xmlpatterns/api/qxmlschema.cpp index 62b6a0e..ec370ca 100644 --- a/src/xmlpatterns/api/qxmlschema.cpp +++ b/src/xmlpatterns/api/qxmlschema.cpp @@ -93,6 +93,12 @@ QXmlSchema::~QXmlSchema() If the schema \l {isValid()} {is invalid}, \c{false} is returned and the behavior is undefined. + + Example: + + \snippet doc/src/snippets/qxmlschema/main.cpp 0 + + \sa isValid() */ bool QXmlSchema::load(const QUrl &source) { @@ -116,6 +122,10 @@ bool QXmlSchema::load(const QUrl &source) If the schema \l {isValid()} {is invalid}, \c{false} is returned and the behavior is undefined. + Example: + + \snippet doc/src/snippets/qxmlschema/main.cpp 1 + \sa isValid() */ bool QXmlSchema::load(QIODevice *source, const QUrl &documentUri) @@ -137,6 +147,12 @@ bool QXmlSchema::load(QIODevice *source, const QUrl &documentUri) If the schema \l {isValid()} {is invalid}, \c{false} is returned and the behavior is undefined. + + Example: + + \snippet doc/src/snippets/qxmlschema/main.cpp 2 + + \sa isValid() */ bool QXmlSchema::load(const QByteArray &data, const QUrl &documentUri) { -- cgit v0.12 From b24611f14453e6b870e25bdc3edcd4f6447ae87e Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Thu, 21 May 2009 15:16:40 +0200 Subject: Added code snippets for QXmlSchemaValidator and referenced them from api docs --- doc/src/snippets/qxmlschemavalidator/main.cpp | 137 +++++++++++++++++++++ .../qxmlschemavalidator/qxmlschemavalidator.pro | 3 + doc/src/snippets/snippets.pro | 1 + src/xmlpatterns/api/qxmlschemavalidator.cpp | 12 ++ 4 files changed, 153 insertions(+) create mode 100644 doc/src/snippets/qxmlschemavalidator/main.cpp create mode 100644 doc/src/snippets/qxmlschemavalidator/qxmlschemavalidator.pro diff --git a/doc/src/snippets/qxmlschemavalidator/main.cpp b/doc/src/snippets/qxmlschemavalidator/main.cpp new file mode 100644 index 0000000..13cd45f --- /dev/null +++ b/doc/src/snippets/qxmlschemavalidator/main.cpp @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +class SchemaValidator +{ + public: + void validateFromUrl() const; + void validateFromFile() const; + void validateFromData() const; + + private: + QXmlSchema getSchema() const; +}; + +void SchemaValidator::validateFromUrl() const +{ +//! [0] + const QXmlSchema schema = getSchema(); + + const QUrl url("http://www.schema-example.org/test.xml"); + + QXmlSchemaValidator validator(schema); + if (validator.validate(url)) + qDebug() << "instance document is valid"; + else + qDebug() << "instance document is invalid"; +//! [0] +} + +void SchemaValidator::validateFromFile() const +{ +//! [1] + const QXmlSchema schema = getSchema(); + + QFile file("test.xml"); + file.open(QIODevice::ReadOnly); + + QXmlSchemaValidator validator(schema); + if (validator.validate(&file, QUrl::fromLocalFile(file.fileName()))) + qDebug() << "instance document is valid"; + else + qDebug() << "instance document is invalid"; +//! [1] +} + +void SchemaValidator::validateFromData() const +{ +//! [2] + const QXmlSchema schema = getSchema(); + + QByteArray data("" + ""); + + QBuffer buffer(&data); + buffer.open(QIODevice::ReadOnly); + + QXmlSchemaValidator validator(schema); + if (validator.validate(&buffer)) + qDebug() << "instance document is valid"; + else + qDebug() << "instance document is invalid"; +//! [2] +} + +QXmlSchema SchemaValidator::getSchema() const +{ + QByteArray data("" + "" + ""); + + QBuffer buffer(&data); + buffer.open(QIODevice::ReadOnly); + + QXmlSchema schema; + schema.load(&buffer); + + return schema; +} + +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + + SchemaValidator validator; + + validator.validateFromUrl(); + validator.validateFromFile(); + validator.validateFromData(); + + return 0; +} diff --git a/doc/src/snippets/qxmlschemavalidator/qxmlschemavalidator.pro b/doc/src/snippets/qxmlschemavalidator/qxmlschemavalidator.pro new file mode 100644 index 0000000..7e8782a --- /dev/null +++ b/doc/src/snippets/qxmlschemavalidator/qxmlschemavalidator.pro @@ -0,0 +1,3 @@ +SOURCES += main.cpp + +QT += xmlpatterns diff --git a/doc/src/snippets/snippets.pro b/doc/src/snippets/snippets.pro index e7219a6..e3e7eca 100644 --- a/doc/src/snippets/snippets.pro +++ b/doc/src/snippets/snippets.pro @@ -74,6 +74,7 @@ SUBDIRS = brush \ qx11embedcontainer \ qx11embedwidget \ qxmlschema \ + qxmlschemavalidator \ reading-selections \ scribe-overview \ separations \ diff --git a/src/xmlpatterns/api/qxmlschemavalidator.cpp b/src/xmlpatterns/api/qxmlschemavalidator.cpp index a69b081..b72b1ef 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator.cpp +++ b/src/xmlpatterns/api/qxmlschemavalidator.cpp @@ -106,6 +106,10 @@ void QXmlSchemaValidator::setSchema(const QXmlSchema &schema) Returns \c true if the XML instance document is valid according the schema, \c false otherwise. + + Example: + + \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 2 */ bool QXmlSchemaValidator::validate(const QByteArray &data, const QUrl &documentUri) const { @@ -122,6 +126,10 @@ bool QXmlSchemaValidator::validate(const QByteArray &data, const QUrl &documentU Returns \c true if the XML instance document is valid according the schema, \c false otherwise. + + Example: + + \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 0 */ bool QXmlSchemaValidator::validate(const QUrl &source) const { @@ -143,6 +151,10 @@ bool QXmlSchemaValidator::validate(const QUrl &source) const Returns \c true if the XML instance document is valid according the schema, \c false otherwise. + + Example: + + \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 1 */ bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri) const { -- cgit v0.12 From 9281f4c219cec2e6a1e24b43e1edd0feb0fcfce5 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Fri, 29 May 2009 14:45:35 +0200 Subject: First bunch of changes after an very first API review This basically move some logic from the scene to the index base class. Lot of work need to be done in order to benefits from the device transform. The sorting needs to be move in the BSP tree. --- src/gui/graphicsview/graphicsview.pri | 1 + src/gui/graphicsview/qgraphicsitem.cpp | 17 +- src/gui/graphicsview/qgraphicsitem.h | 4 + src/gui/graphicsview/qgraphicsscene.cpp | 618 +++------------------ src/gui/graphicsview/qgraphicsscene.h | 9 + src/gui/graphicsview/qgraphicsscene_bsp.cpp | 12 +- src/gui/graphicsview/qgraphicsscene_bsp_p.h | 8 +- src/gui/graphicsview/qgraphicsscene_p.h | 88 ++- .../graphicsview/qgraphicsscenebsptreeindex_p.cpp | 120 ++-- .../graphicsview/qgraphicsscenebsptreeindex_p.h | 18 +- src/gui/graphicsview/qgraphicssceneindex.cpp | 558 +++++++++++++++++-- src/gui/graphicsview/qgraphicssceneindex.h | 50 +- src/gui/graphicsview/qgraphicssceneindex_p.h | 96 ++++ src/gui/graphicsview/qgraphicsscenelinearindex_p.h | 17 +- src/gui/graphicsview/qgraphicsview.cpp | 21 +- 15 files changed, 857 insertions(+), 780 deletions(-) create mode 100644 src/gui/graphicsview/qgraphicssceneindex_p.h diff --git a/src/gui/graphicsview/graphicsview.pri b/src/gui/graphicsview/graphicsview.pri index 9097497..cc57892 100644 --- a/src/gui/graphicsview/graphicsview.pri +++ b/src/gui/graphicsview/graphicsview.pri @@ -10,6 +10,7 @@ HEADERS += \ graphicsview/qgraphicsscene_bsp_p.h \ graphicsview/qgraphicsscenelinearindex_p.h \ graphicsview/qgraphicssceneindex.h \ + graphicsview/qgraphicssceneindex_p.h \ graphicsview/qgraphicssceneevent.h \ graphicsview/qgraphicsview_p.h \ graphicsview/qgraphicsview.h diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index c1d44d3..fc5895c 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -567,17 +567,6 @@ QT_BEGIN_NAMESPACE -// QRectF::intersects() returns false always if either the source or target -// rectangle's width or height are 0. This works around that problem. -static inline void _q_adjustRect(QRectF *rect) -{ - Q_ASSERT(rect); - if (!rect->width()) - rect->adjust(-0.00001, 0, 0.00001, 0); - if (!rect->height()) - rect->adjust(0, -0.00001, 0, 0.00001); -} - static inline void _q_adjustRect(QRect *rect) { Q_ASSERT(rect); @@ -6357,7 +6346,7 @@ void QGraphicsItem::addToIndex() return; } if (d_ptr->scene) - d_ptr->scene->d_func()->index->insertItem(this); + d_ptr->scene->d_func()->index->addItem(this); d_ptr->updateHelper(); } @@ -6372,7 +6361,7 @@ void QGraphicsItem::removeFromIndex() { d_ptr->updateHelper(); if (d_ptr->scene) - d_ptr->scene->d_func()->index->removeItem(this,false); + d_ptr->scene->d_func()->index->removeItem(this); } /*! @@ -6393,7 +6382,7 @@ void QGraphicsItem::prepareGeometryChange() if (d_ptr->scene) { d_ptr->updateHelper(QRectF(), false, /*maybeDirtyClipPath=*/!d_ptr->inSetPosHelper); QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func(); - scenePrivate->index->updateItem(this); + scenePrivate->index->prepareBoundingRectChange(this); } if (d_ptr->inSetPosHelper) diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index cb86020..e244c13 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -409,6 +409,8 @@ protected: virtual void setExtension(Extension extension, const QVariant &variant); virtual QVariant extension(const QVariant &variant) const; + bool operator<(const QGraphicsItem *other) const; + protected: QGraphicsItem(QGraphicsItemPrivate &dd, QGraphicsItem *parent, QGraphicsScene *scene); @@ -430,6 +432,8 @@ private: friend class QGraphicsWidget; friend class QGraphicsWidgetPrivate; friend class QGraphicsProxyWidgetPrivate; + friend class QGraphicsSceneIndex; + friend class QGraphicsSceneIndexPrivate; friend class QGraphicsSceneBspTreeIndex; friend class ::tst_QGraphicsItem; friend bool qt_closestLeaf(const QGraphicsItem *, const QGraphicsItem *); diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 51c8294..9b6d40b 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -249,65 +249,6 @@ QT_BEGIN_NAMESPACE -static inline bool QRectF_intersects(const QRectF &s, const QRectF &r) -{ - qreal xp = s.left(); - qreal yp = s.top(); - qreal w = s.width(); - qreal h = s.height(); - qreal l1 = xp; - qreal r1 = xp; - if (w < 0) - l1 += w; - else - r1 += w; - - qreal l2 = r.left(); - qreal r2 = r.left(); - if (w < 0) - l2 += r.width(); - else - r2 += r.width(); - - if (l1 >= r2 || l2 >= r1) - return false; - - qreal t1 = yp; - qreal b1 = yp; - if (h < 0) - t1 += h; - else - b1 += h; - - qreal t2 = r.top(); - qreal b2 = r.top(); - if (r.height() < 0) - t2 += r.height(); - else - b2 += r.height(); - - return !(t1 >= b2 || t2 >= b1); -} - -// QRectF::intersects() returns false always if either the source or target -// rectangle's width or height are 0. This works around that problem. -static inline void _q_adjustRect(QRectF *rect) -{ - Q_ASSERT(rect); - if (!rect->width()) - rect->adjust(-0.00001, 0, 0.00001, 0); - if (!rect->height()) - rect->adjust(0, -0.00001, 0, 0.00001); -} - -static inline QRectF adjustedItemBoundingRect(const QGraphicsItem *item) -{ - Q_ASSERT(item); - QRectF boundingRect(item->boundingRect()); - _q_adjustRect(&boundingRect); - return boundingRect; -} - static void _q_hoverFromMouseEvent(QGraphicsSceneHoverEvent *hover, const QGraphicsSceneMouseEvent *mouseEvent) { hover->setWidget(mouseEvent->widget()); @@ -374,21 +315,6 @@ void QGraphicsScenePrivate::init() /*! \internal */ -QList QGraphicsScenePrivate::estimateItemsInRect(const QRectF &rect) const -{ - const_cast(this)->_q_updateSortCache(); - - // ### Only do this once in a while. - QGraphicsScenePrivate *that = const_cast(this); - - // Get items from index - return that->index->items(rect); - -} - -/*! - \internal -*/ void QGraphicsScenePrivate::_q_emitUpdated() { Q_Q(QGraphicsScene); @@ -528,7 +454,7 @@ void QGraphicsScenePrivate::_q_removeItemLater(QGraphicsItem *item) item->clearFocus(); //We ask for a removing in the index - this->index->removeItem(item, true); + this->index->deleteItem(item); // Reset the mouse grabber and focus item data. if (item == focusItem) @@ -1145,444 +1071,6 @@ QGraphicsWidget *QGraphicsScenePrivate::windowForItem(const QGraphicsItem *item) return 0; } - -QList QGraphicsScenePrivate::items_helper(const QPointF &pos) const -{ - QList items; - - // The index returns a rough estimate of what items are inside the rect. - // Refine it by iterating through all returned items. - QRectF adjustedRect = QRectF(pos, QSize(1,1)); - foreach (QGraphicsItem *item, estimateItemsInRect(adjustedRect)) { - // Find the item's scene transform in a clever way. - QTransform x = item->sceneTransform(); - bool keep = false; - - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - // Rect intersects/contains item's shape - if (QRectF_intersects(adjustedRect, x.mapRect(br))) { - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) { - if (item->contains(xinv.map(pos))) { - items << item; - keep = true; - } - } - } - - if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { - // Recurse into children that clip children. - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) - childItems_helper(&items, item, xinv.map(pos)); - } - } - - sortItems(&items, Qt::AscendingOrder, sortCacheEnabled); - return items; -} - -QList QGraphicsScenePrivate::items_helper(const QRectF &rect, - Qt::ItemSelectionMode mode, - Qt::SortOrder order) const -{ - QList items; - - QPainterPath path; - - // The index returns a rough estimate of what items are inside the rect. - // Refine it by iterating through all returned items. - QRectF adjustedRect(rect); - _q_adjustRect(&adjustedRect); - foreach (QGraphicsItem *item, estimateItemsInRect(adjustedRect)) { - // Find the item's scene transform in a clever way. - QTransform x = item->sceneTransform(); - bool keep = false; - - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - if (mode >= Qt::ContainsItemBoundingRect) { - // Rect intersects/contains item's bounding rect - QRectF mbr = x.mapRect(br); - if ((mode == Qt::IntersectsItemBoundingRect && QRectF_intersects(rect, mbr)) - || (mode == Qt::ContainsItemBoundingRect && rect != mbr && rect.contains(mbr))) { - items << item; - keep = true; - } - } else { - // Rect intersects/contains item's shape - if (QRectF_intersects(adjustedRect, x.mapRect(br))) { - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) { - if (path.isEmpty()) - path.addRect(rect); - if (itemCollidesWithPath(item, xinv.map(path), mode)) { - items << item; - keep = true; - } - } - } - } - - if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { - // Recurse into children that clip children. - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) { - if (x.type() <= QTransform::TxScale) { - // Rect - childItems_helper(&items, item, xinv.mapRect(rect), mode); - } else { - // Polygon - childItems_helper(&items, item, xinv.map(rect), mode); - } - } - } - } - - if (order != Qt::SortOrder(-1)) - sortItems(&items, order, sortCacheEnabled); - return items; -} - -QList QGraphicsScenePrivate::items_helper(const QPolygonF &polygon, - Qt::ItemSelectionMode mode, - Qt::SortOrder order) const -{ - QList items; - - QRectF polyRect(polygon.boundingRect()); - _q_adjustRect(&polyRect); - QPainterPath path; - - // The index returns a rough estimate of what items are inside the rect. - // Refine it by iterating through all returned items. - foreach (QGraphicsItem *item, estimateItemsInRect(polyRect)) { - // Find the item's scene transform in a clever way. - QTransform x = item->sceneTransform(); - bool keep = false; - - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - if (mode >= Qt::ContainsItemBoundingRect) { - // Polygon contains/intersects item's bounding rect - if (path == QPainterPath()) - path.addPolygon(polygon); - if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(x.mapRect(br))) - || (mode == Qt::ContainsItemBoundingRect && path.contains(x.mapRect(br)))) { - items << item; - keep = true; - } - } else { - // Polygon contains/intersects item's shape - if (QRectF_intersects(polyRect, x.mapRect(br))) { - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) { - if (path == QPainterPath()) - path.addPolygon(polygon); - if (itemCollidesWithPath(item, xinv.map(path), mode)) { - items << item; - keep = true; - } - } - } - } - - if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { - // Recurse into children that clip children. - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) - childItems_helper(&items, item, xinv.map(polygon), mode); - } - } - - if (order != Qt::SortOrder(-1)) - sortItems(&items, order, sortCacheEnabled); - return items; -} - -QList QGraphicsScenePrivate::items_helper(const QPainterPath &path, - Qt::ItemSelectionMode mode, - Qt::SortOrder order) const -{ - QList items; - QRectF pathRect(path.controlPointRect()); - _q_adjustRect(&pathRect); - - // The index returns a rough estimate of what items are inside the rect. - // Refine it by iterating through all returned items. - foreach (QGraphicsItem *item, estimateItemsInRect(pathRect)) { - // Find the item's scene transform in a clever way. - QTransform x = item->sceneTransform(); - bool keep = false; - - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - if (mode >= Qt::ContainsItemBoundingRect) { - // Path contains/intersects item's bounding rect - if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(x.mapRect(br))) - || (mode == Qt::ContainsItemBoundingRect && path.contains(x.mapRect(br)))) { - items << item; - keep = true; - } - } else { - // Path contains/intersects item's shape - if (QRectF_intersects(pathRect, x.mapRect(br))) { - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) { - if (itemCollidesWithPath(item, xinv.map(path), mode)) { - items << item; - keep = true; - } - } - } - } - - if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) - childItems_helper(&items, item, xinv.map(path), mode); - } - } - - if (order != Qt::SortOrder(-1)) - sortItems(&items, order, sortCacheEnabled); - return items; -} - -void QGraphicsScenePrivate::childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPointF &pos) const -{ - bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); - if (parentClip && parent->d_ptr->isClippedAway()) - return; - // ### is this needed? - if (parentClip && !parent->boundingRect().contains(pos)) - return; - - QList &children = parent->d_ptr->children; - for (int i = 0; i < children.size(); ++i) { - QGraphicsItem *item = children.at(i); - if (item->d_ptr->hasTransform && !item->transform().isInvertible()) - continue; - - // Skip invisible items and all their children. - if (item->d_ptr->isInvisible()) - continue; - - bool keep = false; - if (!item->d_ptr->isClippedAway()) { - if (item->contains(item->mapFromParent(pos))) { - items->append(item); - keep = true; - } - } - - if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) - // Recurse into children. - childItems_helper(items, item, item->mapFromParent(pos)); - } -} - - -void QGraphicsScenePrivate::childItems_helper(QList *items, - const QGraphicsItem *parent, - const QRectF &rect, - Qt::ItemSelectionMode mode) const -{ - bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); - if (parentClip && parent->d_ptr->isClippedAway()) - return; - QRectF adjustedRect(rect); - _q_adjustRect(&adjustedRect); - QRectF r = !parentClip ? adjustedRect : adjustedRect.intersected(adjustedItemBoundingRect(parent)); - if (r.isEmpty()) - return; - - QPainterPath path; - QList &children = parent->d_ptr->children; - for (int i = 0; i < children.size(); ++i) { - QGraphicsItem *item = children.at(i); - if (item->d_ptr->hasTransform && !item->transform().isInvertible()) - continue; - - // Skip invisible items and all their children. - if (item->d_ptr->isInvisible()) - continue; - - bool keep = false; - if (!item->d_ptr->isClippedAway()) { - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - QRectF mbr = item->mapRectToParent(br); - if (mode >= Qt::ContainsItemBoundingRect) { - // Rect intersects/contains item's bounding rect - if ((mode == Qt::IntersectsItemBoundingRect && QRectF_intersects(rect, mbr)) - || (mode == Qt::ContainsItemBoundingRect && rect != mbr && rect.contains(br))) { - items->append(item); - keep = true; - } - } else { - // Rect intersects/contains item's shape - if (QRectF_intersects(rect, mbr)) { - if (path == QPainterPath()) - path.addRect(rect); - if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) { - items->append(item); - keep = true; - } - } - } - } - - if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) { - // Recurse into children. - if (!item->d_ptr->hasTransform || item->transform().type() <= QTransform::TxScale) { - // Rect - childItems_helper(items, item, item->mapRectFromParent(rect), mode); - } else { - // Polygon - childItems_helper(items, item, item->mapFromParent(rect), mode); - } - } - } -} - - -void QGraphicsScenePrivate::childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPolygonF &polygon, - Qt::ItemSelectionMode mode) const -{ - bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); - if (parentClip && parent->d_ptr->isClippedAway()) - return; - QRectF polyRect(polygon.boundingRect()); - _q_adjustRect(&polyRect); - QRectF r = !parentClip ? polyRect : polyRect.intersected(adjustedItemBoundingRect(parent)); - if (r.isEmpty()) - return; - - QPainterPath path; - QList &children = parent->d_ptr->children; - for (int i = 0; i < children.size(); ++i) { - QGraphicsItem *item = children.at(i); - if (item->d_ptr->hasTransform && !item->transform().isInvertible()) - continue; - - // Skip invisible items. - if (item->d_ptr->isInvisible()) - continue; - - bool keep = false; - if (!item->d_ptr->isClippedAway()) { - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - if (mode >= Qt::ContainsItemBoundingRect) { - // Polygon contains/intersects item's bounding rect - if (path == QPainterPath()) - path.addPolygon(polygon); - if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br))) - || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) { - items->append(item); - keep = true; - } - } else { - // Polygon contains/intersects item's shape - if (QRectF_intersects(polyRect, item->mapRectToParent(br))) { - if (path == QPainterPath()) - path.addPolygon(polygon); - if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) { - items->append(item); - keep = true; - } - } - } - } - - if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) { - // Recurse into children that clip children. - childItems_helper(items, item, item->mapFromParent(polygon), mode); - } - } -} - -void QGraphicsScenePrivate::childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPainterPath &path, - Qt::ItemSelectionMode mode) const -{ - bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); - if (parentClip && parent->d_ptr->isClippedAway()) - return; - QRectF pathRect(path.boundingRect()); - _q_adjustRect(&pathRect); - QRectF r = !parentClip ? pathRect : pathRect.intersected(adjustedItemBoundingRect(parent)); - if (r.isEmpty()) - return; - - QList &children = parent->d_ptr->children; - for (int i = 0; i < children.size(); ++i) { - QGraphicsItem *item = children.at(i); - if (item->d_ptr->hasTransform && !item->transform().isInvertible()) - continue; - - // Skip invisible items. - if (item->d_ptr->isInvisible()) - continue; - - bool keep = false; - if (!item->d_ptr->isClippedAway()) { - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - if (mode >= Qt::ContainsItemBoundingRect) { - // Polygon contains/intersects item's bounding rect - if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br))) - || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) { - items->append(item); - keep = true; - } - } else { - // Path contains/intersects item's shape - if (QRectF_intersects(pathRect, item->mapRectToParent(br))) { - if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) { - items->append(item); - keep = true; - } - } - } - } - - if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) { - // Recurse into children that clip children. - childItems_helper(items, item, item->mapFromParent(path), mode); - } - } -} - void QGraphicsScenePrivate::invalidateSortCache() { Q_Q(QGraphicsScene); @@ -1709,7 +1197,8 @@ void QGraphicsScenePrivate::climbTree(QGraphicsItem *item, int *stackingOrder) void QGraphicsScenePrivate::_q_updateSortCache() { - index->updateIndex(); + //### FIXME + //index->updateIndex(); if (!sortCacheEnabled || !updatingSortCache) return; @@ -1719,8 +1208,8 @@ void QGraphicsScenePrivate::_q_updateSortCache() QList topLevels; - for (int i = 0; i < index->indexedItems().count(); ++i) { - QGraphicsItem *item = index->indexedItems().at(i); + for (int i = 0; i < index->items().count(); ++i) { + QGraphicsItem *item = index->items().at(i); if (item && item->parentItem() == 0) topLevels << item; } @@ -1933,8 +1422,7 @@ QGraphicsScene::~QGraphicsScene() QRectF QGraphicsScene::sceneRect() const { Q_D(const QGraphicsScene); - d->index->updateIndex(); - return d->hasSceneRect ? d->index->rect() : d->growingItemsBoundingRect; + return d->hasSceneRect ? d->sceneRect : d->growingItemsBoundingRect; } void QGraphicsScene::setSceneRect(const QRectF &rect) { @@ -1942,7 +1430,7 @@ void QGraphicsScene::setSceneRect(const QRectF &rect) if (rect != d->sceneRect) { d->hasSceneRect = !rect.isNull(); d->sceneRect = rect; - d->index->setRect(rect); + d->index->sceneRectChanged(rect); emit sceneRectChanged(rect); } } @@ -2106,9 +1594,11 @@ void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method) } if (d->indexMethod == CustomIndex && method == BspTreeIndex) { + //We re-add in the new index all items from the old index QGraphicsSceneIndex *oldIndex = d->index; d->index = new QGraphicsSceneBspTreeIndex(this); - d->index->insertItems(oldIndex->items(oldIndex->rect())); + for (int i = 0 ; i < oldIndex->items().size() ; ++ i) + d->index->addItem(oldIndex->items().at(i)); } if (d->indexMethod == CustomIndex && method == NoIndex) { @@ -2246,7 +1736,7 @@ QRectF QGraphicsScene::itemsBoundingRect() const QList QGraphicsScene::items() const { Q_D(const QGraphicsScene); - return d->index->indexedItems(); + return d->index->items(); } /*! @@ -2259,7 +1749,7 @@ QList QGraphicsScene::items() const QList QGraphicsScene::items(const QPointF &pos) const { Q_D(const QGraphicsScene); - return d->items_helper(pos); + return d->index->items(pos, Qt::IntersectsItemShape, Qt::AscendingOrder); } @@ -2279,7 +1769,7 @@ QList QGraphicsScene::items(const QPointF &pos) const QList QGraphicsScene::items(const QRectF &rect, Qt::ItemSelectionMode mode) const { Q_D(const QGraphicsScene); - return d->items_helper(rect, mode, Qt::AscendingOrder); + return d->index->items(rect, mode, Qt::AscendingOrder); } /*! @@ -2303,7 +1793,7 @@ QList QGraphicsScene::items(const QRectF &rect, Qt::ItemSelecti QList QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode) const { Q_D(const QGraphicsScene); - return d->items_helper(polygon, mode, Qt::AscendingOrder); + return d->index->items(polygon, mode, Qt::AscendingOrder); } /*! @@ -2320,7 +1810,74 @@ QList QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemS QList QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode) const { Q_D(const QGraphicsScene); - return d->items_helper(path, mode, Qt::AscendingOrder); + return d->index->items(path, mode, Qt::AscendingOrder); +} + +/*! + Returns all visible items at position \a pos in the scene. + + The default value for \a mode is Qt::IntersectsItemShape; all items whose + exact shape intersects with or is contained by \a path are returned. + + \sa itemAt() +*/ +QList QGraphicsScene::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +{ + Q_D(const QGraphicsScene); + return d->index->items(pos, mode, order, deviceTransform); +} + +/*! + \fn QList QGraphicsScene::items(const QRectF &rectangle, Qt::SortOrder order, const QTransform &deviceTransform) const + + \overload + + Returns all visible items that, depending on \a mode, are either inside or + intersect with the specified \a rectangle. + + The default value for \a mode is Qt::IntersectsItemShape; all items whose + exact shape intersects with or is contained by \a rectangle are returned. + + \sa itemAt() +*/ +QList QGraphicsScene::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +{ + Q_D(const QGraphicsScene); + return d->index->items(rect, mode, order, deviceTransform); +} + +/*! + \overload + + Returns all visible items that, depending on \a mode, are either inside or + intersect with the polygon \a polygon. + + The default value for \a mode is Qt::IntersectsItemShape; all items whose + exact shape intersects with or is contained by \a polygon are returned. + + \sa itemAt() +*/ +QList QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +{ + Q_D(const QGraphicsScene); + return d->index->items(polygon, mode, order, deviceTransform); +} + +/*! + \overload + + Returns all visible items that, depending on \a path, are either inside or + intersect with the path \a path. + + The default value for \a mode is Qt::IntersectsItemShape; all items whose + exact shape intersects with or is contained by \a path are returned. + + \sa itemAt() +*/ +QList QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +{ + Q_D(const QGraphicsScene); + return d->index->items(path, mode, order, deviceTransform); } /*! @@ -2344,10 +1901,11 @@ QList QGraphicsScene::collidingItems(const QGraphicsItem *item, } QList tmp; - foreach (QGraphicsItem *itemInVicinity, d->estimateItemsInRect(item->sceneBoundingRect())) { + foreach (QGraphicsItem *itemInVicinity, d->index->estimateItems(item->sceneBoundingRect(), Qt::AscendingOrder, QTransform())) { if (item != itemInVicinity && item->collidesWithItem(itemInVicinity, mode)) tmp << itemInVicinity; } + //### remove me d->sortItems(&tmp, Qt::AscendingOrder, d->sortCacheEnabled); return tmp; } @@ -2517,8 +2075,8 @@ void QGraphicsScene::clear() Q_D(QGraphicsScene); QList items; // Recursive descent delete - for (int i = 0; i < d->index->indexedItems().size(); ++i) { - if (QGraphicsItem *item = d->index->indexedItems().at(i)) { + for (int i = 0; i < d->index->items().size(); ++i) { + if (QGraphicsItem *item = d->index->items().at(i)) { if (!item->parentItem()) items << item; } @@ -2663,7 +2221,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item) item->d_func()->scene = targetScene; // Add the item in the index - d->index->insertItem(item); + d->index->addItem(item); // Add to list of toplevels if this item is a toplevel. if (!item->d_ptr->parent) @@ -3023,7 +2581,7 @@ void QGraphicsScene::removeItem(QGraphicsItem *item) // Note: This will access item's sceneBoundingRect(), which (as this is // C++) is why we cannot call removeItem() from QGraphicsItem's // destructor. - d->index->removeItem(item, false); + d->index->deleteItem(item); if (item == d->tabFocusFirst) { QGraphicsWidget *widget = static_cast(item); diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h index 6476b8c..5d70087 100644 --- a/src/gui/graphicsview/qgraphicsscene.h +++ b/src/gui/graphicsview/qgraphicsscene.h @@ -156,10 +156,17 @@ public: QRectF itemsBoundingRect() const; QList items() const; + + QList items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + QList items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + QList items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + QList items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + QList items(const QPointF &pos) const; QList items(const QRectF &rect, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; QList items(const QPolygonF &polygon, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; QList items(const QPainterPath &path, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; + QList collidingItems(const QGraphicsItem *item, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; QGraphicsItem *itemAt(const QPointF &pos) const; @@ -291,6 +298,8 @@ private: friend class QGraphicsViewPrivate; friend class QGraphicsWidget; friend class QGraphicsWidgetPrivate; + friend class QGraphicsSceneIndex; + friend class QGraphicsSceneIndexPrivate; friend class QGraphicsSceneBspTreeIndex; }; diff --git a/src/gui/graphicsview/qgraphicsscene_bsp.cpp b/src/gui/graphicsview/qgraphicsscene_bsp.cpp index f8fa450..5c1820f 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp.cpp +++ b/src/gui/graphicsview/qgraphicsscene_bsp.cpp @@ -143,7 +143,7 @@ void QGraphicsSceneBspTree::removeItems(const QSet &items) } } -QList QGraphicsSceneBspTree::items(const QRectF &rect) +QList QGraphicsSceneBspTree::items(const QRectF &rect) const { QList tmp; findVisitor->foundItems = &tmp; @@ -151,7 +151,7 @@ QList QGraphicsSceneBspTree::items(const QRectF &rect) return tmp; } -QList QGraphicsSceneBspTree::items(const QPointF &pos) +QList QGraphicsSceneBspTree::items(const QPointF &pos) const { QList tmp; findVisitor->foundItems = &tmp; @@ -235,7 +235,7 @@ void QGraphicsSceneBspTree::initialize(const QRectF &rect, int depth, int index) } } -void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QPointF &pos, int index) +void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QPointF &pos, int index) const { if (nodes.isEmpty()) return; @@ -245,7 +245,7 @@ void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, con switch (node.type) { case Node::Leaf: { - visitor->visit(&leaves[node.leafIndex]); + visitor->visit(const_cast*>(&leaves[node.leafIndex])); break; } case Node::Vertical: @@ -265,7 +265,7 @@ void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, con } } -void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QRectF &rect, int index) +void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QRectF &rect, int index) const { if (nodes.isEmpty()) return; @@ -275,7 +275,7 @@ void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, con switch (node.type) { case Node::Leaf: { - visitor->visit(&leaves[node.leafIndex]); + visitor->visit(const_cast*>(&leaves[node.leafIndex])); break; } case Node::Vertical: diff --git a/src/gui/graphicsview/qgraphicsscene_bsp_p.h b/src/gui/graphicsview/qgraphicsscene_bsp_p.h index e6ceb78..a13d862 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp_p.h +++ b/src/gui/graphicsview/qgraphicsscene_bsp_p.h @@ -92,8 +92,8 @@ public: void removeItem(QGraphicsItem *item, const QRectF &rect); void removeItems(const QSet &items); - QList items(const QRectF &rect); - QList items(const QPointF &pos); + QList items(const QRectF &rect) const; + QList items(const QPointF &pos) const; int leafCount() const; inline int firstChildIndex(int index) const @@ -106,8 +106,8 @@ public: private: void initialize(const QRectF &rect, int depth, int index); - void climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QPointF &pos, int index = 0); - void climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QRectF &rect, int index = 0); + void climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QPointF &pos, int index = 0) const; + void climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QRectF &rect, int index = 0) const; void findItems(QList *foundItems, const QRectF &rect, int index); void findItems(QList *foundItems, const QPointF &pos, int index); diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 2c0d464..a035159 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -88,8 +88,6 @@ public: QGraphicsScene::ItemIndexMethod indexMethod; int bspTreeDepth; - QList estimateItemsInRect(const QRectF &rect) const; - int lastItemCount; QGraphicsSceneIndex *index; @@ -189,33 +187,6 @@ public: void sendMouseEvent(QGraphicsSceneMouseEvent *mouseEvent); void mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent); QGraphicsWidget *windowForItem(const QGraphicsItem *item) const; - - QList items_helper(const QPointF &pos) const; - QList items_helper(const QRectF &rect, - Qt::ItemSelectionMode mode, - Qt::SortOrder order) const; - QList items_helper(const QPolygonF &rect, - Qt::ItemSelectionMode mode, - Qt::SortOrder order) const; - QList items_helper(const QPainterPath &rect, - Qt::ItemSelectionMode mode, - Qt::SortOrder order) const; - void childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPointF &pos) const; - void childItems_helper(QList *items, - const QGraphicsItem *parent, - const QRectF &rect, - Qt::ItemSelectionMode mode) const; - void childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPolygonF &polygon, - Qt::ItemSelectionMode mode) const; - void childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPainterPath &path, - Qt::ItemSelectionMode mode) const; - bool sortCacheEnabled; bool updatingSortCache; void invalidateSortCache(); @@ -255,6 +226,65 @@ public: mutable QVector freeSceneTransformSlots; }; +static inline bool QRectF_intersects(const QRectF &s, const QRectF &r) +{ + qreal xp = s.left(); + qreal yp = s.top(); + qreal w = s.width(); + qreal h = s.height(); + qreal l1 = xp; + qreal r1 = xp; + if (w < 0) + l1 += w; + else + r1 += w; + + qreal l2 = r.left(); + qreal r2 = r.left(); + if (w < 0) + l2 += r.width(); + else + r2 += r.width(); + + if (l1 >= r2 || l2 >= r1) + return false; + + qreal t1 = yp; + qreal b1 = yp; + if (h < 0) + t1 += h; + else + b1 += h; + + qreal t2 = r.top(); + qreal b2 = r.top(); + if (r.height() < 0) + t2 += r.height(); + else + b2 += r.height(); + + return !(t1 >= b2 || t2 >= b1); +} + +// QRectF::intersects() returns false always if either the source or target +// rectangle's width or height are 0. This works around that problem. +static inline void _q_adjustRect(QRectF *rect) +{ + Q_ASSERT(rect); + if (!rect->width()) + rect->adjust(-0.00001, 0, 0.00001, 0); + if (!rect->height()) + rect->adjust(0, -0.00001, 0, 0.00001); +} + +static inline QRectF adjustedItemBoundingRect(const QGraphicsItem *item) +{ + Q_ASSERT(item); + QRectF boundingRect(item->boundingRect()); + _q_adjustRect(&boundingRect); + return boundingRect; +} + QT_END_NAMESPACE #endif // QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp index ebc167a..1f2b81d 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp @@ -61,18 +61,6 @@ QGraphicsSceneBspTreeIndex::QGraphicsSceneBspTreeIndex(QGraphicsScene *scene) } -void QGraphicsSceneBspTreeIndex::setRect(const QRectF &rect) -{ - m_sceneRect = rect; - resetIndex(); -} - -QRectF QGraphicsSceneBspTreeIndex::rect() const -{ - const_cast(this)->updateIndex(); - return m_sceneRect; -} - void QGraphicsSceneBspTreeIndex::clear() { bsp.clear(); @@ -82,7 +70,7 @@ void QGraphicsSceneBspTreeIndex::clear() unindexedItems.clear(); } -void QGraphicsSceneBspTreeIndex::insertItem(QGraphicsItem *item) +void QGraphicsSceneBspTreeIndex::addItem(QGraphicsItem *item) { // Prevent reusing a recently deleted pointer: purge all removed items // from our lists. @@ -113,42 +101,43 @@ void QGraphicsSceneBspTreeIndex::addToIndex(QGraphicsItem *item) } } -void QGraphicsSceneBspTreeIndex::removeItem(QGraphicsItem *item, bool itemIsAboutToDie) +void QGraphicsSceneBspTreeIndex::removeItem(QGraphicsItem *item) { - if (!itemIsAboutToDie) { - // Note: This will access item's sceneBoundingRect(), which (as this is - // C++) is why we cannot call removeItem() from QGraphicsItem's - // destructor. - removeFromIndex(item); - - // Remove from our item lists. - int index = item->d_func()->index; - if (index != -1) { - freeItemIndexes << index; - m_indexedItems[index] = 0; - } else { - unindexedItems.removeAll(item); - } + // Note: This will access item's sceneBoundingRect(), which (as this is + // C++) is why we cannot call removeItem() from QGraphicsItem's + // destructor. + removeFromIndex(item); + // Remove from our item lists. + int index = item->d_func()->index; + if (index != -1) { + freeItemIndexes << index; + m_indexedItems[index] = 0; } else { - int index = item->d_func()->index; - if (index != -1) { - // Important: The index is useless until purgeRemovedItems() is - // called. - m_indexedItems[index] = (QGraphicsItem *)0; - if (!purgePending) { - purgePending = true; - scene()->update(); - } - removedItems << item; - } else { - // Recently added items are purged immediately. unindexedItems() never - // contains stale items. - unindexedItems.removeAll(item); + unindexedItems.removeAll(item); + } +} + +void QGraphicsSceneBspTreeIndex::deleteItem(QGraphicsItem *item) +{ + int index = item->d_func()->index; + if (index != -1) { + // Important: The index is useless until purgeRemovedItems() is + // called. + m_indexedItems[index] = (QGraphicsItem *)0; + if (!purgePending) { + purgePending = true; scene()->update(); } + removedItems << item; + } else { + // Recently added items are purged immediately. unindexedItems() never + // contains stale items. + unindexedItems.removeAll(item); + scene()->update(); } } + /*! \internal */ @@ -173,41 +162,17 @@ void QGraphicsSceneBspTreeIndex::removeFromIndex(QGraphicsItem *item) startIndexTimer(); } -void QGraphicsSceneBspTreeIndex::updateItem(QGraphicsItem *item) +void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem *item) { // Note: This will access item's sceneBoundingRect(), which (as this is // C++) is why we cannot call removeItem() from QGraphicsItem's // destructor. - removeFromIndex(item); -} - -QList QGraphicsSceneBspTreeIndex::items(const QPointF &point) -{ - purgeRemovedItems(); - QList rectItems = bsp.items(QRectF(point, QSizeF(1, 1))); - // Fill in with any unindexed items - for (int i = 0; i < unindexedItems.size(); ++i) { - if (QGraphicsItem *item = unindexedItems.at(i)) { - if (!item->d_ptr->itemDiscovered && item->d_ptr->visible && !(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { - QRectF boundingRect = item->sceneBoundingRect(); - if (boundingRect.intersects(QRectF(point, QSizeF(1, 1)))) { - item->d_ptr->itemDiscovered = 1; - rectItems << item; - } - } - } - } - - // Reset the discovered state of all discovered items - for (int i = 0; i < rectItems.size(); ++i) - rectItems.at(i)->d_func()->itemDiscovered = 0; - - return rectItems; + removeFromIndex(const_cast(item)); } -QList QGraphicsSceneBspTreeIndex::items(const QRectF &rect) +QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const { - purgeRemovedItems(); + const_cast(this)->purgeRemovedItems(); QList rectItems = bsp.items(rect); // Fill in with any unindexed items for (int i = 0; i < unindexedItems.size(); ++i) { @@ -229,9 +194,9 @@ QList QGraphicsSceneBspTreeIndex::items(const QRectF &rect) return rectItems; } -QList QGraphicsSceneBspTreeIndex::indexedItems() +QList QGraphicsSceneBspTreeIndex::items() const { - purgeRemovedItems(); + const_cast(this)->purgeRemovedItems(); // If freeItemIndexes is empty, we know there are no holes in indexedItems and // unindexedItems. if (freeItemIndexes.isEmpty()) { @@ -250,11 +215,6 @@ QList QGraphicsSceneBspTreeIndex::indexedItems() return itemList; } -void QGraphicsSceneBspTreeIndex::updateIndex() -{ - _q_updateIndex(); -} - int QGraphicsSceneBspTreeIndex::bspDepth() { return bspTreeDepth; @@ -266,6 +226,12 @@ void QGraphicsSceneBspTreeIndex::setBspDepth(int depth) resetIndex(); } +void QGraphicsSceneBspTreeIndex::sceneRectChanged(const QRectF &rect) +{ + m_sceneRect = rect; + resetIndex(); +} + bool QGraphicsSceneBspTreeIndex::event(QEvent *event) { switch (event->type()) { diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 74af910..63cd0e1 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -62,27 +62,23 @@ class Q_AUTOTEST_EXPORT QGraphicsSceneBspTreeIndex : public QGraphicsSceneIndex public: QGraphicsSceneBspTreeIndex(QGraphicsScene *scene = 0); - void setRect(const QRectF &rect); - virtual QRectF rect() const; - void clear(); - void insertItem(QGraphicsItem *item); - void removeItem(QGraphicsItem *item, bool itemIsAboutToDie); - void updateItem(QGraphicsItem *item); - - QList items(const QPointF &point); - QList items(const QRectF &rect); + void addItem(QGraphicsItem *item); + void removeItem(QGraphicsItem *item); + void deleteItem(QGraphicsItem *item); + void prepareBoundingRectChange(const QGraphicsItem *item); - QList indexedItems(); + QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const; - void updateIndex(); + QList items() const; int bspDepth(); void setBspDepth(int depth); protected: bool event(QEvent *event); + void sceneRectChanged(const QRectF &rect); public slots : void _q_updateIndex(); diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 86a2fbb..870a62a 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -40,16 +40,244 @@ ****************************************************************************/ #include "qgraphicssceneindex.h" +#include "qgraphicssceneindex_p.h" #include "qgraphicsscene.h" +#include "qgraphicsitem_p.h" +#include "qgraphicsscene_p.h" #ifndef QT_NO_GRAPHICSVIEW QT_BEGIN_NAMESPACE /*! + Constructs a private scene index. +*/ +QGraphicsSceneIndexPrivate::QGraphicsSceneIndexPrivate(QGraphicsScene *scene) : scene(scene) +{ +} + +void QGraphicsSceneIndexPrivate::childItems_helper(QList *items, + const QGraphicsItem *parent, + const QPointF &pos) const +{ + bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); + if (parentClip && parent->d_ptr->isClippedAway()) + return; + // ### is this needed? + if (parentClip && !parent->boundingRect().contains(pos)) + return; + + QList &children = parent->d_ptr->children; + for (int i = 0; i < children.size(); ++i) { + QGraphicsItem *item = children.at(i); + if (item->d_ptr->hasTransform && !item->transform().isInvertible()) + continue; + + // Skip invisible items and all their children. + if (item->d_ptr->isInvisible()) + continue; + + bool keep = false; + if (!item->d_ptr->isClippedAway()) { + if (item->contains(item->mapFromParent(pos))) { + items->append(item); + keep = true; + } + } + + if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) + // Recurse into children. + childItems_helper(items, item, item->mapFromParent(pos)); + } +} + + +void QGraphicsSceneIndexPrivate::childItems_helper(QList *items, + const QGraphicsItem *parent, + const QRectF &rect, + Qt::ItemSelectionMode mode) const +{ + bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); + if (parentClip && parent->d_ptr->isClippedAway()) + return; + QRectF adjustedRect(rect); + _q_adjustRect(&adjustedRect); + QRectF r = !parentClip ? adjustedRect : adjustedRect.intersected(adjustedItemBoundingRect(parent)); + if (r.isEmpty()) + return; + + QPainterPath path; + QList &children = parent->d_ptr->children; + for (int i = 0; i < children.size(); ++i) { + QGraphicsItem *item = children.at(i); + if (item->d_ptr->hasTransform && !item->transform().isInvertible()) + continue; + + // Skip invisible items and all their children. + if (item->d_ptr->isInvisible()) + continue; + + bool keep = false; + if (!item->d_ptr->isClippedAway()) { + // ### _q_adjustedRect is only needed because QRectF::intersects, + // QRectF::contains and QTransform::map() and friends don't work with + // flat rectangles. + const QRectF br(adjustedItemBoundingRect(item)); + QRectF mbr = item->mapRectToParent(br); + if (mode >= Qt::ContainsItemBoundingRect) { + // Rect intersects/contains item's bounding rect + if ((mode == Qt::IntersectsItemBoundingRect && QRectF_intersects(rect, mbr)) + || (mode == Qt::ContainsItemBoundingRect && rect != mbr && rect.contains(br))) { + items->append(item); + keep = true; + } + } else { + // Rect intersects/contains item's shape + if (QRectF_intersects(rect, mbr)) { + if (path == QPainterPath()) + path.addRect(rect); + if (scene->d_func()->itemCollidesWithPath(item, item->mapFromParent(path), mode)) { + items->append(item); + keep = true; + } + } + } + } + + if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) { + // Recurse into children. + if (!item->d_ptr->hasTransform || item->transform().type() <= QTransform::TxScale) { + // Rect + childItems_helper(items, item, item->mapRectFromParent(rect), mode); + } else { + // Polygon + childItems_helper(items, item, item->mapFromParent(rect), mode); + } + } + } +} + + +void QGraphicsSceneIndexPrivate::childItems_helper(QList *items, + const QGraphicsItem *parent, + const QPolygonF &polygon, + Qt::ItemSelectionMode mode) const +{ + bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); + if (parentClip && parent->d_ptr->isClippedAway()) + return; + QRectF polyRect(polygon.boundingRect()); + _q_adjustRect(&polyRect); + QRectF r = !parentClip ? polyRect : polyRect.intersected(adjustedItemBoundingRect(parent)); + if (r.isEmpty()) + return; + + QPainterPath path; + QList &children = parent->d_ptr->children; + for (int i = 0; i < children.size(); ++i) { + QGraphicsItem *item = children.at(i); + if (item->d_ptr->hasTransform && !item->transform().isInvertible()) + continue; + + // Skip invisible items. + if (item->d_ptr->isInvisible()) + continue; + + bool keep = false; + if (!item->d_ptr->isClippedAway()) { + // ### _q_adjustedRect is only needed because QRectF::intersects, + // QRectF::contains and QTransform::map() and friends don't work with + // flat rectangles. + const QRectF br(adjustedItemBoundingRect(item)); + if (mode >= Qt::ContainsItemBoundingRect) { + // Polygon contains/intersects item's bounding rect + if (path == QPainterPath()) + path.addPolygon(polygon); + if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br))) + || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) { + items->append(item); + keep = true; + } + } else { + // Polygon contains/intersects item's shape + if (QRectF_intersects(polyRect, item->mapRectToParent(br))) { + if (path == QPainterPath()) + path.addPolygon(polygon); + if (scene->d_func()->itemCollidesWithPath(item, item->mapFromParent(path), mode)) { + items->append(item); + keep = true; + } + } + } + } + + if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) { + // Recurse into children that clip children. + childItems_helper(items, item, item->mapFromParent(polygon), mode); + } + } +} + +void QGraphicsSceneIndexPrivate::childItems_helper(QList *items, + const QGraphicsItem *parent, + const QPainterPath &path, + Qt::ItemSelectionMode mode) const +{ + bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); + if (parentClip && parent->d_ptr->isClippedAway()) + return; + QRectF pathRect(path.boundingRect()); + _q_adjustRect(&pathRect); + QRectF r = !parentClip ? pathRect : pathRect.intersected(adjustedItemBoundingRect(parent)); + if (r.isEmpty()) + return; + + QList &children = parent->d_ptr->children; + for (int i = 0; i < children.size(); ++i) { + QGraphicsItem *item = children.at(i); + if (item->d_ptr->hasTransform && !item->transform().isInvertible()) + continue; + + // Skip invisible items. + if (item->d_ptr->isInvisible()) + continue; + + bool keep = false; + if (!item->d_ptr->isClippedAway()) { + // ### _q_adjustedRect is only needed because QRectF::intersects, + // QRectF::contains and QTransform::map() and friends don't work with + // flat rectangles. + const QRectF br(adjustedItemBoundingRect(item)); + if (mode >= Qt::ContainsItemBoundingRect) { + // Polygon contains/intersects item's bounding rect + if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br))) + || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) { + items->append(item); + keep = true; + } + } else { + // Path contains/intersects item's shape + if (QRectF_intersects(pathRect, item->mapRectToParent(br))) { + if (scene->d_func()->itemCollidesWithPath(item, item->mapFromParent(path), mode)) { + items->append(item); + keep = true; + } + } + } + } + + if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) { + // Recurse into children that clip children. + childItems_helper(items, item, item->mapFromParent(path), mode); + } + } +} + +/*! Constructs an abstract scene index. */ -QGraphicsSceneIndex::QGraphicsSceneIndex(QGraphicsScene *scene): QObject(scene), m_scene(scene) +QGraphicsSceneIndex::QGraphicsSceneIndex(QGraphicsScene *scene) +: QObject(*new QGraphicsSceneIndexPrivate(scene)) { } @@ -62,109 +290,325 @@ QGraphicsSceneIndex::~QGraphicsSceneIndex() } /*! - \fn virtual void setRect(const QRectF &rect) = 0 - - This pure virtual function is called when the scene changes its bounding - rectangle. - - \sa rect(), QGraphicsScene::setSceneRect + Returns the scene of this index. */ - +QGraphicsScene* QGraphicsSceneIndex::scene() const +{ + Q_D(const QGraphicsSceneIndex); + return d->scene; +} /*! - \fn virtual QRectF rect() const = 0 + \fn QList items() const = 0 - This pure virtual function returns the bounding rectangle of this - scene index. It could be as large as or larger than the scene - bounding rectangle, depending on the implementation of the - scene index. + This pure virtual function return the list of items that are actually in the index. - \sa setRect(), QGraphicsScene::sceneRect */ -/*! - \fn virtual void clear() = 0 +QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +{ + Q_D(const QGraphicsSceneIndex); + QList items; + + // The index returns a rough estimate of what items are inside the rect. + // Refine it by iterating through all returned items. + QRectF adjustedRect = QRectF(pos, QSize(1,1)); + foreach (QGraphicsItem *item, estimateItems(adjustedRect, order, deviceTransform)) { + // Find the item's scene transform in a clever way. + QTransform x = item->sceneTransform(); + bool keep = false; + + // ### _q_adjustedRect is only needed because QRectF::intersects, + // QRectF::contains and QTransform::map() and friends don't work with + // flat rectangles. + const QRectF br(adjustedItemBoundingRect(item)); + // Rect intersects/contains item's shape + if (QRectF_intersects(adjustedRect, x.mapRect(br))) { + bool ok; + QTransform xinv = x.inverted(&ok); + if (ok) { + if (item->contains(xinv.map(pos))) { + items << item; + keep = true; + } + } + } + + if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { + // Recurse into children that clip children. + bool ok; + QTransform xinv = x.inverted(&ok); + if (ok) + d->childItems_helper(&items, item, xinv.map(pos)); + } + } + + d->scene->d_func()->sortItems(&items, Qt::AscendingOrder, d->scene->d_func()->sortCacheEnabled); + return items; +} - This pure virtual function removes all items in the scene index. -*/ +QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +{ + Q_D(const QGraphicsSceneIndex); + QList items; + + QPainterPath path; + + // The index returns a rough estimate of what items are inside the rect. + // Refine it by iterating through all returned items. + QRectF adjustedRect(rect); + _q_adjustRect(&adjustedRect); + foreach (QGraphicsItem *item, estimateItems(adjustedRect, order, deviceTransform)) { + // Find the item's scene transform in a clever way. + QTransform x = item->sceneTransform(); + bool keep = false; + + // ### _q_adjustedRect is only needed because QRectF::intersects, + // QRectF::contains and QTransform::map() and friends don't work with + // flat rectangles. + const QRectF br(adjustedItemBoundingRect(item)); + if (mode >= Qt::ContainsItemBoundingRect) { + // Rect intersects/contains item's bounding rect + QRectF mbr = x.mapRect(br); + if ((mode == Qt::IntersectsItemBoundingRect && QRectF_intersects(rect, mbr)) + || (mode == Qt::ContainsItemBoundingRect && rect != mbr && rect.contains(mbr))) { + items << item; + keep = true; + } + } else { + // Rect intersects/contains item's shape + if (QRectF_intersects(adjustedRect, x.mapRect(br))) { + bool ok; + QTransform xinv = x.inverted(&ok); + if (ok) { + if (path.isEmpty()) + path.addRect(rect); + if (d->scene->d_func()->itemCollidesWithPath(item, xinv.map(path), mode)) { + items << item; + keep = true; + } + } + } + } + + if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { + // Recurse into children that clip children. + bool ok; + QTransform xinv = x.inverted(&ok); + if (ok) { + if (x.type() <= QTransform::TxScale) { + // Rect + d->childItems_helper(&items, item, xinv.mapRect(rect), mode); + } else { + // Polygon + d->childItems_helper(&items, item, xinv.map(rect), mode); + } + } + } + } + + if (order != Qt::SortOrder(-1)) + d->scene->d_func()->sortItems(&items, order, d->scene->d_func()->sortCacheEnabled); + return items; +} -/*! - \fn virtual void insertItem(QGraphicsItem *item) = 0 +QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +{ + Q_D(const QGraphicsSceneIndex); + QList items; + + QRectF polyRect(polygon.boundingRect()); + _q_adjustRect(&polyRect); + QPainterPath path; + + // The index returns a rough estimate of what items are inside the rect. + // Refine it by iterating through all returned items. + foreach (QGraphicsItem *item, estimateItems(polyRect, order, deviceTransform)) { + // Find the item's scene transform in a clever way. + QTransform x = item->sceneTransform(); + bool keep = false; + + // ### _q_adjustedRect is only needed because QRectF::intersects, + // QRectF::contains and QTransform::map() and friends don't work with + // flat rectangles. + const QRectF br(adjustedItemBoundingRect(item)); + if (mode >= Qt::ContainsItemBoundingRect) { + // Polygon contains/intersects item's bounding rect + if (path == QPainterPath()) + path.addPolygon(polygon); + if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(x.mapRect(br))) + || (mode == Qt::ContainsItemBoundingRect && path.contains(x.mapRect(br)))) { + items << item; + keep = true; + } + } else { + // Polygon contains/intersects item's shape + if (QRectF_intersects(polyRect, x.mapRect(br))) { + bool ok; + QTransform xinv = x.inverted(&ok); + if (ok) { + if (path == QPainterPath()) + path.addPolygon(polygon); + if (d->scene->d_func()->itemCollidesWithPath(item, xinv.map(path), mode)) { + items << item; + keep = true; + } + } + } + } + + if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { + // Recurse into children that clip children. + bool ok; + QTransform xinv = x.inverted(&ok); + if (ok) + d->childItems_helper(&items, item, xinv.map(polygon), mode); + } + } + + if (order != Qt::SortOrder(-1)) + d->scene->d_func()->sortItems(&items, order, d->scene->d_func()->sortCacheEnabled); + return items; +} +QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +{ + Q_D(const QGraphicsSceneIndex); + QList items; + QRectF pathRect(path.controlPointRect()); + _q_adjustRect(&pathRect); + + // The index returns a rough estimate of what items are inside the rect. + // Refine it by iterating through all returned items. + foreach (QGraphicsItem *item, estimateItems(pathRect, order, deviceTransform)) { + // Find the item's scene transform in a clever way. + QTransform x = item->sceneTransform(); + bool keep = false; + + // ### _q_adjustedRect is only needed because QRectF::intersects, + // QRectF::contains and QTransform::map() and friends don't work with + // flat rectangles. + const QRectF br(adjustedItemBoundingRect(item)); + if (mode >= Qt::ContainsItemBoundingRect) { + // Path contains/intersects item's bounding rect + if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(x.mapRect(br))) + || (mode == Qt::ContainsItemBoundingRect && path.contains(x.mapRect(br)))) { + items << item; + keep = true; + } + } else { + // Path contains/intersects item's shape + if (QRectF_intersects(pathRect, x.mapRect(br))) { + bool ok; + QTransform xinv = x.inverted(&ok); + if (ok) { + if (d->scene->d_func()->itemCollidesWithPath(item, xinv.map(path), mode)) { + items << item; + keep = true; + } + } + } + } + + if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { + bool ok; + QTransform xinv = x.inverted(&ok); + if (ok) + d->childItems_helper(&items, item, xinv.map(path), mode); + } + } + + if (order != Qt::SortOrder(-1)) + d->scene->d_func()->sortItems(&items, order, d->scene->d_func()->sortCacheEnabled); + return items; +} - This pure virtual function inserts an item to the scene index. +/*! + This pure virtual function return an estimation of items at position \a pos. - \sa removeItem(), updateItem(), insertItems() */ +QList QGraphicsSceneIndex::estimateItems(const QPointF &point, Qt::SortOrder order, const QTransform &deviceTransform) const +{ + return estimateItems(QRectF(point, QSize(1,1)), order, deviceTransform); +} /*! - \fn virtual void removeItem(QGraphicsItem *item) = 0 + \fn virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const = 0 - This pure virtual function removes an item to the scene index. + This pure virtual function return an estimation of items in the \a rect. - \sa insertItem(), updateItem(), removeItems() */ + /*! - Returns the scene of this index. + This virtual function removes all items in the scene index. */ -QGraphicsScene* QGraphicsSceneIndex::scene() const +void QGraphicsSceneIndex::clear() { - return m_scene; + for (int i = 0 ; i < items().size(); ++i) + removeItem(items().at(i)); } /*! - Updates an item when its geometry has changed. + \fn virtual void addItem(QGraphicsItem *item) = 0 - The default implemention will remove the item from the index - and then insert it again. + This pure virtual function inserts an item to the scene index. - \sa insertItem(), removeItem(), updateItems() + \sa removeItem(), deleteItem() */ -void QGraphicsSceneIndex::updateItem(QGraphicsItem *item) -{ - removeItem(item,false); - insertItem(item); -} /*! - Inserts a list of items to the index. + \fn virtual void removeItem(QGraphicsItem *item) = 0 - The default implemention will insert the items one by one. + This pure virtual function removes an item to the scene index. - \sa insertItem(), removeItems(), updateItems() + \sa addItem(), deleteItem() */ -void QGraphicsSceneIndex::insertItems(const QList &items) + +/*! + This method is called when an item has been deleted. + The default implementation call removeItem. Be carefull, + if your implementation of removeItem use pure virtual method + of QGraphicsItem like boundingRect(), then you should reimplement + this method. + + \sa addItem(), removeItem() +*/ +void QGraphicsSceneIndex::deleteItem(QGraphicsItem *item) { - foreach (QGraphicsItem *item, items) - insertItem(item); + removeItem(item); } /*! - Removes a list of items from the index. + This virtual function is called by QGraphicsItem to notify the index + that some part of the item's state changes. By reimplementing this + function, your can react to a change, and in some cases, (depending on \a + change,) adjustments in the index can be made. - The default implemention will remove the items one by one. + \a change is the parameter of the item that is changing. \a value is the + value that changed; the type of the value depends on \a change. - \sa removeItem(), removeItems(), updateItems() + The default implementation does nothing. + + \sa GraphicsItemChange */ -void QGraphicsSceneIndex::removeItems(const QList &items, bool itemsAreAboutToDie) +void QGraphicsSceneIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value) { - foreach (QGraphicsItem *item, items) - removeItem(item,itemsAreAboutToDie); } /*! - Update a list of items which have changed the geometry. - - The default implemention will update the items one by one. + Notify the index for a geometry change of an item. - \sa updateItem(), insertItems(), removeItems() + \sa QGraphicsItem::prepareGeometryChange */ -void QGraphicsSceneIndex::updateItems(const QList &items) +void QGraphicsSceneIndex::prepareBoundingRectChange(const QGraphicsItem *item) { - foreach (QGraphicsItem *item, items) - updateItem(item); } -void QGraphicsSceneIndex::updateIndex() +/*! + This virtual function is called when the scene changes its bounding + rectangle. + \sa QGraphicsScene::sceneRect +*/ +void QGraphicsSceneIndex::sceneRectChanged(const QRectF &rect) { } diff --git a/src/gui/graphicsview/qgraphicssceneindex.h b/src/gui/graphicsview/qgraphicssceneindex.h index a782323..da3096e 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.h +++ b/src/gui/graphicsview/qgraphicssceneindex.h @@ -44,6 +44,8 @@ #include #include +#include +#include QT_BEGIN_HEADER @@ -53,7 +55,7 @@ QT_MODULE(Gui) #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW -class QGraphicsItem; +class QGraphicsSceneIndexPrivate; class QGraphicsScene; class QRectF; class QPointF; @@ -67,29 +69,31 @@ public: QGraphicsSceneIndex(QGraphicsScene *scene = 0); virtual ~QGraphicsSceneIndex(); - QGraphicsScene* scene() const; - - virtual void setRect(const QRectF &rect) = 0; - virtual QRectF rect() const = 0; - virtual void clear() = 0; - - virtual void insertItem(QGraphicsItem *item) = 0; - virtual void removeItem(QGraphicsItem *items, bool itemIsAboutToDie) = 0; - virtual void updateItem(QGraphicsItem *item); - - virtual void insertItems(const QList &items); - virtual void removeItems(const QList &items, bool itemsAreAboutToDie); - virtual void updateItems(const QList &items); - - virtual QList items(const QPointF &point) = 0; - virtual QList items(const QRectF &rect) = 0; - - virtual QList indexedItems() = 0; - - virtual void updateIndex(); - + QGraphicsScene *scene() const; + + virtual QList items() const = 0; + virtual QList items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + virtual QList items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + virtual QList items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + virtual QList items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + virtual QList estimateItems(const QPointF &point, Qt::SortOrder order, const QTransform &deviceTransform) const; + virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const = 0; + +protected: + virtual void clear(); + virtual void addItem(QGraphicsItem *item) = 0; + virtual void removeItem(QGraphicsItem *item) = 0; + virtual void deleteItem(QGraphicsItem *item); + + virtual void itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value); + virtual void prepareBoundingRectChange(const QGraphicsItem *item); + virtual void sceneRectChanged(const QRectF &rect); + + friend class QGraphicsScene; + friend class QGraphicsScenePrivate; + friend class QGraphicsItem; private: - QGraphicsScene *m_scene; + Q_DECLARE_PRIVATE(QGraphicsSceneIndex) }; #endif // QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h new file mode 100644 index 0000000..f2cdca3 --- /dev/null +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui 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 qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGRAPHICSSCENEINDEX_P_H +#define QGRAPHICSSCENEINDEX_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + +#include "qgraphicssceneindex.h" + +#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW + +#include + +QT_BEGIN_NAMESPACE + +class QGraphicsScene; + +class QGraphicsSceneIndexPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QGraphicsSceneIndex) +public: + QGraphicsSceneIndexPrivate(QGraphicsScene *scene); + + + void childItems_helper(QList *items, + const QGraphicsItem *parent, + const QPointF &pos) const; + void childItems_helper(QList *items, + const QGraphicsItem *parent, + const QRectF &rect, + Qt::ItemSelectionMode mode) const; + void childItems_helper(QList *items, + const QGraphicsItem *parent, + const QPolygonF &polygon, + Qt::ItemSelectionMode mode) const; + void childItems_helper(QList *items, + const QGraphicsItem *parent, + const QPainterPath &path, + Qt::ItemSelectionMode mode) const; + + QGraphicsScene *scene; +}; + +QT_END_NAMESPACE + +#endif // QGRAPHICSSCENEINDEX_P_H + +#endif diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h index 30948d9..dc45a17 100644 --- a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h @@ -89,24 +89,15 @@ public: m_items.clear(); } - virtual void insertItem(QGraphicsItem *item) { + virtual void addItem(QGraphicsItem *item) { m_items << item; } - virtual void removeItem(QGraphicsItem *item, bool itemIsAboutToDie) { - Q_UNUSED(itemIsAboutToDie); + virtual void removeItem(QGraphicsItem *item) { m_items.removeAll(item); } - virtual QList items(const QPointF &point) { - QList result; - foreach (QGraphicsItem *item, m_items) - if (item->sceneBoundingRect().contains(point)) - result << item; - return result; - } - - virtual QList items(const QRectF &rect) { + virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const { QList result; foreach (QGraphicsItem *item, m_items) if (item->sceneBoundingRect().intersects(rect)) @@ -114,7 +105,7 @@ public: return result; } - QList indexedItems() { + QList items() const { return m_items; } }; diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 10b837a..91f97a1 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -791,19 +791,6 @@ QRegion QGraphicsViewPrivate::mapToViewRegion(const QGraphicsItem *item, const Q return item->boundingRegion(itv) & itv.mapRect(rect).toAlignedRect(); } -// QRectF::intersects() returns false always if either the source or target -// rectangle's width or height are 0. This works around that problem. -static inline QRectF adjustedItemBoundingRect(const QGraphicsItem *item) -{ - Q_ASSERT(item); - QRectF boundingRect(item->boundingRect()); - if (!boundingRect.width()) - boundingRect.adjust(-0.00001, 0, 0.00001, 0); - if (!boundingRect.height()) - boundingRect.adjust(0, -0.00001, 0, 0.00001); - return boundingRect; -} - /*! \internal */ @@ -1094,7 +1081,7 @@ QList QGraphicsViewPrivate::findItems(const QRegion &exposedReg bool simpleRectLookup = (scene->d_func()->largestUntransformableItem.isNull() && exposedRegion.numRects() == 1 && matrix.type() <= QTransform::TxScale); if (simpleRectLookup) { - return scene->d_func()->items_helper(exposedRegionSceneBounds, + return scene->d_func()->index->items(exposedRegionSceneBounds, Qt::IntersectsItemBoundingRect, Qt::DescendingOrder); } @@ -1109,7 +1096,7 @@ QList QGraphicsViewPrivate::findItems(const QRegion &exposedReg const QPainterPath exposedPath(qt_regionToPath(adjustedRegion)); if (scene->d_func()->largestUntransformableItem.isNull()) { const QPainterPath exposedScenePath(q->mapToScene(exposedPath)); - return scene->d_func()->items_helper(exposedScenePath, + return scene->d_func()->index->items(exposedScenePath, Qt::IntersectsItemBoundingRect, Qt::DescendingOrder); } @@ -2143,7 +2130,7 @@ QList QGraphicsViewPrivate::itemsInArea(const QPainterPath &pat // First build a (potentially large) list of all items in the vicinity // that might be untransformable. - QList allCandidates = scene->d_func()->estimateItemsInRect(adjustedRect); + QList allCandidates = scene->d_func()->index->estimateItems(adjustedRect, order, q->transform()); // Then find the minimal list of items that are inside \a path, and // convert it to a set. @@ -2154,6 +2141,8 @@ QList QGraphicsViewPrivate::itemsInArea(const QPainterPath &pat QList result; + //### this will disapear + // Run through all candidates and keep all items that are in candSet, or // are untransformable and collide with \a path. ### We can improve this // algorithm. -- cgit v0.12 From 32155ed07a6f8b8c831db6ba219395b4825fa9fd Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Fri, 29 May 2009 15:15:58 +0200 Subject: Fix a wrong parenting. --- src/gui/graphicsview/qgraphicssceneindex.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 870a62a..36da295 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -277,7 +277,7 @@ void QGraphicsSceneIndexPrivate::childItems_helper(QList *items Constructs an abstract scene index. */ QGraphicsSceneIndex::QGraphicsSceneIndex(QGraphicsScene *scene) -: QObject(*new QGraphicsSceneIndexPrivate(scene)) +: QObject(*new QGraphicsSceneIndexPrivate(scene), scene) { } -- cgit v0.12 From 53187fabdbfb8a513e735fdd034e1a9fbbccc9cd Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Fri, 29 May 2009 17:18:38 +0200 Subject: Add an API to know the indexed rect of the index. Usefull for the POV of the scene and let the BSP update its internal structure before the next event loop reentrancy. --- src/gui/graphicsview/qgraphicsscene.cpp | 2 +- src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp | 7 +++++++ src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h | 1 + src/gui/graphicsview/qgraphicssceneindex.cpp | 10 ++++++++++ src/gui/graphicsview/qgraphicssceneindex.h | 2 ++ 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 9b6d40b..479a548 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1422,7 +1422,7 @@ QGraphicsScene::~QGraphicsScene() QRectF QGraphicsScene::sceneRect() const { Q_D(const QGraphicsScene); - return d->hasSceneRect ? d->sceneRect : d->growingItemsBoundingRect; + return d->index->indexedRect(); } void QGraphicsScene::setSceneRect(const QRectF &rect) { diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp index 1f2b81d..8a26447 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp @@ -61,6 +61,13 @@ QGraphicsSceneBspTreeIndex::QGraphicsSceneBspTreeIndex(QGraphicsScene *scene) } + +QRectF QGraphicsSceneBspTreeIndex::indexedRect() +{ + _q_updateIndex(); + return scene()->d_func()->hasSceneRect ? scene()->d_func()->sceneRect : scene()->d_func()->growingItemsBoundingRect; +} + void QGraphicsSceneBspTreeIndex::clear() { bsp.clear(); diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 63cd0e1..7a6ea0b 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -61,6 +61,7 @@ class Q_AUTOTEST_EXPORT QGraphicsSceneBspTreeIndex : public QGraphicsSceneIndex Q_OBJECT public: QGraphicsSceneBspTreeIndex(QGraphicsScene *scene = 0); + QRectF indexedRect(); void clear(); diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 36da295..fe3a68a 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -297,6 +297,16 @@ QGraphicsScene* QGraphicsSceneIndex::scene() const Q_D(const QGraphicsSceneIndex); return d->scene; } + +/*! + Returns the indexed area for the index +*/ +QRectF QGraphicsSceneIndex::indexedRect() +{ + Q_D(const QGraphicsSceneIndex); + return d->scene->d_func()->sceneRect; +} + /*! \fn QList items() const = 0 diff --git a/src/gui/graphicsview/qgraphicssceneindex.h b/src/gui/graphicsview/qgraphicssceneindex.h index da3096e..11d9aae 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.h +++ b/src/gui/graphicsview/qgraphicssceneindex.h @@ -71,6 +71,8 @@ public: QGraphicsScene *scene() const; + virtual QRectF indexedRect(); + virtual QList items() const = 0; virtual QList items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; virtual QList items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; -- cgit v0.12 From 4785ed9b76104c272476f62780dde086e21b20ce Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Sun, 31 May 2009 13:28:18 +0200 Subject: Add conformance section to qtxmlpatterns doc and extended api docs --- doc/src/qtxmlpatterns.qdoc | 21 +++++++++++++++++++++ src/xmlpatterns/api/qxmlschemavalidator.cpp | 8 +++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/doc/src/qtxmlpatterns.qdoc b/doc/src/qtxmlpatterns.qdoc index cb260fc..a48d713 100644 --- a/doc/src/qtxmlpatterns.qdoc +++ b/doc/src/qtxmlpatterns.qdoc @@ -839,6 +839,27 @@ with the \c fn:id() function. See \l{http://www.w3.org/TR/xml-id/}{xml:id Version 1.0} for details. + \section2 XML Schema 1.0 + + The QtXmlPatterns implementation of XML Schema validation supports + the schema specification version 1.0 in large parts. Known problems + of the implementation and areas where conformancy may be questionable + are: + + \list + \o Large \c minOccurs or \c maxOccurs values or deeply nested ones + require huge amount of memory which might cause the system to freeze. + Such a schema should be rewritten to use \c unbounded as value instead + of large numbers. This restriction will hopefully be fixed in a later release. + \o Comparison of really small or large floating point values might lead to + wrong results in some cases. However such numbers should not be relevant + for day-to-day usage. + \o Regular expression support is currently not conformant but follows + Qt's QRegExp standard syntax. + \o Identity constraint checks can not use the values of default or fixed + attribute definitions. + \endlist + \section2 Resource Loading When QtXmlPatterns loads an XML resource, e.g., using the diff --git a/src/xmlpatterns/api/qxmlschemavalidator.cpp b/src/xmlpatterns/api/qxmlschemavalidator.cpp index b72b1ef..dc8e55d 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator.cpp +++ b/src/xmlpatterns/api/qxmlschemavalidator.cpp @@ -69,7 +69,7 @@ /*! Constructs a schema validator. The schema used for validation must be referenced in the XML instance document - via the xsi:schemaLocation attribute. + via the \c xsi:schemaLocation or \c xsi:noNamespaceSchemaLocation attribute. */ QXmlSchemaValidator::QXmlSchemaValidator() : d(new QXmlSchemaValidatorPrivate(QXmlSchema())) @@ -78,6 +78,9 @@ QXmlSchemaValidator::QXmlSchemaValidator() /*! Constructs a schema validator that will use \a schema for validation. + If an empty \l {QXmlSchema} schema is passed to the validator, the schema used + for validation must be referenced in the XML instance document + via the \c xsi:schemaLocation or \c xsi:noNamespaceSchemaLocation attribute. */ QXmlSchemaValidator::QXmlSchemaValidator(const QXmlSchema &schema) : d(new QXmlSchemaValidatorPrivate(schema)) @@ -94,6 +97,9 @@ QXmlSchemaValidator::~QXmlSchemaValidator() /*! Sets the \a schema that shall be used for further validation. + If the schema is empty, the schema used for validation must be referenced + in the XML instance document via the \c xsi:schemaLocation or + \c xsi:noNamespaceSchemaLocation attribute. */ void QXmlSchemaValidator::setSchema(const QXmlSchema &schema) { -- cgit v0.12 From 427c4d6b0a8b3004c86facd382de33c171c0458b Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 2 Jun 2009 17:45:27 +0200 Subject: Fix all auto-tests regressions. --- src/gui/graphicsview/qgraphicsscene.cpp | 15 +++++++++------ src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp | 11 ++++++----- src/gui/graphicsview/qgraphicssceneindex.cpp | 2 +- tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp | 3 +++ .../auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp | 4 ++-- 5 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 479a548..0172a23 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -453,7 +453,9 @@ void QGraphicsScenePrivate::_q_removeItemLater(QGraphicsItem *item) // chain. item->clearFocus(); - //We ask for a removing in the index + // Note: This will access item's sceneBoundingRect(), which (as this is + // C++) is why we cannot call removeItem() from QGraphicsItem's + // destructor. this->index->deleteItem(item); // Reset the mouse grabber and focus item data. @@ -1198,7 +1200,10 @@ void QGraphicsScenePrivate::climbTree(QGraphicsItem *item, int *stackingOrder) void QGraphicsScenePrivate::_q_updateSortCache() { //### FIXME - //index->updateIndex(); + QGraphicsSceneBspTreeIndex *tree = qobject_cast(index); + if (tree) { + tree->_q_updateIndex(); + } if (!sortCacheEnabled || !updatingSortCache) return; @@ -2578,10 +2583,8 @@ void QGraphicsScene::removeItem(QGraphicsItem *item) // Clear its background item->update(); - // Note: This will access item's sceneBoundingRect(), which (as this is - // C++) is why we cannot call removeItem() from QGraphicsItem's - // destructor. - d->index->deleteItem(item); + // Remove it from the index properly + d->index->removeItem(item); if (item == d->tabFocusFirst) { QGraphicsWidget *widget = static_cast(item); diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp index 8a26447..f8f1f56 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp @@ -61,11 +61,10 @@ QGraphicsSceneBspTreeIndex::QGraphicsSceneBspTreeIndex(QGraphicsScene *scene) } - QRectF QGraphicsSceneBspTreeIndex::indexedRect() { _q_updateIndex(); - return scene()->d_func()->hasSceneRect ? scene()->d_func()->sceneRect : scene()->d_func()->growingItemsBoundingRect; + return scene()->d_func()->hasSceneRect ? scene()->d_func()->sceneRect : scene()->d_func()->growingItemsBoundingRect; } void QGraphicsSceneBspTreeIndex::clear() @@ -162,7 +161,7 @@ void QGraphicsSceneBspTreeIndex::removeFromIndex(QGraphicsItem *item) item->d_func()->index = -1; unindexedItems << item; - //prepareGeometryChange will call updateItem + //prepareGeometryChange will call prepareBoundingRectChange foreach (QGraphicsItem *child, item->children()) child->prepareGeometryChange(); } @@ -180,13 +179,15 @@ void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem * QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const { const_cast(this)->purgeRemovedItems(); + scene()->d_func()->_q_updateSortCache(); + QList rectItems = bsp.items(rect); // Fill in with any unindexed items for (int i = 0; i < unindexedItems.size(); ++i) { if (QGraphicsItem *item = unindexedItems.at(i)) { if (!item->d_ptr->itemDiscovered && item->d_ptr->visible && !(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { QRectF boundingRect = item->sceneBoundingRect(); - if (boundingRect.intersects(rect)) { + if (QRectF_intersects(boundingRect, rect)) { item->d_ptr->itemDiscovered = 1; rectItems << item; } @@ -328,7 +329,7 @@ void QGraphicsSceneBspTreeIndex::_q_updateIndex() if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) continue; - bsp.insertItem(item,rect); + bsp.insertItem(item, rect); // If the item ignores view transformations, update our // largest-item-counter to ensure that the view can accurately diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index fe3a68a..d0d6081 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -352,7 +352,7 @@ QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSe } } - d->scene->d_func()->sortItems(&items, Qt::AscendingOrder, d->scene->d_func()->sortCacheEnabled); + d->scene->d_func()->sortItems(&items, order, d->scene->d_func()->sortCacheEnabled); return items; } diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index 0c5ebf6..eb117ab 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -395,6 +395,9 @@ void tst_QGraphicsScene::items() QGraphicsLineItem *l2 = scene.addLine(0, -5, 0, 5); QVERIFY(!l1->sceneBoundingRect().intersects(l2->sceneBoundingRect())); QVERIFY(!l2->sceneBoundingRect().intersects(l1->sceneBoundingRect())); + QList items; + items<setRect(QRectF(0, 0, 2000, 2000)); - QCOMPARE(index->rect(), QRectF(0, 0, 2000, 2000)); + scene->setSceneRect(QRectF(0, 0, 2000, 2000)); + QCOMPARE(index->indexedRect(), QRectF(0, 0, 2000, 2000)); } void tst_QGraphicsSceneIndex::customIndex_data() -- cgit v0.12 From f7741b78c90abcb272345810d55e446a7f390032 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Wed, 3 Jun 2009 17:40:41 +0200 Subject: Fixed typo in apidocs and extended example code --- doc/src/snippets/qxmlschemavalidator/main.cpp | 23 +++++++++++++++++++++++ src/xmlpatterns/api/qxmlschema.cpp | 5 +++++ src/xmlpatterns/api/qxmlschemavalidator.cpp | 12 +++++++++--- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/doc/src/snippets/qxmlschemavalidator/main.cpp b/doc/src/snippets/qxmlschemavalidator/main.cpp index 13cd45f..0803380 100644 --- a/doc/src/snippets/qxmlschemavalidator/main.cpp +++ b/doc/src/snippets/qxmlschemavalidator/main.cpp @@ -48,6 +48,7 @@ class SchemaValidator void validateFromUrl() const; void validateFromFile() const; void validateFromData() const; + void validateComplete() const; private: QXmlSchema getSchema() const; @@ -123,6 +124,27 @@ QXmlSchema SchemaValidator::getSchema() const return schema; } +void SchemaValidator::validateComplete() const +{ +//! [3] + QUrl schemaUrl("file:///home/user/schema.xsd"); + + QXmlSchema schema; + schema.load(schemaUrl); + + if (schema.isValid()) { + QFile file("test.xml"); + file.open(QIODevice::ReadOnly); + + QXmlSchemaValidator validator(schema); + if (validator.validate(&file, QUrl::fromLocalFile(file.fileName()))) + qDebug() << "instance document is valid"; + else + qDebug() << "instance document is invalid"; + } +//! [3] +} + int main(int argc, char **argv) { QCoreApplication app(argc, argv); @@ -132,6 +154,7 @@ int main(int argc, char **argv) validator.validateFromUrl(); validator.validateFromFile(); validator.validateFromData(); + validator.validateComplete(); return 0; } diff --git a/src/xmlpatterns/api/qxmlschema.cpp b/src/xmlpatterns/api/qxmlschema.cpp index ec370ca..c6dc9b2 100644 --- a/src/xmlpatterns/api/qxmlschema.cpp +++ b/src/xmlpatterns/api/qxmlschema.cpp @@ -58,6 +58,11 @@ that can be used further for validation of XML instance documents via \l{QXmlSchemaValidator}. + The following example shows how to load a XML Schema file from the network + and test whether it is a valid schema document: + + \snippet doc/src/snippets/qxmlschema/main.cpp 0 + \sa QXmlSchemaValidator, {xmlpatterns/schema}{XML Schema Validation Example} */ diff --git a/src/xmlpatterns/api/qxmlschemavalidator.cpp b/src/xmlpatterns/api/qxmlschemavalidator.cpp index dc8e55d..d5596c5 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator.cpp +++ b/src/xmlpatterns/api/qxmlschemavalidator.cpp @@ -63,6 +63,12 @@ The QXmlSchemaValidator class loads, parses an XML instance document and validates it against a W3C XML Schema that has been compiled with \l{QXmlSchema}. + The following example shows how to load a XML Schema from a local + file, check whether it is a valid schema document and use it for validation + of an XML instance document: + + \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 3 + \sa QXmlSchema, {xmlpatterns/schema}{XML Schema Validation Example} */ @@ -110,7 +116,7 @@ void QXmlSchemaValidator::setSchema(const QXmlSchema &schema) Validates the XML instance document read from \a data with the given \a documentUri against the schema. - Returns \c true if the XML instance document is valid according the + Returns \c true if the XML instance document is valid according to the schema, \c false otherwise. Example: @@ -130,7 +136,7 @@ bool QXmlSchemaValidator::validate(const QByteArray &data, const QUrl &documentU /*! Validates the XML instance document read from \a source against the schema. - Returns \c true if the XML instance document is valid according the + Returns \c true if the XML instance document is valid according to the schema, \c false otherwise. Example: @@ -155,7 +161,7 @@ bool QXmlSchemaValidator::validate(const QUrl &source) const Validates the XML instance document read from \a source with the given \a documentUri against the schema. - Returns \c true if the XML instance document is valid according the + Returns \c true if the XML instance document is valid according to the schema, \c false otherwise. Example: -- cgit v0.12 From ffd6bc0351c96c8a3828bd7376f2b6bda317cd71 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 3 Jun 2009 18:23:20 +0200 Subject: Remove the sorting cache from the QGraphicsScene and move it to the BSP. Now the QGraphicsScene has no idea how works the index. So we can improve it separatly, add new ones and benchmarks existing ones. --- src/gui/graphicsview/graphicsview.pri | 1 + src/gui/graphicsview/qgraphicsitem.cpp | 22 +- src/gui/graphicsview/qgraphicsitem.h | 1 + src/gui/graphicsview/qgraphicsscene.cpp | 200 +------ src/gui/graphicsview/qgraphicsscene.h | 2 +- src/gui/graphicsview/qgraphicsscene_p.h | 19 - .../graphicsview/qgraphicsscenebsptreeindex_p.cpp | 614 ++++++++++++++------- .../graphicsview/qgraphicsscenebsptreeindex_p.h | 51 +- .../graphicsview/qgraphicsscenebsptreeindex_p_p.h | 140 +++++ src/gui/graphicsview/qgraphicssceneindex.cpp | 28 +- src/gui/graphicsview/qgraphicssceneindex.h | 9 +- src/gui/graphicsview/qgraphicssceneindex_p.h | 3 +- src/gui/graphicsview/qgraphicsscenelinearindex_p.h | 2 +- src/gui/graphicsview/qgraphicsview.cpp | 11 +- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 5 + tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp | 5 +- tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 8 +- 17 files changed, 642 insertions(+), 479 deletions(-) create mode 100644 src/gui/graphicsview/qgraphicsscenebsptreeindex_p_p.h diff --git a/src/gui/graphicsview/graphicsview.pri b/src/gui/graphicsview/graphicsview.pri index cc57892..a4a79e8 100644 --- a/src/gui/graphicsview/graphicsview.pri +++ b/src/gui/graphicsview/graphicsview.pri @@ -7,6 +7,7 @@ HEADERS += \ graphicsview/qgraphicsscene.h \ graphicsview/qgraphicsscene_p.h \ graphicsview/qgraphicsscenebsptreeindex_p.h \ + graphicsview/qgraphicsscenebsptreeindex_p_p.h \ graphicsview/qgraphicsscene_bsp_p.h \ graphicsview/qgraphicsscenelinearindex_p.h \ graphicsview/qgraphicssceneindex.h \ diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index fc5895c..ee32724 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -537,6 +537,7 @@ #include "qgraphicsview.h" #include "qgraphicswidget.h" #include "qgraphicsproxywidget.h" +#include "qgraphicsscenebsptreeindex_p_p.h" #include #include #include @@ -888,12 +889,6 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, bool de } } - if (scene) { - // Invalidate any sort caching; arrival of a new item means we need to - // resort. - scene->d_func()->invalidateSortCache(); - } - // Resolve opacity. updateEffectiveOpacity(); @@ -905,6 +900,11 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, bool de // Deliver post-change notification q->itemChange(QGraphicsItem::ItemParentHasChanged, newParentVariant); + + if (scene) { + // Deliver the change to the index + scene->d_func()->index->itemChanged(q, QGraphicsItem::ItemParentHasChanged, newParentVariant); + } } /*! @@ -3528,11 +3528,9 @@ void QGraphicsItem::setZValue(qreal z) d_ptr->z = newZ; d_ptr->fullUpdateHelper(); - if (d_ptr->scene) { - // Invalidate any sort caching; arrival of a new item means we need to - // resort. - d_ptr->scene->d_func()->invalidateSortCache(); - } + //Z Value has changed, we have to notify the index. + if (d_ptr->scene) + d_ptr->scene->d_func()->index->itemChanged(this, ItemZValueChange, z); itemChange(ItemZValueHasChanged, newZVariant); } @@ -3991,7 +3989,7 @@ bool QGraphicsItem::isObscuredBy(const QGraphicsItem *item) const { if (!item) return false; - return QGraphicsScenePrivate::closestItemFirst_withoutCache(item, this) + return QGraphicsSceneBspTreeIndexPrivate::closestItemFirst_withoutCache(item, this) && qt_QGraphicsItem_isObscured(this, item, boundingRect()); } diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index e244c13..7874033 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -435,6 +435,7 @@ private: friend class QGraphicsSceneIndex; friend class QGraphicsSceneIndexPrivate; friend class QGraphicsSceneBspTreeIndex; + friend class QGraphicsSceneBspTreeIndexPrivate; friend class ::tst_QGraphicsItem; friend bool qt_closestLeaf(const QGraphicsItem *, const QGraphicsItem *); friend bool qt_closestItemFirst(const QGraphicsItem *, const QGraphicsItem *); diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 0172a23..4734e74 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -218,6 +218,7 @@ #include "qgraphicswidget.h" #include "qgraphicswidget_p.h" #include "qgraphicssceneindex.h" +#include "qgraphicsscenebsptreeindex_p_p.h" #include #include @@ -291,8 +292,6 @@ QGraphicsScenePrivate::QGraphicsScenePrivate() allItemsIgnoreHoverEvents(true), allItemsUseDefaultCursor(true), painterStateProtection(true), - sortCacheEnabled(false), - updatingSortCache(false), style(0) { } @@ -1073,175 +1072,6 @@ QGraphicsWidget *QGraphicsScenePrivate::windowForItem(const QGraphicsItem *item) return 0; } -void QGraphicsScenePrivate::invalidateSortCache() -{ - Q_Q(QGraphicsScene); - if (!sortCacheEnabled || updatingSortCache) - return; - - updatingSortCache = true; - QMetaObject::invokeMethod(q, "_q_updateSortCache", Qt::QueuedConnection); -} - -/*! - \internal - - Should not be exported, but we can't change that now. - ### Qt 5: Remove symbol / make static -*/ -inline bool qt_closestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2) -{ - // Return true if sibling item1 is on top of item2. - const QGraphicsItemPrivate *d1 = item1->d_ptr; - const QGraphicsItemPrivate *d2 = item2->d_ptr; - bool f1 = d1->flags & QGraphicsItem::ItemStacksBehindParent; - bool f2 = d2->flags & QGraphicsItem::ItemStacksBehindParent; - if (f1 != f2) return f2; - qreal z1 = d1->z; - qreal z2 = d2->z; - return z1 != z2 ? z1 > z2 : d1->siblingIndex > d2->siblingIndex; -} - -/*! - \internal - - Should not be exported, but we can't change that now. -*/ -inline bool qt_closestItemFirst(const QGraphicsItem *item1, const QGraphicsItem *item2) -{ - return QGraphicsScenePrivate::closestItemFirst_withoutCache(item1, item2); -} - -/*! - Returns true if \a item1 is on top of \a item2. - - \internal -*/ -bool QGraphicsScenePrivate::closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2) -{ - // Siblings? Just check their z-values. - const QGraphicsItemPrivate *d1 = item1->d_ptr; - const QGraphicsItemPrivate *d2 = item2->d_ptr; - if (d1->parent == d2->parent) - return qt_closestLeaf(item1, item2); - - // Find common ancestor, and each item's ancestor closest to the common - // ancestor. - int item1Depth = d1->depth; - int item2Depth = d2->depth; - const QGraphicsItem *p = item1; - const QGraphicsItem *t1 = item1; - while (item1Depth > item2Depth && (p = p->d_ptr->parent)) { - if (p == item2) { - // item2 is one of item1's ancestors; item1 is on top - return !(t1->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent); - } - t1 = p; - --item1Depth; - } - p = item2; - const QGraphicsItem *t2 = item2; - while (item2Depth > item1Depth && (p = p->d_ptr->parent)) { - if (p == item1) { - // item1 is one of item2's ancestors; item1 is not on top - return (t2->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent); - } - t2 = p; - --item2Depth; - } - - // item1Ancestor is now at the same level as item2Ancestor, but not the same. - const QGraphicsItem *a1 = t1; - const QGraphicsItem *a2 = t2; - while (a1) { - const QGraphicsItem *p1 = a1; - const QGraphicsItem *p2 = a2; - a1 = a1->parentItem(); - a2 = a2->parentItem(); - if (a1 && a1 == a2) - return qt_closestLeaf(p1, p2); - } - - // No common ancestor? Then just compare the items' toplevels directly. - return qt_closestLeaf(t1->topLevelItem(), t2->topLevelItem()); -} - -/*! - Returns true if \a item2 is on top of \a item1. - - \internal -*/ -bool QGraphicsScenePrivate::closestItemLast_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2) -{ - return closestItemFirst_withoutCache(item2, item1); -} - -void QGraphicsScenePrivate::climbTree(QGraphicsItem *item, int *stackingOrder) -{ - if (!item->d_ptr->children.isEmpty()) { - QList childList = item->d_ptr->children; - qSort(childList.begin(), childList.end(), qt_closestLeaf); - for (int i = 0; i < childList.size(); ++i) { - QGraphicsItem *item = childList.at(i); - if (!(item->flags() & QGraphicsItem::ItemStacksBehindParent)) - climbTree(childList.at(i), stackingOrder); - } - item->d_ptr->globalStackingOrder = (*stackingOrder)++; - for (int i = 0; i < childList.size(); ++i) { - QGraphicsItem *item = childList.at(i); - if (item->flags() & QGraphicsItem::ItemStacksBehindParent) - climbTree(childList.at(i), stackingOrder); - } - } else { - item->d_ptr->globalStackingOrder = (*stackingOrder)++; - } -} - -void QGraphicsScenePrivate::_q_updateSortCache() -{ - //### FIXME - QGraphicsSceneBspTreeIndex *tree = qobject_cast(index); - if (tree) { - tree->_q_updateIndex(); - } - - if (!sortCacheEnabled || !updatingSortCache) - return; - - updatingSortCache = false; - int stackingOrder = 0; - - QList topLevels; - - for (int i = 0; i < index->items().count(); ++i) { - QGraphicsItem *item = index->items().at(i); - if (item && item->parentItem() == 0) - topLevels << item; - } - - qSort(topLevels.begin(), topLevels.end(), qt_closestLeaf); - for (int i = 0; i < topLevels.size(); ++i) - climbTree(topLevels.at(i), &stackingOrder); -} - -void QGraphicsScenePrivate::sortItems(QList *itemList, Qt::SortOrder order, - bool sortCacheEnabled) -{ - if (sortCacheEnabled) { - if (order == Qt::AscendingOrder) { - qSort(itemList->begin(), itemList->end(), closestItemFirst_withCache); - } else if (order == Qt::DescendingOrder) { - qSort(itemList->begin(), itemList->end(), closestItemLast_withCache); - } - } else { - if (order == Qt::AscendingOrder) { - qSort(itemList->begin(), itemList->end(), closestItemFirst_withoutCache); - } else if (order == Qt::DescendingOrder) { - qSort(itemList->begin(), itemList->end(), closestItemLast_withoutCache); - } - } -} - /*! \internal @@ -1707,15 +1537,25 @@ void QGraphicsScene::setBspTreeDepth(int depth) bool QGraphicsScene::isSortCacheEnabled() const { Q_D(const QGraphicsScene); - return d->sortCacheEnabled; + QGraphicsSceneBspTreeIndex *bspTree = qobject_cast(d->index); + if (!bspTree) { + qWarning("QGraphicsScene::isSortCacheEnabled: can not apply if indexing method is not BSP"); + return false; + } + return bspTree->d_func()->sortCacheEnabled; } void QGraphicsScene::setSortCacheEnabled(bool enabled) { Q_D(QGraphicsScene); - if (enabled == d->sortCacheEnabled) + QGraphicsSceneBspTreeIndex *bspTree = qobject_cast(d->index); + if (!bspTree) { + qWarning("QGraphicsScene::isSortCacheEnabled: can not apply if indexing method is not BSP"); return; - if ((d->sortCacheEnabled = enabled)) - d->invalidateSortCache(); + } + if (enabled == bspTree->d_func()->sortCacheEnabled) + return; + if ((bspTree->d_func()->sortCacheEnabled = enabled)) + bspTree->d_func()->invalidateSortCache(); } /*! @@ -1910,8 +1750,6 @@ QList QGraphicsScene::collidingItems(const QGraphicsItem *item, if (item != itemInVicinity && item->collidesWithItem(itemInVicinity, mode)) tmp << itemInVicinity; } - //### remove me - d->sortItems(&tmp, Qt::AscendingOrder, d->sortCacheEnabled); return tmp; } @@ -2211,10 +2049,6 @@ void QGraphicsScene::addItem(QGraphicsItem *item) return; } - // Invalidate any sort caching; arrival of a new item means we need to - // resort. - d->invalidateSortCache(); - // Detach this item from its parent if the parent's scene is different // from this scene. if (QGraphicsItem *itemParent = item->parentItem()) { @@ -2232,10 +2066,6 @@ void QGraphicsScene::addItem(QGraphicsItem *item) if (!item->d_ptr->parent) d->registerTopLevelItem(item); - // Update the scene's sort cache settings. - item->d_ptr->globalStackingOrder = -1; - d->invalidateSortCache(); - // Add to list of items that require an update. We cannot assume that the // item is fully constructed, so calling item->update() can lead to a pure // virtual function call to boundingRect(). diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h index 5d70087..702813c 100644 --- a/src/gui/graphicsview/qgraphicsscene.h +++ b/src/gui/graphicsview/qgraphicsscene.h @@ -290,7 +290,6 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_removeItemLater(QGraphicsItem *item)) Q_PRIVATE_SLOT(d_func(), void _q_updateLater()) Q_PRIVATE_SLOT(d_func(), void _q_polishItems()) - Q_PRIVATE_SLOT(d_func(), void _q_updateSortCache()) Q_PRIVATE_SLOT(d_func(), void _q_resetDirtyItems()) friend class QGraphicsItem; friend class QGraphicsItemPrivate; @@ -301,6 +300,7 @@ private: friend class QGraphicsSceneIndex; friend class QGraphicsSceneIndexPrivate; friend class QGraphicsSceneBspTreeIndex; + friend class QGraphicsSceneBspTreeIndexPrivate; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsScene::SceneLayers) diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index a035159..d2a5cdb 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -187,25 +187,6 @@ public: void sendMouseEvent(QGraphicsSceneMouseEvent *mouseEvent); void mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent); QGraphicsWidget *windowForItem(const QGraphicsItem *item) const; - bool sortCacheEnabled; - bool updatingSortCache; - void invalidateSortCache(); - static void climbTree(QGraphicsItem *item, int *stackingOrder); - void _q_updateSortCache(); - - static bool closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2); - static bool closestItemLast_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2); - - static inline bool closestItemFirst_withCache(const QGraphicsItem *item1, const QGraphicsItem *item2) - { - return item1->d_ptr->globalStackingOrder < item2->d_ptr->globalStackingOrder; - } - static inline bool closestItemLast_withCache(const QGraphicsItem *item1, const QGraphicsItem *item2) - { - return item1->d_ptr->globalStackingOrder >= item2->d_ptr->globalStackingOrder; - } - - static void sortItems(QList *itemList, Qt::SortOrder order, bool cached); void drawItemHelper(QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget, diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp index f8f1f56..19aa9d5 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp @@ -39,9 +39,15 @@ ** ****************************************************************************/ + static const int QGRAPHICSSCENE_INDEXTIMER_TIMEOUT = 2000; #include "qgraphicsscenebsptreeindex_p.h" + +#ifndef QT_NO_GRAPHICSVIEW + +#include "qgraphicsscenebsptreeindex_p_p.h" +#include "qgraphicssceneindex_p.h" #include "qgraphicsitem_p.h" #include "qgraphicsscene_p.h" @@ -49,51 +55,365 @@ static const int QGRAPHICSSCENE_INDEXTIMER_TIMEOUT = 2000; #include -QGraphicsSceneBspTreeIndex::QGraphicsSceneBspTreeIndex(QGraphicsScene *scene) - : QGraphicsSceneIndex(scene), +QT_BEGIN_NAMESPACE + +static inline int intmaxlog(int n) +{ + return (n > 0 ? qMax(qCeil(qLn(qreal(n)) / qLn(qreal(2))), 5) : 0); +} + +/*! + Constructs a private scene index. +*/ +QGraphicsSceneBspTreeIndexPrivate::QGraphicsSceneBspTreeIndexPrivate(QGraphicsScene *scene) + : scene(scene), bspTreeDepth(0), indexTimerId(0), restartIndexTimer(false), regenerateIndex(true), lastItemCount(0), - purgePending(false) + purgePending(false), + sortCacheEnabled(false), + updatingSortCache(false) +{ +} + + +/*! + \internal +*/ +void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() { + Q_Q(QGraphicsSceneBspTreeIndex); + if (!indexTimerId) + return; + QGraphicsScenePrivate * scenePrivate = q->scene()->d_func(); + q->killTimer(indexTimerId); + indexTimerId = 0; + + purgeRemovedItems(); + + // Add unindexedItems to indexedItems + QRectF unindexedItemsBoundingRect; + for (int i = 0; i < unindexedItems.size(); ++i) { + if (QGraphicsItem *item = unindexedItems.at(i)) { + unindexedItemsBoundingRect |= item->sceneBoundingRect(); + if (!freeItemIndexes.isEmpty()) { + int freeIndex = freeItemIndexes.takeFirst(); + item->d_func()->index = freeIndex; + indexedItems[freeIndex] = item; + } else { + item->d_func()->index = indexedItems.size(); + indexedItems << item; + } + } + } + + // Update growing scene rect. + QRectF oldGrowingItemsBoundingRect = scenePrivate->growingItemsBoundingRect; + scenePrivate->growingItemsBoundingRect |= unindexedItemsBoundingRect; + + // Determine whether we should regenerate the BSP tree. + if (bspTreeDepth == 0) { + int oldDepth = intmaxlog(lastItemCount); + bspTreeDepth = intmaxlog(indexedItems.size()); + static const int slack = 100; + if (bsp.leafCount() == 0 || (oldDepth != bspTreeDepth && qAbs(lastItemCount - indexedItems.size()) > slack)) { + // ### Crude algorithm. + regenerateIndex = true; + } + } + + // Regenerate the tree. + if (regenerateIndex) { + regenerateIndex = false; + bsp.initialize(q->scene()->sceneRect(), bspTreeDepth); + unindexedItems = indexedItems; + lastItemCount = indexedItems.size(); + q->scene()->update(); + + // Take this opportunity to reset our largest-item counter for + // untransformable items. When the items are inserted into the BSP + // tree, we'll get an accurate calculation. + scenePrivate->largestUntransformableItem = QRectF(); + } + + // Insert all unindexed items into the tree. + for (int i = 0; i < unindexedItems.size(); ++i) { + if (QGraphicsItem *item = unindexedItems.at(i)) { + QRectF rect = item->sceneBoundingRect(); + if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) + continue; + + bsp.insertItem(item, rect); + + // If the item ignores view transformations, update our + // largest-item-counter to ensure that the view can accurately + // discover untransformable items when drawing. + if (item->d_ptr->itemIsUntransformable()) { + QGraphicsItem *topmostUntransformable = item; + while (topmostUntransformable && (topmostUntransformable->d_ptr->ancestorFlags + & QGraphicsItemPrivate::AncestorIgnoresTransformations)) { + topmostUntransformable = topmostUntransformable->parentItem(); + } + // ### Verify that this is the correct largest untransformable rectangle. + scenePrivate->largestUntransformableItem |= item->mapToItem(topmostUntransformable, item->boundingRect()).boundingRect(); + } + } + } + unindexedItems.clear(); + + // Notify scene rect changes. + if (!scenePrivate->hasSceneRect && scenePrivate->growingItemsBoundingRect != oldGrowingItemsBoundingRect) + emit q->scene()->sceneRectChanged(scenePrivate->growingItemsBoundingRect); } -QRectF QGraphicsSceneBspTreeIndex::indexedRect() + +/*! + \internal + + Removes stale pointers from all data structures. +*/ +void QGraphicsSceneBspTreeIndexPrivate::purgeRemovedItems() +{ + Q_Q(QGraphicsSceneBspTreeIndex); + if (!purgePending && removedItems.isEmpty()) + return; + + // Remove stale items from the BSP tree. + bsp.removeItems(removedItems.toSet()); + // Purge this list. + removedItems.clear(); + freeItemIndexes.clear(); + for (int i = 0; i < indexedItems.size(); ++i) { + if (!indexedItems.at(i)) + freeItemIndexes << i; + } + purgePending = false; + + // No locality info for the items; update the whole scene. + q->scene()->update(); +} + +/*! + \internal + + Starts or restarts the timer used for reindexing unindexed items. +*/ +void QGraphicsSceneBspTreeIndexPrivate::startIndexTimer() +{ + Q_Q(QGraphicsSceneBspTreeIndex); + if (indexTimerId) { + restartIndexTimer = true; + } else { + indexTimerId = q->startTimer(QGRAPHICSSCENE_INDEXTIMER_TIMEOUT); + } +} + +/*! + \internal +*/ +void QGraphicsSceneBspTreeIndexPrivate::resetIndex() +{ + purgeRemovedItems(); + for (int i = 0; i < indexedItems.size(); ++i) { + if (QGraphicsItem *item = indexedItems.at(i)) { + item->d_ptr->index = -1; + unindexedItems << item; + } + } + indexedItems.clear(); + freeItemIndexes.clear(); + regenerateIndex = true; + startIndexTimer(); +} + +void QGraphicsSceneBspTreeIndexPrivate::climbTree(QGraphicsItem *item, int *stackingOrder) { + if (!item->d_ptr->children.isEmpty()) { + QList childList = item->d_ptr->children; + qSort(childList.begin(), childList.end(), qt_closestLeaf); + for (int i = 0; i < childList.size(); ++i) { + QGraphicsItem *item = childList.at(i); + if (!(item->flags() & QGraphicsItem::ItemStacksBehindParent)) + climbTree(childList.at(i), stackingOrder); + } + item->d_ptr->globalStackingOrder = (*stackingOrder)++; + for (int i = 0; i < childList.size(); ++i) { + QGraphicsItem *item = childList.at(i); + if (item->flags() & QGraphicsItem::ItemStacksBehindParent) + climbTree(childList.at(i), stackingOrder); + } + } else { + item->d_ptr->globalStackingOrder = (*stackingOrder)++; + } +} + +void QGraphicsSceneBspTreeIndexPrivate::_q_updateSortCache() +{ + Q_Q(QGraphicsSceneBspTreeIndex); _q_updateIndex(); + + if (!sortCacheEnabled || !updatingSortCache) + return; + + updatingSortCache = false; + int stackingOrder = 0; + + QList topLevels; + + for (int i = 0; i < q->items().count(); ++i) { + QGraphicsItem *item = q->items().at(i); + if (item && item->parentItem() == 0) + topLevels << item; + } + + qSort(topLevels.begin(), topLevels.end(), qt_closestLeaf); + for (int i = 0; i < topLevels.size(); ++i) + climbTree(topLevels.at(i), &stackingOrder); +} + +void QGraphicsSceneBspTreeIndexPrivate::invalidateSortCache() +{ + Q_Q(QGraphicsSceneBspTreeIndex); + if (!sortCacheEnabled || updatingSortCache) + return; + + updatingSortCache = true; + QMetaObject::invokeMethod(q, "_q_updateSortCache", Qt::QueuedConnection); +} + +/*! + Returns true if \a item1 is on top of \a item2. + + \internal +*/ +bool QGraphicsSceneBspTreeIndexPrivate::closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2) +{ + // Siblings? Just check their z-values. + const QGraphicsItemPrivate *d1 = item1->d_ptr; + const QGraphicsItemPrivate *d2 = item2->d_ptr; + if (d1->parent == d2->parent) + return qt_closestLeaf(item1, item2); + + // Find common ancestor, and each item's ancestor closest to the common + // ancestor. + int item1Depth = d1->depth; + int item2Depth = d2->depth; + const QGraphicsItem *p = item1; + const QGraphicsItem *t1 = item1; + while (item1Depth > item2Depth && (p = p->d_ptr->parent)) { + if (p == item2) { + // item2 is one of item1's ancestors; item1 is on top + return !(t1->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent); + } + t1 = p; + --item1Depth; + } + p = item2; + const QGraphicsItem *t2 = item2; + while (item2Depth > item1Depth && (p = p->d_ptr->parent)) { + if (p == item1) { + // item1 is one of item2's ancestors; item1 is not on top + return (t2->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent); + } + t2 = p; + --item2Depth; + } + + // item1Ancestor is now at the same level as item2Ancestor, but not the same. + const QGraphicsItem *a1 = t1; + const QGraphicsItem *a2 = t2; + while (a1) { + const QGraphicsItem *p1 = a1; + const QGraphicsItem *p2 = a2; + a1 = a1->parentItem(); + a2 = a2->parentItem(); + if (a1 && a1 == a2) + return qt_closestLeaf(p1, p2); + } + + // No common ancestor? Then just compare the items' toplevels directly. + return qt_closestLeaf(t1->topLevelItem(), t2->topLevelItem()); +} + +/*! + Returns true if \a item2 is on top of \a item1. + + \internal +*/ +bool QGraphicsSceneBspTreeIndexPrivate::closestItemLast_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2) +{ + return closestItemFirst_withoutCache(item2, item1); +} + +void QGraphicsSceneBspTreeIndexPrivate::sortItems(QList *itemList, Qt::SortOrder order, + bool sortCacheEnabled) +{ + if (sortCacheEnabled) { + if (order == Qt::AscendingOrder) { + qSort(itemList->begin(), itemList->end(), closestItemFirst_withCache); + } else if (order == Qt::DescendingOrder) { + qSort(itemList->begin(), itemList->end(), closestItemLast_withCache); + } + } else { + if (order == Qt::AscendingOrder) { + qSort(itemList->begin(), itemList->end(), closestItemFirst_withoutCache); + } else if (order == Qt::DescendingOrder) { + qSort(itemList->begin(), itemList->end(), closestItemLast_withoutCache); + } + } +} + +QGraphicsSceneBspTreeIndex::QGraphicsSceneBspTreeIndex(QGraphicsScene *scene) + : QGraphicsSceneIndex(*new QGraphicsSceneBspTreeIndexPrivate(scene), scene) +{ + +} + +QRectF QGraphicsSceneBspTreeIndex::indexedRect() const +{ + Q_D(const QGraphicsSceneBspTreeIndex); + const_cast(d)->_q_updateIndex(); return scene()->d_func()->hasSceneRect ? scene()->d_func()->sceneRect : scene()->d_func()->growingItemsBoundingRect; } void QGraphicsSceneBspTreeIndex::clear() { - bsp.clear(); - lastItemCount = 0; - freeItemIndexes.clear(); - m_indexedItems.clear(); - unindexedItems.clear(); + Q_D(QGraphicsSceneBspTreeIndex); + d->bsp.clear(); + d->lastItemCount = 0; + d->freeItemIndexes.clear(); + d->indexedItems.clear(); + d->unindexedItems.clear(); } void QGraphicsSceneBspTreeIndex::addItem(QGraphicsItem *item) { + Q_D(QGraphicsSceneBspTreeIndex); // Prevent reusing a recently deleted pointer: purge all removed items // from our lists. - purgeRemovedItems(); + d->purgeRemovedItems(); + + // Invalidate any sort caching; arrival of a new item means we need to + // resort. + // Update the scene's sort cache settings. + item->d_ptr->globalStackingOrder = -1; + d->invalidateSortCache(); // Indexing requires sceneBoundingRect(), but because \a item might // not be completely constructed at this point, we need to store it in // a temporary list and schedule an indexing for later. - unindexedItems << item; + d->unindexedItems << item; item->d_func()->index = -1; - startIndexTimer(); + d->startIndexTimer(); } /*! \internal */ -void QGraphicsSceneBspTreeIndex::addToIndex(QGraphicsItem *item) +void QGraphicsSceneBspTreeIndexPrivate::addToIndex(QGraphicsItem *item) { if (item->d_func()->index != -1) { bsp.insertItem(item, item->sceneBoundingRect()); @@ -109,37 +429,47 @@ void QGraphicsSceneBspTreeIndex::addToIndex(QGraphicsItem *item) void QGraphicsSceneBspTreeIndex::removeItem(QGraphicsItem *item) { + Q_D(QGraphicsSceneBspTreeIndex); // Note: This will access item's sceneBoundingRect(), which (as this is // C++) is why we cannot call removeItem() from QGraphicsItem's // destructor. - removeFromIndex(item); + d->removeFromIndex(item); + + // Invalidate any sort caching; arrival of a new item means we need to + // resort. + d->invalidateSortCache(); // Remove from our item lists. int index = item->d_func()->index; if (index != -1) { - freeItemIndexes << index; - m_indexedItems[index] = 0; + d->freeItemIndexes << index; + d->indexedItems[index] = 0; } else { - unindexedItems.removeAll(item); + d->unindexedItems.removeAll(item); } } void QGraphicsSceneBspTreeIndex::deleteItem(QGraphicsItem *item) { + Q_D(QGraphicsSceneBspTreeIndex); + // Invalidate any sort caching; arrival of a new item means we need to + // resort. + d->invalidateSortCache(); + int index = item->d_func()->index; if (index != -1) { // Important: The index is useless until purgeRemovedItems() is // called. - m_indexedItems[index] = (QGraphicsItem *)0; - if (!purgePending) { - purgePending = true; + d->indexedItems[index] = (QGraphicsItem *)0; + if (!d->purgePending) { + d->purgePending = true; scene()->update(); } - removedItems << item; + d->removedItems << item; } else { // Recently added items are purged immediately. unindexedItems() never // contains stale items. - unindexedItems.removeAll(item); + d->unindexedItems.removeAll(item); scene()->update(); } } @@ -147,7 +477,7 @@ void QGraphicsSceneBspTreeIndex::deleteItem(QGraphicsItem *item) /*! \internal */ -void QGraphicsSceneBspTreeIndex::removeFromIndex(QGraphicsItem *item) +void QGraphicsSceneBspTreeIndexPrivate::removeFromIndex(QGraphicsItem *item) { if (item->d_func()->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { // ### remove from child index only if applicable @@ -157,7 +487,7 @@ void QGraphicsSceneBspTreeIndex::removeFromIndex(QGraphicsItem *item) if (index != -1) { bsp.removeItem(item, item->sceneBoundingRect()); freeItemIndexes << index; - m_indexedItems[index] = 0; + indexedItems[index] = 0; item->d_func()->index = -1; unindexedItems << item; @@ -170,21 +500,23 @@ void QGraphicsSceneBspTreeIndex::removeFromIndex(QGraphicsItem *item) void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem *item) { + Q_D(QGraphicsSceneBspTreeIndex); // Note: This will access item's sceneBoundingRect(), which (as this is // C++) is why we cannot call removeItem() from QGraphicsItem's // destructor. - removeFromIndex(const_cast(item)); + d->removeFromIndex(const_cast(item)); } QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const { - const_cast(this)->purgeRemovedItems(); - scene()->d_func()->_q_updateSortCache(); + Q_D(const QGraphicsSceneBspTreeIndex); + const_cast(d)->purgeRemovedItems(); + const_cast(d)->_q_updateSortCache(); - QList rectItems = bsp.items(rect); + QList rectItems = d->bsp.items(rect); // Fill in with any unindexed items - for (int i = 0; i < unindexedItems.size(); ++i) { - if (QGraphicsItem *item = unindexedItems.at(i)) { + for (int i = 0; i < d->unindexedItems.size(); ++i) { + if (QGraphicsItem *item = d->unindexedItems.at(i)) { if (!item->d_ptr->itemDiscovered && item->d_ptr->visible && !(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { QRectF boundingRect = item->sceneBoundingRect(); if (QRectF_intersects(boundingRect, rect)) { @@ -199,57 +531,83 @@ QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &r for (int i = 0; i < rectItems.size(); ++i) rectItems.at(i)->d_func()->itemDiscovered = 0; + d->sortItems(&rectItems, order, d->sortCacheEnabled); + return rectItems; } -QList QGraphicsSceneBspTreeIndex::items() const +QList QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order) const { - const_cast(this)->purgeRemovedItems(); + Q_D(const QGraphicsSceneBspTreeIndex); + const_cast(d)->purgeRemovedItems(); + QList itemList; // If freeItemIndexes is empty, we know there are no holes in indexedItems and // unindexedItems. - if (freeItemIndexes.isEmpty()) { - if (unindexedItems.isEmpty()) - return m_indexedItems; - return m_indexedItems + unindexedItems; - } - - // Rebuild the list of items to avoid holes. ### We could also just - // compress the item lists at this point. - QList itemList; - foreach (QGraphicsItem *item, m_indexedItems + unindexedItems) { - if (item) - itemList << item; + if (d->freeItemIndexes.isEmpty()) { + if (d->unindexedItems.isEmpty()) { + itemList = d->indexedItems; + } else { + itemList = d->indexedItems + d->unindexedItems; + } + } else { + // Rebuild the list of items to avoid holes. ### We could also just + // compress the item lists at this point. + foreach (QGraphicsItem *item, d->indexedItems + d->unindexedItems) { + if (item) + itemList << item; + } } + //We sort descending order + d->sortItems(&itemList, order, d->sortCacheEnabled); return itemList; } int QGraphicsSceneBspTreeIndex::bspDepth() { - return bspTreeDepth; + Q_D(const QGraphicsSceneBspTreeIndex); + return d->bspTreeDepth; } void QGraphicsSceneBspTreeIndex::setBspDepth(int depth) { - bspTreeDepth = depth; - resetIndex(); + Q_D(QGraphicsSceneBspTreeIndex); + d->bspTreeDepth = depth; + d->resetIndex(); } void QGraphicsSceneBspTreeIndex::sceneRectChanged(const QRectF &rect) { - m_sceneRect = rect; - resetIndex(); + Q_D(QGraphicsSceneBspTreeIndex); + d->sceneRect = rect; + d->resetIndex(); +} + +void QGraphicsSceneBspTreeIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) +{ + Q_D(QGraphicsSceneBspTreeIndex); + switch (change) { + case QGraphicsItem::ItemZValueChange: + case QGraphicsItem::ItemParentChange: { + d->invalidateSortCache(); + break; + } + default: + break; + } + return QGraphicsSceneIndex::itemChanged(item, change, value); } bool QGraphicsSceneBspTreeIndex::event(QEvent *event) { + Q_D(QGraphicsSceneBspTreeIndex); switch (event->type()) { case QEvent::Timer: - if (indexTimerId && static_cast(event)->timerId() == indexTimerId) { - if (restartIndexTimer) { - restartIndexTimer = false; + if (d->indexTimerId && static_cast(event)->timerId() == d->indexTimerId) { + if (d->restartIndexTimer) { + d->restartIndexTimer = false; } else { // this call will kill the timer - _q_updateIndex(); + d->_q_updateIndex(); } } // Fallthrough intended - support timers in subclasses. @@ -259,153 +617,9 @@ bool QGraphicsSceneBspTreeIndex::event(QEvent *event) return true; } -static inline int intmaxlog(int n) -{ - return (n > 0 ? qMax(qCeil(qLn(qreal(n)) / qLn(qreal(2))), 5) : 0); -} +QT_END_NAMESPACE -/*! - \internal -*/ -void QGraphicsSceneBspTreeIndex::_q_updateIndex() -{ - if (!indexTimerId) - return; +#include "moc_qgraphicsscenebsptreeindex_p.cpp" - killTimer(indexTimerId); - indexTimerId = 0; +#endif // QT_NO_GRAPHICSVIEW - purgeRemovedItems(); - - // Add unindexedItems to indexedItems - QRectF unindexedItemsBoundingRect; - for (int i = 0; i < unindexedItems.size(); ++i) { - if (QGraphicsItem *item = unindexedItems.at(i)) { - unindexedItemsBoundingRect |= item->sceneBoundingRect(); - if (!freeItemIndexes.isEmpty()) { - int freeIndex = freeItemIndexes.takeFirst(); - item->d_func()->index = freeIndex; - m_indexedItems[freeIndex] = item; - } else { - item->d_func()->index = m_indexedItems.size(); - m_indexedItems << item; - } - } - } - - // Update growing scene rect. - QRectF oldGrowingItemsBoundingRect = scene()->d_func()->growingItemsBoundingRect; - scene()->d_func()->growingItemsBoundingRect |= unindexedItemsBoundingRect; - - // Determine whether we should regenerate the BSP tree. - if (bspTreeDepth == 0) { - int oldDepth = intmaxlog(lastItemCount); - bspTreeDepth = intmaxlog(m_indexedItems.size()); - static const int slack = 100; - if (bsp.leafCount() == 0 || (oldDepth != bspTreeDepth && qAbs(lastItemCount - m_indexedItems.size()) > slack)) { - // ### Crude algorithm. - regenerateIndex = true; - } - } - - // Regenerate the tree. - if (regenerateIndex) { - regenerateIndex = false; - bsp.initialize(scene()->sceneRect(), bspTreeDepth); - unindexedItems = m_indexedItems; - lastItemCount = m_indexedItems.size(); - scene()->update(); - - // Take this opportunity to reset our largest-item counter for - // untransformable items. When the items are inserted into the BSP - // tree, we'll get an accurate calculation. - scene()->d_func()->largestUntransformableItem = QRectF(); - } - - // Insert all unindexed items into the tree. - for (int i = 0; i < unindexedItems.size(); ++i) { - if (QGraphicsItem *item = unindexedItems.at(i)) { - QRectF rect = item->sceneBoundingRect(); - if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) - continue; - - bsp.insertItem(item, rect); - - // If the item ignores view transformations, update our - // largest-item-counter to ensure that the view can accurately - // discover untransformable items when drawing. - if (item->d_ptr->itemIsUntransformable()) { - QGraphicsItem *topmostUntransformable = item; - while (topmostUntransformable && (topmostUntransformable->d_ptr->ancestorFlags - & QGraphicsItemPrivate::AncestorIgnoresTransformations)) { - topmostUntransformable = topmostUntransformable->parentItem(); - } - // ### Verify that this is the correct largest untransformable rectangle. - scene()->d_func()->largestUntransformableItem |= item->mapToItem(topmostUntransformable, item->boundingRect()).boundingRect(); - } - } - } - unindexedItems.clear(); - - // Notify scene rect changes. - if (!scene()->d_func()->hasSceneRect && scene()->d_func()->growingItemsBoundingRect != oldGrowingItemsBoundingRect) - emit scene()->sceneRectChanged(scene()->d_func()->growingItemsBoundingRect); -} - - -/*! - \internal - - Removes stale pointers from all data structures. -*/ -void QGraphicsSceneBspTreeIndex::purgeRemovedItems() -{ - if (!purgePending && removedItems.isEmpty()) - return; - - // Remove stale items from the BSP tree. - bsp.removeItems(removedItems.toSet()); - // Purge this list. - removedItems.clear(); - freeItemIndexes.clear(); - for (int i = 0; i < m_indexedItems.size(); ++i) { - if (!m_indexedItems.at(i)) - freeItemIndexes << i; - } - purgePending = false; - - // No locality info for the items; update the whole scene. - scene()->update(); -} - -/*! - \internal - - Starts or restarts the timer used for reindexing unindexed items. -*/ -void QGraphicsSceneBspTreeIndex::startIndexTimer() -{ - if (indexTimerId) { - restartIndexTimer = true; - } else { - indexTimerId = startTimer(QGRAPHICSSCENE_INDEXTIMER_TIMEOUT); - } -} - -/*! - \internal -*/ -void QGraphicsSceneBspTreeIndex::resetIndex() -{ - purgeRemovedItems(); - for (int i = 0; i < m_indexedItems.size(); ++i) { - if (QGraphicsItem *item = m_indexedItems.at(i)) { - item->d_ptr->index = -1; - unindexedItems << item; - } - } - m_indexedItems.clear(); - freeItemIndexes.clear(); - regenerateIndex = true; - startIndexTimer(); -} diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 7a6ea0b..b1ea977 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -56,56 +56,41 @@ QT_BEGIN_NAMESPACE #include "qgraphicsscene_bsp_p.h" +class QGraphicsSceneBspTreeIndexPrivate; class Q_AUTOTEST_EXPORT QGraphicsSceneBspTreeIndex : public QGraphicsSceneIndex { Q_OBJECT public: QGraphicsSceneBspTreeIndex(QGraphicsScene *scene = 0); - QRectF indexedRect(); - - void clear(); - - void addItem(QGraphicsItem *item); - void removeItem(QGraphicsItem *item); - void deleteItem(QGraphicsItem *item); - void prepareBoundingRectChange(const QGraphicsItem *item); + QRectF indexedRect() const; QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const; - QList items() const; + QList items(Qt::SortOrder order = Qt::AscendingOrder) const; int bspDepth(); void setBspDepth(int depth); protected: bool event(QEvent *event); - void sceneRectChanged(const QRectF &rect); + void clear(); + + void addItem(QGraphicsItem *item); + void removeItem(QGraphicsItem *item); + void deleteItem(QGraphicsItem *item); + void prepareBoundingRectChange(const QGraphicsItem *item); -public slots : - void _q_updateIndex(); + void sceneRectChanged(const QRectF &rect); + void itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value); private : - QGraphicsSceneBspTree bsp; - QRectF m_sceneRect; - int bspTreeDepth; - int indexTimerId; - bool restartIndexTimer; - bool regenerateIndex; - int lastItemCount; - - QList m_indexedItems; - QList unindexedItems; - QList freeItemIndexes; - - bool purgePending; - QList removedItems; - void purgeRemovedItems(); - - void startIndexTimer(); - void resetIndex(); - - void addToIndex(QGraphicsItem *item); - void removeFromIndex(QGraphicsItem *item); + Q_DECLARE_PRIVATE(QGraphicsSceneBspTreeIndex) + Q_DISABLE_COPY(QGraphicsSceneBspTreeIndex) + Q_PRIVATE_SLOT(d_func(), void _q_updateSortCache()) + Q_PRIVATE_SLOT(d_func(), void _q_updateIndex()) + + friend class QGraphicsScene; + friend class QGraphicsScenePrivate; }; QT_END_NAMESPACE diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p_p.h new file mode 100644 index 0000000..2df5fbc --- /dev/null +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p_p.h @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui 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 qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGRAPHICSSCENEBSPTREEINDEX_P_P_H +#define QGRAPHICSSCENEBSPTREEINDEX_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + +#include "qgraphicsscenebsptreeindex_p.h" + +#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW + +#include +#include + +QT_BEGIN_NAMESPACE + +class QGraphicsScene; + +class QGraphicsSceneBspTreeIndexPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QGraphicsSceneBspTreeIndex) +public: + QGraphicsSceneBspTreeIndexPrivate(QGraphicsScene *scene); + + QGraphicsScene *scene; + QGraphicsSceneBspTree bsp; + QRectF sceneRect; + int bspTreeDepth; + int indexTimerId; + bool restartIndexTimer; + bool regenerateIndex; + int lastItemCount; + + QList indexedItems; + QList unindexedItems; + QList freeItemIndexes; + + bool purgePending; + QList removedItems; + void purgeRemovedItems(); + + void _q_updateIndex(); + void startIndexTimer(); + void resetIndex(); + + void addToIndex(QGraphicsItem *item); + void removeFromIndex(QGraphicsItem *item); + + void _q_updateSortCache(); + bool sortCacheEnabled; + bool updatingSortCache; + void invalidateSortCache(); + + static void climbTree(QGraphicsItem *item, int *stackingOrder); + static bool closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2); + static bool closestItemLast_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2); + + static inline bool closestItemFirst_withCache(const QGraphicsItem *item1, const QGraphicsItem *item2) + { + return item1->d_ptr->globalStackingOrder < item2->d_ptr->globalStackingOrder; + } + static inline bool closestItemLast_withCache(const QGraphicsItem *item1, const QGraphicsItem *item2) + { + return item1->d_ptr->globalStackingOrder >= item2->d_ptr->globalStackingOrder; + } + + static void sortItems(QList *itemList, Qt::SortOrder order, bool cached); +}; + + +/*! + \internal +*/ +inline bool qt_closestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2) +{ + // Return true if sibling item1 is on top of item2. + const QGraphicsItemPrivate *d1 = item1->d_ptr; + const QGraphicsItemPrivate *d2 = item2->d_ptr; + bool f1 = d1->flags & QGraphicsItem::ItemStacksBehindParent; + bool f2 = d2->flags & QGraphicsItem::ItemStacksBehindParent; + if (f1 != f2) return f2; + qreal z1 = d1->z; + qreal z2 = d2->z; + return z1 != z2 ? z1 > z2 : d1->siblingIndex > d2->siblingIndex; +} + +QT_END_NAMESPACE + +#endif // QGRAPHICSSCENEBSPTREEINDEX_P_P_H + +#endif + diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index d0d6081..eeee74e 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -41,6 +41,7 @@ #include "qgraphicssceneindex.h" #include "qgraphicssceneindex_p.h" +#include "qgraphicsscenebsptreeindex_p_p.h" #include "qgraphicsscene.h" #include "qgraphicsitem_p.h" #include "qgraphicsscene_p.h" @@ -282,6 +283,14 @@ QGraphicsSceneIndex::QGraphicsSceneIndex(QGraphicsScene *scene) } /*! + \internal +*/ +QGraphicsSceneIndex::QGraphicsSceneIndex(QObjectPrivate &dd, QGraphicsScene *scene) + : QObject(dd, scene) +{ +} + +/*! Destroys the scene index. */ QGraphicsSceneIndex::~QGraphicsSceneIndex() @@ -301,7 +310,7 @@ QGraphicsScene* QGraphicsSceneIndex::scene() const /*! Returns the indexed area for the index */ -QRectF QGraphicsSceneIndex::indexedRect() +QRectF QGraphicsSceneIndex::indexedRect() const { Q_D(const QGraphicsSceneIndex); return d->scene->d_func()->sceneRect; @@ -351,8 +360,9 @@ QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSe d->childItems_helper(&items, item, xinv.map(pos)); } } - - d->scene->d_func()->sortItems(&items, order, d->scene->d_func()->sortCacheEnabled); + //### Needed but it should be handle differently + if (order != Qt::SortOrder(-1)) + QGraphicsSceneBspTreeIndexPrivate::sortItems(&items, order, false); return items; } @@ -415,9 +425,9 @@ QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSe } } } - + //### Needed but it should be handle differently if (order != Qt::SortOrder(-1)) - d->scene->d_func()->sortItems(&items, order, d->scene->d_func()->sortCacheEnabled); + QGraphicsSceneBspTreeIndexPrivate::sortItems(&items, order, false); return items; } @@ -474,9 +484,9 @@ QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt:: d->childItems_helper(&items, item, xinv.map(polygon), mode); } } - + //### Needed but it should be handle differently if (order != Qt::SortOrder(-1)) - d->scene->d_func()->sortItems(&items, order, d->scene->d_func()->sortCacheEnabled); + QGraphicsSceneBspTreeIndexPrivate::sortItems(&items, order, false); return items; } QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const @@ -525,9 +535,9 @@ QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt:: d->childItems_helper(&items, item, xinv.map(path), mode); } } - + //### Needed but it should be handle differently if (order != Qt::SortOrder(-1)) - d->scene->d_func()->sortItems(&items, order, d->scene->d_func()->sortCacheEnabled); + QGraphicsSceneBspTreeIndexPrivate::sortItems(&items, order, false); return items; } diff --git a/src/gui/graphicsview/qgraphicssceneindex.h b/src/gui/graphicsview/qgraphicssceneindex.h index 11d9aae..084a623 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.h +++ b/src/gui/graphicsview/qgraphicssceneindex.h @@ -71,9 +71,9 @@ public: QGraphicsScene *scene() const; - virtual QRectF indexedRect(); + virtual QRectF indexedRect() const; - virtual QList items() const = 0; + virtual QList items(Qt::SortOrder order = Qt::AscendingOrder) const = 0; virtual QList items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; virtual QList items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; virtual QList items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; @@ -91,10 +91,15 @@ protected: virtual void prepareBoundingRectChange(const QGraphicsItem *item); virtual void sceneRectChanged(const QRectF &rect); + QGraphicsSceneIndex(QObjectPrivate &dd, QGraphicsScene *scene); + friend class QGraphicsScene; friend class QGraphicsScenePrivate; friend class QGraphicsItem; + friend class QGraphicsItemPrivate; + friend class QGraphicsSceneBspTreeIndex; private: + Q_DISABLE_COPY(QGraphicsSceneIndex) Q_DECLARE_PRIVATE(QGraphicsSceneIndex) }; diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index f2cdca3..2014693 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -58,6 +58,7 @@ #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW #include +#include QT_BEGIN_NAMESPACE @@ -86,7 +87,7 @@ public: const QPainterPath &path, Qt::ItemSelectionMode mode) const; - QGraphicsScene *scene; + QGraphicsScene *scene; }; QT_END_NAMESPACE diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h index dc45a17..3057b4a 100644 --- a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h @@ -105,7 +105,7 @@ public: return result; } - QList items() const { + QList items(Qt::SortOrder order = Qt::AscendingOrder) const { return m_items; } }; diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 91f97a1..e8330a9 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -1056,7 +1056,7 @@ QList QGraphicsViewPrivate::findItems(const QRegion &exposedReg *allItems = true; // All items are guaranteed within the exposed region, don't bother using the index. - QList itemList(scene->items()); + QList itemList(scene->d_func()->index->items(Qt::DescendingOrder)); int i = 0; while (i < itemList.size()) { const QGraphicsItem *item = itemList.at(i); @@ -1069,9 +1069,6 @@ QList QGraphicsViewPrivate::findItems(const QRegion &exposedReg else ++i; } - - // Sort the items. - QGraphicsScenePrivate::sortItems(&itemList, Qt::DescendingOrder, scene->d_func()->sortCacheEnabled); return itemList; } @@ -2134,7 +2131,7 @@ QList QGraphicsViewPrivate::itemsInArea(const QPainterPath &pat // Then find the minimal list of items that are inside \a path, and // convert it to a set. - QList regularCandidates = scene->items(q->mapToScene(path), mode); + QList regularCandidates = scene->items(q->mapToScene(path), mode, order, q->transform()); QSet candSet = QSet::fromList(regularCandidates); QTransform viewMatrix = q->viewportTransform(); @@ -2161,10 +2158,6 @@ QList QGraphicsViewPrivate::itemsInArea(const QPainterPath &pat } ++it; } - - // ### Insertion sort would be faster. - if (order != Qt::SortOrder(-1)) - QGraphicsScenePrivate::sortItems(&result, order, scene->d_func()->sortCacheEnabled); return result; } diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 8afdeb4..c83134f 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -4685,6 +4685,11 @@ void tst_QGraphicsItem::itemClipsChildrenToShape() scene.render(&painter); painter.end(); + QGraphicsView view(&scene); + view.show(); + + QTest::qWait(5000); + QCOMPARE(image.pixel(16, 16), QColor(255, 0, 0).rgba()); QCOMPARE(image.pixel(32, 32), QColor(0, 0, 255).rgba()); QCOMPARE(image.pixel(50, 50), QColor(0, 255, 0).rgba()); diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index eb117ab..dd997c7 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -379,8 +379,7 @@ void tst_QGraphicsScene::items() for (int x = minX; x < maxX; x += 100) items << scene.addRect(QRectF(0, 0, 10, 10)); } - - QCOMPARE(scene.items(), items); + QCOMPARE(scene.items().size(), items.size()); scene.itemAt(0, 0); // trigger indexing scene.removeItem(items.at(5)); @@ -397,7 +396,7 @@ void tst_QGraphicsScene::items() QVERIFY(!l2->sceneBoundingRect().intersects(l1->sceneBoundingRect())); QList items; items<rect().center()); - QTest::qWait(100); + QTest::qWait(250); for (int size = 200; size <= 400; size += 25) { view.resize(size, size); @@ -2122,7 +2122,7 @@ void tst_QGraphicsView::resizeAnchor() QVERIFY(qAbs(newCenter.x() - center.x()) < slack); QVERIFY(qAbs(newCenter.y() - center.y()) < slack); } - QTest::qWait(100); + QTest::qWait(250); } } } @@ -2925,7 +2925,7 @@ void tst_QGraphicsView::task245469_itemsAtPointWithClip() QTest::qWait(100); QList itemsAtCenter = view.items(view.viewport()->rect().center()); - QCOMPARE(itemsAtCenter, (QList() << child << parent)); + QCOMPARE(itemsAtCenter, (QList() << parent << child)); QPolygonF p = view.mapToScene(QRect(view.viewport()->rect().center(), QSize(1, 1))); QList itemsAtCenter2 = scene.items(p); -- cgit v0.12 From cea8678e5fca8b33bbd5da057282888bc260a5c9 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Thu, 4 Jun 2009 16:46:36 +0200 Subject: Fix doc and auto-test regression. --- src/gui/graphicsview/qgraphicsscene.cpp | 2 +- tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 4734e74..d811ade 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1586,7 +1586,7 @@ QList QGraphicsScene::items() const /*! Returns all visible items at position \a pos in the scene. The items are - listed in descending Z order (i.e., the first item in the list is the + listed in descending stacking order (i.e., the first item in the list is the top-most item, and the last item is the bottom-most item). \sa itemAt() diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index 447de34..696a42d 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -2925,7 +2925,7 @@ void tst_QGraphicsView::task245469_itemsAtPointWithClip() QTest::qWait(100); QList itemsAtCenter = view.items(view.viewport()->rect().center()); - QCOMPARE(itemsAtCenter, (QList() << parent << child)); + QCOMPARE(itemsAtCenter, (QList() << child << parent)); QPolygonF p = view.mapToScene(QRect(view.viewport()->rect().center(), QSize(1, 1))); QList itemsAtCenter2 = scene.items(p); -- cgit v0.12 From 3d9d7d10c2c6a4aed4650572bc9f3c8bd5b899b5 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Thu, 11 Jun 2009 17:05:32 +0200 Subject: Kill one items_helper + one childItem helper and use the new recursive approach. --- src/gui/graphicsview/qgraphicsscene.cpp | 5 +- src/gui/graphicsview/qgraphicssceneindex.cpp | 232 ++++++++++++--------------- src/gui/graphicsview/qgraphicssceneindex_p.h | 7 +- 3 files changed, 110 insertions(+), 134 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 33232af..0a1cd2b 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1734,10 +1734,7 @@ QList QGraphicsScene::items(const QPointF &pos) const QList QGraphicsScene::items(const QRectF &rect, Qt::ItemSelectionMode mode) const { Q_D(const QGraphicsScene); - QList itemList; - //###d->index->items(rect, mode, Qt::AscendingOrder); - d->recursive_items_helper(0, rect, &itemList, QTransform(), QTransform(), mode, Qt::AscendingOrder); - return itemList; + return d->index->items(rect, mode, Qt::AscendingOrder); } /*! diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 6895911..954cef3 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -57,57 +57,121 @@ QGraphicsSceneIndexPrivate::QGraphicsSceneIndexPrivate(QGraphicsScene *scene) : { } -void QGraphicsSceneIndexPrivate::childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPointF &pos) const +void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRectF rect, + QList *items, + const QTransform &parentTransform, + const QTransform &viewTransform, + Qt::ItemSelectionMode mode, Qt::SortOrder order, + qreal parentOpacity) const { - bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); - if (parentClip && parent->d_ptr->isClippedAway()) - return; - // ### is this needed? - if (parentClip && !parent->boundingRect().contains(pos)) - return; + // Calculate opacity. + qreal opacity; + if (item) { + if (!item->d_ptr->visible) + return; + QGraphicsItem *p = item->d_ptr->parent; + bool itemIgnoresParentOpacity = item->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity; + bool parentDoesntPropagateOpacity = (p && (p->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)); + if (!itemIgnoresParentOpacity && !parentDoesntPropagateOpacity) { + opacity = parentOpacity * item->opacity(); + } else { + opacity = item->d_ptr->opacity; + } + if (opacity == 0.0 && !(item->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) + return; + } else { + opacity = parentOpacity; + } - QList &children = parent->d_ptr->children; - for (int i = 0; i < children.size(); ++i) { - QGraphicsItem *item = children.at(i); - if (item->d_ptr->transformData && !item->d_ptr->transformData->computedFullTransform().isInvertible()) - continue; + // Calculate the full transform for this item. + QTransform transform = parentTransform; + bool keep = false; + if (item) { + item->d_ptr->combineTransformFromParent(&transform, &viewTransform); + + // ### This does not take the clip into account. + QRectF brect = item->boundingRect(); + _q_adjustRect(&brect); + + keep = true; + if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) + keep = rect.contains(transform.mapRect(brect)) && rect != brect; + else + keep = rect.intersects(transform.mapRect(brect)); + + if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { + QPainterPath rectPath; + rectPath.addRect(rect); + keep = scene->d_func()->itemCollidesWithPath(item, transform.inverted().map(rectPath), mode); + } + } - // Skip invisible items and all their children. - if (item->d_ptr->isInvisible()) - continue; + bool childClip = (item && (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)); + bool dontProcessItem = !item || !keep; + bool dontProcessChildren = item && dontProcessItem && childClip; + + // Find and sort children. + QList &children = item ? item->d_ptr->children : const_cast(scene->d_func())->topLevelItems; + if (!dontProcessChildren) { + if (item && item->d_ptr->needSortChildren) { + item->d_ptr->needSortChildren = 0; + qStableSort(children.begin(), children.end(), qt_notclosestLeaf); + } else if (!item && scene->d_func()->needSortTopLevelItems) { + const_cast(scene->d_func())->needSortTopLevelItems = false; + qStableSort(children.begin(), children.end(), qt_notclosestLeaf); + } + } - bool keep = false; - if (!item->d_ptr->isClippedAway()) { - if (item->contains(item->mapFromParent(pos))) { - items->append(item); - keep = true; - } + childClip &= !dontProcessChildren & !children.isEmpty(); + + // Clip. + if (childClip) + rect &= transform.map(item->shape()).controlPointRect(); + + // Process children behind + int i = 0; + if (!dontProcessChildren) { + for (i = 0; i < children.size(); ++i) { + QGraphicsItem *child = children.at(i); + if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent)) + break; + recursive_items_helper(child, rect, items, transform, viewTransform, + mode, order, opacity); } + } - if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) - // Recurse into children. - childItems_helper(items, item, item->mapFromParent(pos)); + // Process item + if (!dontProcessItem) + items->append(item); + + // Process children in front + if (!dontProcessChildren) { + for (; i < children.size(); ++i) + recursive_items_helper(children.at(i), rect, items, transform, viewTransform, + mode, order, opacity); } -} + if (!item && order == Qt::AscendingOrder) { + int n = items->size(); + for (int i = 0; i < n / 2; ++i) { + QGraphicsItem *tmp = (*items)[n - i - 1]; + (*items)[n - i - 1] = (*items)[i]; + (*items)[i] = tmp; + } + } +} void QGraphicsSceneIndexPrivate::childItems_helper(QList *items, const QGraphicsItem *parent, - const QRectF &rect, - Qt::ItemSelectionMode mode) const + const QPointF &pos) const { bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); if (parentClip && parent->d_ptr->isClippedAway()) return; - QRectF adjustedRect(rect); - _q_adjustRect(&adjustedRect); - QRectF r = !parentClip ? adjustedRect : adjustedRect.intersected(adjustedItemBoundingRect(parent)); - if (r.isEmpty()) + // ### is this needed? + if (parentClip && !parent->boundingRect().contains(pos)) return; - QPainterPath path; QList &children = parent->d_ptr->children; for (int i = 0; i < children.size(); ++i) { QGraphicsItem *item = children.at(i); @@ -120,45 +184,18 @@ void QGraphicsSceneIndexPrivate::childItems_helper(QList *items bool keep = false; if (!item->d_ptr->isClippedAway()) { - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - QRectF mbr = item->mapRectToParent(br); - if (mode >= Qt::ContainsItemBoundingRect) { - // Rect intersects/contains item's bounding rect - if ((mode == Qt::IntersectsItemBoundingRect && QRectF_intersects(rect, mbr)) - || (mode == Qt::ContainsItemBoundingRect && rect != mbr && rect.contains(br))) { - items->append(item); - keep = true; - } - } else { - // Rect intersects/contains item's shape - if (QRectF_intersects(rect, mbr)) { - if (path == QPainterPath()) - path.addRect(rect); - if (scene->d_func()->itemCollidesWithPath(item, item->mapFromParent(path), mode)) { - items->append(item); - keep = true; - } - } + if (item->contains(item->mapFromParent(pos))) { + items->append(item); + keep = true; } } - if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) { + if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) // Recurse into children. - if (!item->d_ptr->transformData || item->d_ptr->transformData->computedFullTransform().type() <= QTransform::TxScale) { - // Rect - childItems_helper(items, item, item->mapRectFromParent(rect), mode); - } else { - // Polygon - childItems_helper(items, item, item->mapFromParent(rect), mode); - } - } + childItems_helper(items, item, item->mapFromParent(pos)); } } - void QGraphicsSceneIndexPrivate::childItems_helper(QList *items, const QGraphicsItem *parent, const QPolygonF &polygon, @@ -369,66 +406,9 @@ QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSe QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); - QList items; - - QPainterPath path; - - // The index returns a rough estimate of what items are inside the rect. - // Refine it by iterating through all returned items. - QRectF adjustedRect(rect); - _q_adjustRect(&adjustedRect); - foreach (QGraphicsItem *item, estimateItems(adjustedRect, order, deviceTransform)) { - // Find the item's scene transform in a clever way. - QTransform x = item->sceneTransform(); - bool keep = false; - - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - if (mode >= Qt::ContainsItemBoundingRect) { - // Rect intersects/contains item's bounding rect - QRectF mbr = x.mapRect(br); - if ((mode == Qt::IntersectsItemBoundingRect && QRectF_intersects(rect, mbr)) - || (mode == Qt::ContainsItemBoundingRect && rect != mbr && rect.contains(mbr))) { - items << item; - keep = true; - } - } else { - // Rect intersects/contains item's shape - if (QRectF_intersects(adjustedRect, x.mapRect(br))) { - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) { - if (path.isEmpty()) - path.addRect(rect); - if (d->scene->d_func()->itemCollidesWithPath(item, xinv.map(path), mode)) { - items << item; - keep = true; - } - } - } - } - - if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { - // Recurse into children that clip children. - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) { - if (x.type() <= QTransform::TxScale) { - // Rect - d->childItems_helper(&items, item, xinv.mapRect(rect), mode); - } else { - // Polygon - d->childItems_helper(&items, item, xinv.map(rect), mode); - } - } - } - } - //### Needed but it should be handle differently - if (order != Qt::SortOrder(-1)) - QGraphicsSceneBspTreeIndexPrivate::sortItems(&items, order, false); - return items; + QList itemList; + d->recursive_items_helper(0, rect, &itemList, QTransform(), deviceTransform, mode, order); + return itemList; } QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index 2014693..3a2cb27 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -70,16 +70,15 @@ class QGraphicsSceneIndexPrivate : public QObjectPrivate public: QGraphicsSceneIndexPrivate(QGraphicsScene *scene); + void recursive_items_helper(QGraphicsItem *item, QRectF rect, QList *items, + const QTransform &parentTransform, const QTransform &viewTransform, + Qt::ItemSelectionMode mode, Qt::SortOrder order, qreal parentOpacity = 1.0) const; void childItems_helper(QList *items, const QGraphicsItem *parent, const QPointF &pos) const; void childItems_helper(QList *items, const QGraphicsItem *parent, - const QRectF &rect, - Qt::ItemSelectionMode mode) const; - void childItems_helper(QList *items, - const QGraphicsItem *parent, const QPolygonF &polygon, Qt::ItemSelectionMode mode) const; void childItems_helper(QList *items, -- cgit v0.12 From da70cf2876cee57299dbeebb86c4c3881e3df721 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Mon, 15 Jun 2009 20:50:26 +0200 Subject: Kill items_helper and child_items_helper for ever. We have now on function recusrsive_item_helper that doing the job. To resolve different use cases we use concept of interceptors for QRectF, QPointF QPolygonF and QPainterPath. --- src/gui/graphicsview/qgraphicsscene.cpp | 5 + src/gui/graphicsview/qgraphicsscene_p.h | 2 + .../graphicsview/qgraphicsscenebsptreeindex_p.cpp | 3 +- .../graphicsview/qgraphicsscenebsptreeindex_p_p.h | 5 +- src/gui/graphicsview/qgraphicssceneindex.cpp | 408 ++++++--------------- src/gui/graphicsview/qgraphicssceneindex_p.h | 36 +- 6 files changed, 140 insertions(+), 319 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 0a1cd2b..eb06186 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -312,6 +312,11 @@ void QGraphicsScenePrivate::init() q->update(); } +QGraphicsScenePrivate *QGraphicsScenePrivate::get(QGraphicsScene *q) +{ + return q->d_func(); +} + void QGraphicsScenePrivate::_q_emitUpdated() { Q_Q(QGraphicsScene); diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index afdba7e..c63e121 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -85,6 +85,8 @@ public: QGraphicsScenePrivate(); void init(); + static QGraphicsScenePrivate *get(QGraphicsScene *q); + quint32 changedSignalMask; QGraphicsScene::ItemIndexMethod indexMethod; diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp index 97d0500..acadcbd 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp @@ -64,7 +64,7 @@ static inline int intmaxlog(int n) Constructs a private scene index. */ QGraphicsSceneBspTreeIndexPrivate::QGraphicsSceneBspTreeIndexPrivate(QGraphicsScene *scene) - : scene(scene), + : QGraphicsSceneIndexPrivate(scene), bspTreeDepth(0), indexTimerId(0), restartIndexTimer(false), @@ -175,7 +175,6 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() */ void QGraphicsSceneBspTreeIndexPrivate::purgeRemovedItems() { - Q_Q(QGraphicsSceneBspTreeIndex); if (!purgePending && removedItems.isEmpty()) return; diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p_p.h index 098b278..30f6e26 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p_p.h @@ -57,7 +57,7 @@ #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW -#include +#include #include QT_BEGIN_NAMESPACE @@ -66,13 +66,12 @@ static const int QGRAPHICSSCENE_INDEXTIMER_TIMEOUT = 2000; class QGraphicsScene; -class QGraphicsSceneBspTreeIndexPrivate : public QObjectPrivate +class QGraphicsSceneBspTreeIndexPrivate : public QGraphicsSceneIndexPrivate { Q_DECLARE_PUBLIC(QGraphicsSceneBspTreeIndex) public: QGraphicsSceneBspTreeIndexPrivate(QGraphicsScene *scene); - QGraphicsScene *scene; QGraphicsSceneBspTree bsp; QRectF sceneRect; int bspTreeDepth; diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 954cef3..8d18806 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -50,14 +50,88 @@ QT_BEGIN_NAMESPACE +class QGraphicsSceneIndexRectIntersector : public QGraphicsSceneIndexIntersector +{ +public: + QGraphicsSceneIndexRectIntersector(QGraphicsScene *scene) : QGraphicsSceneIndexIntersector(scene) {} + bool intersect(const QRectF &brect) const + { + bool keep = true; + if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) + keep = rect.contains(transform.mapRect(brect)) && rect != brect; + else + keep = rect.intersects(transform.mapRect(brect)); + + if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { + QPainterPath rectPath; + rectPath.addRect(rect); + keep = QGraphicsScenePrivate::get(scene)->itemCollidesWithPath(item, transform.inverted().map(rectPath), mode); + } + return keep; + } +}; + +class QGraphicsSceneIndexPointIntersector : public QGraphicsSceneIndexIntersector +{ +public: + QGraphicsSceneIndexPointIntersector(QGraphicsScene *scene) : QGraphicsSceneIndexIntersector(scene) {} + bool intersect(const QRectF &brect) const + { + bool keep = false; + if (rect.intersects(transform.mapRect(brect))) + if (item->contains(transform.inverted().map(pos))) + keep = true; + if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { + QPainterPath rectPath; + rectPath.addRect(rect); + keep = QGraphicsScenePrivate::get(scene)->itemCollidesWithPath(item, transform.inverted().map(rectPath), mode); + } + return keep; + } + QPointF pos; +}; + +class QGraphicsSceneIndexPathIntersector : public QGraphicsSceneIndexIntersector +{ +public: + QGraphicsSceneIndexPathIntersector(QGraphicsScene *scene) : QGraphicsSceneIndexIntersector(scene) {} + bool intersect(const QRectF &brect) const + { + bool keep = true; + if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) + keep = rect.contains(transform.mapRect(brect)) && rect != brect; + else + keep = rect.intersects(transform.mapRect(brect)); + + if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { + keep = QGraphicsScenePrivate::get(scene)->itemCollidesWithPath(item, transform.inverted().map(path), mode); + } + return keep; + } + QPainterPath path; +}; + /*! Constructs a private scene index. */ QGraphicsSceneIndexPrivate::QGraphicsSceneIndexPrivate(QGraphicsScene *scene) : scene(scene) { + pointIntersector = new QGraphicsSceneIndexPointIntersector(scene); + rectIntersector = new QGraphicsSceneIndexRectIntersector(scene); + pathIntersector = new QGraphicsSceneIndexPathIntersector(scene); +} + +/*! + Destructor of private scene index. +*/ +QGraphicsSceneIndexPrivate::~QGraphicsSceneIndexPrivate() +{ + delete pointIntersector; + delete rectIntersector; + delete pathIntersector; } -void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRectF rect, +void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QGraphicsSceneIndexIntersector *intersector, QList *items, const QTransform &parentTransform, const QTransform &viewTransform, @@ -93,17 +167,10 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe QRectF brect = item->boundingRect(); _q_adjustRect(&brect); - keep = true; - if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) - keep = rect.contains(transform.mapRect(brect)) && rect != brect; - else - keep = rect.intersects(transform.mapRect(brect)); - - if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { - QPainterPath rectPath; - rectPath.addRect(rect); - keep = scene->d_func()->itemCollidesWithPath(item, transform.inverted().map(rectPath), mode); - } + //We fill the intersector with needed informations + intersector->transform = transform; + intersector->item = item; + keep = intersector->intersect(brect); } bool childClip = (item && (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)); @@ -126,7 +193,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe // Clip. if (childClip) - rect &= transform.map(item->shape()).controlPointRect(); + intersector->rect &= transform.map(item->shape()).controlPointRect(); // Process children behind int i = 0; @@ -135,7 +202,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe QGraphicsItem *child = children.at(i); if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent)) break; - recursive_items_helper(child, rect, items, transform, viewTransform, + recursive_items_helper(child, intersector, items, transform, viewTransform, mode, order, opacity); } } @@ -147,7 +214,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe // Process children in front if (!dontProcessChildren) { for (; i < children.size(); ++i) - recursive_items_helper(children.at(i), rect, items, transform, viewTransform, + recursive_items_helper(children.at(i), intersector, items, transform, viewTransform, mode, order, opacity); } @@ -161,156 +228,6 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe } } -void QGraphicsSceneIndexPrivate::childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPointF &pos) const -{ - bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); - if (parentClip && parent->d_ptr->isClippedAway()) - return; - // ### is this needed? - if (parentClip && !parent->boundingRect().contains(pos)) - return; - - QList &children = parent->d_ptr->children; - for (int i = 0; i < children.size(); ++i) { - QGraphicsItem *item = children.at(i); - if (item->d_ptr->transformData && !item->d_ptr->transformData->computedFullTransform().isInvertible()) - continue; - - // Skip invisible items and all their children. - if (item->d_ptr->isInvisible()) - continue; - - bool keep = false; - if (!item->d_ptr->isClippedAway()) { - if (item->contains(item->mapFromParent(pos))) { - items->append(item); - keep = true; - } - } - - if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) - // Recurse into children. - childItems_helper(items, item, item->mapFromParent(pos)); - } -} - -void QGraphicsSceneIndexPrivate::childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPolygonF &polygon, - Qt::ItemSelectionMode mode) const -{ - bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); - if (parentClip && parent->d_ptr->isClippedAway()) - return; - QRectF polyRect(polygon.boundingRect()); - _q_adjustRect(&polyRect); - QRectF r = !parentClip ? polyRect : polyRect.intersected(adjustedItemBoundingRect(parent)); - if (r.isEmpty()) - return; - - QPainterPath path; - QList &children = parent->d_ptr->children; - for (int i = 0; i < children.size(); ++i) { - QGraphicsItem *item = children.at(i); - if (item->d_ptr->transformData && !item->d_ptr->transformData->computedFullTransform().isInvertible()) - continue; - - // Skip invisible items. - if (item->d_ptr->isInvisible()) - continue; - - bool keep = false; - if (!item->d_ptr->isClippedAway()) { - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - if (mode >= Qt::ContainsItemBoundingRect) { - // Polygon contains/intersects item's bounding rect - if (path == QPainterPath()) - path.addPolygon(polygon); - if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br))) - || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) { - items->append(item); - keep = true; - } - } else { - // Polygon contains/intersects item's shape - if (QRectF_intersects(polyRect, item->mapRectToParent(br))) { - if (path == QPainterPath()) - path.addPolygon(polygon); - if (scene->d_func()->itemCollidesWithPath(item, item->mapFromParent(path), mode)) { - items->append(item); - keep = true; - } - } - } - } - - if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) { - // Recurse into children that clip children. - childItems_helper(items, item, item->mapFromParent(polygon), mode); - } - } -} - -void QGraphicsSceneIndexPrivate::childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPainterPath &path, - Qt::ItemSelectionMode mode) const -{ - bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); - if (parentClip && parent->d_ptr->isClippedAway()) - return; - QRectF pathRect(path.boundingRect()); - _q_adjustRect(&pathRect); - QRectF r = !parentClip ? pathRect : pathRect.intersected(adjustedItemBoundingRect(parent)); - if (r.isEmpty()) - return; - - QList &children = parent->d_ptr->children; - for (int i = 0; i < children.size(); ++i) { - QGraphicsItem *item = children.at(i); - if (item->d_ptr->transformData && !item->d_ptr->transformData->computedFullTransform().isInvertible()) - continue; - - // Skip invisible items. - if (item->d_ptr->isInvisible()) - continue; - - bool keep = false; - if (!item->d_ptr->isClippedAway()) { - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - if (mode >= Qt::ContainsItemBoundingRect) { - // Polygon contains/intersects item's bounding rect - if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br))) - || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) { - items->append(item); - keep = true; - } - } else { - // Path contains/intersects item's shape - if (QRectF_intersects(pathRect, item->mapRectToParent(br))) { - if (scene->d_func()->itemCollidesWithPath(item, item->mapFromParent(path), mode)) { - items->append(item); - keep = true; - } - } - } - } - - if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) { - // Recurse into children that clip children. - childItems_helper(items, item, item->mapFromParent(path), mode); - } - } -} - /*! Constructs an abstract scene index. */ @@ -363,162 +280,50 @@ QRectF QGraphicsSceneIndex::indexedRect() const QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); - QList items; - - // The index returns a rough estimate of what items are inside the rect. - // Refine it by iterating through all returned items. - QRectF adjustedRect = QRectF(pos, QSize(1,1)); - foreach (QGraphicsItem *item, estimateItems(adjustedRect, order, deviceTransform)) { - // Find the item's scene transform in a clever way. - QTransform x = item->sceneTransform(); - bool keep = false; - - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - // Rect intersects/contains item's shape - if (QRectF_intersects(adjustedRect, x.mapRect(br))) { - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) { - if (item->contains(xinv.map(pos))) { - items << item; - keep = true; - } - } - } - - if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { - // Recurse into children that clip children. - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) - d->childItems_helper(&items, item, xinv.map(pos)); - } - } - //### Needed but it should be handle differently - if (order != Qt::SortOrder(-1)) - QGraphicsSceneBspTreeIndexPrivate::sortItems(&items, order, false); - return items; + QList itemList; + d->pointIntersector->mode = mode; + d->pointIntersector->rect = QRectF(pos, QSize(1,1)); + d->pointIntersector->pos = pos; + d->recursive_items_helper(0, d->pointIntersector, &itemList, QTransform(), deviceTransform, mode, order); + return itemList; } QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); QList itemList; - d->recursive_items_helper(0, rect, &itemList, QTransform(), deviceTransform, mode, order); + d->rectIntersector->mode = mode; + d->rectIntersector->rect = rect; + d->recursive_items_helper(0, d->rectIntersector, &itemList, QTransform(), deviceTransform, mode, order); return itemList; } QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); - QList items; - + QList itemList; QRectF polyRect(polygon.boundingRect()); _q_adjustRect(&polyRect); + d->pathIntersector->mode = mode; + d->pathIntersector->rect = polyRect; QPainterPath path; - - // The index returns a rough estimate of what items are inside the rect. - // Refine it by iterating through all returned items. - foreach (QGraphicsItem *item, estimateItems(polyRect, order, deviceTransform)) { - // Find the item's scene transform in a clever way. - QTransform x = item->sceneTransform(); - bool keep = false; - - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - if (mode >= Qt::ContainsItemBoundingRect) { - // Polygon contains/intersects item's bounding rect - if (path == QPainterPath()) - path.addPolygon(polygon); - if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(x.mapRect(br))) - || (mode == Qt::ContainsItemBoundingRect && path.contains(x.mapRect(br)))) { - items << item; - keep = true; - } - } else { - // Polygon contains/intersects item's shape - if (QRectF_intersects(polyRect, x.mapRect(br))) { - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) { - if (path == QPainterPath()) - path.addPolygon(polygon); - if (d->scene->d_func()->itemCollidesWithPath(item, xinv.map(path), mode)) { - items << item; - keep = true; - } - } - } - } - - if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { - // Recurse into children that clip children. - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) - d->childItems_helper(&items, item, xinv.map(polygon), mode); - } - } - //### Needed but it should be handle differently - if (order != Qt::SortOrder(-1)) - QGraphicsSceneBspTreeIndexPrivate::sortItems(&items, order, false); - return items; + path.addPolygon(polygon); + d->pathIntersector->path = path; + d->recursive_items_helper(0, d->pathIntersector, &itemList, QTransform(), deviceTransform, mode, order); + return itemList; } + QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); - QList items; + QList itemList; QRectF pathRect(path.controlPointRect()); _q_adjustRect(&pathRect); - - // The index returns a rough estimate of what items are inside the rect. - // Refine it by iterating through all returned items. - foreach (QGraphicsItem *item, estimateItems(pathRect, order, deviceTransform)) { - // Find the item's scene transform in a clever way. - QTransform x = item->sceneTransform(); - bool keep = false; - - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - const QRectF br(adjustedItemBoundingRect(item)); - if (mode >= Qt::ContainsItemBoundingRect) { - // Path contains/intersects item's bounding rect - if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(x.mapRect(br))) - || (mode == Qt::ContainsItemBoundingRect && path.contains(x.mapRect(br)))) { - items << item; - keep = true; - } - } else { - // Path contains/intersects item's shape - if (QRectF_intersects(pathRect, x.mapRect(br))) { - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) { - if (d->scene->d_func()->itemCollidesWithPath(item, xinv.map(path), mode)) { - items << item; - keep = true; - } - } - } - } - - if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) - d->childItems_helper(&items, item, xinv.map(path), mode); - } - } - //### Needed but it should be handle differently - if (order != Qt::SortOrder(-1)) - QGraphicsSceneBspTreeIndexPrivate::sortItems(&items, order, false); - return items; + d->pathIntersector->mode = mode; + d->pathIntersector->rect = pathRect; + d->pathIntersector->path = path; + d->recursive_items_helper(0, d->pathIntersector, &itemList, QTransform(), deviceTransform, mode, order); + return itemList; } /*! @@ -592,6 +397,8 @@ void QGraphicsSceneIndex::deleteItem(QGraphicsItem *item) */ void QGraphicsSceneIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value) { + //Q_UNUSED(item); + //Q_UNUSED(value); } /*! @@ -601,6 +408,7 @@ void QGraphicsSceneIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem:: */ void QGraphicsSceneIndex::prepareBoundingRectChange(const QGraphicsItem *item) { + //Q_UNUSED(item); } /*! diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index 3a2cb27..d0d181b 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -63,30 +63,38 @@ QT_BEGIN_NAMESPACE class QGraphicsScene; +class QGraphicsSceneIndexIntersector; +class QGraphicsSceneIndexRectIntersector; +class QGraphicsSceneIndexPointIntersector; +class QGraphicsSceneIndexPathIntersector; class QGraphicsSceneIndexPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QGraphicsSceneIndex) public: QGraphicsSceneIndexPrivate(QGraphicsScene *scene); + ~QGraphicsSceneIndexPrivate(); - void recursive_items_helper(QGraphicsItem *item, QRectF rect, QList *items, + void recursive_items_helper(QGraphicsItem *item, QGraphicsSceneIndexIntersector *intersector, QList *items, const QTransform &parentTransform, const QTransform &viewTransform, Qt::ItemSelectionMode mode, Qt::SortOrder order, qreal parentOpacity = 1.0) const; - - void childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPointF &pos) const; - void childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPolygonF &polygon, - Qt::ItemSelectionMode mode) const; - void childItems_helper(QList *items, - const QGraphicsItem *parent, - const QPainterPath &path, - Qt::ItemSelectionMode mode) const; - QGraphicsScene *scene; + QGraphicsSceneIndexPointIntersector *pointIntersector; + QGraphicsSceneIndexRectIntersector *rectIntersector; + QGraphicsSceneIndexPathIntersector *pathIntersector; +}; + +class QGraphicsSceneIndexIntersector +{ +public: + QGraphicsSceneIndexIntersector(QGraphicsScene *scene) : scene(scene) { } + virtual ~QGraphicsSceneIndexIntersector() { } + virtual bool intersect(const QRectF &rect) const = 0; + Qt::ItemSelectionMode mode; + QGraphicsItem *item; + QGraphicsScene *scene; + QRectF rect; + QTransform transform; }; QT_END_NAMESPACE -- cgit v0.12 From 3dce31e5eb0fac43d445fb9664f1b68f4cd4c11f Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 16 Jun 2009 10:26:34 +0200 Subject: Warnings -- --- src/gui/graphicsview/qgraphicssceneindex.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 8d18806..3c4efe7 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -395,10 +395,11 @@ void QGraphicsSceneIndex::deleteItem(QGraphicsItem *item) \sa GraphicsItemChange */ -void QGraphicsSceneIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value) +void QGraphicsSceneIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) { - //Q_UNUSED(item); - //Q_UNUSED(value); + Q_UNUSED(item); + Q_UNUSED(change); + Q_UNUSED(value); } /*! @@ -408,7 +409,7 @@ void QGraphicsSceneIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem:: */ void QGraphicsSceneIndex::prepareBoundingRectChange(const QGraphicsItem *item) { - //Q_UNUSED(item); + Q_UNUSED(item); } /*! @@ -418,6 +419,7 @@ void QGraphicsSceneIndex::prepareBoundingRectChange(const QGraphicsItem *item) */ void QGraphicsSceneIndex::sceneRectChanged(const QRectF &rect) { + Q_UNUSED(rect); } QT_END_NAMESPACE -- cgit v0.12 From 2ceb72068fbb9157a058a1788863b68a12d25646 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 16 Jun 2009 11:41:35 +0200 Subject: Fix all documentation warnings. --- src/gui/graphicsview/qgraphicsitem.h | 2 - src/gui/graphicsview/qgraphicsscene.cpp | 50 +++++++++---- src/gui/graphicsview/qgraphicssceneindex.cpp | 106 ++++++++++++++++++++++----- 3 files changed, 125 insertions(+), 33 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index 6194249..56a4a3b 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -418,8 +418,6 @@ protected: virtual void setExtension(Extension extension, const QVariant &variant); virtual QVariant extension(const QVariant &variant) const; - bool operator<(const QGraphicsItem *other) const; - protected: QGraphicsItem(QGraphicsItemPrivate &dd, QGraphicsItem *parent, QGraphicsScene *scene); diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 6e08a76..0729a9d 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -201,6 +201,8 @@ however, is done in constant time. This approach is ideal for dynamic scenes, where many items are added, moved or removed continuously. + \omitvalue CustomIndex + \sa setItemIndexMethod(), bspTreeDepth */ @@ -312,6 +314,9 @@ void QGraphicsScenePrivate::init() q->update(); } +/*! + \internal +*/ QGraphicsScenePrivate *QGraphicsScenePrivate::get(QGraphicsScene *q) { return q->d_func(); @@ -454,11 +459,11 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) markDirty(item, QRectF(), false, false, false, false, /*removingItemFromScene=*/true); if (item->d_ptr->inDestructor) { - // Can potentially call item->boundingRect() (virtual function), that's why - // we only can call this function if the item is not in its destructor. + // The item is actually in its destructor, we call the special method in the index. index->deleteItem(item); } else { - // Remove it from the index properly + // Can potentially call item->boundingRect() (virtual function), that's why + // we only can call this function if the item is not in its destructor. index->removeItem(item); } @@ -1569,6 +1574,13 @@ void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method) d->indexMethod = method; } +/*! + \brief the item indexing method. + This method allow to apply an indexing algorithm \a index to the scene, to speed up + item discovery functions like items() and itemAt(). + + \sa sceneIndex(), QGraphicsSceneIndex +*/ void QGraphicsScene::setSceneIndex(QGraphicsSceneIndex *index) { Q_D(QGraphicsScene); @@ -1583,6 +1595,11 @@ void QGraphicsScene::setSceneIndex(QGraphicsSceneIndex *index) } } +/*! + This method return the current indexing algorithm of the scene. + + \sa setSceneIndex(), QGraphicsSceneIndex +*/ QGraphicsSceneIndex* QGraphicsScene::sceneIndex() const { Q_D(const QGraphicsScene); @@ -1784,10 +1801,13 @@ QList QGraphicsScene::items(const QPainterPath &path, Qt::ItemS } /*! - Returns all visible items at position \a pos in the scene. + Returns all visible items that, depending on \a mode, are at the specified \a pos + and return a list sorted using \a order. The default value for \a mode is Qt::IntersectsItemShape; all items whose - exact shape intersects with or is contained by \a path are returned. + exact shape intersects with \a pos are returned. + + \a deviceTransform is the transformation apply to the view. \sa itemAt() */ @@ -1798,15 +1818,15 @@ QList QGraphicsScene::items(const QPointF &pos, Qt::ItemSelecti } /*! - \fn QList QGraphicsScene::items(const QRectF &rectangle, Qt::SortOrder order, const QTransform &deviceTransform) const - \overload Returns all visible items that, depending on \a mode, are either inside or - intersect with the specified \a rectangle. + intersect with the specified \a rect and return a list sorted using \a order. The default value for \a mode is Qt::IntersectsItemShape; all items whose - exact shape intersects with or is contained by \a rectangle are returned. + exact shape intersects with or is contained by \a rect are returned. + + \a deviceTransform is the transformation apply to the view. \sa itemAt() */ @@ -1820,11 +1840,13 @@ QList QGraphicsScene::items(const QRectF &rect, Qt::ItemSelecti \overload Returns all visible items that, depending on \a mode, are either inside or - intersect with the polygon \a polygon. + intersect with the specified \a polygon and return a list sorted using \a order. The default value for \a mode is Qt::IntersectsItemShape; all items whose exact shape intersects with or is contained by \a polygon are returned. + \a deviceTransform is the transformation apply to the view. + \sa itemAt() */ QList QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const @@ -1834,14 +1856,16 @@ QList QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemS } /*! - \overload + \overload - Returns all visible items that, depending on \a path, are either inside or - intersect with the path \a path. + Returns all visible items that, depending on \a mode, are either inside or + intersect with the specified \a path and return a list sorted using \a order. The default value for \a mode is Qt::IntersectsItemShape; all items whose exact shape intersects with or is contained by \a path are returned. + \a deviceTransform is the transformation apply to the view. + \sa itemAt() */ QList QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 3c4efe7..b713452 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -38,6 +38,22 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ +/*! + \class QGraphicsSceneIndex + \brief The QGraphicsSceneIndex class provides a base class to implement + a custom indexing algorithm for discovering items in QGraphicsScene. + \since 4.6 + \ingroup multimedia + \ingroup graphicsview-api + \mainclass + + The QGraphicsSceneIndex class provides a base class to implement + a custom indexing algorithm for discovering items in QGraphicsScene. You + need to subclass it and reimplement addItem, removeItem, estimateItems + and items in order to have an functional indexing. + + \sa QGraphicsScene, QGraphicsView +*/ #include "qgraphicssceneindex.h" #include "qgraphicssceneindex_p.h" @@ -229,7 +245,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QGr } /*! - Constructs an abstract scene index. + Constructs an abstract scene index for a given \a scene. */ QGraphicsSceneIndex::QGraphicsSceneIndex(QGraphicsScene *scene) : QObject(*new QGraphicsSceneIndexPrivate(scene), scene) @@ -271,12 +287,17 @@ QRectF QGraphicsSceneIndex::indexedRect() const } /*! - \fn QList items() const = 0 + \fn QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const - This pure virtual function return the list of items that are actually in the index. + Returns all visible items that, depending on \a mode, are at the specified \a pos + and return a list sorted using \a order. -*/ + The default value for \a mode is Qt::IntersectsItemShape; all items whose + exact shape intersects with \a pos are returned. + + \a deviceTransform is the transformation apply to the view. +*/ QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); @@ -288,6 +309,20 @@ QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSe return itemList; } +/*! + \fn QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const + + \overload + + Returns all visible items that, depending on \a mode, are either inside or + intersect with the specified \a rect and return a list sorted using \a order. + + The default value for \a mode is Qt::IntersectsItemShape; all items whose + exact shape intersects with or is contained by \a rect are returned. + + \a deviceTransform is the transformation apply to the view. + +*/ QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); @@ -298,6 +333,20 @@ QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSe return itemList; } +/*! + \fn QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const + + \overload + + Returns all visible items that, depending on \a mode, are either inside or + intersect with the specified \a polygon and return a list sorted using \a order. + + The default value for \a mode is Qt::IntersectsItemShape; all items whose + exact shape intersects with or is contained by \a polygon are returned. + + \a deviceTransform is the transformation apply to the view. + +*/ QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); @@ -313,6 +362,20 @@ QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt:: return itemList; } +/*! + \fn QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const + + \overload + + Returns all visible items that, depending on \a mode, are either inside or + intersect with the specified \a path and return a list sorted using \a order. + + The default value for \a mode is Qt::IntersectsItemShape; all items whose + exact shape intersects with or is contained by \a path are returned. + + \a deviceTransform is the transformation apply to the view. + +*/ QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); @@ -327,8 +390,9 @@ QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt:: } /*! - This pure virtual function return an estimation of items at position \a pos. - + This virtual function return an estimation of items at position \a point. + This method return a list sorted using \a order. + \a deviceTransform is the transformation apply to the view. */ QList QGraphicsSceneIndex::estimateItems(const QPointF &point, Qt::SortOrder order, const QTransform &deviceTransform) const { @@ -336,12 +400,18 @@ QList QGraphicsSceneIndex::estimateItems(const QPointF &point, } /*! - \fn virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const = 0 + \fn virtual QList QGraphicsSceneIndex::estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const = 0 This pure virtual function return an estimation of items in the \a rect. + This method return a list sorted using \a order. + \a deviceTransform is the transformation apply to the view. */ +/*! + \fn virtual QList QGraphicsSceneIndex::items(Qt::SortOrder order = Qt::AscendingOrder) const = 0; + This pure virtual function all items in the index and sort them using \a order. +*/ /*! This virtual function removes all items in the scene index. @@ -353,23 +423,23 @@ void QGraphicsSceneIndex::clear() } /*! - \fn virtual void addItem(QGraphicsItem *item) = 0 + \fn virtual void QGraphicsSceneIndex::addItem(QGraphicsItem *item) = 0 - This pure virtual function inserts an item to the scene index. + This pure virtual function inserts an \a item to the scene index. \sa removeItem(), deleteItem() */ /*! - \fn virtual void removeItem(QGraphicsItem *item) = 0 + \fn virtual void QGraphicsSceneIndex::removeItem(QGraphicsItem *item) = 0 - This pure virtual function removes an item to the scene index. + This pure virtual function removes an \a item to the scene index. \sa addItem(), deleteItem() */ /*! - This method is called when an item has been deleted. + This method is called when an \a item has been deleted. The default implementation call removeItem. Be carefull, if your implementation of removeItem use pure virtual method of QGraphicsItem like boundingRect(), then you should reimplement @@ -384,7 +454,7 @@ void QGraphicsSceneIndex::deleteItem(QGraphicsItem *item) /*! This virtual function is called by QGraphicsItem to notify the index - that some part of the item's state changes. By reimplementing this + that some part of the \a item 's state changes. By reimplementing this function, your can react to a change, and in some cases, (depending on \a change,) adjustments in the index can be made. @@ -393,7 +463,7 @@ void QGraphicsSceneIndex::deleteItem(QGraphicsItem *item) The default implementation does nothing. - \sa GraphicsItemChange + \sa QGraphicsItem::GraphicsItemChange */ void QGraphicsSceneIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) { @@ -403,9 +473,9 @@ void QGraphicsSceneIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem:: } /*! - Notify the index for a geometry change of an item. + Notify the index for a geometry change of an \a item. - \sa QGraphicsItem::prepareGeometryChange + \sa QGraphicsItem::prepareGeometryChange() */ void QGraphicsSceneIndex::prepareBoundingRectChange(const QGraphicsItem *item) { @@ -414,8 +484,8 @@ void QGraphicsSceneIndex::prepareBoundingRectChange(const QGraphicsItem *item) /*! This virtual function is called when the scene changes its bounding - rectangle. - \sa QGraphicsScene::sceneRect + rectangle. \a rect is the new value of the scene rectangle. + \sa QGraphicsScene::sceneRect() */ void QGraphicsSceneIndex::sceneRectChanged(const QRectF &rect) { -- cgit v0.12 From 0fa15d71015adfd8895ef41a082fb9479bf4bb3d Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 16 Jun 2009 13:45:36 +0200 Subject: Remove old legacy and fix documentation. --- src/gui/graphicsview/graphicsview.pri | 1 + src/gui/graphicsview/qgraphicsscene.cpp | 12 +- src/gui/graphicsview/qgraphicsscene_p.h | 4 +- .../graphicsview/qgraphicsscenebsptreeindex_p.cpp | 145 ++++++++++++++++++++- .../graphicsview/qgraphicsscenebsptreeindex_p.h | 5 +- src/gui/graphicsview/qgraphicssceneindex.cpp | 27 ++++ src/gui/graphicsview/qgraphicsscenelinearindex_p.h | 37 +++--- 7 files changed, 198 insertions(+), 33 deletions(-) diff --git a/src/gui/graphicsview/graphicsview.pri b/src/gui/graphicsview/graphicsview.pri index 9dc4112..a4d142a 100644 --- a/src/gui/graphicsview/graphicsview.pri +++ b/src/gui/graphicsview/graphicsview.pri @@ -18,6 +18,7 @@ SOURCES += graphicsview/qgraphicsitem.cpp \ graphicsview/qgraphicsscene.cpp \ graphicsview/qgraphicsscene_bsp.cpp \ graphicsview/qgraphicsscenebsptreeindex_p.cpp \ + graphicsview/qgraphicsscenelinearindex.cpp \ graphicsview/qgraphicssceneindex.cpp \ graphicsview/qgraphicssceneevent.cpp \ graphicsview/qgraphicsview.cpp diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 0729a9d..328ab4c 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -271,9 +271,8 @@ static void _q_hoverFromMouseEvent(QGraphicsSceneHoverEvent *hover, const QGraph QGraphicsScenePrivate::QGraphicsScenePrivate() : changedSignalMask(0), indexMethod(QGraphicsScene::BspTreeIndex), - bspTreeDepth(0), - lastItemCount(0), index(0), + lastItemCount(0), hasSceneRect(false), updateAll(false), calledEmitUpdated(false), @@ -1642,14 +1641,11 @@ int QGraphicsScene::bspTreeDepth() const { Q_D(const QGraphicsScene); QGraphicsSceneBspTreeIndex *bspTree = qobject_cast(d->index); - return bspTree ? bspTree->bspDepth() : 0; + return bspTree ? bspTree->bspTreeDepth() : 0; } void QGraphicsScene::setBspTreeDepth(int depth) { Q_D(QGraphicsScene); - if (d->bspTreeDepth == depth) - return; - if (depth < 0) { qWarning("QGraphicsScene::setBspTreeDepth: invalid depth %d ignored; must be >= 0", depth); return; @@ -1660,8 +1656,10 @@ void QGraphicsScene::setBspTreeDepth(int depth) qWarning("QGraphicsScene::setBspTreeDepth: can not apply if indexing method is not BSP"); return; } + if (bspTree->bspTreeDepth() == depth) + return; - bspTree->setBspDepth(depth); + bspTree->setBspTreeDepth(depth); } /*! diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index c63e121..db401ef 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -90,12 +90,10 @@ public: quint32 changedSignalMask; QGraphicsScene::ItemIndexMethod indexMethod; - int bspTreeDepth; + QGraphicsSceneIndex *index; int lastItemCount; - QGraphicsSceneIndex *index; - QRectF sceneRect; bool hasSceneRect; QRectF growingItemsBoundingRect; diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp index acadcbd..b19248a 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp @@ -39,6 +39,40 @@ ** ****************************************************************************/ +/*! + \class QGraphicsSceneBspTreeIndex + \brief The QGraphicsSceneBspTreeIndex class provides an implementation of + a BSP indexing algorithm for discovering items in QGraphicsScene. + \since 4.6 + \ingroup multimedia + \ingroup graphicsview-api + \mainclass + + QGraphicsSceneBspTreeIndex index use a BSP(Binary Space Partitioning) + implementation to discover items quickly. This implementation is + very efficient for static scene. It has a depth that you can set. + The depth directly affects performance and memory usage; the latter + growing exponentially with the depth of the tree. With an optimal tree + depth, the index can instantly determine the locality of items, even + for scenes with thousands or millions of items. This also greatly improves + rendering performance. + + By default, the value is 0, in which case Qt will guess a reasonable + default depth based on the size, location and number of items in the + scene. If these parameters change frequently, however, you may experience + slowdowns as the index retunes the depth internally. You can avoid + potential slowdowns by fixating the tree depth through setting this + property. + + The depth of the tree and the size of the scene rectangle decide the + granularity of the scene's partitioning. The size of each scene segment is + determined by the following algorithm: + + The BSP tree has an optimal size when each segment contains between 0 and + 10 items. + + \sa QGraphicsScene, QGraphicsView, QGraphicsSceneIndex +*/ #include "qgraphicsscenebsptreeindex_p.h" @@ -61,7 +95,7 @@ static inline int intmaxlog(int n) } /*! - Constructs a private scene index. + Constructs a private scene bsp index. */ QGraphicsSceneBspTreeIndexPrivate::QGraphicsSceneBspTreeIndexPrivate(QGraphicsScene *scene) : QGraphicsSceneIndexPrivate(scene), @@ -78,6 +112,11 @@ QGraphicsSceneBspTreeIndexPrivate::QGraphicsSceneBspTreeIndexPrivate(QGraphicsSc /*! + This method will update the BSP index by removing the items from the temporary + unindexed list and add them in the indexedItems list. This will also + update the growingItemsBoundingRect if needed. This will update the BSP + implementation as well. + \internal */ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() @@ -223,6 +262,9 @@ void QGraphicsSceneBspTreeIndexPrivate::resetIndex() startIndexTimer(); } +/*! + \internal +*/ void QGraphicsSceneBspTreeIndexPrivate::climbTree(QGraphicsItem *item, int *stackingOrder) { if (!item->d_ptr->children.isEmpty()) { @@ -244,6 +286,9 @@ void QGraphicsSceneBspTreeIndexPrivate::climbTree(QGraphicsItem *item, int *stac } } +/*! + \internal +*/ void QGraphicsSceneBspTreeIndexPrivate::_q_updateSortCache() { Q_Q(QGraphicsSceneBspTreeIndex); @@ -268,6 +313,9 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateSortCache() climbTree(topLevels.at(i), &stackingOrder); } +/*! + \internal +*/ void QGraphicsSceneBspTreeIndexPrivate::invalidateSortCache() { Q_Q(QGraphicsSceneBspTreeIndex); @@ -342,6 +390,11 @@ bool QGraphicsSceneBspTreeIndexPrivate::closestItemLast_withoutCache(const QGrap return closestItemFirst_withoutCache(item2, item1); } +/*! + Sort a list of \a itemList in a specific \a order and use the cache if requested. + + \internal +*/ void QGraphicsSceneBspTreeIndexPrivate::sortItems(QList *itemList, Qt::SortOrder order, bool sortCacheEnabled) { @@ -360,12 +413,19 @@ void QGraphicsSceneBspTreeIndexPrivate::sortItems(QList *itemLi } } +/*! + Constructs a BSP scene index for the given \a scene. +*/ QGraphicsSceneBspTreeIndex::QGraphicsSceneBspTreeIndex(QGraphicsScene *scene) : QGraphicsSceneIndex(*new QGraphicsSceneBspTreeIndexPrivate(scene), scene) { } +/*! + \reimp + Return the rect indexed by the BSP index. +*/ QRectF QGraphicsSceneBspTreeIndex::indexedRect() const { Q_D(const QGraphicsSceneBspTreeIndex); @@ -373,6 +433,10 @@ QRectF QGraphicsSceneBspTreeIndex::indexedRect() const return scene()->d_func()->hasSceneRect ? scene()->d_func()->sceneRect : scene()->d_func()->growingItemsBoundingRect; } +/*! + \reimp + Clear the all the BSP index. +*/ void QGraphicsSceneBspTreeIndex::clear() { Q_D(QGraphicsSceneBspTreeIndex); @@ -383,6 +447,9 @@ void QGraphicsSceneBspTreeIndex::clear() d->unindexedItems.clear(); } +/*! + Add the \a item into the BSP index. +*/ void QGraphicsSceneBspTreeIndex::addItem(QGraphicsItem *item) { Q_D(QGraphicsSceneBspTreeIndex); @@ -405,6 +472,7 @@ void QGraphicsSceneBspTreeIndex::addItem(QGraphicsItem *item) } /*! + This really add the item in the BSP. \internal */ void QGraphicsSceneBspTreeIndexPrivate::addToIndex(QGraphicsItem *item) @@ -421,6 +489,9 @@ void QGraphicsSceneBspTreeIndexPrivate::addToIndex(QGraphicsItem *item) } } +/*! + Remove the \a item from the BSP index. +*/ void QGraphicsSceneBspTreeIndex::removeItem(QGraphicsItem *item) { Q_D(QGraphicsSceneBspTreeIndex); @@ -443,6 +514,10 @@ void QGraphicsSceneBspTreeIndex::removeItem(QGraphicsItem *item) } } +/*! + \reimp + Delete the \a item from the BSP index (without accessing its boundingRect). +*/ void QGraphicsSceneBspTreeIndex::deleteItem(QGraphicsItem *item) { Q_D(QGraphicsSceneBspTreeIndex); @@ -469,6 +544,7 @@ void QGraphicsSceneBspTreeIndex::deleteItem(QGraphicsItem *item) } /*! + Really remove the item from the BSP \internal */ void QGraphicsSceneBspTreeIndexPrivate::removeFromIndex(QGraphicsItem *item) @@ -492,6 +568,10 @@ void QGraphicsSceneBspTreeIndexPrivate::removeFromIndex(QGraphicsItem *item) startIndexTimer(); } +/*! + \reimp + Update the BSP when the \a item 's bounding rect has changed. +*/ void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem *item) { Q_D(QGraphicsSceneBspTreeIndex); @@ -501,6 +581,13 @@ void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem * d->removeFromIndex(const_cast(item)); } +/*! + Returns an estimation visible items that are either inside or + intersect with the specified \a rect and return a list sorted using \a order. + + \a deviceTransform is the transformation apply to the view. + +*/ QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneBspTreeIndex); @@ -530,6 +617,12 @@ QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &r return rectItems; } + +/*! + \fn QList QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order = Qt::AscendingOrder) const; + + Return all items in the BSP index and sort them using \a order. +*/ QList QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order) const { Q_D(const QGraphicsSceneBspTreeIndex); @@ -558,19 +651,52 @@ QList QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order) co return itemList; } -int QGraphicsSceneBspTreeIndex::bspDepth() +/*! + \property QGraphicsSceneBspTreeIndex::bspTreeDepth + \brief the depth of the BSP index tree + \since 4.6 + + This value determines the depth of BSP tree. The depth + directly affects performance and memory usage; the latter + growing exponentially with the depth of the tree. With an optimal tree + depth, the index can instantly determine the locality of items, even + for scenes with thousands or millions of items. This also greatly improves + rendering performance. + + By default, the value is 0, in which case Qt will guess a reasonable + default depth based on the size, location and number of items in the + scene. If these parameters change frequently, however, you may experience + slowdowns as the index retunes the depth internally. You can avoid + potential slowdowns by fixating the tree depth through setting this + property. + + The depth of the tree and the size of the scene rectangle decide the + granularity of the scene's partitioning. The size of each scene segment is + determined by the following algorithm: + + The BSP tree has an optimal size when each segment contains between 0 and + 10 items. + +*/ +int QGraphicsSceneBspTreeIndex::bspTreeDepth() { Q_D(const QGraphicsSceneBspTreeIndex); return d->bspTreeDepth; } -void QGraphicsSceneBspTreeIndex::setBspDepth(int depth) +void QGraphicsSceneBspTreeIndex::setBspTreeDepth(int depth) { Q_D(QGraphicsSceneBspTreeIndex); d->bspTreeDepth = depth; d->resetIndex(); } +/*! + \reimp + + This method react to the \a rect change of the scene and + reset the BSP tree index. +*/ void QGraphicsSceneBspTreeIndex::sceneRectChanged(const QRectF &rect) { Q_D(QGraphicsSceneBspTreeIndex); @@ -578,6 +704,13 @@ void QGraphicsSceneBspTreeIndex::sceneRectChanged(const QRectF &rect) d->resetIndex(); } +/*! + \reimp + + This method react to the \a change of the \a item and use the \a value to + update the BSP tree if necessary. + +*/ void QGraphicsSceneBspTreeIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) { Q_D(QGraphicsSceneBspTreeIndex); @@ -592,7 +725,13 @@ void QGraphicsSceneBspTreeIndex::itemChanged(const QGraphicsItem *item, QGraphic } return QGraphicsSceneIndex::itemChanged(item, change, value); } +/*! + \reimp + Used to catch the timer event. + + \internal +*/ bool QGraphicsSceneBspTreeIndex::event(QEvent *event) { Q_D(QGraphicsSceneBspTreeIndex); diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index b1ea977..40b8f0b 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -60,6 +60,7 @@ class QGraphicsSceneBspTreeIndexPrivate; class Q_AUTOTEST_EXPORT QGraphicsSceneBspTreeIndex : public QGraphicsSceneIndex { Q_OBJECT + Q_PROPERTY(int bspTreeDepth READ bspTreeDepth WRITE setBspTreeDepth) public: QGraphicsSceneBspTreeIndex(QGraphicsScene *scene = 0); QRectF indexedRect() const; @@ -68,8 +69,8 @@ public: QList items(Qt::SortOrder order = Qt::AscendingOrder) const; - int bspDepth(); - void setBspDepth(int depth); + int bspTreeDepth(); + void setBspTreeDepth(int depth); protected: bool event(QEvent *event); diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index b713452..05ec28b 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -147,6 +147,9 @@ QGraphicsSceneIndexPrivate::~QGraphicsSceneIndexPrivate() delete pathIntersector; } +/*! + \internal +*/ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QGraphicsSceneIndexIntersector *intersector, QList *items, const QTransform &parentTransform, @@ -297,6 +300,12 @@ QRectF QGraphicsSceneIndex::indexedRect() const \a deviceTransform is the transformation apply to the view. + This method use the estimation of the index (estimateItems) and refine + the list to get an exact result. If you want to implement your own + refinement algorithm you can reimplement this method. + + \sa estimateItems() + */ QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { @@ -322,6 +331,12 @@ QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSe \a deviceTransform is the transformation apply to the view. + This method use the estimation of the index (estimateItems) and refine + the list to get an exact result. If you want to implement your own + refinement algorithm you can reimplement this method. + + \sa estimateItems() + */ QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { @@ -346,6 +361,12 @@ QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSe \a deviceTransform is the transformation apply to the view. + This method use the estimation of the index (estimateItems) and refine + the list to get an exact result. If you want to implement your own + refinement algorithm you can reimplement this method. + + \sa estimateItems() + */ QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { @@ -375,6 +396,12 @@ QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt:: \a deviceTransform is the transformation apply to the view. + This method use the estimation of the index (estimateItems) and refine + the list to get an exact result. If you want to implement your own + refinement algorithm you can reimplement this method. + + \sa estimateItems() + */ QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h index 3057b4a..d21475c 100644 --- a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h @@ -68,23 +68,32 @@ class Q_AUTOTEST_EXPORT QGraphicsSceneLinearIndex : public QGraphicsSceneIndex { Q_OBJECT -private: - QRectF m_sceneRect; - QList m_items; - public: QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0): QGraphicsSceneIndex(scene) { } - virtual void setRect(const QRectF &rect) { - m_sceneRect = rect; + QList items(Qt::SortOrder order = Qt::AscendingOrder) const { + Q_UNUSED(order); + return m_items; + } + + virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const { + Q_UNUSED(rect); + Q_UNUSED(order); + Q_UNUSED(deviceTransform); + return m_items; } - virtual QRectF rect() const { + virtual QRectF indexedRect() const { return m_sceneRect; } +protected : + void sceneRectChanged(const QRectF &rect) { + m_sceneRect = rect; + } + virtual void clear() { m_items.clear(); } @@ -97,17 +106,9 @@ public: m_items.removeAll(item); } - virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const { - QList result; - foreach (QGraphicsItem *item, m_items) - if (item->sceneBoundingRect().intersects(rect)) - result << item; - return result; - } - - QList items(Qt::SortOrder order = Qt::AscendingOrder) const { - return m_items; - } +private: + QRectF m_sceneRect; + QList m_items; }; QT_END_NAMESPACE -- cgit v0.12 From 8dee7b0c5be293f4b8ebafcae6baa052ca92f1d0 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 16 Jun 2009 13:46:43 +0200 Subject: Add missing file. --- src/gui/graphicsview/qgraphicsscenelinearindex.cpp | 70 ++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/gui/graphicsview/qgraphicsscenelinearindex.cpp diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex.cpp b/src/gui/graphicsview/qgraphicsscenelinearindex.cpp new file mode 100644 index 0000000..1c898bc --- /dev/null +++ b/src/gui/graphicsview/qgraphicsscenelinearindex.cpp @@ -0,0 +1,70 @@ +#include "qgraphicsscenelinearindex_p.h" + +/*! + \class QGraphicsSceneLinearIndex + \brief The QGraphicsSceneLinearIndex class provides an implementation of + a linear indexing algorithm for discovering items in QGraphicsScene. + \since 4.6 + \ingroup multimedia + \ingroup graphicsview-api + \mainclass + + QGraphicsSceneLinearIndex index is default linear implementation to discover items. + It basically store all items in a list and return them to the scene. + + \sa QGraphicsScene, QGraphicsView, QGraphicsSceneIndex, QGraphicsSceneBspTreeIndex +*/ + +/*! + \fn QGraphicsSceneLinearIndex::QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0): + + Construct a linear index for the given \a scene. +*/ + +/*! + \fn QList QGraphicsSceneLinearIndex::items(Qt::SortOrder order = Qt::AscendingOrder) const; + + Return all items in the index and sort them using \a order. +*/ + + +/*! + \fn virtual QList QGraphicsSceneLinearIndex::estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const; + + Returns an estimation visible items that are either inside or + intersect with the specified \a rect and return a list sorted using \a order. + + \a deviceTransform is the transformation apply to the view. + +*/ + +/*! + \fn QRectF QGraphicsSceneLinearIndex::indexedRect() const; + \reimp + Return the rect indexed by the the index. +*/ + +/*! + \fn void QGraphicsSceneLinearIndex::sceneRectChanged(const QRectF &rect); + \reimp + This method react to the \a rect change of the scene. +*/ + +/*! + \fn void QGraphicsSceneLinearIndex::clear(); + \reimp + Clear the all the BSP index. +*/ + +/*! + \fn virtual void QGraphicsSceneLinearIndex::addItem(QGraphicsItem *item); + + Add the \a item into the index. +*/ + +/*! + \fn virtual void QGraphicsSceneLinearIndex::removeItem(QGraphicsItem *item); + + Add the \a item from the index. +*/ + -- cgit v0.12 From d72727cb7530da54b59c51effa97263512e9238c Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 17 Jun 2009 11:25:36 +0200 Subject: Fix broken auto-test for the index. Since now items() doesn't use the index then the growingboundingrect is not updated if you call right after a delete. It's because the timer is not yet fired (even the processEvent) so you call add, move, remove which will trigger only one update index so the growingboundingrect will never change. --- tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index 4d786c7..17d290b 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -2726,8 +2726,8 @@ void tst_QGraphicsScene::update() qRegisterMetaType >("QList"); QSignalSpy spy(&scene, SIGNAL(changed(QList))); - // When deleted, the item will lazy-remove itself - delete rect; + // We update the scene. + scene.update(); // This function forces a purge, which will post an update signal scene.itemAt(0, 0); -- cgit v0.12 From 8a0e002ccc762ef3edbc3c9ad91b4d6017cb91bb Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 17 Jun 2009 14:15:14 +0200 Subject: Make eveything internal for now but ready to see the light. --- src/gui/graphicsview/graphicsview.pri | 6 +- src/gui/graphicsview/qgraphicsitem.cpp | 2 +- src/gui/graphicsview/qgraphicsscene.cpp | 7 +- src/gui/graphicsview/qgraphicsscene_p.h | 1 - .../graphicsview/qgraphicsscenebsptreeindex.cpp | 761 +++++++++++++++++++++ src/gui/graphicsview/qgraphicsscenebsptreeindex.h | 119 ++++ .../graphicsview/qgraphicsscenebsptreeindex_p.cpp | 760 -------------------- .../graphicsview/qgraphicsscenebsptreeindex_p.h | 137 ++-- .../graphicsview/qgraphicsscenebsptreeindex_p_p.h | 150 ---- src/gui/graphicsview/qgraphicssceneindex.cpp | 2 +- src/gui/graphicsview/qgraphicssceneindex.h | 13 +- src/gui/graphicsview/qgraphicsscenelinearindex.cpp | 3 +- src/gui/graphicsview/qgraphicsscenelinearindex.h | 124 ++++ src/gui/graphicsview/qgraphicsscenelinearindex_p.h | 118 ---- 14 files changed, 1122 insertions(+), 1081 deletions(-) create mode 100644 src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp create mode 100644 src/gui/graphicsview/qgraphicsscenebsptreeindex.h delete mode 100644 src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp delete mode 100644 src/gui/graphicsview/qgraphicsscenebsptreeindex_p_p.h create mode 100644 src/gui/graphicsview/qgraphicsscenelinearindex.h delete mode 100644 src/gui/graphicsview/qgraphicsscenelinearindex_p.h diff --git a/src/gui/graphicsview/graphicsview.pri b/src/gui/graphicsview/graphicsview.pri index a4d142a..5ac1c54 100644 --- a/src/gui/graphicsview/graphicsview.pri +++ b/src/gui/graphicsview/graphicsview.pri @@ -5,11 +5,11 @@ HEADERS += graphicsview/qgraphicsitem.h \ graphicsview/qgraphicsscene.h \ graphicsview/qgraphicsscene_p.h \ graphicsview/qgraphicsscene_bsp_p.h \ - graphicsview/qgraphicsscenelinearindex_p.h \ + graphicsview/qgraphicsscenelinearindex.h \ graphicsview/qgraphicssceneindex.h \ graphicsview/qgraphicssceneindex_p.h \ + graphicsview/qgraphicsscenebsptreeindex.h \ graphicsview/qgraphicsscenebsptreeindex_p.h \ - graphicsview/qgraphicsscenebsptreeindex_p_p.h \ graphicsview/qgraphicssceneevent.h \ graphicsview/qgraphicsview_p.h \ graphicsview/qgraphicsview.h @@ -17,7 +17,7 @@ SOURCES += graphicsview/qgraphicsitem.cpp \ graphicsview/qgraphicsitemanimation.cpp \ graphicsview/qgraphicsscene.cpp \ graphicsview/qgraphicsscene_bsp.cpp \ - graphicsview/qgraphicsscenebsptreeindex_p.cpp \ + graphicsview/qgraphicsscenebsptreeindex.cpp \ graphicsview/qgraphicsscenelinearindex.cpp \ graphicsview/qgraphicssceneindex.cpp \ graphicsview/qgraphicssceneevent.cpp \ diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 39ad447..593d7be 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -554,7 +554,7 @@ #include "qgraphicsview.h" #include "qgraphicswidget.h" #include "qgraphicsproxywidget.h" -#include "qgraphicsscenebsptreeindex_p_p.h" +#include "qgraphicsscenebsptreeindex_p.h" #include #include #include diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 5a3028c..a33cb3e 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -220,7 +220,8 @@ #include "qgraphicswidget.h" #include "qgraphicswidget_p.h" #include "qgraphicssceneindex.h" -#include "qgraphicsscenebsptreeindex_p_p.h" +#include "qgraphicsscenebsptreeindex.h" +#include "qgraphicsscenelinearindex.h" #include #include @@ -1574,6 +1575,8 @@ void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method) } /*! + \internal + \brief the item indexing method. This method allow to apply an indexing algorithm \a index to the scene, to speed up item discovery functions like items() and itemAt(). @@ -1595,6 +1598,8 @@ void QGraphicsScene::setSceneIndex(QGraphicsSceneIndex *index) } /*! + \internal + This method return the current indexing algorithm of the scene. \sa setSceneIndex(), QGraphicsSceneIndex diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 72ae158..563e016 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -58,7 +58,6 @@ #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW #include "qgraphicsscenebsptreeindex_p.h" -#include "qgraphicsscenelinearindex_p.h" #include "qgraphicssceneindex.h" #include "qgraphicsview.h" #include "qgraphicsitem_p.h" diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp new file mode 100644 index 0000000..76fd218 --- /dev/null +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -0,0 +1,761 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui 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 qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \class QGraphicsSceneBspTreeIndex + \brief The QGraphicsSceneBspTreeIndex class provides an implementation of + a BSP indexing algorithm for discovering items in QGraphicsScene. + \since 4.6 + \ingroup multimedia + \ingroup graphicsview-api + \mainclass + \internal + + QGraphicsSceneBspTreeIndex index use a BSP(Binary Space Partitioning) + implementation to discover items quickly. This implementation is + very efficient for static scene. It has a depth that you can set. + The depth directly affects performance and memory usage; the latter + growing exponentially with the depth of the tree. With an optimal tree + depth, the index can instantly determine the locality of items, even + for scenes with thousands or millions of items. This also greatly improves + rendering performance. + + By default, the value is 0, in which case Qt will guess a reasonable + default depth based on the size, location and number of items in the + scene. If these parameters change frequently, however, you may experience + slowdowns as the index retunes the depth internally. You can avoid + potential slowdowns by fixating the tree depth through setting this + property. + + The depth of the tree and the size of the scene rectangle decide the + granularity of the scene's partitioning. The size of each scene segment is + determined by the following algorithm: + + The BSP tree has an optimal size when each segment contains between 0 and + 10 items. + + \sa QGraphicsScene, QGraphicsView, QGraphicsSceneIndex +*/ + +#include "qgraphicsscenebsptreeindex.h" + +#ifndef QT_NO_GRAPHICSVIEW + +#include "qgraphicsscenebsptreeindex_p.h" +#include "qgraphicssceneindex_p.h" +#include "qgraphicsitem_p.h" +#include "qgraphicsscene_p.h" + +#include + +#include + +QT_BEGIN_NAMESPACE + +static inline int intmaxlog(int n) +{ + return (n > 0 ? qMax(qCeil(qLn(qreal(n)) / qLn(qreal(2))), 5) : 0); +} + +/*! + Constructs a private scene bsp index. +*/ +QGraphicsSceneBspTreeIndexPrivate::QGraphicsSceneBspTreeIndexPrivate(QGraphicsScene *scene) + : QGraphicsSceneIndexPrivate(scene), + bspTreeDepth(0), + indexTimerId(0), + restartIndexTimer(false), + regenerateIndex(true), + lastItemCount(0), + purgePending(false), + sortCacheEnabled(false), + updatingSortCache(false) +{ +} + + +/*! + This method will update the BSP index by removing the items from the temporary + unindexed list and add them in the indexedItems list. This will also + update the growingItemsBoundingRect if needed. This will update the BSP + implementation as well. + + \internal +*/ +void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() +{ + Q_Q(QGraphicsSceneBspTreeIndex); + if (!indexTimerId) + return; + + QGraphicsScenePrivate * scenePrivate = q->scene()->d_func(); + q->killTimer(indexTimerId); + indexTimerId = 0; + + purgeRemovedItems(); + + // Add unindexedItems to indexedItems + QRectF unindexedItemsBoundingRect; + for (int i = 0; i < unindexedItems.size(); ++i) { + if (QGraphicsItem *item = unindexedItems.at(i)) { + unindexedItemsBoundingRect |= item->sceneBoundingRect(); + if (!freeItemIndexes.isEmpty()) { + int freeIndex = freeItemIndexes.takeFirst(); + item->d_func()->index = freeIndex; + indexedItems[freeIndex] = item; + } else { + item->d_func()->index = indexedItems.size(); + indexedItems << item; + } + } + } + + // Update growing scene rect. + QRectF oldGrowingItemsBoundingRect = scenePrivate->growingItemsBoundingRect; + scenePrivate->growingItemsBoundingRect |= unindexedItemsBoundingRect; + + // Determine whether we should regenerate the BSP tree. + if (bspTreeDepth == 0) { + int oldDepth = intmaxlog(lastItemCount); + bspTreeDepth = intmaxlog(indexedItems.size()); + static const int slack = 100; + if (bsp.leafCount() == 0 || (oldDepth != bspTreeDepth && qAbs(lastItemCount - indexedItems.size()) > slack)) { + // ### Crude algorithm. + regenerateIndex = true; + } + } + + // Regenerate the tree. + if (regenerateIndex) { + regenerateIndex = false; + bsp.initialize(q->scene()->sceneRect(), bspTreeDepth); + unindexedItems = indexedItems; + lastItemCount = indexedItems.size(); + q->scene()->update(); + + // Take this opportunity to reset our largest-item counter for + // untransformable items. When the items are inserted into the BSP + // tree, we'll get an accurate calculation. + scenePrivate->largestUntransformableItem = QRectF(); + } + + // Insert all unindexed items into the tree. + for (int i = 0; i < unindexedItems.size(); ++i) { + if (QGraphicsItem *item = unindexedItems.at(i)) { + QRectF rect = item->sceneBoundingRect(); + if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) + continue; + + bsp.insertItem(item, rect); + + // If the item ignores view transformations, update our + // largest-item-counter to ensure that the view can accurately + // discover untransformable items when drawing. + if (item->d_ptr->itemIsUntransformable()) { + QGraphicsItem *topmostUntransformable = item; + while (topmostUntransformable && (topmostUntransformable->d_ptr->ancestorFlags + & QGraphicsItemPrivate::AncestorIgnoresTransformations)) { + topmostUntransformable = topmostUntransformable->parentItem(); + } + // ### Verify that this is the correct largest untransformable rectangle. + scenePrivate->largestUntransformableItem |= item->mapToItem(topmostUntransformable, item->boundingRect()).boundingRect(); + } + } + } + unindexedItems.clear(); + + // Notify scene rect changes. + if (!scenePrivate->hasSceneRect && scenePrivate->growingItemsBoundingRect != oldGrowingItemsBoundingRect) + emit q->scene()->sceneRectChanged(scenePrivate->growingItemsBoundingRect); +} + + +/*! + \internal + + Removes stale pointers from all data structures. +*/ +void QGraphicsSceneBspTreeIndexPrivate::purgeRemovedItems() +{ + if (!purgePending && removedItems.isEmpty()) + return; + + // Remove stale items from the BSP tree. + bsp.removeItems(removedItems); + // Purge this list. + removedItems.clear(); + freeItemIndexes.clear(); + for (int i = 0; i < indexedItems.size(); ++i) { + if (!indexedItems.at(i)) + freeItemIndexes << i; + } + purgePending = false; +} + +/*! + \internal + + Starts or restarts the timer used for reindexing unindexed items. +*/ +void QGraphicsSceneBspTreeIndexPrivate::startIndexTimer(int interval) +{ + Q_Q(QGraphicsSceneBspTreeIndex); + if (indexTimerId) { + restartIndexTimer = true; + } else { + indexTimerId = q->startTimer(interval); + } +} + +/*! + \internal +*/ +void QGraphicsSceneBspTreeIndexPrivate::resetIndex() +{ + purgeRemovedItems(); + for (int i = 0; i < indexedItems.size(); ++i) { + if (QGraphicsItem *item = indexedItems.at(i)) { + item->d_ptr->index = -1; + unindexedItems << item; + } + } + indexedItems.clear(); + freeItemIndexes.clear(); + regenerateIndex = true; + startIndexTimer(); +} + +/*! + \internal +*/ +void QGraphicsSceneBspTreeIndexPrivate::climbTree(QGraphicsItem *item, int *stackingOrder) +{ + if (!item->d_ptr->children.isEmpty()) { + QList childList = item->d_ptr->children; + qSort(childList.begin(), childList.end(), qt_closestLeaf); + for (int i = 0; i < childList.size(); ++i) { + QGraphicsItem *item = childList.at(i); + if (!(item->flags() & QGraphicsItem::ItemStacksBehindParent)) + climbTree(childList.at(i), stackingOrder); + } + item->d_ptr->globalStackingOrder = (*stackingOrder)++; + for (int i = 0; i < childList.size(); ++i) { + QGraphicsItem *item = childList.at(i); + if (item->flags() & QGraphicsItem::ItemStacksBehindParent) + climbTree(childList.at(i), stackingOrder); + } + } else { + item->d_ptr->globalStackingOrder = (*stackingOrder)++; + } +} + +/*! + \internal +*/ +void QGraphicsSceneBspTreeIndexPrivate::_q_updateSortCache() +{ + Q_Q(QGraphicsSceneBspTreeIndex); + _q_updateIndex(); + + if (!sortCacheEnabled || !updatingSortCache) + return; + + updatingSortCache = false; + int stackingOrder = 0; + + QList topLevels; + + for (int i = 0; i < q->items().count(); ++i) { + QGraphicsItem *item = q->items().at(i); + if (item && item->parentItem() == 0) + topLevels << item; + } + + qSort(topLevels.begin(), topLevels.end(), qt_closestLeaf); + for (int i = 0; i < topLevels.size(); ++i) + climbTree(topLevels.at(i), &stackingOrder); +} + +/*! + \internal +*/ +void QGraphicsSceneBspTreeIndexPrivate::invalidateSortCache() +{ + Q_Q(QGraphicsSceneBspTreeIndex); + if (!sortCacheEnabled || updatingSortCache) + return; + + updatingSortCache = true; + QMetaObject::invokeMethod(q, "_q_updateSortCache", Qt::QueuedConnection); +} + +/*! + Returns true if \a item1 is on top of \a item2. + + \internal +*/ +bool QGraphicsSceneBspTreeIndexPrivate::closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2) +{ + // Siblings? Just check their z-values. + const QGraphicsItemPrivate *d1 = item1->d_ptr; + const QGraphicsItemPrivate *d2 = item2->d_ptr; + if (d1->parent == d2->parent) + return qt_closestLeaf(item1, item2); + + // Find common ancestor, and each item's ancestor closest to the common + // ancestor. + int item1Depth = d1->depth; + int item2Depth = d2->depth; + const QGraphicsItem *p = item1; + const QGraphicsItem *t1 = item1; + while (item1Depth > item2Depth && (p = p->d_ptr->parent)) { + if (p == item2) { + // item2 is one of item1's ancestors; item1 is on top + return !(t1->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent); + } + t1 = p; + --item1Depth; + } + p = item2; + const QGraphicsItem *t2 = item2; + while (item2Depth > item1Depth && (p = p->d_ptr->parent)) { + if (p == item1) { + // item1 is one of item2's ancestors; item1 is not on top + return (t2->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent); + } + t2 = p; + --item2Depth; + } + + // item1Ancestor is now at the same level as item2Ancestor, but not the same. + const QGraphicsItem *a1 = t1; + const QGraphicsItem *a2 = t2; + while (a1) { + const QGraphicsItem *p1 = a1; + const QGraphicsItem *p2 = a2; + a1 = a1->parentItem(); + a2 = a2->parentItem(); + if (a1 && a1 == a2) + return qt_closestLeaf(p1, p2); + } + + // No common ancestor? Then just compare the items' toplevels directly. + return qt_closestLeaf(t1->topLevelItem(), t2->topLevelItem()); +} + +/*! + Returns true if \a item2 is on top of \a item1. + + \internal +*/ +bool QGraphicsSceneBspTreeIndexPrivate::closestItemLast_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2) +{ + return closestItemFirst_withoutCache(item2, item1); +} + +/*! + Sort a list of \a itemList in a specific \a order and use the cache if requested. + + \internal +*/ +void QGraphicsSceneBspTreeIndexPrivate::sortItems(QList *itemList, Qt::SortOrder order, + bool sortCacheEnabled) +{ + if (sortCacheEnabled) { + if (order == Qt::AscendingOrder) { + qSort(itemList->begin(), itemList->end(), closestItemFirst_withCache); + } else if (order == Qt::DescendingOrder) { + qSort(itemList->begin(), itemList->end(), closestItemLast_withCache); + } + } else { + if (order == Qt::AscendingOrder) { + qSort(itemList->begin(), itemList->end(), closestItemFirst_withoutCache); + } else if (order == Qt::DescendingOrder) { + qSort(itemList->begin(), itemList->end(), closestItemLast_withoutCache); + } + } +} + +/*! + Constructs a BSP scene index for the given \a scene. +*/ +QGraphicsSceneBspTreeIndex::QGraphicsSceneBspTreeIndex(QGraphicsScene *scene) + : QGraphicsSceneIndex(*new QGraphicsSceneBspTreeIndexPrivate(scene), scene) +{ + +} + +/*! + \reimp + Return the rect indexed by the BSP index. +*/ +QRectF QGraphicsSceneBspTreeIndex::indexedRect() const +{ + Q_D(const QGraphicsSceneBspTreeIndex); + const_cast(d)->_q_updateIndex(); + return scene()->d_func()->hasSceneRect ? scene()->d_func()->sceneRect : scene()->d_func()->growingItemsBoundingRect; +} + +/*! + \reimp + Clear the all the BSP index. +*/ +void QGraphicsSceneBspTreeIndex::clear() +{ + Q_D(QGraphicsSceneBspTreeIndex); + d->bsp.clear(); + d->lastItemCount = 0; + d->freeItemIndexes.clear(); + d->indexedItems.clear(); + d->unindexedItems.clear(); +} + +/*! + Add the \a item into the BSP index. +*/ +void QGraphicsSceneBspTreeIndex::addItem(QGraphicsItem *item) +{ + Q_D(QGraphicsSceneBspTreeIndex); + // Prevent reusing a recently deleted pointer: purge all removed items + // from our lists. + d->purgeRemovedItems(); + + // Invalidate any sort caching; arrival of a new item means we need to + // resort. + // Update the scene's sort cache settings. + item->d_ptr->globalStackingOrder = -1; + d->invalidateSortCache(); + + // Indexing requires sceneBoundingRect(), but because \a item might + // not be completely constructed at this point, we need to store it in + // a temporary list and schedule an indexing for later. + d->unindexedItems << item; + item->d_func()->index = -1; + d->startIndexTimer(0); +} + +/*! + This really add the item in the BSP. + \internal +*/ +void QGraphicsSceneBspTreeIndexPrivate::addToIndex(QGraphicsItem *item) +{ + if (item->d_func()->index != -1) { + bsp.insertItem(item, item->sceneBoundingRect()); + foreach (QGraphicsItem *child, item->children()) + child->addToIndex(); + } else { + // The BSP tree is regenerated if the number of items grows to a + // certain threshold, or if the bounding rect of the graph doubles in + // size. + startIndexTimer(); + } +} + +/*! + Remove the \a item from the BSP index. +*/ +void QGraphicsSceneBspTreeIndex::removeItem(QGraphicsItem *item) +{ + Q_D(QGraphicsSceneBspTreeIndex); + // Note: This will access item's sceneBoundingRect(), which (as this is + // C++) is why we cannot call removeItem() from QGraphicsItem's + // destructor. + d->removeFromIndex(item); + + // Invalidate any sort caching; arrival of a new item means we need to + // resort. + d->invalidateSortCache(); + + // Remove from our item lists. + int index = item->d_func()->index; + if (index != -1) { + d->freeItemIndexes << index; + d->indexedItems[index] = 0; + } else { + d->unindexedItems.removeAll(item); + } +} + +/*! + \reimp + Delete the \a item from the BSP index (without accessing its boundingRect). +*/ +void QGraphicsSceneBspTreeIndex::deleteItem(QGraphicsItem *item) +{ + Q_D(QGraphicsSceneBspTreeIndex); + // Invalidate any sort caching; arrival of a new item means we need to + // resort. + d->invalidateSortCache(); + + int index = item->d_func()->index; + if (index != -1) { + // Important: The index is useless until purgeRemovedItems() is + // called. + d->indexedItems[index] = (QGraphicsItem *)0; + if (!d->purgePending) { + d->purgePending = true; + scene()->update(); + } + d->removedItems << item; + } else { + // Recently added items are purged immediately. unindexedItems() never + // contains stale items. + d->unindexedItems.removeAll(item); + scene()->update(); + } +} + +/*! + Really remove the item from the BSP + \internal +*/ +void QGraphicsSceneBspTreeIndexPrivate::removeFromIndex(QGraphicsItem *item) +{ + if (item->d_func()->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { + // ### remove from child index only if applicable + return; + } + int index = item->d_func()->index; + if (index != -1) { + bsp.removeItem(item, item->sceneBoundingRect()); + freeItemIndexes << index; + indexedItems[index] = 0; + item->d_func()->index = -1; + unindexedItems << item; + + //prepareGeometryChange will call prepareBoundingRectChange + foreach (QGraphicsItem *child, item->children()) + child->prepareGeometryChange(); + } + startIndexTimer(); +} + +/*! + \reimp + Update the BSP when the \a item 's bounding rect has changed. +*/ +void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem *item) +{ + Q_D(QGraphicsSceneBspTreeIndex); + // Note: This will access item's sceneBoundingRect(), which (as this is + // C++) is why we cannot call removeItem() from QGraphicsItem's + // destructor. + d->removeFromIndex(const_cast(item)); +} + +/*! + Returns an estimation visible items that are either inside or + intersect with the specified \a rect and return a list sorted using \a order. + + \a deviceTransform is the transformation apply to the view. + +*/ +QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const +{ + Q_D(const QGraphicsSceneBspTreeIndex); + const_cast(d)->purgeRemovedItems(); + const_cast(d)->_q_updateSortCache(); + + QList rectItems = d->bsp.items(rect); + // Fill in with any unindexed items + for (int i = 0; i < d->unindexedItems.size(); ++i) { + if (QGraphicsItem *item = d->unindexedItems.at(i)) { + if (!item->d_ptr->itemDiscovered && item->d_ptr->visible && !(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { + QRectF boundingRect = item->sceneBoundingRect(); + if (QRectF_intersects(boundingRect, rect)) { + item->d_ptr->itemDiscovered = 1; + rectItems << item; + } + } + } + } + + // Reset the discovered state of all discovered items + for (int i = 0; i < rectItems.size(); ++i) + rectItems.at(i)->d_func()->itemDiscovered = 0; + + d->sortItems(&rectItems, order, d->sortCacheEnabled); + + return rectItems; +} + + +/*! + \fn QList QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order = Qt::AscendingOrder) const; + + Return all items in the BSP index and sort them using \a order. +*/ +QList QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order) const +{ + Q_D(const QGraphicsSceneBspTreeIndex); + const_cast(d)->purgeRemovedItems(); + QList itemList; + // If freeItemIndexes is empty, we know there are no holes in indexedItems and + // unindexedItems. + if (d->freeItemIndexes.isEmpty()) { + if (d->unindexedItems.isEmpty()) { + itemList = d->indexedItems; + } else { + itemList = d->indexedItems + d->unindexedItems; + } + } else { + // Rebuild the list of items to avoid holes. ### We could also just + // compress the item lists at this point. + foreach (QGraphicsItem *item, d->indexedItems + d->unindexedItems) { + if (item) + itemList << item; + } + } + if (order != -1) { + //We sort descending order + d->sortItems(&itemList, order, d->sortCacheEnabled); + } + return itemList; +} + +/*! + \property QGraphicsSceneBspTreeIndex::bspTreeDepth + \brief the depth of the BSP index tree + \since 4.6 + + This value determines the depth of BSP tree. The depth + directly affects performance and memory usage; the latter + growing exponentially with the depth of the tree. With an optimal tree + depth, the index can instantly determine the locality of items, even + for scenes with thousands or millions of items. This also greatly improves + rendering performance. + + By default, the value is 0, in which case Qt will guess a reasonable + default depth based on the size, location and number of items in the + scene. If these parameters change frequently, however, you may experience + slowdowns as the index retunes the depth internally. You can avoid + potential slowdowns by fixating the tree depth through setting this + property. + + The depth of the tree and the size of the scene rectangle decide the + granularity of the scene's partitioning. The size of each scene segment is + determined by the following algorithm: + + The BSP tree has an optimal size when each segment contains between 0 and + 10 items. + +*/ +int QGraphicsSceneBspTreeIndex::bspTreeDepth() +{ + Q_D(const QGraphicsSceneBspTreeIndex); + return d->bspTreeDepth; +} + +void QGraphicsSceneBspTreeIndex::setBspTreeDepth(int depth) +{ + Q_D(QGraphicsSceneBspTreeIndex); + d->bspTreeDepth = depth; + d->resetIndex(); +} + +/*! + \reimp + + This method react to the \a rect change of the scene and + reset the BSP tree index. +*/ +void QGraphicsSceneBspTreeIndex::sceneRectChanged(const QRectF &rect) +{ + Q_D(QGraphicsSceneBspTreeIndex); + d->sceneRect = rect; + d->resetIndex(); +} + +/*! + \reimp + + This method react to the \a change of the \a item and use the \a value to + update the BSP tree if necessary. + +*/ +void QGraphicsSceneBspTreeIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) +{ + Q_D(QGraphicsSceneBspTreeIndex); + switch (change) { + case QGraphicsItem::ItemZValueChange: + case QGraphicsItem::ItemParentChange: { + d->invalidateSortCache(); + break; + } + default: + break; + } + return QGraphicsSceneIndex::itemChanged(item, change, value); +} +/*! + \reimp + + Used to catch the timer event. + + \internal +*/ +bool QGraphicsSceneBspTreeIndex::event(QEvent *event) +{ + Q_D(QGraphicsSceneBspTreeIndex); + switch (event->type()) { + case QEvent::Timer: + if (d->indexTimerId && static_cast(event)->timerId() == d->indexTimerId) { + if (d->restartIndexTimer) { + d->restartIndexTimer = false; + } else { + // this call will kill the timer + d->_q_updateIndex(); + } + } + // Fallthrough intended - support timers in subclasses. + default: + return QObject::event(event); + } + return true; +} + +QT_END_NAMESPACE + +#include "moc_qgraphicsscenebsptreeindex.cpp" + +#endif // QT_NO_GRAPHICSVIEW + diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex.h new file mode 100644 index 0000000..0444a30 --- /dev/null +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.h @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui 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 qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + +#ifndef QGRAPHICSBSPTREEINDEX_H +#define QGRAPHICSBSPTREEINDEX_H + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW + +#include +#include +#include +#include +#include + +#include "qgraphicsscene_bsp_p.h" + +class QGraphicsSceneBspTreeIndexPrivate; + +class Q_AUTOTEST_EXPORT QGraphicsSceneBspTreeIndex : public QGraphicsSceneIndex +{ + Q_OBJECT + Q_PROPERTY(int bspTreeDepth READ bspTreeDepth WRITE setBspTreeDepth) +public: + QGraphicsSceneBspTreeIndex(QGraphicsScene *scene = 0); + QRectF indexedRect() const; + + QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const; + + QList items(Qt::SortOrder order = Qt::AscendingOrder) const; + + int bspTreeDepth(); + void setBspTreeDepth(int depth); + +protected: + bool event(QEvent *event); + void clear(); + + void addItem(QGraphicsItem *item); + void removeItem(QGraphicsItem *item); + void deleteItem(QGraphicsItem *item); + void prepareBoundingRectChange(const QGraphicsItem *item); + + void sceneRectChanged(const QRectF &rect); + void itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value); + +private : + Q_DECLARE_PRIVATE(QGraphicsSceneBspTreeIndex) + Q_DISABLE_COPY(QGraphicsSceneBspTreeIndex) + Q_PRIVATE_SLOT(d_func(), void _q_updateSortCache()) + Q_PRIVATE_SLOT(d_func(), void _q_updateIndex()) + + friend class QGraphicsScene; + friend class QGraphicsScenePrivate; +}; + +#endif // QT_NO_GRAPHICSVIEW + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QGRAPHICSBSPTREEINDEX_H diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp deleted file mode 100644 index b19248a..0000000 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.cpp +++ /dev/null @@ -1,760 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui 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 qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \class QGraphicsSceneBspTreeIndex - \brief The QGraphicsSceneBspTreeIndex class provides an implementation of - a BSP indexing algorithm for discovering items in QGraphicsScene. - \since 4.6 - \ingroup multimedia - \ingroup graphicsview-api - \mainclass - - QGraphicsSceneBspTreeIndex index use a BSP(Binary Space Partitioning) - implementation to discover items quickly. This implementation is - very efficient for static scene. It has a depth that you can set. - The depth directly affects performance and memory usage; the latter - growing exponentially with the depth of the tree. With an optimal tree - depth, the index can instantly determine the locality of items, even - for scenes with thousands or millions of items. This also greatly improves - rendering performance. - - By default, the value is 0, in which case Qt will guess a reasonable - default depth based on the size, location and number of items in the - scene. If these parameters change frequently, however, you may experience - slowdowns as the index retunes the depth internally. You can avoid - potential slowdowns by fixating the tree depth through setting this - property. - - The depth of the tree and the size of the scene rectangle decide the - granularity of the scene's partitioning. The size of each scene segment is - determined by the following algorithm: - - The BSP tree has an optimal size when each segment contains between 0 and - 10 items. - - \sa QGraphicsScene, QGraphicsView, QGraphicsSceneIndex -*/ - -#include "qgraphicsscenebsptreeindex_p.h" - -#ifndef QT_NO_GRAPHICSVIEW - -#include "qgraphicsscenebsptreeindex_p_p.h" -#include "qgraphicssceneindex_p.h" -#include "qgraphicsitem_p.h" -#include "qgraphicsscene_p.h" - -#include - -#include - -QT_BEGIN_NAMESPACE - -static inline int intmaxlog(int n) -{ - return (n > 0 ? qMax(qCeil(qLn(qreal(n)) / qLn(qreal(2))), 5) : 0); -} - -/*! - Constructs a private scene bsp index. -*/ -QGraphicsSceneBspTreeIndexPrivate::QGraphicsSceneBspTreeIndexPrivate(QGraphicsScene *scene) - : QGraphicsSceneIndexPrivate(scene), - bspTreeDepth(0), - indexTimerId(0), - restartIndexTimer(false), - regenerateIndex(true), - lastItemCount(0), - purgePending(false), - sortCacheEnabled(false), - updatingSortCache(false) -{ -} - - -/*! - This method will update the BSP index by removing the items from the temporary - unindexed list and add them in the indexedItems list. This will also - update the growingItemsBoundingRect if needed. This will update the BSP - implementation as well. - - \internal -*/ -void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() -{ - Q_Q(QGraphicsSceneBspTreeIndex); - if (!indexTimerId) - return; - - QGraphicsScenePrivate * scenePrivate = q->scene()->d_func(); - q->killTimer(indexTimerId); - indexTimerId = 0; - - purgeRemovedItems(); - - // Add unindexedItems to indexedItems - QRectF unindexedItemsBoundingRect; - for (int i = 0; i < unindexedItems.size(); ++i) { - if (QGraphicsItem *item = unindexedItems.at(i)) { - unindexedItemsBoundingRect |= item->sceneBoundingRect(); - if (!freeItemIndexes.isEmpty()) { - int freeIndex = freeItemIndexes.takeFirst(); - item->d_func()->index = freeIndex; - indexedItems[freeIndex] = item; - } else { - item->d_func()->index = indexedItems.size(); - indexedItems << item; - } - } - } - - // Update growing scene rect. - QRectF oldGrowingItemsBoundingRect = scenePrivate->growingItemsBoundingRect; - scenePrivate->growingItemsBoundingRect |= unindexedItemsBoundingRect; - - // Determine whether we should regenerate the BSP tree. - if (bspTreeDepth == 0) { - int oldDepth = intmaxlog(lastItemCount); - bspTreeDepth = intmaxlog(indexedItems.size()); - static const int slack = 100; - if (bsp.leafCount() == 0 || (oldDepth != bspTreeDepth && qAbs(lastItemCount - indexedItems.size()) > slack)) { - // ### Crude algorithm. - regenerateIndex = true; - } - } - - // Regenerate the tree. - if (regenerateIndex) { - regenerateIndex = false; - bsp.initialize(q->scene()->sceneRect(), bspTreeDepth); - unindexedItems = indexedItems; - lastItemCount = indexedItems.size(); - q->scene()->update(); - - // Take this opportunity to reset our largest-item counter for - // untransformable items. When the items are inserted into the BSP - // tree, we'll get an accurate calculation. - scenePrivate->largestUntransformableItem = QRectF(); - } - - // Insert all unindexed items into the tree. - for (int i = 0; i < unindexedItems.size(); ++i) { - if (QGraphicsItem *item = unindexedItems.at(i)) { - QRectF rect = item->sceneBoundingRect(); - if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) - continue; - - bsp.insertItem(item, rect); - - // If the item ignores view transformations, update our - // largest-item-counter to ensure that the view can accurately - // discover untransformable items when drawing. - if (item->d_ptr->itemIsUntransformable()) { - QGraphicsItem *topmostUntransformable = item; - while (topmostUntransformable && (topmostUntransformable->d_ptr->ancestorFlags - & QGraphicsItemPrivate::AncestorIgnoresTransformations)) { - topmostUntransformable = topmostUntransformable->parentItem(); - } - // ### Verify that this is the correct largest untransformable rectangle. - scenePrivate->largestUntransformableItem |= item->mapToItem(topmostUntransformable, item->boundingRect()).boundingRect(); - } - } - } - unindexedItems.clear(); - - // Notify scene rect changes. - if (!scenePrivate->hasSceneRect && scenePrivate->growingItemsBoundingRect != oldGrowingItemsBoundingRect) - emit q->scene()->sceneRectChanged(scenePrivate->growingItemsBoundingRect); -} - - -/*! - \internal - - Removes stale pointers from all data structures. -*/ -void QGraphicsSceneBspTreeIndexPrivate::purgeRemovedItems() -{ - if (!purgePending && removedItems.isEmpty()) - return; - - // Remove stale items from the BSP tree. - bsp.removeItems(removedItems); - // Purge this list. - removedItems.clear(); - freeItemIndexes.clear(); - for (int i = 0; i < indexedItems.size(); ++i) { - if (!indexedItems.at(i)) - freeItemIndexes << i; - } - purgePending = false; -} - -/*! - \internal - - Starts or restarts the timer used for reindexing unindexed items. -*/ -void QGraphicsSceneBspTreeIndexPrivate::startIndexTimer(int interval) -{ - Q_Q(QGraphicsSceneBspTreeIndex); - if (indexTimerId) { - restartIndexTimer = true; - } else { - indexTimerId = q->startTimer(interval); - } -} - -/*! - \internal -*/ -void QGraphicsSceneBspTreeIndexPrivate::resetIndex() -{ - purgeRemovedItems(); - for (int i = 0; i < indexedItems.size(); ++i) { - if (QGraphicsItem *item = indexedItems.at(i)) { - item->d_ptr->index = -1; - unindexedItems << item; - } - } - indexedItems.clear(); - freeItemIndexes.clear(); - regenerateIndex = true; - startIndexTimer(); -} - -/*! - \internal -*/ -void QGraphicsSceneBspTreeIndexPrivate::climbTree(QGraphicsItem *item, int *stackingOrder) -{ - if (!item->d_ptr->children.isEmpty()) { - QList childList = item->d_ptr->children; - qSort(childList.begin(), childList.end(), qt_closestLeaf); - for (int i = 0; i < childList.size(); ++i) { - QGraphicsItem *item = childList.at(i); - if (!(item->flags() & QGraphicsItem::ItemStacksBehindParent)) - climbTree(childList.at(i), stackingOrder); - } - item->d_ptr->globalStackingOrder = (*stackingOrder)++; - for (int i = 0; i < childList.size(); ++i) { - QGraphicsItem *item = childList.at(i); - if (item->flags() & QGraphicsItem::ItemStacksBehindParent) - climbTree(childList.at(i), stackingOrder); - } - } else { - item->d_ptr->globalStackingOrder = (*stackingOrder)++; - } -} - -/*! - \internal -*/ -void QGraphicsSceneBspTreeIndexPrivate::_q_updateSortCache() -{ - Q_Q(QGraphicsSceneBspTreeIndex); - _q_updateIndex(); - - if (!sortCacheEnabled || !updatingSortCache) - return; - - updatingSortCache = false; - int stackingOrder = 0; - - QList topLevels; - - for (int i = 0; i < q->items().count(); ++i) { - QGraphicsItem *item = q->items().at(i); - if (item && item->parentItem() == 0) - topLevels << item; - } - - qSort(topLevels.begin(), topLevels.end(), qt_closestLeaf); - for (int i = 0; i < topLevels.size(); ++i) - climbTree(topLevels.at(i), &stackingOrder); -} - -/*! - \internal -*/ -void QGraphicsSceneBspTreeIndexPrivate::invalidateSortCache() -{ - Q_Q(QGraphicsSceneBspTreeIndex); - if (!sortCacheEnabled || updatingSortCache) - return; - - updatingSortCache = true; - QMetaObject::invokeMethod(q, "_q_updateSortCache", Qt::QueuedConnection); -} - -/*! - Returns true if \a item1 is on top of \a item2. - - \internal -*/ -bool QGraphicsSceneBspTreeIndexPrivate::closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2) -{ - // Siblings? Just check their z-values. - const QGraphicsItemPrivate *d1 = item1->d_ptr; - const QGraphicsItemPrivate *d2 = item2->d_ptr; - if (d1->parent == d2->parent) - return qt_closestLeaf(item1, item2); - - // Find common ancestor, and each item's ancestor closest to the common - // ancestor. - int item1Depth = d1->depth; - int item2Depth = d2->depth; - const QGraphicsItem *p = item1; - const QGraphicsItem *t1 = item1; - while (item1Depth > item2Depth && (p = p->d_ptr->parent)) { - if (p == item2) { - // item2 is one of item1's ancestors; item1 is on top - return !(t1->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent); - } - t1 = p; - --item1Depth; - } - p = item2; - const QGraphicsItem *t2 = item2; - while (item2Depth > item1Depth && (p = p->d_ptr->parent)) { - if (p == item1) { - // item1 is one of item2's ancestors; item1 is not on top - return (t2->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent); - } - t2 = p; - --item2Depth; - } - - // item1Ancestor is now at the same level as item2Ancestor, but not the same. - const QGraphicsItem *a1 = t1; - const QGraphicsItem *a2 = t2; - while (a1) { - const QGraphicsItem *p1 = a1; - const QGraphicsItem *p2 = a2; - a1 = a1->parentItem(); - a2 = a2->parentItem(); - if (a1 && a1 == a2) - return qt_closestLeaf(p1, p2); - } - - // No common ancestor? Then just compare the items' toplevels directly. - return qt_closestLeaf(t1->topLevelItem(), t2->topLevelItem()); -} - -/*! - Returns true if \a item2 is on top of \a item1. - - \internal -*/ -bool QGraphicsSceneBspTreeIndexPrivate::closestItemLast_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2) -{ - return closestItemFirst_withoutCache(item2, item1); -} - -/*! - Sort a list of \a itemList in a specific \a order and use the cache if requested. - - \internal -*/ -void QGraphicsSceneBspTreeIndexPrivate::sortItems(QList *itemList, Qt::SortOrder order, - bool sortCacheEnabled) -{ - if (sortCacheEnabled) { - if (order == Qt::AscendingOrder) { - qSort(itemList->begin(), itemList->end(), closestItemFirst_withCache); - } else if (order == Qt::DescendingOrder) { - qSort(itemList->begin(), itemList->end(), closestItemLast_withCache); - } - } else { - if (order == Qt::AscendingOrder) { - qSort(itemList->begin(), itemList->end(), closestItemFirst_withoutCache); - } else if (order == Qt::DescendingOrder) { - qSort(itemList->begin(), itemList->end(), closestItemLast_withoutCache); - } - } -} - -/*! - Constructs a BSP scene index for the given \a scene. -*/ -QGraphicsSceneBspTreeIndex::QGraphicsSceneBspTreeIndex(QGraphicsScene *scene) - : QGraphicsSceneIndex(*new QGraphicsSceneBspTreeIndexPrivate(scene), scene) -{ - -} - -/*! - \reimp - Return the rect indexed by the BSP index. -*/ -QRectF QGraphicsSceneBspTreeIndex::indexedRect() const -{ - Q_D(const QGraphicsSceneBspTreeIndex); - const_cast(d)->_q_updateIndex(); - return scene()->d_func()->hasSceneRect ? scene()->d_func()->sceneRect : scene()->d_func()->growingItemsBoundingRect; -} - -/*! - \reimp - Clear the all the BSP index. -*/ -void QGraphicsSceneBspTreeIndex::clear() -{ - Q_D(QGraphicsSceneBspTreeIndex); - d->bsp.clear(); - d->lastItemCount = 0; - d->freeItemIndexes.clear(); - d->indexedItems.clear(); - d->unindexedItems.clear(); -} - -/*! - Add the \a item into the BSP index. -*/ -void QGraphicsSceneBspTreeIndex::addItem(QGraphicsItem *item) -{ - Q_D(QGraphicsSceneBspTreeIndex); - // Prevent reusing a recently deleted pointer: purge all removed items - // from our lists. - d->purgeRemovedItems(); - - // Invalidate any sort caching; arrival of a new item means we need to - // resort. - // Update the scene's sort cache settings. - item->d_ptr->globalStackingOrder = -1; - d->invalidateSortCache(); - - // Indexing requires sceneBoundingRect(), but because \a item might - // not be completely constructed at this point, we need to store it in - // a temporary list and schedule an indexing for later. - d->unindexedItems << item; - item->d_func()->index = -1; - d->startIndexTimer(0); -} - -/*! - This really add the item in the BSP. - \internal -*/ -void QGraphicsSceneBspTreeIndexPrivate::addToIndex(QGraphicsItem *item) -{ - if (item->d_func()->index != -1) { - bsp.insertItem(item, item->sceneBoundingRect()); - foreach (QGraphicsItem *child, item->children()) - child->addToIndex(); - } else { - // The BSP tree is regenerated if the number of items grows to a - // certain threshold, or if the bounding rect of the graph doubles in - // size. - startIndexTimer(); - } -} - -/*! - Remove the \a item from the BSP index. -*/ -void QGraphicsSceneBspTreeIndex::removeItem(QGraphicsItem *item) -{ - Q_D(QGraphicsSceneBspTreeIndex); - // Note: This will access item's sceneBoundingRect(), which (as this is - // C++) is why we cannot call removeItem() from QGraphicsItem's - // destructor. - d->removeFromIndex(item); - - // Invalidate any sort caching; arrival of a new item means we need to - // resort. - d->invalidateSortCache(); - - // Remove from our item lists. - int index = item->d_func()->index; - if (index != -1) { - d->freeItemIndexes << index; - d->indexedItems[index] = 0; - } else { - d->unindexedItems.removeAll(item); - } -} - -/*! - \reimp - Delete the \a item from the BSP index (without accessing its boundingRect). -*/ -void QGraphicsSceneBspTreeIndex::deleteItem(QGraphicsItem *item) -{ - Q_D(QGraphicsSceneBspTreeIndex); - // Invalidate any sort caching; arrival of a new item means we need to - // resort. - d->invalidateSortCache(); - - int index = item->d_func()->index; - if (index != -1) { - // Important: The index is useless until purgeRemovedItems() is - // called. - d->indexedItems[index] = (QGraphicsItem *)0; - if (!d->purgePending) { - d->purgePending = true; - scene()->update(); - } - d->removedItems << item; - } else { - // Recently added items are purged immediately. unindexedItems() never - // contains stale items. - d->unindexedItems.removeAll(item); - scene()->update(); - } -} - -/*! - Really remove the item from the BSP - \internal -*/ -void QGraphicsSceneBspTreeIndexPrivate::removeFromIndex(QGraphicsItem *item) -{ - if (item->d_func()->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { - // ### remove from child index only if applicable - return; - } - int index = item->d_func()->index; - if (index != -1) { - bsp.removeItem(item, item->sceneBoundingRect()); - freeItemIndexes << index; - indexedItems[index] = 0; - item->d_func()->index = -1; - unindexedItems << item; - - //prepareGeometryChange will call prepareBoundingRectChange - foreach (QGraphicsItem *child, item->children()) - child->prepareGeometryChange(); - } - startIndexTimer(); -} - -/*! - \reimp - Update the BSP when the \a item 's bounding rect has changed. -*/ -void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem *item) -{ - Q_D(QGraphicsSceneBspTreeIndex); - // Note: This will access item's sceneBoundingRect(), which (as this is - // C++) is why we cannot call removeItem() from QGraphicsItem's - // destructor. - d->removeFromIndex(const_cast(item)); -} - -/*! - Returns an estimation visible items that are either inside or - intersect with the specified \a rect and return a list sorted using \a order. - - \a deviceTransform is the transformation apply to the view. - -*/ -QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const -{ - Q_D(const QGraphicsSceneBspTreeIndex); - const_cast(d)->purgeRemovedItems(); - const_cast(d)->_q_updateSortCache(); - - QList rectItems = d->bsp.items(rect); - // Fill in with any unindexed items - for (int i = 0; i < d->unindexedItems.size(); ++i) { - if (QGraphicsItem *item = d->unindexedItems.at(i)) { - if (!item->d_ptr->itemDiscovered && item->d_ptr->visible && !(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { - QRectF boundingRect = item->sceneBoundingRect(); - if (QRectF_intersects(boundingRect, rect)) { - item->d_ptr->itemDiscovered = 1; - rectItems << item; - } - } - } - } - - // Reset the discovered state of all discovered items - for (int i = 0; i < rectItems.size(); ++i) - rectItems.at(i)->d_func()->itemDiscovered = 0; - - d->sortItems(&rectItems, order, d->sortCacheEnabled); - - return rectItems; -} - - -/*! - \fn QList QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order = Qt::AscendingOrder) const; - - Return all items in the BSP index and sort them using \a order. -*/ -QList QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order) const -{ - Q_D(const QGraphicsSceneBspTreeIndex); - const_cast(d)->purgeRemovedItems(); - QList itemList; - // If freeItemIndexes is empty, we know there are no holes in indexedItems and - // unindexedItems. - if (d->freeItemIndexes.isEmpty()) { - if (d->unindexedItems.isEmpty()) { - itemList = d->indexedItems; - } else { - itemList = d->indexedItems + d->unindexedItems; - } - } else { - // Rebuild the list of items to avoid holes. ### We could also just - // compress the item lists at this point. - foreach (QGraphicsItem *item, d->indexedItems + d->unindexedItems) { - if (item) - itemList << item; - } - } - if (order != -1) { - //We sort descending order - d->sortItems(&itemList, order, d->sortCacheEnabled); - } - return itemList; -} - -/*! - \property QGraphicsSceneBspTreeIndex::bspTreeDepth - \brief the depth of the BSP index tree - \since 4.6 - - This value determines the depth of BSP tree. The depth - directly affects performance and memory usage; the latter - growing exponentially with the depth of the tree. With an optimal tree - depth, the index can instantly determine the locality of items, even - for scenes with thousands or millions of items. This also greatly improves - rendering performance. - - By default, the value is 0, in which case Qt will guess a reasonable - default depth based on the size, location and number of items in the - scene. If these parameters change frequently, however, you may experience - slowdowns as the index retunes the depth internally. You can avoid - potential slowdowns by fixating the tree depth through setting this - property. - - The depth of the tree and the size of the scene rectangle decide the - granularity of the scene's partitioning. The size of each scene segment is - determined by the following algorithm: - - The BSP tree has an optimal size when each segment contains between 0 and - 10 items. - -*/ -int QGraphicsSceneBspTreeIndex::bspTreeDepth() -{ - Q_D(const QGraphicsSceneBspTreeIndex); - return d->bspTreeDepth; -} - -void QGraphicsSceneBspTreeIndex::setBspTreeDepth(int depth) -{ - Q_D(QGraphicsSceneBspTreeIndex); - d->bspTreeDepth = depth; - d->resetIndex(); -} - -/*! - \reimp - - This method react to the \a rect change of the scene and - reset the BSP tree index. -*/ -void QGraphicsSceneBspTreeIndex::sceneRectChanged(const QRectF &rect) -{ - Q_D(QGraphicsSceneBspTreeIndex); - d->sceneRect = rect; - d->resetIndex(); -} - -/*! - \reimp - - This method react to the \a change of the \a item and use the \a value to - update the BSP tree if necessary. - -*/ -void QGraphicsSceneBspTreeIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) -{ - Q_D(QGraphicsSceneBspTreeIndex); - switch (change) { - case QGraphicsItem::ItemZValueChange: - case QGraphicsItem::ItemParentChange: { - d->invalidateSortCache(); - break; - } - default: - break; - } - return QGraphicsSceneIndex::itemChanged(item, change, value); -} -/*! - \reimp - - Used to catch the timer event. - - \internal -*/ -bool QGraphicsSceneBspTreeIndex::event(QEvent *event) -{ - Q_D(QGraphicsSceneBspTreeIndex); - switch (event->type()) { - case QEvent::Timer: - if (d->indexTimerId && static_cast(event)->timerId() == d->indexTimerId) { - if (d->restartIndexTimer) { - d->restartIndexTimer = false; - } else { - // this call will kill the timer - d->_q_updateIndex(); - } - } - // Fallthrough intended - support timers in subclasses. - default: - return QObject::event(event); - } - return true; -} - -QT_END_NAMESPACE - -#include "moc_qgraphicsscenebsptreeindex_p.cpp" - -#endif // QT_NO_GRAPHICSVIEW - diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 40b8f0b..6bafbc8 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -39,63 +39,112 @@ ** ****************************************************************************/ -#include - -#ifndef QGRAPHICSBSPTREEINDEX_H -#define QGRAPHICSBSPTREEINDEX_H +#ifndef QGRAPHICSSCENEBSPTREEINDEX_P_H +#define QGRAPHICSSCENEBSPTREEINDEX_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + +#include "qgraphicsscenebsptreeindex.h" #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW +#include +#include + QT_BEGIN_NAMESPACE -#include -#include -#include -#include -#include +static const int QGRAPHICSSCENE_INDEXTIMER_TIMEOUT = 2000; -#include "qgraphicsscene_bsp_p.h" +class QGraphicsScene; -class QGraphicsSceneBspTreeIndexPrivate; -class Q_AUTOTEST_EXPORT QGraphicsSceneBspTreeIndex : public QGraphicsSceneIndex +class QGraphicsSceneBspTreeIndexPrivate : public QGraphicsSceneIndexPrivate { - Q_OBJECT - Q_PROPERTY(int bspTreeDepth READ bspTreeDepth WRITE setBspTreeDepth) + Q_DECLARE_PUBLIC(QGraphicsSceneBspTreeIndex) public: - QGraphicsSceneBspTreeIndex(QGraphicsScene *scene = 0); - QRectF indexedRect() const; - - QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const; - - QList items(Qt::SortOrder order = Qt::AscendingOrder) const; - - int bspTreeDepth(); - void setBspTreeDepth(int depth); - -protected: - bool event(QEvent *event); - void clear(); - - void addItem(QGraphicsItem *item); - void removeItem(QGraphicsItem *item); - void deleteItem(QGraphicsItem *item); - void prepareBoundingRectChange(const QGraphicsItem *item); + QGraphicsSceneBspTreeIndexPrivate(QGraphicsScene *scene); + + QGraphicsSceneBspTree bsp; + QRectF sceneRect; + int bspTreeDepth; + int indexTimerId; + bool restartIndexTimer; + bool regenerateIndex; + int lastItemCount; + + QList indexedItems; + QList unindexedItems; + QList freeItemIndexes; + + bool purgePending; + QSet removedItems; + void purgeRemovedItems(); + + void _q_updateIndex(); + void startIndexTimer(int interval = QGRAPHICSSCENE_INDEXTIMER_TIMEOUT); + void resetIndex(); + + void addToIndex(QGraphicsItem *item); + void removeFromIndex(QGraphicsItem *item); + + void _q_updateSortCache(); + bool sortCacheEnabled; + bool updatingSortCache; + void invalidateSortCache(); + + static void climbTree(QGraphicsItem *item, int *stackingOrder); + static bool closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2); + static bool closestItemLast_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2); + + static inline bool closestItemFirst_withCache(const QGraphicsItem *item1, const QGraphicsItem *item2) + { + return item1->d_ptr->globalStackingOrder < item2->d_ptr->globalStackingOrder; + } + static inline bool closestItemLast_withCache(const QGraphicsItem *item1, const QGraphicsItem *item2) + { + return item1->d_ptr->globalStackingOrder >= item2->d_ptr->globalStackingOrder; + } + + static void sortItems(QList *itemList, Qt::SortOrder order, bool cached); +}; - void sceneRectChanged(const QRectF &rect); - void itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value); -private : - Q_DECLARE_PRIVATE(QGraphicsSceneBspTreeIndex) - Q_DISABLE_COPY(QGraphicsSceneBspTreeIndex) - Q_PRIVATE_SLOT(d_func(), void _q_updateSortCache()) - Q_PRIVATE_SLOT(d_func(), void _q_updateIndex()) +/*! + \internal +*/ +inline bool qt_closestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2) +{ + // Return true if sibling item1 is on top of item2. + const QGraphicsItemPrivate *d1 = item1->d_ptr; + const QGraphicsItemPrivate *d2 = item2->d_ptr; + bool f1 = d1->flags & QGraphicsItem::ItemStacksBehindParent; + bool f2 = d2->flags & QGraphicsItem::ItemStacksBehindParent; + if (f1 != f2) return f2; + qreal z1 = d1->z; + qreal z2 = d2->z; + return z1 > z2; +} + +/*! + \internal +*/ +static inline bool qt_notclosestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2) +{ + return qt_closestLeaf(item2, item1); +} - friend class QGraphicsScene; - friend class QGraphicsScenePrivate; -}; QT_END_NAMESPACE -#endif // QT_NO_GRAPHICSVIEW +#endif // QGRAPHICSSCENEBSPTREEINDEX_P_H + +#endif -#endif // QGRAPHICSBSPTREEINDEX_H diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p_p.h deleted file mode 100644 index 30f6e26..0000000 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p_p.h +++ /dev/null @@ -1,150 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui 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 qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGRAPHICSSCENEBSPTREEINDEX_P_P_H -#define QGRAPHICSSCENEBSPTREEINDEX_P_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header -// file may change from version to version without notice, or even be removed. -// -// We mean it. -// - -#include "qgraphicsscenebsptreeindex_p.h" - -#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW - -#include -#include - -QT_BEGIN_NAMESPACE - -static const int QGRAPHICSSCENE_INDEXTIMER_TIMEOUT = 2000; - -class QGraphicsScene; - -class QGraphicsSceneBspTreeIndexPrivate : public QGraphicsSceneIndexPrivate -{ - Q_DECLARE_PUBLIC(QGraphicsSceneBspTreeIndex) -public: - QGraphicsSceneBspTreeIndexPrivate(QGraphicsScene *scene); - - QGraphicsSceneBspTree bsp; - QRectF sceneRect; - int bspTreeDepth; - int indexTimerId; - bool restartIndexTimer; - bool regenerateIndex; - int lastItemCount; - - QList indexedItems; - QList unindexedItems; - QList freeItemIndexes; - - bool purgePending; - QSet removedItems; - void purgeRemovedItems(); - - void _q_updateIndex(); - void startIndexTimer(int interval = QGRAPHICSSCENE_INDEXTIMER_TIMEOUT); - void resetIndex(); - - void addToIndex(QGraphicsItem *item); - void removeFromIndex(QGraphicsItem *item); - - void _q_updateSortCache(); - bool sortCacheEnabled; - bool updatingSortCache; - void invalidateSortCache(); - - static void climbTree(QGraphicsItem *item, int *stackingOrder); - static bool closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2); - static bool closestItemLast_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2); - - static inline bool closestItemFirst_withCache(const QGraphicsItem *item1, const QGraphicsItem *item2) - { - return item1->d_ptr->globalStackingOrder < item2->d_ptr->globalStackingOrder; - } - static inline bool closestItemLast_withCache(const QGraphicsItem *item1, const QGraphicsItem *item2) - { - return item1->d_ptr->globalStackingOrder >= item2->d_ptr->globalStackingOrder; - } - - static void sortItems(QList *itemList, Qt::SortOrder order, bool cached); -}; - - -/*! - \internal -*/ -inline bool qt_closestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2) -{ - // Return true if sibling item1 is on top of item2. - const QGraphicsItemPrivate *d1 = item1->d_ptr; - const QGraphicsItemPrivate *d2 = item2->d_ptr; - bool f1 = d1->flags & QGraphicsItem::ItemStacksBehindParent; - bool f2 = d2->flags & QGraphicsItem::ItemStacksBehindParent; - if (f1 != f2) return f2; - qreal z1 = d1->z; - qreal z2 = d2->z; - return z1 > z2; -} - -/*! - \internal -*/ -static inline bool qt_notclosestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2) -{ - return qt_closestLeaf(item2, item1); -} - - -QT_END_NAMESPACE - -#endif // QGRAPHICSSCENEBSPTREEINDEX_P_P_H - -#endif - diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 05ec28b..966d8fe 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -46,6 +46,7 @@ \ingroup multimedia \ingroup graphicsview-api \mainclass + \internal The QGraphicsSceneIndex class provides a base class to implement a custom indexing algorithm for discovering items in QGraphicsScene. You @@ -57,7 +58,6 @@ #include "qgraphicssceneindex.h" #include "qgraphicssceneindex_p.h" -#include "qgraphicsscenebsptreeindex_p_p.h" #include "qgraphicsscene.h" #include "qgraphicsitem_p.h" #include "qgraphicsscene_p.h" diff --git a/src/gui/graphicsview/qgraphicssceneindex.h b/src/gui/graphicsview/qgraphicssceneindex.h index 084a623..c0e415c 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.h +++ b/src/gui/graphicsview/qgraphicssceneindex.h @@ -42,6 +42,17 @@ #ifndef QGRAPHICSSCENEINDEX_H #define QGRAPHICSSCENEINDEX_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + #include #include #include @@ -61,7 +72,7 @@ class QRectF; class QPointF; template class QList; -class Q_GUI_EXPORT QGraphicsSceneIndex: public QObject +class Q_AUTOTEST_EXPORT QGraphicsSceneIndex: public QObject { Q_OBJECT diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex.cpp b/src/gui/graphicsview/qgraphicsscenelinearindex.cpp index 1c898bc..5504493 100644 --- a/src/gui/graphicsview/qgraphicsscenelinearindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenelinearindex.cpp @@ -1,4 +1,4 @@ -#include "qgraphicsscenelinearindex_p.h" +#include "qgraphicsscenelinearindex.h" /*! \class QGraphicsSceneLinearIndex @@ -8,6 +8,7 @@ \ingroup multimedia \ingroup graphicsview-api \mainclass + \internal QGraphicsSceneLinearIndex index is default linear implementation to discover items. It basically store all items in a list and return them to the scene. diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex.h b/src/gui/graphicsview/qgraphicsscenelinearindex.h new file mode 100644 index 0000000..b793d98 --- /dev/null +++ b/src/gui/graphicsview/qgraphicsscenelinearindex.h @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui 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 qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGRAPHICSSCENELINEARINDEX_H +#define QGRAPHICSSCENELINEARINDEX_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW + +#include +#include +#include +#include + +class Q_AUTOTEST_EXPORT QGraphicsSceneLinearIndex : public QGraphicsSceneIndex +{ + Q_OBJECT + +public: + QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0): QGraphicsSceneIndex(scene) + { + } + + QList items(Qt::SortOrder order = Qt::AscendingOrder) const { + Q_UNUSED(order); + return m_items; + } + + virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const { + Q_UNUSED(rect); + Q_UNUSED(order); + Q_UNUSED(deviceTransform); + return m_items; + } + + virtual QRectF indexedRect() const { + return m_sceneRect; + } + +protected : + void sceneRectChanged(const QRectF &rect) { + m_sceneRect = rect; + } + + virtual void clear() { + m_items.clear(); + } + + virtual void addItem(QGraphicsItem *item) { + m_items << item; + } + + virtual void removeItem(QGraphicsItem *item) { + m_items.removeAll(item); + } + +private: + QRectF m_sceneRect; + QList m_items; +}; + +#endif // QT_NO_GRAPHICSVIEW + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QGRAPHICSSCENELINEARINDEX_H diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h deleted file mode 100644 index d21475c..0000000 --- a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui 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 qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGRAPHICSSCENELINEARINDEX_P_H -#define QGRAPHICSSCENELINEARINDEX_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include - -#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW - -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class Q_AUTOTEST_EXPORT QGraphicsSceneLinearIndex : public QGraphicsSceneIndex -{ - Q_OBJECT - -public: - QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0): QGraphicsSceneIndex(scene) - { - } - - QList items(Qt::SortOrder order = Qt::AscendingOrder) const { - Q_UNUSED(order); - return m_items; - } - - virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const { - Q_UNUSED(rect); - Q_UNUSED(order); - Q_UNUSED(deviceTransform); - return m_items; - } - - virtual QRectF indexedRect() const { - return m_sceneRect; - } - -protected : - void sceneRectChanged(const QRectF &rect) { - m_sceneRect = rect; - } - - virtual void clear() { - m_items.clear(); - } - - virtual void addItem(QGraphicsItem *item) { - m_items << item; - } - - virtual void removeItem(QGraphicsItem *item) { - m_items.removeAll(item); - } - -private: - QRectF m_sceneRect; - QList m_items; -}; - -QT_END_NAMESPACE - -#endif // QT_NO_GRAPHICSVIEW - -#endif // QGRAPHICSSCENELINEARINDEX_P_H -- cgit v0.12 From 5d682567d1acb79b2fa55ae8f005c5dcdc9aacb7 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Wed, 17 Jun 2009 14:27:46 +0200 Subject: API / code review for QGraphicsSceneIndex (internal API). A few minor modifications only, marked some things as ### obsolete, removed the public get/set for the index (it's internal anyway). --- src/gui/graphicsview/qgraphicsitem.h | 48 ++++++------ src/gui/graphicsview/qgraphicsscene.cpp | 90 ++++------------------ src/gui/graphicsview/qgraphicsscene.h | 11 +-- src/gui/graphicsview/qgraphicsscene_p.h | 40 ---------- .../graphicsview/qgraphicsscenebsptreeindex.cpp | 6 +- .../graphicsview/qgraphicsscenebsptreeindex_p.h | 40 ++++++++++ 6 files changed, 86 insertions(+), 149 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index ec16d26..12dcad2 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -141,7 +141,7 @@ public: QGraphicsItem(QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); @@ -208,8 +208,8 @@ public: Qt::MouseButtons acceptedMouseButtons() const; void setAcceptedMouseButtons(Qt::MouseButtons buttons); - bool acceptsHoverEvents() const; // obsolete - void setAcceptsHoverEvents(bool enabled); // obsolete + bool acceptsHoverEvents() const; // ### obsolete + void setAcceptsHoverEvents(bool enabled); // ### obsolete bool acceptHoverEvents() const; void setAcceptHoverEvents(bool enabled); @@ -534,7 +534,7 @@ class Q_GUI_EXPORT QAbstractGraphicsShapeItem : public QGraphicsItem public: QAbstractGraphicsShapeItem(QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); @@ -564,13 +564,13 @@ class Q_GUI_EXPORT QGraphicsPathItem : public QAbstractGraphicsShapeItem public: QGraphicsPathItem(QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); QGraphicsPathItem(const QPainterPath &path, QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); @@ -607,19 +607,19 @@ class Q_GUI_EXPORT QGraphicsRectItem : public QAbstractGraphicsShapeItem public: QGraphicsRectItem(QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); QGraphicsRectItem(const QRectF &rect, QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); QGraphicsRectItem(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); @@ -660,19 +660,19 @@ class Q_GUI_EXPORT QGraphicsEllipseItem : public QAbstractGraphicsShapeItem public: QGraphicsEllipseItem(QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); QGraphicsEllipseItem(const QRectF &rect, QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); QGraphicsEllipseItem(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); @@ -719,14 +719,14 @@ class Q_GUI_EXPORT QGraphicsPolygonItem : public QAbstractGraphicsShapeItem public: QGraphicsPolygonItem(QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); QGraphicsPolygonItem(const QPolygonF &polygon, QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); @@ -766,19 +766,19 @@ class Q_GUI_EXPORT QGraphicsLineItem : public QGraphicsItem public: QGraphicsLineItem(QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); QGraphicsLineItem(const QLineF &line, QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); QGraphicsLineItem(qreal x1, qreal y1, qreal x2, qreal y2, QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); @@ -826,13 +826,13 @@ public: QGraphicsPixmapItem(QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); QGraphicsPixmapItem(const QPixmap &pixmap, QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); @@ -888,13 +888,13 @@ class Q_GUI_EXPORT QGraphicsTextItem : public QGraphicsObject public: QGraphicsTextItem(QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); QGraphicsTextItem(const QString &text, QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); @@ -989,13 +989,13 @@ class Q_GUI_EXPORT QGraphicsSimpleTextItem : public QAbstractGraphicsShapeItem public: QGraphicsSimpleTextItem(QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); QGraphicsSimpleTextItem(const QString &text, QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); @@ -1035,7 +1035,7 @@ class Q_GUI_EXPORT QGraphicsItemGroup : public QGraphicsItem public: QGraphicsItemGroup(QGraphicsItem *parent = 0 #ifndef Q_QDOC - // obsolete argument + // ### obsolete argument , QGraphicsScene *scene = 0 #endif ); diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index a33cb3e..dacfc87 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -201,8 +201,6 @@ however, is done in constant time. This approach is ideal for dynamic scenes, where many items are added, moved or removed continuously. - \omitvalue CustomIndex - \sa setItemIndexMethod(), bspTreeDepth */ @@ -1529,85 +1527,19 @@ QGraphicsScene::ItemIndexMethod QGraphicsScene::itemIndexMethod() const Q_D(const QGraphicsScene); return d->indexMethod; } - -// Possibilities -// NoIndex -> CustomIndex : warning -// BspTreeIndex -> CustomIndex : warning -// CustomIndex -> CustomIndex : warning -// NoIndex -> BspTreeIndex : create an empty BSP if necessary -// BspTreeIndex -> BspTreeIndex : nothing -// CustomIndex -> BspTreeIndex : create BSP and transfer items -// NoIndex -> NoIndex : nothing -// BspTreeIndex -> NoIndex : nothing -// CustomIndex -> NoIndex : create BSP tree but do not populate void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method) { Q_D(QGraphicsScene); - if (method == CustomIndex) { - qWarning("QGraphicsScene: Invalid index type %d", CustomIndex); + if (d->indexMethod == method) return; - } - if (d->indexMethod == method) { - return; - } - if (d->indexMethod == NoIndex && method == BspTreeIndex) { - QGraphicsSceneBspTreeIndex *tree = qobject_cast(d->index); - if (!tree) { - delete d->index; - d->index = new QGraphicsSceneBspTreeIndex(this); - } - } + d->indexMethod = method; - if (d->indexMethod == CustomIndex && method == BspTreeIndex) { - //We re-add in the new index all items from the old index - QGraphicsSceneIndex *oldIndex = d->index; + delete d->index; + if (method == BspTreeIndex) d->index = new QGraphicsSceneBspTreeIndex(this); - for (int i = 0 ; i < oldIndex->items().size() ; ++ i) - d->index->addItem(oldIndex->items().at(i)); - } - - if (d->indexMethod == CustomIndex && method == NoIndex) { + else d->index = new QGraphicsSceneLinearIndex(this); - } - - d->indexMethod = method; -} - -/*! - \internal - - \brief the item indexing method. - This method allow to apply an indexing algorithm \a index to the scene, to speed up - item discovery functions like items() and itemAt(). - - \sa sceneIndex(), QGraphicsSceneIndex -*/ -void QGraphicsScene::setSceneIndex(QGraphicsSceneIndex *index) -{ - Q_D(QGraphicsScene); - if (!index) { - qWarning("QGraphicsScene::setSceneIndex: Attempt to insert a null indexer"); - } else { - if (d->indexMethod == BspTreeIndex) { - delete d->index; - } - d->indexMethod = CustomIndex; - d->index = index; - } -} - -/*! - \internal - - This method return the current indexing algorithm of the scene. - - \sa setSceneIndex(), QGraphicsSceneIndex -*/ -QGraphicsSceneIndex* QGraphicsScene::sceneIndex() const -{ - Q_D(const QGraphicsScene); - return d->index; } /*! @@ -1814,7 +1746,8 @@ QList QGraphicsScene::items(const QPainterPath &path, Qt::ItemS \sa itemAt() */ -QList QGraphicsScene::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +QList QGraphicsScene::items(const QPointF &pos, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsScene); return d->index->items(pos, mode, order, deviceTransform); @@ -1833,7 +1766,8 @@ QList QGraphicsScene::items(const QPointF &pos, Qt::ItemSelecti \sa itemAt() */ -QList QGraphicsScene::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +QList QGraphicsScene::items(const QRectF &rect, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsScene); return d->index->items(rect, mode, order, deviceTransform); @@ -1852,7 +1786,8 @@ QList QGraphicsScene::items(const QRectF &rect, Qt::ItemSelecti \sa itemAt() */ -QList QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +QList QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsScene); return d->index->items(polygon, mode, order, deviceTransform); @@ -1871,7 +1806,8 @@ QList QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemS \sa itemAt() */ -QList QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +QList QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsScene); return d->index->items(path, mode, order, deviceTransform); diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h index 36374c8..b922be5 100644 --- a/src/gui/graphicsview/qgraphicsscene.h +++ b/src/gui/graphicsview/qgraphicsscene.h @@ -114,7 +114,6 @@ class Q_GUI_EXPORT QGraphicsScene : public QObject public: enum ItemIndexMethod { BspTreeIndex, - CustomIndex, NoIndex = -1 }; @@ -144,8 +143,6 @@ public: ItemIndexMethod itemIndexMethod() const; void setItemIndexMethod(ItemIndexMethod method); - void setSceneIndex(QGraphicsSceneIndex *index); - QGraphicsSceneIndex* sceneIndex() const; bool isSortCacheEnabled() const; void setSortCacheEnabled(bool enabled); @@ -162,10 +159,10 @@ public: QList items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; QList items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; - QList items(const QPointF &pos) const; - QList items(const QRectF &rect, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; - QList items(const QPolygonF &polygon, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; - QList items(const QPainterPath &path, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; + QList items(const QPointF &pos) const; // ### obsolete + QList items(const QRectF &rect, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; // ### obsolete + QList items(const QPolygonF &polygon, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; // ### obsolete + QList items(const QPainterPath &path, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; // ### obsolete QList collidingItems(const QGraphicsItem *item, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; QGraphicsItem *itemAt(const QPointF &pos) const; diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 563e016..8e05c00 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -229,46 +229,6 @@ public: QStyleOptionGraphicsItem styleOptionTmp; }; -static inline bool QRectF_intersects(const QRectF &s, const QRectF &r) -{ - qreal xp = s.left(); - qreal yp = s.top(); - qreal w = s.width(); - qreal h = s.height(); - qreal l1 = xp; - qreal r1 = xp; - if (w < 0) - l1 += w; - else - r1 += w; - - qreal l2 = r.left(); - qreal r2 = r.left(); - if (w < 0) - l2 += r.width(); - else - r2 += r.width(); - - if (l1 >= r2 || l2 >= r1) - return false; - - qreal t1 = yp; - qreal b1 = yp; - if (h < 0) - t1 += h; - else - b1 += h; - - qreal t2 = r.top(); - qreal b2 = r.top(); - if (r.height() < 0) - t2 += r.height(); - else - b2 += r.height(); - - return !(t1 >= b2 || t2 >= b1); -} - // QRectF::intersects() returns false always if either the source or target // rectangle's width or height are 0. This works around that problem. static inline void _q_adjustRect(QRectF *rect) diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 76fd218..969d3c5 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -589,12 +589,16 @@ void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem * \a deviceTransform is the transformation apply to the view. */ -QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const +QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &rect, Qt::SortOrder order, + const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneBspTreeIndex); const_cast(d)->purgeRemovedItems(); const_cast(d)->_q_updateSortCache(); + // ### Handle items that ignore transformations + Q_UNUSED(deviceTransform); + QList rectItems = d->bsp.items(rect); // Fill in with any unindexed items for (int i = 0; i < d->unindexedItems.size(); ++i) { diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 6bafbc8..b6f782d 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -142,6 +142,46 @@ static inline bool qt_notclosestLeaf(const QGraphicsItem *item1, const QGraphics } +static inline bool QRectF_intersects(const QRectF &s, const QRectF &r) +{ + qreal xp = s.left(); + qreal yp = s.top(); + qreal w = s.width(); + qreal h = s.height(); + qreal l1 = xp; + qreal r1 = xp; + if (w < 0) + l1 += w; + else + r1 += w; + + qreal l2 = r.left(); + qreal r2 = r.left(); + if (w < 0) + l2 += r.width(); + else + r2 += r.width(); + + if (l1 >= r2 || l2 >= r1) + return false; + + qreal t1 = yp; + qreal b1 = yp; + if (h < 0) + t1 += h; + else + b1 += h; + + qreal t2 = r.top(); + qreal b2 = r.top(); + if (r.height() < 0) + t2 += r.height(); + else + b2 += r.height(); + + return !(t1 >= b2 || t2 >= b1); +} + QT_END_NAMESPACE #endif // QGRAPHICSSCENEBSPTREEINDEX_P_H -- cgit v0.12 From 625dadcc9b88dccebf607b84089ab960740b94f2 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Wed, 17 Jun 2009 14:36:55 +0200 Subject: Don't lose all the items when we switch item index method. Readd the items to the new index. Reviewed-by: Alexis --- src/gui/graphicsview/qgraphicsscene.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index dacfc87..36af30d 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1535,11 +1535,14 @@ void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method) d->indexMethod = method; + QList oldItems = d->index->items(); delete d->index; if (method == BspTreeIndex) d->index = new QGraphicsSceneBspTreeIndex(this); else d->index = new QGraphicsSceneLinearIndex(this); + for (int i = 0; i < oldItems.size(); ++i) + d->index->addItem(oldItems.at(i)); } /*! -- cgit v0.12 From ac8bf5ec1f99d0e00e3ffefe53306c0d511376bf Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Wed, 17 Jun 2009 14:46:54 +0200 Subject: More cleanups during code review. Reviewed-by: Alexis --- src/gui/graphicsview/qgraphicsscene.cpp | 104 --------------------------- src/gui/graphicsview/qgraphicsscene_p.h | 4 -- src/gui/graphicsview/qgraphicssceneindex.cpp | 54 +++++++++----- src/gui/graphicsview/qgraphicssceneindex.h | 18 +++-- 4 files changed, 47 insertions(+), 133 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 36af30d..380ac20 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1097,110 +1097,6 @@ QGraphicsWidget *QGraphicsScenePrivate::windowForItem(const QGraphicsItem *item) return 0; } -void QGraphicsScenePrivate::recursive_items_helper(QGraphicsItem *item, QRectF rect, - QList *items, - const QTransform &parentTransform, - const QTransform &viewTransform, - Qt::ItemSelectionMode mode, Qt::SortOrder order, - qreal parentOpacity) const -{ - // Calculate opacity. - qreal opacity; - if (item) { - if (!item->d_ptr->visible) - return; - QGraphicsItem *p = item->d_ptr->parent; - bool itemIgnoresParentOpacity = item->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity; - bool parentDoesntPropagateOpacity = (p && (p->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)); - if (!itemIgnoresParentOpacity && !parentDoesntPropagateOpacity) { - opacity = parentOpacity * item->opacity(); - } else { - opacity = item->d_ptr->opacity; - } - if (opacity == 0.0 && !(item->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) - return; - } else { - opacity = parentOpacity; - } - - // Calculate the full transform for this item. - QTransform transform = parentTransform; - bool keep = false; - if (item) { - item->d_ptr->combineTransformFromParent(&transform, &viewTransform); - - // ### This does not take the clip into account. - QRectF brect = item->boundingRect(); - _q_adjustRect(&brect); - - keep = true; - if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) - keep = rect.contains(transform.mapRect(brect)) && rect != brect; - else - keep = rect.intersects(transform.mapRect(brect)); - - if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { - QPainterPath rectPath; - rectPath.addRect(rect); - keep = itemCollidesWithPath(item, transform.inverted().map(rectPath), mode); - } - } - - bool childClip = (item && (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)); - bool dontProcessItem = !item || !keep; - bool dontProcessChildren = item && dontProcessItem && childClip; - - // Find and sort children. - QList &children = item ? item->d_ptr->children : const_cast(this)->topLevelItems; - if (!dontProcessChildren) { - if (item && item->d_ptr->needSortChildren) { - item->d_ptr->needSortChildren = 0; - qStableSort(children.begin(), children.end(), qt_notclosestLeaf); - } else if (!item && needSortTopLevelItems) { - const_cast(this)->needSortTopLevelItems = false; - qStableSort(children.begin(), children.end(), qt_notclosestLeaf); - } - } - - childClip &= !dontProcessChildren & !children.isEmpty(); - - // Clip. - if (childClip) - rect &= transform.map(item->shape()).controlPointRect(); - - // Process children behind - int i = 0; - if (!dontProcessChildren) { - for (i = 0; i < children.size(); ++i) { - QGraphicsItem *child = children.at(i); - if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent)) - break; - recursive_items_helper(child, rect, items, transform, viewTransform, - mode, order, opacity); - } - } - - // Process item - if (!dontProcessItem) - items->append(item); - - // Process children in front - if (!dontProcessChildren) { - for (; i < children.size(); ++i) - recursive_items_helper(children.at(i), rect, items, transform, viewTransform, - mode, order, opacity); - } - - if (!item && order == Qt::AscendingOrder) { - int n = items->size(); - for (int i = 0; i < n / 2; ++i) { - QGraphicsItem *tmp = (*items)[n - i - 1]; - (*items)[n - i - 1] = (*items)[i]; - (*items)[i] = tmp; - } - } -} - /*! \internal diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 8e05c00..538ff3f 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -188,10 +188,6 @@ public: void mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent); QGraphicsWidget *windowForItem(const QGraphicsItem *item) const; - void recursive_items_helper(QGraphicsItem *item, QRectF rect, QList *items, - const QTransform &parentTransform, const QTransform &viewTransform, - Qt::ItemSelectionMode mode, Qt::SortOrder order, qreal parentOpacity = 1.0) const; - void drawItemHelper(QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget, bool painterStateProtection); diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 966d8fe..4ca1c02 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -119,9 +119,8 @@ public: else keep = rect.intersects(transform.mapRect(brect)); - if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { + if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) keep = QGraphicsScenePrivate::get(scene)->itemCollidesWithPath(item, transform.inverted().map(path), mode); - } return keep; } QPainterPath path; @@ -290,24 +289,27 @@ QRectF QGraphicsSceneIndex::indexedRect() const } /*! - \fn QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const + \fn QList QGraphicsSceneIndex::items(const QPointF &pos, + Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform + &deviceTransform) const - Returns all visible items that, depending on \a mode, are at the specified \a pos - and return a list sorted using \a order. + Returns all visible items that, depending on \a mode, are at the specified + \a pos and return a list sorted using \a order. The default value for \a mode is Qt::IntersectsItemShape; all items whose exact shape intersects with \a pos are returned. \a deviceTransform is the transformation apply to the view. - This method use the estimation of the index (estimateItems) and refine - the list to get an exact result. If you want to implement your own - refinement algorithm you can reimplement this method. + This method use the estimation of the index (estimateItems) and refine the + list to get an exact result. If you want to implement your own refinement + algorithm you can reimplement this method. \sa estimateItems() */ -QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); QList itemList; @@ -319,7 +321,9 @@ QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSe } /*! - \fn QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const + \fn QList QGraphicsSceneIndex::items(const QRectF &rect, + Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform + &deviceTransform) const \overload @@ -338,7 +342,8 @@ QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSe \sa estimateItems() */ -QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); QList itemList; @@ -349,7 +354,9 @@ QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSe } /*! - \fn QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const + \fn QList QGraphicsSceneIndex::items(const QPolygonF + &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const + QTransform &deviceTransform) const \overload @@ -368,7 +375,8 @@ QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSe \sa estimateItems() */ -QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); QList itemList; @@ -384,7 +392,9 @@ QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt:: } /*! - \fn QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const + \fn QList QGraphicsSceneIndex::items(const QPainterPath + &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform + &deviceTransform) const \overload @@ -403,7 +413,8 @@ QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt:: \sa estimateItems() */ -QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const +QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); QList itemList; @@ -421,13 +432,16 @@ QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt:: This method return a list sorted using \a order. \a deviceTransform is the transformation apply to the view. */ -QList QGraphicsSceneIndex::estimateItems(const QPointF &point, Qt::SortOrder order, const QTransform &deviceTransform) const +QList QGraphicsSceneIndex::estimateItems(const QPointF &point, Qt::SortOrder order, + const QTransform &deviceTransform) const { return estimateItems(QRectF(point, QSize(1,1)), order, deviceTransform); } /*! - \fn virtual QList QGraphicsSceneIndex::estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const = 0 + \fn virtual QList + QGraphicsSceneIndex::estimateItems(const QRectF &rect, Qt::SortOrder + order, const QTransform &deviceTransform) const = 0 This pure virtual function return an estimation of items in the \a rect. This method return a list sorted using \a order. @@ -436,8 +450,10 @@ QList QGraphicsSceneIndex::estimateItems(const QPointF &point, */ /*! - \fn virtual QList QGraphicsSceneIndex::items(Qt::SortOrder order = Qt::AscendingOrder) const = 0; - This pure virtual function all items in the index and sort them using \a order. + \fn virtual QList + QGraphicsSceneIndex::items(Qt::SortOrder order = Qt::AscendingOrder) const + = 0; This pure virtual function all items in the index and sort them using + \a order. */ /*! diff --git a/src/gui/graphicsview/qgraphicssceneindex.h b/src/gui/graphicsview/qgraphicssceneindex.h index c0e415c..ddce9d4 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.h +++ b/src/gui/graphicsview/qgraphicssceneindex.h @@ -85,12 +85,18 @@ public: virtual QRectF indexedRect() const; virtual QList items(Qt::SortOrder order = Qt::AscendingOrder) const = 0; - virtual QList items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; - virtual QList items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; - virtual QList items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; - virtual QList items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; - virtual QList estimateItems(const QPointF &point, Qt::SortOrder order, const QTransform &deviceTransform) const; - virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const = 0; + virtual QList items(const QPointF &pos, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + virtual QList items(const QRectF &rect, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + virtual QList items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + virtual QList items(const QPainterPath &path, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + virtual QList estimateItems(const QPointF &point, + Qt::SortOrder order, const QTransform &deviceTransform) const; + virtual QList estimateItems(const QRectF &rect, + Qt::SortOrder order, const QTransform &deviceTransform) const = 0; protected: virtual void clear(); -- cgit v0.12 From 0d839e3655d985920aff81882bd444605d97c21c Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Thu, 18 Jun 2009 14:28:29 +0200 Subject: Changes after first round of code reviewing. This change removes all code that handles ItemIgnoresTransformations from QGraphicsView, and changes the APIs of the scene index intersectors. Reviewed-by: Alexis --- src/gui/graphicsview/qgraphicsitem.cpp | 33 ++-- src/gui/graphicsview/qgraphicsitem_p.h | 9 + src/gui/graphicsview/qgraphicsscene.cpp | 141 ++++++-------- src/gui/graphicsview/qgraphicsscene.h | 17 +- src/gui/graphicsview/qgraphicsscene_p.h | 4 +- .../graphicsview/qgraphicsscenebsptreeindex.cpp | 96 +++++---- src/gui/graphicsview/qgraphicsscenebsptreeindex.h | 2 +- .../graphicsview/qgraphicsscenebsptreeindex_p.h | 5 +- src/gui/graphicsview/qgraphicssceneindex.cpp | 216 ++++++++++++++------- src/gui/graphicsview/qgraphicssceneindex.h | 2 +- src/gui/graphicsview/qgraphicssceneindex_p.h | 19 +- src/gui/graphicsview/qgraphicsview.cpp | 161 ++++----------- src/gui/graphicsview/qgraphicsview_p.h | 7 +- 13 files changed, 368 insertions(+), 344 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 593d7be..75683d8 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -857,6 +857,11 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) if (newParent == parent) return; + if (scene) { + // Deliver the change to the index + scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParentVariant); + } + if (QGraphicsWidget *w = isWidget ? static_cast(q) : q->parentWidget()) { // Update the child focus chain; when reparenting a widget that has a // focus child, ensure that that focus child clears its focus child @@ -951,11 +956,6 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) // Deliver post-change notification q->itemChange(QGraphicsItem::ItemParentHasChanged, newParentVariant); - if (scene) { - // Deliver the change to the index - scene->d_func()->index->itemChanged(q, QGraphicsItem::ItemParentHasChanged, newParentVariant); - } - if (isObject) emit static_cast(q)->parentChanged(); } @@ -1426,6 +1426,8 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) flags = GraphicsItemFlags(itemChange(ItemFlagsChange, quint32(flags)).toUInt()); if (quint32(d_ptr->flags) == quint32(flags)) return; + if (d_ptr->scene) + d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, quint32(flags)); // Flags that alter the geometry of the item (or its children). const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations); @@ -3577,17 +3579,20 @@ void QGraphicsItem::setZValue(qreal z) qreal newZ = qreal(newZVariant.toDouble()); if (newZ == d_ptr->z) return; + + if (d_ptr->scene) { + // Z Value has changed, we have to notify the index. + d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, newZVariant); + } + d_ptr->z = newZ; if (d_ptr->parent) d_ptr->parent->d_ptr->needSortChildren = 1; else if (d_ptr->scene) d_ptr->scene->d_func()->needSortTopLevelItems = 1; - if (d_ptr->scene) { + if (d_ptr->scene) d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true); - //Z Value has changed, we have to notify the index. - d_ptr->scene->d_func()->index->itemChanged(this, ItemZValueChange, z); - } itemChange(ItemZValueHasChanged, newZVariant); @@ -9655,17 +9660,11 @@ QDebug operator<<(QDebug debug, QGraphicsItem *item) return debug; } - QStringList flags; - if (item->isVisible()) flags << QLatin1String("isVisible"); - if (item->isEnabled()) flags << QLatin1String("isEnabled"); - if (item->isSelected()) flags << QLatin1String("isSelected"); - if (item->hasFocus()) flags << QLatin1String("HasFocus"); - debug << "QGraphicsItem(this =" << ((void*)item) << ", parent =" << ((void*)item->parentItem()) << ", pos =" << item->pos() - << ", z =" << item->zValue() << ", flags = {" - << flags.join(QLatin1String("|")) << " })"; + << ", z =" << item->zValue() << ", flags = " + << item->flags() << ")"; return debug; } diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 9c1ee4f..1c95a62 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -158,6 +158,15 @@ public: inline virtual ~QGraphicsItemPrivate() { } + static const QGraphicsItemPrivate *get(const QGraphicsItem *item) + { + return item->d_ptr; + } + static QGraphicsItemPrivate *get(QGraphicsItem *item) + { + return item->d_ptr; + } + void updateAncestorFlag(QGraphicsItem::GraphicsItemFlag childFlag, AncestorFlag flag = NoFlag, bool enabled = false, bool root = true); void setIsMemberOfGroup(bool enabled); diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 380ac20..55f0f20 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -774,41 +774,8 @@ QList QGraphicsScenePrivate::itemsAtPosition(const QPoint &scre { Q_Q(const QGraphicsScene); QGraphicsView *view = widget ? qobject_cast(widget->parentWidget()) : 0; - QList items; - if (view) - items = view->items(view->viewport()->mapFromGlobal(screenPos)); - else - items = q->items(scenePos); - return items; -} - -/*! - \internal - - Checks if item collides with the path and mode, but also checks that if it - doesn't collide, maybe its frame rect will. -*/ -bool QGraphicsScenePrivate::itemCollidesWithPath(QGraphicsItem *item, - const QPainterPath &path, - Qt::ItemSelectionMode mode) -{ - if (item->collidesWithPath(path, mode)) - return true; - if (item->isWidget()) { - // Check if this is a window, and if its frame rect collides. - QGraphicsWidget *widget = static_cast(item); - if (widget->isWindow()) { - QRectF frameRect = widget->windowFrameRect(); - QPainterPath framePath; - framePath.addRect(frameRect); - bool intersects = path.intersects(frameRect); - if (mode == Qt::IntersectsItemShape || mode == Qt::IntersectsItemBoundingRect) - return intersects || path.contains(frameRect.topLeft()) - || framePath.contains(path.elementAt(0)); - return !intersects && path.contains(frameRect.topLeft()); - } - } - return false; + return q->items(scenePos, Qt::IntersectsItemShape, Qt::AscendingOrder, + view ? view->viewportTransform() : QTransform()); } /*! @@ -820,7 +787,7 @@ void QGraphicsScenePrivate::storeMouseButtonsForMouseGrabber(QGraphicsSceneMouse if (event->buttons() & i) { mouseGrabberButtonDownPos.insert(Qt::MouseButton(i), mouseGrabberItems.last()->d_ptr->genericMapFromScene(event->scenePos(), - event->widget())); + event->widget())); mouseGrabberButtonDownScenePos.insert(Qt::MouseButton(i), event->scenePos()); mouseGrabberButtonDownScreenPos.insert(Qt::MouseButton(i), event->screenPos()); } @@ -1282,6 +1249,8 @@ QGraphicsScene::~QGraphicsScene() QRectF QGraphicsScene::sceneRect() const { Q_D(const QGraphicsScene); + /// ### Remove? The growing items bounding rect might be managed + // by the scene. return d->index->indexedRect(); } void QGraphicsScene::setSceneRect(const QRectF &rect) @@ -1332,6 +1301,8 @@ void QGraphicsScene::setSceneRect(const QRectF &rect) void QGraphicsScene::render(QPainter *painter, const QRectF &target, const QRectF &source, Qt::AspectRatioMode aspectRatioMode) { + // ### Switch to using the recursive rendering algorithm instead. + // Default source rect = scene rect QRectF sourceRect = source; if (sourceRect.isNull()) @@ -1431,14 +1402,16 @@ void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method) d->indexMethod = method; - QList oldItems = d->index->items(); + QList oldItems = d->index->items(Qt::AscendingOrder); delete d->index; if (method == BspTreeIndex) d->index = new QGraphicsSceneBspTreeIndex(this); else d->index = new QGraphicsSceneLinearIndex(this); - for (int i = 0; i < oldItems.size(); ++i) + for (int i = oldItems.size() - 1; i >= 0; --i) d->index->addItem(oldItems.at(i)); + + d->index->sceneRectChanged(d->sceneRect); } /*! @@ -1476,7 +1449,7 @@ void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method) int QGraphicsScene::bspTreeDepth() const { Q_D(const QGraphicsScene); - QGraphicsSceneBspTreeIndex *bspTree = qobject_cast(d->index); + QGraphicsSceneBspTreeIndex *bspTree = qobject_cast(d->index); return bspTree ? bspTree->bspTreeDepth() : 0; } void QGraphicsScene::setBspTreeDepth(int depth) @@ -1487,14 +1460,11 @@ void QGraphicsScene::setBspTreeDepth(int depth) return; } - QGraphicsSceneBspTreeIndex *bspTree = qobject_cast(d->index); + QGraphicsSceneBspTreeIndex *bspTree = qobject_cast(d->index); if (!bspTree) { qWarning("QGraphicsScene::setBspTreeDepth: can not apply if indexing method is not BSP"); return; } - if (bspTree->bspTreeDepth() == depth) - return; - bspTree->setBspTreeDepth(depth); } @@ -1502,37 +1472,21 @@ void QGraphicsScene::setBspTreeDepth(int depth) \property QGraphicsScene::sortCacheEnabled \brief whether sort caching is enabled \since 4.5 + \obsolete - When enabled, this property adds a cache that speeds up sorting and - transformations for scenes with deep hierarchies (i.e., items with many - levels of descendents), at the cost of using more memory (approx. 100 more - bytes of memory per item). - - Items that are not part of a deep hierarchy suffer no penalty from this - cache. + Since Qt 4.6, this property has no effect. */ bool QGraphicsScene::isSortCacheEnabled() const { Q_D(const QGraphicsScene); - QGraphicsSceneBspTreeIndex *bspTree = qobject_cast(d->index); - if (!bspTree) { - qWarning("QGraphicsScene::isSortCacheEnabled: can not apply if indexing method is not BSP"); - return false; - } - return bspTree->d_func()->sortCacheEnabled; + return d->sortCacheEnabled; } void QGraphicsScene::setSortCacheEnabled(bool enabled) { Q_D(QGraphicsScene); - QGraphicsSceneBspTreeIndex *bspTree = qobject_cast(d->index); - if (!bspTree) { - qWarning("QGraphicsScene::isSortCacheEnabled: can not apply if indexing method is not BSP"); + if (d->sortCacheEnabled == enabled) return; - } - if (enabled == bspTree->d_func()->sortCacheEnabled) - return; - if ((bspTree->d_func()->sortCacheEnabled = enabled)) - bspTree->d_func()->invalidateSortCache(); + d->sortCacheEnabled = enabled; } /*! @@ -1544,6 +1498,7 @@ void QGraphicsScene::setSortCacheEnabled(bool enabled) */ QRectF QGraphicsScene::itemsBoundingRect() const { + // Does not take untransformable items into account. QRectF boundingRect; foreach (QGraphicsItem *item, items()) boundingRect |= item->sceneBoundingRect(); @@ -1558,7 +1513,19 @@ QRectF QGraphicsScene::itemsBoundingRect() const QList QGraphicsScene::items() const { Q_D(const QGraphicsScene); - return d->index->items(); + return d->index->items(Qt::AscendingOrder); +} + +/*! + Returns an ordered list of all items on the scene. \a order decides the + sorting. + + \sa addItem(), removeItem() +*/ +QList QGraphicsScene::items(Qt::SortOrder order) const +{ + Q_D(const QGraphicsScene); + return d->index->items(order); } /*! @@ -1732,6 +1699,7 @@ QList QGraphicsScene::collidingItems(const QGraphicsItem *item, return QList(); } + // Does not support ItemIgnoresTransformations. QList tmp; foreach (QGraphicsItem *itemInVicinity, d->index->estimateItems(item->sceneBoundingRect(), Qt::AscendingOrder, QTransform())) { if (item != itemInVicinity && item->collidesWithItem(itemInVicinity, mode)) @@ -1756,6 +1724,13 @@ QGraphicsItem *QGraphicsScene::itemAt(const QPointF &pos) const return itemsAtPoint.isEmpty() ? 0 : itemsAtPoint.first(); } +QGraphicsItem *QGraphicsScene::itemAt(const QPointF &pos, const QTransform &deviceTransform) const +{ + QList itemsAtPoint = items(pos, Qt::IntersectsItemShape, + Qt::AscendingOrder, deviceTransform); + return itemsAtPoint.isEmpty() ? 0 : itemsAtPoint.first(); +} + /*! \fn QGraphicsScene::itemAt(qreal x, qreal y) const \overload @@ -1831,6 +1806,21 @@ void QGraphicsScene::setSelectionArea(const QPainterPath &path) */ void QGraphicsScene::setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode) { + setSelectionArea(path, Qt::IntersectsItemShape, QTransform()); +} + +/*! + \overload + \since 4.3 + + Sets the selection area to \a path using \a mode to determine if items are + included in the selection area. + + \sa clearSelection(), selectionArea() +*/ +void QGraphicsScene::setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode, + const QTransform &deviceTransform) +{ Q_D(QGraphicsScene); // Note: with boolean path operations, we can improve performance here @@ -1846,7 +1836,7 @@ void QGraphicsScene::setSelectionArea(const QPainterPath &path, Qt::ItemSelectio bool changed = false; // Set all items in path to selected. - foreach (QGraphicsItem *item, items(path, mode)) { + foreach (QGraphicsItem *item, items(path, mode, Qt::AscendingOrder, deviceTransform)) { if (item->flags() & QGraphicsItem::ItemIsSelectable) { if (!item->isSelected()) changed = true; @@ -1904,7 +1894,10 @@ void QGraphicsScene::clear() { Q_D(QGraphicsScene); QList items = d->index->items(); +#if 1 QList toDelete; + // ### As the item list is already in ascending order, + // the items should be deleted in topological order. // Recursive descent delete for (int i = 0; i < items.size(); ++i) { if (QGraphicsItem *item = items.at(i)) { @@ -1912,11 +1905,13 @@ void QGraphicsScene::clear() toDelete << item; } } - //We delete all top level items + // We delete all top level items qDeleteAll(toDelete); +#else + qDeleteAll(items); +#endif d->lastItemCount = 0; d->index->clear(); - d->largestUntransformableItem = QRectF(); d->allItemsIgnoreHoverEvents = true; d->allItemsUseDefaultCursor = true; } @@ -4129,16 +4124,6 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter * children = &this->topLevelItems; } else { QRectF sceneRect = viewTransform.inverted().mapRect(QRectF(exposedRegion->boundingRect().adjusted(-1, -1, 1, 1))); - if (!largestUntransformableItem.isEmpty()) { - // ### Nuke this when we move the indexing code into a separate - // class. All the largestUntransformableItem code should then go - // away, and the estimate function should return untransformable - // items as well. - QRectF untr = largestUntransformableItem; - QRectF ltri = viewTransform.inverted().mapRect(untr); - ltri.adjust(-untr.width(), -untr.height(), untr.width(), untr.height()); - sceneRect.adjust(-ltri.width(), -ltri.height(), ltri.width(), ltri.height()); - } tmp = index->estimateItems(sceneRect, Qt::DescendingOrder, viewTransform); QList tli; diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h index b922be5..421adbd 100644 --- a/src/gui/graphicsview/qgraphicsscene.h +++ b/src/gui/graphicsview/qgraphicsscene.h @@ -153,6 +153,7 @@ public: QRectF itemsBoundingRect() const; QList items() const; + QList items(Qt::SortOrder order) const; // ### Qt 5: unify QList items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; QList items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; @@ -165,17 +166,25 @@ public: QList items(const QPainterPath &path, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; // ### obsolete QList collidingItems(const QGraphicsItem *item, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; - QGraphicsItem *itemAt(const QPointF &pos) const; + + QGraphicsItem *itemAt(const QPointF &pos) const; // ### obsolete + QGraphicsItem *itemAt(const QPointF &pos, const QTransform &deviceTransform) const; inline QList items(qreal x, qreal y, qreal w, qreal h, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const - { return items(QRectF(x, y, w, h), mode); } - inline QGraphicsItem *itemAt(qreal x, qreal y) const + { return items(QRectF(x, y, w, h), mode); } // ### obsolete + inline QList items(qreal x, qreal y, qreal w, qreal h, Qt::ItemSelectionMode mode, Qt::SortOrder order, + const QTransform &deviceTransform = QTransform()) const + { return items(QRectF(x, y, w, h), mode, order, deviceTransform); } + inline QGraphicsItem *itemAt(qreal x, qreal y) const // ### obsolete { return itemAt(QPointF(x, y)); } + inline QGraphicsItem *itemAt(qreal x, qreal y, const QTransform &deviceTransform) const + { return itemAt(QPointF(x, y), deviceTransform); } QList selectedItems() const; QPainterPath selectionArea() const; void setSelectionArea(const QPainterPath &path); - void setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode); + void setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode); + void setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode, const QTransform &deviceTransform); QGraphicsItemGroup *createItemGroup(const QList &items); void destroyItemGroup(QGraphicsItemGroup *group); diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 538ff3f..a081e04 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -96,7 +96,6 @@ public: QRectF sceneRect; bool hasSceneRect; QRectF growingItemsBoundingRect; - QRectF largestUntransformableItem; void _q_emitUpdated(); QList updatedRects; @@ -162,7 +161,6 @@ public: QList itemsAtPosition(const QPoint &screenPos, const QPointF &scenePos, QWidget *widget) const; - static bool itemCollidesWithPath(QGraphicsItem *item, const QPainterPath &path, Qt::ItemSelectionMode mode); void storeMouseButtonsForMouseGrabber(QGraphicsSceneMouseEvent *event); QList views; @@ -188,6 +186,8 @@ public: void mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent); QGraphicsWidget *windowForItem(const QGraphicsItem *item) const; + bool sortCacheEnabled; // for compatibility + void drawItemHelper(QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget, bool painterStateProtection); diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 969d3c5..40cafa6 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -170,11 +170,6 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() unindexedItems = indexedItems; lastItemCount = indexedItems.size(); q->scene()->update(); - - // Take this opportunity to reset our largest-item counter for - // untransformable items. When the items are inserted into the BSP - // tree, we'll get an accurate calculation. - scenePrivate->largestUntransformableItem = QRectF(); } // Insert all unindexed items into the tree. @@ -185,19 +180,6 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() continue; bsp.insertItem(item, rect); - - // If the item ignores view transformations, update our - // largest-item-counter to ensure that the view can accurately - // discover untransformable items when drawing. - if (item->d_ptr->itemIsUntransformable()) { - QGraphicsItem *topmostUntransformable = item; - while (topmostUntransformable && (topmostUntransformable->d_ptr->ancestorFlags - & QGraphicsItemPrivate::AncestorIgnoresTransformations)) { - topmostUntransformable = topmostUntransformable->parentItem(); - } - // ### Verify that this is the correct largest untransformable rectangle. - scenePrivate->largestUntransformableItem |= item->mapToItem(topmostUntransformable, item->boundingRect()).boundingRect(); - } } } unindexedItems.clear(); @@ -467,17 +449,23 @@ void QGraphicsSceneBspTreeIndex::addItem(QGraphicsItem *item) // Indexing requires sceneBoundingRect(), but because \a item might // not be completely constructed at this point, we need to store it in // a temporary list and schedule an indexing for later. - d->unindexedItems << item; - item->d_func()->index = -1; - d->startIndexTimer(0); + item->d_ptr->index = -1; + if (item->d_ptr->itemIsUntransformable()) { + d->untransformableItems << item; + } else { + d->unindexedItems << item; + d->startIndexTimer(0); + } } /*! This really add the item in the BSP. \internal */ -void QGraphicsSceneBspTreeIndexPrivate::addToIndex(QGraphicsItem *item) +void QGraphicsSceneBspTreeIndexPrivate::addToBspTree(QGraphicsItem *item) { + if (item->d_ptr->itemIsUntransformable()) + return; if (item->d_func()->index != -1) { bsp.insertItem(item, item->sceneBoundingRect()); foreach (QGraphicsItem *child, item->children()) @@ -496,10 +484,11 @@ void QGraphicsSceneBspTreeIndexPrivate::addToIndex(QGraphicsItem *item) void QGraphicsSceneBspTreeIndex::removeItem(QGraphicsItem *item) { Q_D(QGraphicsSceneBspTreeIndex); + // Note: This will access item's sceneBoundingRect(), which (as this is // C++) is why we cannot call removeItem() from QGraphicsItem's // destructor. - d->removeFromIndex(item); + d->removeFromBspTree(item); // Invalidate any sort caching; arrival of a new item means we need to // resort. @@ -511,7 +500,10 @@ void QGraphicsSceneBspTreeIndex::removeItem(QGraphicsItem *item) d->freeItemIndexes << index; d->indexedItems[index] = 0; } else { - d->unindexedItems.removeAll(item); + if (item->d_ptr->itemIsUntransformable()) + d->untransformableItems.removeOne(item); + else + d->unindexedItems.removeOne(item); } } @@ -539,7 +531,10 @@ void QGraphicsSceneBspTreeIndex::deleteItem(QGraphicsItem *item) } else { // Recently added items are purged immediately. unindexedItems() never // contains stale items. - d->unindexedItems.removeAll(item); + if (item->d_ptr->itemIsUntransformable()) + d->untransformableItems.removeOne(item); + else + d->unindexedItems.removeOne(item); scene()->update(); } } @@ -548,8 +543,11 @@ void QGraphicsSceneBspTreeIndex::deleteItem(QGraphicsItem *item) Really remove the item from the BSP \internal */ -void QGraphicsSceneBspTreeIndexPrivate::removeFromIndex(QGraphicsItem *item) +void QGraphicsSceneBspTreeIndexPrivate::removeFromBspTree(QGraphicsItem *item) { + if (item->d_ptr->itemIsUntransformable()) + return; + if (item->d_func()->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { // ### remove from child index only if applicable return; @@ -579,7 +577,7 @@ void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem * // Note: This will access item's sceneBoundingRect(), which (as this is // C++) is why we cannot call removeItem() from QGraphicsItem's // destructor. - d->removeFromIndex(const_cast(item)); + d->removeFromBspTree(const_cast(item)); } /*! @@ -633,7 +631,8 @@ QList QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order) co Q_D(const QGraphicsSceneBspTreeIndex); const_cast(d)->purgeRemovedItems(); QList itemList; - // If freeItemIndexes is empty, we know there are no holes in indexedItems and + + // If freeItemIndexes is empty, we know there are no holes in indexedItems and // unindexedItems. if (d->freeItemIndexes.isEmpty()) { if (d->unindexedItems.isEmpty()) { @@ -649,6 +648,7 @@ QList QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order) co itemList << item; } } + itemList += d->untransformableItems; if (order != -1) { //We sort descending order d->sortItems(&itemList, order, d->sortCacheEnabled); @@ -692,6 +692,8 @@ int QGraphicsSceneBspTreeIndex::bspTreeDepth() void QGraphicsSceneBspTreeIndex::setBspTreeDepth(int depth) { Q_D(QGraphicsSceneBspTreeIndex); + if (d->bspTreeDepth == depth) + return; d->bspTreeDepth = depth; d->resetIndex(); } @@ -716,19 +718,41 @@ void QGraphicsSceneBspTreeIndex::sceneRectChanged(const QRectF &rect) update the BSP tree if necessary. */ -void QGraphicsSceneBspTreeIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) +void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) { Q_D(QGraphicsSceneBspTreeIndex); switch (change) { - case QGraphicsItem::ItemZValueChange: - case QGraphicsItem::ItemParentChange: { - d->invalidateSortCache(); - break; + case QGraphicsItem::ItemFlagsChange: { + // Handle ItemIgnoresTransformations + bool ignoredTransform = item->flags() & QGraphicsItem::ItemIgnoresTransformations; + bool willIgnoreTransform = value.toUInt() & QGraphicsItem::ItemIgnoresTransformations; + if (ignoredTransform != willIgnoreTransform) { + QGraphicsItem *thatItem = const_cast(item); + removeItem(thatItem); + addItem(thatItem); } - default: - break; + break; + } + case QGraphicsItem::ItemZValueChange: + d->invalidateSortCache(); + break; + case QGraphicsItem::ItemParentChange: { + d->invalidateSortCache(); + // Handle ItemIgnoresTransformations + QGraphicsItem *newParent = qVariantValue(value); + bool ignoredTransform = item->d_ptr->itemIsUntransformable(); + bool willIgnoreTransform = (item->flags() & QGraphicsItem::ItemIgnoresTransformations) || (newParent && newParent->d_ptr->itemIsUntransformable()); + if (ignoredTransform != willIgnoreTransform) { + QGraphicsItem *thatItem = const_cast(item); + removeItem(thatItem); + addItem(thatItem); + } + break; + } + default: + break; } - return QGraphicsSceneIndex::itemChanged(item, change, value); + return QGraphicsSceneIndex::itemChange(item, change, value); } /*! \reimp diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex.h index 0444a30..504ea8b 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.h @@ -98,7 +98,7 @@ protected: void prepareBoundingRectChange(const QGraphicsItem *item); void sceneRectChanged(const QRectF &rect); - void itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value); + void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value); private : Q_DECLARE_PRIVATE(QGraphicsSceneBspTreeIndex) diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index b6f782d..ed12fac 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -82,6 +82,7 @@ public: QList indexedItems; QList unindexedItems; + QList untransformableItems; QList freeItemIndexes; bool purgePending; @@ -92,8 +93,8 @@ public: void startIndexTimer(int interval = QGRAPHICSSCENE_INDEXTIMER_TIMEOUT); void resetIndex(); - void addToIndex(QGraphicsItem *item); - void removeFromIndex(QGraphicsItem *item); + void addToBspTree(QGraphicsItem *item); + void removeFromBspTree(QGraphicsItem *item); void _q_updateSortCache(); bool sortCacheEnabled; diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 4ca1c02..eb3abc1 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -61,6 +61,7 @@ #include "qgraphicsscene.h" #include "qgraphicsitem_p.h" #include "qgraphicsscene_p.h" +#include "qgraphicswidget.h" #ifndef QT_NO_GRAPHICSVIEW @@ -69,61 +70,118 @@ QT_BEGIN_NAMESPACE class QGraphicsSceneIndexRectIntersector : public QGraphicsSceneIndexIntersector { public: - QGraphicsSceneIndexRectIntersector(QGraphicsScene *scene) : QGraphicsSceneIndexIntersector(scene) {} - bool intersect(const QRectF &brect) const + bool intersect(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode, + const QTransform &transform, const QTransform &deviceTransform) const { + QRectF brect = item->boundingRect(); + _q_adjustRect(&brect); + + // ### Add test for this (without making things slower?) + Q_UNUSED(exposeRect); + bool keep = true; - if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) - keep = rect.contains(transform.mapRect(brect)) && rect != brect; - else - keep = rect.intersects(transform.mapRect(brect)); - - if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { - QPainterPath rectPath; - rectPath.addRect(rect); - keep = QGraphicsScenePrivate::get(scene)->itemCollidesWithPath(item, transform.inverted().map(rectPath), mode); + if (QGraphicsItemPrivate::get(item)->itemIsUntransformable()) { + // Untransformable items; map the scene rect to item coordinates. + QRectF itemRect = (deviceTransform * transform.inverted()).mapRect(sceneRect); + if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) + keep = itemRect.contains(brect) && itemRect != brect; + else + keep = itemRect.intersects(brect); + if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { + QPainterPath itemPath; + itemPath.addRect(itemRect); + keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, itemPath, mode); + } + } else { + if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) + keep = sceneRect.contains(transform.mapRect(brect)) && sceneRect != brect; + else + keep = sceneRect.intersects(transform.mapRect(brect)); + if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { + QPainterPath rectPath; + rectPath.addRect(sceneRect); + keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, transform.inverted().map(rectPath), mode); + } } return keep; } + + QRectF sceneRect; }; class QGraphicsSceneIndexPointIntersector : public QGraphicsSceneIndexIntersector { public: - QGraphicsSceneIndexPointIntersector(QGraphicsScene *scene) : QGraphicsSceneIndexIntersector(scene) {} - bool intersect(const QRectF &brect) const + bool intersect(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode, + const QTransform &transform, const QTransform &deviceTransform) const { + QRectF brect = item->boundingRect(); + _q_adjustRect(&brect); + + // ### Add test for this (without making things slower?) + Q_UNUSED(exposeRect); + bool keep = false; - if (rect.intersects(transform.mapRect(brect))) - if (item->contains(transform.inverted().map(pos))) - keep = true; - if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { - QPainterPath rectPath; - rectPath.addRect(rect); - keep = QGraphicsScenePrivate::get(scene)->itemCollidesWithPath(item, transform.inverted().map(rectPath), mode); + if (QGraphicsItemPrivate::get(item)->itemIsUntransformable()) { + // Untransformable items; map the scene point to item coordinates. + QPointF itemPoint = (deviceTransform * transform.inverted()).map(scenePoint); + keep = brect.contains(itemPoint); + if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { + QPainterPath pointPath; + pointPath.addRect(QRectF(itemPoint, QSizeF(1, 1))); + keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, pointPath, mode); + } + } else { + QRectF sceneBrect = transform.mapRect(brect); + keep = sceneBrect.contains(scenePoint); + if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { + QPainterPath pointPath; + pointPath.addRect(QRectF(transform.inverted().map(scenePoint), QSizeF(1, 1))); + keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, pointPath, mode); + } } return keep; } - QPointF pos; + + QPointF scenePoint; }; class QGraphicsSceneIndexPathIntersector : public QGraphicsSceneIndexIntersector { public: - QGraphicsSceneIndexPathIntersector(QGraphicsScene *scene) : QGraphicsSceneIndexIntersector(scene) {} - bool intersect(const QRectF &brect) const + bool intersect(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode, + const QTransform &transform, const QTransform &deviceTransform) const { - bool keep = true; - if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) - keep = rect.contains(transform.mapRect(brect)) && rect != brect; - else - keep = rect.intersects(transform.mapRect(brect)); + QRectF brect = item->boundingRect(); + _q_adjustRect(&brect); + + // ### Add test for this (without making things slower?) + Q_UNUSED(exposeRect); - if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) - keep = QGraphicsScenePrivate::get(scene)->itemCollidesWithPath(item, transform.inverted().map(path), mode); + bool keep = true; + if (QGraphicsItemPrivate::get(item)->itemIsUntransformable()) { + // Untransformable items; map the scene rect to item coordinates. + QPainterPath itemPath = (deviceTransform * transform.inverted()).map(scenePath); + if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) + keep = itemPath.contains(brect); + else + keep = itemPath.intersects(brect); + if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) + keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, itemPath, mode); + } else { + if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) + keep = scenePath.contains(transform.mapRect(brect)); + else + keep = scenePath.intersects(transform.mapRect(brect)); + if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { + QPainterPath itemPath = transform.inverted().map(scenePath); + keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, itemPath, mode); + } + } return keep; } - QPainterPath path; + + QPainterPath scenePath; }; /*! @@ -131,9 +189,9 @@ public: */ QGraphicsSceneIndexPrivate::QGraphicsSceneIndexPrivate(QGraphicsScene *scene) : scene(scene) { - pointIntersector = new QGraphicsSceneIndexPointIntersector(scene); - rectIntersector = new QGraphicsSceneIndexRectIntersector(scene); - pathIntersector = new QGraphicsSceneIndexPathIntersector(scene); + pointIntersector = new QGraphicsSceneIndexPointIntersector; + rectIntersector = new QGraphicsSceneIndexRectIntersector; + pathIntersector = new QGraphicsSceneIndexPathIntersector; } /*! @@ -148,19 +206,50 @@ QGraphicsSceneIndexPrivate::~QGraphicsSceneIndexPrivate() /*! \internal + + Checks if item collides with the path and mode, but also checks that if it + doesn't collide, maybe its frame rect will. +*/ +bool QGraphicsSceneIndexPrivate::itemCollidesWithPath(const QGraphicsItem *item, + const QPainterPath &path, + Qt::ItemSelectionMode mode) +{ + if (item->collidesWithPath(path, mode)) + return true; + if (item->isWidget()) { + // Check if this is a window, and if its frame rect collides. + const QGraphicsWidget *widget = static_cast(item); + if (widget->isWindow()) { + QRectF frameRect = widget->windowFrameRect(); + QPainterPath framePath; + framePath.addRect(frameRect); + bool intersects = path.intersects(frameRect); + if (mode == Qt::IntersectsItemShape || mode == Qt::IntersectsItemBoundingRect) + return intersects || path.contains(frameRect.topLeft()) + || framePath.contains(path.elementAt(0)); + return !intersects && path.contains(frameRect.topLeft()); + } + } + return false; +} + +/*! + \internal */ -void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QGraphicsSceneIndexIntersector *intersector, - QList *items, - const QTransform &parentTransform, - const QTransform &viewTransform, - Qt::ItemSelectionMode mode, Qt::SortOrder order, - qreal parentOpacity) const +void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRectF exposeRect, + QGraphicsSceneIndexIntersector *intersector, + QList *items, + const QTransform &parentTransform, + const QTransform &viewTransform, + Qt::ItemSelectionMode mode, Qt::SortOrder order, + qreal parentOpacity) const { // Calculate opacity. qreal opacity; if (item) { if (!item->d_ptr->visible) return; + QGraphicsItem *p = item->d_ptr->parent; bool itemIgnoresParentOpacity = item->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity; bool parentDoesntPropagateOpacity = (p && (p->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)); @@ -186,9 +275,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QGr _q_adjustRect(&brect); //We fill the intersector with needed informations - intersector->transform = transform; - intersector->item = item; - keep = intersector->intersect(brect); + keep = intersector->intersect(item, exposeRect, mode, transform, viewTransform); } bool childClip = (item && (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)); @@ -211,7 +298,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QGr // Clip. if (childClip) - intersector->rect &= transform.map(item->shape()).controlPointRect(); + exposeRect &= transform.map(item->shape()).controlPointRect(); // Process children behind int i = 0; @@ -220,7 +307,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QGr QGraphicsItem *child = children.at(i); if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent)) break; - recursive_items_helper(child, intersector, items, transform, viewTransform, + recursive_items_helper(child, exposeRect, intersector, items, transform, viewTransform, mode, order, opacity); } } @@ -232,7 +319,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QGr // Process children in front if (!dontProcessChildren) { for (; i < children.size(); ++i) - recursive_items_helper(children.at(i), intersector, items, transform, viewTransform, + recursive_items_helper(children.at(i), exposeRect, intersector, items, transform, viewTransform, mode, order, opacity); } @@ -311,12 +398,12 @@ QRectF QGraphicsSceneIndex::indexedRect() const QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const { + Q_D(const QGraphicsSceneIndex); QList itemList; - d->pointIntersector->mode = mode; - d->pointIntersector->rect = QRectF(pos, QSize(1,1)); - d->pointIntersector->pos = pos; - d->recursive_items_helper(0, d->pointIntersector, &itemList, QTransform(), deviceTransform, mode, order); + d->pointIntersector->scenePoint = pos; + d->recursive_items_helper(0, QRectF(pos, QSizeF(1, 1)), d->pointIntersector, &itemList, + QTransform(), deviceTransform, mode, order); return itemList; } @@ -346,10 +433,11 @@ QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSe Qt::SortOrder order, const QTransform &deviceTransform) const { Q_D(const QGraphicsSceneIndex); + QRectF exposeRect = rect; + _q_adjustRect(&exposeRect); QList itemList; - d->rectIntersector->mode = mode; - d->rectIntersector->rect = rect; - d->recursive_items_helper(0, d->rectIntersector, &itemList, QTransform(), deviceTransform, mode, order); + d->rectIntersector->sceneRect = rect; + d->recursive_items_helper(0, exposeRect, d->rectIntersector, &itemList, QTransform(), deviceTransform, mode, order); return itemList; } @@ -380,14 +468,12 @@ QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt:: { Q_D(const QGraphicsSceneIndex); QList itemList; - QRectF polyRect(polygon.boundingRect()); - _q_adjustRect(&polyRect); - d->pathIntersector->mode = mode; - d->pathIntersector->rect = polyRect; + QRectF exposeRect = polygon.boundingRect(); + _q_adjustRect(&exposeRect); QPainterPath path; path.addPolygon(polygon); - d->pathIntersector->path = path; - d->recursive_items_helper(0, d->pathIntersector, &itemList, QTransform(), deviceTransform, mode, order); + d->pathIntersector->scenePath = path; + d->recursive_items_helper(0, exposeRect, d->pathIntersector, &itemList, QTransform(), deviceTransform, mode, order); return itemList; } @@ -418,12 +504,10 @@ QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt:: { Q_D(const QGraphicsSceneIndex); QList itemList; - QRectF pathRect(path.controlPointRect()); - _q_adjustRect(&pathRect); - d->pathIntersector->mode = mode; - d->pathIntersector->rect = pathRect; - d->pathIntersector->path = path; - d->recursive_items_helper(0, d->pathIntersector, &itemList, QTransform(), deviceTransform, mode, order); + QRectF exposeRect = path.controlPointRect(); + _q_adjustRect(&exposeRect); + d->pathIntersector->scenePath = path; + d->recursive_items_helper(0, exposeRect, d->pathIntersector, &itemList, QTransform(), deviceTransform, mode, order); return itemList; } @@ -508,7 +592,7 @@ void QGraphicsSceneIndex::deleteItem(QGraphicsItem *item) \sa QGraphicsItem::GraphicsItemChange */ -void QGraphicsSceneIndex::itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) +void QGraphicsSceneIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) { Q_UNUSED(item); Q_UNUSED(change); diff --git a/src/gui/graphicsview/qgraphicssceneindex.h b/src/gui/graphicsview/qgraphicssceneindex.h index ddce9d4..25ece04 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.h +++ b/src/gui/graphicsview/qgraphicssceneindex.h @@ -104,7 +104,7 @@ protected: virtual void removeItem(QGraphicsItem *item) = 0; virtual void deleteItem(QGraphicsItem *item); - virtual void itemChanged(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value); + virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value); virtual void prepareBoundingRectChange(const QGraphicsItem *item); virtual void sceneRectChanged(const QRectF &rect); diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index d0d181b..576ee98 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -75,9 +75,12 @@ public: QGraphicsSceneIndexPrivate(QGraphicsScene *scene); ~QGraphicsSceneIndexPrivate(); - void recursive_items_helper(QGraphicsItem *item, QGraphicsSceneIndexIntersector *intersector, QList *items, - const QTransform &parentTransform, const QTransform &viewTransform, - Qt::ItemSelectionMode mode, Qt::SortOrder order, qreal parentOpacity = 1.0) const; + static bool itemCollidesWithPath(const QGraphicsItem *item, const QPainterPath &path, Qt::ItemSelectionMode mode); + + void recursive_items_helper(QGraphicsItem *item, QRectF exposeRect, + QGraphicsSceneIndexIntersector *intersector, QList *items, + const QTransform &parentTransform, const QTransform &viewTransform, + Qt::ItemSelectionMode mode, Qt::SortOrder order, qreal parentOpacity = 1.0) const; QGraphicsScene *scene; QGraphicsSceneIndexPointIntersector *pointIntersector; QGraphicsSceneIndexRectIntersector *rectIntersector; @@ -87,14 +90,10 @@ public: class QGraphicsSceneIndexIntersector { public: - QGraphicsSceneIndexIntersector(QGraphicsScene *scene) : scene(scene) { } + QGraphicsSceneIndexIntersector() { } virtual ~QGraphicsSceneIndexIntersector() { } - virtual bool intersect(const QRectF &rect) const = 0; - Qt::ItemSelectionMode mode; - QGraphicsItem *item; - QGraphicsScene *scene; - QRectF rect; - QTransform transform; + virtual bool intersect(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode, + const QTransform &transform, const QTransform &deviceTransform) const = 0; }; QT_END_NAMESPACE diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 8c40878..a1e6d9c 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -914,44 +914,32 @@ extern QPainterPath qt_regionToPath(const QRegion ®ion); is at risk of painting 1 pixel outside the bounding rect. Therefore we must search for items with an adjustment of (-1, -1, 1, 1). */ -QList QGraphicsViewPrivate::findItems(const QRegion &exposedRegion, bool *allItems) const +QList QGraphicsViewPrivate::findItems(const QRegion &exposedRegion, bool *allItems, + const QTransform &viewTransform) const { Q_Q(const QGraphicsView); // Step 1) If all items are contained within the expose region, then - // return a list of all visible items. + // return a list of all visible items. ### the scene's growing bounding + // rect does not take into account untransformable items. const QRectF exposedRegionSceneBounds = q->mapToScene(exposedRegion.boundingRect().adjusted(-1, -1, 1, 1)) .boundingRect(); if (exposedRegionSceneBounds.contains(scene->d_func()->growingItemsBoundingRect)) { Q_ASSERT(allItems); *allItems = true; - // All items are guaranteed within the exposed region, don't bother using the index. - QList itemList(scene->d_func()->index->items(Qt::DescendingOrder)); - int i = 0; - while (i < itemList.size()) { - const QGraphicsItem *item = itemList.at(i); - // But we only want to include items that are visible - // The following check is basically the same as item->d_ptr->isInvisible(), except - // that we don't check whether the item clips children to shape or propagates its - // opacity (we loop through all items, so those checks are wrong in this context). - if (!item->isVisible() || item->d_ptr->isClippedAway() || item->d_ptr->isFullyTransparent()) - itemList.removeAt(i); - else - ++i; - } - return itemList; + // All items are guaranteed within the exposed region. + return scene->items(Qt::DescendingOrder); } // Step 2) If the expose region is a simple rect and the view is only // translated or scaled, search for items using // QGraphicsScene::items(QRectF). - bool simpleRectLookup = (scene->d_func()->largestUntransformableItem.isNull() - && exposedRegion.numRects() == 1 && matrix.type() <= QTransform::TxScale); + bool simpleRectLookup = exposedRegion.numRects() == 1 && matrix.type() <= QTransform::TxScale; if (simpleRectLookup) { - return scene->d_func()->index->items(exposedRegionSceneBounds, - Qt::IntersectsItemBoundingRect, - Qt::DescendingOrder); + return scene->items(exposedRegionSceneBounds, + Qt::IntersectsItemBoundingRect, + Qt::DescendingOrder, viewTransform); } // If the region is complex or the view has a complex transform, adjust @@ -961,16 +949,9 @@ QList QGraphicsViewPrivate::findItems(const QRegion &exposedReg foreach (const QRect &r, exposedRegion.rects()) adjustedRegion += r.adjusted(-1, -1, 1, 1); - const QPainterPath exposedPath(qt_regionToPath(adjustedRegion)); - if (scene->d_func()->largestUntransformableItem.isNull()) { - const QPainterPath exposedScenePath(q->mapToScene(exposedPath)); - return scene->d_func()->index->items(exposedScenePath, - Qt::IntersectsItemBoundingRect, - Qt::DescendingOrder); - } - - // NB! Path must be in viewport coordinates. - return itemsInArea(exposedPath, Qt::IntersectsItemBoundingRect, Qt::DescendingOrder); + const QPainterPath exposedScenePath(q->mapToScene(qt_regionToPath(adjustedRegion))); + return scene->items(exposedScenePath, Qt::IntersectsItemBoundingRect, + Qt::DescendingOrder, viewTransform); } /*! @@ -1875,6 +1856,8 @@ void QGraphicsView::fitInView(const QGraphicsItem *item, Qt::AspectRatioMode asp void QGraphicsView::render(QPainter *painter, const QRectF &target, const QRect &source, Qt::AspectRatioMode aspectRatioMode) { + // ### Switch to using the recursive rendering algorithm instead. + Q_D(QGraphicsView); if (!d->scene || !(painter && painter->isActive())) return; @@ -1972,67 +1955,6 @@ QList QGraphicsView::items() const } /*! - Returns all items in the area \a path, which is in viewport coordinates, - also taking untransformable items into consideration. This function is - considerably slower than just checking the scene directly. There is - certainly room for improvement. -*/ -QList QGraphicsViewPrivate::itemsInArea(const QPainterPath &path, - Qt::ItemSelectionMode mode, - Qt::SortOrder order) const -{ - Q_Q(const QGraphicsView); - - // Determine the size of the largest untransformable subtree of children - // mapped to scene coordinates. - QRectF untr = scene->d_func()->largestUntransformableItem; - QRectF ltri = matrix.inverted().mapRect(untr); - ltri.adjust(-untr.width(), -untr.height(), untr.width(), untr.height()); - - QRectF rect = path.controlPointRect(); - - // Find all possible items in the relevant area. - // ### Improve this algorithm; it might be searching a too large area. - QRectF adjustedRect = q->mapToScene(rect.adjusted(-1, -1, 1, 1).toRect()).boundingRect(); - adjustedRect.adjust(-ltri.width(), -ltri.height(), ltri.width(), ltri.height()); - - // First build a (potentially large) list of all items in the vicinity - // that might be untransformable. - QList allCandidates = scene->d_func()->index->estimateItems(adjustedRect, order, q->transform()); - - // Then find the minimal list of items that are inside \a path, and - // convert it to a set. - QList regularCandidates = scene->items(q->mapToScene(path), mode, order, q->transform()); - QSet candSet = QSet::fromList(regularCandidates); - - QTransform viewMatrix = q->viewportTransform(); - - QList result; - - //### this will disapear - - // Run through all candidates and keep all items that are in candSet, or - // are untransformable and collide with \a path. ### We can improve this - // algorithm. - QList::Iterator it = allCandidates.begin(); - while (it != allCandidates.end()) { - QGraphicsItem *item = *it; - if (item->d_ptr->itemIsUntransformable()) { - // Check if this untransformable item collides with the - // original selection rect. - QTransform itemTransform = item->deviceTransform(viewMatrix); - if (QGraphicsScenePrivate::itemCollidesWithPath(item, itemTransform.inverted().map(path), mode)) - result << item; - } else { - if (candSet.contains(item)) - result << item; - } - ++it; - } - return result; -} - -/*! Returns a list of all the items at the position \a pos in the view. The items are listed in descending Z order (i.e., the first item in the list is the top-most item, and the last item is the bottom-most item). \a pos @@ -2051,17 +1973,22 @@ QList QGraphicsView::items(const QPoint &pos) const Q_D(const QGraphicsView); if (!d->scene) return QList(); - if (d->scene->d_func()->largestUntransformableItem.isNull()) { - if ((d->identityMatrix || d->matrix.type() <= QTransform::TxScale)) { - QTransform xinv = viewportTransform().inverted(); - return d->scene->items(xinv.mapRect(QRectF(pos.x(), pos.y(), 1, 1))); - } - return d->scene->items(mapToScene(pos.x(), pos.y(), 1, 1)); + // ### Unify these two, and use the items(QPointF) version in + // QGraphicsScene instead. The scene items function could use the viewport + // transform to map the point to a rect/polygon. + if ((d->identityMatrix || d->matrix.type() <= QTransform::TxScale)) { + // Use the rect version + QTransform xinv = viewportTransform().inverted(); + return d->scene->items(xinv.mapRect(QRectF(pos.x(), pos.y(), 1, 1)), + Qt::IntersectsItemShape, + Qt::AscendingOrder, + viewportTransform()); } - - QPainterPath path; - path.addRect(QRectF(pos.x(), pos.y(), 1, 1)); - return d->itemsInArea(path); + // Use the polygon version + return d->scene->items(mapToScene(pos.x(), pos.y(), 1, 1), + Qt::IntersectsItemShape, + Qt::AscendingOrder, + viewportTransform()); } /*! @@ -2088,12 +2015,7 @@ QList QGraphicsView::items(const QRect &rect, Qt::ItemSelection Q_D(const QGraphicsView); if (!d->scene) return QList(); - if (d->scene->d_func()->largestUntransformableItem.isNull()) - return d->scene->items(mapToScene(rect), mode); - - QPainterPath path; - path.addRect(rect); - return d->itemsInArea(path); + return d->scene->items(mapToScene(rect), mode, Qt::AscendingOrder, viewportTransform()); } /*! @@ -2121,13 +2043,7 @@ QList QGraphicsView::items(const QPolygon &polygon, Qt::ItemSel Q_D(const QGraphicsView); if (!d->scene) return QList(); - if (d->scene->d_func()->largestUntransformableItem.isNull()) - return d->scene->items(mapToScene(polygon), mode); - - QPainterPath path; - path.addPolygon(polygon); - path.closeSubpath(); - return d->itemsInArea(path); + return d->scene->items(mapToScene(polygon), mode, Qt::AscendingOrder, viewportTransform()); } /*! @@ -2147,9 +2063,7 @@ QList QGraphicsView::items(const QPainterPath &path, Qt::ItemSe Q_D(const QGraphicsView); if (!d->scene) return QList(); - if (d->scene->d_func()->largestUntransformableItem.isNull()) - return d->scene->items(mapToScene(path), mode); - return d->itemsInArea(path); + return d->scene->items(mapToScene(path), mode, Qt::AscendingOrder, viewportTransform()); } /*! @@ -2168,7 +2082,9 @@ QGraphicsItem *QGraphicsView::itemAt(const QPoint &pos) const Q_D(const QGraphicsView); if (!d->scene) return 0; - QList itemsAtPos = items(pos); + // ### Use QGraphicsScene::itemAt() instead. + QList itemsAtPos = d->scene->items(pos, Qt::IntersectsItemShape, Qt::AscendingOrder, + viewportTransform()); return itemsAtPos.isEmpty() ? 0 : itemsAtPos.first(); } @@ -3073,7 +2989,8 @@ void QGraphicsView::mouseMoveEvent(QMouseEvent *event) selectionArea.addPolygon(mapToScene(d->rubberBandRect)); selectionArea.closeSubpath(); if (d->scene) - d->scene->setSelectionArea(selectionArea, d->rubberBandSelectionMode); + d->scene->setSelectionArea(selectionArea, d->rubberBandSelectionMode, + viewportTransform()); return; } } else @@ -3280,7 +3197,7 @@ void QGraphicsView::paintEvent(QPaintEvent *event) } else { // Find all exposed items bool allItems = false; - QList itemList = d->findItems(d->exposedRegion, &allItems); + QList itemList = d->findItems(d->exposedRegion, &allItems, viewTransform); if (!itemList.isEmpty()) { // Generate the style options. diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h index fac7bf9..760f54e 100644 --- a/src/gui/graphicsview/qgraphicsview_p.h +++ b/src/gui/graphicsview/qgraphicsview_p.h @@ -84,10 +84,6 @@ public: qint64 horizontalScroll() const; qint64 verticalScroll() const; - QList itemsInArea(const QPainterPath &path, - Qt::ItemSelectionMode mode = Qt::IntersectsItemShape, - Qt::SortOrder = Qt::AscendingOrder) const; - QPointF mousePressItemPoint; QPointF mousePressScenePoint; QPoint mousePressViewPoint; @@ -176,7 +172,8 @@ public: bool updateSceneSlotReimplementedChecked; QRegion exposedRegion; - QList findItems(const QRegion &exposedRegion, bool *allItems) const; + QList findItems(const QRegion &exposedRegion, bool *allItems, + const QTransform &viewTransform) const; }; QT_END_NAMESPACE -- cgit v0.12 From b8ca90d6ca745915455f044f967a345bab7a910e Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Thu, 18 Jun 2009 14:49:24 +0200 Subject: Move QGraphicsSceneIndex into private headers (=> _p.h). We'd like to keep this API private for now. Reviewed-by: Alexis --- src/gui/graphicsview/graphicsview.pri | 57 +++++---- src/gui/graphicsview/qgraphicsscene.cpp | 5 +- src/gui/graphicsview/qgraphicsscene_p.h | 2 +- .../graphicsview/qgraphicsscenebsptreeindex.cpp | 4 +- src/gui/graphicsview/qgraphicsscenebsptreeindex.h | 2 +- src/gui/graphicsview/qgraphicssceneindex.cpp | 5 +- src/gui/graphicsview/qgraphicssceneindex.h | 129 --------------------- src/gui/graphicsview/qgraphicssceneindex_p.h | 79 +++++++++++-- src/gui/graphicsview/qgraphicsscenelinearindex.h | 2 +- 9 files changed, 106 insertions(+), 179 deletions(-) delete mode 100644 src/gui/graphicsview/qgraphicssceneindex.h diff --git a/src/gui/graphicsview/graphicsview.pri b/src/gui/graphicsview/graphicsview.pri index 5ac1c54..2d8f37e 100644 --- a/src/gui/graphicsview/graphicsview.pri +++ b/src/gui/graphicsview/graphicsview.pri @@ -1,46 +1,43 @@ # Qt graphicsview module -HEADERS += graphicsview/qgraphicsitem.h \ +HEADERS += graphicsview/qgraphicsgridlayout.h \ + graphicsview/qgraphicsitem.h \ graphicsview/qgraphicsitem_p.h \ graphicsview/qgraphicsitemanimation.h \ + graphicsview/qgraphicslayout.h \ + graphicsview/qgraphicslayout_p.h \ + graphicsview/qgraphicslayoutitem.h \ + graphicsview/qgraphicslayoutitem_p.h \ + graphicsview/qgraphicslinearlayout.h \ + graphicsview/qgraphicsproxywidget.h \ graphicsview/qgraphicsscene.h \ - graphicsview/qgraphicsscene_p.h \ graphicsview/qgraphicsscene_bsp_p.h \ - graphicsview/qgraphicsscenelinearindex.h \ - graphicsview/qgraphicssceneindex.h \ - graphicsview/qgraphicssceneindex_p.h \ + graphicsview/qgraphicsscene_p.h \ graphicsview/qgraphicsscenebsptreeindex.h \ graphicsview/qgraphicsscenebsptreeindex_p.h \ graphicsview/qgraphicssceneevent.h \ + graphicsview/qgraphicssceneindex_p.h \ + graphicsview/qgraphicsscenelinearindex.h \ + graphicsview/qgraphicsview.h \ graphicsview/qgraphicsview_p.h \ - graphicsview/qgraphicsview.h -SOURCES += graphicsview/qgraphicsitem.cpp \ - graphicsview/qgraphicsitemanimation.cpp \ - graphicsview/qgraphicsscene.cpp \ - graphicsview/qgraphicsscene_bsp.cpp \ - graphicsview/qgraphicsscenebsptreeindex.cpp \ - graphicsview/qgraphicsscenelinearindex.cpp \ - graphicsview/qgraphicssceneindex.cpp \ - graphicsview/qgraphicssceneevent.cpp \ - graphicsview/qgraphicsview.cpp - - -# Widgets on the canvas -HEADERS += graphicsview/qgraphicslayout.h \ - graphicsview/qgraphicslayout_p.h \ - graphicsview/qgraphicslayoutitem.h \ - graphicsview/qgraphicslayoutitem_p.h \ - graphicsview/qgraphicslinearlayout.h \ graphicsview/qgraphicswidget.h \ graphicsview/qgraphicswidget_p.h \ - graphicsview/qgridlayoutengine_p.h \ - graphicsview/qgraphicsproxywidget.h \ - graphicsview/qgraphicsgridlayout.h -SOURCES += graphicsview/qgraphicslayout.cpp \ + graphicsview/qgridlayoutengine_p.h + +SOURCES += graphicsview/qgraphicsgridlayout.cpp \ + graphicsview/qgraphicsitem.cpp \ + graphicsview/qgraphicsitemanimation.cpp \ + graphicsview/qgraphicslayout.cpp \ graphicsview/qgraphicslayout_p.cpp \ graphicsview/qgraphicslayoutitem.cpp \ graphicsview/qgraphicslinearlayout.cpp \ + graphicsview/qgraphicsproxywidget.cpp \ + graphicsview/qgraphicsscene.cpp \ + graphicsview/qgraphicsscene_bsp.cpp \ + graphicsview/qgraphicsscenebsptreeindex.cpp \ + graphicsview/qgraphicssceneevent.cpp \ + graphicsview/qgraphicssceneindex.cpp \ + graphicsview/qgraphicsscenelinearindex.cpp \ + graphicsview/qgraphicsview.cpp \ graphicsview/qgraphicswidget.cpp \ graphicsview/qgraphicswidget_p.cpp \ - graphicsview/qgridlayoutengine.cpp \ - graphicsview/qgraphicsproxywidget.cpp \ - graphicsview/qgraphicsgridlayout.cpp + graphicsview/qgridlayoutengine.cpp diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 55f0f20..9d224b1 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -217,7 +217,6 @@ #include "qgraphicsview_p.h" #include "qgraphicswidget.h" #include "qgraphicswidget_p.h" -#include "qgraphicssceneindex.h" #include "qgraphicsscenebsptreeindex.h" #include "qgraphicsscenelinearindex.h" @@ -244,6 +243,7 @@ #include #include #include +#include #include #ifdef Q_WS_X11 #include @@ -772,6 +772,7 @@ QList QGraphicsScenePrivate::itemsAtPosition(const QPoint &scre const QPointF &scenePos, QWidget *widget) const { + Q_UNUSED(screenPos); Q_Q(const QGraphicsScene); QGraphicsView *view = widget ? qobject_cast(widget->parentWidget()) : 0; return q->items(scenePos, Qt::IntersectsItemShape, Qt::AscendingOrder, @@ -1806,7 +1807,7 @@ void QGraphicsScene::setSelectionArea(const QPainterPath &path) */ void QGraphicsScene::setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode) { - setSelectionArea(path, Qt::IntersectsItemShape, QTransform()); + setSelectionArea(path, mode, QTransform()); } /*! diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index a081e04..fd25283 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -58,7 +58,6 @@ #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW #include "qgraphicsscenebsptreeindex_p.h" -#include "qgraphicssceneindex.h" #include "qgraphicsview.h" #include "qgraphicsitem_p.h" @@ -74,6 +73,7 @@ QT_BEGIN_NAMESPACE +class QGraphicsSceneIndex; class QGraphicsView; class QGraphicsWidget; diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 40cafa6..54bf09b 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -80,12 +80,12 @@ #ifndef QT_NO_GRAPHICSVIEW #include "qgraphicsscenebsptreeindex_p.h" -#include "qgraphicssceneindex_p.h" #include "qgraphicsitem_p.h" #include "qgraphicsscene_p.h" -#include +#include +#include #include QT_BEGIN_NAMESPACE diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex.h index 504ea8b..f3c77d3 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.h @@ -67,7 +67,7 @@ QT_MODULE(Gui) #include #include #include -#include +#include #include "qgraphicsscene_bsp_p.h" diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index eb3abc1..8d7581f 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -56,12 +56,11 @@ \sa QGraphicsScene, QGraphicsView */ -#include "qgraphicssceneindex.h" -#include "qgraphicssceneindex_p.h" #include "qgraphicsscene.h" #include "qgraphicsitem_p.h" #include "qgraphicsscene_p.h" #include "qgraphicswidget.h" +#include #ifndef QT_NO_GRAPHICSVIEW @@ -621,6 +620,6 @@ void QGraphicsSceneIndex::sceneRectChanged(const QRectF &rect) QT_END_NAMESPACE -#include "moc_qgraphicssceneindex.cpp" +#include "moc_qgraphicssceneindex_p.cpp" #endif // QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicssceneindex.h b/src/gui/graphicsview/qgraphicssceneindex.h deleted file mode 100644 index 25ece04..0000000 --- a/src/gui/graphicsview/qgraphicssceneindex.h +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui 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 qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGRAPHICSSCENEINDEX_H -#define QGRAPHICSSCENEINDEX_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header -// file may change from version to version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW - -class QGraphicsSceneIndexPrivate; -class QGraphicsScene; -class QRectF; -class QPointF; -template class QList; - -class Q_AUTOTEST_EXPORT QGraphicsSceneIndex: public QObject -{ - Q_OBJECT - -public: - QGraphicsSceneIndex(QGraphicsScene *scene = 0); - virtual ~QGraphicsSceneIndex(); - - QGraphicsScene *scene() const; - - virtual QRectF indexedRect() const; - - virtual QList items(Qt::SortOrder order = Qt::AscendingOrder) const = 0; - virtual QList items(const QPointF &pos, Qt::ItemSelectionMode mode, - Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; - virtual QList items(const QRectF &rect, Qt::ItemSelectionMode mode, - Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; - virtual QList items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, - Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; - virtual QList items(const QPainterPath &path, Qt::ItemSelectionMode mode, - Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; - virtual QList estimateItems(const QPointF &point, - Qt::SortOrder order, const QTransform &deviceTransform) const; - virtual QList estimateItems(const QRectF &rect, - Qt::SortOrder order, const QTransform &deviceTransform) const = 0; - -protected: - virtual void clear(); - virtual void addItem(QGraphicsItem *item) = 0; - virtual void removeItem(QGraphicsItem *item) = 0; - virtual void deleteItem(QGraphicsItem *item); - - virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value); - virtual void prepareBoundingRectChange(const QGraphicsItem *item); - virtual void sceneRectChanged(const QRectF &rect); - - QGraphicsSceneIndex(QObjectPrivate &dd, QGraphicsScene *scene); - - friend class QGraphicsScene; - friend class QGraphicsScenePrivate; - friend class QGraphicsItem; - friend class QGraphicsItemPrivate; - friend class QGraphicsSceneBspTreeIndex; -private: - Q_DISABLE_COPY(QGraphicsSceneIndex) - Q_DECLARE_PRIVATE(QGraphicsSceneIndex) -}; - -#endif // QT_NO_GRAPHICSVIEW - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QGRAPHICSSCENEINDEX_H diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index 576ee98..85a1140 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QGRAPHICSSCENEINDEX_P_H -#define QGRAPHICSSCENEINDEX_P_H +#ifndef QGRAPHICSSCENEINDEX_H +#define QGRAPHICSSCENEINDEX_H // // W A R N I N G @@ -53,20 +53,77 @@ // We mean it. // -#include "qgraphicssceneindex.h" - -#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW - +#include +#include +#include +#include #include -#include + +QT_BEGIN_HEADER QT_BEGIN_NAMESPACE +QT_MODULE(Gui) + +#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW + class QGraphicsScene; class QGraphicsSceneIndexIntersector; -class QGraphicsSceneIndexRectIntersector; class QGraphicsSceneIndexPointIntersector; +class QGraphicsSceneIndexRectIntersector; class QGraphicsSceneIndexPathIntersector; +class QGraphicsSceneIndexPrivate; +class QPointF; +class QRectF; +template class QList; + +class Q_AUTOTEST_EXPORT QGraphicsSceneIndex : public QObject +{ + Q_OBJECT + +public: + QGraphicsSceneIndex(QGraphicsScene *scene = 0); + virtual ~QGraphicsSceneIndex(); + + QGraphicsScene *scene() const; + + virtual QRectF indexedRect() const; + + virtual QList items(Qt::SortOrder order = Qt::AscendingOrder) const = 0; + virtual QList items(const QPointF &pos, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + virtual QList items(const QRectF &rect, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + virtual QList items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + virtual QList items(const QPainterPath &path, Qt::ItemSelectionMode mode, + Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; + virtual QList estimateItems(const QPointF &point, + Qt::SortOrder order, const QTransform &deviceTransform) const; + virtual QList estimateItems(const QRectF &rect, + Qt::SortOrder order, const QTransform &deviceTransform) const = 0; + +protected: + virtual void clear(); + virtual void addItem(QGraphicsItem *item) = 0; + virtual void removeItem(QGraphicsItem *item) = 0; + virtual void deleteItem(QGraphicsItem *item); + + virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value); + virtual void prepareBoundingRectChange(const QGraphicsItem *item); + virtual void sceneRectChanged(const QRectF &rect); + + QGraphicsSceneIndex(QObjectPrivate &dd, QGraphicsScene *scene); + + friend class QGraphicsScene; + friend class QGraphicsScenePrivate; + friend class QGraphicsItem; + friend class QGraphicsItemPrivate; + friend class QGraphicsSceneBspTreeIndex; +private: + Q_DISABLE_COPY(QGraphicsSceneIndex) + Q_DECLARE_PRIVATE(QGraphicsSceneIndex) +}; class QGraphicsSceneIndexPrivate : public QObjectPrivate { @@ -96,8 +153,10 @@ public: const QTransform &transform, const QTransform &deviceTransform) const = 0; }; +#endif // QT_NO_GRAPHICSVIEW + QT_END_NAMESPACE -#endif // QGRAPHICSSCENEINDEX_P_H +QT_END_HEADER -#endif +#endif // QGRAPHICSSCENEINDEX_H diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex.h b/src/gui/graphicsview/qgraphicsscenelinearindex.h index b793d98..a5327ef 100644 --- a/src/gui/graphicsview/qgraphicsscenelinearindex.h +++ b/src/gui/graphicsview/qgraphicsscenelinearindex.h @@ -65,8 +65,8 @@ QT_MODULE(Gui) #include #include -#include #include +#include class Q_AUTOTEST_EXPORT QGraphicsSceneLinearIndex : public QGraphicsSceneIndex { -- cgit v0.12 From d49fd874258c055b54b122a0c1f6f10ee20f11ea Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Thu, 18 Jun 2009 14:52:47 +0200 Subject: Move QGraphicsSceneLinearIndex into private headers (=> _p.h). We want to keep this as private API for now. Reviewed-by: Alexis --- src/gui/graphicsview/graphicsview.pri | 2 +- src/gui/graphicsview/qgraphicsscene.cpp | 2 +- src/gui/graphicsview/qgraphicsscenelinearindex.cpp | 4 +- src/gui/graphicsview/qgraphicsscenelinearindex.h | 124 --------------------- src/gui/graphicsview/qgraphicsscenelinearindex_p.h | 124 +++++++++++++++++++++ 5 files changed, 128 insertions(+), 128 deletions(-) delete mode 100644 src/gui/graphicsview/qgraphicsscenelinearindex.h create mode 100644 src/gui/graphicsview/qgraphicsscenelinearindex_p.h diff --git a/src/gui/graphicsview/graphicsview.pri b/src/gui/graphicsview/graphicsview.pri index 2d8f37e..5981ce5 100644 --- a/src/gui/graphicsview/graphicsview.pri +++ b/src/gui/graphicsview/graphicsview.pri @@ -16,7 +16,7 @@ HEADERS += graphicsview/qgraphicsgridlayout.h \ graphicsview/qgraphicsscenebsptreeindex_p.h \ graphicsview/qgraphicssceneevent.h \ graphicsview/qgraphicssceneindex_p.h \ - graphicsview/qgraphicsscenelinearindex.h \ + graphicsview/qgraphicsscenelinearindex_p.h \ graphicsview/qgraphicsview.h \ graphicsview/qgraphicsview_p.h \ graphicsview/qgraphicswidget.h \ diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 9d224b1..e004917 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -218,7 +218,7 @@ #include "qgraphicswidget.h" #include "qgraphicswidget_p.h" #include "qgraphicsscenebsptreeindex.h" -#include "qgraphicsscenelinearindex.h" +#include #include #include diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex.cpp b/src/gui/graphicsview/qgraphicsscenelinearindex.cpp index 5504493..694062b 100644 --- a/src/gui/graphicsview/qgraphicsscenelinearindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenelinearindex.cpp @@ -1,5 +1,3 @@ -#include "qgraphicsscenelinearindex.h" - /*! \class QGraphicsSceneLinearIndex \brief The QGraphicsSceneLinearIndex class provides an implementation of @@ -16,6 +14,8 @@ \sa QGraphicsScene, QGraphicsView, QGraphicsSceneIndex, QGraphicsSceneBspTreeIndex */ +#include + /*! \fn QGraphicsSceneLinearIndex::QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0): diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex.h b/src/gui/graphicsview/qgraphicsscenelinearindex.h deleted file mode 100644 index a5327ef..0000000 --- a/src/gui/graphicsview/qgraphicsscenelinearindex.h +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui 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 qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGRAPHICSSCENELINEARINDEX_H -#define QGRAPHICSSCENELINEARINDEX_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW - -#include -#include -#include -#include - -class Q_AUTOTEST_EXPORT QGraphicsSceneLinearIndex : public QGraphicsSceneIndex -{ - Q_OBJECT - -public: - QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0): QGraphicsSceneIndex(scene) - { - } - - QList items(Qt::SortOrder order = Qt::AscendingOrder) const { - Q_UNUSED(order); - return m_items; - } - - virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const { - Q_UNUSED(rect); - Q_UNUSED(order); - Q_UNUSED(deviceTransform); - return m_items; - } - - virtual QRectF indexedRect() const { - return m_sceneRect; - } - -protected : - void sceneRectChanged(const QRectF &rect) { - m_sceneRect = rect; - } - - virtual void clear() { - m_items.clear(); - } - - virtual void addItem(QGraphicsItem *item) { - m_items << item; - } - - virtual void removeItem(QGraphicsItem *item) { - m_items.removeAll(item); - } - -private: - QRectF m_sceneRect; - QList m_items; -}; - -#endif // QT_NO_GRAPHICSVIEW - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QGRAPHICSSCENELINEARINDEX_H diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h new file mode 100644 index 0000000..a5327ef --- /dev/null +++ b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui 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 qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGRAPHICSSCENELINEARINDEX_H +#define QGRAPHICSSCENELINEARINDEX_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW + +#include +#include +#include +#include + +class Q_AUTOTEST_EXPORT QGraphicsSceneLinearIndex : public QGraphicsSceneIndex +{ + Q_OBJECT + +public: + QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0): QGraphicsSceneIndex(scene) + { + } + + QList items(Qt::SortOrder order = Qt::AscendingOrder) const { + Q_UNUSED(order); + return m_items; + } + + virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const { + Q_UNUSED(rect); + Q_UNUSED(order); + Q_UNUSED(deviceTransform); + return m_items; + } + + virtual QRectF indexedRect() const { + return m_sceneRect; + } + +protected : + void sceneRectChanged(const QRectF &rect) { + m_sceneRect = rect; + } + + virtual void clear() { + m_items.clear(); + } + + virtual void addItem(QGraphicsItem *item) { + m_items << item; + } + + virtual void removeItem(QGraphicsItem *item) { + m_items.removeAll(item); + } + +private: + QRectF m_sceneRect; + QList m_items; +}; + +#endif // QT_NO_GRAPHICSVIEW + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QGRAPHICSSCENELINEARINDEX_H -- cgit v0.12 From 734cc7dd63147f80cd4794351b9124f8d6eb88fe Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Thu, 18 Jun 2009 14:56:59 +0200 Subject: Move QGraphicsSceneBspTreeIndex into private headers (=> _p.h). We'll keep this as private API for now. Reviewed-by: Alexis --- src/gui/graphicsview/graphicsview.pri | 1 - src/gui/graphicsview/qgraphicsscene.cpp | 2 +- .../graphicsview/qgraphicsscenebsptreeindex.cpp | 10 +- src/gui/graphicsview/qgraphicsscenebsptreeindex.h | 119 --------------------- .../graphicsview/qgraphicsscenebsptreeindex_p.h | 66 ++++++++++-- 5 files changed, 61 insertions(+), 137 deletions(-) delete mode 100644 src/gui/graphicsview/qgraphicsscenebsptreeindex.h diff --git a/src/gui/graphicsview/graphicsview.pri b/src/gui/graphicsview/graphicsview.pri index 5981ce5..0c0747e 100644 --- a/src/gui/graphicsview/graphicsview.pri +++ b/src/gui/graphicsview/graphicsview.pri @@ -12,7 +12,6 @@ HEADERS += graphicsview/qgraphicsgridlayout.h \ graphicsview/qgraphicsscene.h \ graphicsview/qgraphicsscene_bsp_p.h \ graphicsview/qgraphicsscene_p.h \ - graphicsview/qgraphicsscenebsptreeindex.h \ graphicsview/qgraphicsscenebsptreeindex_p.h \ graphicsview/qgraphicssceneevent.h \ graphicsview/qgraphicssceneindex_p.h \ diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index e004917..28dd3be 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -217,7 +217,7 @@ #include "qgraphicsview_p.h" #include "qgraphicswidget.h" #include "qgraphicswidget_p.h" -#include "qgraphicsscenebsptreeindex.h" +#include #include #include diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 54bf09b..27b5514 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -75,14 +75,10 @@ \sa QGraphicsScene, QGraphicsView, QGraphicsSceneIndex */ -#include "qgraphicsscenebsptreeindex.h" - #ifndef QT_NO_GRAPHICSVIEW -#include "qgraphicsscenebsptreeindex_p.h" -#include "qgraphicsitem_p.h" -#include "qgraphicsscene_p.h" - +#include +#include #include #include @@ -783,7 +779,7 @@ bool QGraphicsSceneBspTreeIndex::event(QEvent *event) QT_END_NAMESPACE -#include "moc_qgraphicsscenebsptreeindex.cpp" +#include "moc_qgraphicsscenebsptreeindex_p.cpp" #endif // QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex.h deleted file mode 100644 index f3c77d3..0000000 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.h +++ /dev/null @@ -1,119 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui 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 qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header -// file may change from version to version without notice, or even be removed. -// -// We mean it. -// - -#ifndef QGRAPHICSBSPTREEINDEX_H -#define QGRAPHICSBSPTREEINDEX_H - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW - -#include -#include -#include -#include -#include - -#include "qgraphicsscene_bsp_p.h" - -class QGraphicsSceneBspTreeIndexPrivate; - -class Q_AUTOTEST_EXPORT QGraphicsSceneBspTreeIndex : public QGraphicsSceneIndex -{ - Q_OBJECT - Q_PROPERTY(int bspTreeDepth READ bspTreeDepth WRITE setBspTreeDepth) -public: - QGraphicsSceneBspTreeIndex(QGraphicsScene *scene = 0); - QRectF indexedRect() const; - - QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const; - - QList items(Qt::SortOrder order = Qt::AscendingOrder) const; - - int bspTreeDepth(); - void setBspTreeDepth(int depth); - -protected: - bool event(QEvent *event); - void clear(); - - void addItem(QGraphicsItem *item); - void removeItem(QGraphicsItem *item); - void deleteItem(QGraphicsItem *item); - void prepareBoundingRectChange(const QGraphicsItem *item); - - void sceneRectChanged(const QRectF &rect); - void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value); - -private : - Q_DECLARE_PRIVATE(QGraphicsSceneBspTreeIndex) - Q_DISABLE_COPY(QGraphicsSceneBspTreeIndex) - Q_PRIVATE_SLOT(d_func(), void _q_updateSortCache()) - Q_PRIVATE_SLOT(d_func(), void _q_updateIndex()) - - friend class QGraphicsScene; - friend class QGraphicsScenePrivate; -}; - -#endif // QT_NO_GRAPHICSVIEW - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QGRAPHICSBSPTREEINDEX_H diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index ed12fac..1e4234e 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -39,8 +39,7 @@ ** ****************************************************************************/ -#ifndef QGRAPHICSSCENEBSPTREEINDEX_P_H -#define QGRAPHICSSCENEBSPTREEINDEX_P_H +#include // // W A R N I N G @@ -53,18 +52,66 @@ // We mean it. // -#include "qgraphicsscenebsptreeindex.h" +#ifndef QGRAPHICSBSPTREEINDEX_H +#define QGRAPHICSBSPTREEINDEX_H + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW -#include +#include +#include +#include +#include #include - -QT_BEGIN_NAMESPACE +#include +#include static const int QGRAPHICSSCENE_INDEXTIMER_TIMEOUT = 2000; class QGraphicsScene; +class QGraphicsSceneBspTreeIndexPrivate; + +class Q_AUTOTEST_EXPORT QGraphicsSceneBspTreeIndex : public QGraphicsSceneIndex +{ + Q_OBJECT + Q_PROPERTY(int bspTreeDepth READ bspTreeDepth WRITE setBspTreeDepth) +public: + QGraphicsSceneBspTreeIndex(QGraphicsScene *scene = 0); + QRectF indexedRect() const; + + QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const; + + QList items(Qt::SortOrder order = Qt::AscendingOrder) const; + + int bspTreeDepth(); + void setBspTreeDepth(int depth); + +protected: + bool event(QEvent *event); + void clear(); + + void addItem(QGraphicsItem *item); + void removeItem(QGraphicsItem *item); + void deleteItem(QGraphicsItem *item); + void prepareBoundingRectChange(const QGraphicsItem *item); + + void sceneRectChanged(const QRectF &rect); + void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value); + +private : + Q_DECLARE_PRIVATE(QGraphicsSceneBspTreeIndex) + Q_DISABLE_COPY(QGraphicsSceneBspTreeIndex) + Q_PRIVATE_SLOT(d_func(), void _q_updateSortCache()) + Q_PRIVATE_SLOT(d_func(), void _q_updateIndex()) + + friend class QGraphicsScene; + friend class QGraphicsScenePrivate; +}; class QGraphicsSceneBspTreeIndexPrivate : public QGraphicsSceneIndexPrivate { @@ -183,9 +230,10 @@ static inline bool QRectF_intersects(const QRectF &s, const QRectF &r) return !(t1 >= b2 || t2 >= b1); } -QT_END_NAMESPACE +#endif // QT_NO_GRAPHICSVIEW -#endif // QGRAPHICSSCENEBSPTREEINDEX_P_H +QT_END_NAMESPACE -#endif +QT_END_HEADER +#endif // QGRAPHICSBSPTREEINDEX_H -- cgit v0.12 From 378b5b603bd269b631bbe108268a683adde11828 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Thu, 18 Jun 2009 15:02:05 +0200 Subject: Make the autotests compile again. Reviewed-by: Alexis --- .../tst_qgraphicssceneindex.cpp | 23 +++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp index 6b352ab..d10f86d 100644 --- a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp +++ b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp @@ -42,11 +42,10 @@ #include #include -#include #include +#include #include - //TESTED_CLASS= //TESTED_FILES= @@ -118,6 +117,7 @@ void tst_QGraphicsSceneIndex::customIndex_data() void tst_QGraphicsSceneIndex::customIndex() { +#if 0 QFETCH(QString, indexMethod); QGraphicsSceneIndex *index = createIndex(indexMethod); @@ -126,6 +126,7 @@ void tst_QGraphicsSceneIndex::customIndex() scene.addRect(0, 0, 30, 40); QCOMPARE(scene.items(QRectF(0, 0, 10, 10)).count(), 1); +#endif } void tst_QGraphicsSceneIndex::scatteredItems_data() @@ -136,10 +137,14 @@ void tst_QGraphicsSceneIndex::scatteredItems_data() void tst_QGraphicsSceneIndex::scatteredItems() { QFETCH(QString, indexMethod); - QGraphicsSceneIndex *index = createIndex(indexMethod); QGraphicsScene scene; +#if 1 + scene.setItemIndexMethod(indexMethod == "linear" ? QGraphicsScene::NoIndex : QGraphicsScene::BspTreeIndex); +#else + QGraphicsSceneIndex *index = createIndex(indexMethod); scene.setSceneIndex(index); +#endif for (int i = 0; i < 10; ++i) scene.addRect(i*50, i*50, 40, 35); @@ -161,10 +166,14 @@ void tst_QGraphicsSceneIndex::overlappedItems_data() void tst_QGraphicsSceneIndex::overlappedItems() { QFETCH(QString, indexMethod); - QGraphicsSceneIndex *index = createIndex(indexMethod); QGraphicsScene scene; +#if 1 + scene.setItemIndexMethod(indexMethod == "linear" ? QGraphicsScene::NoIndex : QGraphicsScene::BspTreeIndex); +#else + QGraphicsSceneIndex *index = createIndex(indexMethod); scene.setSceneIndex(index); +#endif for (int i = 0; i < 10; ++i) for (int j = 0; j < 10; ++j) @@ -191,10 +200,14 @@ void tst_QGraphicsSceneIndex::movingItems_data() void tst_QGraphicsSceneIndex::movingItems() { QFETCH(QString, indexMethod); - QGraphicsSceneIndex *index = createIndex(indexMethod); QGraphicsScene scene; +#if 1 + scene.setItemIndexMethod(indexMethod == "linear" ? QGraphicsScene::NoIndex : QGraphicsScene::BspTreeIndex); +#else + QGraphicsSceneIndex *index = createIndex(indexMethod); scene.setSceneIndex(index); +#endif for (int i = 0; i < 10; ++i) scene.addRect(i*50, i*50, 40, 35); -- cgit v0.12 From a18e5288324aa13da014ee52daffbfc589c87be3 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Thu, 18 Jun 2009 17:29:42 +0200 Subject: Fix crash with untransformable items. Be sure that item goes in the correct list if it set its flags to untransformable. Reviewed-by: andreas --- .../graphicsview/qgraphicsscenebsptreeindex.cpp | 43 +++++++++++++++------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 27b5514..72636b8 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -548,14 +548,9 @@ void QGraphicsSceneBspTreeIndexPrivate::removeFromBspTree(QGraphicsItem *item) // ### remove from child index only if applicable return; } - int index = item->d_func()->index; - if (index != -1) { - bsp.removeItem(item, item->sceneBoundingRect()); - freeItemIndexes << index; - indexedItems[index] = 0; - item->d_func()->index = -1; - unindexedItems << item; + if (item->d_func()->index != -1) { + bsp.removeItem(item, item->sceneBoundingRect()); //prepareGeometryChange will call prepareBoundingRectChange foreach (QGraphicsItem *child, item->children()) child->prepareGeometryChange(); @@ -570,10 +565,20 @@ void QGraphicsSceneBspTreeIndexPrivate::removeFromBspTree(QGraphicsItem *item) void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem *item) { Q_D(QGraphicsSceneBspTreeIndex); - // Note: This will access item's sceneBoundingRect(), which (as this is - // C++) is why we cannot call removeItem() from QGraphicsItem's - // destructor. - d->removeFromBspTree(const_cast(item)); + if (!item->d_ptr->itemIsUntransformable()) { + // Note: This will access item's sceneBoundingRect(), which (as this is + // C++) is why we cannot call removeItem() from QGraphicsItem's + // destructor. + QGraphicsItem *thatItem = const_cast(item); + d->removeFromBspTree(thatItem); + int index = item->d_func()->index; + if (index != -1) { + d->freeItemIndexes << index; + d->indexedItems[index] = 0; + thatItem->d_func()->index = -1; + d->unindexedItems << thatItem; + } + } } /*! @@ -725,7 +730,13 @@ void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphics if (ignoredTransform != willIgnoreTransform) { QGraphicsItem *thatItem = const_cast(item); removeItem(thatItem); - addItem(thatItem); + thatItem->d_ptr->index = -1; + if (willIgnoreTransform) { + d->untransformableItems << thatItem; + } else { + d->unindexedItems << thatItem; + d->startIndexTimer(0); + } } break; } @@ -741,7 +752,13 @@ void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphics if (ignoredTransform != willIgnoreTransform) { QGraphicsItem *thatItem = const_cast(item); removeItem(thatItem); - addItem(thatItem); + thatItem->d_ptr->index = -1; + if (willIgnoreTransform) { + d->untransformableItems << thatItem; + } else { + d->unindexedItems << thatItem; + d->startIndexTimer(0); + } } break; } -- cgit v0.12 From 8befd7589456c6fd193676daeba8f0779d88776e Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Mon, 22 Jun 2009 11:32:51 +0200 Subject: Remove unused code / delay in this autotest. --- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 1ca6c98..981efeb 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -4710,11 +4710,6 @@ void tst_QGraphicsItem::itemClipsChildrenToShape() scene.render(&painter); painter.end(); - QGraphicsView view(&scene); - view.show(); - - QTest::qWait(5000); - QCOMPARE(image.pixel(16, 16), QColor(255, 0, 0).rgba()); QCOMPARE(image.pixel(32, 32), QColor(0, 0, 255).rgba()); QCOMPARE(image.pixel(50, 50), QColor(0, 255, 0).rgba()); -- cgit v0.12 From 375c4f53e9702aa3273154c0879e3b6dbd2723d6 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Mon, 22 Jun 2009 11:38:17 +0200 Subject: QGraphicsSceneLinearIndex: touch-ups. --- src/gui/graphicsview/qgraphicsscenelinearindex_p.h | 39 +++++++++------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h index a5327ef..88e0e6a 100644 --- a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h @@ -73,42 +73,35 @@ class Q_AUTOTEST_EXPORT QGraphicsSceneLinearIndex : public QGraphicsSceneIndex Q_OBJECT public: - QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0): QGraphicsSceneIndex(scene) - { - } + QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0) : QGraphicsSceneIndex(scene) + { } - QList items(Qt::SortOrder order = Qt::AscendingOrder) const { - Q_UNUSED(order); - return m_items; - } + QList items(Qt::SortOrder order = Qt::AscendingOrder) const + { Q_UNUSED(order); return m_items; } - virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const { + virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const + { Q_UNUSED(rect); Q_UNUSED(order); Q_UNUSED(deviceTransform); return m_items; } - virtual QRectF indexedRect() const { - return m_sceneRect; - } + virtual QRectF indexedRect() const + { return m_sceneRect; } protected : - void sceneRectChanged(const QRectF &rect) { - m_sceneRect = rect; - } + void sceneRectChanged(const QRectF &rect) + { m_sceneRect = rect; } - virtual void clear() { - m_items.clear(); - } + virtual void clear() + { m_items.clear(); } - virtual void addItem(QGraphicsItem *item) { - m_items << item; - } + virtual void addItem(QGraphicsItem *item) + { m_items << item; } - virtual void removeItem(QGraphicsItem *item) { - m_items.removeAll(item); - } + virtual void removeItem(QGraphicsItem *item) + { m_items.removeOne(item); } private: QRectF m_sceneRect; -- cgit v0.12 From be79229e9c454764d63262f46f686b3e1721ee2c Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Tue, 23 Jun 2009 12:35:31 +0200 Subject: More work on getting autotests to pass. --- src/gui/graphicsview/qgraphicsscene.cpp | 33 ++++++++++++++------ src/gui/graphicsview/qgraphicsscene_p.h | 1 + .../graphicsview/qgraphicsscenebsptreeindex.cpp | 36 +++++----------------- .../graphicsview/qgraphicsscenebsptreeindex_p.h | 3 +- src/gui/graphicsview/qgraphicssceneindex.cpp | 23 +++----------- src/gui/graphicsview/qgraphicssceneindex_p.h | 4 +-- src/gui/graphicsview/qgraphicsscenelinearindex_p.h | 7 ----- src/gui/graphicsview/qgraphicsview.cpp | 16 +++++----- tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp | 28 ++++++++++++++--- tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 1 + 10 files changed, 71 insertions(+), 81 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 2f7ae04..6f92629 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -273,6 +273,7 @@ QGraphicsScenePrivate::QGraphicsScenePrivate() index(0), lastItemCount(0), hasSceneRect(false), + dirtyGrowingItemsBoundingRect(true), updateAll(false), calledEmitUpdated(false), processDirtyItemsEmitted(false), @@ -378,8 +379,9 @@ void QGraphicsScenePrivate::unregisterTopLevelItem(QGraphicsItem *item) */ void QGraphicsScenePrivate::_q_updateLater() { + QRectF null; foreach (QGraphicsItem *item, pendingUpdateItems) - item->update(); + markDirty(item, null); pendingUpdateItems.clear(); } @@ -409,8 +411,11 @@ void QGraphicsScenePrivate::_q_processDirtyItems() const bool wasPendingSceneUpdate = calledEmitUpdated; const QRectF oldGrowingItemsBoundingRect = growingItemsBoundingRect; processDirtyItemsRecursive(0); - if (!hasSceneRect && oldGrowingItemsBoundingRect != growingItemsBoundingRect) + dirtyGrowingItemsBoundingRect = false; + if (oldGrowingItemsBoundingRect != growingItemsBoundingRect) { + index->sceneRectChanged(); emit q_func()->sceneRectChanged(growingItemsBoundingRect); + } if (wasPendingSceneUpdate) return; @@ -1250,9 +1255,18 @@ QGraphicsScene::~QGraphicsScene() QRectF QGraphicsScene::sceneRect() const { Q_D(const QGraphicsScene); - /// ### Remove? The growing items bounding rect might be managed - // by the scene. - return d->index->indexedRect(); + if (!d->hasSceneRect && d->dirtyGrowingItemsBoundingRect) { + // Lazily update the growing items bounding rect + QGraphicsScenePrivate *thatd = const_cast(d); + QRectF oldGrowingBoundingRect = thatd->growingItemsBoundingRect; + thatd->growingItemsBoundingRect |= itemsBoundingRect(); + thatd->dirtyGrowingItemsBoundingRect = false; + if (oldGrowingBoundingRect != thatd->growingItemsBoundingRect) { + thatd->index->sceneRectChanged(); + emit const_cast(this)->sceneRectChanged(thatd->growingItemsBoundingRect); + } + } + return d->hasSceneRect ? d->sceneRect : d->growingItemsBoundingRect; } void QGraphicsScene::setSceneRect(const QRectF &rect) { @@ -1260,8 +1274,8 @@ void QGraphicsScene::setSceneRect(const QRectF &rect) if (rect != d->sceneRect) { d->hasSceneRect = !rect.isNull(); d->sceneRect = rect; - d->index->sceneRectChanged(rect); - emit sceneRectChanged(rect); + d->index->sceneRectChanged(); + emit sceneRectChanged(d->hasSceneRect ? rect : d->growingItemsBoundingRect); } } @@ -1411,8 +1425,6 @@ void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method) d->index = new QGraphicsSceneLinearIndex(this); for (int i = oldItems.size() - 1; i >= 0; --i) d->index->addItem(oldItems.at(i)); - - d->index->sceneRectChanged(d->sceneRect); } /*! @@ -2057,6 +2069,8 @@ void QGraphicsScene::addItem(QGraphicsItem *item) if (d->pendingUpdateItems.isEmpty()) QMetaObject::invokeMethod(this, "_q_updateLater", Qt::QueuedConnection); d->pendingUpdateItems << item; + } else { + d->dirtyGrowingItemsBoundingRect = true; } // Disable selectionChanged() for individual items @@ -4235,6 +4249,7 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b bool removingItemFromScene) { Q_ASSERT(item); + dirtyGrowingItemsBoundingRect = true; if (updateAll) return; diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index ea65707..8c4b2d2 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -95,6 +95,7 @@ public: QRectF sceneRect; bool hasSceneRect; + bool dirtyGrowingItemsBoundingRect; QRectF growingItemsBoundingRect; void _q_emitUpdated(); diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 72636b8..aeee982 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -122,7 +122,6 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() if (!indexTimerId) return; - QGraphicsScenePrivate * scenePrivate = q->scene()->d_func(); q->killTimer(indexTimerId); indexTimerId = 0; @@ -144,10 +143,6 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() } } - // Update growing scene rect. - QRectF oldGrowingItemsBoundingRect = scenePrivate->growingItemsBoundingRect; - scenePrivate->growingItemsBoundingRect |= unindexedItemsBoundingRect; - // Determine whether we should regenerate the BSP tree. if (bspTreeDepth == 0) { int oldDepth = intmaxlog(lastItemCount); @@ -165,7 +160,6 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() bsp.initialize(q->scene()->sceneRect(), bspTreeDepth); unindexedItems = indexedItems; lastItemCount = indexedItems.size(); - q->scene()->update(); } // Insert all unindexed items into the tree. @@ -179,10 +173,6 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() } } unindexedItems.clear(); - - // Notify scene rect changes. - if (!scenePrivate->hasSceneRect && scenePrivate->growingItemsBoundingRect != oldGrowingItemsBoundingRect) - emit q->scene()->sceneRectChanged(scenePrivate->growingItemsBoundingRect); } @@ -248,7 +238,7 @@ void QGraphicsSceneBspTreeIndexPrivate::climbTree(QGraphicsItem *item, int *stac { if (!item->d_ptr->children.isEmpty()) { QList childList = item->d_ptr->children; - qSort(childList.begin(), childList.end(), qt_closestLeaf); + qStableSort(childList.begin(), childList.end(), qt_closestLeaf); for (int i = 0; i < childList.size(); ++i) { QGraphicsItem *item = childList.at(i); if (!(item->flags() & QGraphicsItem::ItemStacksBehindParent)) @@ -287,7 +277,7 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateSortCache() topLevels << item; } - qSort(topLevels.begin(), topLevels.end(), qt_closestLeaf); + qStableSort(topLevels.begin(), topLevels.end(), qt_closestLeaf); for (int i = 0; i < topLevels.size(); ++i) climbTree(topLevels.at(i), &stackingOrder); } @@ -379,15 +369,15 @@ void QGraphicsSceneBspTreeIndexPrivate::sortItems(QList *itemLi { if (sortCacheEnabled) { if (order == Qt::AscendingOrder) { - qSort(itemList->begin(), itemList->end(), closestItemFirst_withCache); + qStableSort(itemList->begin(), itemList->end(), closestItemFirst_withCache); } else if (order == Qt::DescendingOrder) { - qSort(itemList->begin(), itemList->end(), closestItemLast_withCache); + qStableSort(itemList->begin(), itemList->end(), closestItemLast_withCache); } } else { if (order == Qt::AscendingOrder) { - qSort(itemList->begin(), itemList->end(), closestItemFirst_withoutCache); + qStableSort(itemList->begin(), itemList->end(), closestItemFirst_withoutCache); } else if (order == Qt::DescendingOrder) { - qSort(itemList->begin(), itemList->end(), closestItemLast_withoutCache); + qStableSort(itemList->begin(), itemList->end(), closestItemLast_withoutCache); } } } @@ -403,17 +393,6 @@ QGraphicsSceneBspTreeIndex::QGraphicsSceneBspTreeIndex(QGraphicsScene *scene) /*! \reimp - Return the rect indexed by the BSP index. -*/ -QRectF QGraphicsSceneBspTreeIndex::indexedRect() const -{ - Q_D(const QGraphicsSceneBspTreeIndex); - const_cast(d)->_q_updateIndex(); - return scene()->d_func()->hasSceneRect ? scene()->d_func()->sceneRect : scene()->d_func()->growingItemsBoundingRect; -} - -/*! - \reimp Clear the all the BSP index. */ void QGraphicsSceneBspTreeIndex::clear() @@ -705,10 +684,9 @@ void QGraphicsSceneBspTreeIndex::setBspTreeDepth(int depth) This method react to the \a rect change of the scene and reset the BSP tree index. */ -void QGraphicsSceneBspTreeIndex::sceneRectChanged(const QRectF &rect) +void QGraphicsSceneBspTreeIndex::sceneRectChanged() { Q_D(QGraphicsSceneBspTreeIndex); - d->sceneRect = rect; d->resetIndex(); } diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 1e4234e..715b22f 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -82,7 +82,6 @@ class Q_AUTOTEST_EXPORT QGraphicsSceneBspTreeIndex : public QGraphicsSceneIndex Q_PROPERTY(int bspTreeDepth READ bspTreeDepth WRITE setBspTreeDepth) public: QGraphicsSceneBspTreeIndex(QGraphicsScene *scene = 0); - QRectF indexedRect() const; QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const; @@ -100,7 +99,7 @@ protected: void deleteItem(QGraphicsItem *item); void prepareBoundingRectChange(const QGraphicsItem *item); - void sceneRectChanged(const QRectF &rect); + void sceneRectChanged(); void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value); private : diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 8d7581f..4eaed2b 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -56,6 +56,7 @@ \sa QGraphicsScene, QGraphicsView */ +#include "qdebug.h" #include "qgraphicsscene.h" #include "qgraphicsitem_p.h" #include "qgraphicsscene_p.h" @@ -131,14 +132,10 @@ public: keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, pointPath, mode); } } else { - QRectF sceneBrect = transform.mapRect(brect); - keep = sceneBrect.contains(scenePoint); - if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { - QPainterPath pointPath; - pointPath.addRect(QRectF(transform.inverted().map(scenePoint), QSizeF(1, 1))); - keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, pointPath, mode); - } + QRectF sceneBoundingRect = transform.mapRect(brect); + keep = sceneBoundingRect.intersects(QRectF(scenePoint, QSizeF(1, 1))) && item->contains(transform.inverted().map(scenePoint)); } + return keep; } @@ -366,15 +363,6 @@ QGraphicsScene* QGraphicsSceneIndex::scene() const } /*! - Returns the indexed area for the index -*/ -QRectF QGraphicsSceneIndex::indexedRect() const -{ - Q_D(const QGraphicsSceneIndex); - return d->scene->d_func()->sceneRect; -} - -/*! \fn QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const @@ -613,9 +601,8 @@ void QGraphicsSceneIndex::prepareBoundingRectChange(const QGraphicsItem *item) rectangle. \a rect is the new value of the scene rectangle. \sa QGraphicsScene::sceneRect() */ -void QGraphicsSceneIndex::sceneRectChanged(const QRectF &rect) +void QGraphicsSceneIndex::sceneRectChanged() { - Q_UNUSED(rect); } QT_END_NAMESPACE diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index 85a1140..60e9032 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -87,8 +87,6 @@ public: QGraphicsScene *scene() const; - virtual QRectF indexedRect() const; - virtual QList items(Qt::SortOrder order = Qt::AscendingOrder) const = 0; virtual QList items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; @@ -111,7 +109,7 @@ protected: virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value); virtual void prepareBoundingRectChange(const QGraphicsItem *item); - virtual void sceneRectChanged(const QRectF &rect); + virtual void sceneRectChanged(); QGraphicsSceneIndex(QObjectPrivate &dd, QGraphicsScene *scene); diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h index 88e0e6a..9463487 100644 --- a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h @@ -87,13 +87,7 @@ public: return m_items; } - virtual QRectF indexedRect() const - { return m_sceneRect; } - protected : - void sceneRectChanged(const QRectF &rect) - { m_sceneRect = rect; } - virtual void clear() { m_items.clear(); } @@ -104,7 +98,6 @@ protected : { m_items.removeOne(item); } private: - QRectF m_sceneRect; QList m_items; }; diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index ec1746a..640f85b 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -802,13 +802,15 @@ void QGraphicsViewPrivate::processPendingUpdates() return; } + if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing) + dirtyBoundingRect.adjust(-1, -1, 1, 1); + else + dirtyBoundingRect.adjust(-2, -2, 2, 2); + if (viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate) { - if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing) - viewport->update(dirtyBoundingRect.adjusted(-1, -1, 1, 1)); - else - viewport->update(dirtyBoundingRect.adjusted(-2, -2, 2, 2)); + viewport->update((dirtyRegion + dirtyBoundingRect).boundingRect()); } else { - viewport->update(dirtyRegion); // Already adjusted in updateRect/Region. + viewport->update(dirtyRegion + dirtyBoundingRect); // Already adjusted in updateRect/Region. } dirtyBoundingRect = QRect(); @@ -2087,9 +2089,7 @@ QGraphicsItem *QGraphicsView::itemAt(const QPoint &pos) const Q_D(const QGraphicsView); if (!d->scene) return 0; - // ### Use QGraphicsScene::itemAt() instead. - QList itemsAtPos = d->scene->items(pos, Qt::IntersectsItemShape, Qt::AscendingOrder, - viewportTransform()); + QList itemsAtPos = items(pos); return itemsAtPos.isEmpty() ? 0 : itemsAtPos.first(); } diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index 1d03ef1..1a7a076 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -271,28 +271,46 @@ void tst_QGraphicsScene::construction() void tst_QGraphicsScene::sceneRect() { QGraphicsScene scene; + QSignalSpy sceneRectChanged(&scene, SIGNAL(sceneRectChanged(QRectF))); QCOMPARE(scene.sceneRect(), QRectF()); + QCOMPARE(sceneRectChanged.count(), 0); QGraphicsItem *item = scene.addRect(QRectF(0, 0, 10, 10)); - qApp->processEvents(); item->setPos(-5, -5); - qApp->processEvents(); + QCOMPARE(sceneRectChanged.count(), 0); QCOMPARE(scene.itemAt(0, 0), item); QCOMPARE(scene.itemAt(10, 10), (QGraphicsItem *)0); + QCOMPARE(sceneRectChanged.count(), 0); + QCOMPARE(scene.sceneRect(), QRectF(-5, -5, 10, 10)); + QCOMPARE(sceneRectChanged.count(), 1); + QCOMPARE(sceneRectChanged.last().at(0).toRectF(), scene.sceneRect()); + + item->setPos(0, 0); QCOMPARE(scene.sceneRect(), QRectF(-5, -5, 15, 15)); + QCOMPARE(sceneRectChanged.count(), 2); + QCOMPARE(sceneRectChanged.last().at(0).toRectF(), scene.sceneRect()); scene.setSceneRect(-100, -100, 10, 10); + QCOMPARE(sceneRectChanged.count(), 3); + QCOMPARE(sceneRectChanged.last().at(0).toRectF(), scene.sceneRect()); QCOMPARE(scene.itemAt(0, 0), item); QCOMPARE(scene.itemAt(10, 10), (QGraphicsItem *)0); QCOMPARE(scene.sceneRect(), QRectF(-100, -100, 10, 10)); + item->setPos(10, 10); + QCOMPARE(scene.sceneRect(), QRectF(-100, -100, 10, 10)); + QCOMPARE(sceneRectChanged.count(), 3); + QCOMPARE(sceneRectChanged.last().at(0).toRectF(), scene.sceneRect()); scene.setSceneRect(QRectF()); - QCOMPARE(scene.itemAt(0, 0), item); - QCOMPARE(scene.itemAt(10, 10), (QGraphicsItem *)0); - QCOMPARE(scene.sceneRect(), QRectF(-5, -5, 15, 15)); + QCOMPARE(scene.itemAt(10, 10), item); + QCOMPARE(scene.itemAt(20, 20), (QGraphicsItem *)0); + QCOMPARE(sceneRectChanged.count(), 4); + QCOMPARE(scene.sceneRect(), QRectF(-5, -5, 25, 25)); + QCOMPARE(sceneRectChanged.count(), 5); + QCOMPARE(sceneRectChanged.last().at(0).toRectF(), scene.sceneRect()); } void tst_QGraphicsScene::itemIndexMethod() diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index c8c032a..02e4046 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -371,6 +371,7 @@ void tst_QGraphicsView::interactive() QCOMPARE(item->events.size(), 0); QPoint itemPoint = view.mapFromScene(item->scenePos()); + QVERIFY(view.itemAt(itemPoint)); for (int i = 0; i < 100; ++i) { -- cgit v0.12 From d39a62720ba67a0fa6e4e37519d22f14c7b7404e Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Tue, 23 Jun 2009 14:35:30 +0200 Subject: Ensure that the BSP index returns all untransformable items. --- src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index aeee982..464fe8e 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -595,6 +595,8 @@ QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &r for (int i = 0; i < rectItems.size(); ++i) rectItems.at(i)->d_func()->itemDiscovered = 0; + rectItems += d->untransformableItems; + d->sortItems(&rectItems, order, d->sortCacheEnabled); return rectItems; -- cgit v0.12 From b0f391ae8f2efc272be852f951403fa8e4a8f561 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Tue, 23 Jun 2009 16:57:32 +0200 Subject: Fix tst_QGraphicsItem::collidesWith_item autotest. Avoid unwanted recursion by keeping the sceneRect variable locally. The recursion happens if the call to sceneRect() lazily emits the sceneRectChanged() signal. --- src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 464fe8e..8861c7b 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -157,7 +157,7 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() // Regenerate the tree. if (regenerateIndex) { regenerateIndex = false; - bsp.initialize(q->scene()->sceneRect(), bspTreeDepth); + bsp.initialize(sceneRect, bspTreeDepth); unindexedItems = indexedItems; lastItemCount = indexedItems.size(); } @@ -689,6 +689,7 @@ void QGraphicsSceneBspTreeIndex::setBspTreeDepth(int depth) void QGraphicsSceneBspTreeIndex::sceneRectChanged() { Q_D(QGraphicsSceneBspTreeIndex); + d->sceneRect = d->scene->sceneRect(); d->resetIndex(); } -- cgit v0.12 From 4fb0f9d8d5275c21b3d16be1170b5e7d2ed77f8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Thu, 25 Jun 2009 14:36:03 +0200 Subject: Partially revert be79229e The change in processPendingUpdates was completely wrong and broke several auto-tests. --- src/gui/graphicsview/qgraphicsview.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 94547a5..e4decf9 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -802,15 +802,13 @@ void QGraphicsViewPrivate::processPendingUpdates() return; } - if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing) - dirtyBoundingRect.adjust(-1, -1, 1, 1); - else - dirtyBoundingRect.adjust(-2, -2, 2, 2); - if (viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate) { - viewport->update((dirtyRegion + dirtyBoundingRect).boundingRect()); + if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing) + viewport->update(dirtyBoundingRect.adjusted(-1, -1, 1, 1)); + else + viewport->update(dirtyBoundingRect.adjusted(-2, -2, 2, 2)); } else { - viewport->update(dirtyRegion + dirtyBoundingRect); // Already adjusted in updateRect/Region. + viewport->update(dirtyRegion); // Already adjusted in updateRect/Region. } dirtyBoundingRect = QRect(); -- cgit v0.12 From fe64e44b0dab0152101b4ec17a49305912415016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Thu, 25 Jun 2009 14:42:16 +0200 Subject: Stabilize tst_QGraphicsView::moveItemWhileScrolling. --- tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index 02e4046..65e066f 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -3093,7 +3093,7 @@ void tst_QGraphicsView::moveItemWhileScrolling() #ifdef Q_WS_X11 qt_x11_wait_for_window_manager(&view); #endif - QTest::qWait(100); + QTest::qWait(200); view.lastPaintedRegion = QRegion(); view.horizontalScrollBar()->setValue(view.horizontalScrollBar()->value() + 10); -- cgit v0.12 From 93e3a72f56d4b9ab020c58a2a3fac79be5fe49eb Mon Sep 17 00:00:00 2001 From: David Boddie Date: Thu, 25 Jun 2009 16:15:01 +0200 Subject: Doc: Indicated that QCompleter::completionModel() returns a proxy model. Task-number: 256138 Reviewed-by: jasplin --- src/gui/util/qcompleter.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/util/qcompleter.cpp b/src/gui/util/qcompleter.cpp index 3d25f13..f4adcea 100644 --- a/src/gui/util/qcompleter.cpp +++ b/src/gui/util/qcompleter.cpp @@ -1582,6 +1582,10 @@ QString QCompleter::currentCompletion() const that contains all the possible matches for the current completion prefix. The completion model is auto-updated to reflect the current completions. + \note The return value of this function is defined to be an QAbstractItemModel + purely for generality. This actual kind of model returned is an instance of an + QAbstractProxyModel subclass. + \sa completionPrefix, model() */ QAbstractItemModel *QCompleter::completionModel() const -- cgit v0.12 From 9dc1fc2d30205bb0bad12df4d3cb061f55f4f3f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Thu, 25 Jun 2009 16:42:10 +0200 Subject: Compile tst_QGrahicsSceneIndex after be79229e --- .../auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp index d10f86d..ac21e20 100644 --- a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp +++ b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp @@ -56,8 +56,6 @@ public slots: void initTestCase(); private slots: - void sceneRect_data(); - void sceneRect(); void customIndex_data(); void customIndex(); void scatteredItems_data(); @@ -97,19 +95,6 @@ QGraphicsSceneIndex *tst_QGraphicsSceneIndex::createIndex(const QString &indexMe return index; } -void tst_QGraphicsSceneIndex::sceneRect_data() -{ - common_data(); -} - -void tst_QGraphicsSceneIndex::sceneRect() -{ - QGraphicsScene *scene = new QGraphicsScene(); - QGraphicsSceneIndex *index = new QGraphicsSceneBspTreeIndex(scene); - scene->setSceneRect(QRectF(0, 0, 2000, 2000)); - QCOMPARE(index->indexedRect(), QRectF(0, 0, 2000, 2000)); -} - void tst_QGraphicsSceneIndex::customIndex_data() { common_data(); -- cgit v0.12 From eab949e2ec8f820a54826c1a837c8c8de07814ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Thu, 25 Jun 2009 11:31:04 +0200 Subject: Re-factor parts of the QGraphicsSceneBspTreeIndex. This patch adds better support for untransformable items and removes some redundant code. --- src/gui/graphicsview/qgraphicsscene.cpp | 22 +- .../graphicsview/qgraphicsscenebsptreeindex.cpp | 282 +++++++++------------ .../graphicsview/qgraphicsscenebsptreeindex_p.h | 6 +- 3 files changed, 133 insertions(+), 177 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 06a251e..6efede2 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1954,25 +1954,13 @@ void QGraphicsScene::clearSelection() void QGraphicsScene::clear() { Q_D(QGraphicsScene); - QList items = d->index->items(); -#if 1 - QList toDelete; - // ### As the item list is already in ascending order, - // the items should be deleted in topological order. - // Recursive descent delete - for (int i = 0; i < items.size(); ++i) { - if (QGraphicsItem *item = items.at(i)) { - if (!item->parentItem()) - toDelete << item; - } - } - // We delete all top level items - qDeleteAll(toDelete); -#else + // NB! We have to clear the index before deleting items; otherwise the + // index might try to access dangling item pointers. + d->index->clear(); + const QList items = d->topLevelItems; qDeleteAll(items); -#endif + Q_ASSERT(d->topLevelItems.isEmpty()); d->lastItemCount = 0; - d->index->clear(); d->allItemsIgnoreHoverEvents = true; d->allItemsUseDefaultCursor = true; } diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 8861c7b..f6994f9 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -128,10 +128,9 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() purgeRemovedItems(); // Add unindexedItems to indexedItems - QRectF unindexedItemsBoundingRect; for (int i = 0; i < unindexedItems.size(); ++i) { if (QGraphicsItem *item = unindexedItems.at(i)) { - unindexedItemsBoundingRect |= item->sceneBoundingRect(); + item->d_ptr->itemDiscovered = 0; if (!freeItemIndexes.isEmpty()) { int freeIndex = freeItemIndexes.takeFirst(); item->d_func()->index = freeIndex; @@ -165,11 +164,14 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() // Insert all unindexed items into the tree. for (int i = 0; i < unindexedItems.size(); ++i) { if (QGraphicsItem *item = unindexedItems.at(i)) { - QRectF rect = item->sceneBoundingRect(); + if (item->d_ptr->itemIsUntransformable()) { + untransformableItems << item; + continue; + } if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) continue; - bsp.insertItem(item, rect); + bsp.insertItem(item, item->sceneBoundingRect()); } } unindexedItems.clear(); @@ -222,11 +224,13 @@ void QGraphicsSceneBspTreeIndexPrivate::resetIndex() for (int i = 0; i < indexedItems.size(); ++i) { if (QGraphicsItem *item = indexedItems.at(i)) { item->d_ptr->index = -1; + item->d_ptr->itemDiscovered = 0; unindexedItems << item; } } indexedItems.clear(); freeItemIndexes.clear(); + untransformableItems.clear(); regenerateIndex = true; startIndexTimer(); } @@ -270,10 +274,10 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateSortCache() int stackingOrder = 0; QList topLevels; - - for (int i = 0; i < q->items().count(); ++i) { - QGraphicsItem *item = q->items().at(i); - if (item && item->parentItem() == 0) + const QList items = q->items(); + for (int i = 0; i < items.size(); ++i) { + QGraphicsItem *item = items.at(i); + if (item && !item->d_ptr->parent) topLevels << item; } @@ -295,6 +299,79 @@ void QGraphicsSceneBspTreeIndexPrivate::invalidateSortCache() QMetaObject::invokeMethod(q, "_q_updateSortCache", Qt::QueuedConnection); } +void QGraphicsSceneBspTreeIndexPrivate::addItem(QGraphicsItem *item, bool recursive) +{ + if (!item) + return; + + // Prevent reusing a recently deleted pointer: purge all removed item from our lists. + purgeRemovedItems(); + + // Invalidate any sort caching; arrival of a new item means we need to resort. + // Update the scene's sort cache settings. + item->d_ptr->globalStackingOrder = -1; + invalidateSortCache(); + + // Indexing requires sceneBoundingRect(), but because \a item might + // not be completely constructed at this point, we need to store it in + // a temporary list and schedule an indexing for later. + if (item->d_ptr->index == -1) { + Q_ASSERT(!unindexedItems.contains(item)); + unindexedItems << item; + startIndexTimer(0); + } else { + Q_ASSERT(indexedItems.contains(item)); + qWarning("QGraphicsSceneBspTreeIndex::addItem: item has already been added to this BSP"); + } + + if (recursive) { + for (int i = 0; i < item->d_ptr->children.size(); ++i) + addItem(item->d_ptr->children.at(i), recursive); + } +} + +void QGraphicsSceneBspTreeIndexPrivate::removeItem(QGraphicsItem *item, bool recursive, + bool moveToUnindexedItems) +{ + if (!item) + return; + + if (item->d_ptr->index != -1) { + Q_ASSERT(item->d_ptr->index < indexedItems.size()); + Q_ASSERT(indexedItems.at(item->d_ptr->index) == item); + freeItemIndexes << item->d_ptr->index; + indexedItems[item->d_ptr->index] = 0; + item->d_ptr->index = -1; + item->d_ptr->itemDiscovered = 0; + + if (item->d_ptr->itemIsUntransformable()) { + untransformableItems.removeOne(item); + } else if (item->d_ptr->inDestructor) { + // Avoid virtual function calls from the destructor. + purgePending = true; + removedItems << item; + } else if (!item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { + bsp.removeItem(item, item->sceneBoundingRect()); + } + } else { + unindexedItems.removeOne(item); + } + invalidateSortCache(); // ### Only do this when removing from BSP? + + Q_ASSERT(item->d_ptr->index == -1); + Q_ASSERT(!indexedItems.contains(item)); + Q_ASSERT(!unindexedItems.contains(item)); + Q_ASSERT(!untransformableItems.contains(item)); + + if (moveToUnindexedItems) + addItem(item); + + if (recursive) { + for (int i = 0; i < item->d_ptr->children.size(); ++i) + removeItem(item->d_ptr->children.at(i), recursive, moveToUnindexedItems); + } +} + /*! Returns true if \a item1 is on top of \a item2. @@ -401,8 +478,16 @@ void QGraphicsSceneBspTreeIndex::clear() d->bsp.clear(); d->lastItemCount = 0; d->freeItemIndexes.clear(); + for (int i = 0; i < d->indexedItems.size(); ++i) { + // Ensure item bits are reset properly. + if (QGraphicsItem *item = d->indexedItems.at(i)) { + item->d_ptr->index = -1; + item->d_ptr->itemDiscovered = 0; + } + } d->indexedItems.clear(); d->unindexedItems.clear(); + d->untransformableItems.clear(); } /*! @@ -411,46 +496,7 @@ void QGraphicsSceneBspTreeIndex::clear() void QGraphicsSceneBspTreeIndex::addItem(QGraphicsItem *item) { Q_D(QGraphicsSceneBspTreeIndex); - // Prevent reusing a recently deleted pointer: purge all removed items - // from our lists. - d->purgeRemovedItems(); - - // Invalidate any sort caching; arrival of a new item means we need to - // resort. - // Update the scene's sort cache settings. - item->d_ptr->globalStackingOrder = -1; - d->invalidateSortCache(); - - // Indexing requires sceneBoundingRect(), but because \a item might - // not be completely constructed at this point, we need to store it in - // a temporary list and schedule an indexing for later. - item->d_ptr->index = -1; - if (item->d_ptr->itemIsUntransformable()) { - d->untransformableItems << item; - } else { - d->unindexedItems << item; - d->startIndexTimer(0); - } -} - -/*! - This really add the item in the BSP. - \internal -*/ -void QGraphicsSceneBspTreeIndexPrivate::addToBspTree(QGraphicsItem *item) -{ - if (item->d_ptr->itemIsUntransformable()) - return; - if (item->d_func()->index != -1) { - bsp.insertItem(item, item->sceneBoundingRect()); - foreach (QGraphicsItem *child, item->children()) - child->addToIndex(); - } else { - // The BSP tree is regenerated if the number of items grows to a - // certain threshold, or if the bounding rect of the graph doubles in - // size. - startIndexTimer(); - } + d->addItem(item); } /*! @@ -459,105 +505,28 @@ void QGraphicsSceneBspTreeIndexPrivate::addToBspTree(QGraphicsItem *item) void QGraphicsSceneBspTreeIndex::removeItem(QGraphicsItem *item) { Q_D(QGraphicsSceneBspTreeIndex); - - // Note: This will access item's sceneBoundingRect(), which (as this is - // C++) is why we cannot call removeItem() from QGraphicsItem's - // destructor. - d->removeFromBspTree(item); - - // Invalidate any sort caching; arrival of a new item means we need to - // resort. - d->invalidateSortCache(); - - // Remove from our item lists. - int index = item->d_func()->index; - if (index != -1) { - d->freeItemIndexes << index; - d->indexedItems[index] = 0; - } else { - if (item->d_ptr->itemIsUntransformable()) - d->untransformableItems.removeOne(item); - else - d->unindexedItems.removeOne(item); - } + d->removeItem(item); } /*! \reimp - Delete the \a item from the BSP index (without accessing its boundingRect). -*/ -void QGraphicsSceneBspTreeIndex::deleteItem(QGraphicsItem *item) -{ - Q_D(QGraphicsSceneBspTreeIndex); - // Invalidate any sort caching; arrival of a new item means we need to - // resort. - d->invalidateSortCache(); - - int index = item->d_func()->index; - if (index != -1) { - // Important: The index is useless until purgeRemovedItems() is - // called. - d->indexedItems[index] = (QGraphicsItem *)0; - if (!d->purgePending) { - d->purgePending = true; - scene()->update(); - } - d->removedItems << item; - } else { - // Recently added items are purged immediately. unindexedItems() never - // contains stale items. - if (item->d_ptr->itemIsUntransformable()) - d->untransformableItems.removeOne(item); - else - d->unindexedItems.removeOne(item); - scene()->update(); - } -} - -/*! - Really remove the item from the BSP - \internal + Update the BSP when the \a item 's bounding rect has changed. */ -void QGraphicsSceneBspTreeIndexPrivate::removeFromBspTree(QGraphicsItem *item) +void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem *item) { - if (item->d_ptr->itemIsUntransformable()) + if (!item) return; - if (item->d_func()->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { - // ### remove from child index only if applicable - return; + if (item->d_ptr->index == -1 || item->d_ptr->itemIsUntransformable() + || item->d_func()->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { + return; // Item is not in BSP tree; nothing to do. } - if (item->d_func()->index != -1) { - bsp.removeItem(item, item->sceneBoundingRect()); - //prepareGeometryChange will call prepareBoundingRectChange - foreach (QGraphicsItem *child, item->children()) - child->prepareGeometryChange(); - } - startIndexTimer(); -} - -/*! - \reimp - Update the BSP when the \a item 's bounding rect has changed. -*/ -void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem *item) -{ Q_D(QGraphicsSceneBspTreeIndex); - if (!item->d_ptr->itemIsUntransformable()) { - // Note: This will access item's sceneBoundingRect(), which (as this is - // C++) is why we cannot call removeItem() from QGraphicsItem's - // destructor. - QGraphicsItem *thatItem = const_cast(item); - d->removeFromBspTree(thatItem); - int index = item->d_func()->index; - if (index != -1) { - d->freeItemIndexes << index; - d->indexedItems[index] = 0; - thatItem->d_func()->index = -1; - d->unindexedItems << thatItem; - } - } + QGraphicsItem *thatItem = const_cast(item); + d->removeItem(thatItem, /*recursive=*/false, /*moveToUnindexedItems=*/true); + for (int i = 0; i < item->d_ptr->children.size(); ++i) // ### Do we really need this? + prepareBoundingRectChange(item->d_ptr->children.at(i)); } /*! @@ -706,18 +675,17 @@ void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphics switch (change) { case QGraphicsItem::ItemFlagsChange: { // Handle ItemIgnoresTransformations - bool ignoredTransform = item->flags() & QGraphicsItem::ItemIgnoresTransformations; + bool ignoredTransform = item->d_ptr->flags & QGraphicsItem::ItemIgnoresTransformations; bool willIgnoreTransform = value.toUInt() & QGraphicsItem::ItemIgnoresTransformations; - if (ignoredTransform != willIgnoreTransform) { + bool clipsChildren = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape; + bool willClipChildren = value.toUInt() & QGraphicsItem::ItemClipsChildrenToShape; + if ((ignoredTransform != willIgnoreTransform) || (clipsChildren != willClipChildren)) { QGraphicsItem *thatItem = const_cast(item); - removeItem(thatItem); - thatItem->d_ptr->index = -1; - if (willIgnoreTransform) { - d->untransformableItems << thatItem; - } else { - d->unindexedItems << thatItem; - d->startIndexTimer(0); - } + // Remove item and its descendants from the index and append + // them to the list of unindexed items. Then, when the index + // is updated, they will be put into the bsp-tree or the list + // of untransformable items. + d->removeItem(thatItem, /*recursive=*/true, /*moveToUnidexedItems=*/true); } break; } @@ -729,17 +697,19 @@ void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphics // Handle ItemIgnoresTransformations QGraphicsItem *newParent = qVariantValue(value); bool ignoredTransform = item->d_ptr->itemIsUntransformable(); - bool willIgnoreTransform = (item->flags() & QGraphicsItem::ItemIgnoresTransformations) || (newParent && newParent->d_ptr->itemIsUntransformable()); - if (ignoredTransform != willIgnoreTransform) { + bool willIgnoreTransform = (item->d_ptr->flags & QGraphicsItem::ItemIgnoresTransformations) + || (newParent && newParent->d_ptr->itemIsUntransformable()); + bool ancestorClippedChildren = item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren; + bool ancestorWillClipChildren = newParent + && ((newParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape) + || (newParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)); + if ((ignoredTransform != willIgnoreTransform) || (ancestorClippedChildren != ancestorWillClipChildren)) { QGraphicsItem *thatItem = const_cast(item); - removeItem(thatItem); - thatItem->d_ptr->index = -1; - if (willIgnoreTransform) { - d->untransformableItems << thatItem; - } else { - d->unindexedItems << thatItem; - d->startIndexTimer(0); - } + // Remove item and its descendants from the index and append + // them to the list of unindexed items. Then, when the index + // is updated, they will be put into the bsp-tree or the list + // of untransformable items. + d->removeItem(thatItem, /*recursive=*/true, /*moveToUnidexedItems=*/true); } break; } diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 715b22f..f2f958f 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -96,7 +96,6 @@ protected: void addItem(QGraphicsItem *item); void removeItem(QGraphicsItem *item); - void deleteItem(QGraphicsItem *item); void prepareBoundingRectChange(const QGraphicsItem *item); void sceneRectChanged(); @@ -139,13 +138,12 @@ public: void startIndexTimer(int interval = QGRAPHICSSCENE_INDEXTIMER_TIMEOUT); void resetIndex(); - void addToBspTree(QGraphicsItem *item); - void removeFromBspTree(QGraphicsItem *item); - void _q_updateSortCache(); bool sortCacheEnabled; bool updatingSortCache; void invalidateSortCache(); + void addItem(QGraphicsItem *item, bool recursive = false); + void removeItem(QGraphicsItem *item, bool recursive = false, bool moveToUnindexedItems = false); static void climbTree(QGraphicsItem *item, int *stackingOrder); static bool closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2); -- cgit v0.12 From 7541247a025bf112716a752bc4d114303f2a77f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Fri, 26 Jun 2009 15:54:04 +0200 Subject: Proper handling of scene rect in QGraphicsScene(Index). Reviewed-by: Andreas --- src/gui/graphicsview/qgraphicsitem.cpp | 1 + src/gui/graphicsview/qgraphicsitem_p.h | 2 +- src/gui/graphicsview/qgraphicsscene.cpp | 65 +++++++++------------- src/gui/graphicsview/qgraphicsscene.h | 1 - src/gui/graphicsview/qgraphicsscene_p.h | 1 - .../graphicsview/qgraphicsscenebsptreeindex.cpp | 4 +- .../graphicsview/qgraphicsscenebsptreeindex_p.h | 4 +- src/gui/graphicsview/qgraphicssceneindex.cpp | 25 ++++++--- src/gui/graphicsview/qgraphicssceneindex_p.h | 4 +- src/gui/graphicsview/qgraphicsscenelinearindex.cpp | 6 -- 10 files changed, 52 insertions(+), 61 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 7393f00..e9d1076 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -6322,6 +6322,7 @@ void QGraphicsItem::removeFromIndex() void QGraphicsItem::prepareGeometryChange() { if (d_ptr->scene) { + d_ptr->scene->d_func()->dirtyGrowingItemsBoundingRect = true; d_ptr->geometryChanged = 1; d_ptr->paintedViewBoundingRectsNeedRepaint = 1; diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 1dfb140..243582a 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -148,7 +148,7 @@ public: dirtyChildrenBoundingRect(1), paintedViewBoundingRectsNeedRepaint(0), dirtySceneTransform(1), - geometryChanged(0), + geometryChanged(1), inDestructor(0), isObject(0), ignoreVisible(0), diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 6efede2..de6f5c4 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -326,6 +326,16 @@ void QGraphicsScenePrivate::_q_emitUpdated() Q_Q(QGraphicsScene); calledEmitUpdated = false; + if (dirtyGrowingItemsBoundingRect) { + if (!hasSceneRect) { + const QRectF oldGrowingItemsBoundingRect = growingItemsBoundingRect; + growingItemsBoundingRect |= q->itemsBoundingRect(); + if (oldGrowingItemsBoundingRect != growingItemsBoundingRect) + emit q->sceneRectChanged(growingItemsBoundingRect); + } + dirtyGrowingItemsBoundingRect = false; + } + // Ensure all views are connected if anything is connected. This disables // the optimization that items send updates directly to the views, but it // needs to happen in order to keep compatibility with the behavior from @@ -373,20 +383,6 @@ void QGraphicsScenePrivate::unregisterTopLevelItem(QGraphicsItem *item) /*! \internal - - Updates all items in the pending update list. At this point, the list is - unlikely to contain partially constructed items. -*/ -void QGraphicsScenePrivate::_q_updateLater() -{ - QRectF null; - foreach (QGraphicsItem *item, pendingUpdateItems) - markDirty(item, null); - pendingUpdateItems.clear(); -} - -/*! - \internal */ void QGraphicsScenePrivate::_q_polishItems() { @@ -412,10 +408,8 @@ void QGraphicsScenePrivate::_q_processDirtyItems() const QRectF oldGrowingItemsBoundingRect = growingItemsBoundingRect; processDirtyItemsRecursive(0); dirtyGrowingItemsBoundingRect = false; - if (oldGrowingItemsBoundingRect != growingItemsBoundingRect) { - index->sceneRectChanged(); + if (!hasSceneRect && oldGrowingItemsBoundingRect != growingItemsBoundingRect) emit q_func()->sceneRectChanged(growingItemsBoundingRect); - } if (wasPendingSceneUpdate) return; @@ -507,7 +501,6 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) hoverItems.removeAll(item); cachedItemsUnderMouse.removeAll(item); unpolishedItems.removeAll(item); - pendingUpdateItems.removeAll(item); resetDirtyItem(item); //We remove all references of item from the sceneEventFilter arrays @@ -1303,18 +1296,19 @@ QGraphicsScene::~QGraphicsScene() QRectF QGraphicsScene::sceneRect() const { Q_D(const QGraphicsScene); - if (!d->hasSceneRect && d->dirtyGrowingItemsBoundingRect) { + if (d->hasSceneRect) + return d->sceneRect; + + if (d->dirtyGrowingItemsBoundingRect) { // Lazily update the growing items bounding rect QGraphicsScenePrivate *thatd = const_cast(d); QRectF oldGrowingBoundingRect = thatd->growingItemsBoundingRect; thatd->growingItemsBoundingRect |= itemsBoundingRect(); thatd->dirtyGrowingItemsBoundingRect = false; - if (oldGrowingBoundingRect != thatd->growingItemsBoundingRect) { - thatd->index->sceneRectChanged(); + if (oldGrowingBoundingRect != thatd->growingItemsBoundingRect) emit const_cast(this)->sceneRectChanged(thatd->growingItemsBoundingRect); - } } - return d->hasSceneRect ? d->sceneRect : d->growingItemsBoundingRect; + return d->growingItemsBoundingRect; } void QGraphicsScene::setSceneRect(const QRectF &rect) { @@ -1322,7 +1316,6 @@ void QGraphicsScene::setSceneRect(const QRectF &rect) if (rect != d->sceneRect) { d->hasSceneRect = !rect.isNull(); d->sceneRect = rect; - d->index->sceneRectChanged(); emit sceneRectChanged(d->hasSceneRect ? rect : d->growingItemsBoundingRect); } } @@ -2101,13 +2094,8 @@ void QGraphicsScene::addItem(QGraphicsItem *item) // Add to list of items that require an update. We cannot assume that the // item is fully constructed, so calling item->update() can lead to a pure // virtual function call to boundingRect(). - if (!d->updateAll) { - if (d->pendingUpdateItems.isEmpty()) - QMetaObject::invokeMethod(this, "_q_updateLater", Qt::QueuedConnection); - d->pendingUpdateItems << item; - } else { - d->dirtyGrowingItemsBoundingRect = true; - } + d->markDirty(item); + d->dirtyGrowingItemsBoundingRect = true; // Disable selectionChanged() for individual items ++d->selectionChanging; @@ -4245,7 +4233,6 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b bool removingItemFromScene) { Q_ASSERT(item); - dirtyGrowingItemsBoundingRect = true; if (updateAll) return; @@ -4351,6 +4338,13 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool item->d_ptr->dirty = 0; item->d_ptr->paintedViewBoundingRectsNeedRepaint = 0; } + + if (item->d_ptr->geometryChanged) { + // Update growingItemsBoundingRect. + if (!hasSceneRect && !itemIsHidden) + growingItemsBoundingRect |= item->d_ptr->sceneTransform.mapRect(item->boundingRect()); + item->d_ptr->geometryChanged = 0; + } } // Process item. @@ -4359,13 +4353,6 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool const bool untransformableItem = item->d_ptr->itemIsUntransformable(); const QRectF itemBoundingRect = adjustedItemBoundingRect(item); - if (item->d_ptr->geometryChanged) { - // Update growingItemsBoundingRect. - if (!hasSceneRect) - growingItemsBoundingRect |= item->d_ptr->sceneTransform.mapRect(itemBoundingRect); - item->d_ptr->geometryChanged = 0; - } - if (useCompatUpdate && !untransformableItem && qFuzzyIsNull(item->boundingRegionGranularity())) { // This block of code is kept for compatibility. Since 4.5, by default // QGraphicsView does not connect the signal and we use the below diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h index 421adbd..560671a 100644 --- a/src/gui/graphicsview/qgraphicsscene.h +++ b/src/gui/graphicsview/qgraphicsscene.h @@ -291,7 +291,6 @@ private: Q_DECLARE_PRIVATE(QGraphicsScene) Q_DISABLE_COPY(QGraphicsScene) Q_PRIVATE_SLOT(d_func(), void _q_emitUpdated()) - Q_PRIVATE_SLOT(d_func(), void _q_updateLater()) Q_PRIVATE_SLOT(d_func(), void _q_polishItems()) Q_PRIVATE_SLOT(d_func(), void _q_processDirtyItems()) friend class QGraphicsItem; diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 36a7e63..f286a8d 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -107,7 +107,6 @@ public: QPainterPath selectionArea; int selectionChanging; QSet selectedItems; - QList pendingUpdateItems; QList unpolishedItems; QList topLevelItems; bool needSortTopLevelItems; diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index f6994f9..3efc742 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -655,10 +655,10 @@ void QGraphicsSceneBspTreeIndex::setBspTreeDepth(int depth) This method react to the \a rect change of the scene and reset the BSP tree index. */ -void QGraphicsSceneBspTreeIndex::sceneRectChanged() +void QGraphicsSceneBspTreeIndex::updateSceneRect(const QRectF &rect) { Q_D(QGraphicsSceneBspTreeIndex); - d->sceneRect = d->scene->sceneRect(); + d->sceneRect = rect; d->resetIndex(); } diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index f2f958f..850cc3f 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -90,6 +90,9 @@ public: int bspTreeDepth(); void setBspTreeDepth(int depth); +protected Q_SLOTS: + void updateSceneRect(const QRectF &rect); + protected: bool event(QEvent *event); void clear(); @@ -98,7 +101,6 @@ protected: void removeItem(QGraphicsItem *item); void prepareBoundingRectChange(const QGraphicsItem *item); - void sceneRectChanged(); void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value); private : diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 4eaed2b..88fb6b0 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -335,6 +335,10 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe QGraphicsSceneIndex::QGraphicsSceneIndex(QGraphicsScene *scene) : QObject(*new QGraphicsSceneIndexPrivate(scene), scene) { + if (scene) { + connect(scene, SIGNAL(sceneRectChanged(const QRectF&)), + this, SLOT(updateSceneRect(const QRectF&))); + } } /*! @@ -527,6 +531,18 @@ QList QGraphicsSceneIndex::estimateItems(const QPointF &point, \a order. */ + +/*! + Notifies the index that the scene's scene rect has changed. \a rect + is thew new scene rect. + + \sa QGraphicsScene::sceneRect() +*/ +void QGraphicsSceneIndex::updateSceneRect(const QRectF &rect) +{ + Q_UNUSED(rect); +} + /*! This virtual function removes all items in the scene index. */ @@ -596,15 +612,6 @@ void QGraphicsSceneIndex::prepareBoundingRectChange(const QGraphicsItem *item) Q_UNUSED(item); } -/*! - This virtual function is called when the scene changes its bounding - rectangle. \a rect is the new value of the scene rectangle. - \sa QGraphicsScene::sceneRect() -*/ -void QGraphicsSceneIndex::sceneRectChanged() -{ -} - QT_END_NAMESPACE #include "moc_qgraphicssceneindex_p.cpp" diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index 60e9032..dc6a740 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -101,6 +101,9 @@ public: virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const = 0; +protected Q_SLOTS: + virtual void updateSceneRect(const QRectF &rect); + protected: virtual void clear(); virtual void addItem(QGraphicsItem *item) = 0; @@ -109,7 +112,6 @@ protected: virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value); virtual void prepareBoundingRectChange(const QGraphicsItem *item); - virtual void sceneRectChanged(); QGraphicsSceneIndex(QObjectPrivate &dd, QGraphicsScene *scene); diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex.cpp b/src/gui/graphicsview/qgraphicsscenelinearindex.cpp index 694062b..bc401f2 100644 --- a/src/gui/graphicsview/qgraphicsscenelinearindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenelinearindex.cpp @@ -46,12 +46,6 @@ */ /*! - \fn void QGraphicsSceneLinearIndex::sceneRectChanged(const QRectF &rect); - \reimp - This method react to the \a rect change of the scene. -*/ - -/*! \fn void QGraphicsSceneLinearIndex::clear(); \reimp Clear the all the BSP index. -- cgit v0.12 From eff4c4b4172d1a95b1b5806622b4e7fe43c2b006 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Fri, 26 Jun 2009 16:32:27 +0200 Subject: Fix broken point item lookup in Graphics View. Done with Andreas. --- src/gui/graphicsview/qgraphicsscene.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index de6f5c4..7c46598 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -770,11 +770,22 @@ QList QGraphicsScenePrivate::itemsAtPosition(const QPoint &scre const QPointF &scenePos, QWidget *widget) const { - Q_UNUSED(screenPos); Q_Q(const QGraphicsScene); QGraphicsView *view = widget ? qobject_cast(widget->parentWidget()) : 0; - return q->items(scenePos, Qt::IntersectsItemShape, Qt::AscendingOrder, - view ? view->viewportTransform() : QTransform()); + if (!view) + return q->items(scenePos, Qt::IntersectsItemShape, Qt::AscendingOrder, QTransform()); + + const QRectF pointRect(QPointF(widget->mapFromGlobal(screenPos)), QSizeF(1, 1)); + if (!view->isTransformed()) + return q->items(pointRect, Qt::IntersectsItemShape, Qt::AscendingOrder); + + const QTransform viewTransform = view->viewportTransform(); + if (viewTransform.type() <= QTransform::TxScale) { + return q->items(viewTransform.inverted().mapRect(pointRect), Qt::IntersectsItemShape, + Qt::AscendingOrder, viewTransform); + } + return q->items(viewTransform.inverted().map(pointRect), Qt::IntersectsItemShape, + Qt::AscendingOrder, viewTransform); } /*! -- cgit v0.12 From 7fe4f8ff71cf09bbabbd3438ef637fe408a11c33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Mon, 29 Jun 2009 15:33:30 +0200 Subject: Graphics View: BSP tree cleanup. Ensure the BSP resets the QGraphicsItemPrivate::itemDiscovered bit before returning the list of discovered items. --- src/gui/graphicsview/qgraphicsitem.h | 1 + src/gui/graphicsview/qgraphicsscene.cpp | 7 +++++-- src/gui/graphicsview/qgraphicsscene_bsp.cpp | 11 ++++++++--- src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp | 21 ++++++++------------- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index 12dcad2..48fb5c3 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -434,6 +434,7 @@ private: friend class QGraphicsScene; friend class QGraphicsScenePrivate; friend class QGraphicsSceneFindItemBspTreeVisitor; + friend class QGraphicsSceneBspTree; friend class QGraphicsView; friend class QGraphicsViewPrivate; friend class QGraphicsWidget; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 7c46598..f1e56c1 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1097,8 +1097,11 @@ QList QGraphicsScenePrivate::topLevelItemsInStackingOrder(const QList tmp = index->estimateItems(sceneRect, Qt::SortOrder(-1), viewTransform ? *viewTransform : QTransform()); - for (int i = 0; i < tmp.size(); ++i) - tmp.at(i)->topLevelItem()->d_ptr->itemDiscovered = 1; + for (int i = 0; i < tmp.size(); ++i) { + QGraphicsItem *item = tmp.at(i); + if (!item->d_ptr->parent) + item->d_ptr->itemDiscovered = 1; + } // Sort if the toplevel list is unsorted. if (needSortTopLevelItems) { diff --git a/src/gui/graphicsview/qgraphicsscene_bsp.cpp b/src/gui/graphicsview/qgraphicsscene_bsp.cpp index eaeec54..5858eab 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp.cpp +++ b/src/gui/graphicsview/qgraphicsscene_bsp.cpp @@ -148,6 +148,9 @@ QList QGraphicsSceneBspTree::items(const QRectF &rect) const QList tmp; findVisitor->foundItems = &tmp; climbTree(findVisitor, rect); + // Reset discovery bits. + for (int i = 0; i < tmp.size(); ++i) + tmp.at(i)->d_ptr->itemDiscovered = 0; return tmp; } @@ -156,6 +159,9 @@ QList QGraphicsSceneBspTree::items(const QPointF &pos) const QList tmp; findVisitor->foundItems = &tmp; climbTree(findVisitor, pos); + // Reset discovery bits. + for (int i = 0; i < tmp.size(); ++i) + tmp.at(i)->d_ptr->itemDiscovered = 0; return tmp; } @@ -241,7 +247,7 @@ void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, con return; const Node &node = nodes.at(index); - int childIndex = firstChildIndex(index); + const int childIndex = firstChildIndex(index); switch (node.type) { case Node::Leaf: { @@ -271,7 +277,7 @@ void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, con return; const Node &node = nodes.at(index); - int childIndex = firstChildIndex(index); + const int childIndex = firstChildIndex(index); switch (node.type) { case Node::Leaf: { @@ -288,7 +294,6 @@ void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, con } break; case Node::Horizontal: - int childIndex = firstChildIndex(index); if (rect.top() < node.offset) { climbTree(visitor, rect, childIndex); if (rect.bottom() >= node.offset) diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 3efc742..44a0082 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -130,7 +130,7 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() // Add unindexedItems to indexedItems for (int i = 0; i < unindexedItems.size(); ++i) { if (QGraphicsItem *item = unindexedItems.at(i)) { - item->d_ptr->itemDiscovered = 0; + Q_ASSERT(!item->d_ptr->itemDiscovered); if (!freeItemIndexes.isEmpty()) { int freeIndex = freeItemIndexes.takeFirst(); item->d_func()->index = freeIndex; @@ -224,7 +224,7 @@ void QGraphicsSceneBspTreeIndexPrivate::resetIndex() for (int i = 0; i < indexedItems.size(); ++i) { if (QGraphicsItem *item = indexedItems.at(i)) { item->d_ptr->index = -1; - item->d_ptr->itemDiscovered = 0; + Q_ASSERT(!item->d_ptr->itemDiscovered); unindexedItems << item; } } @@ -339,10 +339,10 @@ void QGraphicsSceneBspTreeIndexPrivate::removeItem(QGraphicsItem *item, bool rec if (item->d_ptr->index != -1) { Q_ASSERT(item->d_ptr->index < indexedItems.size()); Q_ASSERT(indexedItems.at(item->d_ptr->index) == item); + Q_ASSERT(!item->d_ptr->itemDiscovered); freeItemIndexes << item->d_ptr->index; indexedItems[item->d_ptr->index] = 0; item->d_ptr->index = -1; - item->d_ptr->itemDiscovered = 0; if (item->d_ptr->itemIsUntransformable()) { untransformableItems.removeOne(item); @@ -481,8 +481,8 @@ void QGraphicsSceneBspTreeIndex::clear() for (int i = 0; i < d->indexedItems.size(); ++i) { // Ensure item bits are reset properly. if (QGraphicsItem *item = d->indexedItems.at(i)) { + Q_ASSERT(!item->d_ptr->itemDiscovered); item->d_ptr->index = -1; - item->d_ptr->itemDiscovered = 0; } } d->indexedItems.clear(); @@ -547,25 +547,20 @@ QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &r Q_UNUSED(deviceTransform); QList rectItems = d->bsp.items(rect); + // Fill in with any unindexed items for (int i = 0; i < d->unindexedItems.size(); ++i) { if (QGraphicsItem *item = d->unindexedItems.at(i)) { - if (!item->d_ptr->itemDiscovered && item->d_ptr->visible && !(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { + if (item->d_ptr->visible + && !(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { QRectF boundingRect = item->sceneBoundingRect(); - if (QRectF_intersects(boundingRect, rect)) { - item->d_ptr->itemDiscovered = 1; + if (QRectF_intersects(boundingRect, rect)) rectItems << item; - } } } } - // Reset the discovered state of all discovered items - for (int i = 0; i < rectItems.size(); ++i) - rectItems.at(i)->d_func()->itemDiscovered = 0; - rectItems += d->untransformableItems; - d->sortItems(&rectItems, order, d->sortCacheEnabled); return rectItems; -- cgit v0.12 From 4dcb46a3796fbd9baf1ba6dcddcc9944e69e3153 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Mon, 29 Jun 2009 15:44:11 +0200 Subject: Add lacking parenthesis around bitwise AND operator. This caused a crash in the diagramscene example because "!bits & something" does not have the same meaning as "!(bits & something)", hence item was never removed from the BSP resulting in a stale item pointer. --- src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 44a0082..413c8de 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -350,7 +350,7 @@ void QGraphicsSceneBspTreeIndexPrivate::removeItem(QGraphicsItem *item, bool rec // Avoid virtual function calls from the destructor. purgePending = true; removedItems << item; - } else if (!item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { + } else if (!(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { bsp.removeItem(item, item->sceneBoundingRect()); } } else { @@ -518,7 +518,7 @@ void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem * return; if (item->d_ptr->index == -1 || item->d_ptr->itemIsUntransformable() - || item->d_func()->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { + || (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { return; // Item is not in BSP tree; nothing to do. } -- cgit v0.12 From 5c23c8e36d07410e53026c7ddd19f00f9984a6e7 Mon Sep 17 00:00:00 2001 From: Bill King Date: Tue, 30 Jun 2009 13:39:58 +1000 Subject: Fixes more DB autotests for testing against SQL Server --- tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp | 1 + tests/auto/qsqldatabase/tst_databases.h | 59 +++++++++++++++++++--------- tests/auto/qsqldatabase/tst_qsqldatabase.cpp | 4 +- 3 files changed, 44 insertions(+), 20 deletions(-) diff --git a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp index 2d89639..fa786f1 100644 --- a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp +++ b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp @@ -135,6 +135,7 @@ void tst_Q3SqlCursor::createTestTables( QSqlDatabase 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 ;) diff --git a/tests/auto/qsqldatabase/tst_databases.h b/tests/auto/qsqldatabase/tst_databases.h index b81182a..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 @@ -239,7 +239,7 @@ public: // use in-memory database to prevent local files // addDb("QSQLITE", ":memory:"); - addDb( "QSQLITE", QDir::toNativeSeparators(QDir::tempPath()+"/foo.db") ); + 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,20 +318,28 @@ 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(); + } } } @@ -343,19 +353,32 @@ public: 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); } } diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index f697488..23b1eb5 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -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,10 +355,9 @@ 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); - tst_Databases::safeDropView(db, qTableName("qtest_view")); } void tst_QSqlDatabase::populateTestTables(QSqlDatabase db) -- cgit v0.12 From 06303a608cd45395fde897f97e58cbfaadc32366 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 30 Jun 2009 09:21:46 +0200 Subject: fix column-spanning in Designer ConnectDialog's layout if showAllCheckBox's text is longer than 1/2 of dialog's width then dialog became asymmetric. Reviewed-by: Friedemann Kleint --- tools/designer/src/components/signalsloteditor/connectdialog.ui | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/designer/src/components/signalsloteditor/connectdialog.ui b/tools/designer/src/components/signalsloteditor/connectdialog.ui index bd062eb..568516a 100644 --- a/tools/designer/src/components/signalsloteditor/connectdialog.ui +++ b/tools/designer/src/components/signalsloteditor/connectdialog.ui @@ -13,7 +13,7 @@ Configure Connection - + GroupBox @@ -53,7 +53,7 @@ - + GroupBox @@ -93,14 +93,14 @@ - + Show signals and slots inherited from QWidget - + Qt::Horizontal -- cgit v0.12 From aa5def2013cb362ddcb8cd4233f37ef936fe0302 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 30 Jun 2009 10:59:22 +0200 Subject: Fixed QLayout to take the maxi/min size into account for the menu bar It was only taking the sizeHint into account Task-number: 141355 Reviewed-by: jasplin --- src/gui/kernel/qlayout.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qlayout.cpp b/src/gui/kernel/qlayout.cpp index 3a3feb2..e750088 100644 --- a/src/gui/kernel/qlayout.cpp +++ b/src/gui/kernel/qlayout.cpp @@ -61,7 +61,10 @@ static int menuBarHeightForWidth(QWidget *menubar, int w) int result = menubar->heightForWidth(qMax(w, menubar->minimumWidth())); if (result != -1) return result; - result = menubar->sizeHint().height(); + result = menubar->sizeHint() + .expandedTo(menubar->minimumSize()) + .expandedTo(menubar->minimumSizeHint()) + .boundedTo(menubar->maximumSize()).height(); if (result != -1) return result; } -- cgit v0.12 From 0a4930f7e0d324d9ec75e4fe8775b8acf21b4ce1 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 30 Jun 2009 11:05:44 +0200 Subject: QMenu: fixed a crash when clicking on a menu with a submenu --- src/gui/widgets/qmenu.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 56b8cb1..31df3f6 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -483,9 +483,9 @@ void QMenuPrivate::setSyncAction() void QMenuPrivate::setFirstActionActive() { Q_Q(QMenu); + updateActionRects(); const int scrollerHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q); for(int i = 0, saccum = 0; i < actions.count(); i++) { - QAction *act = actions.at(i); const QRect &rect = actionRects.at(i); if (rect.isNull()) continue; @@ -494,6 +494,7 @@ void QMenuPrivate::setFirstActionActive() if (saccum > scroll->scrollOffset-scrollerHeight) continue; } + QAction *act = actions.at(i); if (!act->isSeparator() && (q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q) || act->isEnabled())) { -- cgit v0.12 From 225aa3154d3c9940775254ed261d6dd8b9123c62 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 30 Jun 2009 11:13:24 +0200 Subject: QMenu: when we access the actions geometry, it's now always up2date --- src/gui/widgets/qmenu.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 31df3f6..d3f5bc5 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -667,6 +667,7 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc Q_Q(QMenu); if (!scroll || !scroll->scrollFlags) return; + updateActionRects(); int newOffset = 0; const int scrollHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q); const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollHeight : 0; @@ -769,6 +770,7 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc void QMenuPrivate::scrollMenu(QMenuScroller::ScrollLocation location, bool active) { Q_Q(QMenu); + updateActionRects(); if(location == QMenuScroller::ScrollBottom) { for(int i = actions.size()-1; i >= 0; --i) { QAction *act = actions.at(i); @@ -808,6 +810,7 @@ void QMenuPrivate::scrollMenu(QMenuScroller::ScrollDirection direction, bool pag Q_Q(QMenu); if (!scroll || !(scroll->scrollFlags & direction)) //not really possible... return; + updateActionRects(); const int scrollHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q); const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollHeight : 0; const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollHeight : 0; @@ -2059,6 +2062,7 @@ void QMenu::hideEvent(QHideEvent *) void QMenu::paintEvent(QPaintEvent *e) { Q_D(QMenu); + d->updateActionRects(); QPainter p(this); QRegion emptyArea = QRegion(rect()); @@ -2345,6 +2349,7 @@ bool QMenu::focusNextPrevChild(bool next) void QMenu::keyPressEvent(QKeyEvent *e) { Q_D(QMenu); + d->updateActionRects(); int key = e->key(); if (isRightToLeft()) { // in reverse mode open/close key for submenues are reversed if (key == Qt::Key_Left) -- cgit v0.12 From a823334a1b61f7a8cf73d96cbc4cd0f71bdc3df7 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 30 Jun 2009 11:20:20 +0200 Subject: QMenuBar: make sure to update the geometries when needed --- src/gui/widgets/qmenubar.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp index 7982d98..f4288ac 100644 --- a/src/gui/widgets/qmenubar.cpp +++ b/src/gui/widgets/qmenubar.cpp @@ -279,6 +279,7 @@ QRect QMenuBarPrivate::actionRect(QAction *act) const void QMenuBarPrivate::focusFirstAction() { if(!currentAction) { + updateGeometries(); int index = 0; while (index < actions.count() && actionRects.at(index).isNull()) ++index; if (index < actions.count()) @@ -757,6 +758,7 @@ void QMenuBarPrivate::init() QAction *QMenuBarPrivate::getNextAction(const int _start, const int increment) const { Q_Q(const QMenuBar); + const_cast(this)->updateGeometries(); bool allowActiveAndDisabled = q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q); const int start = (_start == -1 && increment == -1) ? actions.count() : _start; const int end = increment == -1 ? 0 : actions.count() - 1; @@ -1123,6 +1125,7 @@ void QMenuBar::mouseReleaseEvent(QMouseEvent *e) void QMenuBar::keyPressEvent(QKeyEvent *e) { Q_D(QMenuBar); + d->updateGeometries(); int key = e->key(); if(isRightToLeft()) { // in reverse mode open/close key for submenues are reversed if(key == Qt::Key_Left) @@ -1597,6 +1600,7 @@ QSize QMenuBar::minimumSizeHint() const ensurePolished(); QSize ret(0, 0); + const_cast(d)->updateGeometries(); const int hmargin = style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, this); const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, this); int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this); -- cgit v0.12 From 5a54b2c4c448ea22adb56bc191303abca34f230b Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Tue, 30 Jun 2009 12:11:32 +0200 Subject: qdoc: Added more handling of \reimp command Also fixed a few qdoc error reports. Task-number: 162182, 222650 --- src/gui/kernel/qevent.cpp | 33 +++++++++++++++++++++---------- tools/qdoc3/cppcodeparser.cpp | 3 ++- tools/qdoc3/generator.cpp | 42 +++++++++++++++++++++++----------------- tools/qdoc3/generator.h | 4 ++-- tools/qdoc3/javadocgenerator.cpp | 3 ++- tools/qdoc3/javadocgenerator.h | 2 +- tools/qdoc3/node.cpp | 12 ++++++++++++ tools/qdoc3/node.h | 4 ++++ 8 files changed, 70 insertions(+), 33 deletions(-) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 2467a62..e40ad9d 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -3647,12 +3647,13 @@ void QGestureEvent::acceptAll() } /*! - Sets the accept flag of the specified gesture inside the event - object, the equivalent of calling - \l{QGestureEvent::gesture()}{gesture(type)}->\l{QGesture::accept()}{accept()} + Sets the accept flag of the gesture specified by \a type. + This is equivalent to calling + \l{QGestureEvent::gesture()}{gesture(type)}-> + \l{QGesture::accept()}{accept()} - Setting the accept parameter indicates that the event receiver - wants the gesture. Unwanted gestures might be propagated to the parent + Setting the accept flag indicates that the event receiver wants + the gesture. Unwanted gestures might be propagated to the parent widget. */ void QGestureEvent::accept(Qt::GestureType type) @@ -3662,12 +3663,13 @@ void QGestureEvent::accept(Qt::GestureType type) } /*! - Sets the accept flag of the specified gesture inside the event - object, the equivalent of calling - \l{QGestureEvent::gesture()}{gesture(type)}->\l{QGesture::accept()}{accept()} + Sets the accept flag of the gesture specified by \a type. + This is equivalent to calling + \l{QGestureEvent::gesture()}{gesture(type)}-> + \l{QGesture::accept()}{accept()} - Setting the accept parameter indicates that the event receiver - wants the gesture. Unwanted gestures might be propagated to the parent + Setting the accept flag indicates that the event receiver wants + the gesture. Unwanted gestures might be propagated to the parent widget. */ void QGestureEvent::accept(const QString &type) @@ -4165,4 +4167,15 @@ QTouchEvent::TouchPoint &QTouchEvent::TouchPoint::operator=(const QTouchEvent::T return *this; } +/*! \fn QTouchEvent::DeviceType QTouchEvent::deviceType() const + Returns the touch device Type, which is of type + \l {QTouchEvent::DeviceType} {DeviceType}. + */ + +/*! \fn void QTouchEvent::setDeviceType(DeviceType deviceType) + Sets the device type to \a deviceType, which is of type + \l {QTouchEvent::DeviceType} {DeviceType}. + */ + + QT_END_NAMESPACE diff --git a/tools/qdoc3/cppcodeparser.cpp b/tools/qdoc3/cppcodeparser.cpp index 792190d..cb6caa9 100644 --- a/tools/qdoc3/cppcodeparser.cpp +++ b/tools/qdoc3/cppcodeparser.cpp @@ -743,7 +743,8 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc, // Reimplemented functions now reported in separate sections. func->setAccess(Node::Private); func->setStatus(Node::Internal); -#endif +#endif + func->setReimp(true); } else { doc.location().warning(tr("Ignored '\\%1' in %2") diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp index fa55b8a..7e10f3e 100644 --- a/tools/qdoc3/generator.cpp +++ b/tools/qdoc3/generator.cpp @@ -241,7 +241,7 @@ void Generator::generateFakeNode(const FakeNode * /* fake */, { } -void Generator::generateText(const Text& text, +bool Generator::generateText(const Text& text, const Node *relative, CodeMarker *marker) { @@ -254,31 +254,35 @@ void Generator::generateText(const Text& text, true, numAtoms); endText(relative, marker); + return true; } + return false; } #ifdef QDOC_QML -void Generator::generateQmlText(const Text& text, +bool Generator::generateQmlText(const Text& text, const Node *relative, CodeMarker *marker) { - if (text.firstAtom() != 0) { - startText(relative, marker); - const Atom *atom = text.firstAtom(); - while (atom) { - if (atom->type() != Atom::QmlText) - atom = atom->next(); - else { - atom = atom->next(); - while (atom && (atom->type() != Atom::EndQmlText)) { - int n = 1 + generateAtom(atom, relative, marker); - while (n-- > 0) - atom = atom->next(); - } + const Atom* atom = text.firstAtom(); + if (atom == 0) + return false; + + startText(relative, marker); + while (atom) { + if (atom->type() != Atom::QmlText) + atom = atom->next(); + else { + atom = atom->next(); + while (atom && (atom->type() != Atom::EndQmlText)) { + int n = 1 + generateAtom(atom, relative, marker); + while (n-- > 0) + atom = atom->next(); } } - endText(relative, marker); } + endText(relative, marker); + return true; } #endif @@ -302,7 +306,7 @@ void Generator::generateBody(const Node *node, CodeMarker *marker) } if (node->doc().isEmpty()) { - if (!quiet) // ### might be unnecessary + if (!quiet && !node->isReimp()) // ### might be unnecessary node->location().warning(tr("No documentation for '%1'") .arg(marker->plainFullName(node))); } @@ -313,7 +317,9 @@ void Generator::generateBody(const Node *node, CodeMarker *marker) generateReimplementedFrom(func, marker); } - generateText(node->doc().body(), node, marker); + if (!generateText(node->doc().body(), node, marker)) + if (node->isReimp()) + return; if (node->type() == Node::Enum) { const EnumNode *enume = (const EnumNode *) node; diff --git a/tools/qdoc3/generator.h b/tools/qdoc3/generator.h index 75134d2..08b857b 100644 --- a/tools/qdoc3/generator.h +++ b/tools/qdoc3/generator.h @@ -93,11 +93,11 @@ class Generator virtual void generateClassLikeNode(const InnerNode *inner, CodeMarker *marker); virtual void generateFakeNode(const FakeNode *fake, CodeMarker *marker); - virtual void generateText(const Text& text, + virtual bool generateText(const Text& text, const Node *relative, CodeMarker *marker); #ifdef QDOC_QML - virtual void generateQmlText(const Text& text, + virtual bool generateQmlText(const Text& text, const Node *relative, CodeMarker *marker); #endif diff --git a/tools/qdoc3/javadocgenerator.cpp b/tools/qdoc3/javadocgenerator.cpp index b32425c..294877b 100644 --- a/tools/qdoc3/javadocgenerator.cpp +++ b/tools/qdoc3/javadocgenerator.cpp @@ -272,9 +272,10 @@ void JavadocGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker HtmlGenerator::generateFakeNode(fake, marker); } -void JavadocGenerator::generateText(const Text& text, const Node *relative, CodeMarker *marker) +bool JavadocGenerator::generateText(const Text& text, const Node *relative, CodeMarker *marker) { HtmlGenerator::generateText(text, relative, marker); + return true; } void JavadocGenerator::generateBody(const Node *node, CodeMarker *marker) diff --git a/tools/qdoc3/javadocgenerator.h b/tools/qdoc3/javadocgenerator.h index ba9b15d..5431c38 100644 --- a/tools/qdoc3/javadocgenerator.h +++ b/tools/qdoc3/javadocgenerator.h @@ -68,7 +68,7 @@ protected: void generateClassLikeNode(const InnerNode *inner, CodeMarker *marker); void generateFakeNode( const FakeNode *fake, CodeMarker *marker ); - void generateText( const Text& text, const Node *relative, CodeMarker *marker ); + bool generateText( const Text& text, const Node *relative, CodeMarker *marker ); void generateBody( const Node *node, CodeMarker *marker ); void generateAlsoList( const Node *node, CodeMarker *marker ); diff --git a/tools/qdoc3/node.cpp b/tools/qdoc3/node.cpp index 0f9468a..b2e53ab 100644 --- a/tools/qdoc3/node.cpp +++ b/tools/qdoc3/node.cpp @@ -868,6 +868,18 @@ void FunctionNode::setOverload(bool overlode) } /*! + Sets the function node's reimplementation flag to \a r. + When \a r is true, it is supposed to mean that this function + is a reimplementation of a virtual function in a base class, + but it really just means the \e reimp command was seen in the + qdoc comment. + */ +void FunctionNode::setReimp(bool r) +{ + reimp = r; +} + +/*! */ void FunctionNode::addParameter(const Parameter& parameter) { diff --git a/tools/qdoc3/node.h b/tools/qdoc3/node.h index 0a671b37d..a35bc17 100644 --- a/tools/qdoc3/node.h +++ b/tools/qdoc3/node.h @@ -123,6 +123,7 @@ class Node void setTemplateStuff(const QString &templateStuff) { tpl = templateStuff; } virtual bool isInnerNode() const = 0; + virtual bool isReimp() const { return false; } Type type() const { return typ; } InnerNode *parent() const { return par; } InnerNode *relates() const { return rel; } @@ -444,6 +445,7 @@ class FunctionNode : public LeafNode void setConst(bool conste) { con = conste; } void setStatic(bool statique) { sta = statique; } void setOverload(bool overlode); + void setReimp(bool r); void addParameter(const Parameter& parameter); inline void setParameters(const QList& parameters); void borrowParameterNames(const FunctionNode *source); @@ -458,6 +460,7 @@ class FunctionNode : public LeafNode bool isConst() const { return con; } bool isStatic() const { return sta; } bool isOverload() const { return ove; } + bool isReimp() const { return reimp; } int overloadNumber() const; int numOverloads() const; const QList& parameters() const { return params; } @@ -483,6 +486,7 @@ class FunctionNode : public LeafNode bool con : 1; bool sta : 1; bool ove : 1; + bool reimp: 1; QList params; const FunctionNode *rf; const PropertyNode *ap; -- cgit v0.12 From 548274de342d6b14de57c96c484e02118b858d4a Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Tue, 30 Jun 2009 13:55:30 +0200 Subject: doc: Fixed several qdoc error reports. --- src/gui/graphicsview/qgraphicswidget.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 0644ce9..86c0b48 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -971,15 +971,18 @@ void QGraphicsWidget::updateGeometry() deliver events related to state changes in the item. Because of this, it is very important that subclasses call the base implementation. - For example, QGraphicsWidget uses ItemVisibleChange to deliver \l Show and - \l Hide events, ItemPositionHasChanged to deliver \l Move events, and - ItemParentChange both to deliver \l ParentChange events, and for managing - the focus chain. + \a change specifies the type of change, and \a value is the new value. + + For example, QGraphicsWidget uses ItemVisibleChange to deliver + \l{QEvent::Show} {Show} and \l{QEvent::Hide}{Hide} events, + ItemPositionHasChanged to deliver \l{QEvent::Move}{Move} events, + and ItemParentChange both to deliver \l{QEvent::ParentChange} + {ParentChange} events, and for managing the focus chain. QGraphicsWidget enables the ItemSendsGeometryChanges flag by default in order to track position changes. - \sa propertyChange() + \sa QGraphicsItem::itemChange() */ QVariant QGraphicsWidget::itemChange(GraphicsItemChange change, const QVariant &value) { @@ -1211,7 +1214,8 @@ Qt::WindowFrameSection QGraphicsWidget::windowFrameSectionAt(const QPointF &pos) /*! \reimp - QGraphicsWidget handles the following events: + Handles the \a event. QGraphicsWidget handles the following + events: \table \o Event \o Usage \row \o Polish -- cgit v0.12 From 4d8567b85bf14b1515aafc97c035b2dda2c79b2a Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 30 Jun 2009 14:16:07 +0200 Subject: QToolBar: fix coverity warnings I also changed a bit the way the timer for the popup is working --- src/gui/widgets/qtoolbar.cpp | 36 ++++++++++++++---------------------- src/gui/widgets/qtoolbar.h | 1 - src/gui/widgets/qtoolbar_p.h | 8 ++++---- 3 files changed, 18 insertions(+), 27 deletions(-) diff --git a/src/gui/widgets/qtoolbar.cpp b/src/gui/widgets/qtoolbar.cpp index b635628..3414b4f 100644 --- a/src/gui/widgets/qtoolbar.cpp +++ b/src/gui/widgets/qtoolbar.cpp @@ -70,6 +70,8 @@ #include "qdebug.h" +#define POPUP_TIMER_INTERVAL 500 + QT_BEGIN_NAMESPACE #ifdef Q_WS_MAC @@ -87,14 +89,6 @@ static void qt_mac_updateToolBarButtonHint(QWidget *parentWidget) void QToolBarPrivate::init() { Q_Q(QToolBar); - - waitForPopupTimer = new QTimer(q); - waitForPopupTimer->setSingleShot(false); - waitForPopupTimer->setInterval(500); - QObject::connect(waitForPopupTimer, SIGNAL(timeout()), q, SLOT(_q_waitForPopup())); - - floatable = true; - movable = true; q->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed)); q->setBackgroundRole(QPalette::Button); q->setAttribute(Qt::WA_Hover); @@ -1086,6 +1080,16 @@ bool QToolBar::event(QEvent *event) Q_D(QToolBar); switch (event->type()) { + case QEvent::Timer: + if (d->waitForPopupTimer.timerId() == static_cast(event)->timerId()) { + QWidget *w = QApplication::activePopupWidget(); + if (!waitForPopup(this, w)) { + d->waitForPopupTimer.stop(); + if (!this->underMouse()) + d->layout->setExpanded(false); + } + } + break; case QEvent::Hide: if (!isHidden()) break; @@ -1183,11 +1187,11 @@ bool QToolBar::event(QEvent *event) QWidget *w = QApplication::activePopupWidget(); if (waitForPopup(this, w)) { - d->waitForPopupTimer->start(); + d->waitForPopupTimer.start(POPUP_TIMER_INTERVAL, this); break; } - d->waitForPopupTimer->stop(); + d->waitForPopupTimer.stop(); d->layout->setExpanded(false); break; } @@ -1197,18 +1201,6 @@ bool QToolBar::event(QEvent *event) return QWidget::event(event); } -void QToolBarPrivate::_q_waitForPopup() -{ - Q_Q(QToolBar); - - QWidget *w = QApplication::activePopupWidget(); - if (!waitForPopup(q, w)) { - waitForPopupTimer->stop(); - if (!q->underMouse()) - layout->setExpanded(false); - } -} - /*! Returns a checkable action that can be used to show or hide this toolbar. diff --git a/src/gui/widgets/qtoolbar.h b/src/gui/widgets/qtoolbar.h index 2ab4ffd..07502b3 100644 --- a/src/gui/widgets/qtoolbar.h +++ b/src/gui/widgets/qtoolbar.h @@ -167,7 +167,6 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_toggleView(bool)) Q_PRIVATE_SLOT(d_func(), void _q_updateIconSize(const QSize &)) Q_PRIVATE_SLOT(d_func(), void _q_updateToolButtonStyle(Qt::ToolButtonStyle)) - Q_PRIVATE_SLOT(d_func(), void _q_waitForPopup()) friend class QMainWindow; friend class QMainWindowLayout; diff --git a/src/gui/widgets/qtoolbar_p.h b/src/gui/widgets/qtoolbar_p.h index b03c460..42ea97f 100644 --- a/src/gui/widgets/qtoolbar_p.h +++ b/src/gui/widgets/qtoolbar_p.h @@ -56,6 +56,7 @@ #include "qtoolbar.h" #include "QtGui/qaction.h" #include "private/qwidget_p.h" +#include QT_BEGIN_NAMESPACE @@ -70,7 +71,7 @@ class QToolBarPrivate : public QWidgetPrivate public: inline QToolBarPrivate() - : explicitIconSize(false), explicitToolButtonStyle(false), movable(false), + : explicitIconSize(false), explicitToolButtonStyle(false), movable(true), floatable(true), allowedAreas(Qt::AllToolBarAreas), orientation(Qt::Horizontal), toolButtonStyle(Qt::ToolButtonIconOnly), layout(0), state(0) @@ -84,16 +85,15 @@ public: void _q_toggleView(bool b); void _q_updateIconSize(const QSize &sz); void _q_updateToolButtonStyle(Qt::ToolButtonStyle style); - void _q_waitForPopup(); bool explicitIconSize; bool explicitToolButtonStyle; bool movable; + bool floatable; Qt::ToolBarAreas allowedAreas; Qt::Orientation orientation; Qt::ToolButtonStyle toolButtonStyle; QSize iconSize; - bool floatable; QAction *toggleViewAction; @@ -125,7 +125,7 @@ public: void unplug(const QRect &r); void plug(const QRect &r); - QTimer *waitForPopupTimer; + QBasicTimer waitForPopupTimer; }; #endif // QT_NO_TOOLBAR -- cgit v0.12 From 951ee7c2995b4f5c1a61c72c8f53ff40a3a0b2d4 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 30 Jun 2009 14:52:13 +0200 Subject: QDockArea: remove coverity warning --- src/gui/widgets/qdockarealayout.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp index 9828413..f245d64 100644 --- a/src/gui/widgets/qdockarealayout.cpp +++ b/src/gui/widgets/qdockarealayout.cpp @@ -2074,7 +2074,7 @@ void QDockAreaLayoutInfo::updateTabBar() const QDockAreaLayoutInfo *that = const_cast(this); - if (tabBar == 0) { + if (that->tabBar == 0) { that->tabBar = mainWindowLayout()->getTabBar(); that->tabBar->setShape(static_cast(tabBarShape)); that->tabBar->setDrawBase(true); -- cgit v0.12 From 6ee3fb750377eeedf161d96fef02c5fa336810e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Tue, 30 Jun 2009 13:00:32 +0200 Subject: More re-factoring of QGraphicsSceneIndex. Mostly re-factoring of QGraphicsSceneIndexPrivate::recursive_items_helper so it can re-use code from the scene (topLevelItemsInStackingOrder). That also means we'll use the bsp tree in case of NoIndex instead of always looping through the top-levels. This function is now almost identical to QGraphicsScenePrivate::drawSubtreeRecursive, so it might be worth looking into how we can abstract it even more and have one common recursive function. --- src/gui/graphicsview/qgraphicsscene.cpp | 20 +--- src/gui/graphicsview/qgraphicsscene_p.h | 11 +- .../graphicsview/qgraphicsscenebsptreeindex_p.h | 12 +-- src/gui/graphicsview/qgraphicssceneindex.cpp | 115 ++++++++------------- src/gui/graphicsview/qgraphicssceneindex_p.h | 34 ++++-- 5 files changed, 89 insertions(+), 103 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index f1e56c1..faacf4d 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -217,8 +217,9 @@ #include "qgraphicsview_p.h" #include "qgraphicswidget.h" #include "qgraphicswidget_p.h" -#include -#include +#include "qgraphicssceneindex_p.h" +#include "qgraphicsscenebsptreeindex_p.h" +#include "qgraphicsscenelinearindex_p.h" #include #include @@ -243,7 +244,6 @@ #include #include #include -#include #include #ifdef Q_WS_X11 #include @@ -1075,9 +1075,9 @@ QGraphicsWidget *QGraphicsScenePrivate::windowForItem(const QGraphicsItem *item) } QList QGraphicsScenePrivate::topLevelItemsInStackingOrder(const QTransform *const viewTransform, - QRegion *exposedRegion) + const QRectF &sceneRect) { - if (indexMethod == QGraphicsScene::NoIndex || !exposedRegion) { + if (indexMethod == QGraphicsScene::NoIndex || sceneRect.isNull()) { if (needSortTopLevelItems) { needSortTopLevelItems = false; qStableSort(topLevelItems.begin(), topLevelItems.end(), qt_notclosestLeaf); @@ -1085,16 +1085,6 @@ QList QGraphicsScenePrivate::topLevelItemsInStackingOrder(const return topLevelItems; } - const QRectF exposedRect = exposedRegion->boundingRect().adjusted(-1, -1, 1, 1); - QRectF sceneRect; - QTransform invertedViewTransform(Qt::Uninitialized); - if (!viewTransform) { - sceneRect = exposedRect; - } else { - invertedViewTransform = viewTransform->inverted(); - sceneRect = invertedViewTransform.mapRect(exposedRect); - } - QList tmp = index->estimateItems(sceneRect, Qt::SortOrder(-1), viewTransform ? *viewTransform : QTransform()); for (int i = 0; i < tmp.size(); ++i) { diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index f286a8d..b3d7535 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -57,7 +57,6 @@ #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW -#include "qgraphicsscenebsptreeindex_p.h" #include "qgraphicsview.h" #include "qgraphicsitem_p.h" @@ -187,7 +186,7 @@ public: QGraphicsWidget *windowForItem(const QGraphicsItem *item) const; bool sortCacheEnabled; // for compatibility - QList topLevelItemsInStackingOrder(const QTransform *const, QRegion *); + QList topLevelItemsInStackingOrder(const QTransform *const, const QRectF&); void drawItemHelper(QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget, @@ -196,7 +195,13 @@ public: inline void drawItems(QPainter *painter, const QTransform *const viewTransform, QRegion *exposedRegion, QWidget *widget) { - const QList tli = topLevelItemsInStackingOrder(viewTransform, exposedRegion); + QRectF exposedSceneRect; + if (exposedRegion && indexMethod != QGraphicsScene::NoIndex) { + exposedSceneRect = exposedRegion->boundingRect().adjusted(-1, -1, 1, 1); + if (viewTransform) + exposedSceneRect = viewTransform->inverted().mapRect(exposedSceneRect); + } + const QList tli = topLevelItemsInStackingOrder(viewTransform, exposedSceneRect); for (int i = 0; i < tli.size(); ++i) drawSubtreeRecursive(tli.at(i), painter, viewTransform, exposedRegion, widget); return; diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 850cc3f..90cc8c3 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -39,8 +39,6 @@ ** ****************************************************************************/ -#include - // // W A R N I N G // ------------- @@ -63,13 +61,13 @@ QT_MODULE(Gui) #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW +#include "qgraphicssceneindex_p.h" +#include "qgraphicsitem_p.h" +#include "qgraphicsscene_bsp_p.h" + +#include #include #include -#include -#include -#include -#include -#include static const int QGRAPHICSSCENE_INDEXTIMER_TIMEOUT = 2000; diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 88fb6b0..a42dc54 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -61,7 +61,8 @@ #include "qgraphicsitem_p.h" #include "qgraphicsscene_p.h" #include "qgraphicswidget.h" -#include +#include "qgraphicssceneindex_p.h" +#include "qgraphicsscenebsptreeindex_p.h" #ifndef QT_NO_GRAPHICSVIEW @@ -240,91 +241,64 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe Qt::ItemSelectionMode mode, Qt::SortOrder order, qreal parentOpacity) const { - // Calculate opacity. - qreal opacity; - if (item) { - if (!item->d_ptr->visible) - return; + Q_ASSERT(item); + if (!item->d_ptr->visible) + return; - QGraphicsItem *p = item->d_ptr->parent; - bool itemIgnoresParentOpacity = item->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity; - bool parentDoesntPropagateOpacity = (p && (p->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)); - if (!itemIgnoresParentOpacity && !parentDoesntPropagateOpacity) { - opacity = parentOpacity * item->opacity(); - } else { - opacity = item->d_ptr->opacity; - } - if (opacity == 0.0 && !(item->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) - return; - } else { - opacity = parentOpacity; - } + const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity); + const bool itemIsFullyTransparent = (opacity < 0.0001); + const bool itemHasChildren = !item->d_ptr->children.isEmpty(); + if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity())) + return; // Calculate the full transform for this item. - QTransform transform = parentTransform; - bool keep = false; - if (item) { - item->d_ptr->combineTransformFromParent(&transform, &viewTransform); - - // ### This does not take the clip into account. - QRectF brect = item->boundingRect(); - _q_adjustRect(&brect); - - //We fill the intersector with needed informations - keep = intersector->intersect(item, exposeRect, mode, transform, viewTransform); - } - - bool childClip = (item && (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)); - bool dontProcessItem = !item || !keep; - bool dontProcessChildren = item && dontProcessItem && childClip; + QTransform transform(parentTransform); + item->d_ptr->combineTransformFromParent(&transform, &viewTransform); + + const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape); + bool processItem = !itemIsFullyTransparent; + if (processItem) { + processItem = intersector->intersect(item, exposeRect, mode, transform, viewTransform); + if (!processItem && (!itemHasChildren || itemClipsChildrenToShape)) + return; + } // else we know for sure this item has children we must process. - // Find and sort children. - QList &children = item ? item->d_ptr->children : const_cast(scene->d_func())->topLevelItems; - if (!dontProcessChildren) { - if (item && item->d_ptr->needSortChildren) { + int i = 0; + if (itemHasChildren) { + // Sort children. + if (item->d_ptr->needSortChildren) { item->d_ptr->needSortChildren = 0; - qStableSort(children.begin(), children.end(), qt_notclosestLeaf); - } else if (!item && scene->d_func()->needSortTopLevelItems) { - const_cast(scene->d_func())->needSortTopLevelItems = false; - qStableSort(children.begin(), children.end(), qt_notclosestLeaf); + qStableSort(item->d_ptr->children.begin(), item->d_ptr->children.end(), qt_notclosestLeaf); } - } - - childClip &= !dontProcessChildren & !children.isEmpty(); - // Clip. - if (childClip) - exposeRect &= transform.map(item->shape()).controlPointRect(); + // Clip to shape. + if (itemClipsChildrenToShape) + exposeRect &= transform.map(item->shape()).controlPointRect(); - // Process children behind - int i = 0; - if (!dontProcessChildren) { - for (i = 0; i < children.size(); ++i) { - QGraphicsItem *child = children.at(i); + // Process children behind + for (i = 0; i < item->d_ptr->children.size(); ++i) { + QGraphicsItem *child = item->d_ptr->children.at(i); if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent)) break; + if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity)) + continue; recursive_items_helper(child, exposeRect, intersector, items, transform, viewTransform, mode, order, opacity); } } // Process item - if (!dontProcessItem) + if (processItem) items->append(item); // Process children in front - if (!dontProcessChildren) { - for (; i < children.size(); ++i) - recursive_items_helper(children.at(i), exposeRect, intersector, items, transform, viewTransform, + if (itemHasChildren) { + for (; i < item->d_ptr->children.size(); ++i) { + QGraphicsItem *child = item->d_ptr->children.at(i); + if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity)) + continue; + recursive_items_helper(child, exposeRect, intersector, items, transform, viewTransform, mode, order, opacity); - } - - if (!item && order == Qt::AscendingOrder) { - int n = items->size(); - for (int i = 0; i < n / 2; ++i) { - QGraphicsItem *tmp = (*items)[n - i - 1]; - (*items)[n - i - 1] = (*items)[i]; - (*items)[i] = tmp; } } } @@ -393,8 +367,7 @@ QList QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSe Q_D(const QGraphicsSceneIndex); QList itemList; d->pointIntersector->scenePoint = pos; - d->recursive_items_helper(0, QRectF(pos, QSizeF(1, 1)), d->pointIntersector, &itemList, - QTransform(), deviceTransform, mode, order); + d->items_helper(QRectF(pos, QSizeF(1, 1)), d->pointIntersector, &itemList, deviceTransform, mode, order); return itemList; } @@ -428,7 +401,7 @@ QList QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSe _q_adjustRect(&exposeRect); QList itemList; d->rectIntersector->sceneRect = rect; - d->recursive_items_helper(0, exposeRect, d->rectIntersector, &itemList, QTransform(), deviceTransform, mode, order); + d->items_helper(exposeRect, d->rectIntersector, &itemList, deviceTransform, mode, order); return itemList; } @@ -464,7 +437,7 @@ QList QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt:: QPainterPath path; path.addPolygon(polygon); d->pathIntersector->scenePath = path; - d->recursive_items_helper(0, exposeRect, d->pathIntersector, &itemList, QTransform(), deviceTransform, mode, order); + d->items_helper(exposeRect, d->pathIntersector, &itemList, deviceTransform, mode, order); return itemList; } @@ -498,7 +471,7 @@ QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt:: QRectF exposeRect = path.controlPointRect(); _q_adjustRect(&exposeRect); d->pathIntersector->scenePath = path; - d->recursive_items_helper(0, exposeRect, d->pathIntersector, &itemList, QTransform(), deviceTransform, mode, order); + d->items_helper(exposeRect, d->pathIntersector, &itemList, deviceTransform, mode, order); return itemList; } diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index dc6a740..122d7ae 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -53,11 +53,13 @@ // We mean it. // +#include "qgraphicsscene_p.h" +#include "qgraphicsscene.h" +#include + #include #include #include -#include -#include QT_BEGIN_HEADER @@ -67,7 +69,6 @@ QT_MODULE(Gui) #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW -class QGraphicsScene; class QGraphicsSceneIndexIntersector; class QGraphicsSceneIndexPointIntersector; class QGraphicsSceneIndexRectIntersector; @@ -138,12 +139,31 @@ public: QGraphicsSceneIndexIntersector *intersector, QList *items, const QTransform &parentTransform, const QTransform &viewTransform, Qt::ItemSelectionMode mode, Qt::SortOrder order, qreal parentOpacity = 1.0) const; - QGraphicsScene *scene; - QGraphicsSceneIndexPointIntersector *pointIntersector; - QGraphicsSceneIndexRectIntersector *rectIntersector; - QGraphicsSceneIndexPathIntersector *pathIntersector; + inline void items_helper(const QRectF &rect, QGraphicsSceneIndexIntersector *intersector, + QList *items, const QTransform &viewTransform, + Qt::ItemSelectionMode mode, Qt::SortOrder order) const; + + QGraphicsScene *scene; + QGraphicsSceneIndexPointIntersector *pointIntersector; + QGraphicsSceneIndexRectIntersector *rectIntersector; + QGraphicsSceneIndexPathIntersector *pathIntersector; }; +inline void QGraphicsSceneIndexPrivate::items_helper(const QRectF &rect, QGraphicsSceneIndexIntersector *intersector, + QList *items, const QTransform &viewTransform, + Qt::ItemSelectionMode mode, Qt::SortOrder order) const +{ + const QList tli = scene->d_func()->topLevelItemsInStackingOrder(&viewTransform, rect); + const QTransform identity; + for (int i = 0; i < tli.size(); ++i) + recursive_items_helper(tli.at(i), rect, intersector, items, identity, viewTransform, mode, order); + if (order == Qt::AscendingOrder) { + const int n = items->size(); + for (int i = 0; i < n / 2; ++i) + items->swap(i, n - i - 1); + } +} + class QGraphicsSceneIndexIntersector { public: -- cgit v0.12 From 771a6a8fd6a31905859a40b729eac872efb20285 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 30 Jun 2009 15:19:10 +0200 Subject: Linguist: defers the creation of the QPrinter On windows, if your default printer is not reachable it would take a lot of time to fail to construct the print engine. During that time the UI would be frozen on the splash screen. Reviewed-by: ossi --- tools/linguist/linguist/mainwindow.cpp | 22 ++++++++++++++++------ tools/linguist/linguist/mainwindow.h | 6 ++++-- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/tools/linguist/linguist/mainwindow.cpp b/tools/linguist/linguist/mainwindow.cpp index 2b1df39..bb79b19 100644 --- a/tools/linguist/linguist/mainwindow.cpp +++ b/tools/linguist/linguist/mainwindow.cpp @@ -82,6 +82,7 @@ #include #include #include +#include #include #include #include @@ -257,6 +258,7 @@ bool FocusWatcher::eventFilter(QObject *, QEvent *event) MainWindow::MainWindow() : QMainWindow(0, Qt::Window), m_assistantProcess(0), + m_printer(0), m_findMatchCase(Qt::CaseInsensitive), m_findIgnoreAccelerators(true), m_findWhere(DataModel::NoLocation), @@ -503,6 +505,7 @@ MainWindow::~MainWindow() qDeleteAll(m_phraseBooks); delete m_dataModel; delete m_statistics; + delete m_printer; } void MainWindow::modelCountChanged() @@ -870,15 +873,22 @@ void MainWindow::releaseAll() releaseInternal(i); } +QPrinter *MainWindow::printer() +{ + if (!m_printer) + m_printer = new QPrinter; + return m_printer; +} + void MainWindow::print() { int pageNum = 0; - QPrintDialog dlg(&m_printer, this); + QPrintDialog dlg(printer(), this); if (dlg.exec()) { QApplication::setOverrideCursor(Qt::WaitCursor); - m_printer.setDocName(m_dataModel->condensedSrcFileNames(true)); + printer()->setDocName(m_dataModel->condensedSrcFileNames(true)); statusBar()->showMessage(tr("Printing...")); - PrintOut pout(&m_printer); + PrintOut pout(printer()); for (int i = 0; i < m_dataModel->contextCount(); ++i) { MultiContextItem *mc = m_dataModel->multiContextItem(i); @@ -1229,11 +1239,11 @@ void MainWindow::printPhraseBook(QAction *action) int pageNum = 0; - QPrintDialog dlg(&m_printer, this); + QPrintDialog dlg(printer(), this); if (dlg.exec()) { - m_printer.setDocName(phraseBook->fileName()); + printer()->setDocName(phraseBook->fileName()); statusBar()->showMessage(tr("Printing...")); - PrintOut pout(&m_printer); + PrintOut pout(printer()); pout.setRule(PrintOut::ThinRule); foreach (const Phrase *p, phraseBook->phrases()) { pout.setGuide(p->source()); diff --git a/tools/linguist/linguist/mainwindow.h b/tools/linguist/linguist/mainwindow.h index 167dfe4..3dedcb5 100644 --- a/tools/linguist/linguist/mainwindow.h +++ b/tools/linguist/linguist/mainwindow.h @@ -51,7 +51,6 @@ #include #include -#include QT_BEGIN_NAMESPACE @@ -60,6 +59,7 @@ class QAction; class QDialog; class QLabel; class QMenu; +class QPrinter; class QProcess; class QIcon; class QSortFilterProxyModel; @@ -200,6 +200,8 @@ private: void releaseInternal(int model); void saveInternal(int model); + QPrinter *printer(); + // FIXME: move to DataModel void updateDanger(const MultiDataIndex &index, bool verbose); @@ -226,7 +228,7 @@ private: QList > > m_phraseDict; QList m_phraseBooks; QMap m_phraseBookMenu[3]; - QPrinter m_printer; + QPrinter *m_printer; FindDialog *m_findDialog; QString m_findText; -- cgit v0.12 From 99bea47fd9b868fb22f175943c11ecb05b51f07c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Tue, 30 Jun 2009 15:54:19 +0200 Subject: Fix broken tst_QGraphicsView::embeddedViews. This test has been broken after 32f32ee3e752a6cc03505ddaa48d2849eaedc2a6, but the test continued to pass because another bug, which is fixed by 6ee3fb750377eeedf161d96fef02c5fa336810e9. The transform should be exactly the same in both cases. --- tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index 65e066f..6db8f27 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -2989,14 +2989,7 @@ void tst_QGraphicsView::embeddedViews() v2->QWidget::render(&actual); QTransform b = item->transform; -#ifdef Q_WS_MAC - // We don't use shared painter on the Mac, so the - // transform should be exactly the same. QVERIFY(a == b); -#else - QVERIFY(a != b); -#endif - delete v1; } -- cgit v0.12 From 6c3412bf598c2bcf8863c08e16d7a80b119ff116 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Tue, 30 Jun 2009 15:58:58 +0200 Subject: add basic tests for QVariant/QObject qtscript integration Some of the more advanced tests will fail for non-obvious reasons if these basic assumptions don't hold. --- tests/auto/qscriptqobject/tst_qscriptqobject.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/auto/qscriptqobject/tst_qscriptqobject.cpp b/tests/auto/qscriptqobject/tst_qscriptqobject.cpp index d8db7b7..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(br), m_myObject->brushProperty()); QCOMPARE(qscriptvalue_cast(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() -- cgit v0.12 From 3a00930fe167e6db5588d9e93d429486f9591bd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Tue, 30 Jun 2009 16:15:28 +0200 Subject: More BSP tree index cleanup. Ensure the index of indexed items are reset to -1. Makes tst_QGraphicsScene::itemIndexMethod happy. (this test passed before we actually started using the BSP from the items() functions, see 6ee3fb750377eeedf161d96fef02c5fa336810e9) --- src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp | 12 ++++++++++++ src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h | 1 + 2 files changed, 13 insertions(+) diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 413c8de..ff9a3da 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -468,6 +468,18 @@ QGraphicsSceneBspTreeIndex::QGraphicsSceneBspTreeIndex(QGraphicsScene *scene) } +QGraphicsSceneBspTreeIndex::~QGraphicsSceneBspTreeIndex() +{ + Q_D(QGraphicsSceneBspTreeIndex); + for (int i = 0; i < d->indexedItems.size(); ++i) { + // Ensure item bits are reset properly. + if (QGraphicsItem *item = d->indexedItems.at(i)) { + Q_ASSERT(!item->d_ptr->itemDiscovered); + item->d_ptr->index = -1; + } + } +} + /*! \reimp Clear the all the BSP index. diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 90cc8c3..7b431e6 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -80,6 +80,7 @@ class Q_AUTOTEST_EXPORT QGraphicsSceneBspTreeIndex : public QGraphicsSceneIndex Q_PROPERTY(int bspTreeDepth READ bspTreeDepth WRITE setBspTreeDepth) public: QGraphicsSceneBspTreeIndex(QGraphicsScene *scene = 0); + ~QGraphicsSceneBspTreeIndex(); QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const; -- cgit v0.12 From 53ef0b0f8b1227cff6ce4c9e2a91a6fbc7e7ee3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Tue, 30 Jun 2009 16:19:25 +0200 Subject: Make QGraphicsSceneIndex::clear() less nasty. --- src/gui/graphicsview/qgraphicssceneindex.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index a42dc54..2f2f05e 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -521,8 +521,9 @@ void QGraphicsSceneIndex::updateSceneRect(const QRectF &rect) */ void QGraphicsSceneIndex::clear() { - for (int i = 0 ; i < items().size(); ++i) - removeItem(items().at(i)); + const QList allItems = items(); + for (int i = 0 ; i < allItems.size(); ++i) + removeItem(allItems.at(i)); } /*! -- cgit v0.12 From 3687425e541bd5f78c7baf63cfa5b1ba4d9ad29e Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Tue, 30 Jun 2009 16:52:11 +0200 Subject: Doc - some minor fixes on the sentences Reviewed-By: TrustMe --- doc/src/tutorials/addressbook.qdoc | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/doc/src/tutorials/addressbook.qdoc b/doc/src/tutorials/addressbook.qdoc index 2f6cec2..23dabb3 100644 --- a/doc/src/tutorials/addressbook.qdoc +++ b/doc/src/tutorials/addressbook.qdoc @@ -697,10 +697,11 @@ \snippet tutorials/addressbook/part5/finddialog.h FindDialog header - We define a public function, \c getFindText() for use by classes that - instantiate \c FindDialog, which allows them to obtain the text - entered by the user. A public slot, \c findClicked(), is defined to - handle the search string when the user clicks the \gui Find button. + We define a public function, \c getFindText(), to be used by classes that + instantiate \c FindDialog. This function allows these classes to obtain the + search string entered by the user. A public slot, \c findClicked(), is also + defined to handle the search string when the user clicks the \gui Find + button. Lastly, we define the private variables, \c findButton, \c lineEdit and \c findText, corresponding to the \gui Find button, the line edit @@ -715,15 +716,15 @@ \snippet tutorials/addressbook/part5/finddialog.cpp constructor - We set the layout and window title, as well as connect the signals - to their respective slots. Notice that \c{findButton}'s - \l{QPushButton::clicked()}{clicked()} signal is connected to to - \c findClicked() and \l{QDialog::accept()}{accept()}. The - \l{QDialog::accept()}{accept()} slot provided by QDialog hides - the dialog and sets the result code to \l{QDialog::}{Accepted}. - We use this function to help \c{AddressBook}'s \c findContact() function - know when the \c FindDialog object has been closed. This will be - further explained when discussing the \c findContact() function. + We set the layout and window title, as well as connect the signals to their + respective slots. Notice that \c{findButton}'s \l{QPushButton::clicked()} + {clicked()} signal is connected to to \c findClicked() and + \l{QDialog::accept()}{accept()}. The \l{QDialog::accept()}{accept()} slot + provided by QDialog hides the dialog and sets the result code to + \l{QDialog::}{Accepted}. We use this function to help \c{AddressBook}'s + \c findContact() function know when the \c FindDialog object has been + closed. We will explain this logic in further detail when discussing the + \c findContact() function. \image addressbook-tutorial-part5-signals-and-slots.png -- cgit v0.12 From e0463464773f5eb2bda98a467a9c91092a1f1964 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 30 Jun 2009 14:11:38 +0200 Subject: const ref for foreach() --- tools/linguist/lupdate/cpp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index eb743c2..09148e7 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -1799,7 +1799,7 @@ void loadCPP(Translator &translator, const QStringList &filenames, ConversionDat ? translator.codecName() : cd.m_codecForSource; QTextCodec *codec = QTextCodec::codecForName(codecName); - foreach (const QString filename, filenames) { + foreach (const QString &filename, filenames) { if (CppFiles::getResults(filename) || CppFiles::isBlacklisted(filename)) continue; -- cgit v0.12 From 7e91986c352677d4c0456d30e1cb5fc3179e28c3 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 30 Jun 2009 18:02:00 +0200 Subject: add 4.6 specific modifications to linguist tools tests --- .../testdata/good/lacksqobject/expectedoutput.txt | 8 +++-- .../testdata/good/parsecpp2/expectedoutput.txt | 7 ++++ .../lupdate/testdata/good/parsecpp2/main.cpp | 24 +++++++++++++ .../lupdate/testdata/good/parsecpp2/main2.cpp | 28 +++++++++++++++ .../lupdate/testdata/good/parsecpp2/main3.cpp | 42 ++++++++++++++++++++++ .../lupdate/testdata/good/parsecpp2/project.pro | 12 +++++++ .../testdata/good/parsecpp2/project.ts.result | 4 +++ 7 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 tests/auto/linguist/lupdate/testdata/good/parsecpp2/expectedoutput.txt create mode 100644 tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.cpp create mode 100644 tests/auto/linguist/lupdate/testdata/good/parsecpp2/main2.cpp create mode 100644 tests/auto/linguist/lupdate/testdata/good/parsecpp2/main3.cpp create mode 100644 tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.pro create mode 100644 tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.ts.result diff --git a/tests/auto/linguist/lupdate/testdata/good/lacksqobject/expectedoutput.txt b/tests/auto/linguist/lupdate/testdata/good/lacksqobject/expectedoutput.txt index 8a0bd11..1a6cfeb 100644 --- a/tests/auto/linguist/lupdate/testdata/good/lacksqobject/expectedoutput.txt +++ b/tests/auto/linguist/lupdate/testdata/good/lacksqobject/expectedoutput.txt @@ -1,4 +1,8 @@ .*/lupdate/testdata/good/lacksqobject/main.cpp:17: Class 'B' lacks Q_OBJECT macro -.*/lupdate/testdata/good/lacksqobject/main.cpp:26: Class 'C' 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:45: Class 'nsB::C' 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/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 @@ + + + + -- cgit v0.12 From a1d5b33bd33ecf1d809346a39d2386cafaf50cef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Tue, 30 Jun 2009 18:41:18 +0200 Subject: Partially revert 7fe4f8ff71cf09bbabbd3438ef637fe408a11c33 We have to ensure that the item's top-level is marked as discovered. This broke the dragandroprobot example after we started using the BSP from QGraphicsSceneIndex::items()* (see 6ee3fb750377eeedf161d96fef02c5fa336810e9) --- src/gui/graphicsview/qgraphicsscene.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index faacf4d..ed1d2f3 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1087,11 +1087,8 @@ QList QGraphicsScenePrivate::topLevelItemsInStackingOrder(const QList tmp = index->estimateItems(sceneRect, Qt::SortOrder(-1), viewTransform ? *viewTransform : QTransform()); - for (int i = 0; i < tmp.size(); ++i) { - QGraphicsItem *item = tmp.at(i); - if (!item->d_ptr->parent) - item->d_ptr->itemDiscovered = 1; - } + for (int i = 0; i < tmp.size(); ++i) + tmp.at(i)->topLevelItem()->d_ptr->itemDiscovered = 1; // Sort if the toplevel list is unsorted. if (needSortTopLevelItems) { -- cgit v0.12 From 436a71e8950ea5a050f95b5889b85e5fafb2e716 Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Tue, 30 Jun 2009 22:50:48 +0200 Subject: Set the focus to a child widget when set on a QGroupBox When the focus is set on a QGroupBox with the policy NoFocus, the focus should be propagated to one of the child if it accepts the focus. This was failing because QWidget::focusWidget() returns the QGroupBox itself. Task-number: 257158 Reviewed-by: Denis --- src/gui/widgets/qgroupbox.cpp | 5 ++--- tests/auto/qgroupbox/tst_qgroupbox.cpp | 11 +++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/gui/widgets/qgroupbox.cpp b/src/gui/widgets/qgroupbox.cpp index 0bfa8c0..2380e78 100644 --- a/src/gui/widgets/qgroupbox.cpp +++ b/src/gui/widgets/qgroupbox.cpp @@ -431,7 +431,7 @@ void QGroupBoxPrivate::_q_fixFocus(Qt::FocusReason reason) { Q_Q(QGroupBox); QWidget *fw = q->focusWidget(); - if (!fw) { + if (!fw || fw == q) { QWidget * best = 0; QWidget * candidate = 0; QWidget * w = q; @@ -449,8 +449,7 @@ void QGroupBoxPrivate::_q_fixFocus(Qt::FocusReason reason) } if (best) fw = best; - else - if (candidate) + else if (candidate) fw = candidate; } if (fw) 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" -- cgit v0.12 From bb8e25a5074a378d5003577fefbeabb1de846a81 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Wed, 1 Jul 2009 10:29:09 +1000 Subject: Fixes configure.exe silently disabling cetest even if you asked for it when paths to the ActiveSync headers/libraries are not set up. Reviewed-by: Michael Goddard --- tools/configure/configureapp.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 8780c62..597cd0e 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -604,10 +604,13 @@ void Configure::parseCmdLine() // cetest --------------------------------------------------- else if (configCmdLine.at(i) == "-no-cetest") { dictionary[ "CETEST" ] = "no"; + dictionary[ "CETEST_REQUESTED" ] = "no"; } else if (configCmdLine.at(i) == "-cetest") { // although specified to use it, we stay at "auto" state // this is because checkAvailability() adds variables - // we need for crosscompilation + // we need for crosscompilation; but remember if we asked + // for it. + dictionary[ "CETEST_REQUESTED" ] = "yes"; } // Qt/CE - signing tool ------------------------------------- else if( configCmdLine.at(i) == "-signature") { @@ -1824,6 +1827,11 @@ bool Configure::checkAvailability(const QString &part) dictionary[ "QT_CE_RAPI_INC" ] += QLatin1String("\"") + rapiHeader + QLatin1String("\""); dictionary[ "QT_CE_RAPI_LIB" ] += QLatin1String("\"") + rapiLib + QLatin1String("\""); } + else if (dictionary[ "CETEST_REQUESTED" ] == "yes") { + cout << "cetest could not be enabled: rapi.h and rapi.lib could not be found." << endl; + cout << "Make sure the environment is set up for compiling with ActiveSync." << endl; + dictionary[ "DONE" ] = "error"; + } } else if (part == "INCREDIBUILD_XGE") available = findFile("BuildConsole.exe") && findFile("xgConsole.exe"); -- cgit v0.12 From c5b5cd3d704bf7c84634188d44c5208fbe55e25b Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Wed, 1 Jul 2009 12:00:16 +1000 Subject: OpenVG compile fix - use const_cast instead of static_cast Reviewed-by: trustme --- src/openvg/qpaintengine_vg.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index 37945bf..c7fe604 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -1320,11 +1320,11 @@ QPainterState *QVGPaintEngine::createState(QPainterState *orig) const if (!orig) { return new QVGPainterState(); } else { - QVGPaintEnginePrivate *d = - static_cast(d_ptr); + Q_D(const QVGPaintEngine); + QVGPaintEnginePrivate *d2 = const_cast(d); QVGPainterState *origState = static_cast(orig); - origState->savedDirty = d->dirty; - d->dirty = 0; + origState->savedDirty = d2->dirty; + d2->dirty = 0; return new QVGPainterState(*origState); } } -- cgit v0.12 From 9cb231d773db6deb8fb145eb40aa949a2758d002 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 1 Jul 2009 10:22:15 +0200 Subject: ItemViews: Fixed signal entered not being emitted when using the mouse wheel The solution is to check the the current "entered item" hasn't change also when the scrollbars change values Task-number: 200665 Reviewed-by: janarve --- src/gui/itemviews/qabstractitemview.cpp | 72 ++++++++++++---------- src/gui/itemviews/qabstractitemview_p.h | 3 + .../qabstractitemview/tst_qabstractitemview.cpp | 19 ++++++ 3 files changed, 61 insertions(+), 33 deletions(-) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index cb0037b..b64bc71 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -127,6 +127,37 @@ void QAbstractItemViewPrivate::init() q->setAttribute(Qt::WA_InputMethodEnabled); } +void QAbstractItemViewPrivate::checkMouseMove(const QPersistentModelIndex &index) +{ + //we take a persistent model index because the model might change by emitting signals + Q_Q(QAbstractItemView); + if (viewportEnteredNeeded || enteredIndex != index) { + viewportEnteredNeeded = false; + + if (index.isValid()) { + emit q->entered(index); +#ifndef QT_NO_STATUSTIP + QString statustip = model->data(index, Qt::StatusTipRole).toString(); + if (parent && !statustip.isEmpty()) { + QStatusTipEvent tip(statustip); + QApplication::sendEvent(parent, &tip); + } +#endif + } else { +#ifndef QT_NO_STATUSTIP + if (parent) { + QString emptyString; + QStatusTipEvent tip( emptyString ); + QApplication::sendEvent(parent, &tip); + } +#endif + emit q->viewportEntered(); + } + enteredIndex = index; + } +} + + /*! \class QAbstractItemView @@ -1557,7 +1588,7 @@ void QAbstractItemView::mouseMoveEvent(QMouseEvent *event) } #endif // QT_NO_DRAGANDDROP - QModelIndex index = indexAt(bottomRight); + QPersistentModelIndex index = indexAt(bottomRight); QModelIndex buddy = d->model->buddy(d->pressedIndex); if ((state() == EditingState && d->hasEditor(buddy)) || edit(index, NoEditTriggers, event)) @@ -1568,33 +1599,7 @@ void QAbstractItemView::mouseMoveEvent(QMouseEvent *event) else topLeft = bottomRight; - if (d->viewportEnteredNeeded || d->enteredIndex != index) { - d->viewportEnteredNeeded = false; - - // signal handlers may change the model - QPersistentModelIndex persistent = index; - if (persistent.isValid()) { - emit entered(persistent); -#ifndef QT_NO_STATUSTIP - QString statustip = d->model->data(persistent, Qt::StatusTipRole).toString(); - if (parent() && !statustip.isEmpty()) { - QStatusTipEvent tip(statustip); - QApplication::sendEvent(parent(), &tip); - } -#endif - } else { -#ifndef QT_NO_STATUSTIP - if (parent()) { - QString emptyString; - QStatusTipEvent tip(emptyString); - QApplication::sendEvent(parent(), &tip); - } -#endif - emit viewportEntered(); - } - d->enteredIndex = persistent; - index = persistent; - } + d->checkMouseMove(index); #ifndef QT_NO_DRAGANDDROP if (index.isValid() @@ -1613,14 +1618,13 @@ void QAbstractItemView::mouseMoveEvent(QMouseEvent *event) // Do the normalize ourselves, since QRect::normalized() is flawed QRect selectionRect = QRect(topLeft, bottomRight); - QPersistentModelIndex persistent = index; setSelection(selectionRect, command); // set at the end because it might scroll the view - if (persistent.isValid() - && (persistent != d->selectionModel->currentIndex()) - && d->isIndexEnabled(persistent)) - d->selectionModel->setCurrentIndex(persistent, QItemSelectionModel::NoUpdate); + if (index.isValid() + && (index != d->selectionModel->currentIndex()) + && d->isIndexEnabled(index)) + d->selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate); } } @@ -2422,6 +2426,7 @@ void QAbstractItemView::verticalScrollbarValueChanged(int value) Q_D(QAbstractItemView); if (verticalScrollBar()->maximum() == value && d->model->canFetchMore(d->root)) d->model->fetchMore(d->root); + d->checkMouseMove(viewport()->mapFromGlobal(QCursor::pos())); } /*! @@ -2432,6 +2437,7 @@ void QAbstractItemView::horizontalScrollbarValueChanged(int value) Q_D(QAbstractItemView); if (horizontalScrollBar()->maximum() == value && d->model->canFetchMore(d->root)) d->model->fetchMore(d->root); + d->checkMouseMove(viewport()->mapFromGlobal(QCursor::pos())); } /*! diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index 030147b..c2c1f32 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -139,6 +139,9 @@ public: const QEvent *event) const; virtual void selectAll(QItemSelectionModel::SelectionFlags command); + void checkMouseMove(const QPersistentModelIndex &index); + inline void checkMouseMove(const QPoint &pos) { checkMouseMove(q_func()->indexAt(pos)); } + inline QItemSelectionModel::SelectionFlags selectionBehaviorFlags() const { switch (selectionBehavior) { 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" -- cgit v0.12 From 728430d16fd62de001ba8eaccabae41feef790f2 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 1 Jul 2009 10:38:51 +0200 Subject: Added QGraphicsScene::sendEvent(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge-request: 787 Reviewed-by: Bjørn Erik Nilsen --- src/gui/graphicsview/qgraphicsscene.cpp | 28 +++++++++++++++++++++++ src/gui/graphicsview/qgraphicsscene.h | 2 ++ tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp | 29 +++++++++++++++++++++++- 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 0dc77cc..d790640 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -5988,6 +5988,34 @@ void QGraphicsScene::setActiveWindow(QGraphicsWidget *widget) } } +/*! + \since 4.6 + + Sends event \a event to item \a item through possible event filters. + + The event is sent only if the item is enabled. + + Returns \c false if the event was filtered or if the item is disabled. + Otherwise returns the value that was returned from the event handler. + + \sa QGraphicsItem::sceneEvent(), QGraphicsItem::sceneEventFilter() +*/ +bool QGraphicsScene::sendEvent(QGraphicsItem *item, QEvent *event) +{ + Q_D(QGraphicsScene); + if (!item) { + qWarning("QGraphicsScene::sendEvent: cannot send event to a null item"); + return false; + } + if (item->scene() != this) { + qWarning("QGraphicsScene::sendEvent: item %p's scene (%p)" + " is different from this scene (%p)", + item, item->scene(), this); + return false; + } + return d->sendEvent(item, event); +} + void QGraphicsScenePrivate::addView(QGraphicsView *view) { views << view; diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h index 4d65b91..c8b147f 100644 --- a/src/gui/graphicsview/qgraphicsscene.h +++ b/src/gui/graphicsview/qgraphicsscene.h @@ -229,6 +229,8 @@ public: QGraphicsWidget *activeWindow() const; void setActiveWindow(QGraphicsWidget *widget); + bool sendEvent(QGraphicsItem *item, QEvent *event); + public Q_SLOTS: void update(const QRectF &rect = QRectF()); void invalidate(const QRectF &rect = QRectF(), SceneLayers layers = AllLayers); 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" -- cgit v0.12 From f1d54091ec24e6cf57008f9b4fac7ddf7c7c8de3 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Wed, 1 Jul 2009 11:49:29 +0200 Subject: doc: Fixed several qdoc error reports. Also changed qdoc not to warn about undocumented parameters if the function is marked with the \reimp command. --- src/gui/kernel/qgesture.cpp | 16 +++++ src/gui/styles/qwindowsvistastyle.cpp | 127 ++++++++++++++++------------------ tools/qdoc3/generator.cpp | 2 +- 3 files changed, 78 insertions(+), 67 deletions(-) diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp index d7b2d1b..ff369e2 100644 --- a/src/gui/kernel/qgesture.cpp +++ b/src/gui/kernel/qgesture.cpp @@ -266,6 +266,22 @@ void QGesture::setPos(const QPoint &point) d_func()->pos = point; } +/*! \fn void QGesture::setAccepted(bool accepted) + Marks the gesture with the value of \a accepted. + */ + +/*! \fn bool QGesture::isAccepted() const + Returns true if the gesture is marked accepted. + */ + +/*! \fn void QGesture::accept() + Marks the gesture accepted. +*/ + +/*! \fn void QGesture::ignore() + Marks the gesture ignored. +*/ + /*! \class QPanningGesture \since 4.6 diff --git a/src/gui/styles/qwindowsvistastyle.cpp b/src/gui/styles/qwindowsvistastyle.cpp index 5f0f053..b131d39 100644 --- a/src/gui/styles/qwindowsvistastyle.cpp +++ b/src/gui/styles/qwindowsvistastyle.cpp @@ -196,17 +196,15 @@ void Animation::paint(QPainter *painter, const QStyleOption *option) Q_UNUSED(painter); } -/* -* ! \internal -* -* Helperfunction to paint the current transition state -* between two animation frames. -* -* The result is a blended image consisting of -* ((alpha)*_primaryImage) + ((1-alpha)*_secondaryImage) -* -*/ +/*! \internal + + Helperfunction to paint the current transition state between two + animation frames. + The result is a blended image consisting of ((alpha)*_primaryImage) + + ((1-alpha)*_secondaryImage) + +*/ void Animation::drawBlendedImage(QPainter *painter, QRect rect, float alpha) { if (_secondaryImage.isNull() || _primaryImage.isNull()) return; @@ -248,14 +246,11 @@ void Animation::drawBlendedImage(QPainter *painter, QRect rect, float alpha) { painter->drawImage(rect, _tempImage); } -/* -* ! \internal -* -* Paints a transition state. The result will be a mix between the -* initial and final state of the transition, depending on the -* time difference between _startTime and current time. +/*! \internal + Paints a transition state. The result will be a mix between the + initial and final state of the transition, depending on the time + difference between _startTime and current time. */ - void Transition::paint(QPainter *painter, const QStyleOption *option) { float alpha = 1.0; @@ -278,15 +273,11 @@ void Transition::paint(QPainter *painter, const QStyleOption *option) drawBlendedImage(painter, option->rect, alpha); } -/* -* ! \internal -* -* Paints a pulse. The result will be a mix between the -* primary and secondary pulse images depending on the -* time difference between _startTime and current time. +/*! \internal + Paints a pulse. The result will be a mix between the primary and + secondary pulse images depending on the time difference between + _startTime and current time. */ - - void Pulse::paint(QPainter *painter, const QStyleOption *option) { float alpha = 1.0; @@ -308,31 +299,37 @@ void Pulse::paint(QPainter *painter, const QStyleOption *option) /*! - \reimp - * - * Animations are used for some state transitions on specific widgets. - * - * Only one running animation can exist for a widget at any specific time. - * Animations can be added through QWindowsVistaStylePrivate::startAnimation(Animation *) - * and any existing animation on a widget can be retrieved with - * QWindowsVistaStylePrivate::widgetAnimation(Widget *). - * - * Once an animation has been started, QWindowsVistaStylePrivate::timerEvent(QTimerEvent *) - * will continuously call update() on the widget until it is stopped, meaning that drawPrimitive - * will be called many times until the transition has completed. During this time, the result - * will be retrieved by the Animation::paint(...) function and not by the style itself. - * - * To determine if a transition should occur, the style needs to know the previous state of the - * widget as well as the current one. This is solved by updating dynamic properties on the widget - * every time the function is called. - * - * Transitions interrupting existing transitions should always be smooth, so whenever a hover-transition - * is started on a pulsating button, it uses the current frame of the pulse-animation as the - * starting image for the hover transition. - * + \internal + + Animations are used for some state transitions on specific widgets. + + Only one running animation can exist for a widget at any specific + time. Animations can be added through + QWindowsVistaStylePrivate::startAnimation(Animation *) and any + existing animation on a widget can be retrieved with + QWindowsVistaStylePrivate::widgetAnimation(Widget *). + + Once an animation has been started, + QWindowsVistaStylePrivate::timerEvent(QTimerEvent *) will + continuously call update() on the widget until it is stopped, + meaning that drawPrimitive will be called many times until the + transition has completed. During this time, the result will be + retrieved by the Animation::paint(...) function and not by the style + itself. + + To determine if a transition should occur, the style needs to know + the previous state of the widget as well as the current one. This is + solved by updating dynamic properties on the widget every time the + function is called. + + Transitions interrupting existing transitions should always be + smooth, so whenever a hover-transition is started on a pulsating + button, it uses the current frame of the pulse-animation as the + starting image for the hover transition. + */ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, - QPainter *painter, const QWidget *widget) const + QPainter *painter, const QWidget *widget) const { QWindowsVistaStylePrivate *d = const_cast(d_func()); @@ -877,11 +874,9 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt /*! - - \reimp + \internal see drawPrimitive for comments on the animation support - */ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const @@ -1541,7 +1536,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption } /*! - \reimp + \internal see drawPrimitive for comments on the animation support @@ -1927,7 +1922,7 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle } /*! - \reimp + \internal */ QSize QWindowsVistaStyle::sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const @@ -2004,7 +1999,7 @@ QSize QWindowsVistaStyle::sizeFromContents(ContentsType type, const QStyleOption } /*! - \reimp + \internal */ QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const { @@ -2175,7 +2170,7 @@ static bool buttonVisible(const QStyle::SubControl sc, const QStyleOptionTitleBa } -/*! \reimp */ +/*! \internal */ int QWindowsVistaStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const { @@ -2209,7 +2204,7 @@ int QWindowsVistaStyle::styleHint(StyleHint hint, const QStyleOption *option, co /*! - \reimp + \internal */ QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option, SubControl subControl, const QWidget *widget) const @@ -2318,7 +2313,7 @@ QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOpt } /*! - \reimp + \internal */ bool QWindowsVistaStyle::event(QEvent *e) { @@ -2341,7 +2336,7 @@ bool QWindowsVistaStyle::event(QEvent *e) } /*! - \reimp + \internal */ QStyle::SubControl QWindowsVistaStyle::hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, const QPoint &pos, const QWidget *widget) const @@ -2353,7 +2348,7 @@ QStyle::SubControl QWindowsVistaStyle::hitTestComplexControl(ComplexControl cont } /*! - \reimp + \internal */ int QWindowsVistaStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const { @@ -2378,7 +2373,7 @@ int QWindowsVistaStyle::pixelMetric(PixelMetric metric, const QStyleOption *opti } /*! - \reimp + \internal */ QPalette QWindowsVistaStyle::standardPalette() const { @@ -2386,7 +2381,7 @@ QPalette QWindowsVistaStyle::standardPalette() const } /*! - \reimp + \internal */ void QWindowsVistaStyle::polish(QApplication *app) { @@ -2394,7 +2389,7 @@ void QWindowsVistaStyle::polish(QApplication *app) } /*! - \reimp + \internal */ void QWindowsVistaStyle::polish(QWidget *widget) { @@ -2448,7 +2443,7 @@ void QWindowsVistaStyle::polish(QWidget *widget) } /*! - \reimp + \internal */ void QWindowsVistaStyle::unpolish(QWidget *widget) { @@ -2490,7 +2485,7 @@ void QWindowsVistaStyle::unpolish(QWidget *widget) /*! - \reimp + \internal */ void QWindowsVistaStyle::unpolish(QApplication *app) { @@ -2498,7 +2493,7 @@ void QWindowsVistaStyle::unpolish(QApplication *app) } /*! - \reimp + \internal */ void QWindowsVistaStyle::polish(QPalette &pal) { @@ -2507,7 +2502,7 @@ void QWindowsVistaStyle::polish(QPalette &pal) } /*! - \reimp + \internal */ QPixmap QWindowsVistaStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option, const QWidget *widget) const diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp index 7e10f3e..00831d1 100644 --- a/tools/qdoc3/generator.cpp +++ b/tools/qdoc3/generator.cpp @@ -401,7 +401,7 @@ void Generator::generateBody(const Node *node, CodeMarker *marker) } } } - if (needWarning) + if (needWarning && !func->isReimp()) node->doc().location().warning( tr("Undocumented parameter '%1' in %2").arg(*a).arg(marker->plainFullName(node))); } -- cgit v0.12 From adc1c08ed9a5de2263564ba654a8ef7fed54af82 Mon Sep 17 00:00:00 2001 From: miniak Date: Wed, 1 Jul 2009 11:49:45 +0200 Subject: src/winmain: Remove QT_WA and non-Unicode code paths, dropping Win9x and NT support Also TCHAR -> wchar_t LPTSTR/LPCTSTRs -> LPWSTR/LPCWSTRs Merge-request: 604 Reviewed-by: Marius Storm-Olsen --- src/winmain/qtmain_win.cpp | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/winmain/qtmain_win.cpp b/src/winmain/qtmain_win.cpp index c266cbf..5f929d6 100644 --- a/src/winmain/qtmain_win.cpp +++ b/src/winmain/qtmain_win.cpp @@ -89,18 +89,12 @@ extern "C" int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR /*cmdParamarg*/, int cmdShow) #endif { - QByteArray cmdParam; - QT_WA({ - LPTSTR cmdline = GetCommandLineW(); - cmdParam = QString::fromUtf16((const unsigned short *)cmdline).toLocal8Bit(); - }, { - cmdParam = GetCommandLineA(); - }); + QByteArray cmdParam = QString::fromWCharArray(GetCommandLine()).toLocal8Bit(); #if defined(Q_OS_WINCE) - TCHAR appName[256]; - GetModuleFileName(0, appName, 255); - cmdParam.prepend(QString::fromLatin1("\"%1\" ").arg(QString::fromUtf16((const unsigned short *)appName)).toLocal8Bit()); + wchar_t appName[MAX_PATH]; + GetModuleFileName(0, appName, MAX_PATH); + cmdParam.prepend(QString(QLatin1String("\"%1\" ")).arg(QString::fromWCharArray(appName)).toLocal8Bit()); #endif int argc = 0; @@ -108,9 +102,9 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR /*cmdPara qWinMain(instance, prevInstance, cmdParam.data(), cmdShow, argc, argv); #if defined(Q_OS_WINCE) - TCHAR uniqueAppID[256]; - GetModuleFileName(0, uniqueAppID, 255); - QString uid = QString::fromUtf16((const unsigned short *)uniqueAppID).toLower().replace(QLatin1Char('\\'), QLatin1Char('_')); + wchar_t uniqueAppID[MAX_PATH]; + GetModuleFileName(0, uniqueAppID, MAX_PATH); + QString uid = QString::fromWCharArray(uniqueAppID).toLower().replace(QLatin1String("\\"), QLatin1String("_")); // If there exists an other instance of this application // it will be the owner of a mutex with the unique ID. -- cgit v0.12 From 5ae330b6546dabada53c394b53ce9513f552a8a5 Mon Sep 17 00:00:00 2001 From: miniak Date: Wed, 1 Jul 2009 11:49:48 +0200 Subject: src/corelib: Remove QT_WA and non-Unicode code paths, dropping Win9x and NT support Also: QString::fromUtf16() -> QString::fromWCharArray() WCHAR & TCHAR -> wchar_t LPTSTR/LPCTSTR -> LPWSTR/LPCWSTR Documentation update Merge-request: 604 Reviewed-by: Marius Storm-Olsen --- src/corelib/codecs/qtextcodec.cpp | 14 +- src/corelib/global/qglobal.cpp | 43 +- src/corelib/global/qglobal.h | 4 +- src/corelib/io/qfileinfo.cpp | 6 +- src/corelib/io/qfilesystemwatcher_win.cpp | 12 +- src/corelib/io/qfsfileengine_iterator_win.cpp | 32 +- src/corelib/io/qfsfileengine_p.h | 4 +- src/corelib/io/qfsfileengine_win.cpp | 798 +++++++++----------------- src/corelib/io/qprocess_win.cpp | 231 +++----- src/corelib/io/qsettings.cpp | 37 +- src/corelib/io/qsettings_win.cpp | 209 ++----- src/corelib/kernel/qcoreapplication.cpp | 22 +- src/corelib/kernel/qcoreapplication_win.cpp | 66 +-- src/corelib/kernel/qcorecmdlineargs_p.h | 9 +- src/corelib/kernel/qeventdispatcher_win.cpp | 89 ++- src/corelib/kernel/qfunctions_wince.cpp | 12 +- src/corelib/kernel/qfunctions_wince.h | 6 +- src/corelib/kernel/qsharedmemory_win.cpp | 17 +- src/corelib/kernel/qsystemsemaphore_win.cpp | 6 +- src/corelib/kernel/qtimer.cpp | 5 +- src/corelib/plugin/qlibrary.cpp | 8 +- src/corelib/plugin/qlibrary_win.cpp | 34 +- src/corelib/thread/qmutex_win.cpp | 14 +- src/corelib/thread/qthread_win.cpp | 38 +- src/corelib/thread/qwaitcondition_win.cpp | 6 +- src/corelib/tools/qdatetime.cpp | 13 +- src/corelib/tools/qlocale.cpp | 133 ++--- src/corelib/tools/qstring.cpp | 26 +- 28 files changed, 554 insertions(+), 1340 deletions(-) diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index d4e5d44..c4266a0 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -233,9 +233,9 @@ QString QWindowsLocalCodec::convertToUnicode(const char *chars, int length, Conv return QString(); const int wclen_auto = 4096; - WCHAR wc_auto[wclen_auto]; + wchar_t wc_auto[wclen_auto]; int wclen = wclen_auto; - WCHAR *wc = wc_auto; + wchar_t *wc = wc_auto; int len; QString sp; bool prepend = false; @@ -275,7 +275,7 @@ QString QWindowsLocalCodec::convertToUnicode(const char *chars, int length, Conv } else { wclen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, mb, mblen, 0, 0); - wc = new WCHAR[wclen]; + wc = new wchar_t[wclen]; // and try again... } } else if (r == ERROR_NO_UNICODE_TRANSLATION) { @@ -341,7 +341,7 @@ QString QWindowsLocalCodec::convertToUnicodeCharByChar(const char *chars, int le const char *next = 0; QString s; while((next = CharNextExA(CP_ACP, mb, 0)) != mb) { - WCHAR wc[2] ={0}; + wchar_t wc[2] ={0}; int charlength = next - mb; int len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, mb, charlength, wc, 2); if (len>0) { @@ -1042,16 +1042,10 @@ QList QTextCodec::availableMibs() This might be needed for some applications that want to use their own mechanism for setting the locale. - Setting this codec is not supported on DOS based Windows. - \sa codecForLocale() */ void QTextCodec::setCodecForLocale(QTextCodec *c) { -#ifdef Q_WS_WIN - if (QSysInfo::WindowsVersion& QSysInfo::WV_DOS_based) - return; -#endif localeMapper = c; if (!localeMapper) setupLocaleMapper(); diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index bb639fe..f7a97e1 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -915,7 +915,7 @@ QT_BEGIN_NAMESPACE \fn bool qt_winUnicode() \relates - Use QSysInfo::WindowsVersion and QSysInfo::WV_DOS_based instead. + This function always returns true. \sa QSysInfo */ @@ -1620,15 +1620,11 @@ QSysInfo::WinVersion QSysInfo::windowsVersion() if (winver) return winver; winver = QSysInfo::WV_NT; -#ifndef Q_OS_WINCE - OSVERSIONINFOA osver; - osver.dwOSVersionInfoSize = sizeof(osver); - GetVersionExA(&osver); -#else - DWORD qt_cever = 0; OSVERSIONINFOW osver; osver.dwOSVersionInfoSize = sizeof(osver); GetVersionEx(&osver); +#ifdef Q_OS_WINCE + DWORD qt_cever = 0; qt_cever = osver.dwMajorVersion * 100; qt_cever += osver.dwMinorVersion * 10; #endif @@ -1904,29 +1900,16 @@ QString qt_error_string(int errorCode) break; default: { #ifdef Q_OS_WIN - QT_WA({ - unsigned short *string = 0; - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - errorCode, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR)&string, - 0, - NULL); - ret = QString::fromUtf16(string); - LocalFree((HLOCAL)string); - }, { - char *string = 0; - FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - errorCode, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPSTR)&string, - 0, - NULL); - ret = QString::fromLocal8Bit(string); - LocalFree((HLOCAL)string); - }); + wchar_t *string = 0; + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + errorCode, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + string, + 0, + NULL); + ret = QString::fromWCharArray(string); + LocalFree((HLOCAL)string); if (ret.isEmpty() && errorCode == ERROR_MOD_NOT_FOUND) ret = QString::fromLatin1("The specified module could not be found."); diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index afc3f58..00a9466 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -147,7 +147,7 @@ namespace QT_NAMESPACE {} MSDOS - MS-DOS and Windows OS2 - OS/2 OS2EMX - XFree86 on OS/2 (not PM) - WIN32 - Win32 (Windows 95/98/ME and Windows NT/2000/XP) + WIN32 - Win32 (Windows 2000/XP/Vista/7 and Windows Server 2003/2008) WINCE - WinCE (Windows CE 5.0) CYGWIN - Cygwin SOLARIS - Sun Solaris @@ -1416,7 +1416,7 @@ inline QT3_SUPPORT bool qSysInfo(int *wordSize, bool *bigEndian) #if defined(Q_WS_WIN) || defined(Q_OS_CYGWIN) #if defined(QT3_SUPPORT) -inline QT3_SUPPORT bool qt_winUnicode() { return !(QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based); } +inline QT3_SUPPORT bool qt_winUnicode() { return true; } inline QT3_SUPPORT int qWinVersion() { return QSysInfo::WindowsVersion; } #endif diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 4c1c21a..c50bb51 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -117,11 +117,7 @@ bool QFileInfoPrivate::hasAccess(Access access) const if (access == ExecuteAccess) return getFileFlags(QAbstractFileEngine::ExeUserPerm); - QT_WA( { - return ::_waccess((TCHAR *)QFSFileEnginePrivate::longFileName(data->fileName).utf16(), mode) == 0; - } , { - return QT_ACCESS(QFSFileEnginePrivate::win95Name(data->fileName), mode) == 0; - } ); + return ::_waccess((wchar_t*)QFSFileEnginePrivate::longFileName(data->fileName).utf16(), mode) == 0; #endif return false; } diff --git a/src/corelib/io/qfilesystemwatcher_win.cpp b/src/corelib/io/qfilesystemwatcher_win.cpp index 9a3aeae..c15b1d2 100644 --- a/src/corelib/io/qfilesystemwatcher_win.cpp +++ b/src/corelib/io/qfilesystemwatcher_win.cpp @@ -56,9 +56,7 @@ QT_BEGIN_NAMESPACE QWindowsFileSystemWatcherEngine::QWindowsFileSystemWatcherEngine() : msg(0) { - HANDLE h = QT_WA_INLINE(CreateEventW(0, false, false, 0), - CreateEventA(0, false, false, 0)); - if (h != INVALID_HANDLE_VALUE) { + if (HANDLE h = CreateEvent(0, false, false, 0)) { handles.reserve(MAXIMUM_WAIT_OBJECTS); handles.append(h); } @@ -216,13 +214,7 @@ QStringList QWindowsFileSystemWatcherEngine::addPaths(const QStringList &paths, const QString effectiveAbsolutePath = isDir ? (absolutePath + QLatin1Char('/')) : absolutePath; - QT_WA({ - handle.handle = FindFirstChangeNotificationW((TCHAR *) QDir::toNativeSeparators(effectiveAbsolutePath).utf16(), - false, flags); - },{ - handle.handle = FindFirstChangeNotificationA(QDir::toNativeSeparators(effectiveAbsolutePath).toLocal8Bit(), - false, flags); - }) + handle.handle = FindFirstChangeNotification((wchar_t*) QDir::toNativeSeparators(effectiveAbsolutePath).utf16(), false, flags); handle.flags = flags; if (handle.handle == INVALID_HANDLE_VALUE) continue; diff --git a/src/corelib/io/qfsfileengine_iterator_win.cpp b/src/corelib/io/qfsfileengine_iterator_win.cpp index 2336542..dd4ddf3 100644 --- a/src/corelib/io/qfsfileengine_iterator_win.cpp +++ b/src/corelib/io/qfsfileengine_iterator_win.cpp @@ -79,11 +79,7 @@ void QFSFileEngineIteratorPlatformSpecificData::saveCurrentFileName() it->currentEntry = uncShares.at(uncShareIndex - 1); } else { // Local directory - QT_WA({ - it->currentEntry = QString::fromUtf16((unsigned short *)findData.cFileName); - } , { - it->currentEntry = QString::fromLocal8Bit((const char *)findData.cFileName); - }); + it->currentEntry = QString::fromWCharArray(findData.cFileName); } } @@ -97,17 +93,10 @@ void QFSFileEngineIterator::advance() if (platform->uncFallback) { ++platform->uncShareIndex; } else if (platform->findFileHandle != INVALID_HANDLE_VALUE) { - QT_WA({ - if (!FindNextFile(platform->findFileHandle, &platform->findData)) { - platform->done = true; - FindClose(platform->findFileHandle); - } - } , { - if (!FindNextFileA(platform->findFileHandle, (WIN32_FIND_DATAA *)&platform->findData)) { - platform->done = true; - FindClose(platform->findFileHandle); - } - }); + if (!FindNextFile(platform->findFileHandle, &platform->findData)) { + platform->done = true; + FindClose(platform->findFileHandle); + } } } @@ -141,15 +130,8 @@ bool QFSFileEngineIterator::hasNext() const path.append(QLatin1Char('/')); path.append(QLatin1String("*.*")); - QT_WA({ - QString fileName = QFSFileEnginePrivate::longFileName(path); - platform->findFileHandle = FindFirstFileW((TCHAR *)fileName.utf16(), - &platform->findData); - }, { - // Cast is safe, since char is at end of WIN32_FIND_DATA - platform->findFileHandle = FindFirstFileA(QFSFileEnginePrivate::win95Name(path), - (WIN32_FIND_DATAA*)&platform->findData); - }); + QString fileName = QFSFileEnginePrivate::longFileName(path); + platform->findFileHandle = FindFirstFile((const wchar_t *)fileName.utf16(), &platform->findData); if (platform->findFileHandle == INVALID_HANDLE_VALUE) { if (path.startsWith(QLatin1String("//"))) { diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h index 5aef229..864599f 100644 --- a/src/corelib/io/qfsfileengine_p.h +++ b/src/corelib/io/qfsfileengine_p.h @@ -72,7 +72,6 @@ class QFSFileEnginePrivate : public QAbstractFileEnginePrivate public: #ifdef Q_WS_WIN - static QByteArray win95Name(const QString &path); static QString longFileName(const QString &path); #endif static QString canonicalized(const QString &path); @@ -151,8 +150,7 @@ public: #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) static void resolveLibs(); - static bool resolveUNCLibs_NT(); - static bool resolveUNCLibs_9x(); + static bool resolveUNCLibs(); static bool uncListSharesOnServer(const QString &server, QStringList *list); #endif diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index eef39e4..ee49853 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -152,66 +152,64 @@ void QFSFileEnginePrivate::resolveLibs() triedResolve = true; #if !defined(Q_OS_WINCE) - if(QSysInfo::WindowsVersion & QSysInfo::WV_NT_based) { - HINSTANCE advapiHnd = LoadLibraryW(L"advapi32"); - if (advapiHnd) { - ptrGetNamedSecurityInfoW = (PtrGetNamedSecurityInfoW)GetProcAddress(advapiHnd, "GetNamedSecurityInfoW"); - ptrLookupAccountSidW = (PtrLookupAccountSidW)GetProcAddress(advapiHnd, "LookupAccountSidW"); - ptrAllocateAndInitializeSid = (PtrAllocateAndInitializeSid)GetProcAddress(advapiHnd, "AllocateAndInitializeSid"); - ptrBuildTrusteeWithSidW = (PtrBuildTrusteeWithSidW)GetProcAddress(advapiHnd, "BuildTrusteeWithSidW"); - ptrBuildTrusteeWithNameW = (PtrBuildTrusteeWithNameW)GetProcAddress(advapiHnd, "BuildTrusteeWithNameW"); - ptrGetEffectiveRightsFromAclW = (PtrGetEffectiveRightsFromAclW)GetProcAddress(advapiHnd, "GetEffectiveRightsFromAclW"); - ptrFreeSid = (PtrFreeSid)GetProcAddress(advapiHnd, "FreeSid"); - } - if (ptrBuildTrusteeWithNameW) { - HINSTANCE versionHnd = LoadLibraryW(L"version"); - if (versionHnd) { - typedef DWORD (WINAPI *PtrGetFileVersionInfoSizeW)(LPWSTR lptstrFilename,LPDWORD lpdwHandle); - PtrGetFileVersionInfoSizeW ptrGetFileVersionInfoSizeW = (PtrGetFileVersionInfoSizeW)GetProcAddress(versionHnd, "GetFileVersionInfoSizeW"); - typedef BOOL (WINAPI *PtrGetFileVersionInfoW)(LPWSTR lptstrFilename,DWORD dwHandle,DWORD dwLen,LPVOID lpData); - PtrGetFileVersionInfoW ptrGetFileVersionInfoW = (PtrGetFileVersionInfoW)GetProcAddress(versionHnd, "GetFileVersionInfoW"); - typedef BOOL (WINAPI *PtrVerQueryValueW)(const LPVOID pBlock,LPWSTR lpSubBlock,LPVOID *lplpBuffer,PUINT puLen); - PtrVerQueryValueW ptrVerQueryValueW = (PtrVerQueryValueW)GetProcAddress(versionHnd, "VerQueryValueW"); - if(ptrGetFileVersionInfoSizeW && ptrGetFileVersionInfoW && ptrVerQueryValueW) { - DWORD fakeHandle; - DWORD versionSize = ptrGetFileVersionInfoSizeW(L"secur32.dll", &fakeHandle); - if(versionSize) { - LPVOID versionData; - versionData = malloc(versionSize); - if(ptrGetFileVersionInfoW(L"secur32.dll", 0, versionSize, versionData)) { - UINT puLen; - VS_FIXEDFILEINFO *pLocalInfo; - if(ptrVerQueryValueW(versionData, L"\\", (void**)&pLocalInfo, &puLen)) { - WORD wVer1, wVer2, wVer3, wVer4; - wVer1 = HIWORD(pLocalInfo->dwFileVersionMS); - wVer2 = LOWORD(pLocalInfo->dwFileVersionMS); - wVer3 = HIWORD(pLocalInfo->dwFileVersionLS); - wVer4 = LOWORD(pLocalInfo->dwFileVersionLS); - // It will not work with secur32.dll version 5.0.2195.2862 - if(!(wVer1 == 5 && wVer2 == 0 && wVer3 == 2195 && (wVer4 == 2862 || wVer4 == 4587))) { - HINSTANCE userHnd = LoadLibraryW(L"secur32"); - if (userHnd) { - typedef BOOL (WINAPI *PtrGetUserNameExW)(EXTENDED_NAME_FORMAT nameFormat, ushort* lpBuffer, LPDWORD nSize); - PtrGetUserNameExW ptrGetUserNameExW = (PtrGetUserNameExW)GetProcAddress(userHnd, "GetUserNameExW"); - if(ptrGetUserNameExW) { - static TCHAR buffer[258]; - DWORD bufferSize = 257; - ptrGetUserNameExW(NameSamCompatible, (ushort*)buffer, &bufferSize); - ptrBuildTrusteeWithNameW(¤tUserTrusteeW, (ushort*)buffer); - } - FreeLibrary(userHnd); + HINSTANCE advapiHnd = LoadLibraryW(L"advapi32"); + if (advapiHnd) { + ptrGetNamedSecurityInfoW = (PtrGetNamedSecurityInfoW)GetProcAddress(advapiHnd, "GetNamedSecurityInfoW"); + ptrLookupAccountSidW = (PtrLookupAccountSidW)GetProcAddress(advapiHnd, "LookupAccountSidW"); + ptrAllocateAndInitializeSid = (PtrAllocateAndInitializeSid)GetProcAddress(advapiHnd, "AllocateAndInitializeSid"); + ptrBuildTrusteeWithSidW = (PtrBuildTrusteeWithSidW)GetProcAddress(advapiHnd, "BuildTrusteeWithSidW"); + ptrBuildTrusteeWithNameW = (PtrBuildTrusteeWithNameW)GetProcAddress(advapiHnd, "BuildTrusteeWithNameW"); + ptrGetEffectiveRightsFromAclW = (PtrGetEffectiveRightsFromAclW)GetProcAddress(advapiHnd, "GetEffectiveRightsFromAclW"); + ptrFreeSid = (PtrFreeSid)GetProcAddress(advapiHnd, "FreeSid"); + } + if (ptrBuildTrusteeWithNameW) { + HINSTANCE versionHnd = LoadLibraryW(L"version"); + if (versionHnd) { + typedef DWORD (WINAPI *PtrGetFileVersionInfoSizeW)(LPWSTR lptstrFilename,LPDWORD lpdwHandle); + PtrGetFileVersionInfoSizeW ptrGetFileVersionInfoSizeW = (PtrGetFileVersionInfoSizeW)GetProcAddress(versionHnd, "GetFileVersionInfoSizeW"); + typedef BOOL (WINAPI *PtrGetFileVersionInfoW)(LPWSTR lptstrFilename,DWORD dwHandle,DWORD dwLen,LPVOID lpData); + PtrGetFileVersionInfoW ptrGetFileVersionInfoW = (PtrGetFileVersionInfoW)GetProcAddress(versionHnd, "GetFileVersionInfoW"); + typedef BOOL (WINAPI *PtrVerQueryValueW)(const LPVOID pBlock,LPWSTR lpSubBlock,LPVOID *lplpBuffer,PUINT puLen); + PtrVerQueryValueW ptrVerQueryValueW = (PtrVerQueryValueW)GetProcAddress(versionHnd, "VerQueryValueW"); + if(ptrGetFileVersionInfoSizeW && ptrGetFileVersionInfoW && ptrVerQueryValueW) { + DWORD fakeHandle; + DWORD versionSize = ptrGetFileVersionInfoSizeW(L"secur32.dll", &fakeHandle); + if(versionSize) { + LPVOID versionData; + versionData = malloc(versionSize); + if(ptrGetFileVersionInfoW(L"secur32.dll", 0, versionSize, versionData)) { + UINT puLen; + VS_FIXEDFILEINFO *pLocalInfo; + if(ptrVerQueryValueW(versionData, L"\\", (void**)&pLocalInfo, &puLen)) { + WORD wVer1, wVer2, wVer3, wVer4; + wVer1 = HIWORD(pLocalInfo->dwFileVersionMS); + wVer2 = LOWORD(pLocalInfo->dwFileVersionMS); + wVer3 = HIWORD(pLocalInfo->dwFileVersionLS); + wVer4 = LOWORD(pLocalInfo->dwFileVersionLS); + // It will not work with secur32.dll version 5.0.2195.2862 + if(!(wVer1 == 5 && wVer2 == 0 && wVer3 == 2195 && (wVer4 == 2862 || wVer4 == 4587))) { + HINSTANCE userHnd = LoadLibraryW(L"secur32"); + if (userHnd) { + typedef BOOL (WINAPI *PtrGetUserNameExW)(EXTENDED_NAME_FORMAT nameFormat, ushort* lpBuffer, LPDWORD nSize); + PtrGetUserNameExW ptrGetUserNameExW = (PtrGetUserNameExW)GetProcAddress(userHnd, "GetUserNameExW"); + if(ptrGetUserNameExW) { + static wchar_t buffer[258]; + DWORD bufferSize = 257; + ptrGetUserNameExW(NameSamCompatible, (ushort*)buffer, &bufferSize); + ptrBuildTrusteeWithNameW(¤tUserTrusteeW, (ushort*)buffer); } + FreeLibrary(userHnd); } } } - free(versionData); } + free(versionData); } - FreeLibrary(versionHnd); } + FreeLibrary(versionHnd); } ptrOpenProcessToken = (PtrOpenProcessToken)GetProcAddress(advapiHnd, "OpenProcessToken"); - HINSTANCE userenvHnd = LoadLibraryW(L"userenv"); + HINSTANCE userenvHnd = LoadLibraryW(L"userenv"); if (userenvHnd) { ptrGetUserProfileDirectoryW = (PtrGetUserProfileDirectoryW)GetProcAddress(userenvHnd, "GetUserProfileDirectoryW"); } @@ -225,120 +223,60 @@ void QFSFileEnginePrivate::resolveLibs() #endif // QT_NO_LIBRARY // UNC functions NT -typedef DWORD (WINAPI *PtrNetShareEnum_NT)(LPWSTR, DWORD, LPBYTE*, DWORD, LPDWORD, LPDWORD, LPDWORD); -static PtrNetShareEnum_NT ptrNetShareEnum_NT = 0; -typedef DWORD (WINAPI *PtrNetApiBufferFree_NT)(LPVOID); -static PtrNetApiBufferFree_NT ptrNetApiBufferFree_NT = 0; -typedef struct _SHARE_INFO_1_NT { +typedef DWORD (WINAPI *PtrNetShareEnum)(LPWSTR, DWORD, LPBYTE*, DWORD, LPDWORD, LPDWORD, LPDWORD); +static PtrNetShareEnum ptrNetShareEnum = 0; +typedef DWORD (WINAPI *PtrNetApiBufferFree)(LPVOID); +static PtrNetApiBufferFree ptrNetApiBufferFree = 0; +typedef struct _SHARE_INFO_1 { LPWSTR shi1_netname; DWORD shi1_type; LPWSTR shi1_remark; -} SHARE_INFO_1_NT; +} SHARE_INFO_1; -bool QFSFileEnginePrivate::resolveUNCLibs_NT() +bool QFSFileEnginePrivate::resolveUNCLibs() { static bool triedResolve = false; if (!triedResolve) { #ifndef QT_NO_THREAD QMutexLocker locker(QMutexPool::globalInstanceGet(&triedResolve)); if (triedResolve) { - return ptrNetShareEnum_NT && ptrNetApiBufferFree_NT; + return ptrNetShareEnum && ptrNetApiBufferFree; } #endif triedResolve = true; #if !defined(Q_OS_WINCE) HINSTANCE hLib = LoadLibraryW(L"Netapi32"); if (hLib) { - ptrNetShareEnum_NT = (PtrNetShareEnum_NT)GetProcAddress(hLib, "NetShareEnum"); - if (ptrNetShareEnum_NT) - ptrNetApiBufferFree_NT = (PtrNetApiBufferFree_NT)GetProcAddress(hLib, "NetApiBufferFree"); - } -#endif - } - return ptrNetShareEnum_NT && ptrNetApiBufferFree_NT; -} - -// UNC functions 9x -typedef DWORD (WINAPI *PtrNetShareEnum_9x)(const char FAR *, short, char FAR *, unsigned short, unsigned short FAR *, unsigned short FAR *); -static PtrNetShareEnum_9x ptrNetShareEnum_9x = 0; -#ifdef LM20_NNLEN -# define LM20_NNLEN_9x LM20_NNLEN -#else -# define LM20_NNLEN_9x 12 -#endif -typedef struct _SHARE_INFO_1_9x { - char shi1_netname[LM20_NNLEN_9x+1]; - char shi1_pad1; - unsigned short shi1_type; - char FAR* shi1_remark; -} SHARE_INFO_1_9x; - -bool QFSFileEnginePrivate::resolveUNCLibs_9x() -{ - static bool triedResolve = false; - if (!triedResolve) { -#ifndef QT_NO_THREAD - QMutexLocker locker(QMutexPool::globalInstanceGet(&triedResolve)); - if (triedResolve) { - return ptrNetShareEnum_9x; + ptrNetShareEnum = (PtrNetShareEnum)GetProcAddress(hLib, "NetShareEnum"); + if (ptrNetShareEnum) + ptrNetApiBufferFree = (PtrNetApiBufferFree)GetProcAddress(hLib, "NetApiBufferFree"); } #endif - triedResolve = true; -#if !defined(Q_OS_WINCE) - HINSTANCE hLib = LoadLibraryA("Svrapi"); - if (hLib) - ptrNetShareEnum_9x = (PtrNetShareEnum_9x)GetProcAddress(hLib, "NetShareEnum"); -#endif } - return ptrNetShareEnum_9x; + return ptrNetShareEnum && ptrNetApiBufferFree; } bool QFSFileEnginePrivate::uncListSharesOnServer(const QString &server, QStringList *list) { - if (resolveUNCLibs_NT()) { - SHARE_INFO_1_NT *BufPtr, *p; + if (resolveUNCLibs()) { + SHARE_INFO_1 *BufPtr, *p; DWORD res; DWORD er=0,tr=0,resume=0, i; do { - res = ptrNetShareEnum_NT((wchar_t*)server.utf16(), 1, (LPBYTE *)&BufPtr, DWORD(-1), &er, &tr, &resume); + res = ptrNetShareEnum((wchar_t*)server.utf16(), 1, (LPBYTE *)&BufPtr, DWORD(-1), &er, &tr, &resume); if (res == ERROR_SUCCESS || res == ERROR_MORE_DATA) { p=BufPtr; for (i = 1; i <= er; ++i) { if (list && p->shi1_type == 0) - list->append(QString::fromUtf16((unsigned short *)p->shi1_netname)); + list->append(QString::fromWCharArray(p->shi1_netname)); p++; } } - ptrNetApiBufferFree_NT(BufPtr); + ptrNetApiBufferFree(BufPtr); } while (res==ERROR_MORE_DATA); return res == ERROR_SUCCESS; - } else if (resolveUNCLibs_9x()) { - SHARE_INFO_1_9x *pBuf = 0; - short cbBuffer; - unsigned short nEntriesRead = 0; - unsigned short nTotalEntries = 0; - short numBuffs = 20; - DWORD nStatus = 0; - do { - cbBuffer = numBuffs * sizeof(SHARE_INFO_1_9x); - pBuf = (SHARE_INFO_1_9x *)malloc(cbBuffer); - if (pBuf) { - nStatus = ptrNetShareEnum_9x(server.toLocal8Bit().constData(), 1, (char FAR *)pBuf, cbBuffer, &nEntriesRead, &nTotalEntries); - if ((nStatus == ERROR_SUCCESS)) { - for (int i = 0; i < nEntriesRead; ++i) { - if (list && pBuf[i].shi1_type == 0) - list->append(QString::fromLocal8Bit(pBuf[i].shi1_netname)); - } - free(pBuf); - break; - } - free(pBuf); - numBuffs *=2; - } - } while (nStatus == ERROR_MORE_DATA); - return nStatus == ERROR_SUCCESS; } return false; } @@ -399,39 +337,19 @@ static bool uncShareExists(const QString &server) return false; } -#if !defined(Q_OS_WINCE) -// If you change this function, remember to also change the UNICODE version -static QString nativeAbsoluteFilePathA(const QString &path) -{ - QString ret; - QVarLengthArray buf(MAX_PATH); - char *fileName = 0; - QByteArray ba = path.toLocal8Bit(); - DWORD retLen = GetFullPathNameA(ba.constData(), buf.size(), buf.data(), &fileName); - if (retLen > (DWORD)buf.size()) { - buf.resize(retLen); - retLen = GetFullPathNameA(ba.constData(), buf.size(), buf.data(), &fileName); - } - if (retLen != 0) - ret = QString::fromLocal8Bit(buf.data(), retLen); - return ret; -} -#endif - -// If you change this function, remember to also change the NON-UNICODE version -static QString nativeAbsoluteFilePathW(const QString &path) +static QString nativeAbsoluteFilePathCore(const QString &path) { QString ret; #if !defined(Q_OS_WINCE) QVarLengthArray buf(MAX_PATH); wchar_t *fileName = 0; - DWORD retLen = GetFullPathNameW((wchar_t*)path.utf16(), buf.size(), buf.data(), &fileName); + DWORD retLen = GetFullPathName((wchar_t*)path.utf16(), buf.size(), buf.data(), &fileName); if (retLen > (DWORD)buf.size()) { buf.resize(retLen); - retLen = GetFullPathNameW((wchar_t*)path.utf16(), buf.size(), buf.data(), &fileName); + retLen = GetFullPathName((wchar_t*)path.utf16(), buf.size(), buf.data(), &fileName); } if (retLen != 0) - ret = QString::fromUtf16((unsigned short *)buf.data(), retLen); + ret = QString::fromWCharArray(buf.data(), retLen); #else if (path.startsWith(QLatin1Char('/')) || path.startsWith(QLatin1Char('\\'))) ret = QDir::toNativeSeparators(path); @@ -443,7 +361,7 @@ static QString nativeAbsoluteFilePathW(const QString &path) static QString nativeAbsoluteFilePath(const QString &path) { - QString absPath = QT_WA_INLINE(nativeAbsoluteFilePathW(path), nativeAbsoluteFilePathA(path)); + QString absPath = nativeAbsoluteFilePathCore(path); // This is really ugly, but GetFullPathName strips off whitespace at the end. // If you for instance write ". " in the lineedit of QFileDialog, // (which is an invalid filename) this function will strip the space off and viola, @@ -461,26 +379,6 @@ static QString nativeAbsoluteFilePath(const QString &path) return absPath; } -QByteArray QFSFileEnginePrivate::win95Name(const QString &path) -{ - QString ret(path); - if(path.length() > 1 && path[0] == QLatin1Char('/') && path[1] == QLatin1Char('/')) { - // Win95 cannot handle slash-slash needs slosh-slosh. - ret[0] = QLatin1Char('\\'); - ret[1] = QLatin1Char('\\'); - int n = ret.indexOf(QLatin1Char('/')); - if(n >= 0) - ret[n] = QLatin1Char('\\'); - } else if(path.length() > 3 && path[2] == QLatin1Char('/') && path[3] == QLatin1Char('/')) { - ret[2] = QLatin1Char('\\'); - ret.remove(3, 1); - int n = ret.indexOf(QLatin1Char('/')); - if(n >= 0) - ret[n] = QLatin1Char('\\'); - } - return ret.toLocal8Bit(); -} - /*! \internal */ @@ -507,13 +405,8 @@ QString QFSFileEnginePrivate::longFileName(const QString &path) */ void QFSFileEnginePrivate::nativeInitFileName() { - QT_WA({ - QString path = longFileName(QDir::toNativeSeparators(fixIfRelativeUncPath(filePath))); - nativeFilePath = QByteArray((const char *)path.utf16(), path.size() * 2 + 1); - }, { - QString path = fixIfRelativeUncPath(filePath); - nativeFilePath = win95Name(path).replace('/', '\\'); - }); + QString path = longFileName(QDir::toNativeSeparators(fixIfRelativeUncPath(filePath))); + nativeFilePath = QByteArray((const char *)path.utf16(), path.size() * 2 + 1); } /* @@ -539,23 +432,13 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) ? OPEN_ALWAYS : OPEN_EXISTING; // Create the file handle. - QT_WA({ - fileHandle = CreateFileW((TCHAR *)nativeFilePath.constData(), - accessRights, - shareMode, - &securityAtts, - creationDisp, - FILE_ATTRIBUTE_NORMAL, - NULL); - }, { - fileHandle = CreateFileA(nativeFilePath.constData(), - accessRights, - shareMode, - &securityAtts, - creationDisp, - FILE_ATTRIBUTE_NORMAL, - NULL); - }); + fileHandle = CreateFile((const wchar_t*)nativeFilePath.constData(), + accessRights, + shareMode, + &securityAtts, + creationDisp, + FILE_ATTRIBUTE_NORMAL, + NULL); // Bail out on error. if (fileHandle == INVALID_HANDLE_VALUE) { @@ -641,15 +524,9 @@ qint64 QFSFileEnginePrivate::nativeSize() const // Not-open mode, where the file name is known: We'll check the // file system directly. if (openMode == QIODevice::NotOpen && !nativeFilePath.isEmpty()) { - bool ok = false; WIN32_FILE_ATTRIBUTE_DATA attribData; - QT_WA({ - ok = ::GetFileAttributesExW((TCHAR *)nativeFilePath.constData(), - GetFileExInfoStandard, &attribData); - } , { - ok = ::GetFileAttributesExA(nativeFilePath.constData(), + bool ok = ::GetFileAttributesEx((const wchar_t*)nativeFilePath.constData(), GetFileExInfoStandard, &attribData); - }); if (ok) { qint64 size = attribData.nFileSizeHigh; size <<= 32; @@ -949,35 +826,21 @@ bool QFSFileEnginePrivate::nativeIsSequential() const bool QFSFileEngine::remove() { Q_D(QFSFileEngine); - QT_WA({ - return ::DeleteFileW((TCHAR*)QFSFileEnginePrivate::longFileName(d->filePath).utf16()) != 0; - } , { - return ::DeleteFileA(QFSFileEnginePrivate::win95Name(d->filePath)) != 0; - }); + return ::DeleteFile((wchar_t*)QFSFileEnginePrivate::longFileName(d->filePath).utf16()) != 0; } bool QFSFileEngine::copy(const QString ©Name) { Q_D(QFSFileEngine); - QT_WA({ - return ::CopyFileW((TCHAR*)QFSFileEnginePrivate::longFileName(d->filePath).utf16(), - (TCHAR*)QFSFileEnginePrivate::longFileName(copyName).utf16(), true) != 0; - } , { - return ::CopyFileA(QFSFileEnginePrivate::win95Name(d->filePath), - QFSFileEnginePrivate::win95Name(copyName), true) != 0; - }); + return ::CopyFile((wchar_t*)QFSFileEnginePrivate::longFileName(d->filePath).utf16(), + (wchar_t*)QFSFileEnginePrivate::longFileName(copyName).utf16(), true) != 0; } bool QFSFileEngine::rename(const QString &newName) { Q_D(QFSFileEngine); - QT_WA({ - return ::MoveFileW((TCHAR*)QFSFileEnginePrivate::longFileName(d->filePath).utf16(), - (TCHAR*)QFSFileEnginePrivate::longFileName(newName).utf16()) != 0; - } , { - return ::MoveFileA(QFSFileEnginePrivate::win95Name(d->filePath), - QFSFileEnginePrivate::win95Name(newName)) != 0; - }); + return ::MoveFile((wchar_t*)QFSFileEnginePrivate::longFileName(d->filePath).utf16(), + (wchar_t*)QFSFileEnginePrivate::longFileName(newName).utf16()) != 0; } static inline bool mkDir(const QString &path) @@ -1001,20 +864,12 @@ static inline bool mkDir(const QString &path) if (platformId == 1 && QFSFileEnginePrivate::longFileName(path).size() > 256) return false; #endif - QT_WA({ - return ::CreateDirectoryW((TCHAR*)QFSFileEnginePrivate::longFileName(path).utf16(), 0); - } , { - return ::CreateDirectoryA(QFSFileEnginePrivate::win95Name(QFileInfo(path).absoluteFilePath()), 0); - }); + return ::CreateDirectory((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(), 0); } static inline bool rmDir(const QString &path) { - QT_WA({ - return ::RemoveDirectoryW((TCHAR*)QFSFileEnginePrivate::longFileName(path).utf16()); - } , { - return ::RemoveDirectoryA(QFSFileEnginePrivate::win95Name(QFileInfo(path).absoluteFilePath())); - }); + return ::RemoveDirectory((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16()); } static inline bool isDirPath(const QString &dirPath, bool *existed) @@ -1023,12 +878,7 @@ static inline bool isDirPath(const QString &dirPath, bool *existed) if (path.length() == 2 &&path.at(1) == QLatin1Char(':')) path += QLatin1Char('\\'); - DWORD fileAttrib = INVALID_FILE_ATTRIBUTES; - QT_WA({ - fileAttrib = ::GetFileAttributesW((TCHAR*)QFSFileEnginePrivate::longFileName(path).utf16()); - } , { - fileAttrib = ::GetFileAttributesA(QFSFileEnginePrivate::win95Name(QFileInfo(path).absoluteFilePath())); - }); + DWORD fileAttrib = ::GetFileAttributes((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16()); if (existed) *existed = fileAttrib != INVALID_FILE_ATTRIBUTES; @@ -1110,16 +960,10 @@ bool QFSFileEngine::setCurrentPath(const QString &path) return false; #if !defined(Q_OS_WINCE) - int r; - QT_WA({ - r = ::SetCurrentDirectoryW((WCHAR*)path.utf16()); - } , { - r = ::SetCurrentDirectoryA(QFSFileEnginePrivate::win95Name(path)); - }); - return r != 0; + return ::SetCurrentDirectory((wchar_t*)path.utf16()) != 0; #else - qfsPrivateCurrentDir = QFSFileEnginePrivate::longFileName(path); - return true; + qfsPrivateCurrentDir = QFSFileEnginePrivate::longFileName(path); + return true; #endif } @@ -1132,48 +976,34 @@ QString QFSFileEngine::currentPath(const QString &fileName) fileName.at(0).isLetter() && fileName.at(1) == QLatin1Char(':')) { int drv = fileName.toUpper().at(0).toLatin1() - 'A' + 1; if (_getdrive() != drv) { - QT_WA({ - TCHAR buf[PATH_MAX]; - ::_wgetdcwd(drv, buf, PATH_MAX); - ret.setUtf16((ushort*)buf, uint(::wcslen(buf))); - }, { - char buf[PATH_MAX]; - ::_getdcwd(drv, buf, PATH_MAX); - ret = QString::fromLatin1(buf); - }); + wchar_t buf[PATH_MAX]; + ::_wgetdcwd(drv, buf, PATH_MAX); + ret = QString::fromWCharArray(buf); } } if (ret.isEmpty()) { //just the pwd - QT_WA({ - DWORD size = 0; - WCHAR currentName[PATH_MAX]; - size = ::GetCurrentDirectoryW(PATH_MAX, currentName); - if (size !=0) { - if (size > PATH_MAX) { - WCHAR * newCurrentName = new WCHAR[size]; - if (::GetCurrentDirectoryW(PATH_MAX, newCurrentName) != 0) - ret = QString::fromUtf16((ushort*)newCurrentName); - delete [] newCurrentName; - } else { - ret = QString::fromUtf16((ushort*)currentName); - } + DWORD size = 0; + wchar_t currentName[PATH_MAX]; + size = ::GetCurrentDirectory(PATH_MAX, currentName); + if (size != 0) { + if (size > PATH_MAX) { + wchar_t *newCurrentName = new wchar_t[size]; + if (::GetCurrentDirectory(PATH_MAX, newCurrentName) != 0) + ret = QString::fromWCharArray(newCurrentName); + delete [] newCurrentName; + } else { + ret = QString::fromWCharArray(currentName); } - } , { - DWORD size = 0; - char currentName[PATH_MAX]; - size = ::GetCurrentDirectoryA(PATH_MAX, currentName); - if (size !=0) - ret = QString::fromLocal8Bit(currentName); - }); + } } if (ret.length() >= 2 && ret[1] == QLatin1Char(':')) ret[0] = ret.at(0).toUpper(); // Force uppercase drive letters. return QDir::fromNativeSeparators(ret); #else - Q_UNUSED(fileName); - if (qfsPrivateCurrentDir.isEmpty()) - qfsPrivateCurrentDir = QCoreApplication::applicationDirPath(); + Q_UNUSED(fileName); + if (qfsPrivateCurrentDir.isEmpty()) + qfsPrivateCurrentDir = QCoreApplication::applicationDirPath(); return QDir::fromNativeSeparators(qfsPrivateCurrentDir); #endif @@ -1183,35 +1013,27 @@ QString QFSFileEngine::homePath() { QString ret; #if !defined(QT_NO_LIBRARY) - QT_WA ( - { - QFSFileEnginePrivate::resolveLibs(); - if (ptrOpenProcessToken && ptrGetUserProfileDirectoryW) { - HANDLE hnd = ::GetCurrentProcess(); - HANDLE token = 0; - BOOL ok = ::ptrOpenProcessToken(hnd, TOKEN_QUERY, &token); - if (ok) { - DWORD dwBufferSize = 0; - // First call, to determine size of the strings (with '\0'). - ok = ::ptrGetUserProfileDirectoryW(token, NULL, &dwBufferSize); - if (!ok && dwBufferSize != 0) { // We got the required buffer size - wchar_t *userDirectory = new wchar_t[dwBufferSize]; - // Second call, now we can fill the allocated buffer. - ok = ::ptrGetUserProfileDirectoryW(token, userDirectory, &dwBufferSize); - if (ok) - ret = QString::fromUtf16((ushort*)userDirectory); - - delete [] userDirectory; - } - ::CloseHandle(token); - } - } - } - , - { - // GetUserProfileDirectory is only available from NT 4.0, - // so fall through for Win98 and friends version. - }) + QFSFileEnginePrivate::resolveLibs(); + if (ptrOpenProcessToken && ptrGetUserProfileDirectoryW) { + HANDLE hnd = ::GetCurrentProcess(); + HANDLE token = 0; + BOOL ok = ::ptrOpenProcessToken(hnd, TOKEN_QUERY, &token); + if (ok) { + DWORD dwBufferSize = 0; + // First call, to determine size of the strings (with '\0'). + ok = ::ptrGetUserProfileDirectoryW(token, NULL, &dwBufferSize); + if (!ok && dwBufferSize != 0) { // We got the required buffer size + wchar_t *userDirectory = new wchar_t[dwBufferSize]; + // Second call, now we can fill the allocated buffer. + ok = ::ptrGetUserProfileDirectoryW(token, userDirectory, &dwBufferSize); + if (ok) + ret = QString::fromWCharArray(userDirectory); + + delete [] userDirectory; + } + ::CloseHandle(token); + } + } #endif if(ret.isEmpty() || !QFile::exists(ret)) { ret = QString::fromLocal8Bit(qgetenv("USERPROFILE").constData()); @@ -1251,17 +1073,10 @@ QString QFSFileEngine::rootPath() QString QFSFileEngine::tempPath() { - QString ret; - int success; - QT_WA({ - wchar_t tempPath[MAX_PATH]; - success = GetTempPathW(MAX_PATH, tempPath); - ret = QString::fromUtf16((ushort*)tempPath); - } , { - char tempPath[MAX_PATH]; - success = GetTempPathA(MAX_PATH, tempPath); - ret = QString::fromLocal8Bit(tempPath); - }); + wchar_t tempPath[MAX_PATH]; + int success = GetTempPath(MAX_PATH, tempPath); + QString ret = QString::fromWCharArray(tempPath); + if (ret.isEmpty() || !success) { #if !defined(Q_OS_WINCE) ret = QString::fromLatin1("c:/tmp"); @@ -1285,7 +1100,7 @@ QFileInfoList QFSFileEngine::drives() #elif defined(Q_OS_OS2EMX) quint32 driveBits, cur; if(DosQueryCurrentDisk(&cur,&driveBits) != NO_ERROR) - exit(1); + exit(1); driveBits &= 0x3ffffff; #endif char driveName[] = "A:/"; @@ -1327,18 +1142,14 @@ bool QFSFileEnginePrivate::doStat() const } } #else - DWORD tmpAttributes = GetFileAttributesW((TCHAR*)QFSFileEnginePrivate::longFileName(fname).utf16()); + DWORD tmpAttributes = GetFileAttributes((wchar_t*)QFSFileEnginePrivate::longFileName(fname).utf16()); if (tmpAttributes != -1) { fileAttrib = tmpAttributes; could_stat = true; } #endif } else { - QT_WA({ - fileAttrib = GetFileAttributesW((TCHAR*)QFSFileEnginePrivate::longFileName(fname).utf16()); - } , { - fileAttrib = GetFileAttributesA(QFSFileEnginePrivate::win95Name(QFileInfo(fname).absoluteFilePath())); - }); + fileAttrib = GetFileAttributes((wchar_t*)QFSFileEnginePrivate::longFileName(fname).utf16()); could_stat = fileAttrib != INVALID_FILE_ATTRIBUTES; if (!could_stat) { #if !defined(Q_OS_WINCE) @@ -1398,74 +1209,39 @@ static QString readLink(const QString &link) #if !defined(Q_OS_WINCE) #if !defined(QT_NO_LIBRARY) QString ret; - QT_WA({ - bool neededCoInit = false; - IShellLink *psl; // pointer to IShellLink i/f - HRESULT hres; - WIN32_FIND_DATA wfd; - TCHAR szGotPath[MAX_PATH]; - // Get pointer to the IShellLink interface. - hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, - IID_IShellLink, (LPVOID *)&psl); - if(hres == CO_E_NOTINITIALIZED) { // COM was not initialized - neededCoInit = true; - CoInitialize(NULL); - hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, - IID_IShellLink, (LPVOID *)&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)link.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)) { - if (psl->GetPath(szGotPath, MAX_PATH, &wfd, SLGP_UNCPRIORITY) == NOERROR) - ret = QString::fromUtf16((ushort*)szGotPath); - } - ppf->Release(); - } - psl->Release(); - } - if(neededCoInit) - CoUninitialize(); - } , { - bool neededCoInit = false; - IShellLinkA *psl; // pointer to IShellLink i/f - HRESULT hres; - WIN32_FIND_DATAA wfd; - char szGotPath[MAX_PATH]; - // Get pointer to the IShellLink interface. + bool neededCoInit = false; + IShellLink *psl; // pointer to IShellLink i/f + WIN32_FIND_DATA wfd; + wchar_t szGotPath[MAX_PATH]; - hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, - IID_IShellLinkA, (LPVOID *)&psl); + // Get pointer to the IShellLink interface. + HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *)&psl); - if(hres == CO_E_NOTINITIALIZED) { // COM was not initialized - neededCoInit = true; - CoInitialize(NULL); - hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, - IID_IShellLinkA, (LPVOID *)&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)QFileInfo(link).absoluteFilePath().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)) { - if (psl->GetPath((char*)szGotPath, MAX_PATH, &wfd, SLGP_UNCPRIORITY) == NOERROR) - ret = QString::fromLocal8Bit(szGotPath); - } - ppf->Release(); + if (hres == CO_E_NOTINITIALIZED) { // COM was not initialized + neededCoInit = true; + CoInitialize(NULL); + hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, + IID_IShellLink, (LPVOID *)&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)link.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)) { + if (psl->GetPath(szGotPath, MAX_PATH, &wfd, SLGP_UNCPRIORITY) == NOERROR) + ret = QString::fromWCharArray(szGotPath); } - psl->Release(); + ppf->Release(); } - if(neededCoInit) - CoUninitialize(); - }); + psl->Release(); + } + if (neededCoInit) + CoUninitialize(); + return ret; #else Q_UNUSED(link); @@ -1475,7 +1251,7 @@ static QString readLink(const QString &link) wchar_t target[MAX_PATH]; QString result; if (SHGetShortcutTarget((wchar_t*)QFileInfo(link).absoluteFilePath().replace(QLatin1Char('/'),QLatin1Char('\\')).utf16(), target, MAX_PATH)) { - result = QString::fromUtf16(reinterpret_cast (target)); + result = QString::fromWCharArray(target); if (result.startsWith(QLatin1Char('"'))) result.remove(0,1); if (result.endsWith(QLatin1Char('"'))) @@ -1502,76 +1278,37 @@ bool QFSFileEngine::link(const QString &newName) QString linkName = newName; //### assume that they add .lnk - QT_WA({ - HRESULT hres; - IShellLink *psl; - bool neededCoInit = false; + IShellLink *psl; + bool neededCoInit = false; - 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)) { - hres = psl->SetPath((wchar_t *)fileName(AbsoluteName).replace(QLatin1Char('/'), QLatin1Char('\\')).utf16()); - if (SUCCEEDED(hres)) { - hres = psl->SetWorkingDirectory((wchar_t *)fileName(AbsolutePathName).replace(QLatin1Char('/'), QLatin1Char('\\')).utf16()); - if (SUCCEEDED(hres)) { - IPersistFile *ppf; - hres = psl->QueryInterface(IID_IPersistFile, (void **)&ppf); - if (SUCCEEDED(hres)) { - hres = ppf->Save((TCHAR*)linkName.utf16(), TRUE); - if (SUCCEEDED(hres)) - ret = true; - ppf->Release(); - } - } - } - psl->Release(); - } - if(neededCoInit) - CoUninitialize(); - } , { - // the SetPath() call _sometimes_ changes the current path and when it does it sometimes - // does not let us change it back unless we call currentPath() many times. - QString cwd = currentPath(); - HRESULT hres; - IShellLinkA *psl; - bool neededCoInit = false; + 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(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)) { + hres = psl->SetPath((wchar_t *)fileName(AbsoluteName).replace(QLatin1Char('/'), QLatin1Char('\\')).utf16()); if (SUCCEEDED(hres)) { - currentPath(); - hres = psl->SetPath((char *)QString::fromLocal8Bit(QFSFileEnginePrivate::win95Name(fileName(AbsoluteName))).utf16()); - currentPath(); + hres = psl->SetWorkingDirectory((wchar_t *)fileName(AbsolutePathName).replace(QLatin1Char('/'), QLatin1Char('\\')).utf16()); if (SUCCEEDED(hres)) { - hres = psl->SetWorkingDirectory((char *)QString::fromLocal8Bit(QFSFileEnginePrivate::win95Name(fileName(AbsolutePathName))).utf16()); - currentPath(); + IPersistFile *ppf; + hres = psl->QueryInterface(IID_IPersistFile, (void **)&ppf); if (SUCCEEDED(hres)) { - IPersistFile *ppf; - hres = psl->QueryInterface(IID_IPersistFile, (void **)&ppf); - if (SUCCEEDED(hres)) { - currentPath(); - hres = ppf->Save((LPCOLESTR)linkName.utf16(), TRUE); - currentPath(); - if (SUCCEEDED(hres)) - ret = true; - ppf->Release(); - } + hres = ppf->Save((wchar_t*)linkName.utf16(), TRUE); + if (SUCCEEDED(hres)) + ret = true; + ppf->Release(); } - psl->Release(); } } - if(neededCoInit) + psl->Release(); + } + if(neededCoInit) CoUninitialize(); - setCurrentPath(cwd); - }); + return ret; #else Q_UNUSED(newName); @@ -1598,9 +1335,9 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions() const #if !defined(QT_NO_LIBRARY) if((qt_ntfs_permission_lookup > 0) && ((QSysInfo::WindowsVersion&QSysInfo::WV_NT_based) > QSysInfo::WV_NT)) { - PSID pOwner = 0; - PSID pGroup = 0; - PACL pDacl; + PSID pOwner = 0; + PSID pGroup = 0; + PACL pDacl; PSECURITY_DESCRIPTOR pSD; ACCESS_MASK access_mask; @@ -1610,42 +1347,42 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions() const QString fname = filePath.endsWith(QLatin1String(".lnk")) ? readLink(filePath) : filePath; DWORD res = ptrGetNamedSecurityInfoW((wchar_t*)fname.utf16(), SE_FILE_OBJECT, - OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, - &pOwner, &pGroup, &pDacl, 0, &pSD); + OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, + &pOwner, &pGroup, &pDacl, 0, &pSD); if(res == ERROR_SUCCESS) { TRUSTEE_W trustee; { //user if(ptrGetEffectiveRightsFromAclW(pDacl, ¤tUserTrusteeW, &access_mask) != ERROR_SUCCESS) access_mask = (ACCESS_MASK)-1; - if(access_mask & ReadMask) - ret |= QAbstractFileEngine::ReadUserPerm; - if(access_mask & WriteMask) - ret |= QAbstractFileEngine::WriteUserPerm; - if(access_mask & ExecMask) - ret |= QAbstractFileEngine::ExeUserPerm; + if(access_mask & ReadMask) + ret |= QAbstractFileEngine::ReadUserPerm; + if(access_mask & WriteMask) + ret |= QAbstractFileEngine::WriteUserPerm; + if(access_mask & ExecMask) + ret |= QAbstractFileEngine::ExeUserPerm; } { //owner ptrBuildTrusteeWithSidW(&trustee, pOwner); if(ptrGetEffectiveRightsFromAclW(pDacl, &trustee, &access_mask) != ERROR_SUCCESS) access_mask = (ACCESS_MASK)-1; - if(access_mask & ReadMask) - ret |= QAbstractFileEngine::ReadOwnerPerm; - if(access_mask & WriteMask) - ret |= QAbstractFileEngine::WriteOwnerPerm; - if(access_mask & ExecMask) - ret |= QAbstractFileEngine::ExeOwnerPerm; + if(access_mask & ReadMask) + ret |= QAbstractFileEngine::ReadOwnerPerm; + if(access_mask & WriteMask) + ret |= QAbstractFileEngine::WriteOwnerPerm; + if(access_mask & ExecMask) + ret |= QAbstractFileEngine::ExeOwnerPerm; } { //group ptrBuildTrusteeWithSidW(&trustee, pGroup); if(ptrGetEffectiveRightsFromAclW(pDacl, &trustee, &access_mask) != ERROR_SUCCESS) access_mask = (ACCESS_MASK)-1; - if(access_mask & ReadMask) - ret |= QAbstractFileEngine::ReadGroupPerm; - if(access_mask & WriteMask) - ret |= QAbstractFileEngine::WriteGroupPerm; - if(access_mask & ExecMask) - ret |= QAbstractFileEngine::ExeGroupPerm; + if(access_mask & ReadMask) + ret |= QAbstractFileEngine::ReadGroupPerm; + if(access_mask & WriteMask) + ret |= QAbstractFileEngine::WriteGroupPerm; + if(access_mask & ExecMask) + ret |= QAbstractFileEngine::ExeGroupPerm; } { //other (world) // Create SID for Everyone (World) @@ -1655,12 +1392,12 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions() const ptrBuildTrusteeWithSidW(&trustee, pWorld); if(ptrGetEffectiveRightsFromAclW(pDacl, &trustee, &access_mask) != ERROR_SUCCESS) access_mask = (ACCESS_MASK)-1; // ### - if(access_mask & ReadMask) - ret |= QAbstractFileEngine::ReadOtherPerm; - if(access_mask & WriteMask) - ret |= QAbstractFileEngine::WriteOtherPerm; - if(access_mask & ExecMask) - ret |= QAbstractFileEngine::ExeOtherPerm; + if(access_mask & ReadMask) + ret |= QAbstractFileEngine::ReadOtherPerm; + if(access_mask & WriteMask) + ret |= QAbstractFileEngine::WriteOtherPerm; + if(access_mask & ExecMask) + ret |= QAbstractFileEngine::ExeOtherPerm; } ptrFreeSid(pWorld); } @@ -1670,13 +1407,13 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions() const } else #endif { - //### what to do with permissions if we don't use ntfs or are not on a NT system - // for now just add all permissions and what about exe missions ?? - // also qt_ntfs_permission_lookup is now not set by defualt ... should it ? - ret |= QAbstractFileEngine::ReadOtherPerm | QAbstractFileEngine::ReadGroupPerm - | QAbstractFileEngine::ReadOwnerPerm | QAbstractFileEngine::ReadUserPerm - | QAbstractFileEngine::WriteUserPerm | QAbstractFileEngine::WriteOwnerPerm - | QAbstractFileEngine::WriteGroupPerm | QAbstractFileEngine::WriteOtherPerm; + //### what to do with permissions if we don't use NTFS + // for now just add all permissions and what about exe missions ?? + // also qt_ntfs_permission_lookup is now not set by defualt ... should it ? + ret |= QAbstractFileEngine::ReadOtherPerm | QAbstractFileEngine::ReadGroupPerm + | QAbstractFileEngine::ReadOwnerPerm | QAbstractFileEngine::ReadUserPerm + | QAbstractFileEngine::WriteUserPerm | QAbstractFileEngine::WriteOwnerPerm + | QAbstractFileEngine::WriteGroupPerm | QAbstractFileEngine::WriteOtherPerm; } if (doStat()) { @@ -1911,13 +1648,9 @@ bool QFSFileEngine::setPermissions(uint perms) return false; #if !defined(Q_OS_WINCE) - QT_WA({ - ret = ::_wchmod((TCHAR*)d->filePath.utf16(), mode) == 0; - } , { - ret = ::_chmod(d->filePath.toLocal8Bit(), mode) == 0; - }); + ret = ::_wchmod((wchar_t*)d->filePath.utf16(), mode) == 0; #else - ret = ::_wchmod((TCHAR*)d->longFileName(d->filePath).utf16(), mode); + ret = ::_wchmod((wchar_t*)d->longFileName(d->filePath).utf16(), mode); #endif return ret; } @@ -1960,34 +1693,33 @@ bool QFSFileEngine::setSize(qint64 size) static inline QDateTime fileTimeToQDateTime(const FILETIME *time) { QDateTime ret; - if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based || QSysInfo::WindowsVersion & QSysInfo::WV_CE_based) { - // SystemTimeToTzSpecificLocalTime is not available on Win98/ME so we have to pull it off ourselves. - SYSTEMTIME systime; - FILETIME ftime; - systime.wYear = 1970; - systime.wMonth = 1; - systime.wDay = 1; - systime.wHour = 0; - systime.wMinute = 0; - systime.wSecond = 0; - systime.wMilliseconds = 0; - systime.wDayOfWeek = 4; - SystemTimeToFileTime(&systime, &ftime); - unsigned __int64 acttime = (unsigned __int64)time->dwHighDateTime << 32 | time->dwLowDateTime; - FileTimeToSystemTime(time, &systime); - unsigned __int64 time1970 = (unsigned __int64)ftime.dwHighDateTime << 32 | ftime.dwLowDateTime; - unsigned __int64 difftime = acttime - time1970; - difftime /= 10000000; - ret.setTime_t((unsigned int)difftime); - } else { -#ifndef Q_OS_WINCE - SYSTEMTIME sTime, lTime; - FileTimeToSystemTime(time, &sTime); - SystemTimeToTzSpecificLocalTime(0, &sTime, &lTime); - ret.setDate(QDate(lTime.wYear, lTime.wMonth, lTime.wDay)); - ret.setTime(QTime(lTime.wHour, lTime.wMinute, lTime.wSecond, lTime.wMilliseconds)); + +#if defined(Q_OS_WINCE) + SYSTEMTIME systime; + FILETIME ftime; + systime.wYear = 1970; + systime.wMonth = 1; + systime.wDay = 1; + systime.wHour = 0; + systime.wMinute = 0; + systime.wSecond = 0; + systime.wMilliseconds = 0; + systime.wDayOfWeek = 4; + SystemTimeToFileTime(&systime, &ftime); + unsigned __int64 acttime = (unsigned __int64)time->dwHighDateTime << 32 | time->dwLowDateTime; + FileTimeToSystemTime(time, &systime); + unsigned __int64 time1970 = (unsigned __int64)ftime.dwHighDateTime << 32 | ftime.dwLowDateTime; + unsigned __int64 difftime = acttime - time1970; + difftime /= 10000000; + ret.setTime_t((unsigned int)difftime); +#else + SYSTEMTIME sTime, lTime; + FileTimeToSystemTime(time, &sTime); + SystemTimeToTzSpecificLocalTime(0, &sTime, &lTime); + ret.setDate(QDate(lTime.wYear, lTime.wMonth, lTime.wDay)); + ret.setTime(QTime(lTime.wHour, lTime.wMinute, lTime.wSecond, lTime.wMilliseconds)); #endif - } + return ret; } @@ -2011,13 +1743,8 @@ QDateTime QFSFileEngine::fileTime(FileTime time) const } #endif } else { - bool ok = false; WIN32_FILE_ATTRIBUTE_DATA attribData; - QT_WA({ - ok = ::GetFileAttributesExW((TCHAR*)QFSFileEnginePrivate::longFileName(d->filePath).utf16(), GetFileExInfoStandard, &attribData); - } , { - ok = ::GetFileAttributesExA(QFSFileEnginePrivate::win95Name(QFileInfo(d->filePath).absoluteFilePath()), GetFileExInfoStandard, &attribData); - }); + bool ok = ::GetFileAttributesEx((wchar_t*)QFSFileEnginePrivate::longFileName(d->filePath).utf16(), GetFileExInfoStandard, &attribData); if (ok) { if(time == CreationTime) ret = fileTimeToQDateTime(&attribData.ftCreationTime); @@ -2037,11 +1764,11 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, Q_UNUSED(flags); if (openMode == QFile::NotOpen) { q->setError(QFile::PermissionsError, qt_error_string()); - return 0; + return 0; } if (offset == 0 && size == 0) { q->setError(QFile::UnspecifiedError, qt_error_string()); - return 0; + return 0; } @@ -2054,7 +1781,7 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, #ifdef Q_USE_DEPRECATED_MAP_API nativeClose(); if (fileMapHandle == INVALID_HANDLE_VALUE) { - fileMapHandle = CreateFileForMappingW((TCHAR *)nativeFilePath.constData(), + fileMapHandle = CreateFileForMapping((const wchar_t*)nativeFilePath.constData(), GENERIC_READ | (openMode & QIODevice::WriteOnly ? GENERIC_WRITE : 0), 0, NULL, @@ -2069,21 +1796,14 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, #endif // first create the file mapping handle - HANDLE mapHandle = 0; DWORD protection = (openMode & QIODevice::WriteOnly) ? PAGE_READWRITE : PAGE_READONLY; - QT_WA({ - mapHandle = ::CreateFileMappingW(handle, 0, protection, - 0, 0, 0); - },{ - mapHandle = ::CreateFileMappingA(handle, 0, protection, - 0, 0, 0); - }); + HANDLE mapHandle = ::CreateFileMapping(handle, 0, protection, 0, 0, 0); if (mapHandle == NULL) { q->setError(QFile::PermissionsError, qt_error_string()); #ifdef Q_USE_DEPRECATED_MAP_API mapHandleClose(); #endif - return 0; + return 0; } // setup args to map @@ -2112,7 +1832,7 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, switch(GetLastError()) { case ERROR_ACCESS_DENIED: q->setError(QFile::PermissionsError, qt_error_string()); - break; + break; case ERROR_INVALID_PARAMETER: // size are out of bounds default: diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index d028df1..eae17b4 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -54,7 +54,7 @@ #include #include -#include "private/qfsfileengine_p.h" // for longFileName and win95FileName +#include "private/qfsfileengine_p.h" // for longFileName #ifndef QT_NO_PROCESS @@ -122,25 +122,15 @@ bool QProcessPrivate::createChannel(Channel &channel) if (&channel == &stdinChannel) { // try to open in read-only mode channel.pipe[1] = INVALID_Q_PIPE; - QT_WA({ - channel.pipe[0] = - CreateFileW((TCHAR*)QFSFileEnginePrivate::longFileName(channel.file).utf16(), - GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, - &secAtt, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - }, { - channel.pipe[0] = - CreateFileA(QFSFileEnginePrivate::win95Name(channel.file), - GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, - &secAtt, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - }); + channel.pipe[0] = + CreateFile((const wchar_t*)QFSFileEnginePrivate::longFileName(channel.file).utf16(), + GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + &secAtt, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (channel.pipe[0] != INVALID_Q_PIPE) return true; @@ -148,31 +138,15 @@ bool QProcessPrivate::createChannel(Channel &channel) } else { // open in write mode channel.pipe[0] = INVALID_Q_PIPE; - DWORD creation; - if (channel.append) - creation = OPEN_ALWAYS; - else - creation = CREATE_ALWAYS; - - QT_WA({ - channel.pipe[1] = - CreateFileW((TCHAR*)QFSFileEnginePrivate::longFileName(channel.file).utf16(), - GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - &secAtt, - creation, - FILE_ATTRIBUTE_NORMAL, - NULL); - }, { - channel.pipe[1] = - CreateFileA(QFSFileEnginePrivate::win95Name(channel.file), - GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - &secAtt, - creation, - FILE_ATTRIBUTE_NORMAL, - NULL); - }); + channel.pipe[1] = + CreateFile((const wchar_t *)QFSFileEnginePrivate::longFileName(channel.file).utf16(), + GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + &secAtt, + channel.append ? OPEN_ALWAYS : CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (channel.pipe[1] != INVALID_Q_PIPE) { if (channel.append) { SetFilePointer(channel.pipe[1], 0, NULL, FILE_END); @@ -327,56 +301,37 @@ static QByteArray qt_create_environment(const QHash *environme int pos = 0; QHash::ConstIterator it = copy.constBegin(), end = copy.constEnd(); -#ifdef UNICODE - if (!(QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based)) { - static const TCHAR equal = L'='; - static const TCHAR nul = L'\0'; - - for ( ; it != end; ++it) { - uint tmpSize = sizeof(TCHAR) * (it.key().length() + it.value().length() + 2); - // ignore empty strings - if (tmpSize == sizeof(TCHAR)*2) - continue; - envlist.resize(envlist.size() + tmpSize); - - tmpSize = it.key().length() * sizeof(TCHAR); - memcpy(envlist.data()+pos, it.key().utf16(), tmpSize); - pos += tmpSize; - - memcpy(envlist.data()+pos, &equal, sizeof(TCHAR)); - pos += sizeof(TCHAR); - - tmpSize = it.value().length() * sizeof(TCHAR); - memcpy(envlist.data()+pos, it.value().utf16(), tmpSize); - pos += tmpSize; - - memcpy(envlist.data()+pos, &nul, sizeof(TCHAR)); - pos += sizeof(TCHAR); - } - // add the 2 terminating 0 (actually 4, just to be on the safe side) - envlist.resize( envlist.size()+4 ); - envlist[pos++] = 0; - envlist[pos++] = 0; - envlist[pos++] = 0; - envlist[pos++] = 0; - } else -#endif // UNICODE - { - for ( ; it != end; it++) { - QByteArray tmp = it.key().toLocal8Bit(); - tmp.append('='); - tmp.append(it.value().toLocal8Bit()); - - uint tmpSize = tmp.length() + 1; - envlist.resize(envlist.size() + tmpSize); - memcpy(envlist.data()+pos, tmp.data(), tmpSize); - pos += tmpSize; - } - // add the terminating 0 (actually 2, just to be on the safe side) - envlist.resize(envlist.size()+2); - envlist[pos++] = 0; - envlist[pos++] = 0; + + static const wchar_t equal = L'='; + static const wchar_t nul = L'\0'; + + for ( ; it != end; ++it) { + uint tmpSize = sizeof(wchar_t) * (it.key().length() + it.value().length() + 2); + // ignore empty strings + if (tmpSize == sizeof(wchar_t) * 2) + continue; + envlist.resize(envlist.size() + tmpSize); + + tmpSize = it.key().length() * sizeof(wchar_t); + memcpy(envlist.data()+pos, it.key().utf16(), tmpSize); + pos += tmpSize; + + memcpy(envlist.data()+pos, &equal, sizeof(wchar_t)); + pos += sizeof(wchar_t); + + tmpSize = it.value().length() * sizeof(wchar_t); + memcpy(envlist.data()+pos, it.value().utf16(), tmpSize); + pos += tmpSize; + + memcpy(envlist.data()+pos, &nul, sizeof(wchar_t)); + pos += sizeof(wchar_t); } + // add the 2 terminating 0 (actually 4, just to be on the safe side) + envlist.resize( envlist.size()+4 ); + envlist[pos++] = 0; + envlist[pos++] = 0; + envlist[pos++] = 0; + envlist[pos++] = 0; } return envlist; } @@ -417,58 +372,33 @@ void QProcessPrivate::startProcess() qDebug(" pass environment : %s", environment.isEmpty() ? "no" : "yes"); #endif - DWORD dwCreationFlags = 0; - if (!(QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based)) - dwCreationFlags |= CREATE_NO_WINDOW; + DWORD dwCreationFlags = CREATE_NO_WINDOW; -#ifdef UNICODE - if (!(QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based)) { #if defined(Q_OS_WINCE) QString fullPathProgram = program; if (!QDir::isAbsolutePath(fullPathProgram)) fullPathProgram = QFileInfo(fullPathProgram).absoluteFilePath(); fullPathProgram.replace(QLatin1Char('/'), QLatin1Char('\\')); - success = CreateProcessW((WCHAR*)fullPathProgram.utf16(), - (WCHAR*)args.utf16(), - 0, 0, false, 0, 0, 0, 0, pid); + success = CreateProcess((wchar_t*)fullPathProgram.utf16(), + (wchar_t*)args.utf16(), + 0, 0, false, 0, 0, 0, 0, pid); #else dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT; STARTUPINFOW startupInfo = { sizeof( STARTUPINFO ), 0, 0, 0, (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, - (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, - 0, 0, 0, - STARTF_USESTDHANDLES, - 0, 0, 0, - stdinChannel.pipe[0], stdoutChannel.pipe[1], stderrChannel.pipe[1] + (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, + 0, 0, 0, + STARTF_USESTDHANDLES, + 0, 0, 0, + stdinChannel.pipe[0], stdoutChannel.pipe[1], stderrChannel.pipe[1] }; - success = CreateProcessW(0, (WCHAR*)args.utf16(), - 0, 0, TRUE, dwCreationFlags, - environment ? envlist.data() : 0, - workingDirectory.isEmpty() ? 0 - : (WCHAR*)QDir::toNativeSeparators(workingDirectory).utf16(), - &startupInfo, pid); -#endif - } else -#endif // UNICODE - { -#ifndef Q_OS_WINCE - STARTUPINFOA startupInfo = { sizeof( STARTUPINFOA ), 0, 0, 0, - (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, - (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, - 0, 0, 0, - STARTF_USESTDHANDLES, - 0, 0, 0, - stdinChannel.pipe[0], stdoutChannel.pipe[1], stderrChannel.pipe[1] - }; - - success = CreateProcessA(0, args.toLocal8Bit().data(), - 0, 0, TRUE, dwCreationFlags, environment ? envlist.data() : 0, - workingDirectory.isEmpty() ? 0 - : QDir::toNativeSeparators(workingDirectory).toLocal8Bit().data(), - &startupInfo, pid); -#endif // Q_OS_WINCE - } -#ifndef Q_OS_WINCE + success = CreateProcess(0, (wchar_t*)args.utf16(), + 0, 0, TRUE, dwCreationFlags, + environment ? envlist.data() : 0, + workingDirectory.isEmpty() ? 0 + : (wchar_t*)QDir::toNativeSeparators(workingDirectory).utf16(), + &startupInfo, pid); + if (stdinChannel.pipe[0] != INVALID_Q_PIPE) { CloseHandle(stdinChannel.pipe[0]); stdinChannel.pipe[0] = INVALID_Q_PIPE; @@ -508,7 +438,7 @@ void QProcessPrivate::startProcess() } // give the process a chance to start ... - Sleep(SLEEPMIN*2); + Sleep(SLEEPMIN * 2); _q_startupNotification(); } @@ -882,42 +812,25 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a PROCESS_INFORMATION pinfo; -#ifdef UNICODE - if (!(QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based)) { #if defined(Q_OS_WINCE) QString fullPathProgram = program; if (!QDir::isAbsolutePath(fullPathProgram)) fullPathProgram.prepend(QDir::currentPath().append(QLatin1Char('/'))); fullPathProgram.replace(QLatin1Char('/'), QLatin1Char('\\')); - success = CreateProcessW((WCHAR*)fullPathProgram.utf16(), - (WCHAR*)args.utf16(), - 0, 0, false, CREATE_NEW_CONSOLE, 0, 0, 0, &pinfo); + success = CreateProcess((wchar_t*)fullPathProgram.utf16(), + (wchar_t*)args.utf16(), + 0, 0, false, CREATE_NEW_CONSOLE, 0, 0, 0, &pinfo); #else STARTUPINFOW startupInfo = { sizeof( STARTUPINFO ), 0, 0, 0, (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - success = CreateProcessW(0, (WCHAR*)args.utf16(), - 0, 0, FALSE, CREATE_UNICODE_ENVIRONMENT | CREATE_NEW_CONSOLE, 0, - workingDir.isEmpty() ? (const WCHAR *)0 : (const WCHAR *)workingDir.utf16(), - &startupInfo, &pinfo); -#endif - } else -#endif // UNICODE - { -#ifndef Q_OS_WINCE - STARTUPINFOA startupInfo = { sizeof( STARTUPINFOA ), 0, 0, 0, - (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, - (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - success = CreateProcessA(0, args.toLocal8Bit().data(), - 0, 0, FALSE, CREATE_NEW_CONSOLE, 0, - workingDir.isEmpty() ? (LPCSTR)0 : workingDir.toLocal8Bit().constData(), + success = CreateProcess(0, (wchar_t*)args.utf16(), + 0, 0, FALSE, CREATE_UNICODE_ENVIRONMENT | CREATE_NEW_CONSOLE, 0, + workingDir.isEmpty() ? 0 : (wchar_t*)workingDir.utf16(), &startupInfo, &pinfo); #endif // Q_OS_WINCE - } if (success) { CloseHandle(pinfo.hThread); diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 3f8dc36f..7de5030 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -1037,33 +1037,16 @@ static QString windowsConfigPath(int type) // This only happens when bootstrapping qmake. #ifndef Q_OS_WINCE QLibrary library(QLatin1String("shell32")); - QT_WA( { - typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPTSTR, int, BOOL); - GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPathW"); - if (SHGetSpecialFolderPath) { - TCHAR path[MAX_PATH]; - SHGetSpecialFolderPath(0, path, type, FALSE); - result = QString::fromUtf16((ushort*)path); - } - } , { - typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, char*, int, BOOL); - GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPathA"); - if (SHGetSpecialFolderPath) { - char path[MAX_PATH]; - SHGetSpecialFolderPath(0, path, type, FALSE); - result = QString::fromLocal8Bit(path); - } - } ); #else QLibrary library(QLatin1String("coredll")); - typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPTSTR, int, BOOL); - GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPath"); +#endif // Q_OS_WINCE + typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPWSTR, int, BOOL); + GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPathW"); if (SHGetSpecialFolderPath) { wchar_t path[MAX_PATH]; SHGetSpecialFolderPath(0, path, type, FALSE); - result = QString::fromUtf16((ushort*)path); + result = QString::fromWCharArray(path); } -#endif // Q_OS_WINCE #endif // QT_NO_QOBJECT @@ -1459,11 +1442,7 @@ void QConfFileSettingsPrivate::syncConfFile(int confFileNo) QString writeSemName = QLatin1String("QSettingsWriteSem "); writeSemName.append(file.fileName()); - QT_WA( { - writeSemaphore = CreateSemaphoreW(0, 1, 1, reinterpret_cast(writeSemName.utf16())); - } , { - writeSemaphore = CreateSemaphoreA(0, 1, 1, writeSemName.toLocal8Bit()); - } ); + writeSemaphore = CreateSemaphore(0, 1, 1, reinterpret_cast(writeSemName.utf16())); if (writeSemaphore) { WaitForSingleObject(writeSemaphore, INFINITE); @@ -1479,11 +1458,7 @@ void QConfFileSettingsPrivate::syncConfFile(int confFileNo) QString readSemName(QLatin1String("QSettingsReadSem ")); readSemName.append(file.fileName()); - QT_WA( { - readSemaphore = CreateSemaphoreW(0, FileLockSemMax, FileLockSemMax, reinterpret_cast(readSemName.utf16())); - } , { - readSemaphore = CreateSemaphoreA(0, FileLockSemMax, FileLockSemMax, readSemName.toLocal8Bit()); - } ); + readSemaphore = CreateSemaphore(0, FileLockSemMax, FileLockSemMax, reinterpret_cast(readSemName.utf16())); if (readSemaphore) { for (int i = 0; i < numReadLocks; ++i) diff --git a/src/corelib/io/qsettings_win.cpp b/src/corelib/io/qsettings_win.cpp index 0cbcc10..1e1509d 100644 --- a/src/corelib/io/qsettings_win.cpp +++ b/src/corelib/io/qsettings_win.cpp @@ -130,24 +130,13 @@ static void mergeKeySets(NameSet *dest, const QStringList &src) static QString errorCodeToString(DWORD errorCode) { - QString result; - QT_WA({ - wchar_t *data = 0; - FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - 0, errorCode, 0, - data, 0, 0); - result = QString::fromUtf16(reinterpret_cast (data)); - if (data != 0) - LocalFree(data); - }, { - char *data = 0; - FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - 0, errorCode, 0, - (char *)&data, 0, 0); - result = QString::fromLocal8Bit(data); - if (data != 0) - LocalFree(data); - }) + wchar_t *data = 0; + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 0, errorCode, 0, data, 0, 0); + QString result = QString::fromWCharArray(data); + + if (data != 0) + LocalFree(data); + if (result.endsWith(QLatin1Char('\n'))) result.truncate(result.length() - 1); @@ -158,15 +147,8 @@ static QString errorCodeToString(DWORD errorCode) static HKEY openKey(HKEY parentHandle, REGSAM perms, const QString &rSubKey) { HKEY resultHandle = 0; - - LONG res; - QT_WA( { - res = RegOpenKeyExW(parentHandle, reinterpret_cast(rSubKey.utf16()), - 0, perms, &resultHandle); - } , { - res = RegOpenKeyExA(parentHandle, rSubKey.toLocal8Bit(), + LONG res = RegOpenKeyEx(parentHandle, reinterpret_cast(rSubKey.utf16()), 0, perms, &resultHandle); - } ); if (res == ERROR_SUCCESS) return resultHandle; @@ -183,14 +165,8 @@ static HKEY createOrOpenKey(HKEY parentHandle, REGSAM perms, const QString &rSub return resultHandle; // try to create it - LONG res; - QT_WA( { - res = RegCreateKeyExW(parentHandle, reinterpret_cast(rSubKey.utf16()), 0, 0, - REG_OPTION_NON_VOLATILE, perms, 0, &resultHandle, 0); - } , { - res = RegCreateKeyExA(parentHandle, rSubKey.toLocal8Bit(), 0, 0, + LONG res = RegCreateKeyEx(parentHandle, reinterpret_cast(rSubKey.utf16()), 0, 0, REG_OPTION_NON_VOLATILE, perms, 0, &resultHandle, 0); - } ); if (res == ERROR_SUCCESS) return resultHandle; @@ -225,20 +201,14 @@ static HKEY createOrOpenKey(HKEY parentHandle, const QString &rSubKey, bool *rea static QStringList childKeysOrGroups(HKEY parentHandle, QSettingsPrivate::ChildSpec spec) { QStringList result; - LONG res; DWORD numKeys; DWORD maxKeySize; DWORD numSubgroups; DWORD maxSubgroupSize; // Find the number of keys and subgroups, as well as the max of their lengths. - QT_WA( { - res = RegQueryInfoKeyW(parentHandle, 0, 0, 0, &numSubgroups, &maxSubgroupSize, 0, + LONG res = RegQueryInfoKey(parentHandle, 0, 0, 0, &numSubgroups, &maxSubgroupSize, 0, &numKeys, &maxKeySize, 0, 0, 0); - }, { - res = RegQueryInfoKeyA(parentHandle, 0, 0, 0, &numSubgroups, &maxSubgroupSize, 0, - &numKeys, &maxKeySize, 0, 0, 0); - } ); if (res != ERROR_SUCCESS) { qWarning("QSettings: RegQueryInfoKey() failed: %s", errorCodeToString(res).toLatin1().data()); @@ -258,36 +228,21 @@ static QStringList childKeysOrGroups(HKEY parentHandle, QSettingsPrivate::ChildS m = maxSubgroupSize; } - /* Windows NT/2000/XP: The size does not include the terminating null character. - Windows Me/98/95: The size includes the terminating null character. */ + /* The size does not include the terminating null character. */ ++m; // Get the list - QByteArray buff(m*sizeof(ushort), 0); + QByteArray buff(m * sizeof(wchar_t), 0); for (int i = 0; i < n; ++i) { QString item; - QT_WA( { - DWORD l = buff.size() / sizeof(ushort); - if (spec == QSettingsPrivate::ChildKeys) { - res = RegEnumValueW(parentHandle, i, - reinterpret_cast(buff.data()), - &l, 0, 0, 0, 0); - } else { - res = RegEnumKeyExW(parentHandle, i, - reinterpret_cast(buff.data()), - &l, 0, 0, 0, 0); - } - if (res == ERROR_SUCCESS) - item = QString::fromUtf16(reinterpret_cast(buff.data()), l); - }, { - DWORD l = buff.size(); - if (spec == QSettingsPrivate::ChildKeys) - res = RegEnumValueA(parentHandle, i, buff.data(), &l, 0, 0, 0, 0); - else - res = RegEnumKeyExA(parentHandle, i, buff.data(), &l, 0, 0, 0, 0); - if (res == ERROR_SUCCESS) - item = QString::fromLocal8Bit(buff.data(), l); - } ); + DWORD l = buff.size() / sizeof(wchar_t); + if (spec == QSettingsPrivate::ChildKeys) { + res = RegEnumValue(parentHandle, i, reinterpret_cast(buff.data()), &l, 0, 0, 0, 0); + } else { + res = RegEnumKeyEx(parentHandle, i, reinterpret_cast(buff.data()), &l, 0, 0, 0, 0); + } + if (res == ERROR_SUCCESS) + item = QString::fromWCharArray((const wchar_t *)buff.constData(), l); if (res != ERROR_SUCCESS) { qWarning("QSettings: RegEnumValue failed: %s", errorCodeToString(res).toLatin1().data()); @@ -342,12 +297,7 @@ static void deleteChildGroups(HKEY parentHandle) RegCloseKey(childGroupHandle); // delete group itself - LONG res; - QT_WA( { - res = RegDeleteKeyW(parentHandle, reinterpret_cast(group.utf16())); - }, { - res = RegDeleteKeyA(parentHandle, group.toLocal8Bit()); - } ); + LONG res = RegDeleteKey(parentHandle, reinterpret_cast(group.utf16())); if (res != ERROR_SUCCESS) { qWarning("QSettings: RegDeleteKey failed on subkey \"%s\": %s", group.toLatin1().data(), errorCodeToString(res).toLatin1().data()); @@ -519,12 +469,7 @@ bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVa // get the size and type of the value DWORD dataType; DWORD dataSize; - LONG res; - QT_WA( { - res = RegQueryValueExW(handle, reinterpret_cast(rSubkeyName.utf16()), 0, &dataType, 0, &dataSize); - }, { - res = RegQueryValueExA(handle, rSubkeyName.toLocal8Bit(), 0, &dataType, 0, &dataSize); - } ); + LONG res = RegQueryValueEx(handle, reinterpret_cast(rSubkeyName.utf16()), 0, &dataType, 0, &dataSize); if (res != ERROR_SUCCESS) { RegCloseKey(handle); return false; @@ -532,13 +477,8 @@ bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVa // get the value QByteArray data(dataSize, 0); - QT_WA( { - res = RegQueryValueExW(handle, reinterpret_cast(rSubkeyName.utf16()), 0, 0, - reinterpret_cast(data.data()), &dataSize); - }, { - res = RegQueryValueExA(handle, rSubkeyName.toLocal8Bit(), 0, 0, - reinterpret_cast(data.data()), &dataSize); - } ); + res = RegQueryValueEx(handle, reinterpret_cast(rSubkeyName.utf16()), 0, 0, + reinterpret_cast(data.data()), &dataSize); if (res != ERROR_SUCCESS) { RegCloseKey(handle); return false; @@ -549,11 +489,7 @@ bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVa case REG_SZ: { QString s; if (dataSize) { - QT_WA( { - s = QString::fromUtf16(((const ushort*)data.constData())); - }, { - s = QString::fromLocal8Bit(data.constData()); - } ); + s = QString::fromWCharArray(((const wchar_t *)data.constData())); } if (value != 0) *value = stringToVariant(s); @@ -565,12 +501,7 @@ bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVa if (dataSize) { int i = 0; for (;;) { - QString s; - QT_WA( { - s = QString::fromUtf16((const ushort*)data.constData() + i); - }, { - s = QString::fromLocal8Bit(data.constData() + i); - } ); + QString s = QString::fromWCharArray((const wchar_t *)data.constData() + i); i += s.length() + 1; if (s.isEmpty()) @@ -587,11 +518,7 @@ bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVa case REG_BINARY: { QString s; if (dataSize) { - QT_WA( { - s = QString::fromUtf16((const ushort*)data.constData(), data.size()/2); - }, { - s = QString::fromLocal8Bit(data.constData(), data.size()); - } ); + s = QString::fromWCharArray((const wchar_t *)data.constData(), data.size() / 2); } if (value != 0) *value = stringToVariant(s); @@ -635,13 +562,8 @@ QWinSettingsPrivate::~QWinSettingsPrivate() #if defined(Q_OS_WINCE) remove(regList.at(0).key()); #else - DWORD res; QString emptyKey; - QT_WA( { - res = RegDeleteKeyW(writeHandle(), reinterpret_cast(emptyKey.utf16())); - }, { - res = RegDeleteKeyA(writeHandle(), emptyKey.toLocal8Bit()); - } ); + DWORD res = RegDeleteKey(writeHandle(), reinterpret_cast(emptyKey.utf16())); if (res != ERROR_SUCCESS) { qWarning("QSettings: Failed to delete key \"%s\": %s", regList.at(0).key().toLatin1().data(), errorCodeToString(res).toLatin1().data()); @@ -666,11 +588,7 @@ void QWinSettingsPrivate::remove(const QString &uKey) LONG res; HKEY handle = openKey(writeHandle(), registryPermissions, keyPath(rKey)); if (handle != 0) { - QT_WA( { - res = RegDeleteValueW(handle, reinterpret_cast(keyName(rKey).utf16())); - }, { - res = RegDeleteValueA(handle, keyName(rKey).toLocal8Bit()); - } ); + res = RegDeleteValue(handle, reinterpret_cast(keyName(rKey).utf16())); RegCloseKey(handle); } @@ -685,12 +603,7 @@ void QWinSettingsPrivate::remove(const QString &uKey) for (int i = 0; i < childKeys.size(); ++i) { QString group = childKeys.at(i); - LONG res; - QT_WA( { - res = RegDeleteValueW(handle, reinterpret_cast(group.utf16())); - }, { - res = RegDeleteValueA(handle, group.toLocal8Bit()); - } ); + LONG res = RegDeleteValue(handle, reinterpret_cast(group.utf16())); if (res != ERROR_SUCCESS) { qWarning("QSettings: RegDeleteValue failed on subkey \"%s\": %s", group.toLatin1().data(), errorCodeToString(res).toLatin1().data()); @@ -701,11 +614,7 @@ void QWinSettingsPrivate::remove(const QString &uKey) // For WinCE always Close the handle first. RegCloseKey(handle); #endif - QT_WA( { - res = RegDeleteKeyW(writeHandle(), reinterpret_cast(rKey.utf16())); - }, { - res = RegDeleteKeyA(writeHandle(), rKey.toLocal8Bit()); - } ); + res = RegDeleteKey(writeHandle(), reinterpret_cast(rKey.utf16())); if (res != ERROR_SUCCESS) { qWarning("QSettings: RegDeleteKey failed on key \"%s\": %s", @@ -761,27 +670,15 @@ void QWinSettingsPrivate::set(const QString &uKey, const QVariant &value) if (type == REG_BINARY) { QString s = variantToString(value); - QT_WA( { - regValueBuff = QByteArray((const char*)s.utf16(), s.length()*2); - }, { - regValueBuff = QByteArray((const char*)s.toLocal8Bit(), s.length()); - } ); + regValueBuff = QByteArray((const char*)s.utf16(), s.length() * 2); } else { QStringList::const_iterator it = l.constBegin(); for (; it != l.constEnd(); ++it) { const QString &s = *it; - QT_WA( { - regValueBuff += QByteArray((const char*)s.utf16(), (s.length() + 1)*2); - }, { - regValueBuff += QByteArray((const char*)s.toLocal8Bit(), s.length() + 1); - } ); + regValueBuff += QByteArray((const char*)s.utf16(), (s.length() + 1) * 2); } - QT_WA( { - regValueBuff.append((char)0); - regValueBuff.append((char)0); - }, { - regValueBuff.append((char)0); - } ); + regValueBuff.append((char)0); + regValueBuff.append((char)0); } break; } @@ -794,21 +691,6 @@ void QWinSettingsPrivate::set(const QString &uKey, const QVariant &value) } case QVariant::ByteArray: - // On Win95/98/Me QString::toLocal8Bit() fails to handle chars > 0x7F. So we don't go through variantToString() at all. - if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) { - QByteArray ba = value.toByteArray(); - regValueBuff = "@ByteArray("; - regValueBuff += ba; - regValueBuff += ')'; - if (ba.contains('\0')) { - type = REG_BINARY; - } else { - type = REG_SZ; - regValueBuff += '\0'; - } - - break; - } // fallthrough intended default: { @@ -817,33 +699,18 @@ void QWinSettingsPrivate::set(const QString &uKey, const QVariant &value) QString s = variantToString(value); type = stringContainsNullChar(s) ? REG_BINARY : REG_SZ; if (type == REG_BINARY) { - QT_WA( { - regValueBuff = QByteArray((const char*)s.utf16(), s.length()*2); - }, { - regValueBuff = QByteArray((const char*)s.toLocal8Bit(), s.length()); - } ); + regValueBuff = QByteArray((const char*)s.utf16(), s.length() * 2); } else { - QT_WA( { - regValueBuff = QByteArray((const char*)s.utf16(), (s.length() + 1)*2); - }, { - regValueBuff = QByteArray((const char*)s.toLocal8Bit(), s.length() + 1); - } ); + regValueBuff = QByteArray((const char*)s.utf16(), (s.length() + 1) * 2); } break; } } // set the value - LONG res; - QT_WA( { - res = RegSetValueExW(handle, reinterpret_cast(keyName(rKey).utf16()), 0, type, - reinterpret_cast(regValueBuff.constData()), - regValueBuff.size()); - }, { - res = RegSetValueExA(handle, keyName(rKey).toLocal8Bit(), 0, type, + LONG res = RegSetValueEx(handle, reinterpret_cast(keyName(rKey).utf16()), 0, type, reinterpret_cast(regValueBuff.constData()), regValueBuff.size()); - } ); if (res == ERROR_SUCCESS) { deleteWriteHandleOnExit = false; diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index e6a471c..f0a3fec 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -1742,18 +1742,10 @@ QString QCoreApplication::applicationFilePath() return d->cachedApplicationFilePath; #if defined( Q_WS_WIN ) - QFileInfo filePath; - QT_WA({ - wchar_t module_name[MAX_PATH+1]; - GetModuleFileNameW(0, module_name, MAX_PATH); - module_name[MAX_PATH] = 0; - filePath = QString::fromUtf16((ushort *)module_name); - }, { - char module_name[MAX_PATH+1]; - GetModuleFileNameA(0, module_name, MAX_PATH); - module_name[MAX_PATH] = 0; - filePath = QString::fromLocal8Bit(module_name); - }); + wchar_t module_name[MAX_PATH]; + GetModuleFileName(0, module_name, MAX_PATH); + module_name[MAX_PATH] = 0; + QFileInfo filePath = QString::fromWCharArray(module_name); d->cachedApplicationFilePath = filePath.filePath(); return d->cachedApplicationFilePath; @@ -1902,13 +1894,13 @@ QStringList QCoreApplication::arguments() return list; } #ifdef Q_OS_WIN - QString cmdline = QT_WA_INLINE(QString::fromUtf16((unsigned short *)GetCommandLineW()), QString::fromLocal8Bit(GetCommandLineA())); + QString cmdline = QString::fromWCharArray(GetCommandLine()); #if defined(Q_OS_WINCE) wchar_t tempFilename[MAX_PATH+1]; - if (GetModuleFileNameW(0, tempFilename, MAX_PATH)) { + if (GetModuleFileName(0, tempFilename, MAX_PATH)) { tempFilename[MAX_PATH] = 0; - cmdline.prepend(QLatin1Char('\"') + QString::fromUtf16((unsigned short *)tempFilename) + QLatin1String("\" ")); + cmdline.prepend(QLatin1Char('\"') + QString::fromWCharArray(tempFilename) + QLatin1String("\" ")); } #endif // Q_OS_WINCE diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp index 7a35340..657abd1 100644 --- a/src/corelib/kernel/qcoreapplication_win.cpp +++ b/src/corelib/kernel/qcoreapplication_win.cpp @@ -45,14 +45,15 @@ #include "qt_windows.h" #include "qvector.h" #include "qmutex.h" +#include "qfileinfo.h" #include "qcorecmdlineargs_p.h" #include #include QT_BEGIN_NAMESPACE -char appFileName[MAX_PATH+1]; // application file name -char theAppName[MAX_PATH+1]; // application name +char appFileName[MAX_PATH]; // application file name +char theAppName[MAX_PATH]; // application name HINSTANCE appInst = 0; // handle to app instance HINSTANCE appPrevInst = 0; // handle to prev app instance int appCmdShow = 0; @@ -73,48 +74,35 @@ Q_CORE_EXPORT int qWinAppCmdShow() // get main window sho return appCmdShow; } +Q_CORE_EXPORT QString qAppFileName() // get application file name +{ + wchar_t buffer[MAX_PATH]; + GetModuleFileName(0, buffer, MAX_PATH); + return QString::fromWCharArray(buffer); +} void set_winapp_name() { static bool already_set = false; if (!already_set) { already_set = true; -#ifndef Q_OS_WINCE - GetModuleFileNameA(0, appFileName, sizeof(appFileName)); - appFileName[sizeof(appFileName)-1] = 0; -#else - QString afm; - afm.resize(sizeof(appFileName)); - afm.resize(GetModuleFileName(0, (wchar_t *) (afm.unicode()), sizeof(appFileName))); - memcpy(appFileName, afm.toLatin1(), sizeof(appFileName)); -#endif - const char *p = strrchr(appFileName, '\\'); // skip path - if (p) - memcpy(theAppName, p+1, qstrlen(p)); - int l = qstrlen(theAppName); - if ((l > 4) && !qstricmp(theAppName + l - 4, ".exe")) - theAppName[l-4] = '\0'; // drop .exe extension - if (appInst == 0) { - QT_WA({ - appInst = GetModuleHandle(0); - }, { - appInst = GetModuleHandleA(0); - }); - } - } -} + QString moduleName = qAppFileName(); -Q_CORE_EXPORT QString qAppFileName() // get application file name -{ - return QString::fromLatin1(appFileName); + QByteArray filePath = moduleName.toLocal8Bit(); + QByteArray fileName = QFileInfo(moduleName).baseName().toLocal8Bit(); + + memcpy(appFileName, filePath.constData(), filePath.length()); + memcpy(theAppName, fileName.constData(), fileName.length()); + + if (appInst == 0) + appInst = GetModuleHandle(0); + } } QString QCoreApplicationPrivate::appName() const { - if (!theAppName[0]) - set_winapp_name(); - return QString::fromLatin1(theAppName); + return QFileInfo(qAppFileName()).baseName(); } class QWinMsgHandlerCriticalSection @@ -145,15 +133,11 @@ Q_CORE_EXPORT void qWinMsgHandler(QtMsgType t, const char* str) str = "(null)"; staticCriticalSection.lock(); - QT_WA({ - QString s(QString::fromLocal8Bit(str)); - s += QLatin1Char('\n'); - OutputDebugStringW((TCHAR*)s.utf16()); - }, { - QByteArray s(str); - s += '\n'; - OutputDebugStringA(s.data()); - }) + + QString s(QString::fromLocal8Bit(str)); + s += QLatin1Char('\n'); + OutputDebugString((wchar_t*)s.utf16()); + staticCriticalSection.unlock(); } diff --git a/src/corelib/kernel/qcorecmdlineargs_p.h b/src/corelib/kernel/qcorecmdlineargs_p.h index c0dd813..a012b4e 100644 --- a/src/corelib/kernel/qcorecmdlineargs_p.h +++ b/src/corelib/kernel/qcorecmdlineargs_p.h @@ -135,9 +135,9 @@ static inline QStringList qWinCmdArgs(QString cmdLine) // not const-ref: this mi QStringList args; int argc = 0; - QVector argv = qWinCmdLine((ushort*)cmdLine.utf16(), cmdLine.length(), argc); + QVector argv = qWinCmdLine((wchar_t *)cmdLine.utf16(), cmdLine.length(), argc); for (int a = 0; a < argc; ++a) { - args << QString::fromUtf16(argv[a]); + args << QString::fromWCharArray(argv[a]); } return args; @@ -147,10 +147,7 @@ static inline QStringList qCmdLineArgs(int argc, char *argv[]) { Q_UNUSED(argc) Q_UNUSED(argv) - QString cmdLine = QT_WA_INLINE( - QString::fromUtf16((unsigned short*)GetCommandLineW()), - QString::fromLocal8Bit(GetCommandLineA()) - ); + QString cmdLine = QString::fromWCharArray(GetCommandLine()); return qWinCmdArgs(cmdLine); } diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index cb1549c..23e4fa9 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -355,8 +355,7 @@ QEventDispatcherWin32Private::QEventDispatcherWin32Private() { resolveTimerAPI(); - wakeUpNotifier.setHandle(QT_WA_INLINE(CreateEventW(0, FALSE, FALSE, 0), - CreateEventA(0, FALSE, FALSE, 0))); + wakeUpNotifier.setHandle(CreateEvent(0, FALSE, FALSE, 0)); if (!wakeUpNotifier.handle()) qWarning("QEventDispatcher: Creating QEventDispatcherWin32Private wakeup event failed"); } @@ -367,13 +366,8 @@ QEventDispatcherWin32Private::~QEventDispatcherWin32Private() CloseHandle(wakeUpNotifier.handle()); if (internalHwnd) DestroyWindow(internalHwnd); - QByteArray className = "QEventDispatcherWin32_Internal_Widget" + QByteArray::number(quintptr(qt_internal_proc)); -#if !defined(Q_OS_WINCE) - UnregisterClassA(className.constData(), qWinAppInst()); -#else - UnregisterClassW(reinterpret_cast (QString::fromLatin1(className.constData()).utf16()) - , qWinAppInst()); -#endif + QString className = QLatin1String("QEventDispatcherWin32_Internal_Widget") + QString::number(quintptr(qt_internal_proc)); + UnregisterClass((wchar_t*)className.utf16(), qWinAppInst()); } void QEventDispatcherWin32Private::activateEventNotifier(QWinEventNotifier * wen) @@ -382,18 +376,24 @@ void QEventDispatcherWin32Private::activateEventNotifier(QWinEventNotifier * wen QCoreApplication::sendEvent(wen, &event); } - +// ### Qt 5: remove Q_CORE_EXPORT bool winPeekMessage(MSG* msg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg) { - QT_WA({ return PeekMessage(msg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); } , - { return PeekMessageA(msg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); }); + return PeekMessage(msg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); } +// ### Qt 5: remove Q_CORE_EXPORT bool winPostMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - QT_WA({ return PostMessage(hWnd, msg, wParam, lParam); } , - { return PostMessageA(hWnd, msg, wParam, lParam); }); + return PostMessage(hWnd, msg, wParam, lParam); +} + +// ### Qt 5: remove +Q_CORE_EXPORT bool winGetMessage(MSG* msg, HWND hWnd, UINT wMsgFilterMin, + UINT wMsgFilterMax) +{ + return GetMessage(msg, hWnd, wMsgFilterMin, wMsgFilterMax); } // This function is called by a workerthread @@ -443,10 +443,10 @@ LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp) #ifdef GWLP_USERDATA QEventDispatcherWin32 *eventDispatcher = - (QEventDispatcherWin32 *) GetWindowLongPtrA(hwnd, GWLP_USERDATA); + (QEventDispatcherWin32 *) GetWindowLongPtr(hwnd, GWLP_USERDATA); #else QEventDispatcherWin32 *eventDispatcher = - (QEventDispatcherWin32 *) GetWindowLongA(hwnd, GWL_USERDATA); + (QEventDispatcherWin32 *) GetWindowLong(hwnd, GWL_USERDATA); #endif if (eventDispatcher) { QEventDispatcherWin32Private *d = eventDispatcher->d_func(); @@ -494,54 +494,35 @@ LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp) static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatcher) { - HINSTANCE hi = qWinAppInst(); -#if defined(Q_OS_WINCE) + // make sure that multiple Qt's can coexist in the same process + QString className = QLatin1Strign("QEventDispatcherWin32_Internal_Widget") + QString::number(quintptr(qt_internal_proc)); + WNDCLASS wc; -#else - WNDCLASSA wc; -#endif wc.style = 0; wc.lpfnWndProc = qt_internal_proc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; - wc.hInstance = hi; + wc.hInstance = qWinAppInst(); wc.hIcon = 0; wc.hCursor = 0; wc.hbrBackground = 0; wc.lpszMenuName = NULL; + wc.lpszClassName = reinterpret_cast (className.utf16()); - // make sure that multiple Qt's can coexist in the same process - QByteArray className = "QEventDispatcherWin32_Internal_Widget" + QByteArray::number(quintptr(qt_internal_proc)); -#if defined(Q_OS_WINCE) - QString tmp = QString::fromLatin1(className.data()); - wc.lpszClassName = reinterpret_cast (tmp.utf16()); RegisterClass(&wc); HWND wnd = CreateWindow(wc.lpszClassName, // classname - wc.lpszClassName, // window name - 0, // style - 0, 0, 0, 0, // geometry - 0, // parent - 0, // menu handle - hi, // application - 0); // windows creation data. -#else - wc.lpszClassName = className.constData(); - RegisterClassA(&wc); - HWND wnd = CreateWindowA(wc.lpszClassName, // classname - wc.lpszClassName, // window name - 0, // style - 0, 0, 0, 0, // geometry - 0, // parent - 0, // menu handle - hi, // application - 0); // windows creation data. -#endif - + wc.lpszClassName, // window name + 0, // style + 0, 0, 0, 0, // geometry + 0, // parent + 0, // menu handle + qWinAppInst(), // application + 0); // windows creation data. #ifdef GWLP_USERDATA - SetWindowLongPtrA(wnd, GWLP_USERDATA, (LONG_PTR)eventDispatcher); + SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR)eventDispatcher); #else - SetWindowLongA(wnd, GWL_USERDATA, (LONG)eventDispatcher); + SetWindowLong(wnd, GWL_USERDATA, (LONG)eventDispatcher); #endif if (!wnd) { @@ -690,7 +671,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) haveMessage = true; msg = d->queuedSocketEvents.takeFirst(); } else { - haveMessage = winPeekMessage(&msg, 0, 0, 0, PM_REMOVE); + haveMessage = PeekMessage(&msg, 0, 0, 0, PM_REMOVE); if (haveMessage && (flags & QEventLoop::ExcludeUserInputEvents) && ((msg.message >= WM_KEYFIRST && msg.message <= WM_KEYLAST) @@ -738,11 +719,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) if (!filterEvent(&msg)) { TranslateMessage(&msg); - QT_WA({ - DispatchMessage(&msg); - } , { - DispatchMessageA(&msg); - }); + DispatchMessage(&msg); } } else if (waitRet >= WAIT_OBJECT_0 && waitRet < WAIT_OBJECT_0 + nCount) { d->activateEventNotifier(d->winEventNotifierList.at(waitRet - WAIT_OBJECT_0)); @@ -781,7 +758,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) bool QEventDispatcherWin32::hasPendingEvents() { MSG msg; - return qGlobalPostedEventsCount() || winPeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); + return qGlobalPostedEventsCount() || PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); } void QEventDispatcherWin32::registerSocketNotifier(QSocketNotifier *notifier) diff --git a/src/corelib/kernel/qfunctions_wince.cpp b/src/corelib/kernel/qfunctions_wince.cpp index 2c47adb..5680ad5 100644 --- a/src/corelib/kernel/qfunctions_wince.cpp +++ b/src/corelib/kernel/qfunctions_wince.cpp @@ -108,7 +108,7 @@ int qt_wince__getdrive( void ) return 1; } -int qt_wince__waccess( const WCHAR *path, int pmode ) +int qt_wince__waccess( const wchar_t *path, int pmode ) { DWORD res = GetFileAttributes( path ); if ( 0xFFFFFFFF == res ) @@ -118,7 +118,7 @@ int qt_wince__waccess( const WCHAR *path, int pmode ) return -1; if ( (pmode & X_OK) && !(res & FILE_ATTRIBUTE_DIRECTORY) ) { - QString file = QString::fromUtf16(reinterpret_cast (path)); + QString file = QString::fromWCharArray(path); if ( !(file.endsWith(QString::fromLatin1(".exe")) || file.endsWith(QString::fromLatin1(".com"))) ) return -1; @@ -130,12 +130,12 @@ int qt_wince__waccess( const WCHAR *path, int pmode ) int qt_wince_open( const char *filename, int oflag, int pmode ) { QString fn( QString::fromLatin1(filename) ); - return _wopen( (WCHAR*)fn.utf16(), oflag, pmode ); + return _wopen( (wchar_t*)fn.utf16(), oflag, pmode ); } -int qt_wince__wopen( const WCHAR *filename, int oflag, int /*pmode*/ ) +int qt_wince__wopen( const wchar_t *filename, int oflag, int /*pmode*/ ) { - WCHAR *flag; + wchar_t *flag; if ( oflag & _O_APPEND ) { if ( oflag & _O_WRONLY ) { @@ -290,7 +290,7 @@ bool qt_wince__chmod(const char *file, int mode) return _wchmod( reinterpret_cast (QString::fromLatin1(file).utf16()), mode); } -bool qt_wince__wchmod(const WCHAR *file, int mode) +bool qt_wince__wchmod(const wchar_t *file, int mode) { // ### Does not work properly, what about just adding one property? if(mode&_S_IWRITE) { diff --git a/src/corelib/kernel/qfunctions_wince.h b/src/corelib/kernel/qfunctions_wince.h index 307e17b..41cb641 100644 --- a/src/corelib/kernel/qfunctions_wince.h +++ b/src/corelib/kernel/qfunctions_wince.h @@ -175,8 +175,8 @@ typedef int mode_t; extern int errno; int qt_wince__getdrive( void ); -int qt_wince__waccess( const WCHAR *path, int pmode ); -int qt_wince__wopen( const WCHAR *filename, int oflag, int pmode ); +int qt_wince__waccess( const wchar_t *path, int pmode ); +int qt_wince__wopen( const wchar_t *filename, int oflag, int pmode ); long qt_wince__lseek( int handle, long offset, int origin ); int qt_wince__read( int handle, void *buffer, unsigned int count ); int qt_wince__write( int handle, const void *buffer, unsigned int count ); @@ -204,7 +204,7 @@ int qt_wince_SetErrorMode(int); #endif bool qt_wince__chmod(const char *file, int mode); -bool qt_wince__wchmod(const WCHAR *file, int mode); +bool qt_wince__wchmod(const wchar_t *file, int mode); #pragma warning(disable: 4273) HANDLE qt_wince_CreateFileA(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE); diff --git a/src/corelib/kernel/qsharedmemory_win.cpp b/src/corelib/kernel/qsharedmemory_win.cpp index d963a6d..c88149a 100644 --- a/src/corelib/kernel/qsharedmemory_win.cpp +++ b/src/corelib/kernel/qsharedmemory_win.cpp @@ -106,16 +106,11 @@ HANDLE QSharedMemoryPrivate::handle() return false; } #ifndef Q_OS_WINCE - QT_WA({ - hand = OpenFileMappingW(FILE_MAP_ALL_ACCESS, false, (TCHAR*)safeKey.utf16()); - }, { - hand = OpenFileMappingA(FILE_MAP_ALL_ACCESS, false, safeKey.toLocal8Bit().constData()); - }); + hand = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, (wchar_t*)safeKey.utf16()); #else // This works for opening a mapping too, but always opens it with read/write access in // attach as it seems. - hand = CreateFileMappingW(INVALID_HANDLE_VALUE, - 0, PAGE_READWRITE, 0, 0, (TCHAR*)safeKey.utf16()); + hand = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, 0, (wchar_t*)safeKey.utf16()); #endif if (!hand) { setErrorString(function); @@ -148,13 +143,7 @@ bool QSharedMemoryPrivate::create(int size) } // Create the file mapping. - QT_WA( { - hand = CreateFileMappingW(INVALID_HANDLE_VALUE, - 0, PAGE_READWRITE, 0, size, (TCHAR*)safeKey.utf16()); - }, { - hand = CreateFileMappingA(INVALID_HANDLE_VALUE, - 0, PAGE_READWRITE, 0, size, safeKey.toLocal8Bit().constData()); - } ); + hand = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, size, (wchar_t*)safeKey.utf16()); setErrorString(function); // hand is valid when it already exists unlike unix so explicitly check diff --git a/src/corelib/kernel/qsystemsemaphore_win.cpp b/src/corelib/kernel/qsystemsemaphore_win.cpp index 4e03ddf..1102258 100644 --- a/src/corelib/kernel/qsystemsemaphore_win.cpp +++ b/src/corelib/kernel/qsystemsemaphore_win.cpp @@ -87,11 +87,7 @@ HANDLE QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode) // Create it if it doesn't already exists. if (semaphore == 0) { QString safeName = makeKeyFileName(); - QT_WA({ - semaphore = CreateSemaphoreW(0, initialValue, MAXLONG, (TCHAR*)safeName.utf16()); - }, { - semaphore = CreateSemaphoreA(0, initialValue, MAXLONG, safeName.toLocal8Bit().constData()); - }); + semaphore = CreateSemaphore(0, initialValue, MAXLONG, (wchar_t*)safeName.utf16()); if (semaphore == NULL) setErrorString(QLatin1String("QSystemSemaphore::handle")); } diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp index d2a0b3a..2ee9d26 100644 --- a/src/corelib/kernel/qtimer.cpp +++ b/src/corelib/kernel/qtimer.cpp @@ -103,9 +103,8 @@ QT_BEGIN_NAMESPACE Note that QTimer's accuracy depends on the underlying operating system and hardware. Most platforms support an accuracy of - 1 millisecond, but Windows 98 supports only 55. If Qt is - unable to deliver the requested number of timer clicks, it will - silently discard some. + 1 millisecond. If Qt is unable to deliver the requested number of + timer clicks, it will silently discard some. An alternative to using QTimer is to call QObject::startTimer() for your object and reimplement the QObject::timerEvent() event diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index 4d465dc..8f364ba 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -623,11 +623,7 @@ bool QLibraryPrivate::isPlugin(QSettings *settings) #endif if (!pHnd) { #ifdef Q_OS_WIN - QT_WA({ - hTempModule = ::LoadLibraryExW((wchar_t*)QDir::toNativeSeparators(fileName).utf16(), 0, DONT_RESOLVE_DLL_REFERENCES); - } , { - temporary_load = load_sys(); - }); + hTempModule = ::LoadLibraryEx((wchar_t*)QDir::toNativeSeparators(fileName).utf16(), 0, DONT_RESOLVE_DLL_REFERENCES); #else temporary_load = load_sys(); #endif @@ -641,7 +637,7 @@ bool QLibraryPrivate::isPlugin(QSettings *settings) QtPluginQueryVerificationDataFunction qtPluginQueryVerificationDataFunction = hTempModule ? (QtPluginQueryVerificationDataFunction) #ifdef Q_OS_WINCE - ::GetProcAddressW(hTempModule, L"qt_plugin_query_verification_data") + ::GetProcAddress(hTempModule, L"qt_plugin_query_verification_data") #else ::GetProcAddress(hTempModule, "qt_plugin_query_verification_data") #endif diff --git a/src/corelib/plugin/qlibrary_win.cpp b/src/corelib/plugin/qlibrary_win.cpp index 43eeafa..847c0d2 100644 --- a/src/corelib/plugin/qlibrary_win.cpp +++ b/src/corelib/plugin/qlibrary_win.cpp @@ -67,30 +67,18 @@ bool QLibraryPrivate::load_sys() //avoid 'Bad Image' message box UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX); - QT_WA({ - pHnd = LoadLibraryW((TCHAR*)QDir::toNativeSeparators(attempt).utf16()); - } , { - pHnd = LoadLibraryA(QFile::encodeName(QDir::toNativeSeparators(attempt)).data()); - }); - + pHnd = LoadLibrary((wchar_t*)QDir::toNativeSeparators(attempt).utf16()); + if (pluginState != IsAPlugin) { #if defined(Q_OS_WINCE) if (!pHnd && ::GetLastError() == ERROR_MOD_NOT_FOUND) { QString secondAttempt = fileName; - QT_WA({ - pHnd = LoadLibraryW((TCHAR*)QDir::toNativeSeparators(secondAttempt).utf16()); - } , { - pHnd = LoadLibraryA(QFile::encodeName(QDir::toNativeSeparators(secondAttempt)).data()); - }); + pHnd = LoadLibrary((wchar_t*)QDir::toNativeSeparators(secondAttempt).utf16()); } #endif if (!pHnd && ::GetLastError() == ERROR_MOD_NOT_FOUND) { attempt += QLatin1String(".dll"); - QT_WA({ - pHnd = LoadLibraryW((TCHAR*)QDir::toNativeSeparators(attempt).utf16()); - } , { - pHnd = LoadLibraryA(QFile::encodeName(QDir::toNativeSeparators(attempt)).data()); - }); + pHnd = LoadLibrary((wchar_t*)QDir::toNativeSeparators(attempt).utf16()); } } @@ -100,15 +88,11 @@ bool QLibraryPrivate::load_sys() } if (pHnd) { errorString.clear(); - QT_WA({ - TCHAR buffer[MAX_PATH + 1]; - ::GetModuleFileNameW(pHnd, buffer, MAX_PATH); - attempt = QString::fromUtf16(reinterpret_cast(&buffer)); - }, { - char buffer[MAX_PATH + 1]; - ::GetModuleFileNameA(pHnd, buffer, MAX_PATH); - attempt = QString::fromLocal8Bit(buffer); - }); + + wchar_t buffer[MAX_PATH]; + ::GetModuleFileName(pHnd, buffer, MAX_PATH); + attempt = QString::fromWCharArray(buffer); + const QDir dir = QFileInfo(fileName).dir(); const QString realfilename = attempt.mid(attempt.lastIndexOf(QLatin1Char('\\')) + 1); if (dir.path() == QLatin1String(".")) diff --git a/src/corelib/thread/qmutex_win.cpp b/src/corelib/thread/qmutex_win.cpp index f2022a5..1d247fc 100644 --- a/src/corelib/thread/qmutex_win.cpp +++ b/src/corelib/thread/qmutex_win.cpp @@ -50,19 +50,7 @@ QT_BEGIN_NAMESPACE QMutexPrivate::QMutexPrivate(QMutex::RecursionMode mode) : recursive(mode == QMutex::Recursive), contenders(0), lastSpinCount(0), owner(0), count(0) { - if (QSysInfo::WindowsVersion == 0) { - // mutex was created before initializing WindowsVersion. this - // can happen when creating the resource file engine handler, - // for example. try again with just the A version -#ifdef Q_OS_WINCE - event = CreateEventW(0, FALSE, FALSE, 0); -#else - event = CreateEventA(0, FALSE, FALSE, 0); -#endif - } else { - event = QT_WA_INLINE(CreateEventW(0, FALSE, FALSE, 0), - CreateEventA(0, FALSE, FALSE, 0)); - } + event = CreateEvent(0, FALSE, FALSE, 0); if (!event) qWarning("QMutexPrivate::QMutexPrivate: Cannot create event"); } diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index b5bdba3..6c24784 100644 --- a/src/corelib/thread/qthread_win.cpp +++ b/src/corelib/thread/qthread_win.cpp @@ -163,8 +163,7 @@ void qt_watch_adopted_thread(const HANDLE adoptedThreadHandle, QThread *qthread) // Start watcher thread if it is not already running. if (qt_adopted_thread_watcher_handle == 0) { if (qt_adopted_thread_wakeup == 0) { - qt_adopted_thread_wakeup = QT_WA_INLINE(CreateEventW(0, false, false, 0), - CreateEventA(0, false, false, 0)); + qt_adopted_thread_wakeup = CreateEvent(0, false, false, 0); qt_adopted_thread_handles.prepend(qt_adopted_thread_wakeup); } @@ -364,11 +363,10 @@ int QThread::idealThreadCount() void QThread::yieldCurrentThread() { #ifndef Q_OS_WINCE - if (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based) - SwitchToThread(); - else + SwitchToThread(); +#else + ::Sleep(0); #endif - ::Sleep(0); } void QThread::sleep(unsigned long secs) @@ -419,17 +417,11 @@ void QThread::start(Priority priority) return; } - // Since Win 9x will have problems if the priority is idle or time critical - // we have to use the closest one instead int prio; d->priority = priority; switch (d->priority) { case IdlePriority: - if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) { - prio = THREAD_PRIORITY_LOWEST; - } else { - prio = THREAD_PRIORITY_IDLE; - } + prio = THREAD_PRIORITY_IDLE; break; case LowestPriority: @@ -453,11 +445,7 @@ void QThread::start(Priority priority) break; case TimeCriticalPriority: - if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) { - prio = THREAD_PRIORITY_HIGHEST; - } else { - prio = THREAD_PRIORITY_TIME_CRITICAL; - } + prio = THREAD_PRIORITY_TIME_CRITICAL; break; case InheritPriority: @@ -563,17 +551,11 @@ void QThread::setPriority(Priority priority) // copied from start() with a few modifications: - // Since Win 9x will have problems if the priority is idle or time critical - // we have to use the closest one instead int prio; d->priority = priority; switch (d->priority) { case IdlePriority: - if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) { - prio = THREAD_PRIORITY_LOWEST; - } else { - prio = THREAD_PRIORITY_IDLE; - } + prio = THREAD_PRIORITY_IDLE; break; case LowestPriority: @@ -597,11 +579,7 @@ void QThread::setPriority(Priority priority) break; case TimeCriticalPriority: - if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) { - prio = THREAD_PRIORITY_HIGHEST; - } else { - prio = THREAD_PRIORITY_TIME_CRITICAL; - } + prio = THREAD_PRIORITY_TIME_CRITICAL; break; case InheritPriority: diff --git a/src/corelib/thread/qwaitcondition_win.cpp b/src/corelib/thread/qwaitcondition_win.cpp index 9129fb6..b0146d2 100644 --- a/src/corelib/thread/qwaitcondition_win.cpp +++ b/src/corelib/thread/qwaitcondition_win.cpp @@ -64,11 +64,7 @@ class QWaitConditionEvent public: inline QWaitConditionEvent() : priority(0), wokenUp(false) { - QT_WA ({ - event = CreateEvent(NULL, TRUE, FALSE, NULL); - }, { - event = CreateEventA(NULL, TRUE, FALSE, NULL); - }); + event = CreateEvent(NULL, TRUE, FALSE, NULL); } inline ~QWaitConditionEvent() { CloseHandle(event); } int priority; diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 6674717..42f4304 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -2503,16 +2503,9 @@ QString QDateTime::toString(Qt::DateFormat f) const buf += QLatin1Char(' '); buf += QString::number(d->date.day()); #else - QString winstr; - QT_WA({ - TCHAR out[255]; - GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ILDATE, out, 255); - winstr = QString::fromUtf16((ushort*)out); - } , { - char out[255]; - GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_ILDATE, (char*)&out, 255); - winstr = QString::fromLocal8Bit(out); - }); + wchar_t out[255]; + GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ILDATE, out, 255); + QString winstr = QString::fromWCharArray(out); switch (winstr.toInt()) { case 1: buf = d->date.shortDayName(d->date.dayOfWeek()); diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 8c1a0ff..fef1931 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -386,15 +386,8 @@ static QString winIso3116CtryName(LCID id = LOCALE_USER_DEFAULT); static QString getWinLocaleInfo(LCTYPE type) { - int cnt = 0; - LCID id = GetUserDefaultLCID(); - - 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)", (int)type); @@ -403,27 +396,14 @@ static QString getWinLocaleInfo(LCTYPE type) QByteArray buff(cnt, 0); - QT_WA({ - cnt = GetLocaleInfoW(id, type, - reinterpret_cast(buff.data()), - buff.size()/2); - } , { - cnt = GetLocaleInfoA(id, type, - buff.data(), buff.size()); - }); + cnt = GetLocaleInfo(id, type, reinterpret_cast(buff.data()), buff.size() / 2); if (cnt == 0) { qWarning("QLocale: empty windows locale info (%d)", (int)type); return QString(); } - QString result; - QT_WA({ - result = QString::fromUtf16(reinterpret_cast(buff.data())); - } , { - result = QString::fromLocal8Bit(buff.data()); - }); - return result; + return QString::fromWCharArray(reinterpret_cast(buff.data())); } QByteArray getWinLocaleName(LCID id = LOCALE_USER_DEFAULT) @@ -445,20 +425,19 @@ QByteArray getWinLocaleName(LCID id = LOCALE_USER_DEFAULT) } } - if (QSysInfo::WindowsVersion == QSysInfo::WV_95 - || (QSysInfo::WindowsVersion & QSysInfo::WV_CE_based)) { - result = winLangCodeToIsoName(id != LOCALE_USER_DEFAULT ? id : GetUserDefaultLCID()); - } else { - if (id == LOCALE_USER_DEFAULT) - id = GetUserDefaultLCID(); - QString resultuage = winIso639LangName(id); - QString country = winIso3116CtryName(id); - result = resultuage.toLatin1(); - if (!country.isEmpty()) { - result += '_'; - result += country.toLatin1(); - } +#if defined(Q_OS_WINCE) + result = winLangCodeToIsoName(id != LOCALE_USER_DEFAULT ? id : GetUserDefaultLCID()); +#else + if (id == LOCALE_USER_DEFAULT) + id = GetUserDefaultLCID(); + QString resultuage = winIso639LangName(id); + QString country = winIso3116CtryName(id); + result = resultuage.toLatin1(); + if (!country.isEmpty()) { + result += '_'; + result += country.toLatin1(); } +#endif return result; } @@ -544,15 +523,9 @@ static QString winDateToString(const QDate &date, DWORD flags) LCID id = GetUserDefaultLCID(); - QT_WA({ - TCHAR buf[255]; - if (GetDateFormatW(id, flags, &st, 0, buf, 255)) - return QString::fromUtf16((ushort*)buf); - } , { - char buf[255]; - if (GetDateFormatA(id, flags, &st, 0, (char*)&buf, 255)) - return QString::fromLocal8Bit(buf); - }); + wchar_t buf[255]; + if (GetDateFormat(id, flags, &st, 0, buf, 255)) + return QString::fromWCharArray(buf); return QString(); } @@ -569,15 +542,9 @@ static QString winTimeToString(const QTime &time) DWORD flags = 0; LCID id = GetUserDefaultLCID(); - QT_WA({ - TCHAR buf[255]; - if (GetTimeFormatW(id, flags, &st, 0, buf, 255)) - return QString::fromUtf16((ushort*)buf); - } , { - char buf[255]; - if (GetTimeFormatA(id, flags, &st, 0, (char*)&buf, 255)) - return QString::fromLocal8Bit(buf); - }); + wchar_t buf[255]; + if (GetTimeFormat(id, flags, &st, 0, buf, 255)) + return QString::fromWCharArray(buf); return QString(); } @@ -626,12 +593,10 @@ static QString winMonthName(int month, bool short_format) static QLocale::MeasurementSystem winSystemMeasurementSystem() { LCID id = GetUserDefaultLCID(); - TCHAR output[2]; + wchar_t output[2]; if (GetLocaleInfo(id, LOCALE_IMEASURE, output, 2)) { - QString iMeasure = QT_WA_INLINE( - QString::fromUtf16(reinterpret_cast(output)), - QString::fromLocal8Bit(reinterpret_cast(output))); + QString iMeasure = QString::fromWCharArray(output); if (iMeasure == QLatin1String("1")) { return QLocale::ImperialSystem; } @@ -643,12 +608,10 @@ static QLocale::MeasurementSystem winSystemMeasurementSystem() static QString winSystemAMText() { LCID id = GetUserDefaultLCID(); - TCHAR output[15]; // maximum length including terminating zero character for Win2003+ + wchar_t output[15]; // maximum length including terminating zero character for Win2003+ if (GetLocaleInfo(id, LOCALE_S1159, output, 15)) { - return QT_WA_INLINE( - QString::fromUtf16(reinterpret_cast(output)), - QString::fromLocal8Bit(reinterpret_cast(output))); + return QString::fromWCharArray(output); } return QString(); @@ -657,12 +620,10 @@ static QString winSystemAMText() static QString winSystemPMText() { LCID id = GetUserDefaultLCID(); - TCHAR output[15]; // maximum length including terminating zero character for Win2003+ + wchar_t output[15]; // maximum length including terminating zero character for Win2003+ if (GetLocaleInfo(id, LOCALE_S2359, output, 15)) { - return QT_WA_INLINE( - QString::fromUtf16(reinterpret_cast(output)), - QString::fromLocal8Bit(reinterpret_cast(output))); + return QString::fromWCharArray(output); } return QString(); @@ -766,9 +727,6 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const return QVariant(); } -/* Win95 doesn't have a function to return the ISO lang/country name of the user's locale. - Instead it can return a "Windows code". This maps windows codes to ISO country names. */ - struct WindowsToISOListElt { ushort windows_code; char iso_name[6]; @@ -924,15 +882,9 @@ static QString winIso639LangName(LCID id) // Windows returns the wrong ISO639 for some languages, we need to detect them here using // the language code QString lang_code; - QT_WA({ - TCHAR out[256]; - if (GetLocaleInfoW(id, LOCALE_ILANGUAGE, out, 255)) - lang_code = QString::fromUtf16((ushort*)out); - } , { - char out[256]; - if (GetLocaleInfoA(id, LOCALE_ILANGUAGE, out, 255)) - lang_code = QString::fromLocal8Bit(out); - }); + wchar_t out[256]; + if (GetLocaleInfo(id, LOCALE_ILANGUAGE, out, 255)) + lang_code = QString::fromWCharArray(out); if (!lang_code.isEmpty()) { const char *endptr; @@ -954,15 +906,8 @@ static QString winIso639LangName(LCID id) return result; // not one of the problematic languages - do the usual lookup - QT_WA({ - TCHAR out[256]; - if (GetLocaleInfoW(id, LOCALE_SISO639LANGNAME , out, 255)) - result = QString::fromUtf16((ushort*)out); - } , { - char out[256]; - if (GetLocaleInfoA(id, LOCALE_SISO639LANGNAME, out, 255)) - result = QString::fromLocal8Bit(out); - }); + if (GetLocaleInfo(id, LOCALE_SISO639LANGNAME , out, 255)) + result = QString::fromWCharArray(out); return result; } @@ -971,15 +916,9 @@ static QString winIso3116CtryName(LCID id) { QString result; - QT_WA({ - TCHAR out[256]; - if (GetLocaleInfoW(id, LOCALE_SISO3166CTRYNAME, out, 255)) - result = QString::fromUtf16((ushort*)out); - } , { - char out[256]; - if (GetLocaleInfoA(id, LOCALE_SISO3166CTRYNAME, out, 255)) - result = QString::fromLocal8Bit(out); - }); + wchar_t out[256]; + if (GetLocaleInfo(id, LOCALE_SISO3166CTRYNAME, out, 255)) + result = QString::fromWCharArray(out); return result; } @@ -2689,7 +2628,7 @@ static QString timeZone() DWORD res = GetTimeZoneInformation(&info); if (res == TIME_ZONE_ID_UNKNOWN) return QString(); - return QString::fromUtf16(reinterpret_cast (info.StandardName)); + return QString::fromWCharArray(info.StandardName); #elif defined(Q_OS_WIN) _tzset(); # if defined(_MSC_VER) && _MSC_VER >= 1400 diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 71482f5..b160b90 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -3714,13 +3714,13 @@ QByteArray qt_winQString2MB(const QChar *ch, int uclen) BOOL used_def; QByteArray mb(4096, 0); int len; - while (!(len=WideCharToMultiByte(CP_ACP, 0, (const WCHAR*)ch, uclen, + while (!(len=WideCharToMultiByte(CP_ACP, 0, (const wchar_t*)ch, uclen, mb.data(), mb.size()-1, 0, &used_def))) { int r = GetLastError(); if (r == ERROR_INSUFFICIENT_BUFFER) { mb.resize(1+WideCharToMultiByte(CP_ACP, 0, - (const WCHAR*)ch, uclen, + (const wchar_t*)ch, uclen, 0, 0, 0, &used_def)); // and try again... } else { @@ -3741,9 +3741,9 @@ QString qt_winMB2QString(const char *mb, int mblen) if (!mb || !mblen) return QString(); const int wclen_auto = 4096; - WCHAR wc_auto[wclen_auto]; + wchar_t wc_auto[wclen_auto]; int wclen = wclen_auto; - WCHAR *wc = wc_auto; + wchar_t *wc = wc_auto; int len; while (!(len=MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, mb, mblen, wc, wclen))) @@ -3756,7 +3756,7 @@ QString qt_winMB2QString(const char *mb, int mblen) } else { wclen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, mb, mblen, 0, 0); - wc = new WCHAR[wclen]; + wc = new wchar_t[wclen]; // and try again... } } else { @@ -3799,11 +3799,6 @@ QString QString::fromLocal8Bit(const char *str, int size) return QString(); if (size == 0 || (!*str && size < 0)) return QLatin1String(""); -#if defined(Q_OS_WIN32) - if(QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) { - return qt_winMB2QString(str, size); - } -#endif #if !defined(QT_NO_TEXTCODEC) if (size < 0) size = qstrlen(str); @@ -4697,16 +4692,7 @@ int QString::localeAwareCompare_helper(const QChar *data1, int length1, return ucstrcmp(data1, length1, data2, length2); #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) - int res; - QT_WA({ - const TCHAR* s1 = (TCHAR*)data1; - const TCHAR* s2 = (TCHAR*)data2; - res = CompareStringW(GetUserDefaultLCID(), 0, s1, length1, s2, length2); - } , { - QByteArray s1 = toLocal8Bit_helper(data1, length1); - QByteArray s2 = toLocal8Bit_helper(data2, length2); - res = CompareStringA(GetUserDefaultLCID(), 0, s1.data(), s1.length(), s2.data(), s2.length()); - }); + int res = CompareString(GetUserDefaultLCID(), 0, (wchar_t*)data1, length1, (wchar_t*)data2, length2); switch (res) { case CSTR_LESS_THAN: -- cgit v0.12 From cfadf08a6c06ce319f6144e724f45e4923e72778 Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Wed, 1 Jul 2009 11:49:51 +0200 Subject: Handle application paths larger than MAX_PATH, and fix potential buffer overflow These days we can easily get very long paths, so we should support application paths as long as needed. There was also a potention exploit in that if the path was MAX_PATH or larger, the string would not be \0 terminated (see MSDN docs for GetModuleFileName), and thus cause problems in QString::fromWCharArray(). Merge-request: 604 Reviewed-by: Marius Storm-Olsen --- src/corelib/kernel/qcoreapplication.cpp | 9 ++----- src/corelib/kernel/qcoreapplication_win.cpp | 40 ++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index f0a3fec..e2708c3 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -1741,13 +1741,8 @@ QString QCoreApplication::applicationFilePath() if (!d->cachedApplicationFilePath.isNull()) return d->cachedApplicationFilePath; -#if defined( Q_WS_WIN ) - wchar_t module_name[MAX_PATH]; - GetModuleFileName(0, module_name, MAX_PATH); - module_name[MAX_PATH] = 0; - QFileInfo filePath = QString::fromWCharArray(module_name); - - d->cachedApplicationFilePath = filePath.filePath(); +#if defined(Q_WS_WIN) + d->cachedApplicationFilePath = QFileInfo(qAppFileName()).filePath(); return d->cachedApplicationFilePath; #elif defined(Q_WS_MAC) QString qAppFileName_str = qAppFileName(); diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp index 657abd1..a71f284 100644 --- a/src/corelib/kernel/qcoreapplication_win.cpp +++ b/src/corelib/kernel/qcoreapplication_win.cpp @@ -76,9 +76,43 @@ Q_CORE_EXPORT int qWinAppCmdShow() // get main window sho Q_CORE_EXPORT QString qAppFileName() // get application file name { - wchar_t buffer[MAX_PATH]; - GetModuleFileName(0, buffer, MAX_PATH); - return QString::fromWCharArray(buffer); + // We do MAX_PATH + 2 here, and request with MAX_PATH + 1, so we can handle all paths + // up to, and including MAX_PATH size perfectly fine with string termination, as well + // as easily detect if the file path is indeed larger than MAX_PATH, in which case we + // need to use the heap instead. This is a work-around, since contrary to what the + // MSDN documentation states, GetModuleFileName sometimes doesn't set the + // ERROR_INSUFFICIENT_BUFFER error number, and we thus cannot rely on this value if + // GetModuleFileName(0, buffer, MAX_PATH) == MAX_PATH. + // GetModuleFileName(0, buffer, MAX_PATH + 1) == MAX_PATH just means we hit the normal + // file path limit, and we handle it normally, if the result is MAX_PATH + 1, we use + // heap (even if the result _might_ be exactly MAX_PATH + 1, but that's ok). + wchar_t buffer[MAX_PATH + 2]; + DWORD v = GetModuleFileName(0, buffer, MAX_PATH + 1); + buffer[MAX_PATH + 1] = 0; + + if (v == 0) + return QString(); + else if (v <= MAX_PATH) + return QString::fromWCharArray(buffer); + + // MAX_PATH sized buffer wasn't large enough to contain the full path, use heap + wchar_t *b = 0; + int i = 1; + size_t size; + do { + ++i; + size = MAX_PATH * i; + b = reinterpret_cast(realloc(b, (size + 1) * sizeof(wchar_t))); + if (b) + v = GetModuleFileName(NULL, b, size); + } while (b && v == size); + + if (b) + *(b + size) = 0; + QString res = QString::fromWCharArray(b); + free(b); + + return res; } void set_winapp_name() -- cgit v0.12 From 55137901012db28857fe7638e63c78743e277c56 Mon Sep 17 00:00:00 2001 From: miniak Date: Wed, 1 Jul 2009 11:49:54 +0200 Subject: src/gui: Remove QT_WA and non-Unicode code paths, dropping Win9x and NT support Also - Make winPeekMessage() & winPostMessage() obsolete - FlashWindowEx, IsValidLanguageGroup functions no longer resolved dynamically (available on >= Windows 2000) - LoadIcon/LoadCursor -> LoadImage w/LR_SHARED for system icons/cursors - qsystemtrayicon_win: use Shell_NotifyIconGetRect if available (Windows 7) Merge-request: 604 Reviewed-by: Marius Storm-Olsen --- src/corelib/global/qt_windows.h | 21 +- src/corelib/kernel/qeventdispatcher_win.cpp | 2 +- src/gui/accessible/qaccessible_win.cpp | 32 +- src/gui/dialogs/qdialog.cpp | 3 +- src/gui/dialogs/qfiledialog_p.h | 3 +- src/gui/dialogs/qfiledialog_win.cpp | 456 +++++-------------- src/gui/dialogs/qfilesystemmodel.cpp | 20 +- src/gui/dialogs/qpagesetupdialog_win.cpp | 3 +- src/gui/dialogs/qprintdialog_win.cpp | 76 +--- src/gui/dialogs/qwizard.cpp | 14 +- src/gui/image/qpixmap_win.cpp | 12 +- src/gui/inputmethod/qwininputcontext_win.cpp | 116 ++--- src/gui/itemviews/qfileiconprovider.cpp | 12 +- src/gui/kernel/qapplication.cpp | 18 +- src/gui/kernel/qapplication_win.cpp | 409 +++++------------ src/gui/kernel/qclipboard_win.cpp | 10 +- src/gui/kernel/qcursor_win.cpp | 44 +- src/gui/kernel/qdesktopwidget_win.cpp | 121 ++--- src/gui/kernel/qdnd_win.cpp | 75 ++-- src/gui/kernel/qguifunctions_wince.cpp | 24 +- src/gui/kernel/qguifunctions_wince.h | 8 +- src/gui/kernel/qkeymapper_win.cpp | 120 +---- src/gui/kernel/qmime_win.cpp | 146 +++--- src/gui/kernel/qsound_win.cpp | 40 +- src/gui/kernel/qwhatsthis.cpp | 8 +- src/gui/kernel/qwidget.cpp | 8 +- src/gui/kernel/qwidget_win.cpp | 127 ++---- src/gui/kernel/qwidget_wince.cpp | 46 +- src/gui/painting/qpdf.cpp | 2 +- src/gui/painting/qprintengine_pdf.cpp | 2 +- src/gui/painting/qprintengine_win.cpp | 646 +++++++++------------------ src/gui/painting/qprintengine_win_p.h | 16 +- src/gui/painting/qprinterinfo_win.cpp | 98 ++-- src/gui/painting/qregion.cpp | 4 - src/gui/painting/qwindowsurface_raster.cpp | 24 +- src/gui/painting/qwindowsurface_raster_p.h | 13 +- src/gui/styles/qwindowsstyle.cpp | 115 ++--- src/gui/styles/qwindowsvistastyle.cpp | 4 +- src/gui/styles/qwindowsxpstyle.cpp | 9 +- src/gui/text/qfont_win.cpp | 8 +- src/gui/text/qfontdatabase_win.cpp | 259 +++-------- src/gui/text/qfontengine_win.cpp | 440 ++++-------------- src/gui/text/qfontengine_win_p.h | 18 +- src/gui/util/qdesktopservices_win.cpp | 28 +- src/gui/util/qsystemtrayicon_win.cpp | 323 ++++---------- src/gui/widgets/qeffects.cpp | 97 ++-- src/gui/widgets/qframe.cpp | 2 +- src/gui/widgets/qmdisubwindow.cpp | 35 +- src/gui/widgets/qsizegrip.cpp | 3 +- src/gui/widgets/qworkspace.cpp | 26 +- 50 files changed, 1227 insertions(+), 2919 deletions(-) diff --git a/src/corelib/global/qt_windows.h b/src/corelib/global/qt_windows.h index 5df57e5..27c06e5 100644 --- a/src/corelib/global/qt_windows.h +++ b/src/corelib/global/qt_windows.h @@ -60,7 +60,6 @@ #endif // already defined when compiled with WINVER >= 0x0500 -// and we only use them in Qt::WV_2000 and Qt::WV_98 #ifndef SPI_SETMENUANIMATION #define SPI_SETMENUANIMATION 0x1003 #endif @@ -113,4 +112,24 @@ #define ETO_PDY 0x2000 #endif +// already defined when compiled with WINVER >= 0x0600 +#ifndef SPI_GETFLATMENU +#define SPI_GETFLATMENU 0x1022 +#endif +#ifndef CS_DROPSHADOW +#define CS_DROPSHADOW 0x00020000 +#endif +#ifndef CLEARTYPE_QUALITY +#define CLEARTYPE_QUALITY 5 +#endif + +#ifdef Q_WS_WINCE +#ifndef LR_DEFAULTSIZE +#define LR_DEFAULTSIZE 0 +#endif +#ifndef LR_SHARED +#define LR_SHARED 0 +#endif +#endif // Q_WS_WINCE + #endif // QT_WINDOWS_H diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 23e4fa9..33b66f5 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -495,7 +495,7 @@ LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp) static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatcher) { // make sure that multiple Qt's can coexist in the same process - QString className = QLatin1Strign("QEventDispatcherWin32_Internal_Widget") + QString::number(quintptr(qt_internal_proc)); + QString className = QLatin1String("QEventDispatcherWin32_Internal_Widget") + QString::number(quintptr(qt_internal_proc)); WNDCLASS wc; wc.style = 0; diff --git a/src/gui/accessible/qaccessible_win.cpp b/src/gui/accessible/qaccessible_win.cpp index ccb2673..bfacb94 100644 --- a/src/gui/accessible/qaccessible_win.cpp +++ b/src/gui/accessible/qaccessible_win.cpp @@ -177,14 +177,14 @@ void QAccessible::updateAccessibility(QObject *o, int who, Event reason) return; } - QByteArray soundName; + QString soundName; switch (reason) { case PopupMenuStart: - soundName = "MenuPopup"; + soundName = QLatin1String("MenuPopup"); break; case MenuCommand: - soundName = "MenuCommand"; + soundName = QLatin1String("MenuCommand"); break; case Alert: @@ -194,13 +194,13 @@ void QAccessible::updateAccessibility(QObject *o, int who, Event reason) if (mb) { switch (mb->icon()) { case QMessageBox::Warning: - soundName = "SystemExclamation"; + soundName = QLatin1String("SystemExclamation"); break; case QMessageBox::Critical: - soundName = "SystemHand"; + soundName = QLatin1String("SystemHand"); break; case QMessageBox::Information: - soundName = "SystemAsterisk"; + soundName = QLatin1String("SystemAsterisk"); break; default: break; @@ -208,7 +208,7 @@ void QAccessible::updateAccessibility(QObject *o, int who, Event reason) } else #endif // QT_NO_MESSAGEBOX { - soundName = "SystemAsterisk"; + soundName = QLatin1String("SystemAsterisk"); } } @@ -219,20 +219,16 @@ void QAccessible::updateAccessibility(QObject *o, int who, Event reason) if (soundName.size()) { #ifndef QT_NO_SETTINGS - QSettings settings(QLatin1String("HKEY_CURRENT_USER\\AppEvents\\Schemes\\Apps\\.Default\\") + - QString::fromLatin1(soundName.constData()), QSettings::NativeFormat); + QSettings settings(QLatin1String("HKEY_CURRENT_USER\\AppEvents\\Schemes\\Apps\\.Default\\") + soundName, + QSettings::NativeFormat); QString file = settings.value(QLatin1String(".Current/.")).toString(); #else - QString file; + QString file; #endif - if (!file.isEmpty()) { - QT_WA({ - PlaySoundW(reinterpret_cast (QString::fromLatin1(soundName).utf16()), 0, SND_ALIAS | SND_ASYNC | SND_NODEFAULT | SND_NOWAIT ); - } , { - PlaySoundA(soundName.constData(), 0, SND_ALIAS | SND_ASYNC | SND_NODEFAULT | SND_NOWAIT ); - }); - } - } + if (!file.isEmpty()) { + PlaySound(reinterpret_cast(soundName.utf16()), 0, SND_ALIAS | SND_ASYNC | SND_NODEFAULT | SND_NOWAIT); + } + } if (!isActive()) return; diff --git a/src/gui/dialogs/qdialog.cpp b/src/gui/dialogs/qdialog.cpp index 0288cd9..bb6c6d6 100644 --- a/src/gui/dialogs/qdialog.cpp +++ b/src/gui/dialogs/qdialog.cpp @@ -762,8 +762,7 @@ void QDialog::setVisible(bool visible) #ifdef Q_WS_WIN if (d->mainDef && isActiveWindow()) { BOOL snapToDefault = false; - if ( QT_WA_INLINE( SystemParametersInfo(SPI_GETSNAPTODEFBUTTON, 0, &snapToDefault, 0) , - SystemParametersInfoA(SPI_GETSNAPTODEFBUTTON, 0, &snapToDefault, 0) )) { + if (SystemParametersInfo(SPI_GETSNAPTODEFBUTTON, 0, &snapToDefault, 0)) { if (snapToDefault) QCursor::setPos(d->mainDef->mapToGlobal(d->mainDef->rect().center())); } diff --git a/src/gui/dialogs/qfiledialog_p.h b/src/gui/dialogs/qfiledialog_p.h index 654b3bb..d798f9d 100644 --- a/src/gui/dialogs/qfiledialog_p.h +++ b/src/gui/dialogs/qfiledialog_p.h @@ -187,8 +187,7 @@ public: #ifndef Q_OS_WINCE DWORD maxLength; QString drive = path.left(3); - if (QT_WA_INLINE(::GetVolumeInformationW(reinterpret_cast(drive.utf16()), NULL, 0, NULL, &maxLength, NULL, NULL, 0), - ::GetVolumeInformationA(drive.toLocal8Bit().constData(), NULL, 0, NULL, &maxLength, NULL, NULL, 0)) == FALSE) + if (::GetVolumeInformation(reinterpret_cast(drive.utf16()), NULL, 0, NULL, &maxLength, NULL, NULL, 0) == FALSE) return -1; return maxLength; #else diff --git a/src/gui/dialogs/qfiledialog_win.cpp b/src/gui/dialogs/qfiledialog_win.cpp index 4cb31f5..6883bf9 100644 --- a/src/gui/dialogs/qfiledialog_win.cpp +++ b/src/gui/dialogs/qfiledialog_win.cpp @@ -70,8 +70,8 @@ typedef struct qt_priv_browseinfo { HWND hwndOwner; LPCITEMIDLIST pidlRoot; - LPTSTR pszDisplayName; - LPCTSTR lpszTitle; + LPWSTR pszDisplayName; + LPCWSTR lpszTitle; UINT ulFlags; BFFCALLBACK lpfn; LPARAM lParam; @@ -90,6 +90,9 @@ typedef LPITEMIDLIST (WINAPI *PtrSHBrowseForFolder)(BROWSEINFO*); static PtrSHBrowseForFolder ptrSHBrowseForFolder = 0; typedef BOOL (WINAPI *PtrSHGetPathFromIDList)(LPITEMIDLIST,LPWSTR); static PtrSHGetPathFromIDList ptrSHGetPathFromIDList = 0; +typedef HRESULT (WINAPI *PtrSHGetMalloc)(LPMALLOC *); +static PtrSHGetMalloc ptrSHGetMalloc = 0; + QT_BEGIN_NAMESPACE @@ -111,20 +114,20 @@ static void qt_win_resolve_libs() #endif triedResolve = true; - if (!(QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based)) { #if !defined(Q_WS_WINCE) - QLibrary lib(QLatin1String("shell32")); - ptrSHBrowseForFolder = (PtrSHBrowseForFolder) lib.resolve("SHBrowseForFolderW"); - ptrSHGetPathFromIDList = (PtrSHGetPathFromIDList) lib.resolve("SHGetPathFromIDListW"); + QLibrary lib(QLatin1String("shell32")); + ptrSHBrowseForFolder = (PtrSHBrowseForFolder) lib.resolve("SHBrowseForFolderW"); + ptrSHGetPathFromIDList = (PtrSHGetPathFromIDList) lib.resolve("SHGetPathFromIDListW"); + ptrSHGetMalloc = (PtrSHGetMalloc) lib.resolve("SHGetMalloc"); #else - // CE stores them in a different lib and does not use unicode version - HINSTANCE handle = LoadLibraryW(L"Ceshell"); - ptrSHBrowseForFolder = (PtrSHBrowseForFolder)GetProcAddress(handle, L"SHBrowseForFolder"); - ptrSHGetPathFromIDList = (PtrSHGetPathFromIDList)GetProcAddress(handle, L"SHGetPathFromIDList"); - if (ptrSHBrowseForFolder && ptrSHGetPathFromIDList) - qt_priv_ptr_valid = true; + // CE stores them in a different lib and does not use unicode version + HINSTANCE handle = LoadLibraryW(L"Ceshell"); + ptrSHBrowseForFolder = (PtrSHBrowseForFolder)GetProcAddress(handle, L"SHBrowseForFolder"); + ptrSHGetPathFromIDList = (PtrSHGetPathFromIDList)GetProcAddress(handle, L"SHGetPathFromIDList"); + ptrSHGetMalloc = (PtrSHGetMalloc)GetProcAddress(handle, L"SHGetMalloc"); + if (ptrSHBrowseForFolder && ptrSHGetPathFromIDList && ptrSHGetMalloc) + qt_priv_ptr_valid = true; #endif - } } } @@ -186,95 +189,15 @@ static QString qt_win_selected_filter(const QString &filter, DWORD idx) return qt_win_make_filters_list(filter).at((int)idx - 1); } -#ifndef Q_WS_WINCE -// Static vars for OFNA funcs: -static QByteArray aInitDir; -static QByteArray aInitSel; -static QByteArray aTitle; -static QByteArray aFilter; -// Use ANSI strings and API - -// If you change this, then make sure you change qt_win_make_OFN (below) too -static OPENFILENAMEA *qt_win_make_OFNA(QWidget *parent, - const QString &initialSelection, - const QString &initialDirectory, - const QString &title, - const QString &filters, - QFileDialog::FileMode mode, - QFileDialog::Options options) -{ - if (parent) - parent = parent->window(); - else - parent = QApplication::activeWindow(); - - aTitle = title.toLocal8Bit(); - aInitDir = QDir::toNativeSeparators(initialDirectory).toLocal8Bit(); - if (initialSelection.isEmpty()) { - aInitSel = ""; - } else { - aInitSel = QDir::toNativeSeparators(initialSelection).toLocal8Bit(); - aInitSel.replace('<', ""); - aInitSel.replace('>', ""); - aInitSel.replace('\"', ""); - aInitSel.replace('|', ""); - } - int maxLen = mode == QFileDialog::ExistingFiles ? maxMultiLen : maxNameLen; - aInitSel.resize(maxLen + 1); // make room for return value - aFilter = filters.toLocal8Bit(); - - OPENFILENAMEA* ofn = new OPENFILENAMEA; - memset(ofn, 0, sizeof(OPENFILENAMEA)); - -#if defined(Q_CC_BOR) && (WINVER >= 0x0500) && (_WIN32_WINNT >= 0x0500) - // according to the MSDN, this should also be necessary for MSVC, but - // OPENFILENAME_SIZE_VERSION_400A is in not Microsoft header, as it seems - if (QApplication::winVersion()==Qt::WV_NT || QApplication::winVersion()&Qt::WV_DOS_based) { - ofn->lStructSize = OPENFILENAME_SIZE_VERSION_400A; - } else { - ofn->lStructSize = sizeof(OPENFILENAMEA); - } -#else - ofn->lStructSize = sizeof(OPENFILENAMEA); -#endif - Q_ASSERT(!parent ||parent->testAttribute(Qt::WA_WState_Created)); - ofn->hwndOwner = parent ? parent->winId() : 0; - ofn->lpstrFilter = aFilter; - ofn->lpstrFile = aInitSel.data(); - ofn->nMaxFile = maxLen; - ofn->lpstrInitialDir = aInitDir.data(); - ofn->lpstrTitle = aTitle.data(); - ofn->Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY | OFN_EXPLORER); - - if (mode == QFileDialog::ExistingFile || - mode == QFileDialog::ExistingFiles) - ofn->Flags |= (OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST); - if (mode == QFileDialog::ExistingFiles) - ofn->Flags |= (OFN_ALLOWMULTISELECT); - if (!(options & QFileDialog::DontConfirmOverwrite)) - ofn->Flags |= OFN_OVERWRITEPROMPT; - - return ofn; -} - -static void qt_win_clean_up_OFNA(OPENFILENAMEA **ofn) -{ - delete *ofn; - *ofn = 0; -} -#endif - static QString tFilters, tTitle, tInitDir; -#ifdef UNICODE -// If you change this, then make sure you change qt_win_make_OFNA (above) too static OPENFILENAME* qt_win_make_OFN(QWidget *parent, const QString& initialSelection, const QString& initialDirectory, const QString& title, const QString& filters, QFileDialog::FileMode mode, - QFileDialog::Options options) + QFileDialog::Options options) { if (parent) parent = parent->window(); @@ -286,14 +209,14 @@ static OPENFILENAME* qt_win_make_OFN(QWidget *parent, tTitle = title; QString initSel = QDir::toNativeSeparators(initialSelection); if (!initSel.isEmpty()) { - initSel.remove(QLatin1Char('<')); - initSel.remove(QLatin1Char('>')); - initSel.remove(QLatin1Char('\"')); - initSel.remove(QLatin1Char('|')); + initSel.remove(QLatin1Char('<')); + initSel.remove(QLatin1Char('>')); + initSel.remove(QLatin1Char('\"')); + initSel.remove(QLatin1Char('|')); } int maxLen = mode == QFileDialog::ExistingFiles ? maxMultiLen : maxNameLen; - TCHAR *tInitSel = new TCHAR[maxLen+1]; + wchar_t *tInitSel = new wchar_t[maxLen + 1]; if (initSel.length() > 0 && initSel.length() <= maxLen) memcpy(tInitSel, initSel.utf16(), (initSel.length()+1)*sizeof(QChar)); else @@ -302,24 +225,14 @@ static OPENFILENAME* qt_win_make_OFN(QWidget *parent, OPENFILENAME* ofn = new OPENFILENAME; memset(ofn, 0, sizeof(OPENFILENAME)); -#if defined(Q_CC_BOR) && (WINVER >= 0x0500) && (_WIN32_WINNT >= 0x0500) - // according to the MSDN, this should also be necessary for MSVC, but - // OPENFILENAME_SIZE_VERSION_400 is in not Microsoft header, as it seems - if (QApplication::winVersion()==Qt::WV_NT || QApplication::winVersion()&Qt::WV_DOS_based) { - ofn->lStructSize= OPENFILENAME_SIZE_VERSION_400; - } else { - ofn->lStructSize = sizeof(OPENFILENAME); - } -#else ofn->lStructSize = sizeof(OPENFILENAME); -#endif Q_ASSERT(!parent ||parent->testAttribute(Qt::WA_WState_Created)); ofn->hwndOwner = parent ? parent->winId() : 0; - ofn->lpstrFilter = (TCHAR *)tFilters.utf16(); + ofn->lpstrFilter = (wchar_t*)tFilters.utf16(); ofn->lpstrFile = tInitSel; ofn->nMaxFile = maxLen; - ofn->lpstrInitialDir = (TCHAR *)tInitDir.utf16(); - ofn->lpstrTitle = (TCHAR *)tTitle.utf16(); + ofn->lpstrInitialDir = (wchar_t*)tInitDir.utf16(); + ofn->lpstrTitle = (wchar_t*)tTitle.utf16(); ofn->Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY | OFN_EXPLORER); if (mode == QFileDialog::ExistingFile || mode == QFileDialog::ExistingFiles) @@ -332,7 +245,6 @@ static OPENFILENAME* qt_win_make_OFN(QWidget *parent, return ofn; } - static void qt_win_clean_up_OFN(OPENFILENAME **ofn) { delete [] (*ofn)->lpstrFile; @@ -340,8 +252,6 @@ static void qt_win_clean_up_OFN(OPENFILENAME **ofn) *ofn = 0; } -#endif // UNICODE - extern void qt_win_eatMouseMove(); QString qt_win_get_open_file_name(const QFileDialogArgs &args, @@ -377,35 +287,20 @@ QString qt_win_get_open_file_name(const QFileDialogArgs &args, modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true); modal_widget.setParent(args.parent, Qt::Window); QApplicationPrivate::enterModal(&modal_widget); - QT_WA({ - // Use Unicode strings and API - OPENFILENAME* ofn = qt_win_make_OFN(args.parent, args.selection, - args.directory, args.caption, - qt_win_filter(args.filter), - QFileDialog::ExistingFile, - args.options); - if (idx) - ofn->nFilterIndex = idx + 1; - if (GetOpenFileName(ofn)) { - result = QString::fromUtf16((ushort*)ofn->lpstrFile); - selFilIdx = ofn->nFilterIndex; - } - qt_win_clean_up_OFN(&ofn); - } , { - // Use ANSI strings and API - OPENFILENAMEA* ofn = qt_win_make_OFNA(args.parent, args.selection, - args.directory, args.caption, - qt_win_filter(args.filter), - QFileDialog::ExistingFile, - args.options); - if (idx) - ofn->nFilterIndex = idx + 1; - if (GetOpenFileNameA(ofn)) { - result = QString::fromLocal8Bit(ofn->lpstrFile); - selFilIdx = ofn->nFilterIndex; - } - qt_win_clean_up_OFNA(&ofn); - }); + + OPENFILENAME* ofn = qt_win_make_OFN(args.parent, args.selection, + args.directory, args.caption, + qt_win_filter(args.filter), + QFileDialog::ExistingFile, + args.options); + if (idx) + ofn->nFilterIndex = idx + 1; + if (GetOpenFileName(ofn)) { + result = QString::fromWCharArray(ofn->lpstrFile); + selFilIdx = ofn->nFilterIndex; + } + qt_win_clean_up_OFN(&ofn); + QApplicationPrivate::leaveModal(&modal_widget); qt_win_eatMouseMove(); @@ -422,7 +317,7 @@ QString qt_win_get_open_file_name(const QFileDialogArgs &args, QString qt_win_get_save_file_name(const QFileDialogArgs &args, QString *initialDirectory, - QString *selectedFilter) + QString *selectedFilter) { QString result; @@ -470,41 +365,22 @@ QString qt_win_get_save_file_name(const QFileDialogArgs &args, } } - QT_WA({ - // Use Unicode strings and API - OPENFILENAME *ofn = qt_win_make_OFN(args.parent, args.selection, - args.directory, args.caption, - qt_win_filter(args.filter), - QFileDialog::AnyFile, - args.options); - - ofn->lpstrDefExt = (TCHAR *)defaultSaveExt.utf16(); - - if (idx) - ofn->nFilterIndex = idx + 1; - if (GetSaveFileName(ofn)) { - result = QString::fromUtf16((ushort*)ofn->lpstrFile); - selFilIdx = ofn->nFilterIndex; - } - qt_win_clean_up_OFN(&ofn); - } , { - // Use ANSI strings and API - OPENFILENAMEA *ofn = qt_win_make_OFNA(args.parent, args.selection, - args.directory, args.caption, - qt_win_filter(args.filter), - QFileDialog::AnyFile, - args.options); - QByteArray asciiExt = defaultSaveExt.toAscii(); - ofn->lpstrDefExt = asciiExt.data(); - - if (idx) - ofn->nFilterIndex = idx + 1; - if (GetSaveFileNameA(ofn)) { - result = QString::fromLocal8Bit(ofn->lpstrFile); - selFilIdx = ofn->nFilterIndex; - } - qt_win_clean_up_OFNA(&ofn); - }); + OPENFILENAME *ofn = qt_win_make_OFN(args.parent, args.selection, + args.directory, args.caption, + qt_win_filter(args.filter), + QFileDialog::AnyFile, + args.options); + + ofn->lpstrDefExt = (wchar_t*)defaultSaveExt.utf16(); + + if (idx) + ofn->nFilterIndex = idx + 1; + if (GetSaveFileName(ofn)) { + result = QString::fromWCharArray(ofn->lpstrFile); + selFilIdx = ofn->nFilterIndex; + } + qt_win_clean_up_OFN(&ofn); + #if defined(Q_WS_WINCE) int semIndex = result.indexOf(QLatin1Char(';')); if (semIndex >= 0) @@ -558,73 +434,40 @@ QStringList qt_win_get_open_file_names(const QFileDialogArgs &args, modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true); modal_widget.setParent(args.parent, Qt::Window); QApplicationPrivate::enterModal(&modal_widget); - QT_WA({ - OPENFILENAME* ofn = qt_win_make_OFN(args.parent, args.selection, - args.directory, args.caption, - qt_win_filter(args.filter), - QFileDialog::ExistingFiles, - args.options); - if (idx) - ofn->nFilterIndex = idx + 1; - if (GetOpenFileName(ofn)) { - QString fileOrDir = QString::fromUtf16((ushort*)ofn->lpstrFile); - selFilIdx = ofn->nFilterIndex; - int offset = fileOrDir.length() + 1; - if (ofn->lpstrFile[offset] == 0) { - // Only one file selected; has full path - fi.setFile(fileOrDir); - QString res = fi.absoluteFilePath(); - if (!res.isEmpty()) - result.append(res); - } - else { - // Several files selected; first string is path - dir.setPath(fileOrDir); - QString f; - while(!(f = QString::fromUtf16((ushort*)ofn->lpstrFile+offset)).isEmpty()) { - fi.setFile(dir, f); - QString res = fi.absoluteFilePath(); - if (!res.isEmpty()) - result.append(res); - offset += f.length() + 1; - } - } + + OPENFILENAME* ofn = qt_win_make_OFN(args.parent, args.selection, + args.directory, args.caption, + qt_win_filter(args.filter), + QFileDialog::ExistingFiles, + args.options); + if (idx) + ofn->nFilterIndex = idx + 1; + if (GetOpenFileName(ofn)) { + QString fileOrDir = QString::fromWCharArray(ofn->lpstrFile); + selFilIdx = ofn->nFilterIndex; + int offset = fileOrDir.length() + 1; + if (ofn->lpstrFile[offset] == 0) { + // Only one file selected; has full path + fi.setFile(fileOrDir); + QString res = fi.absoluteFilePath(); + if (!res.isEmpty()) + result.append(res); } - qt_win_clean_up_OFN(&ofn); - } , { - OPENFILENAMEA* ofn = qt_win_make_OFNA(args.parent, args.selection, - args.directory, args.caption, - qt_win_filter(args.filter), - QFileDialog::ExistingFiles, - args.options); - if (idx) - ofn->nFilterIndex = idx + 1; - if (GetOpenFileNameA(ofn)) { - QByteArray fileOrDir(ofn->lpstrFile); - selFilIdx = ofn->nFilterIndex; - int offset = fileOrDir.length() + 1; - if (ofn->lpstrFile[offset] == '\0') { - // Only one file selected; has full path - fi.setFile(QString::fromLocal8Bit(fileOrDir)); + else { + // Several files selected; first string is path + dir.setPath(fileOrDir); + QString f; + while(!(f = QString::fromWCharArray(ofn->lpstrFile + offset)).isEmpty()) { + fi.setFile(dir, f); QString res = fi.absoluteFilePath(); if (!res.isEmpty()) result.append(res); + offset += f.length() + 1; } - else { - // Several files selected; first string is path - dir.setPath(QString::fromLocal8Bit(fileOrDir)); - QByteArray f; - while (!(f = QByteArray(ofn->lpstrFile + offset)).isEmpty()) { - fi.setFile(dir, QString::fromLocal8Bit(f)); - QString res = fi.absoluteFilePath(); - if (!res.isEmpty()) - result.append(res); - offset += f.length() + 1; - } - } - qt_win_clean_up_OFNA(&ofn); } - }); + } + qt_win_clean_up_OFN(&ofn); + QApplicationPrivate::leaveModal(&modal_widget); qt_win_eatMouseMove(); @@ -647,34 +490,20 @@ static int __stdcall winGetExistDirCallbackProc(HWND hwnd, if (uMsg == BFFM_INITIALIZED && lpData != 0) { QString *initDir = (QString *)(lpData); if (!initDir->isEmpty()) { - // ### Lars asks: is this correct for the A version???? - QT_WA({ - SendMessage(hwnd, BFFM_SETSELECTION, TRUE, LPARAM(initDir->utf16())); - } , { - SendMessageA(hwnd, BFFM_SETSELECTION, TRUE, LPARAM(initDir->utf16())); - }); + SendMessage(hwnd, BFFM_SETSELECTION, TRUE, LPARAM(initDir->utf16())); } } else if (uMsg == BFFM_SELCHANGED) { - QT_WA({ - qt_win_resolve_libs(); - TCHAR path[MAX_PATH]; + qt_win_resolve_libs(); + if (ptrSHGetPathFromIDList) { + wchar_t path[MAX_PATH]; ptrSHGetPathFromIDList(LPITEMIDLIST(lParam), path); - QString tmpStr = QString::fromUtf16((ushort*)path); + QString tmpStr = QString::fromWCharArray(path); if (!tmpStr.isEmpty()) SendMessage(hwnd, BFFM_ENABLEOK, 1, 1); else SendMessage(hwnd, BFFM_ENABLEOK, 0, 0); SendMessage(hwnd, BFFM_SETSTATUSTEXT, 1, LPARAM(path)); - } , { - char path[MAX_PATH]; - SHGetPathFromIDListA(LPITEMIDLIST(lParam), path); - QString tmpStr = QString::fromLocal8Bit(path); - if (!tmpStr.isEmpty()) - SendMessageA(hwnd, BFFM_ENABLEOK, 1, 1); - else - SendMessageA(hwnd, BFFM_ENABLEOK, 0, 0); - SendMessageA(hwnd, BFFM_SETSTATUSTEXT, 1, LPARAM(path)); - }); + } } return 0; } @@ -700,116 +529,49 @@ QString qt_win_get_existing_directory(const QFileDialogArgs &args) modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true); modal_widget.setParent(parent, Qt::Window); QApplicationPrivate::enterModal(&modal_widget); -#if !defined(Q_WS_WINCE) - QT_WA({ - qt_win_resolve_libs(); - QString initDir = QDir::toNativeSeparators(args.directory); - TCHAR path[MAX_PATH]; - TCHAR initPath[MAX_PATH]; - initPath[0] = 0; - path[0] = 0; - tTitle = args.caption; - BROWSEINFO bi; - Q_ASSERT(!parent ||parent->testAttribute(Qt::WA_WState_Created)); - bi.hwndOwner = (parent ? parent->winId() : 0); - bi.pidlRoot = NULL; - //### This does not seem to be respected? - the dialog always displays "Browse for folder" - bi.lpszTitle = (TCHAR*)tTitle.utf16(); - bi.pszDisplayName = initPath; - bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_NEWDIALOGSTYLE; - bi.lpfn = winGetExistDirCallbackProc; - bi.lParam = LPARAM(&initDir); - if (ptrSHBrowseForFolder) { - LPITEMIDLIST pItemIDList = ptrSHBrowseForFolder(&bi); - if (pItemIDList && ptrSHGetPathFromIDList) { - ptrSHGetPathFromIDList(pItemIDList, path); - IMalloc *pMalloc; - if (SHGetMalloc(&pMalloc) != NOERROR) - result = QString(); - else { - pMalloc->Free(pItemIDList); - pMalloc->Release(); - result = QString::fromUtf16((ushort*)path); - } - } else - result = QString(); - } - tTitle = QString(); - } , { - QString initDir = QDir::toNativeSeparators(args.directory); - char path[MAX_PATH]; - char initPath[MAX_PATH]; - QByteArray ctitle = args.caption.toLocal8Bit(); - initPath[0]=0; - path[0]=0; - BROWSEINFOA bi; - Q_ASSERT(!parent ||parent->testAttribute(Qt::WA_WState_Created)); - bi.hwndOwner = (parent ? parent->winId() : 0); - bi.pidlRoot = NULL; - bi.lpszTitle = ctitle; - bi.pszDisplayName = initPath; - bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_NEWDIALOGSTYLE; - bi.lpfn = winGetExistDirCallbackProc; - bi.lParam = LPARAM(&initDir); - LPITEMIDLIST pItemIDList = SHBrowseForFolderA(&bi); - if (pItemIDList) { - SHGetPathFromIDListA(pItemIDList, path); - IMalloc *pMalloc; - if (SHGetMalloc(&pMalloc) != NOERROR) - result = QString(); - else { - pMalloc->Free(pItemIDList); - pMalloc->Release(); - result = QString::fromLocal8Bit(path); - } - } else - result = QString(); - }); -#else - qt_win_resolve_libs(); + QString initDir = QDir::toNativeSeparators(args.directory); - TCHAR path[MAX_PATH]; - TCHAR initPath[MAX_PATH]; - memset(initPath, 0 , MAX_PATH*sizeof(TCHAR)); - memset(path, 0, MAX_PATH*sizeof(TCHAR)); + wchar_t path[MAX_PATH]; + wchar_t initPath[MAX_PATH]; + initPath[0] = 0; + path[0] = 0; tTitle = args.caption; + +#if !defined(Q_WS_WINCE) + BROWSEINFO bi; +#else qt_BROWSEINFO bi; +#endif + Q_ASSERT(!parent ||parent->testAttribute(Qt::WA_WState_Created)); bi.hwndOwner = (parent ? parent->winId() : 0); bi.pidlRoot = NULL; - bi.lpszTitle = (TCHAR*)tTitle.utf16(); + //### This does not seem to be respected? - the dialog always displays "Browse for folder" + bi.lpszTitle = (wchar_t*)tTitle.utf16(); bi.pszDisplayName = initPath; bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_NEWDIALOGSTYLE; bi.lpfn = winGetExistDirCallbackProc; bi.lParam = LPARAM(&initDir); + + qt_win_resolve_libs(); if (ptrSHBrowseForFolder) { LPITEMIDLIST pItemIDList = ptrSHBrowseForFolder((BROWSEINFO*)&bi); - if (pItemIDList && ptrSHGetPathFromIDList) { + if (pItemIDList) { ptrSHGetPathFromIDList(pItemIDList, path); IMalloc *pMalloc; - if (SHGetMalloc(&pMalloc) != NOERROR) - result = QString(); - else { + if (ptrSHGetMalloc(&pMalloc) == NOERROR) { pMalloc->Free(pItemIDList); pMalloc->Release(); - result = QString::fromUtf16((ushort*)path); + result = QString::fromWCharArray(path); } - } else - result = QString(); + } } tTitle = QString(); -#endif QApplicationPrivate::leaveModal(&modal_widget); qt_win_eatMouseMove(); - // Due to a bug on Windows Me, we need to reset the current - // directory - if ((QSysInfo::WindowsVersion == QSysInfo::WV_98 || QSysInfo::WindowsVersion == QSysInfo::WV_Me) - && QDir::currentPath() != currentDir) - QDir::setCurrent(currentDir); - if (!result.isEmpty()) result.replace(QLatin1Char('\\'), QLatin1Char('/')); return result; diff --git a/src/gui/dialogs/qfilesystemmodel.cpp b/src/gui/dialogs/qfilesystemmodel.cpp index 347a084..e523ec3 100644 --- a/src/gui/dialogs/qfilesystemmodel.cpp +++ b/src/gui/dialogs/qfilesystemmodel.cpp @@ -296,22 +296,14 @@ static QString qt_GetLongPathName(const QString &strShortPath) #else QString longSection = QDir::toNativeSeparators(section); #endif - QT_WA({ - WIN32_FIND_DATAW findData; - h = ::FindFirstFileW((wchar_t *)longSection.utf16(), &findData); - if (h != INVALID_HANDLE_VALUE) - longPath.append(QString::fromUtf16((ushort*)findData.cFileName)); - } , { - WIN32_FIND_DATAA findData; - h = ::FindFirstFileA(section.toLocal8Bit(), &findData); - if (h != INVALID_HANDLE_VALUE) - longPath.append(QString::fromLocal8Bit(findData.cFileName)); - }); - if (h == INVALID_HANDLE_VALUE) { + WIN32_FIND_DATA findData; + h = ::FindFirstFile((wchar_t*)longSection.utf16(), &findData); + if (h != INVALID_HANDLE_VALUE) { + longPath.append(QString::fromWCharArray(findData.cFileName)); + ::FindClose(h); + } else { longPath.append(section); break; - } else { - ::FindClose(h); } } if (it != constEnd) diff --git a/src/gui/dialogs/qpagesetupdialog_win.cpp b/src/gui/dialogs/qpagesetupdialog_win.cpp index 136f939..a84a7ce 100644 --- a/src/gui/dialogs/qpagesetupdialog_win.cpp +++ b/src/gui/dialogs/qpagesetupdialog_win.cpp @@ -81,8 +81,7 @@ int QPageSetupDialog::exec() HGLOBAL hDevMode; int devModeSize; if (!ep->globalDevMode) { - QT_WA( { devModeSize = sizeof(DEVMODEW) + ((DEVMODEW *) ep->devMode)->dmDriverExtra; }, - { devModeSize = sizeof(DEVMODEA) + ((DEVMODEA *) ep->devMode)->dmDriverExtra; }); + devModeSize = sizeof(DEVMODE) + ep->devMode->dmDriverExtra; hDevMode = GlobalAlloc(GHND, devModeSize); if (hDevMode) { void *dest = GlobalLock(hDevMode); diff --git a/src/gui/dialogs/qprintdialog_win.cpp b/src/gui/dialogs/qprintdialog_win.cpp index e89ce90..6022a66 100644 --- a/src/gui/dialogs/qprintdialog_win.cpp +++ b/src/gui/dialogs/qprintdialog_win.cpp @@ -77,27 +77,22 @@ public: QWin32PrintEnginePrivate *ep; }; -#ifndef Q_OS_WINCE -// If you change this function, make sure you also change the unicode equivalent -template -static PrintDialog *qt_win_make_PRINTDLG(QWidget *parent, - QPrintDialog *pdlg, - QPrintDialogPrivate *d, HGLOBAL *tempDevNames) +static PRINTDLG* qt_win_make_PRINTDLG(QWidget *parent, + QPrintDialog *pdlg, + QPrintDialogPrivate *d, HGLOBAL *tempDevNames) { - PrintDialog *pd = new PrintDialog; - memset(pd, 0, sizeof(PrintDialog)); - pd->lStructSize = sizeof(PrintDialog); + PRINTDLG *pd = new PRINTDLG; + memset(pd, 0, sizeof(PRINTDLG)); + pd->lStructSize = sizeof(PRINTDLG); - void *devMode = sizeof(DeviceMode) == sizeof(DEVMODEA) - ? (void *) d->ep->devModeA() - : (void *) d->ep->devModeW(); + DEVMODE *devMode = d->ep->devMode; if (devMode) { - int size = sizeof(DeviceMode) + ((DeviceMode *) devMode)->dmDriverExtra; + int size = sizeof(DEVMODE) + devMode->dmDriverExtra; pd->hDevMode = GlobalAlloc(GHND, size); { void *dest = GlobalLock(pd->hDevMode); - memcpy(dest, d->ep->devMode, size); + memcpy(dest, devMode, size); GlobalUnlock(pd->hDevMode); } } else { @@ -140,20 +135,14 @@ static PrintDialog *qt_win_make_PRINTDLG(QWidget *parent, return pd; } -#endif // Q_OS_WINCE -// If you change this function, make sure you also change the ansi equivalent -template -static void qt_win_clean_up_PRINTDLG(T **pd) +static void qt_win_clean_up_PRINTDLG(PRINTDLG **pd) { delete *pd; *pd = 0; } - -// If you change this function, make sure you also change the ansi equivalent -template -static void qt_win_read_back_PRINTDLG(T *pd, QPrintDialog *pdlg, QPrintDialogPrivate *d) +static void qt_win_read_back_PRINTDLG(PRINTDLG *pd, QPrintDialog *pdlg, QPrintDialogPrivate *d) { if (pd->Flags & PD_SELECTION) { pdlg->setPrintRange(QPrintDialog::Selection); @@ -236,32 +225,18 @@ int QPrintDialogPrivate::openWindowsPrintDialogModally() bool result; bool done; - void *pd = QT_WA_INLINE( - (void*)(qt_win_make_PRINTDLG(parent, q, this, tempDevNames)), - (void*)(qt_win_make_PRINTDLG(parent, q, this, tempDevNames)) - ); + PRINTDLG *pd = qt_win_make_PRINTDLG(parent, q, this, tempDevNames); do { done = true; - QT_WA({ - PRINTDLGW *pdw = reinterpret_cast(pd); - result = PrintDlgW(pdw); - if ((pdw->Flags & PD_PAGENUMS) && (pdw->nFromPage > pdw->nToPage)) - done = false; - if (result && pdw->hDC == 0) - result = false; - else if (!result) - done = true; - }, { - PRINTDLGA *pda = reinterpret_cast(pd); - result = PrintDlgA(pda); - if ((pda->Flags & PD_PAGENUMS) && (pda->nFromPage > pda->nToPage)) - done = false; - if (result && pda->hDC == 0) - result = false; - else if (!result) - done = true; - }); + result = PrintDlg(pd); + if ((pd->Flags & PD_PAGENUMS) && (pd->nFromPage > pd->nToPage)) + done = false; + if (result && pd->hDC == 0) + result = false; + else if (!result) + done = true; + if (!done) { QMessageBox::warning(0, QPrintDialog::tr("Print"), QPrintDialog::tr("The 'From' value cannot be greater than the 'To' value."), @@ -275,15 +250,8 @@ int QPrintDialogPrivate::openWindowsPrintDialogModally() // write values back... if (result) { - QT_WA({ - PRINTDLGW *pdw = reinterpret_cast(pd); - qt_win_read_back_PRINTDLG(pdw, q, this); - qt_win_clean_up_PRINTDLG(&pdw); - }, { - PRINTDLGA *pda = reinterpret_cast(pd); - qt_win_read_back_PRINTDLG(pda, q, this); - qt_win_clean_up_PRINTDLG(&pda); - }); + qt_win_read_back_PRINTDLG(pd, q, this); + qt_win_clean_up_PRINTDLG(&pd); // update printer validity printer->d_func()->validPrinter = !ep->name.isEmpty(); } diff --git a/src/gui/dialogs/qwizard.cpp b/src/gui/dialogs/qwizard.cpp index 3fdea54..a7dccd8 100644 --- a/src/gui/dialogs/qwizard.cpp +++ b/src/gui/dialogs/qwizard.cpp @@ -1251,13 +1251,7 @@ void QWizardPrivate::updateMinMaxSizes(const QWizardLayoutInfo &info) extraHeight = vistaHelper->titleBarSize() + vistaHelper->topOffset(); #endif QSize minimumSize = mainLayout->totalMinimumSize() + QSize(0, extraHeight); - QSize maximumSize; - bool skipMaxSize = false; -#if defined(Q_WS_WIN) - if (QSysInfo::WindowsVersion <= QSysInfo::WV_Me) // ### See Tasks 164078 and 161660 - skipMaxSize = true; -#endif - maximumSize = mainLayout->totalMaximumSize(); + QSize maximumSize = mainLayout->totalMaximumSize(); if (info.header && headerWidget->maximumWidth() != QWIDGETSIZE_MAX) { minimumSize.setWidth(headerWidget->maximumWidth()); maximumSize.setWidth(headerWidget->maximumWidth()); @@ -1276,13 +1270,11 @@ void QWizardPrivate::updateMinMaxSizes(const QWizardLayoutInfo &info) } if (q->maximumWidth() == maximumWidth) { maximumWidth = maximumSize.width(); - if (!skipMaxSize) - q->setMaximumWidth(maximumWidth); + q->setMaximumWidth(maximumWidth); } if (q->maximumHeight() == maximumHeight) { maximumHeight = maximumSize.height(); - if (!skipMaxSize) - q->setMaximumHeight(maximumHeight); + q->setMaximumHeight(maximumHeight); } } diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp index 2c84ce7..56b53bd 100644 --- a/src/gui/image/qpixmap_win.cpp +++ b/src/gui/image/qpixmap_win.cpp @@ -179,13 +179,7 @@ QPixmap QPixmap::fromWinHBITMAP(HBITMAP bitmap, HBitmapFormat format) 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); if (!res) { qErrnoWarning("QPixmap::fromWinHBITMAP(), failed to get bitmap info"); return QPixmap(); @@ -417,9 +411,9 @@ QPixmap convertHIconToPixmap( const HICON icon, bool large) QPixmap loadIconFromShell32( int resourceId, int size ) { #ifdef Q_OS_WINCE - HMODULE hmod = LoadLibrary((const wchar_t *) QString::fromLatin1("ceshell.dll").utf16()); + HMODULE hmod = LoadLibrary(L"ceshell.dll"); #else - HMODULE hmod = LoadLibraryA("shell32.dll"); + HMODULE hmod = LoadLibrary(L"shell32.dll"); #endif if( hmod ) { HICON iconHandle = (HICON)LoadImage(hmod, MAKEINTRESOURCE(resourceId), IMAGE_ICON, size, size, 0); diff --git a/src/gui/inputmethod/qwininputcontext_win.cpp b/src/gui/inputmethod/qwininputcontext_win.cpp index 3bbde89..741d8da 100644 --- a/src/gui/inputmethod/qwininputcontext_win.cpp +++ b/src/gui/inputmethod/qwininputcontext_win.cpp @@ -45,16 +45,11 @@ #include "qfont.h" #include "qwidget.h" #include "qapplication.h" -#include "qlibrary.h" #include "qevent.h" #include "qtextformat.h" //#define Q_IME_DEBUG -/* Active Input method support on Win95/98/NT */ -#include -#include - #ifdef Q_IME_DEBUG #include "qdebug.h" #endif @@ -218,25 +213,6 @@ static DWORD WM_MSIME_MOUSE = 0; QWinInputContext::QWinInputContext(QObject *parent) : QInputContext(parent), recursionGuard(false) { - if (QSysInfo::WindowsVersion < QSysInfo::WV_2000) { - // try to get the Active IMM COM object on Win95/98/NT, where english versions don't - // support the regular Windows input methods. - if (CoCreateInstance(CLSID_CActiveIMM, NULL, CLSCTX_INPROC_SERVER, - IID_IActiveIMMApp, (LPVOID *)&aimm) != S_OK) { - aimm = 0; - } - if (aimm && (aimm->QueryInterface(IID_IActiveIMMMessagePumpOwner, (LPVOID *)&aimmpump) != S_OK || - aimm->Activate(true) != S_OK)) { - aimm->Release(); - aimm = 0; - if (aimmpump) - aimmpump->Release(); - aimmpump = 0; - } - if (aimmpump) - aimmpump->Start(); - } - #ifndef Q_WS_WINCE QSysInfo::WinVersion ver = QSysInfo::windowsVersion(); if (ver & QSysInfo::WV_NT_based && ver >= QSysInfo::WV_VISTA) { @@ -262,25 +238,21 @@ QWinInputContext::QWinInputContext(QObject *parent) delete []lpList; } } else { - // figure out whether a RTL language is installed - typedef BOOL(WINAPI *PtrIsValidLanguageGroup)(DWORD,DWORD); - PtrIsValidLanguageGroup isValidLanguageGroup = (PtrIsValidLanguageGroup)QLibrary::resolve(QLatin1String("kernel32"), "IsValidLanguageGroup"); - if (isValidLanguageGroup) { - qt_use_rtl_extensions = isValidLanguageGroup(LGRPID_ARABIC, LGRPID_INSTALLED) - || isValidLanguageGroup(LGRPID_HEBREW, LGRPID_INSTALLED); - } - qt_use_rtl_extensions |= IsValidLocale(MAKELCID(MAKELANGID(LANG_ARABIC, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED) - || IsValidLocale(MAKELCID(MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED) + // figure out whether a RTL language is installed + qt_use_rtl_extensions = IsValidLanguageGroup(LGRPID_ARABIC, LGRPID_INSTALLED) + || IsValidLanguageGroup(LGRPID_HEBREW, LGRPID_INSTALLED) + || IsValidLocale(MAKELCID(MAKELANGID(LANG_ARABIC, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED) + || IsValidLocale(MAKELCID(MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED) #ifdef LANG_SYRIAC - || IsValidLocale(MAKELCID(MAKELANGID(LANG_SYRIAC, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED) + || IsValidLocale(MAKELCID(MAKELANGID(LANG_SYRIAC, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED) #endif - || IsValidLocale(MAKELCID(MAKELANGID(LANG_FARSI, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED); + || IsValidLocale(MAKELCID(MAKELANGID(LANG_FARSI, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED); } #else qt_use_rtl_extensions = false; #endif - WM_MSIME_MOUSE = QT_WA_INLINE(RegisterWindowMessage(L"MSIMEMouseOperation"), RegisterWindowMessageA("MSIMEMouseOperation")); + WM_MSIME_MOUSE = RegisterWindowMessage(L"MSIMEMouseOperation"); } QWinInputContext::~QWinInputContext() @@ -337,26 +309,13 @@ static void notifyIME(HIMC imc, DWORD dwAction, DWORD dwIndex, DWORD dwValue) ImmNotifyIME(imc, dwAction, dwIndex, dwValue); } -static LONG getCompositionString(HIMC himc, DWORD dwIndex, LPVOID lpbuf, DWORD dBufLen, bool *unicode = 0) +static LONG getCompositionString(HIMC himc, DWORD dwIndex, LPVOID lpbuf, DWORD dBufLen) { LONG len = 0; - if (unicode) - *unicode = true; if (aimm) aimm->GetCompositionStringW(himc, dwIndex, dBufLen, &len, lpbuf); else - { - if(QSysInfo::WindowsVersion != QSysInfo::WV_95) { - len = ImmGetCompositionStringW(himc, dwIndex, lpbuf, dBufLen); - } -#if !defined(Q_WS_WINCE) - else { - len = ImmGetCompositionStringA(himc, dwIndex, lpbuf, dBufLen); - if (unicode) - *unicode = false; - } -#endif - } + len = ImmGetCompositionString(himc, dwIndex, lpbuf, dBufLen); return len; } @@ -367,29 +326,28 @@ static int getCursorPosition(HIMC himc) static QString getString(HIMC himc, DWORD dwindex, int *selStart = 0, int *selLength = 0) { - static char *buffer = 0; + static wchar_t *buffer = 0; static int buflen = 0; int len = getCompositionString(himc, dwindex, 0, 0) + 1; if (!buffer || len > buflen) { delete [] buffer; buflen = qMin(len, 256); - buffer = new char[buflen]; + buffer = new wchar_t[buflen]; } - bool unicode = true; - len = getCompositionString(himc, dwindex, buffer, buflen, &unicode); + len = getCompositionString(himc, dwindex, buffer, buflen * sizeof(wchar_t)); if (selStart) { - static char *attrbuffer = 0; + static wchar_t *attrbuffer = 0; static int attrbuflen = 0; int attrlen = getCompositionString(himc, dwindex, 0, 0) + 1; if (!attrbuffer || attrlen> attrbuflen) { delete [] attrbuffer; attrbuflen = qMin(attrlen, 256); - attrbuffer = new char[attrbuflen]; + attrbuffer = new wchar_t[attrbuflen]; } - attrlen = getCompositionString(himc, GCS_COMPATTR, attrbuffer, attrbuflen); + attrlen = getCompositionString(himc, GCS_COMPATTR, attrbuffer, attrbuflen * sizeof(wchar_t)); *selStart = attrlen+1; *selLength = -1; for (int i = 0; i < attrlen; i++) { @@ -403,18 +361,8 @@ static QString getString(HIMC himc, DWORD dwindex, int *selStart = 0, int *selLe if (len <= 0) return QString(); - if (unicode) { - return QString((QChar *)buffer, len/sizeof(QChar)); - } - else { - buffer[len] = 0; - WCHAR *wc = new WCHAR[len+1]; - int l = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, - buffer, len, wc, len+1); - QString res = QString((QChar *)wc, l); - delete [] wc; - return res; - } + + return QString((QChar*)buffer, len / sizeof(QChar)); } void QWinInputContext::TranslateMessage(const MSG *msg) @@ -428,11 +376,7 @@ LRESULT QWinInputContext::DefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR LRESULT retval; if (!aimm || aimm->OnDefWindowProc(hwnd, msg, wParam, lParam, &retval) != S_OK) { - QT_WA({ - retval = ::DefWindowProc(hwnd, msg, wParam, lParam); - } , { - retval = ::DefWindowProcA(hwnd,msg, wParam, lParam); - }); + retval = ::DefWindowProc(hwnd, msg, wParam, lParam); } return retval; } @@ -454,21 +398,13 @@ void QWinInputContext::update() HFONT hf; hf = f.handle(); - QT_WA({ - LOGFONT lf; - if (GetObject(hf, sizeof(lf), &lf)) - if (aimm) - aimm->SetCompositionFontW(imc, &lf); - else - ImmSetCompositionFont(imc, &lf); - } , { - LOGFONTA lf; - if (GetObjectA(hf, sizeof(lf), &lf)) - if (aimm) - aimm->SetCompositionFontA(imc, &lf); - else - ImmSetCompositionFontA(imc, &lf); - }); + LOGFONT lf; + if (GetObject(hf, sizeof(lf), &lf)) { + if (aimm) + aimm->SetCompositionFontW(imc, &lf); + else + ImmSetCompositionFont(imc, &lf); + } QRect r = w->inputMethodQuery(Qt::ImMicroFocus).toRect(); diff --git a/src/gui/itemviews/qfileiconprovider.cpp b/src/gui/itemviews/qfileiconprovider.cpp index 3f7b53d..506b988 100644 --- a/src/gui/itemviews/qfileiconprovider.cpp +++ b/src/gui/itemviews/qfileiconprovider.cpp @@ -243,10 +243,10 @@ QIcon QFileIconProviderPrivate::getWinIcon(const QFileInfo &fileInfo) const //Get the small icon #ifndef Q_OS_WINCE - val = SHGetFileInfo((const WCHAR *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, + val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_SMALLICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS); #else - val = SHGetFileInfo((const WCHAR *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, + val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_SYSICONINDEX); #endif if (val) { @@ -282,10 +282,10 @@ QIcon QFileIconProviderPrivate::getWinIcon(const QFileInfo &fileInfo) const //Get the big icon #ifndef Q_OS_WINCE - val = SHGetFileInfo((const WCHAR *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, + val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_LARGEICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS); #else - val = SHGetFileInfo((const WCHAR *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, + val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, sizeof(SHFILEINFO), SHGFI_LARGEICON|SHGFI_SYSICONINDEX); #endif if (val) { @@ -357,9 +357,7 @@ QIcon QFileIconProvider::icon(const QFileInfo &info) const if (info.isRoot()) #if defined (Q_WS_WIN) && !defined(Q_WS_WINCE) { - uint type = DRIVE_UNKNOWN; - QT_WA({ type = GetDriveTypeW((wchar_t *)info.absoluteFilePath().utf16()); }, - { type = GetDriveTypeA(info.absoluteFilePath().toLocal8Bit()); }); + UINT type = GetDriveType((wchar_t *)info.absoluteFilePath().utf16()); switch (type) { case DRIVE_REMOVABLE: diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 05d9b3c..15ddce8 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -863,12 +863,6 @@ void QApplicationPrivate::initialize() if (qgetenv("QT_USE_NATIVE_WINDOWS").toInt() > 0) q->setAttribute(Qt::AA_NativeWindows); -#if defined(Q_WS_WIN) - // Alien is not currently working on Windows 98 - if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) - q->setAttribute(Qt::AA_NativeWindows); -#endif - #ifdef Q_WS_WINCE #ifdef QT_AUTO_MAXIMIZE_THRESHOLD autoMaximizeThreshold = QT_AUTO_MAXIMIZE_THRESHOLD; @@ -4414,13 +4408,13 @@ HRESULT qt_CoCreateGuid(GUID* guid) { // We will use the following information to create the GUID // 1. absolute path to application - wchar_t tempFilename[512]; - if (!GetModuleFileNameW(0, tempFilename, 512)) + wchar_t tempFilename[MAX_PATH]; + if (!GetModuleFileName(0, tempFilename, MAX_PATH)) return S_FALSE; - unsigned int hash = qHash(QString::fromUtf16((const unsigned short *) tempFilename)); + unsigned int hash = qHash(QString::fromWCharArray(tempFilename)); guid->Data1 = hash; // 2. creation time of file - QFileInfo info(QString::fromUtf16((const unsigned short *) tempFilename)); + QFileInfo info(QString::fromWCharArray(tempFilename)); guid->Data2 = qHash(info.created().toTime_t()); // 3. current system time guid->Data3 = qHash(QDateTime::currentDateTime().toTime_t()); @@ -4454,10 +4448,10 @@ QSessionManager::QSessionManager(QApplication * app, QString &id, QString &key) GUID guid; CoCreateGuid(&guid); StringFromGUID2(guid, guidstr, 40); - id = QString::fromUtf16((ushort*)guidstr); + id = QString::fromWCharArray(guidstr); CoCreateGuid(&guid); StringFromGUID2(guid, guidstr, 40); - key = QString::fromUtf16((ushort*)guidstr); + key = QString::fromWCharArray(guidstr); #endif d->sessionId = id; d->sessionKey = key; diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index bb7d931..e1af0f7 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -145,24 +145,6 @@ typedef struct tagTOUCHINPUT #endif -#ifndef FLASHW_STOP -typedef struct { - UINT cbSize; - HWND hwnd; - DWORD dwFlags; - UINT uCount; - DWORD dwTimeout; -} FLASHWINFO, *PFLASHWINFO; -#define FLASHW_STOP 0 -#define FLASHW_CAPTION 0x00000001 -#define FLASHW_TRAY 0x00000002 -#define FLASHW_ALL (FLASHW_CAPTION | FLASHW_TRAY) -#define FLASHW_TIMER 0x00000004 -#define FLASHW_TIMERNOFG 0x0000000C -#endif /* FLASHW_STOP */ -typedef BOOL (WINAPI *PtrFlashWindowEx)(PFLASHWINFO pfwi); -static PtrFlashWindowEx pFlashWindowEx = 0; - #include #include #include @@ -272,10 +254,6 @@ QTabletDeviceData currentTabletPointer; // from qregion_win.cpp extern HRGN qt_tryCreateRegion(QRegion::RegionType type, int left, int top, int right, int bottom); -Q_CORE_EXPORT bool winPeekMessage(MSG* msg, HWND hWnd, UINT wMsgFilterMin, - UINT wMsgFilterMax, UINT wRemoveMsg); -Q_CORE_EXPORT bool winPostMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); - // support for on-the-fly changes of the XP theme engine #ifndef WM_THEMECHANGED #define WM_THEMECHANGED 0x031A @@ -302,7 +280,7 @@ Q_CORE_EXPORT bool winPostMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa #define GET_KEYSTATE_WPARAM(wParam) (LOWORD(wParam)) #endif -// support for multi-media-keys on ME/2000/XP +// support for multi-media-keys #ifndef WM_APPCOMMAND #define WM_APPCOMMAND 0x0319 @@ -375,8 +353,6 @@ Q_CORE_EXPORT bool winPostMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa #endif // WM_APPCOMMAND -static UINT WM95_MOUSEWHEEL = 0; - #if (_WIN32_WINNT < 0x0400) // This struct is defined in winuser.h if the _WIN32_WINNT >= 0x0400 -- in the // other cases we have to define it on our own. @@ -543,14 +519,13 @@ static void qt_set_windows_color_resources() pal.setColor(QPalette::Inactive, QPalette::Light, pal.light().color()); pal.setColor(QPalette::Inactive, QPalette::Dark, pal.dark().color()); - if (QSysInfo::WindowsVersion != QSysInfo::WV_NT && QSysInfo::WindowsVersion != QSysInfo::WV_95) { - if (pal.midlight() == pal.button()) - pal.setColor(QPalette::Midlight, pal.button().color().lighter(110)); - if (pal.background() != pal.base()) { - pal.setColor(QPalette::Inactive, QPalette::Highlight, pal.color(QPalette::Inactive, QPalette::Window)); - pal.setColor(QPalette::Inactive, QPalette::HighlightedText, pal.color(QPalette::Inactive, QPalette::Text)); - } + if (pal.midlight() == pal.button()) + pal.setColor(QPalette::Midlight, pal.button().color().lighter(110)); + if (pal.background() != pal.base()) { + pal.setColor(QPalette::Inactive, QPalette::Highlight, pal.color(QPalette::Inactive, QPalette::Window)); + pal.setColor(QPalette::Inactive, QPalette::HighlightedText, pal.color(QPalette::Inactive, QPalette::Text)); } + const QColor bg = pal.background().color(); const QColor fg = pal.foreground().color(), btn = pal.button().color(); QColor disabled((fg.red()+btn.red())/2,(fg.green()+btn.green())/2, @@ -601,35 +576,18 @@ static void qt_set_windows_color_resources() static void qt_set_windows_font_resources() { #ifndef Q_WS_WINCE - QFont menuFont; - QFont messageFont; - QFont statusFont; - QFont titleFont; - QFont iconTitleFont; - QT_WA({ - NONCLIENTMETRICS ncm; - ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONTW); - SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize , &ncm, 0); - menuFont = qt_LOGFONTtoQFont(ncm.lfMenuFont,true); - messageFont = qt_LOGFONTtoQFont(ncm.lfMessageFont,true); - statusFont = qt_LOGFONTtoQFont(ncm.lfStatusFont,true); - titleFont = qt_LOGFONTtoQFont(ncm.lfCaptionFont,true); - LOGFONTW lfIconTitleFont; - SystemParametersInfoW(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0); - iconTitleFont = qt_LOGFONTtoQFont(lfIconTitleFont,true); - } , { - // A version - NONCLIENTMETRICSA ncm; - ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, lfMessageFont) + sizeof(LOGFONTA); - SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0); - menuFont = qt_LOGFONTtoQFont((LOGFONT&)ncm.lfMenuFont,true); - messageFont = qt_LOGFONTtoQFont((LOGFONT&)ncm.lfMessageFont,true); - statusFont = qt_LOGFONTtoQFont((LOGFONT&)ncm.lfStatusFont,true); - titleFont = qt_LOGFONTtoQFont((LOGFONT&)ncm.lfCaptionFont,true); - LOGFONTA lfIconTitleFont; - SystemParametersInfoA(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0); - iconTitleFont = qt_LOGFONTtoQFont((LOGFONT&)lfIconTitleFont,true); - }); + NONCLIENTMETRICS ncm; + ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT); + SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize , &ncm, 0); + + QFont menuFont = qt_LOGFONTtoQFont(ncm.lfMenuFont, true); + QFont messageFont = qt_LOGFONTtoQFont(ncm.lfMessageFont, true); + QFont statusFont = qt_LOGFONTtoQFont(ncm.lfStatusFont, true); + QFont titleFont = qt_LOGFONTtoQFont(ncm.lfCaptionFont, true); + + LOGFONT lfIconTitleFont; + SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0); + QFont iconTitleFont = qt_LOGFONTtoQFont(lfIconTitleFont, true); QApplication::setFont(menuFont, "QMenu"); QApplication::setFont(menuFont, "QMenuBar"); @@ -657,26 +615,13 @@ static void qt_set_windows_font_resources() static void qt_win_read_cleartype_settings() { + UINT result = 0; #ifdef Q_OS_WINCE - UINT result; - BOOL ok; - ok = SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &result, 0); - if (ok) - qt_cleartype_enabled = result; + if (SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &result, 0)) + qt_cleartype_enabled = result; #else - QT_WA({ - UINT result; - BOOL ok; - ok = SystemParametersInfoW(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0); - if (ok) - qt_cleartype_enabled = (result == FE_FONTSMOOTHINGCLEARTYPE); - }, { - UINT result; - BOOL ok; - ok = SystemParametersInfoA(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0); - if (ok) - qt_cleartype_enabled = (result == FE_FONTSMOOTHINGCLEARTYPE); - }); + if (SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0)) + qt_cleartype_enabled = (result == FE_FONTSMOOTHINGCLEARTYPE); #endif } @@ -694,10 +639,10 @@ void QApplicationPrivate::initializeWidgetPaletteHash() QPalette pal = *QApplicationPrivate::sys_pal; QColor menuCol(qt_colorref2qrgb(GetSysColor(COLOR_MENU))); QColor menuText(qt_colorref2qrgb(GetSysColor(COLOR_MENUTEXT))); - BOOL isFlat = 0; + BOOL isFlat = false; if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) - SystemParametersInfo(0x1022 /*SPI_GETFLATMENU*/, 0, &isFlat, 0); + SystemParametersInfo(SPI_GETFLATMENU, 0, &isFlat, 0); QPalette menu(pal); // we might need a special color group for the menu. menu.setColor(QPalette::Active, QPalette::Button, menuCol); @@ -712,8 +657,7 @@ void QApplicationPrivate::initializeWidgetPaletteHash() QColor(qt_colorref2qrgb(GetSysColor( (QSysInfo::WindowsVersion >= QSysInfo::WV_XP && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) - && isFlat ? COLOR_MENUHILIGHT - : COLOR_HIGHLIGHT)))); + && isFlat ? COLOR_MENUHILIGHT : COLOR_HIGHLIGHT)))); menu.setColor(QPalette::Disabled, QPalette::HighlightedText, disabled); menu.setColor(QPalette::Disabled, QPalette::Button, menu.color(QPalette::Active, QPalette::Button)); @@ -729,10 +673,8 @@ void QApplicationPrivate::initializeWidgetPaletteHash() menu.color(QPalette::Active, QPalette::Highlight)); menu.setColor(QPalette::Inactive, QPalette::HighlightedText, menu.color(QPalette::Active, QPalette::HighlightedText)); - - if (QSysInfo::WindowsVersion != QSysInfo::WV_NT && QSysInfo::WindowsVersion != QSysInfo::WV_95) - menu.setColor(QPalette::Inactive, QPalette::ButtonText, - pal.color(QPalette::Inactive, QPalette::Dark)); + menu.setColor(QPalette::Inactive, QPalette::ButtonText, + pal.color(QPalette::Inactive, QPalette::Dark)); QApplication::setPalette(menu, "QMenu"); if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP @@ -749,15 +691,10 @@ void QApplicationPrivate::initializeWidgetPaletteHash() qt_init() - initializes Qt for Windows *****************************************************************************/ -typedef BOOL (WINAPI *PtrUpdateLayeredWindow)(HWND hwnd, HDC hdcDst, const POINT *pptDst, - const SIZE *psize, HDC hdcSrc, const POINT *pptSrc, COLORREF crKey, - const Q_BLENDFUNCTION *pblend, DWORD dwflags); - typedef BOOL (WINAPI *PtrSetProcessDPIAware) (VOID); - -static PtrUpdateLayeredWindow ptrUpdateLayeredWindow = 0; static PtrSetProcessDPIAware ptrSetProcessDPIAware = 0; - +PtrUpdateLayeredWindow ptrUpdateLayeredWindow = 0; +PtrUpdateLayeredWindowIndirect ptrUpdateLayeredWindowIndirect = 0; static BOOL WINAPI qt_updateLayeredWindowIndirect(HWND hwnd, const Q_UPDATELAYEREDWINDOWINFO *info) { return (*ptrUpdateLayeredWindow)(hwnd, info->hdcDst, info->pptDst, info->psize, info->hdcSrc, @@ -822,46 +759,30 @@ void qt_init(QApplicationPrivate *priv, int) #endif qApp->setObjectName(priv->appName()); -#if !defined(Q_WS_WINCE) // default font - HFONT hfont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); - QFont f(QLatin1String("MS Sans Serif"),8); - int result = 0; - QT_WA({ - LOGFONT lf; - if (result = GetObject(hfont, sizeof(lf), &lf)) - f = qt_LOGFONTtoQFont((LOGFONT&)lf,true); - } , { - LOGFONTA lf; - if (result = GetObjectA(hfont, sizeof(lf), &lf)) - f = qt_LOGFONTtoQFont((LOGFONT&)lf,true); - }); - if (result - && QSysInfo::WindowsVersion >= QSysInfo::WV_2000 - && QSysInfo::WindowsVersion <= QSysInfo::WV_NT_based - && f.family() == QLatin1String("MS Shell Dlg")) - f.setFamily(QLatin1String("MS Shell Dlg 2")); - QApplicationPrivate::setSystemFont(f); -#else //Q_WS_WINCE - LOGFONT lf; - HGDIOBJ stockFont = GetStockObject(SYSTEM_FONT); - int result = 0; - result = GetObject(stockFont, sizeof(lf), &lf); - QFont font = qt_LOGFONTtoQFont(lf, true); - if (result) - QApplicationPrivate::setSystemFont(font); -#endif //Q_WS_WINCE +#ifndef Q_WS_WINCE + HGDIOBJ stockFont = GetStockObject(DEFAULT_GUI_FONT); +#else + HGDIOBJ stockFont = GetStockObject(SYSTEM_FONT); +#endif + + LOGFONT lf; + GetObject(stockFont, sizeof(lf), &lf); + QFont systemFont = qt_LOGFONTtoQFont(lf, true); + +#ifndef Q_WS_WINCE + if (systemFont.family() == QLatin1String("MS Shell Dlg")) { + systemFont.setFamily(QLatin1String("MS Shell Dlg 2")); + } +#endif + + QApplicationPrivate::setSystemFont(systemFont); // QFont::locale_init(); ### Uncomment when it does something on Windows if (QApplication::desktopSettingsAware()) qt_set_windows_resources(); - QT_WA({ - WM95_MOUSEWHEEL = RegisterWindowMessage(L"MSWHEEL_ROLLMSG"); - } , { - WM95_MOUSEWHEEL = RegisterWindowMessageA("MSWHEEL_ROLLMSG"); - }); initWinTabFunctions(); QApplicationPrivate::inputContext = new QWinInputContext(0); @@ -963,7 +884,7 @@ const QString qt_reg_winclass(QWidget *w) // register window class if (w->inherits("QTipLabel") || w->inherits("QAlphaWidget")) { if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) { - style |= 0x00020000; // CS_DROPSHADOW + style |= CS_DROPSHADOW; } cname = QLatin1String("QToolTip"); } else { @@ -981,7 +902,7 @@ const QString qt_reg_winclass(QWidget *w) // register window class #endif if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) - style |= 0x00020000; // CS_DROPSHADOW + style |= CS_DROPSHADOW; icon = false; } else { cname = QLatin1String("QWidget"); @@ -1001,10 +922,10 @@ const QString qt_reg_winclass(QWidget *w) // register window class // unique ID on WinCE to make sure we can // move the windows to the front when starting // a second instance. - wchar_t uniqueAppID[256]; - GetModuleFileNameW(0, uniqueAppID, 255); - cname = QString::number(RegisterWindowMessageW( - (const wchar_t *) QString::fromUtf16((const ushort *)uniqueAppID).toLower().replace(QLatin1Char('\\'), + wchar_t uniqueAppID[MAX_PATH]; + GetModuleFileName(0, uniqueAppID, MAX_PATH); + cname = QString::number(RegisterWindowMessage( + (const wchar_t *) QString::fromWCharArray(uniqueAppID).toLower().replace(QLatin1Char('\\'), QLatin1Char('_')).utf16())); #endif @@ -1016,15 +937,9 @@ const QString qt_reg_winclass(QWidget *w) // register window class static int classExists = -1; if (classExists == -1) { - QT_WA({ - WNDCLASS wcinfo; - classExists = GetClassInfo(qWinAppInst(), (TCHAR*)cname.utf16(), &wcinfo); - classExists = classExists && wcinfo.lpfnWndProc != QtWndProc; - }, { - WNDCLASSA wcinfo; - classExists = GetClassInfoA(qWinAppInst(), cname.toLatin1(), &wcinfo); - classExists = classExists && wcinfo.lpfnWndProc != QtWndProc; - }); + WNDCLASS wcinfo; + classExists = GetClassInfo((HINSTANCE)qWinAppInst(), (wchar_t*)cname.utf16(), &wcinfo); + classExists = classExists && wcinfo.lpfnWndProc != QtWndProc; } if (classExists) @@ -1033,69 +948,31 @@ const QString qt_reg_winclass(QWidget *w) // register window class if (winclassNames()->contains(cname)) // already registered in our list return cname; - ATOM atom; + WNDCLASS wc; + wc.style = style; + wc.lpfnWndProc = (WNDPROC)QtWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = qWinAppInst(); + if (icon) { + wc.hIcon = (HICON)LoadImage(qWinAppInst(), L"IDI_ICON1", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE); #ifndef Q_WS_WINCE - HBRUSH bgBrush = (HBRUSH)GetSysColorBrush(COLOR_WINDOW); - QT_WA({ - WNDCLASS wc; - wc.style = style; - wc.lpfnWndProc = (WNDPROC)QtWndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = qWinAppInst(); - if (icon) { - wc.hIcon = LoadIcon(qWinAppInst(), L"IDI_ICON1"); - if (!wc.hIcon) - wc.hIcon = LoadIcon(0, IDI_APPLICATION); - } else { - wc.hIcon = 0; - } - wc.hCursor = 0; - wc.hbrBackground= bgBrush; - wc.lpszMenuName = 0; - wc.lpszClassName= (TCHAR*)cname.utf16(); - atom = RegisterClass(&wc); - } , { - WNDCLASSA wc; - wc.style = style; - wc.lpfnWndProc = (WNDPROC)QtWndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = qWinAppInst(); - if (icon) { - wc.hIcon = LoadIconA(qWinAppInst(), (char*)"IDI_ICON1"); - if (!wc.hIcon) - wc.hIcon = LoadIconA(0, (char*)IDI_APPLICATION); - } else { - wc.hIcon = 0; - } - wc.hCursor = 0; - wc.hbrBackground= bgBrush; - wc.lpszMenuName = 0; - QByteArray tempArray = cname.toLatin1(); - wc.lpszClassName= tempArray; - atom = RegisterClassA(&wc); - }); + if (!wc.hIcon) + wc.hIcon = (HICON)LoadImage(0, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); +#endif + } else { + wc.hIcon = 0; + } + wc.hCursor = 0; +#ifndef Q_WS_WINCE + wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_WINDOW); #else - WNDCLASS wc; - wc.style = style; - wc.lpfnWndProc = (WNDPROC)QtWndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = qWinAppInst(); - if (icon) { - wc.hIcon = LoadIcon(qWinAppInst(), L"IDI_ICON1"); -// if (!wc.hIcon) -// wc.hIcon = LoadIcon(0, IDI_APPLICATION); - } else { - wc.hIcon = 0; - } - wc.hCursor = 0; - wc.hbrBackground= 0; - wc.lpszMenuName = 0; - wc.lpszClassName= (TCHAR*)cname.utf16(); - atom = RegisterClass(&wc); + wc.hbrBackground = 0; #endif + wc.lpszMenuName = 0; + wc.lpszClassName = (wchar_t*)cname.utf16(); + + ATOM atom = RegisterClass(&wc); #ifndef QT_NO_DEBUG if (!atom) @@ -1117,11 +994,7 @@ static void unregWinClasses() WinClassNameHash *hash = winclassNames(); QHash::ConstIterator it = hash->constBegin(); while (it != hash->constEnd()) { - QT_WA({ - UnregisterClass((TCHAR*)it.key().utf16(), qWinAppInst()); - } , { - UnregisterClassA(it.key().toLatin1(), qWinAppInst()); - }); + UnregisterClass((wchar_t*)it.key().utf16(), qWinAppInst()); ++it; } hash->clear(); @@ -1338,16 +1211,10 @@ void QApplication::beep() static void alert_widget(QWidget *widget, int duration) { - bool stopFlash = duration < 0; - - if (!pFlashWindowEx) { #ifndef Q_OS_WINCE - QLibrary themeLib(QLatin1String("user32")); - pFlashWindowEx = (PtrFlashWindowEx)themeLib.resolve("FlashWindowEx"); -#endif - } + bool stopFlash = duration < 0; - if (pFlashWindowEx && widget && (!widget->isActiveWindow() || stopFlash)) { + if (widget && (!widget->isActiveWindow() || stopFlash)) { DWORD timeOut = GetCaretBlinkTime(); if (timeOut <= 0) timeOut = 250; @@ -1365,8 +1232,9 @@ static void alert_widget(QWidget *widget, int duration) info.dwTimeout = stopFlash ? 0 : timeOut; info.uCount = stopFlash ? 0 : flashCount; - pFlashWindowEx(&info); + FlashWindowEx(&info); } +#endif } void QApplication::alert(QWidget *widget, int duration) @@ -1727,7 +1595,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam // Sometimes we only get a WM_MOUSEMOVE message // and sometimes we get both a WM_MOUSEMOVE and // a WM_LBUTTONDOWN/UP, this creates a spurious mouse - // press/release event, using the winPeekMessage + // press/release event, using the PeekMessage // will help us fix this. This leaves us with a // question: // This effectively kills using the mouse AND the @@ -1737,16 +1605,14 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam bool is_mouse_move = (message == WM_MOUSEMOVE); if (is_mouse_move) { MSG msg1; - if (winPeekMessage(&msg1, msg.hwnd, WM_MOUSEFIRST, - WM_MOUSELAST, PM_NOREMOVE)) + if (PeekMessage(&msg1, msg.hwnd, WM_MOUSEFIRST, + WM_MOUSELAST, PM_NOREMOVE)) next_is_button = (msg1.message == WM_LBUTTONUP || msg1.message == WM_LBUTTONDOWN); } if (!is_mouse_move || (is_mouse_move && !next_is_button)) qt_tabletChokeMouse = false; } - } else if (message == WM95_MOUSEWHEEL) { - result = widget->translateWheelEvent(msg); } else { switch (message) { case WM_TOUCH: @@ -1777,7 +1643,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam case WM_IME_KEYDOWN: case WM_CHAR: { MSG msg1; - bool anyMsg = winPeekMessage(&msg1, msg.hwnd, 0, 0, PM_NOREMOVE); + bool anyMsg = PeekMessage(&msg1, msg.hwnd, 0, 0, PM_NOREMOVE); if (anyMsg && msg1.message == WM_DEADCHAR) { result = true; // consume event since there is a dead char next break; @@ -1977,11 +1843,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam #ifndef QT_NO_WHATSTHIS QWhatsThis::enterWhatsThisMode(); #endif - QT_WA({ - DefWindowProc(hwnd, WM_NCPAINT, 1, 0); - } , { - DefWindowProcA(hwnd, WM_NCPAINT, 1, 0); - }); + DefWindowProc(hwnd, WM_NCPAINT, 1, 0); break; #if defined(QT_NON_COMMERCIAL) QT_NC_SYSCOMMAND @@ -2043,8 +1905,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam break; if (!msg.wParam) { - QString area = QT_WA_INLINE(QString::fromUtf16((unsigned short *)msg.lParam), - QString::fromLocal8Bit((char*)msg.lParam)); + QString area = QString::fromWCharArray((wchar_t*)msg.lParam); if (area == QLatin1String("intl")) { QLocalePrivate::updateSystemPrivate(); if (!widget->testAttribute(Qt::WA_SetLocale)) @@ -2422,11 +2283,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam text = widget->objectName(); ret = qMin(wParam - 1, text.size()); text.resize(ret); - QT_WA({ - memcpy((void *)lParam, text.utf16(), (text.size() + 1) * 2); - }, { - memcpy((void *)lParam, text.toLocal8Bit().data(), text.size() + 1); - }); + memcpy((void *)lParam, text.utf16(), (text.size() + 1) * sizeof(ushort)); delete acc; } if (!ret) { @@ -2514,11 +2371,11 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam #ifndef Q_WS_WINCE case WM_INPUTLANGCHANGE: { - char info[7]; - if (!GetLocaleInfoA(MAKELCID(lParam, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, info, 6)) { + wchar_t info[7]; + if (!GetLocaleInfo(MAKELCID(lParam, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, info, 6)) { inputcharset = CP_ACP; } else { - inputcharset = QString::fromLatin1(info).toInt(); + inputcharset = QString::fromWCharArray(info).toInt(); } QKeyMapper::changeKeyboard(); break; @@ -2714,8 +2571,7 @@ bool qt_try_modal(QWidget *widget, MSG *msg, int& ret) if (type != WM_NCHITTEST) #endif if ((type >= WM_MOUSEFIRST && type <= WM_MOUSELAST) || - type == WM_MOUSEWHEEL || type == (int)WM95_MOUSEWHEEL || - type == WM_MOUSEHWHEEL || + type == WM_MOUSEWHEEL || type == WM_MOUSEHWHEEL || type == WM_MOUSELEAVE || (type >= WM_KEYFIRST && type <= WM_KEYLAST) #ifndef Q_WS_WINCE @@ -2955,19 +2811,10 @@ void qt_win_eatMouseMove() // reset button state MSG msg = {0, 0, 0, 0, 0, 0, 0}; - QT_WA( { - while (PeekMessage(&msg, 0, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)) - ; - if (msg.message == WM_MOUSEMOVE) - PostMessage(msg.hwnd, msg.message, 0, msg.lParam); - }, { - MSG msg; - msg.message = 0; - while (PeekMessageA(&msg, 0, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)) - ; - if (msg.message == WM_MOUSEMOVE) - PostMessageA(msg.hwnd, msg.message, 0, msg.lParam); - } ); + while (PeekMessage(&msg, 0, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)) + ; + if (msg.message == WM_MOUSEMOVE) + PostMessage(msg.hwnd, msg.message, 0, msg.lParam); } // In DnD, the mouse release event never appears, so the @@ -3002,8 +2849,8 @@ bool QETWidget::translateMouseEvent(const MSG &msg) // Compress mouse move events if (msg.message == WM_MOUSEMOVE) { MSG mouseMsg; - while (winPeekMessage(&mouseMsg, msg.hwnd, WM_MOUSEFIRST, - WM_MOUSELAST, PM_NOREMOVE)) { + while (PeekMessage(&mouseMsg, msg.hwnd, WM_MOUSEFIRST, + WM_MOUSELAST, PM_NOREMOVE)) { if (mouseMsg.message == WM_MOUSEMOVE) { #define PEEKMESSAGE_IS_BROKEN 1 #ifdef PEEKMESSAGE_IS_BROKEN @@ -3014,12 +2861,12 @@ bool QETWidget::translateMouseEvent(const MSG &msg) // key release events (kls 2003-05-13): MSG keyMsg; bool done = false; - while (winPeekMessage(&keyMsg, 0, WM_KEYFIRST, WM_KEYLAST, - PM_NOREMOVE)) { + while (PeekMessage(&keyMsg, 0, WM_KEYFIRST, WM_KEYLAST, + PM_NOREMOVE)) { if (keyMsg.time < mouseMsg.time) { if ((keyMsg.lParam & 0xC0000000) == 0x40000000) { - winPeekMessage(&keyMsg, 0, keyMsg.message, - keyMsg.message, PM_REMOVE); + PeekMessage(&keyMsg, 0, keyMsg.message, + keyMsg.message, PM_REMOVE); } else { done = true; break; @@ -3045,8 +2892,8 @@ bool QETWidget::translateMouseEvent(const MSG &msg) msgPtr->wParam = mouseMsg.wParam; msgPtr->pt = mouseMsg.pt; // Remove the mouse move message - winPeekMessage(&mouseMsg, msg.hwnd, WM_MOUSEMOVE, - WM_MOUSEMOVE, PM_REMOVE); + PeekMessage(&mouseMsg, msg.hwnd, WM_MOUSEMOVE, + WM_MOUSEMOVE, PM_REMOVE); } else { break; // there was no more WM_MOUSEMOVE event } @@ -3260,7 +3107,7 @@ bool QETWidget::translateMouseEvent(const MSG &msg) POINT widgetpt = gpos; ScreenToClient(hwndTarget, &widgetpt); LPARAM lParam = MAKELPARAM(widgetpt.x, widgetpt.y); - winPostMessage(hwndTarget, msg.message, msg.wParam, lParam); + PostMessage(hwndTarget, msg.message, msg.wParam, lParam); } } else if (type == QEvent::MouseButtonRelease && button == Qt::RightButton && QApplication::activePopupWidget() == activePopupWidget) { @@ -3627,14 +3474,8 @@ static void initWinTabFunctions() QLibrary library(QLatin1String("wintab32")); if (library.load()) { - QT_WA({ - ptrWTInfo = (PtrWTInfo)library.resolve("WTInfoW"); - ptrWTGet = (PtrWTGet)library.resolve("WTGetW"); - } , { - ptrWTInfo = (PtrWTInfo)library.resolve("WTInfoA"); - ptrWTGet = (PtrWTGet)library.resolve("WTGetA"); - }); - + ptrWTInfo = (PtrWTInfo)library.resolve("WTInfoW"); + ptrWTGet = (PtrWTGet)library.resolve("WTGetW"); ptrWTEnable = (PtrWTEnable)library.resolve("WTEnable"); ptrWTOverlap = (PtrWTEnable)library.resolve("WTOverlap"); ptrWTPacketsGet = (PtrWTPacketsGet)library.resolve("WTPacketsGet"); @@ -3861,11 +3702,7 @@ void QApplication::setWheelScrollLines(int n) #ifdef SPI_SETWHEELSCROLLLINES if (n < 0) n = 0; - QT_WA({ - SystemParametersInfo(SPI_SETWHEELSCROLLLINES, (uint)n, 0, 0); - } , { - SystemParametersInfoA(SPI_SETWHEELSCROLLLINES, (uint)n, 0, 0); - }); + SystemParametersInfo(SPI_SETWHEELSCROLLLINES, (uint)n, 0, 0); #else QApplicationPrivate::wheel_scroll_lines = n; #endif @@ -3875,11 +3712,7 @@ int QApplication::wheelScrollLines() { #ifdef SPI_GETWHEELSCROLLLINES uint i = 3; - QT_WA({ - SystemParametersInfo(SPI_GETWHEELSCROLLLINES, sizeof(uint), &i, 0); - } , { - SystemParametersInfoA(SPI_GETWHEELSCROLLLINES, sizeof(uint), &i, 0); - }); + SystemParametersInfo(SPI_GETWHEELSCROLLLINES, sizeof(uint), &i, 0); if (i > INT_MAX) i = INT_MAX; return i; @@ -3924,8 +3757,7 @@ bool QApplication::isEffectEnabled(Qt::UIEffect effect) if (QColormap::instance().depth() < 16) return false; - if (!effect_override && desktopSettingsAware() - && !(QSysInfo::WindowsVersion == QSysInfo::WV_95 || QSysInfo::WindowsVersion == QSysInfo::WV_NT)) { + if (!effect_override && desktopSettingsAware()) { // we know that they can be used when we are here BOOL enabled = false; UINT api; @@ -3934,33 +3766,22 @@ bool QApplication::isEffectEnabled(Qt::UIEffect effect) api = SPI_GETMENUANIMATION; break; case Qt::UI_FadeMenu: - if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) - return false; api = SPI_GETMENUFADE; break; case Qt::UI_AnimateCombo: api = SPI_GETCOMBOBOXANIMATION; break; case Qt::UI_AnimateTooltip: - if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) - api = SPI_GETMENUANIMATION; - else - api = SPI_GETTOOLTIPANIMATION; + api = SPI_GETTOOLTIPANIMATION; break; case Qt::UI_FadeTooltip: - if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) - return false; api = SPI_GETTOOLTIPFADE; break; default: api = SPI_GETUIEFFECTS; break; } - QT_WA({ - SystemParametersInfo(api, 0, &enabled, 0); - } , { - SystemParametersInfoA(api, 0, &enabled, 0); - }); + SystemParametersInfo(api, 0, &enabled, 0); return enabled; } diff --git a/src/gui/kernel/qclipboard_win.cpp b/src/gui/kernel/qclipboard_win.cpp index 09b5448..f5aa088 100644 --- a/src/gui/kernel/qclipboard_win.cpp +++ b/src/gui/kernel/qclipboard_win.cpp @@ -200,7 +200,7 @@ HRESULT QtCeGetClipboard(IDataObject** obj) if (clipData == 0) { clipData = GetClipboardData(CF_UNICODETEXT); if (clipData != 0) - clipText = QString::fromUtf16((unsigned short *)clipData); + clipText = QString::fromWCharArray((wchar_t *)clipData); } else { clipText = QString::fromLatin1((const char*)clipData); } @@ -325,13 +325,7 @@ bool QClipboard::event(QEvent *e) } if (propagate && d->nextClipboardViewer) { - QT_WA({ - SendMessage(d->nextClipboardViewer, m->message, - m->wParam, m->lParam); - } , { - SendMessageA(d->nextClipboardViewer, m->message, - m->wParam, m->lParam); - }); + SendMessage(d->nextClipboardViewer, m->message, m->wParam, m->lParam); } return true; diff --git a/src/gui/kernel/qcursor_win.cpp b/src/gui/kernel/qcursor_win.cpp index f0dc108..db00835 100644 --- a/src/gui/kernel/qcursor_win.cpp +++ b/src/gui/kernel/qcursor_win.cpp @@ -317,54 +317,50 @@ void QCursorData::update() phand_bits, phandm_bits }; - unsigned short *sh; + wchar_t *sh = 0; switch (cshape) { // map to windows cursor case Qt::ArrowCursor: - sh = (unsigned short*)IDC_ARROW; + sh = IDC_ARROW; break; case Qt::UpArrowCursor: - sh = (unsigned short*)IDC_UPARROW; + sh = IDC_UPARROW; break; case Qt::CrossCursor: - sh = (unsigned short*)IDC_CROSS; + sh = IDC_CROSS; break; case Qt::WaitCursor: - sh = (unsigned short*)IDC_WAIT; + sh = IDC_WAIT; break; case Qt::IBeamCursor: - sh = (unsigned short*)IDC_IBEAM; + sh = IDC_IBEAM; break; case Qt::SizeVerCursor: - sh = (unsigned short*)IDC_SIZENS; + sh = IDC_SIZENS; break; case Qt::SizeHorCursor: - sh = (unsigned short*)IDC_SIZEWE; + sh = IDC_SIZEWE; break; case Qt::SizeBDiagCursor: - sh = (unsigned short*)IDC_SIZENESW; + sh = IDC_SIZENESW; break; case Qt::SizeFDiagCursor: - sh = (unsigned short*)IDC_SIZENWSE; + sh = IDC_SIZENWSE; break; case Qt::SizeAllCursor: - sh = (unsigned short*)IDC_SIZEALL; + sh = IDC_SIZEALL; break; case Qt::ForbiddenCursor: - sh = (unsigned short*)IDC_NO; + sh = IDC_NO; break; case Qt::WhatsThisCursor: - sh = (unsigned short*)IDC_HELP; + sh = IDC_HELP; break; case Qt::BusyCursor: - sh = (unsigned short*)IDC_APPSTARTING; + sh = IDC_APPSTARTING; break; case Qt::PointingHandCursor: - if ((QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) > QSysInfo::WV_95 || - (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based) > QSysInfo::WV_NT) { - sh = (unsigned short*)IDC_HAND; - break; - } - // fall through + sh = IDC_HAND; + break; case Qt::BlankCursor: case Qt::SplitVCursor: case Qt::SplitHCursor: @@ -480,13 +476,7 @@ void QCursorData::update() qWarning("QCursor::update: Invalid cursor shape %d", cshape); return; } - // ### From MSDN: - // ### LoadCursor has been superseded by the LoadImage function. - QT_WA({ - hcurs = LoadCursorW(0, reinterpret_cast(sh)); - } , { - hcurs = LoadCursorA(0, reinterpret_cast(sh)); - }); + hcurs = (HCURSOR)LoadImage(0, sh, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); } QT_END_NAMESPACE diff --git a/src/gui/kernel/qdesktopwidget_win.cpp b/src/gui/kernel/qdesktopwidget_win.cpp index aa290c4..fb176b7 100644 --- a/src/gui/kernel/qdesktopwidget_win.cpp +++ b/src/gui/kernel/qdesktopwidget_win.cpp @@ -152,41 +152,27 @@ void QDesktopWidgetPrivate::init(QDesktopWidget *that) rects = new QVector(); workrects = new QVector(); + screenCount = 0; #ifndef Q_OS_WINCE - if (QSysInfo::WindowsVersion != QSysInfo::WV_95 && QSysInfo::WindowsVersion != QSysInfo::WV_NT) { - screenCount = 0; - // Trying to get the function pointers to Win98/2000 only functions - QLibrary user32Lib(QLatin1String("user32")); - if (!user32Lib.load()) - return; + QLibrary user32Lib(QLatin1String("user32")); + if (user32Lib.load()) { enumDisplayMonitors = (EnumFunc)user32Lib.resolve("EnumDisplayMonitors"); - QT_WA({ - getMonitorInfo = (InfoFunc)user32Lib.resolve("GetMonitorInfoW"); - } , { - getMonitorInfo = (InfoFunc)user32Lib.resolve("GetMonitorInfoA"); - }); - - if (!enumDisplayMonitors || !getMonitorInfo) { - screenCount = GetSystemMetrics(80); // SM_CMONITORS - rects->resize(screenCount); - for (int i = 0; i < screenCount; ++i) - rects->replace(i, that->rect()); - return; - } - // Calls enumCallback - enumDisplayMonitors(0, 0, enumCallback, 0); - enumDisplayMonitors = 0; - getMonitorInfo = 0; - } else { - rects->resize(1); - rects->replace(0, that->rect()); - workrects->resize(1); - workrects->replace(0, that->rect()); + getMonitorInfo = (InfoFunc)user32Lib.resolve("GetMonitorInfoW"); } -#else - screenCount = 0; + if (!enumDisplayMonitors || !getMonitorInfo) { + screenCount = GetSystemMetrics(80); // SM_CMONITORS + rects->resize(screenCount); + for (int i = 0; i < screenCount; ++i) + rects->replace(i, that->rect()); + return; + } + // Calls enumCallback + enumDisplayMonitors(0, 0, enumCallback, 0); + enumDisplayMonitors = 0; + getMonitorInfo = 0; +#else QLibrary coreLib(QLatin1String("coredll")); if (coreLib.load()) { // CE >= 4.0 case @@ -307,70 +293,61 @@ const QRect QDesktopWidget::availableGeometry(int screen) const for(int i=0; i < d->workrects->size(); ++i) qt_get_sip_info((*d->workrects)[i]); #endif - if (QSysInfo::WindowsVersion != QSysInfo::WV_95 && QSysInfo::WindowsVersion != QSysInfo::WV_NT) { - if (screen < 0 || screen >= d->screenCount) - screen = d->primaryScreen; + if (screen < 0 || screen >= d->screenCount) + screen = d->primaryScreen; - return d->workrects->at(screen); - } else { - return d->workrects->at(d->primaryScreen); - } + return d->workrects->at(screen); } const QRect QDesktopWidget::screenGeometry(int screen) const { const QDesktopWidgetPrivate *d = d_func(); - if (QSysInfo::WindowsVersion != QSysInfo::WV_95 && QSysInfo::WindowsVersion != QSysInfo::WV_NT) { - if (screen < 0 || screen >= d->screenCount) - screen = d->primaryScreen; + if (screen < 0 || screen >= d->screenCount) + screen = d->primaryScreen; - return d->rects->at(screen); - } else { - return d->rects->at(d->primaryScreen); - } + return d->rects->at(screen); } int QDesktopWidget::screenNumber(const QWidget *widget) const { Q_D(const QDesktopWidget); - if (QSysInfo::WindowsVersion != QSysInfo::WV_95 && QSysInfo::WindowsVersion != QSysInfo::WV_NT) { - if (!widget) - return d->primaryScreen; - QRect frame = widget->frameGeometry(); - if (!widget->isWindow()) - frame.moveTopLeft(widget->mapToGlobal(QPoint(0,0))); - - int maxSize = -1; - int maxScreen = -1; - - for (int i = 0; i < d->screenCount; ++i) { - QRect sect = d->rects->at(i).intersected(frame); - int size = sect.width() * sect.height(); - if (size > maxSize && sect.width() > 0 && sect.height() > 0) { - maxSize = size; - maxScreen = i; - } - } - return maxScreen; - } else { + if (!widget) return d->primaryScreen; + + QRect frame = widget->frameGeometry(); + if (!widget->isWindow()) + frame.moveTopLeft(widget->mapToGlobal(QPoint(0,0))); + + int maxSize = -1; + int maxScreen = -1; + + for (int i = 0; i < d->screenCount; ++i) { + QRect sect = d->rects->at(i).intersected(frame); + int size = sect.width() * sect.height(); + if (size > maxSize && sect.width() > 0 && sect.height() > 0) { + maxSize = size; + maxScreen = i; + } } + + return maxScreen; } int QDesktopWidget::screenNumber(const QPoint &point) const { Q_D(const QDesktopWidget); + int closestScreen = -1; - if (QSysInfo::WindowsVersion != QSysInfo::WV_95 && QSysInfo::WindowsVersion != QSysInfo::WV_NT) { - int shortestDistance = INT_MAX; - for (int i = 0; i < d->screenCount; ++i) { - int thisDistance = d->pointToRect(point, d->rects->at(i)); - if (thisDistance < shortestDistance) { - shortestDistance = thisDistance; - closestScreen = i; - } + int shortestDistance = INT_MAX; + + for (int i = 0; i < d->screenCount; ++i) { + int thisDistance = d->pointToRect(point, d->rects->at(i)); + if (thisDistance < shortestDistance) { + shortestDistance = thisDistance; + closestScreen = i; } } + return closestScreen; } diff --git a/src/gui/kernel/qdnd_win.cpp b/src/gui/kernel/qdnd_win.cpp index 99c960c..70f89d2 100644 --- a/src/gui/kernel/qdnd_win.cpp +++ b/src/gui/kernel/qdnd_win.cpp @@ -154,9 +154,9 @@ QOleDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium) #ifdef QDND_DEBUG qDebug("QOleDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium)"); #ifndef Q_OS_WINCE - char buf[256] = {0}; - GetClipboardFormatNameA(pformatetc->cfFormat, buf, 255); - qDebug("CF = %d : %s", pformatetc->cfFormat, buf); + wchar_t buf[256] = {0}; + GetClipboardFormatName(pformatetc->cfFormat, buf, 255); + qDebug("CF = %d : %s", pformatetc->cfFormat, QString::fromWCharArray(buf)); #endif #endif @@ -398,52 +398,47 @@ void QOleDropSource::createCursors() int h = cpm.height(); if (!pm.isNull()) { - int x1 = qMin(-hotSpot.x(),0); - int x2 = qMax(pm.width()-hotSpot.x(),cpm.width()); - int y1 = qMin(-hotSpot.y(),0); - int y2 = qMax(pm.height()-hotSpot.y(),cpm.height()); + int x1 = qMin(-hotSpot.x(), 0); + int x2 = qMax(pm.width() - hotSpot.x(), cpm.width()); + int y1 = qMin(-hotSpot.y(), 0); + int y2 = qMax(pm.height() - hotSpot.y(), cpm.height()); - w = x2-x1+1; - h = y2-y1+1; + w = x2 - x1 + 1; + h = y2 - y1 + 1; } QRect srcRect = pm.rect(); QPoint pmDest = QPoint(qMax(0, -hotSpot.x()), qMax(0, -hotSpot.y())); QPoint newHotSpot = hotSpot; -#if !defined(Q_OS_WINCE) || defined(GWES_ICONCURS) - bool limitedCursorSize = (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) - || (QSysInfo::WindowsVersion == QSysInfo::WV_NT) - || (QSysInfo::WindowsVersion == QSysInfo::WV_CE); - - if (limitedCursorSize) { - // Limited cursor size - int reqw = GetSystemMetrics(SM_CXCURSOR); - int reqh = GetSystemMetrics(SM_CYCURSOR); - - QPoint hotspotInPM = newHotSpot - pmDest; - if (reqw < w) { - // Not wide enough - move objectpm right - qreal r = qreal(newHotSpot.x()) / w; - newHotSpot = QPoint(int(r * reqw), newHotSpot.y()); - if (newHotSpot.x() + cpm.width() > reqw) - newHotSpot.setX(reqw - cpm.width()); - - srcRect = QRect(QPoint(hotspotInPM.x() - newHotSpot.x(), srcRect.top()), QSize(reqw, srcRect.height())); - } - if (reqh < h) { - qreal r = qreal(newHotSpot.y()) / h; - newHotSpot = QPoint(newHotSpot.x(), int(r * reqh)); - if (newHotSpot.y() + cpm.height() > reqh) - newHotSpot.setY(reqh - cpm.height()); - - srcRect = QRect(QPoint(srcRect.left(), hotspotInPM.y() - newHotSpot.y()), QSize(srcRect.width(), reqh)); - } - // Always use system cursor size - w = reqw; - h = reqh; +#if defined(Q_OS_WINCE) + // Limited cursor size + int reqw = GetSystemMetrics(SM_CXCURSOR); + int reqh = GetSystemMetrics(SM_CYCURSOR); + + QPoint hotspotInPM = newHotSpot - pmDest; + if (reqw < w) { + // Not wide enough - move objectpm right + qreal r = qreal(newHotSpot.x()) / w; + newHotSpot = QPoint(int(r * reqw), newHotSpot.y()); + if (newHotSpot.x() + cpm.width() > reqw) + newHotSpot.setX(reqw - cpm.width()); + + srcRect = QRect(QPoint(hotspotInPM.x() - newHotSpot.x(), srcRect.top()), QSize(reqw, srcRect.height())); } + if (reqh < h) { + qreal r = qreal(newHotSpot.y()) / h; + newHotSpot = QPoint(newHotSpot.x(), int(r * reqh)); + if (newHotSpot.y() + cpm.height() > reqh) + newHotSpot.setY(reqh - cpm.height()); + + srcRect = QRect(QPoint(srcRect.left(), hotspotInPM.y() - newHotSpot.y()), QSize(srcRect.width(), reqh)); + } + // Always use system cursor size + w = reqw; + h = reqh; #endif + QPixmap newCursor(w, h); if (!pm.isNull()) { newCursor.fill(QColor(0, 0, 0, 0)); diff --git a/src/gui/kernel/qguifunctions_wince.cpp b/src/gui/kernel/qguifunctions_wince.cpp index c986117..011c726 100644 --- a/src/gui/kernel/qguifunctions_wince.cpp +++ b/src/gui/kernel/qguifunctions_wince.cpp @@ -215,13 +215,7 @@ int qt_wince_GetDIBits(HDC /*hdc*/ , HBITMAP hSourceBitmap, uint, uint, LPVOID l return ret; } -bool qt_wince_TextOutW(HDC hdc, int x, int y, LPWSTR lpString, UINT c) -{ - return ExtTextOutW(hdc, x, y, 0, NULL, lpString, c, NULL); -} - - -HINSTANCE qt_wince_ShellExecute(HWND hwnd, LPCTSTR, LPCTSTR file, LPCTSTR params, LPCTSTR dir, int showCmd) +HINSTANCE qt_wince_ShellExecute(HWND hwnd, LPCWSTR, LPCWSTR file, LPCWSTR params, LPCWSTR dir, int showCmd) { SHELLEXECUTEINFO info; info.hwnd = hwnd; @@ -253,17 +247,11 @@ COLORREF qt_wince_PALETTEINDEX( WORD /*wPaletteIndex*/) return 0; } -BOOL qt_wince_TextOut( HDC hdc, int nXStart, int nYStart, LPCTSTR lpString, int cbString ) -{ - return ExtTextOut( hdc, nXStart, nYStart - 16, 0, NULL, lpString, cbString, NULL ); -} - // Internal Qt ----------------------------------------------------- bool qt_wince_is_platform(const QString &platformString) { - TCHAR tszPlatform[64]; - if (SystemParametersInfo(SPI_GETPLATFORMTYPE, - sizeof(tszPlatform)/sizeof(*tszPlatform),tszPlatform,0)) - if (0 == _tcsicmp(reinterpret_cast (platformString.utf16()), tszPlatform)) + wchar_t tszPlatform[64]; + if (SystemParametersInfo(SPI_GETPLATFORMTYPE, sizeof(tszPlatform) / sizeof(wchar_t), tszPlatform, 0)) + if (0 == _tcsicmp(reinterpret_cast (platformString.utf16()), tszPlatform)) return true; return false; } @@ -316,8 +304,8 @@ void qt_wince_maximize(QWidget *widget) void qt_wince_minimize(HWND hwnd) { - uint exstyle = GetWindowLongW(hwnd, GWL_EXSTYLE); - uint style = GetWindowLongW(hwnd, GWL_STYLE); + uint exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); + uint style = GetWindowLong(hwnd, GWL_STYLE); RECT rect; RECT crect = {0,0,0,0}; GetWindowRect(hwnd, &rect); diff --git a/src/gui/kernel/qguifunctions_wince.h b/src/gui/kernel/qguifunctions_wince.h index bcf2004..234c8c6 100644 --- a/src/gui/kernel/qguifunctions_wince.h +++ b/src/gui/kernel/qguifunctions_wince.h @@ -73,10 +73,6 @@ int qt_wince_GetDIBits(HDC, HBITMAP, uint, uint, void*, LPBITMAPINFO, uint); // QWidget #define SW_SHOWMINIMIZED SW_MINIMIZE -// QPaintEngine -bool qt_wince_TextOutW(HDC, int, int, LPWSTR, UINT); -#define TextOutW(a,b,c,d,e) qt_wince_TextOutW(a,b,c,d,e) - // QRegion #define ALTERNATE 0 #define WINDING 1 @@ -128,7 +124,7 @@ typedef struct tagTTPOLYCURVE #define TT_PRIM_CSPLINE 3 #define ANSI_VAR_FONT 12 -HINSTANCE qt_wince_ShellExecute(HWND hwnd, LPCTSTR operation, LPCTSTR file, LPCTSTR params, LPCTSTR dir, int showCmd); +HINSTANCE qt_wince_ShellExecute(HWND hwnd, LPCWSTR operation, LPCWSTR file, LPCWSTR params, LPCWSTR dir, int showCmd); #define ShellExecute(a,b,c,d,e,f) qt_wince_ShellExecute(a,b,c,d,e,f) @@ -150,8 +146,6 @@ HWND qt_wince_SetClipboardViewer( // Graphics --------------------------------------------------------- COLORREF qt_wince_PALETTEINDEX( WORD wPaletteIndex ); #define PALETTEINDEX(a) qt_wince_PALETTEINDEX(a) -BOOL qt_wince_TextOut( HDC hdc, int nXStart, int nYStart, LPCTSTR lpString, int cbString ); -#define TextOut(a,b,c,d,e) qt_wince_TextOut(a,b,c,d,e) #endif // Q_OS_WINCE #endif // QGUIFUNCTIONS_WCE_H diff --git a/src/gui/kernel/qkeymapper_win.cpp b/src/gui/kernel/qkeymapper_win.cpp index e40dfa0..3d53f31 100644 --- a/src/gui/kernel/qkeymapper_win.cpp +++ b/src/gui/kernel/qkeymapper_win.cpp @@ -57,9 +57,7 @@ QT_BEGIN_NAMESPACE // Implemented elsewhere extern "C" LRESULT CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM); -Q_CORE_EXPORT bool winPostMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); -Q_CORE_EXPORT bool winPeekMessage(MSG* msg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, - UINT wRemoveMsg); + extern Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id); #ifndef LANG_PASHTO #define LANG_PASHTO 0x63 @@ -467,12 +465,7 @@ static inline int toKeyOrUnicode(int vk, int scancode, unsigned char *kbdBuffer, Q_ASSERT(vk > 0 && vk < 256); int code = 0; QChar unicodeBuffer[5]; - int res = 0; - if (QSysInfo::WindowsVersion < QSysInfo::WV_NT) - res = ToAscii(vk, scancode, kbdBuffer, reinterpret_cast(unicodeBuffer), 0); - else - res = ToUnicode(vk, scancode, kbdBuffer, reinterpret_cast(unicodeBuffer), 5, 0); - + int res = ToUnicode(vk, scancode, kbdBuffer, reinterpret_cast(unicodeBuffer), 5, 0); if (res) code = unicodeBuffer[0].toUpper().unicode(); @@ -504,38 +497,6 @@ static inline int asciiToKeycode(char a, int state) return a & 0xff; } -static int inputcharset = CP_ACP; -static inline QChar wmchar_to_unicode(DWORD c) -{ - // qt_winMB2QString is the generalization of this function. - QT_WA({ - return QChar((ushort)c); - } , { - char mb[2]; - mb[0] = c & 0xff; - mb[1] = 0; - WCHAR wc[1]; - MultiByteToWideChar(inputcharset, MB_PRECOMPOSED, mb, -1, wc, 1); - return QChar(wc[0]); - }); -} - -static inline QChar imechar_to_unicode(DWORD c) -{ - // qt_winMB2QString is the generalization of this function. - QT_WA({ - return QChar((ushort)c); - } , { - char mb[3]; - mb[0] = (c >> 8) & 0xff; - mb[1] = c & 0xff; - mb[2] = 0; - WCHAR wc[1]; - MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, mb, -1, wc, 1); - return QChar(wc[0]); - }); -} - static inline bool isModifierKey(int code) { return (code >= Qt::Key_Shift) && (code <= Qt::Key_ScrollLock); @@ -635,43 +596,15 @@ void QKeyMapperPrivate::clearMappings() /* MAKELCID()'s first argument is a WORD, and GetKeyboardLayout() * returns a DWORD. */ -// LCID newLCID = MAKELCID(DWORD(GetKeyboardLayout(0)), SORT_DEFAULT); + + LCID newLCID = MAKELCID((DWORD)GetKeyboardLayout(0), SORT_DEFAULT); // keyboardInputLocale = qt_localeFromLCID(newLCID); - LCID newLCID = MAKELCID( - reinterpret_cast(GetKeyboardLayout(0)), - SORT_DEFAULT - ); - keyboardInputLocale = qt_localeFromLCID(newLCID); + bool bidi = false; -#ifdef UNICODE - if (QSysInfo::WindowsVersion >= QSysInfo::WV_2000) { - WCHAR wchLCIDFontSig[16]; - if (GetLocaleInfoW(newLCID, - LOCALE_FONTSIGNATURE, - &wchLCIDFontSig[0], - (sizeof(wchLCIDFontSig)/sizeof(WCHAR))) - && (wchLCIDFontSig[7] & (WCHAR)0x0800)) + wchar_t LCIDFontSig[16]; + if (GetLocaleInfo(newLCID, LOCALE_FONTSIGNATURE, LCIDFontSig, sizeof(LCIDFontSig) / sizeof(wchar_t)) + && (LCIDFontSig[7] & (wchar_t)0x0800)) bidi = true; - } else -#endif //UNICODE - { - if (newLCID == 0x0859 || //Sindhi (Arabic script) - newLCID == 0x0460) //Kashmiri (Arabic script) - bidi = true;; - - switch (PRIMARYLANGID(newLCID)) - { - case LANG_ARABIC: - case LANG_HEBREW: - case LANG_URDU: - case LANG_FARSI: - case LANG_PASHTO: - //case LANG_UIGHUR: - case LANG_SYRIAC: - case LANG_DIVEHI: - bidi = true; - } - } keyboardInputDirection = bidi ? Qt::RightToLeft : Qt::LeftToRight; } @@ -760,7 +693,7 @@ void QKeyMapperPrivate::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32 keyLayout[vk_key]->qtKey[8] = fallbackKey; // If this vk_key a Dead Key - if (MapVirtualKey(vk_key, 2) & 0x80008000) { // (High-order dead key on Win 95 is 0x8000) + if (MapVirtualKey(vk_key, 2) & 0x80000000) { // Push a Space, then the original key through the low-level ToAscii functions. // We do this because these functions (ToAscii / ToUnicode) will alter the internal state of // the keyboard driver By doing the following, we set the keyboard driver state back to what @@ -837,13 +770,13 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool bool isNumpad = (msg.wParam >= VK_NUMPAD0 && msg.wParam <= VK_NUMPAD9); quint32 nModifiers = 0; - if (QSysInfo::WindowsVersion < QSysInfo::WV_NT || QSysInfo::WindowsVersion & QSysInfo::WV_CE_based) { +#if defined(QT_OS_WINCE) nModifiers |= (GetKeyState(VK_SHIFT ) < 0 ? ShiftAny : 0); nModifiers |= (GetKeyState(VK_CONTROL) < 0 ? ControlAny : 0); nModifiers |= (GetKeyState(VK_MENU ) < 0 ? AltAny : 0); nModifiers |= (GetKeyState(VK_LWIN ) < 0 ? MetaLeft : 0); nModifiers |= (GetKeyState(VK_RWIN ) < 0 ? MetaRight : 0); - } else { +#else // Map native modifiers to some bit representation nModifiers |= (GetKeyState(VK_LSHIFT ) & 0x80 ? ShiftLeft : 0); nModifiers |= (GetKeyState(VK_RSHIFT ) & 0x80 ? ShiftRight : 0); @@ -857,7 +790,8 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool nModifiers |= (GetKeyState(VK_CAPITAL ) & 0x01 ? CapsLock : 0); nModifiers |= (GetKeyState(VK_NUMLOCK ) & 0x01 ? NumLock : 0); nModifiers |= (GetKeyState(VK_SCROLL ) & 0x01 ? ScrollLock : 0); - } +#endif // QT_OS_WINCE + if (msg.lParam & ExtendedKey) nModifiers |= msg.lParam & ExtendedKey; @@ -870,12 +804,12 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool // Now we know enough to either have MapVirtualKey or our own keymap tell us if it's a deadkey bool isDeadKey = isADeadKey(msg.wParam, state) - || MapVirtualKey(msg.wParam, 2) & 0x80008000; // High-order on 95 is 0x8000 + || MapVirtualKey(msg.wParam, 2) & 0x80000000; // A multi-character key not found by our look-ahead if (msgType == WM_CHAR) { QString s; - QChar ch = wmchar_to_unicode(msg.wParam); + QChar ch = QChar((ushort)msg.wParam); if (!ch.isNull()) s += ch; @@ -886,7 +820,7 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool // Input method characters not found by our look-ahead else if (msgType == WM_IME_CHAR) { QString s; - QChar ch = imechar_to_unicode(msg.wParam); + QChar ch = QChar((ushort)msg.wParam); if (!ch.isNull()) s += ch; @@ -1050,11 +984,9 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool : msgType == WM_IME_KEYDOWN ? WM_IME_CHAR : WM_SYSCHAR); QChar uch; - if (winPeekMessage(&wm_char, 0, charType, charType, PM_REMOVE)) { + if (PeekMessage(&wm_char, 0, charType, charType, PM_REMOVE)) { // Found a ?_CHAR - uch = charType == WM_IME_CHAR - ? imechar_to_unicode(wm_char.wParam) - : wmchar_to_unicode(wm_char.wParam); + uch = QChar((ushort)wm_char.wParam); if (msgType == WM_SYSKEYDOWN && uch.isLetter() && (msg.lParam & KF_ALTDOWN)) uch = uch.toLower(); // (See doc of WM_SYSCHAR) Alt-letter if (!code && !uch.row()) @@ -1067,7 +999,7 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool // to find the correct key using the current message parameters & keyboard state. if (uch.isNull() && msgType == WM_IME_KEYDOWN) { BYTE keyState[256]; - WCHAR newKey[3] = {0}; + wchar_t newKey[3] = {0}; GetKeyboardState(keyState); int val = ToUnicode(vk_key, scancode, keyState, newKey, 2, 0); if (val == 1) { @@ -1085,18 +1017,10 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool uch = QChar(QLatin1Char(0x7f)); // Windows doesn't know this one. } else { if (msgType != WM_SYSKEYDOWN || !code) { - UINT map; - QT_WA({ - map = MapVirtualKey(msg.wParam, 2); - } , { - map = MapVirtualKeyA(msg.wParam, 2); - // High-order bit is 0x8000 on '95 - if (map & 0x8000) - map = (map^0x8000)|0x80000000; - }); + UINT map = MapVirtualKey(msg.wParam, 2); // If the high bit of the return value is set, it's a deadkey if (!(map & 0x80000000)) - uch = wmchar_to_unicode((DWORD)map); + uch = QChar((ushort)map); } } if (!code && !uch.row()) @@ -1237,6 +1161,8 @@ bool QKeyMapper::sendKeyEvent(QWidget *widget, bool grab, if (QApplicationPrivate::instance()->qt_tryAccelEvent(widget, &a)) return true; } +#else + Q_UNUSED(grab); #endif if (!widget->isEnabled()) return false; diff --git a/src/gui/kernel/qmime_win.cpp b/src/gui/kernel/qmime_win.cpp index bc15638..c7559d8 100644 --- a/src/gui/kernel/qmime_win.cpp +++ b/src/gui/kernel/qmime_win.cpp @@ -281,11 +281,7 @@ QWindowsMime::~QWindowsMime() */ int QWindowsMime::registerMimeType(const QString &mime) { -#ifdef Q_OS_WINCE int f = RegisterClipboardFormat(reinterpret_cast (mime.utf16())); -#else - int f = RegisterClipboardFormatA(mime.toLocal8Bit()); -#endif if (!f) qErrnoWarning("QWindowsMime::registerMimeType: Failed to register clipboard format"); @@ -401,9 +397,9 @@ QStringList QWindowsMime::allMimesForFormats(IDataObject *pDataObj) while (S_OK == fmtenum->Next(1, &fmtetc, 0)) { #if defined(QMIME_DEBUG) && !defined(Q_OS_WINCE) qDebug("QWindowsMime::allMimesForFormats()"); - char buf[256] = {0}; - GetClipboardFormatNameA(fmtetc.cfFormat, buf, 255); - qDebug("CF = %d : %s", fmtetc.cfFormat, buf); + wchar_t buf[256] = {0}; + GetClipboardFormatName(fmtetc.cfFormat, buf, 255); + qDebug("CF = %d : %s", fmtetc.cfFormat, QString::fromWCharArray(buf)); #endif for (int i=mimes.size()-1; i>=0; --i) { QString format = mimes.at(i)->mimeForFormat(fmtetc); @@ -504,7 +500,7 @@ bool QWindowsMimeText::convertFromMime(const FORMATETC &formatetc, const QMimeDa ++u; } res.truncate(ri); - const int byteLength = res.length()*2; + const int byteLength = res.length() * sizeof(ushort); QByteArray r(byteLength + 2, '\0'); memcpy(r.data(), res.unicode(), byteLength); r[byteLength] = 0; @@ -549,7 +545,7 @@ QVariant QWindowsMimeText::convertToMime(const QString &mime, LPDATAOBJECT pData QString str; QByteArray data = getData(CF_UNICODETEXT, pDataObj); if (!data.isEmpty()) { - str = QString::fromUtf16((const unsigned short *)data.data()); + str = QString::fromWCharArray((const wchar_t *)data.data()); str.replace(QLatin1String("\r\n"), QLatin1String("\n")); } else { data = getData(CF_TEXT, pDataObj); @@ -620,11 +616,7 @@ bool QWindowsMimeURI::convertFromMime(const FORMATETC &formatetc, const QMimeDat for (int i=0; ifNC = true; char* files = ((char*)d) + d->pFiles; - QT_WA({ - d->fWide = true; - TCHAR* f = (TCHAR*)files; - for (int i=0; ifWide = false; - char* f = files; - for (int i=0; ifWide = true; + wchar_t* f = (wchar_t*)files; + for (int i=0; i urls = mimeData->urls(); QByteArray result; QString url = urls.at(0).toString(); - result = QByteArray((const char *)url.utf16(), url.length() * 2); + result = QByteArray((const char *)url.utf16(), url.length() * sizeof(ushort)); result.append('\0'); result.append('\0'); return setData(result, pmedium); @@ -720,15 +698,15 @@ QVariant QWindowsMimeURI::convertToMime(const QString &mimeType, LPDATAOBJECT pD LPDROPFILES hdrop = (LPDROPFILES)data.data(); if (hdrop->fWide) { - const ushort* filesw = (const ushort*)(data.data() + hdrop->pFiles); - int i=0; + const wchar_t* filesw = (const wchar_t *)(data.data() + hdrop->pFiles); + int i = 0; while (filesw[i]) { - QString fileurl = QString::fromUtf16(filesw+i); + QString fileurl = QString::fromWCharArray(filesw + i); urls += QUrl::fromLocalFile(fileurl); i += fileurl.length()+1; } } else { - const char* files = (const char*)data.data() + hdrop->pFiles; + const char* files = (const char *)data.data() + hdrop->pFiles; int i=0; while (files[i]) { urls += QUrl::fromLocalFile(QString::fromLocal8Bit(files+i)); @@ -744,7 +722,7 @@ QVariant QWindowsMimeURI::convertToMime(const QString &mimeType, LPDATAOBJECT pD QByteArray data = getData(CF_INETURL_W, pDataObj); if (data.isEmpty()) return QVariant(); - return QUrl(QString::fromUtf16((const unsigned short *)data.constData())); + return QUrl(QString::fromWCharArray((const wchar_t *)data.constData())); } else if (canGetData(CF_INETURL, pDataObj)) { QByteArray data = getData(CF_INETURL, pDataObj); if (data.isEmpty()) @@ -913,11 +891,7 @@ private: QWindowsMimeImage::QWindowsMimeImage() { -#ifdef Q_OS_WINCE - CF_PNG = RegisterClipboardFormat(reinterpret_cast (QString::fromLatin1("PNG").utf16())); -#else - CF_PNG = RegisterClipboardFormatA("PNG"); -#endif + CF_PNG = RegisterClipboardFormat(L"PNG"); } QVector QWindowsMimeImage::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const @@ -1114,7 +1088,7 @@ bool QBuiltInMimes::convertFromMime(const FORMATETC &formatetc, const QMimeData ++u; } res.truncate(ri); - const int byteLength = res.length()*2; + const int byteLength = res.length() * sizeof(ushort); QByteArray r(byteLength + 2, '\0'); memcpy(r.data(), res.unicode(), byteLength); r[byteLength] = 0; @@ -1154,8 +1128,8 @@ QVariant QBuiltInMimes::convertToMime(const QString &mimeType, IDataObject *pDat qDebug("QBuiltInMimes::convertToMime()"); #endif if (mimeType == QLatin1String("text/html") && preferredType == QVariant::String) { - // text/html is in wide chars on windows (compatible with mozillia) - val = QString::fromUtf16((const unsigned short *)data.data()); + // text/html is in wide chars on windows (compatible with Mozilla) + val = QString::fromWCharArray((const wchar_t *)data.data()); } else { val = data; // it should be enough to return the data and let QMimeData do the rest. } @@ -1280,11 +1254,7 @@ bool QLastResortMimes::canConvertToMime(const QString &mimeType, IDataObject *pD { if (isCustomMimeType(mimeType)) { QString clipFormat = customMimeType(mimeType); -#ifdef Q_OS_WINCE int cf = RegisterClipboardFormat(reinterpret_cast (clipFormat.utf16())); -#else - int cf = RegisterClipboardFormatA(clipFormat.toLocal8Bit()); -#endif return canGetData(cf, pDataObj); } else if (formats.keys(mimeType).isEmpty()) { // if it is not in there then register it an see if we can get it @@ -1304,11 +1274,7 @@ QVariant QLastResortMimes::convertToMime(const QString &mimeType, IDataObject *p QByteArray data; if (isCustomMimeType(mimeType)) { QString clipFormat = customMimeType(mimeType); -#ifdef Q_OS_WINCE int cf = RegisterClipboardFormat(reinterpret_cast (clipFormat.utf16())); -#else - int cf = RegisterClipboardFormatA(clipFormat.toLocal8Bit()); -#endif data = getData(cf, pDataObj); } else if (formats.keys(mimeType).isEmpty()) { int cf = QWindowsMime::registerMimeType(mimeType); @@ -1325,46 +1291,38 @@ QVariant QLastResortMimes::convertToMime(const QString &mimeType, IDataObject *p QString QLastResortMimes::mimeForFormat(const FORMATETC &formatetc) const { QString format = formats.value(getCf(formatetc)); - if (format.isEmpty()) { - QByteArray ba; - QString clipFormat; - int len; - QT_WA({ - ba.resize(256*2); - len = GetClipboardFormatNameW(getCf(formatetc), (TCHAR*)ba.data(), 255); - if (len) - clipFormat = QString::fromUtf16((ushort *)ba.data(), len); - } , { - ba.resize(256); - len = GetClipboardFormatNameA(getCf(formatetc), ba.data(), 255); - if (len) - clipFormat = QString::fromLocal8Bit(ba.data(), len); - }); - if (len) { + if (!format.isEmpty()) + return format; + + wchar_t buffer[256]; + int len = GetClipboardFormatName(getCf(formatetc), buffer, 256); + + if (len) { + QString clipFormat = QString::fromWCharArray(buffer, len); #ifndef QT_NO_DRAGANDDROP - if (QInternalMimeData::canReadData(clipFormat)) - format = clipFormat; - else if((formatetc.cfFormat >= 0xC000)){ - //create the mime as custom. not registered. - if (!excludeList.contains(clipFormat, Qt::CaseInsensitive)) { - //check if this is a mime type - bool ianaType = false; - int sz = ianaTypes.size(); - for (int i = 0; i < sz; i++) { - if (clipFormat.startsWith(ianaTypes[i], Qt::CaseInsensitive)) { - ianaType = true; - break; - } + if (QInternalMimeData::canReadData(clipFormat)) + format = clipFormat; + else if((formatetc.cfFormat >= 0xC000)){ + //create the mime as custom. not registered. + if (!excludeList.contains(clipFormat, Qt::CaseInsensitive)) { + //check if this is a mime type + bool ianaType = false; + int sz = ianaTypes.size(); + for (int i = 0; i < sz; i++) { + if (clipFormat.startsWith(ianaTypes[i], Qt::CaseInsensitive)) { + ianaType = true; + break; } - if (!ianaType) - format = QLatin1String(x_qt_windows_mime) + clipFormat + QLatin1Char('\"'); - else - format = clipFormat; } + if (!ianaType) + format = QLatin1String(x_qt_windows_mime) + clipFormat + QLatin1Char('\"'); + else + format = clipFormat; } -#endif //QT_NO_DRAGANDDROP } +#endif //QT_NO_DRAGANDDROP } + return format; } diff --git a/src/gui/kernel/qsound_win.cpp b/src/gui/kernel/qsound_win.cpp index 7330d4b..82854ae 100644 --- a/src/gui/kernel/qsound_win.cpp +++ b/src/gui/kernel/qsound_win.cpp @@ -77,13 +77,8 @@ public: QAuServerWindows::QAuServerWindows(QObject* parent) : QAuServer(parent), current(0) { - QT_WA({ - mutex = CreateMutexW(0, 0, 0); - event = CreateEventW(0, FALSE, FALSE, 0); - } , { - mutex = CreateMutexA(0, 0, 0); - event = CreateEventA(0, FALSE, FALSE, 0); - }); + mutex = CreateMutex(0, 0, 0); + event = CreateEvent(0, FALSE, FALSE, 0); } QAuServerWindows::~QAuServerWindows() @@ -133,13 +128,9 @@ DWORD WINAPI SoundPlayProc(LPVOID param) if (loops == -1) flags |= SND_LOOP; - QT_WA({ - PlaySoundW((TCHAR*)filename.utf16(), 0, flags); - } , { - PlaySoundA(QFile::encodeName(filename).data(), 0, flags); - }); - if (sound && loops == 1) - server->decLoop(sound); + PlaySound((wchar_t*)filename.utf16(), 0, flags); + if (sound && loops == 1) + server->decLoop(sound); // GUI thread continues, but we are done as well. SetEvent(event); @@ -148,18 +139,13 @@ DWORD WINAPI SoundPlayProc(LPVOID param) QPointer guarded_sound = sound; SetEvent(event); - for (int l = 0; l < loops && server->current; ++l) { - QT_WA( { - PlaySoundW( (TCHAR*)filename.utf16(), 0, SND_FILENAME|SND_SYNC ); - } , { - PlaySoundA( QFile::encodeName(filename).data(), 0, - SND_FILENAME|SND_SYNC ); - } ); - - if (guarded_sound) - server->decLoop(guarded_sound); - } - server->current = 0; + for (int l = 0; l < loops && server->current; ++l) { + PlaySound((wchar_t*)filename.utf16(), 0, SND_FILENAME | SND_SYNC); + + if (guarded_sound) + server->decLoop(guarded_sound); + } + server->current = 0; } ReleaseMutex(mutex); @@ -169,7 +155,7 @@ DWORD WINAPI SoundPlayProc(LPVOID param) void QAuServerWindows::playHelper(const QString &filename, int loop, QSound *snd) { if (loop == 0) - return; + return; // busy? if (WaitForSingleObject(mutex, 0) == WAIT_TIMEOUT) return; diff --git a/src/gui/kernel/qwhatsthis.cpp b/src/gui/kernel/qwhatsthis.cpp index 067c783..f38b0f6 100644 --- a/src/gui/kernel/qwhatsthis.cpp +++ b/src/gui/kernel/qwhatsthis.cpp @@ -226,7 +226,9 @@ QWhatsThat::QWhatsThat(const QString& txt, QWidget* parent, QWidget *showTextFor text); } #if defined(Q_WS_WIN) - if ((QSysInfo::WindowsVersion&QSysInfo::WV_NT_based) > QSysInfo::WV_2000) { + if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP + && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) + { BOOL shadow; SystemParametersInfo(SPI_GETDROPSHADOW, 0, &shadow, 0); shadowWidth = shadow ? 0 : 6; @@ -302,7 +304,9 @@ void QWhatsThat::paintEvent(QPaintEvent*) { bool drawShadow = true; #if defined(Q_WS_WIN) - if ((QSysInfo::WindowsVersion&QSysInfo::WV_NT_based) > QSysInfo::WV_2000) { + if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP + && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) + { BOOL shadow; SystemParametersInfo(SPI_GETDROPSHADOW, 0, &shadow, 0); drawShadow = !shadow; diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 304d72a..1b31318 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -863,8 +863,8 @@ void QWidget::setAutoFillBackground(bool enabled) \list \o X11: This feature relies on the use of an X server that supports ARGB visuals and a compositing window manager. - \o Windows: This feature requires Windows 2000 or later. The widget needs to have - the Qt::FramelessWindowHint window flag set for the translucency to work. + \o Windows: The widget needs to have the Qt::FramelessWindowHint window flag set + for the translucency to work. \endlist @@ -9964,8 +9964,8 @@ bool QWidget::testAttribute_helper(Qt::WidgetAttribute attribute) const By default the value of this property is 1.0. - This feature is available on Embedded Linux, Mac OS X, X11 platforms that - support the Composite extension, and Windows 2000 and later. + This feature is available on Embedded Linux, Mac OS X, Windows, + and X11 platforms that support the Composite extension. This feature is not available on Windows CE. diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp index e39ca77..dcf541c 100644 --- a/src/gui/kernel/qwidget_win.cpp +++ b/src/gui/kernel/qwidget_win.cpp @@ -140,14 +140,8 @@ static void init_wintab_functions() if (!qt_is_gui_used) return; QLibrary library(QLatin1String("wintab32")); - QT_WA({ - ptrWTOpen = (PtrWTOpen)library.resolve("WTOpenW"); - ptrWTInfo = (PtrWTInfo)library.resolve("WTInfoW"); - } , { - ptrWTOpen = (PtrWTOpen)library.resolve("WTOpenA"); - ptrWTInfo = (PtrWTInfo)library.resolve("WTInfoA"); - }); - + ptrWTOpen = (PtrWTOpen)library.resolve("WTOpenW"); + ptrWTInfo = (PtrWTInfo)library.resolve("WTInfoW"); ptrWTClose = (PtrWTClose)library.resolve("WTClose"); ptrWTQueueSizeGet = (PtrWTQueueSizeGet)library.resolve("WTQueueSizeGet"); ptrWTQueueSizeSet = (PtrWTQueueSizeSet)library.resolve("WTQueueSizeSet"); @@ -287,25 +281,18 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO if (desktop && !q->testAttribute(Qt::WA_DontShowOnScreen)) { // desktop widget popup = false; // force this flags off - if (QSysInfo::WindowsVersion != QSysInfo::WV_NT && QSysInfo::WindowsVersion != QSysInfo::WV_95) - data.crect.setRect(GetSystemMetrics(76 /* SM_XVIRTUALSCREEN */), GetSystemMetrics(77 /* SM_YVIRTUALSCREEN */), + data.crect.setRect(GetSystemMetrics(76 /* SM_XVIRTUALSCREEN */), GetSystemMetrics(77 /* SM_YVIRTUALSCREEN */), GetSystemMetrics(78 /* SM_CXVIRTUALSCREEN */), GetSystemMetrics(79 /* SM_CYVIRTUALSCREEN */)); - else - data.crect.setRect(0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); } parentw = q->parentWidget() ? q->parentWidget()->effectiveWinId() : 0; -#ifdef UNICODE QString title; - const TCHAR *ttitle = 0; -#endif - QByteArray title95; int style = WS_CHILD; int exsty = 0; if (window) { - style = GetWindowLongA(window, GWL_STYLE); + style = GetWindowLong(window, GWL_STYLE); if (!style) qErrnoWarning("QWidget::create: GetWindowLong failed"); topLevel = false; // #### needed for some IE plugins?? @@ -361,12 +348,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO } if (flags & Qt::WindowTitleHint) { - QT_WA({ - title = q->isWindow() ? qAppName() : q->objectName(); - ttitle = (TCHAR*)title.utf16(); - } , { - title95 = q->isWindow() ? qAppName().toLocal8Bit() : q->objectName().toLatin1(); - }); + title = q->isWindow() ? qAppName() : q->objectName(); } // The Qt::WA_WState_Created flag is checked by translateConfigEvent() in @@ -379,13 +361,13 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO destroyw = data.winid; id = window; setWinId(window); - LONG res = SetWindowLongA(window, GWL_STYLE, style); + LONG res = SetWindowLong(window, GWL_STYLE, style); if (!res) qErrnoWarning("QWidget::create: Failed to set window style"); #ifdef _WIN64 - res = SetWindowLongPtrA( window, GWLP_WNDPROC, (LONG_PTR)QtWndProc ); + res = SetWindowLongPtr( window, GWLP_WNDPROC, (LONG_PTR)QtWndProc ); #else - res = SetWindowLongA( window, GWL_WNDPROC, (LONG)QtWndProc ); + res = SetWindowLong( window, GWL_WNDPROC, (LONG)QtWndProc ); #endif if (!res) qErrnoWarning("QWidget::create: Failed to set window procedure"); @@ -436,16 +418,10 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO } } - QT_WA({ - const TCHAR *cname = (TCHAR*)windowClassName.utf16(); - id = CreateWindowEx(exsty, cname, ttitle, style, - x, y, w, h, - parentw, 0, appinst, 0); - } , { - id = CreateWindowExA(exsty, windowClassName.toLatin1(), title95, style, - x, y, w, h, - parentw, 0, appinst, 0); - }); + id = CreateWindowEx(exsty, reinterpret_cast(windowClassName.utf16()), + reinterpret_cast(title.utf16()), style, + x, y, w, h, + parentw, NULL, appinst, NULL); if (!id) qErrnoWarning("QWidget::create: Failed to create window"); setWinId(id); @@ -457,16 +433,10 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO SetWindowPos(id, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); winUpdateIsOpaque(); } else if (q->testAttribute(Qt::WA_NativeWindow) || paintOnScreen()) { // create child widget - QT_WA({ - const TCHAR *cname = (TCHAR*)windowClassName.utf16(); - id = CreateWindowEx(exsty, cname, ttitle, style, - data.crect.left(), data.crect.top(), data.crect.width(), data.crect.height(), - parentw, NULL, appinst, NULL); - } , { - id = CreateWindowExA(exsty, windowClassName.toLatin1(), title95, style, - data.crect.left(), data.crect.top(), data.crect.width(), data.crect.height(), + id = CreateWindowEx(exsty, reinterpret_cast(windowClassName.utf16()), + reinterpret_cast(title.utf16()), style, + data.crect.left(), data.crect.top(), data.crect.width(), data.crect.height(), parentw, NULL, appinst, NULL); - }); if (!id) qErrnoWarning("QWidget::create: Failed to create window"); SetWindowPos(id, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); @@ -682,7 +652,7 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f) // Show borderless toplevel windows in tasklist & NavBar if (!parent) { QString txt = q->windowTitle().isEmpty()?qAppName():q->windowTitle(); - SetWindowText(q->internalWinId(), (TCHAR*)txt.utf16()); + SetWindowText(q->internalWinId(), (wchar_t*)txt.utf16()); } #endif invalidateBuffer(q->rect()); @@ -767,11 +737,7 @@ void QWidgetPrivate::setWindowTitle_sys(const QString &caption) return; Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); - QT_WA({ - SetWindowText(q->internalWinId(), (TCHAR*)caption.utf16()); - } , { - SetWindowTextA(q->internalWinId(), caption.toLocal8Bit()); - }); + SetWindowText(q->internalWinId(), (wchar_t*)caption.utf16()); } /* @@ -853,11 +819,11 @@ void QWidgetPrivate::setWindowIcon_sys(bool forceReset) GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), &(x->iconPixmap)); if (x->winIconBig) { - SendMessageA(q->internalWinId(), WM_SETICON, 0 /* ICON_SMALL */, (LPARAM)x->winIconSmall); - SendMessageA(q->internalWinId(), WM_SETICON, 1 /* ICON_BIG */, (LPARAM)x->winIconBig); + SendMessage(q->internalWinId(), WM_SETICON, 0 /* ICON_SMALL */, (LPARAM)x->winIconSmall); + SendMessage(q->internalWinId(), WM_SETICON, 1 /* ICON_BIG */, (LPARAM)x->winIconBig); } else { - SendMessageA(q->internalWinId(), WM_SETICON, 0 /* ICON_SMALL */, (LPARAM)x->winIconSmall); - SendMessageA(q->internalWinId(), WM_SETICON, 1 /* ICON_BIG */, (LPARAM)x->winIconSmall); + SendMessage(q->internalWinId(), WM_SETICON, 0 /* ICON_SMALL */, (LPARAM)x->winIconSmall); + SendMessage(q->internalWinId(), WM_SETICON, 1 /* ICON_BIG */, (LPARAM)x->winIconSmall); } } @@ -884,7 +850,7 @@ LRESULT CALLBACK qJournalRecordProc(int nCode, WPARAM wParam, LPARAM lParam) /* Works only as long as pointer is inside the application's window, which is good enough for QDockWidget. - Doesn't call SetWindowsHookExA() - this function causes a system-wide + Doesn't call SetWindowsHookEx() - this function causes a system-wide freeze if any other app on the system installs a hook and fails to process events. */ void QWidgetPrivate::grabMouseWhileInWindow() @@ -908,7 +874,7 @@ void QWidget::grabMouse() if (!qt_nograb()) { if (mouseGrb) mouseGrb->releaseMouse(); - journalRec = SetWindowsHookExA(WH_JOURNALRECORD, (HOOKPROC)qJournalRecordProc, GetModuleHandleA(0), 0); + journalRec = SetWindowsHookEx(WH_JOURNALRECORD, (HOOKPROC)qJournalRecordProc, GetModuleHandle(0), 0); Q_ASSERT(testAttribute(Qt::WA_WState_Created)); SetCapture(effectiveWinId()); mouseGrb = this; @@ -921,7 +887,7 @@ void QWidget::grabMouse(const QCursor &cursor) if (!qt_nograb()) { if (mouseGrb) mouseGrb->releaseMouse(); - journalRec = SetWindowsHookExA(WH_JOURNALRECORD, (HOOKPROC)qJournalRecordProc, GetModuleHandleA(0), 0); + journalRec = SetWindowsHookEx(WH_JOURNALRECORD, (HOOKPROC)qJournalRecordProc, GetModuleHandle(0), 0); Q_ASSERT(testAttribute(Qt::WA_WState_Created)); SetCapture(effectiveWinId()); mouseGrbCur = new QCursor(cursor); @@ -1028,7 +994,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate) if (newstate & Qt::WindowFullScreen) { if (d->topData()->normalGeometry.width() < 0 && !(oldstate & Qt::WindowMaximized)) d->topData()->normalGeometry = geometry(); - d->topData()->savedFlags = Qt::WindowFlags(GetWindowLongA(internalWinId(), GWL_STYLE)); + d->topData()->savedFlags = Qt::WindowFlags(GetWindowLong(internalWinId(), GWL_STYLE)); #ifndef Q_FLATTEN_EXPOSE UINT style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP; #else @@ -1038,7 +1004,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate) style |= WS_SYSMENU; if (isVisible()) style |= WS_VISIBLE; - SetWindowLongA(internalWinId(), GWL_STYLE, style); + SetWindowLong(internalWinId(), GWL_STYLE, style); QRect r = QApplication::desktop()->screenGeometry(this); UINT swpf = SWP_FRAMECHANGED; if (newstate & Qt::WindowActive) @@ -1050,7 +1016,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate) UINT style = d->topData()->savedFlags; if (isVisible()) style |= WS_VISIBLE; - SetWindowLongA(internalWinId(), GWL_STYLE, style); + SetWindowLong(internalWinId(), GWL_STYLE, style); UINT swpf = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE; if (newstate & Qt::WindowActive) @@ -1395,7 +1361,7 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) UINT style = top->savedFlags; if (q->isVisible()) style |= WS_VISIBLE; - SetWindowLongA(q->internalWinId(), GWL_STYLE, style); + SetWindowLong(q->internalWinId(), GWL_STYLE, style); UINT swpf = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE; if (data.window_state & Qt::WindowActive) @@ -1410,7 +1376,7 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData(); const bool inTopLevelResize = tlwExtra ? tlwExtra->inTopLevelResize : false; const bool isTranslucentWindow = !isOpaque && ptrUpdateLayeredWindowIndirect && (data.window_flags & Qt::FramelessWindowHint) - && GetWindowLongA(q->internalWinId(), GWL_EXSTYLE) & Q_WS_EX_LAYERED; + && GetWindowLong(q->internalWinId(), GWL_EXSTYLE) & Q_WS_EX_LAYERED; if (q->testAttribute(Qt::WA_WState_ConfigPending)) { // processing config event if (q->internalWinId()) @@ -1578,11 +1544,11 @@ void QWidgetPrivate::winUpdateIsOpaque() return; if (!isOpaque && ptrUpdateLayeredWindowIndirect) { - SetWindowLongA(q->internalWinId(), GWL_EXSTYLE, - GetWindowLongA(q->internalWinId(), GWL_EXSTYLE) | Q_WS_EX_LAYERED); + SetWindowLong(q->internalWinId(), GWL_EXSTYLE, + GetWindowLong(q->internalWinId(), GWL_EXSTYLE) | Q_WS_EX_LAYERED); } else { - SetWindowLongA(q->internalWinId(), GWL_EXSTYLE, - GetWindowLongA(q->internalWinId(), GWL_EXSTYLE) & ~Q_WS_EX_LAYERED); + SetWindowLong(q->internalWinId(), GWL_EXSTYLE, + GetWindowLong(q->internalWinId(), GWL_EXSTYLE) & ~Q_WS_EX_LAYERED); } #endif } @@ -1592,12 +1558,12 @@ void QWidgetPrivate::setConstraints_sys() #ifndef Q_WS_WINCE_WM Q_Q(QWidget); if (q->isWindow() && q->testAttribute(Qt::WA_WState_Created)) { - int style = GetWindowLongA(q->internalWinId(), GWL_STYLE); + int style = GetWindowLong(q->internalWinId(), GWL_STYLE); if (shouldShowMaximizeButton()) style |= WS_MAXIMIZEBOX; else style &= ~WS_MAXIMIZEBOX; - SetWindowLongA(q->internalWinId(), GWL_STYLE, style); + SetWindowLong(q->internalWinId(), GWL_STYLE, style); } #endif } @@ -1867,10 +1833,8 @@ void QWidgetPrivate::updateFrameStrut() RECT rect = {0,0,0,0}; QTLWExtra *top = topData(); - uint exstyle = QT_WA_INLINE(GetWindowLongW(q->internalWinId(), GWL_EXSTYLE), - GetWindowLongA(q->internalWinId(), GWL_EXSTYLE)); - uint style = QT_WA_INLINE(GetWindowLongW(q->internalWinId(), GWL_STYLE), - GetWindowLongA(q->internalWinId(), GWL_STYLE)); + uint exstyle = GetWindowLong(q->internalWinId(), GWL_EXSTYLE); + uint style = GetWindowLong(q->internalWinId(), GWL_STYLE); #ifndef Q_WS_WINCE if (AdjustWindowRectEx(&rect, style & ~(WS_OVERLAPPED), FALSE, exstyle)) { #else @@ -1886,11 +1850,10 @@ void QWidgetPrivate::setWindowOpacity_sys(qreal level) { Q_Q(QWidget); - if (!isOpaque && ptrUpdateLayeredWindowIndirect && (data.window_flags & Qt::FramelessWindowHint)) { - if (GetWindowLongA(q->internalWinId(), GWL_EXSTYLE) & Q_WS_EX_LAYERED) { - Q_BLENDFUNCTION blend = {AC_SRC_OVER, 0, (int)(255.0 * level), Q_AC_SRC_ALPHA}; - Q_UPDATELAYEREDWINDOWINFO info = {sizeof(info), NULL, NULL, NULL, NULL, NULL, 0, &blend, Q_ULW_ALPHA, NULL}; - (*ptrUpdateLayeredWindowIndirect)(q->internalWinId(), &info); + if (!isOpaque && ptrUpdateLayeredWindow && (data.window_flags & Qt::FramelessWindowHint)) { + if (GetWindowLong(q->internalWinId(), GWL_EXSTYLE) & Q_WS_EX_LAYERED) { + BLENDFUNCTION blend = {AC_SRC_OVER, 0, (int)(255.0 * level), AC_SRC_ALPHA}; + ptrUpdateLayeredWindow(q->internalWinId(), NULL, NULL, NULL, NULL, NULL, 0, &blend, Q_ULW_ALPHA); } return; } @@ -1906,15 +1869,15 @@ void QWidgetPrivate::setWindowOpacity_sys(qreal level) if (!ptrSetLayeredWindowAttributes) return; - int wl = GetWindowLongA(q->internalWinId(), GWL_EXSTYLE); + int wl = GetWindowLong(q->internalWinId(), GWL_EXSTYLE); if (level != 1.0) { if ((wl&Q_WS_EX_LAYERED) == 0) - SetWindowLongA(q->internalWinId(), GWL_EXSTYLE, wl|Q_WS_EX_LAYERED); + SetWindowLong(q->internalWinId(), GWL_EXSTYLE, wl | Q_WS_EX_LAYERED); } else if (wl&Q_WS_EX_LAYERED) { - SetWindowLongA(q->internalWinId(), GWL_EXSTYLE, wl & ~Q_WS_EX_LAYERED); + SetWindowLong(q->internalWinId(), GWL_EXSTYLE, wl & ~Q_WS_EX_LAYERED); } - (*ptrSetLayeredWindowAttributes)(q->internalWinId(), 0, (int)(level * 255), Q_LWA_ALPHA); + ptrSetLayeredWindowAttributes(q->internalWinId(), 0, (int)(level * 255), Q_LWA_ALPHA); } #endif //Q_WS_WINCE diff --git a/src/gui/kernel/qwidget_wince.cpp b/src/gui/kernel/qwidget_wince.cpp index 24d8156..b0eaa12 100644 --- a/src/gui/kernel/qwidget_wince.cpp +++ b/src/gui/kernel/qwidget_wince.cpp @@ -188,11 +188,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO parentw = q->parentWidget() ? q->parentWidget()->effectiveWinId() : 0; -#ifdef UNICODE QString title; - const TCHAR *ttitle = 0; -#endif - QByteArray title95; int style = WS_CHILD; int exsty = WS_EX_NOPARENTNOTIFY; @@ -236,12 +232,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO } if (flags & Qt::WindowTitleHint) { - QT_WA({ - title = q->isWindow() ? qAppName() : q->objectName(); - ttitle = (TCHAR*)title.utf16(); - } , { - title95 = q->isWindow() ? qAppName().toLocal8Bit() : q->objectName().toLatin1(); - }); + title = q->isWindow() ? qAppName() : q->objectName(); } // The Qt::WA_WState_Created flag is checked by translateConfigEvent() in @@ -254,11 +245,11 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO destroyw = data.winid; id = window; setWinId(window); - LONG res = SetWindowLongA(window, GWL_STYLE, style); + LONG res = SetWindowLong(window, GWL_STYLE, style); if (!res) qErrnoWarning("QWidget::create: Failed to set window style"); - res = SetWindowLongA( window, GWL_WNDPROC, (LONG)QtWndProc ); + res = SetWindowLong( window, GWL_WNDPROC, (LONG)QtWndProc ); if (!res) qErrnoWarning("QWidget::create: Failed to set window procedure"); @@ -267,10 +258,10 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO if (!id) { //Create a dummy desktop RECT r; SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); - const TCHAR *cname = reinterpret_cast (windowClassName.utf16()); - id = CreateWindow(cname, ttitle, style, - r.left, r.top, r.right - r.left, r.bottom - r.top, - 0, 0, appinst, 0); + id = CreateWindow(reinterpret_cast(windowClassName.utf16()), + reinterpret_cast(title.utf16()), style, + r.left, r.top, r.right - r.left, r.bottom - r.top, + 0, 0, appinst, 0); } setWinId(id); } else if (topLevel) { // create top-level widget @@ -303,8 +294,8 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO } } - const TCHAR *cname = reinterpret_cast (windowClassName.utf16()); - id = CreateWindowEx(exsty, cname, ttitle, style, + id = CreateWindowEx(exsty, reinterpret_cast(windowClassName.utf16()), + reinterpret_cast(title.utf16()), style, x, y, w, h, 0, 0, appinst, 0); @@ -314,16 +305,9 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO if ((flags & Qt::WindowStaysOnTopHint) || (type == Qt::ToolTip)) SetWindowPos(id, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); } else if (q->testAttribute(Qt::WA_NativeWindow) || paintOnScreen()) { // create child widget - QT_WA({ - const TCHAR *cname = (TCHAR*)windowClassName.utf16(); - id = CreateWindowEx(exsty, cname, ttitle, style, - data.crect.left(), data.crect.top(), data.crect.width(), data.crect.height(), - parentw, NULL, appinst, NULL); - } , { - id = CreateWindowExA(exsty, windowClassName.toLatin1(), title95, style, - data.crect.left(), data.crect.top(), data.crect.width(), data.crect.height(), + id = CreateWindowEx(exsty, (wchar_t*)windowClassName.utf16(), (wchar_t*)title.utf16(), style, + data.crect.left(), data.crect.top(), data.crect.width(), data.crect.height(), parentw, NULL, appinst, NULL); - }); if (!id) qErrnoWarning("QWidget::create: Failed to create window"); SetWindowPos(id, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); @@ -510,7 +494,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate) } if ((oldstate & Qt::WindowMaximized) != (newstate & Qt::WindowMaximized)) { if (!(newstate & Qt::WindowMaximized)) { - int style = GetWindowLongW(internalWinId(), GWL_STYLE) | WS_BORDER | WS_POPUP | WS_CAPTION; + int style = GetWindowLong(internalWinId(), GWL_STYLE) | WS_BORDER | WS_POPUP | WS_CAPTION; SetWindowLong(internalWinId(), GWL_STYLE, style); SetWindowLong(internalWinId(), GWL_EXSTYLE, GetWindowLong (internalWinId(), GWL_EXSTYLE) & ~ WS_EX_NODRAG); } @@ -535,11 +519,11 @@ void QWidget::setWindowState(Qt::WindowStates newstate) if (newstate & Qt::WindowFullScreen) { if (d->topData()->normalGeometry.width() < 0 && !(oldstate & Qt::WindowMaximized)) d->topData()->normalGeometry = geometry(); - d->topData()->savedFlags = (Qt::WindowFlags) GetWindowLongA(internalWinId(), GWL_STYLE); + d->topData()->savedFlags = (Qt::WindowFlags)GetWindowLong(internalWinId(), GWL_STYLE); UINT style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP; if (isVisible()) style |= WS_VISIBLE; - SetWindowLongA(internalWinId(), GWL_STYLE, style); + SetWindowLong(internalWinId(), GWL_STYLE, style); QRect r = qApp->desktop()->screenGeometry(this); UINT swpf = SWP_FRAMECHANGED; if (newstate & Qt::WindowActive) @@ -550,7 +534,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate) UINT style = d->topData()->savedFlags; if (isVisible()) style |= WS_VISIBLE; - SetWindowLongA(internalWinId(), GWL_STYLE, style); + SetWindowLong(internalWinId(), GWL_STYLE, style); UINT swpf = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE; if (newstate & Qt::WindowActive) swpf |= SWP_NOACTIVATE; diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index 664751a..a6ecd4e 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -1923,7 +1923,7 @@ void QPdfBaseEnginePrivate::drawTextItem(const QPointF &p, const QTextItemInt &t #ifdef Q_WS_WIN if (ti.fontEngine->type() == QFontEngine::Win) { QFontEngineWin *fe = static_cast(ti.fontEngine); - size = fe->tm.w.tmHeight; + size = fe->tm.tmHeight; } #endif diff --git a/src/gui/painting/qprintengine_pdf.cpp b/src/gui/painting/qprintengine_pdf.cpp index c1edcb3..b267860 100644 --- a/src/gui/painting/qprintengine_pdf.cpp +++ b/src/gui/painting/qprintengine_pdf.cpp @@ -655,7 +655,7 @@ void QPdfEnginePrivate::drawTextItem(const QPointF &p, const QTextItemInt &ti) #ifdef Q_WS_WIN if (ti.fontEngine->type() == QFontEngine::Win) { QFontEngineWin *fe = static_cast(ti.fontEngine); - size = fe->tm.w.tmHeight; + size = fe->tm.tmHeight; } #endif int synthesized = ti.fontEngine->synthesized(); diff --git a/src/gui/painting/qprintengine_win.cpp b/src/gui/painting/qprintengine_win.cpp index f36028f..7b99e2f 100644 --- a/src/gui/painting/qprintengine_win.cpp +++ b/src/gui/painting/qprintengine_win.cpp @@ -199,33 +199,18 @@ bool QWin32PrintEngine::begin(QPaintDevice *pdev) if (d->printToFile && d->fileName.isEmpty()) d->fileName = d->port; - QT_WA({ - d->devModeW()->dmCopies = d->num_copies; - DOCINFO di; - memset(&di, 0, sizeof(DOCINFO)); - di.cbSize = sizeof(DOCINFO); - di.lpszDocName = reinterpret_cast(d->docName.utf16()); - if (d->printToFile && !d->fileName.isEmpty()) - di.lpszOutput = reinterpret_cast(d->fileName.utf16()); - if (ok && StartDoc(d->hdc, &di) == SP_ERROR) { - qErrnoWarning("QWin32PrintEngine::begin: StartDoc failed"); - ok = false; - } - } , { - d->devModeA()->dmCopies = d->num_copies; - DOCINFOA di; - memset(&di, 0, sizeof(DOCINFOA)); - di.cbSize = sizeof(DOCINFOA); - QByteArray docNameA = d->docName.toLocal8Bit(); - di.lpszDocName = docNameA.data(); - QByteArray outfileA = d->fileName.toLocal8Bit(); - if (d->printToFile && !d->fileName.isEmpty()) - di.lpszOutput = outfileA; - if (ok && StartDocA(d->hdc, &di) == SP_ERROR) { - qErrnoWarning("QWin32PrintEngine::begin: StartDoc failed"); - ok = false; - } - }); + d->devMode->dmCopies = d->num_copies; + + DOCINFO di; + memset(&di, 0, sizeof(DOCINFO)); + di.cbSize = sizeof(DOCINFO); + di.lpszDocName = reinterpret_cast(d->docName.utf16()); + if (d->printToFile && !d->fileName.isEmpty()) + di.lpszOutput = reinterpret_cast(d->fileName.utf16()); + if (ok && StartDoc(d->hdc, &di) == SP_ERROR) { + qErrnoWarning("QWin32PrintEngine::begin: StartDoc failed"); + ok = false; + } if (StartPage(d->hdc) <= 0) { qErrnoWarning("QWin32PrintEngine::begin: StartPage failed"); @@ -317,11 +302,6 @@ bool QWin32PrintEngine::newPage() bool success = false; if (d->hdc && d->state == QPrinter::Active) { -// bool restorePainter = false; -// if ((qWinVersion()& Qt::WV_DOS_based) && painter && painter->isActive()) { -// painter->save(); // EndPage/StartPage ruins the DC -// restorePainter = true; -// } if (EndPage(d->hdc) != SP_ERROR) { // reinitialize the DC before StartPage if needed, // because resetdc is disabled between calls to the StartPage and EndPage functions @@ -337,16 +317,10 @@ bool QWin32PrintEngine::newPage() } success = (StartPage(d->hdc) != SP_ERROR); } - if (!success) + if (!success) { d->state = QPrinter::Aborted; - -// if (qWinVersion() & Qt::WV_DOS_based) -// if (restorePainter) { -// painter->restore(); -// } - - if (!success) return false; + } } return true; } @@ -369,7 +343,7 @@ void QWin32PrintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem QRgb brushColor = state->pen().brush().color().rgb(); bool fallBack = state->pen().brush().style() != Qt::SolidPattern || qAlpha(brushColor) != 0xff - || QT_WA_INLINE(d->txop >= QTransform::TxProject, d->txop >= QTransform::TxScale) + || d->txop >= QTransform::TxProject || ti.fontEngine->type() != QFontEngine::Win; @@ -380,17 +354,10 @@ void QWin32PrintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem SelectObject(d->hdc, fe->hfont); if (GetDeviceCaps(d->hdc, TECHNOLOGY) != DT_CHARSTREAM) { - QT_WA({ - TCHAR n[64]; - GetTextFaceW(d->hdc, 64, n); - fallBack = QString::fromUtf16((ushort *)n) - != QString::fromUtf16((ushort *)fe->logfont.lfFaceName); - } , { - char an[64]; - GetTextFaceA(d->hdc, 64, an); - fallBack = QString::fromLocal8Bit(an) - != QString::fromLocal8Bit(((LOGFONTA*)(&fe->logfont))->lfFaceName); - }); + wchar_t n[64]; + GetTextFace(d->hdc, 64, n); + fallBack = QString::fromWCharArray(n) + != QString::fromWCharArray(fe->logfont.lfFaceName); } } @@ -983,22 +950,14 @@ void QWin32PrintEnginePrivate::queryDefault() * Strings "windows" and "device" are specified in the MSDN under EnumPrinters() */ QString noPrinters(QLatin1String("qt_no_printers")); - QString output; - QT_WA({ - ushort buffer[256]; - GetProfileStringW(L"windows", L"device", - reinterpret_cast(noPrinters.utf16()), - reinterpret_cast(buffer), 256); - output = QString::fromUtf16(buffer); - if (output.isEmpty() || output == noPrinters) // no printers - return; - }, { - char buffer[256]; - GetProfileStringA("windows", "device", noPrinters.toLatin1(), buffer, 256); - output = QString::fromLocal8Bit(buffer); - if (output.isEmpty() || output == noPrinters) // no printers - return; - }); + wchar_t buffer[256]; + GetProfileString(L"windows", L"device", + reinterpret_cast(noPrinters.utf16()), + buffer, 256); + QString output = QString::fromWCharArray(buffer); + if (output.isEmpty() || output == noPrinters) // no printers + return; + QStringList info = output.split(QLatin1Char(',')); if (info.size() > 0) { if (name.isEmpty()) @@ -1030,13 +989,7 @@ void QWin32PrintEnginePrivate::initialize() txop = QTransform::TxNone; - bool ok; - QT_WA( { - ok = OpenPrinterW((LPWSTR)name.utf16(), (LPHANDLE)&hPrinter, 0); - }, { - ok = OpenPrinterA((LPSTR)name.toLatin1().data(), (LPHANDLE)&hPrinter, 0); - } ); - + bool ok = OpenPrinter((LPWSTR)name.utf16(), (LPHANDLE)&hPrinter, 0); if (!ok) { qErrnoWarning("QWin32PrintEngine::initialize: OpenPrinter failed"); return; @@ -1045,22 +998,10 @@ void QWin32PrintEnginePrivate::initialize() // Fetch the PRINTER_INFO_2 with DEVMODE data containing the // printer settings. DWORD infoSize, numBytes; - ok = true; - QT_WA( { - GetPrinterW(hPrinter, 2, NULL, 0, &infoSize); - hMem = GlobalAlloc(GHND, infoSize); - pInfo = GlobalLock(hMem); - if (!GetPrinterW(hPrinter, 2, (LPBYTE)pInfo, infoSize, &numBytes)) { - ok = false; - } - }, { - GetPrinterA(hPrinter, 2, NULL, 0, &infoSize); - hMem = GlobalAlloc(GHND, infoSize); - pInfo = GlobalLock(hMem); - if (!GetPrinterA(hPrinter, 2, (LPBYTE)pInfo, infoSize, &numBytes)) { - ok = false; - } - }); + GetPrinter(hPrinter, 2, NULL, 0, &infoSize); + hMem = GlobalAlloc(GHND, infoSize); + pInfo = (PRINTER_INFO_2*) GlobalLock(hMem); + ok = GetPrinter(hPrinter, 2, (LPBYTE)pInfo, infoSize, &numBytes); if (!ok) { qErrnoWarning("QWin32PrintEngine::initialize: GetPrinter failed"); @@ -1073,28 +1014,15 @@ void QWin32PrintEnginePrivate::initialize() return; } - QT_WA( { - devMode = pInfoW()->pDevMode; - }, { - devMode = pInfoA()->pDevMode; - } ); - - QT_WA( { - hdc = CreateDC(reinterpret_cast(program.utf16()), - reinterpret_cast(name.utf16()), 0, devModeW()); - }, { - hdc = CreateDCA(program.toLatin1(), name.toLatin1(), 0, devModeA()); - } ); + devMode = pInfo->pDevMode; + hdc = CreateDC(reinterpret_cast(program.utf16()), + reinterpret_cast(name.utf16()), 0, devMode); Q_ASSERT(hPrinter); Q_ASSERT(pInfo); if (devMode) { - QT_WA( { - num_copies = devModeW()->dmCopies; - }, { - num_copies = devModeA()->dmCopies; - } ); + num_copies = devMode->dmCopies; } initHDC(); @@ -1212,28 +1140,18 @@ void QWin32PrintEnginePrivate::release() QList QWin32PrintEnginePrivate::queryResolutions() const { // Read the supported resolutions of the printer. - DWORD numRes; - LONG *enumRes; - DWORD errRes; QList list; - QT_WA({ - numRes = DeviceCapabilities(reinterpret_cast(name.utf16()), - reinterpret_cast(port.utf16()), - DC_ENUMRESOLUTIONS, 0, 0); - if (numRes == (DWORD)-1) - return list; - enumRes = (LONG*)malloc(numRes * 2 * sizeof(LONG)); - errRes = DeviceCapabilities(reinterpret_cast(name.utf16()), - reinterpret_cast(port.utf16()), - DC_ENUMRESOLUTIONS, (LPWSTR)enumRes, 0); - }, { - numRes = DeviceCapabilitiesA(name.toLocal8Bit(), port.toLocal8Bit(), DC_ENUMRESOLUTIONS, 0, 0); - if (numRes == (DWORD)-1) - return list; - enumRes = (LONG*)malloc(numRes * 2 * sizeof(LONG)); - errRes = DeviceCapabilitiesA(name.toLocal8Bit(), port.toLocal8Bit(), DC_ENUMRESOLUTIONS, (LPSTR)enumRes, 0); - }); + DWORD numRes = DeviceCapabilities(reinterpret_cast(name.utf16()), + reinterpret_cast(port.utf16()), + DC_ENUMRESOLUTIONS, 0, 0); + if (numRes == (DWORD)-1) + return list; + + LONG *enumRes = (LONG*)malloc(numRes * 2 * sizeof(LONG)); + DWORD errRes = DeviceCapabilities(reinterpret_cast(name.utf16()), + reinterpret_cast(port.utf16()), + DC_ENUMRESOLUTIONS, (LPWSTR)enumRes, 0); if (errRes == (DWORD)-1) { qErrnoWarning("QWin32PrintEngine::queryResolutions: DeviceCapabilities failed"); @@ -1241,7 +1159,8 @@ QList QWin32PrintEnginePrivate::queryResolutions() const } for (uint i=0; idevMode) break; - short collate = value.toBool() ? DMCOLLATE_TRUE : DMCOLLATE_FALSE; - QT_WA( { d->devModeW()->dmCollate = collate; }, - { d->devModeA()->dmCollate = collate; } ); + d->devMode->dmCollate = value.toBool() ? DMCOLLATE_TRUE : DMCOLLATE_FALSE; d->doReinit(); } break; @@ -1296,8 +1213,7 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & { if (!d->devMode) break; - int cm = value.toInt() == QPrinter::Color ? DMCOLOR_COLOR : DMCOLOR_MONOCHROME; - QT_WA( { d->devModeW()->dmColor = cm; }, { d->devModeA()->dmColor = cm; } ); + d->devMode->dmColor = (value.toInt() == QPrinter::Color) ? DMCOLOR_COLOR : DMCOLOR_MONOCHROME; d->doReinit(); } break; @@ -1323,8 +1239,7 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & if (!d->devMode) break; d->num_copies = value.toInt(); - QT_WA( { d->devModeW()->dmCopies = d->num_copies; }, - { d->devModeA()->dmCopies = d->num_copies; }); + d->devMode->dmCopies = d->num_copies; d->doReinit(); break; @@ -1333,14 +1248,8 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & if (!d->devMode) break; int orientation = value.toInt() == QPrinter::Landscape ? DMORIENT_LANDSCAPE : DMORIENT_PORTRAIT; - int old_orientation; - QT_WA( { - old_orientation = d->devModeW()->dmOrientation; - d->devModeW()->dmOrientation = orientation; - }, { - old_orientation = d->devModeA()->dmOrientation; - d->devModeA()->dmOrientation = orientation; - } ); + int old_orientation = d->devMode->dmOrientation; + d->devMode->dmOrientation = orientation; if (d->has_custom_paper_size && old_orientation != orientation) d->paper_size = QSizeF(d->paper_size.height(), d->paper_size.width()); d->doReinit(); @@ -1359,11 +1268,7 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & case PPK_PaperSize: if (!d->devMode) break; - QT_WA( { - d->devModeW()->dmPaperSize = mapPaperSizeDevmode(QPrinter::PaperSize(value.toInt())); - }, { - d->devModeA()->dmPaperSize = mapPaperSizeDevmode(QPrinter::PaperSize(value.toInt())); - } ); + d->devMode->dmPaperSize = mapPaperSizeDevmode(QPrinter::PaperSize(value.toInt())); d->has_custom_paper_size = (QPrinter::PaperSize(value.toInt()) == QPrinter::Custom); d->doReinit(); break; @@ -1378,11 +1283,7 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & if (v.contains(value)) dmMapped = mapPaperSourceDevmode(QPrinter::PaperSource(value.toInt())); - QT_WA( { - d->devModeW()->dmDefaultSource = dmMapped; - }, { - d->devModeA()->dmDefaultSource = dmMapped; - } ); + d->devMode->dmDefaultSource = dmMapped; d->doReinit(); } break; @@ -1416,11 +1317,7 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & if (!d->devMode) break; d->has_custom_paper_size = false; - QT_WA( { - d->devModeW()->dmPaperSize = value.toInt(); - }, { - d->devModeA()->dmPaperSize = value.toInt(); - } ); + d->devMode->dmPaperSize = value.toInt(); d->doReinit(); break; @@ -1430,33 +1327,28 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & d->paper_size = value.toSizeF(); if (!d->devMode) break; - int orientation; - QT_WA( { - orientation = d->devModeW()->dmOrientation; - DWORD needed = 0; - DWORD returned = 0; - if (!EnumForms(d->hPrinter, 1, 0, 0, &needed, &returned)) { - BYTE *forms = (BYTE *) malloc(needed); - if (EnumForms(d->hPrinter, 1, forms, needed, &needed, &returned)) { - for (DWORD i=0; i< returned; ++i) { - FORM_INFO_1 *formArray = reinterpret_cast(forms); - // the form sizes are specified in 1000th of a mm, - // convert the size to Points - QSizeF size((formArray[i].Size.cx * 72/25.4)/1000.0, - (formArray[i].Size.cy * 72/25.4)/1000.0); - if (qAbs(d->paper_size.width() - size.width()) <= 2 - && qAbs(d->paper_size.height() - size.height()) <= 2) - { - d->devModeW()->dmPaperSize = i+1; - break; - } + int orientation = d->devMode->dmOrientation; + DWORD needed = 0; + DWORD returned = 0; + if (!EnumForms(d->hPrinter, 1, 0, 0, &needed, &returned)) { + BYTE *forms = (BYTE *) malloc(needed); + if (EnumForms(d->hPrinter, 1, forms, needed, &needed, &returned)) { + for (DWORD i=0; i< returned; ++i) { + FORM_INFO_1 *formArray = reinterpret_cast(forms); + // the form sizes are specified in 1000th of a mm, + // convert the size to Points + QSizeF size((formArray[i].Size.cx * 72/25.4)/1000.0, + (formArray[i].Size.cy * 72/25.4)/1000.0); + if (qAbs(d->paper_size.width() - size.width()) <= 2 + && qAbs(d->paper_size.height() - size.height()) <= 2) + { + d->devMode->dmPaperSize = i + 1; + break; } } - free(forms); } - }, { - orientation = d->devModeA()->dmOrientation; - } ); + free(forms); + } if (orientation != DMORIENT_PORTRAIT) d->paper_size = QSizeF(d->paper_size.height(), d->paper_size.width()); break; @@ -1496,13 +1388,7 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const if (!d->devMode) { value = QPrinter::Color; } else { - int mode; - QT_WA( { - mode = d->devModeW()->dmColor; - }, { - mode = d->devModeA()->dmColor; - } ); - value = mode == DMCOLOR_COLOR ? QPrinter::Color : QPrinter::GrayScale; + value = (d->devMode->dmColor == DMCOLOR_COLOR) ? QPrinter::Color : QPrinter::GrayScale; } } break; @@ -1524,9 +1410,7 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const if (!d->devMode) { value = QPrinter::Portrait; } else { - int o; - QT_WA( { o = d->devModeW()->dmOrientation; }, { o = d->devModeA()->dmOrientation; } ); - value = o == DMORIENT_LANDSCAPE ? QPrinter::Landscape : QPrinter::Portrait; + value = (d->devMode->dmOrientation == DMORIENT_LANDSCAPE) ? QPrinter::Landscape : QPrinter::Portrait; } } break; @@ -1560,11 +1444,7 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const if (!d->devMode) { value = QPrinter::A4; } else { - QT_WA( { - value = mapDevmodePaperSize(d->devModeW()->dmPaperSize); - }, { - value = mapDevmodePaperSize(d->devModeA()->dmPaperSize); - } ); + value = mapDevmodePaperSize(d->devMode->dmPaperSize); } } break; @@ -1583,11 +1463,7 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const if (!d->devMode) { value = QPrinter::Auto; } else { - QT_WA( { - value = mapDevmodePaperSource(d->devModeW()->dmDefaultSource); - }, { - value = mapDevmodePaperSource(d->devModeA()->dmDefaultSource); - } ); + value = mapDevmodePaperSource(d->devMode->dmDefaultSource); } break; @@ -1608,38 +1484,21 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const if (!d->devMode) { value = -1; } else { - QT_WA( { - value = d->devModeW()->dmPaperSize; - }, { - value = d->devModeA()->dmPaperSize; - } ); + value = d->devMode->dmPaperSize; } break; case PPK_PaperSources: { - int available, count; - WORD *data; - - QT_WA({ - available = DeviceCapabilitiesW((const WCHAR *)d->name.utf16(), (const WCHAR *)d->port.utf16(), DC_BINS, 0, - d->devModeW()); - }, { - available = DeviceCapabilitiesA(d->name.toLatin1(), d->port.toLatin1(), DC_BINS, 0, - d->devModeA()); - }); + int available = DeviceCapabilities((const wchar_t *)d->name.utf16(), + (const wchar_t *)d->port.utf16(), DC_BINS, 0, d->devMode); if (available <= 0) break; - data = (WORD *) malloc(available * sizeof(WORD)); - QT_WA({ - count = DeviceCapabilitiesW((const WCHAR *)d->name.utf16(), (const WCHAR *)d->port.utf16(), DC_BINS, (WCHAR *)data, - d->devModeW()); - }, { - count = DeviceCapabilitiesA(d->name.toLatin1(), d->port.toLatin1(), DC_BINS, - (char *) data, d->devModeA()); - }); + wchar_t *data = new wchar_t[available]; + int count = DeviceCapabilities((const wchar_t *)d->name.utf16(), + (const wchar_t *)d->port.utf16(), DC_BINS, data, d->devMode); QList out; for (int i=0; iwDriverOffset = sizeof(DEVNAMES) / sizeof(TCHAR); - dn->wDeviceOffset = dn->wDriverOffset + program.length() + 1; - dn->wOutputOffset = dn->wDeviceOffset + name.length() + 1; + dn->wDriverOffset = sizeof(DEVNAMES) / sizeof(wchar_t); + dn->wDeviceOffset = dn->wDriverOffset + program.length() + 1; + dn->wOutputOffset = dn->wDeviceOffset + name.length() + 1; - memcpy((ushort*)dn + dn->wDriverOffset, program.utf16(), program.length() * 2 + 2); - memcpy((ushort*)dn + dn->wDeviceOffset, name.utf16(), name.length() * 2 + 2); - memcpy((ushort*)dn + dn->wOutputOffset, port.utf16(), port.length() * 2 + 2); - dn->wDefault = 0; + memcpy((ushort*)dn + dn->wDriverOffset, program.utf16(), program.length() * 2 + 2); + memcpy((ushort*)dn + dn->wDeviceOffset, name.utf16(), name.length() * 2 + 2); + memcpy((ushort*)dn + dn->wOutputOffset, port.utf16(), port.length() * 2 + 2); + dn->wDefault = 0; - GlobalUnlock(hGlobal); + GlobalUnlock(hGlobal); // printf("QPrintDialogWinPrivate::createDevNames()\n" // " -> wDriverOffset: %d\n" @@ -1721,89 +1580,46 @@ HGLOBAL *QWin32PrintEnginePrivate::createDevNames() // dn->wOutputOffset); // printf("QPrintDialogWinPrivate::createDevNames(): %s, %s, %s\n", -// QString::fromUtf16((ushort*)(dn) + dn->wDriverOffset).latin1(), -// QString::fromUtf16((ushort*)(dn) + dn->wDeviceOffset).latin1(), -// QString::fromUtf16((ushort*)(dn) + dn->wOutputOffset).latin1()); - - return hGlobal; - }, { - int size = sizeof(DEVNAMES) - + program.length() + 2 - + name.length() + 2 - + port.length() + 2; - HGLOBAL *hGlobal = (HGLOBAL *) GlobalAlloc(GMEM_MOVEABLE, size); - DEVNAMES *dn = (DEVNAMES*) GlobalLock(hGlobal); - - dn->wDriverOffset = sizeof(DEVNAMES); - dn->wDeviceOffset = dn->wDriverOffset + program.length() + 1; - dn->wOutputOffset = dn->wDeviceOffset + name.length() + 1; - - memcpy((char*)dn + dn->wDriverOffset, program.toLatin1(), program.length() + 2); - memcpy((char*)dn + dn->wDeviceOffset, name.toLatin1(), name.length() + 2); - memcpy((char*)dn + dn->wOutputOffset, port.toLatin1(), port.length() + 2); - dn->wDefault = 0; - - GlobalUnlock(hGlobal); - return hGlobal; - } ); +// QString::fromWCharArray((wchar_t*)(dn) + dn->wDriverOffset).latin1(), +// QString::fromWCharArray((wchar_t*)(dn) + dn->wDeviceOffset).latin1(), +// QString::fromWCharArray((wchar_t*)(dn) + dn->wOutputOffset).latin1()); + + return hGlobal; } void QWin32PrintEnginePrivate::readDevnames(HGLOBAL globalDevnames) { if (globalDevnames) { - QT_WA( { - DEVNAMES *dn = (DEVNAMES*) GlobalLock(globalDevnames); - name = QString::fromUtf16((ushort*)(dn) + dn->wDeviceOffset); - port = QString::fromUtf16((ushort*)(dn) + dn->wOutputOffset); - program = QString::fromUtf16((ushort*)(dn) + dn->wDriverOffset); - GlobalUnlock(globalDevnames); - }, { - DEVNAMES *dn = (DEVNAMES*) GlobalLock(globalDevnames); - name = QString::fromLatin1((char*)(dn) + dn->wDeviceOffset); - port = QString::fromLatin1((char*)(dn) + dn->wOutputOffset); - program = QString::fromLatin1((char*)(dn) + dn->wDriverOffset); - GlobalUnlock(globalDevnames); - } ); + DEVNAMES *dn = (DEVNAMES*) GlobalLock(globalDevnames); + name = QString::fromWCharArray((wchar_t*)(dn) + dn->wDeviceOffset); + port = QString::fromWCharArray((wchar_t*)(dn) + dn->wOutputOffset); + program = QString::fromWCharArray((wchar_t*)(dn) + dn->wDriverOffset); + GlobalUnlock(globalDevnames); } } void QWin32PrintEnginePrivate::readDevmode(HGLOBAL globalDevmode) { if (globalDevmode) { - QT_WA( { - DEVMODE *dm = (DEVMODE*) GlobalLock(globalDevmode); - release(); - globalDevMode = globalDevmode; - devMode = dm; - hdc = CreateDC(reinterpret_cast(program.utf16()), - reinterpret_cast(name.utf16()), 0, dm); - - num_copies = devModeW()->dmCopies; - if (!OpenPrinterW((LPWSTR)name.utf16(), (LPHANDLE)&hPrinter, 0)) - qWarning("QPrinter: OpenPrinter() failed after reading DEVMODE."); - }, { - DEVMODEA *dm = (DEVMODEA*) GlobalLock(globalDevmode); - release(); - globalDevMode = globalDevmode; - devMode = dm; - hdc = CreateDCA(program.toLatin1(), name.toLatin1(), 0, dm); - - num_copies = devModeA()->dmCopies; - if (!OpenPrinterA((LPSTR)name.toLatin1().data(), (LPHANDLE)&hPrinter, 0)) - qWarning("QPrinter: OpenPrinter() failed after reading DEVMODE."); - } ); + DEVMODE *dm = (DEVMODE*) GlobalLock(globalDevmode); + release(); + globalDevMode = globalDevmode; + devMode = dm; + hdc = CreateDC(reinterpret_cast(program.utf16()), + reinterpret_cast(name.utf16()), 0, dm); + + num_copies = devMode->dmCopies; + if (!OpenPrinter((wchar_t*)name.utf16(), &hPrinter, 0)) + qWarning("QPrinter: OpenPrinter() failed after reading DEVMODE."); } if (hdc) initHDC(); } -static void draw_text_item_win(const QPointF &_pos, const QTextItemInt &ti, HDC hdc, +static void draw_text_item_win(const QPointF &pos, const QTextItemInt &ti, HDC hdc, bool convertToText, const QTransform &xform, const QPointF &topLeft) { - - // Make sure we translate for systems that can't handle world transforms - QPointF pos(QT_WA_INLINE(_pos, _pos + QPointF(xform.dx(), xform.dy()))); QFontEngine *fe = ti.fontEngine; QPointF baseline_pos = xform.inverted().map(xform.map(pos) - topLeft); @@ -1815,12 +1631,10 @@ static void draw_text_item_win(const QPointF &_pos, const QTextItemInt &ti, HDC HFONT hfont; bool ttf = false; - bool useTextOutA = false; if (winfe) { hfont = winfe->hfont; ttf = winfe->ttf; - useTextOutA = winfe->useTextOutA; } else { hfont = (HFONT)GetStockObject(ANSI_VAR_FONT); } @@ -1830,153 +1644,115 @@ static void draw_text_item_win(const QPointF &_pos, const QTextItemInt &ti, HDC wchar_t *convertedGlyphs = (wchar_t *)ti.chars; QGlyphLayout glyphs = ti.glyphs; - if (!(ti.flags & QTextItem::RightToLeft) && useTextOutA) { - qreal x = pos.x(); - qreal y = pos.y(); - - // hack to get symbol fonts working on Win95. See also QFontEngine constructor - // can only happen if !ttf - for(int i = 0; i < glyphs.numGlyphs; i++) { - QString str(QChar(glyphs.glyphs[i])); - QT_WA({ - TextOutW(hdc, qRound(x + glyphs.offsets[i].x.toReal()), - qRound(y + glyphs.offsets[i].y.toReal()), - (LPWSTR)str.utf16(), str.length()); - } , { - QByteArray cstr = str.toLocal8Bit(); - TextOutA(hdc, qRound(x + glyphs.offsets[i].x.toReal()), - qRound(y + glyphs.offsets[i].y.toReal()), - cstr.data(), cstr.length()); - }); - x += glyphs.effectiveAdvance(i).toReal(); - } - } else { - bool fast = !has_kerning && !(ti.flags & QTextItem::RightToLeft); - for(int i = 0; fast && i < glyphs.numGlyphs; i++) { - if (glyphs.offsets[i].x != 0 || glyphs.offsets[i].y != 0 || glyphs.justifications[i].space_18d6 != 0 - || glyphs.attributes[i].dontPrint) { - fast = false; - break; - } + bool fast = !has_kerning && !(ti.flags & QTextItem::RightToLeft); + for (int i = 0; fast && i < glyphs.numGlyphs; i++) { + if (glyphs.offsets[i].x != 0 || glyphs.offsets[i].y != 0 || glyphs.justifications[i].space_18d6 != 0 + || glyphs.attributes[i].dontPrint) { + fast = false; + break; } + } #if !defined(Q_OS_WINCE) - // Scale, rotate and translate here. This is only valid for systems > Windows Me. - // We should never get here on Windows Me or lower if the transformation specifies - // scaling or rotation. - QT_WA({ - XFORM win_xform; - win_xform.eM11 = xform.m11(); - win_xform.eM12 = xform.m12(); - win_xform.eM21 = xform.m21(); - win_xform.eM22 = xform.m22(); - win_xform.eDx = xform.dx(); - win_xform.eDy = xform.dy(); - SetGraphicsMode(hdc, GM_ADVANCED); - SetWorldTransform(hdc, &win_xform); - }, { - // nothing - }); + // Scale, rotate and translate here. + XFORM win_xform; + win_xform.eM11 = xform.m11(); + win_xform.eM12 = xform.m12(); + win_xform.eM21 = xform.m21(); + win_xform.eM22 = xform.m22(); + win_xform.eDx = xform.dx(); + win_xform.eDy = xform.dy(); + + SetGraphicsMode(hdc, GM_ADVANCED); + SetWorldTransform(hdc, &win_xform); #endif - if (fast) { - // fast path - QVarLengthArray g(glyphs.numGlyphs); - for (int i = 0; i < glyphs.numGlyphs; ++i) - g[i] = glyphs.glyphs[i]; - ExtTextOutW(hdc, - qRound(baseline_pos.x() + glyphs.offsets[0].x.toReal()), - qRound(baseline_pos.y() + glyphs.offsets[0].y.toReal()), - options, 0, convertToText ? convertedGlyphs : g.data(), glyphs.numGlyphs, 0); - } else { - QVarLengthArray positions; - QVarLengthArray _glyphs; - - QTransform matrix = QTransform::fromTranslate(baseline_pos.x(), baseline_pos.y()); - ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, - _glyphs, positions); - if (_glyphs.size() == 0) { - SelectObject(hdc, old_font); - return; - } - - convertToText = convertToText && glyphs.numGlyphs == _glyphs.size(); - - bool outputEntireItem = (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based) - && QSysInfo::WindowsVersion != QSysInfo::WV_NT - && _glyphs.size() > 0; + if (fast) { + // fast path + QVarLengthArray g(glyphs.numGlyphs); + for (int i = 0; i < glyphs.numGlyphs; ++i) + g[i] = glyphs.glyphs[i]; + ExtTextOut(hdc, + qRound(baseline_pos.x() + glyphs.offsets[0].x.toReal()), + qRound(baseline_pos.y() + glyphs.offsets[0].y.toReal()), + options, 0, convertToText ? convertedGlyphs : g.data(), glyphs.numGlyphs, 0); + } else { + QVarLengthArray positions; + QVarLengthArray _glyphs; + + QTransform matrix = QTransform::fromTranslate(baseline_pos.x(), baseline_pos.y()); + ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, + _glyphs, positions); + if (_glyphs.size() == 0) { + SelectObject(hdc, old_font); + return; + } - if (outputEntireItem) { - options |= ETO_PDY; - QVarLengthArray glyphDistances(_glyphs.size() * 2); - QVarLengthArray g(_glyphs.size()); - for (int i=0; i<_glyphs.size() - 1; ++i) { - glyphDistances[i * 2] = qRound(positions[i + 1].x) - qRound(positions[i].x); - glyphDistances[i * 2 + 1] = qRound(positions[i + 1].y) - qRound(positions[i].y); - g[i] = _glyphs[i]; - } - glyphDistances[(_glyphs.size() - 1) * 2] = 0; - glyphDistances[(_glyphs.size() - 1) * 2 + 1] = 0; - g[_glyphs.size() - 1] = _glyphs[_glyphs.size() - 1]; - ExtTextOutW(hdc, qRound(positions[0].x), qRound(positions[0].y), options, 0, - convertToText ? convertedGlyphs : g.data(), _glyphs.size(), - glyphDistances.data()); - } else { - int i = 0; - while(i < _glyphs.size()) { - wchar_t g = _glyphs[i]; - - ExtTextOutW(hdc, qRound(positions[i].x), - qRound(positions[i].y), options, 0, - convertToText ? convertedGlyphs + i : &g, 1, 0); - ++i; - } + convertToText = convertToText && glyphs.numGlyphs == _glyphs.size(); + bool outputEntireItem = _glyphs.size() > 0; + + if (outputEntireItem) { + options |= ETO_PDY; + QVarLengthArray glyphDistances(_glyphs.size() * 2); + QVarLengthArray g(_glyphs.size()); + for (int i=0; i<_glyphs.size() - 1; ++i) { + glyphDistances[i * 2] = qRound(positions[i + 1].x) - qRound(positions[i].x); + glyphDistances[i * 2 + 1] = qRound(positions[i + 1].y) - qRound(positions[i].y); + g[i] = _glyphs[i]; + } + glyphDistances[(_glyphs.size() - 1) * 2] = 0; + glyphDistances[(_glyphs.size() - 1) * 2 + 1] = 0; + g[_glyphs.size() - 1] = _glyphs[_glyphs.size() - 1]; + ExtTextOut(hdc, qRound(positions[0].x), qRound(positions[0].y), options, 0, + convertToText ? convertedGlyphs : g.data(), _glyphs.size(), + glyphDistances.data()); + } else { + int i = 0; + while(i < _glyphs.size()) { + wchar_t g = _glyphs[i]; + + ExtTextOut(hdc, qRound(positions[i].x), + qRound(positions[i].y), options, 0, + convertToText ? convertedGlyphs + i : &g, 1, 0); + ++i; } } + } #if !defined(Q_OS_WINCE) - QT_WA({ - XFORM win_xform; - win_xform.eM11 = win_xform.eM22 = 1.0; - win_xform.eM12 = win_xform.eM21 = win_xform.eDx = win_xform.eDy = 0.0; - SetWorldTransform(hdc, &win_xform); - }, { - // nothing - }); + win_xform.eM11 = win_xform.eM22 = 1.0; + win_xform.eM12 = win_xform.eM21 = win_xform.eDx = win_xform.eDy = 0.0; + SetWorldTransform(hdc, &win_xform); #endif - } + SelectObject(hdc, old_font); } void QWin32PrintEnginePrivate::updateCustomPaperSize() { - QT_WA( { - uint paperSize = devModeW()->dmPaperSize; - if (paperSize > 0 && mapDevmodePaperSize(paperSize) == QPrinter::Custom) { - has_custom_paper_size = true; - DWORD needed = 0; - DWORD returned = 0; - if (!EnumForms(hPrinter, 1, 0, 0, &needed, &returned)) { - BYTE *forms = (BYTE *) malloc(needed); - if (EnumForms(hPrinter, 1, forms, needed, &needed, &returned)) { - if (paperSize <= returned) { - FORM_INFO_1 *formArray = (FORM_INFO_1 *) forms; - int width = formArray[paperSize-1].Size.cx; // 1/1000 of a mm - int height = formArray[paperSize-1].Size.cy; // 1/1000 of a mm - paper_size = QSizeF((width*72/25.4)/1000.0, (height*72/25.4)/1000.0); - } else { - has_custom_paper_size = false; - } + uint paperSize = devMode->dmPaperSize; + if (paperSize > 0 && mapDevmodePaperSize(paperSize) == QPrinter::Custom) { + has_custom_paper_size = true; + DWORD needed = 0; + DWORD returned = 0; + if (!EnumForms(hPrinter, 1, 0, 0, &needed, &returned)) { + BYTE *forms = (BYTE *) malloc(needed); + if (EnumForms(hPrinter, 1, forms, needed, &needed, &returned)) { + if (paperSize <= returned) { + FORM_INFO_1 *formArray = (FORM_INFO_1 *) forms; + int width = formArray[paperSize - 1].Size.cx; // 1/1000 of a mm + int height = formArray[paperSize - 1].Size.cy; // 1/1000 of a mm + paper_size = QSizeF((width * 72 /25.4) / 1000.0, (height * 72 / 25.4) / 1000.0); + } else { + has_custom_paper_size = false; } - free(forms); } - } else { - has_custom_paper_size = false; + free(forms); } - }, { - // Not supported under Win98 - } ); + } else { + has_custom_paper_size = false; + } } QT_END_NAMESPACE diff --git a/src/gui/painting/qprintengine_win_p.h b/src/gui/painting/qprintengine_win_p.h index 9eb0b69..36a32e8 100644 --- a/src/gui/painting/qprintengine_win_p.h +++ b/src/gui/painting/qprintengine_win_p.h @@ -169,18 +169,8 @@ public: void readDevmode(HGLOBAL globalDevmode); void readDevnames(HGLOBAL globalDevnames); - inline DEVMODEW *devModeW() const { return (DEVMODEW*) devMode; } - inline DEVMODEA *devModeA() const { return (DEVMODEA*) devMode; } - - inline PRINTER_INFO_2W *pInfoW() { return (PRINTER_INFO_2W*) pInfo; }; - inline PRINTER_INFO_2A *pInfoA() { return (PRINTER_INFO_2A*) pInfo; }; - inline bool resetDC() { - QT_WA( { - hdc = ResetDCW(hdc, devModeW()); - }, { - hdc = ResetDCA(hdc, devModeA()); - } ); + hdc = ResetDC(hdc, devMode); return hdc != 0; } @@ -202,8 +192,8 @@ public: HANDLE hPrinter; HGLOBAL globalDevMode; - void *devMode; - void *pInfo; + DEVMODE *devMode; + PRINTER_INFO_2 *pInfo; HGLOBAL hMem; HDC hdc; diff --git a/src/gui/painting/qprinterinfo_win.cpp b/src/gui/painting/qprinterinfo_win.cpp index f0352e6..a10cf3f 100644 --- a/src/gui/painting/qprinterinfo_win.cpp +++ b/src/gui/painting/qprinterinfo_win.cpp @@ -79,45 +79,24 @@ QList QPrinterInfo::availablePrinters() DWORD needed = 0; DWORD returned = 0; - QT_WA({ - if (!EnumPrintersW(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, - 4, 0, 0, &needed, &returned)) - { - buffer = new BYTE[needed]; - if (!EnumPrintersW(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS , NULL, - 4, buffer, needed, &needed, &returned)) - { - delete [] buffer; - return printers; - } - PPRINTER_INFO_4 infoList = reinterpret_cast(buffer); - QPrinterInfo defPrn = defaultPrinter(); - for (uint i = 0; i < returned; ++i) { - printers.append(QPrinterInfo(QString::fromUtf16(reinterpret_cast(infoList[i].pPrinterName)))); - if (printers.at(i).printerName() == defPrn.printerName()) - printers[i].d_ptr->m_default = true; - } - delete [] buffer; - } - }, { - // In Windows 98 networked printers are served through the local connection - if (!EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 5, 0, 0, &needed, &returned)) { - buffer = new BYTE[needed]; - if (!EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 5, buffer, needed, &needed, &returned)) { - delete [] buffer; - return printers; - } - - PPRINTER_INFO_5 infoList = reinterpret_cast(buffer); - QPrinterInfo defPrn = defaultPrinter(); - for (uint i = 0; i < returned; ++i) { - printers.append(QPrinterInfo(QString::fromLocal8Bit(reinterpret_cast(infoList[i].pPrinterName)))); - if (printers.at(i).printerName() == defPrn.printerName()) - printers[i].d_ptr->m_default = true; - } - delete [] buffer; - } - }); + if ( !EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, 0, 0, &needed, &returned)) + { + buffer = new BYTE[needed]; + if (!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS , NULL, + 4, buffer, needed, &needed, &returned)) + { + delete [] buffer; + return printers; + } + PPRINTER_INFO_4 infoList = reinterpret_cast(buffer); + QPrinterInfo defPrn = defaultPrinter(); + for (uint i = 0; i < returned; ++i) { + printers.append(QPrinterInfo(QString::fromWCharArray(infoList[i].pPrinterName))); + if (printers.at(i).printerName() == defPrn.printerName()) + printers[i].d_ptr->m_default = true; + } + delete [] buffer; + } return printers; } @@ -125,18 +104,9 @@ QList QPrinterInfo::availablePrinters() QPrinterInfo QPrinterInfo::defaultPrinter() { QString noPrinters(QLatin1String("qt_no_printers")); - QString output; - QT_WA({ - ushort buffer[256]; - GetProfileStringW(L"windows", L"device", - reinterpret_cast(noPrinters.utf16()), - reinterpret_cast(buffer), 256); - output = QString::fromUtf16(buffer); - }, { - char buffer[256]; - GetProfileStringA("windows", "device", noPrinters.toLatin1(), buffer, 256); - output = QString::fromLocal8Bit(buffer); - }); + wchar_t buffer[256]; + GetProfileString(L"windows", L"device", (wchar_t*)noPrinters.utf16(), buffer, 256); + QString output = QString::fromWCharArray(buffer); // Filter out the name of the printer, which should be everything // before a comma. @@ -222,26 +192,16 @@ bool QPrinterInfo::isDefault() const QList QPrinterInfo::supportedPaperSizes() const { const Q_D(QPrinterInfo); - DWORD size; - WORD* papers; QList paperList; - QT_WA({ - size = DeviceCapabilitiesW(reinterpret_cast(d->m_name.utf16()), - NULL, DC_PAPERS, NULL, NULL); - if ((int)size == -1) - return paperList; - papers = new WORD[size]; - size = DeviceCapabilitiesW(reinterpret_cast(d->m_name.utf16()), - NULL, DC_PAPERS, reinterpret_cast(papers), NULL); - }, { - size = DeviceCapabilitiesA(d->m_name.toLatin1().data(), NULL, DC_PAPERS, NULL, NULL); - if ((int)size == -1) - return paperList; - papers = new WORD[size]; - size = DeviceCapabilitiesA(d->m_name.toLatin1().data(), NULL, DC_PAPERS, - reinterpret_cast(papers), NULL); - }); + DWORD size = DeviceCapabilities(reinterpret_cast(d->m_name.utf16()), + NULL, DC_PAPERS, NULL, NULL); + if ((int)size == -1) + return paperList; + + wchar_t *papers = new wchar_t[size]; + size = DeviceCapabilities(reinterpret_cast(d->m_name.utf16()), + NULL, DC_PAPERS, papers, NULL); for (int c = 0; c < (int)size; ++c) { paperList.append(mapDevmodePaperSize(papers[c])); diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp index 1b7dc1b..762e9e0 100644 --- a/src/gui/painting/qregion.cpp +++ b/src/gui/painting/qregion.cpp @@ -92,10 +92,6 @@ QT_BEGIN_NAMESPACE Example of using complex regions: \snippet doc/src/snippets/code/src_gui_painting_qregion.cpp 0 - \warning Due to window system limitations, the whole coordinate space for a - region is limited to the points between -32767 and 32767 on Windows - 95/98/ME. You can circumvent this limitation by using a QPainterPath. - \section1 Additional License Information On Embedded Linux, Windows CE and X11 platforms, parts of this class rely on diff --git a/src/gui/painting/qwindowsurface_raster.cpp b/src/gui/painting/qwindowsurface_raster.cpp index c163d79..22433dd 100644 --- a/src/gui/painting/qwindowsurface_raster.cpp +++ b/src/gui/painting/qwindowsurface_raster.cpp @@ -43,6 +43,7 @@ #include // for Q_WS_WIN define (non-PCH) #ifdef Q_WS_WIN +#include #include #endif @@ -67,10 +68,6 @@ QT_BEGIN_NAMESPACE -#ifdef Q_WS_WIN -PtrUpdateLayeredWindowIndirect ptrUpdateLayeredWindowIndirect; -#endif - class QRasterWindowSurfacePrivate { public: @@ -82,9 +79,6 @@ public: uint translucentBackground : 1; #endif #endif -#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE) - uint canUseLayeredWindow : 1; -#endif uint inSetGeometry : 1; }; @@ -98,10 +92,6 @@ QRasterWindowSurface::QRasterWindowSurface(QWidget *window) && window->x11Info().depth() == 32; #endif #endif -#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE) - d_ptr->canUseLayeredWindow = ptrUpdateLayeredWindowIndirect - && (qt_widget_private(window)->data.window_flags & Qt::FramelessWindowHint); -#endif d_ptr->image = 0; d_ptr->inSetGeometry = false; setStaticContentsSupport(true); @@ -130,8 +120,7 @@ void QRasterWindowSurface::beginPaint(const QRegion &rgn) #if (defined(Q_WS_X11) && !defined(QT_NO_XRENDER)) || (defined(Q_WS_WIN) && !defined(Q_WS_WINCE)) if (!qt_widget_private(window())->isOpaque) { #if defined(Q_WS_WIN) && !defined(Q_WS_WINCE) - if (d_ptr->image->image.format() != QImage::Format_ARGB32_Premultiplied - && d_ptr->canUseLayeredWindow) + if (d_ptr->image->image.format() != QImage::Format_ARGB32_Premultiplied) prepareBuffer(QImage::Format_ARGB32_Premultiplied, window()); #endif QPainter p(&d_ptr->image->image); @@ -160,7 +149,7 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi QRect br = rgn.boundingRect(); #ifndef Q_WS_WINCE - if (!qt_widget_private(window())->isOpaque && d->canUseLayeredWindow) { + if (!qt_widget_private(window())->isOpaque) { QRect r = window()->frameGeometry(); QPoint frameOffset = qt_widget_private(window())->frameStrut().topLeft(); QRect dirtyRect = br.translated(offset + frameOffset); @@ -168,12 +157,11 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi SIZE size = {r.width(), r.height()}; POINT ptDst = {r.x(), r.y()}; POINT ptSrc = {0, 0}; - Q_BLENDFUNCTION blend = {AC_SRC_OVER, 0, (int)(255.0 * window()->windowOpacity()), Q_AC_SRC_ALPHA}; + BLENDFUNCTION blend = {AC_SRC_OVER, 0, (int)(255.0 * window()->windowOpacity()), Q_AC_SRC_ALPHA}; RECT dirty = {dirtyRect.x(), dirtyRect.y(), dirtyRect.x() + dirtyRect.width(), dirtyRect.y() + dirtyRect.height()}; Q_UPDATELAYEREDWINDOWINFO info = {sizeof(info), NULL, &ptDst, &size, d->image->hdc, &ptSrc, 0, &blend, Q_ULW_ALPHA, &dirty}; - - (*ptrUpdateLayeredWindowIndirect)(window()->internalWinId(), &info); + ptrUpdateLayeredWindowIndirect(window()->internalWinId(), &info); } else #endif { @@ -308,7 +296,7 @@ void QRasterWindowSurface::setGeometry(const QRect &rect) #ifndef Q_WS_WIN if (d_ptr->translucentBackground) #else - if (!qt_widget_private(window())->isOpaque && d->canUseLayeredWindow) + if (!qt_widget_private(window())->isOpaque) #endif prepareBuffer(QImage::Format_ARGB32_Premultiplied, window()); else diff --git a/src/gui/painting/qwindowsurface_raster_p.h b/src/gui/painting/qwindowsurface_raster_p.h index 897ed8d..996aaef 100644 --- a/src/gui/painting/qwindowsurface_raster_p.h +++ b/src/gui/painting/qwindowsurface_raster_p.h @@ -64,13 +64,6 @@ QT_BEGIN_NAMESPACE #define Q_ULW_ALPHA 0x00000002 // copied from ULW_ALPHA in winuser.h #define Q_AC_SRC_ALPHA 0x00000001 // copied from AC_SRC_ALPHA in winuser.h -struct Q_BLENDFUNCTION { - BYTE BlendOp; - BYTE BlendFlags; - BYTE SourceConstantAlpha; - BYTE AlphaFormat; -}; - struct Q_UPDATELAYEREDWINDOWINFO { DWORD cbSize; HDC hdcDst; @@ -79,12 +72,16 @@ struct Q_UPDATELAYEREDWINDOWINFO { HDC hdcSrc; const POINT *pptSrc; COLORREF crKey; - const Q_BLENDFUNCTION *pblend; + const BLENDFUNCTION *pblend; DWORD dwFlags; const RECT *prcDirty; }; +typedef BOOL (WINAPI *PtrUpdateLayeredWindow)(HWND hwnd, HDC hdcDst, const POINT *pptDst, + const SIZE *psize, HDC hdcSrc, const POINT *pptSrc, COLORREF crKey, + const BLENDFUNCTION *pblend, DWORD dwflags); typedef BOOL (WINAPI *PtrUpdateLayeredWindowIndirect)(HWND hwnd, const Q_UPDATELAYEREDWINDOWINFO *pULWInfo); +extern PtrUpdateLayeredWindow ptrUpdateLayeredWindow; extern PtrUpdateLayeredWindowIndirect ptrUpdateLayeredWindowIndirect; #endif diff --git a/src/gui/styles/qwindowsstyle.cpp b/src/gui/styles/qwindowsstyle.cpp index 997c2ce..4f25e68 100644 --- a/src/gui/styles/qwindowsstyle.cpp +++ b/src/gui/styles/qwindowsstyle.cpp @@ -126,8 +126,6 @@ static const int windowsCheckMarkHMargin = 2; // horiz. margins of check mark static const int windowsRightBorder = 15; // right border on windows static const int windowsCheckMarkWidth = 12; // checkmarks width on windows -static bool use2000style = true; - enum QSliderDirection { SlUp, SlDown, SlLeft, SlRight }; /* @@ -269,9 +267,6 @@ bool QWindowsStyle::eventFilter(QObject *o, QEvent *e) */ QWindowsStyle::QWindowsStyle() : QCommonStyle(*new QWindowsStylePrivate) { -#if defined(Q_OS_WIN32) - use2000style = QSysInfo::WindowsVersion != QSysInfo::WV_NT && QSysInfo::WindowsVersion != QSysInfo::WV_95; -#endif } /*! @@ -281,9 +276,6 @@ QWindowsStyle::QWindowsStyle() : QCommonStyle(*new QWindowsStylePrivate) */ QWindowsStyle::QWindowsStyle(QWindowsStylePrivate &dd) : QCommonStyle(dd) { -#if defined(Q_OS_WIN32) - use2000style = QSysInfo::WindowsVersion != QSysInfo::WV_NT && QSysInfo::WindowsVersion != QSysInfo::WV_95; -#endif } @@ -1137,12 +1129,7 @@ int QWindowsStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWid #endif break; case SH_ItemView_ChangeHighlightOnFocus: -#if defined(Q_WS_WIN) - if (QSysInfo::WindowsVersion != QSysInfo::WV_95 && QSysInfo::WindowsVersion != QSysInfo::WV_NT) - ret = 1; - else -#endif - ret = 0; + ret = 1; break; case SH_ToolBox_SelectedPageTitleBold: ret = 0; @@ -1150,36 +1137,34 @@ int QWindowsStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWid #if defined(Q_WS_WIN) case SH_UnderlineShortcut: + { ret = 1; - if (QSysInfo::WindowsVersion != QSysInfo::WV_95 - && QSysInfo::WindowsVersion != QSysInfo::WV_98 - && QSysInfo::WindowsVersion != QSysInfo::WV_NT) { - BOOL cues; - SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &cues, 0); - ret = int(cues); - // Do nothing if we always paint underlines - Q_D(const QWindowsStyle); - if (!ret && widget && d) { + BOOL cues = false; + SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &cues, 0); + ret = int(cues); + // Do nothing if we always paint underlines + Q_D(const QWindowsStyle); + if (!ret && widget && d) { #ifndef QT_NO_MENUBAR - const QMenuBar *menuBar = qobject_cast(widget); - if (!menuBar && qobject_cast(widget)) { - QWidget *w = QApplication::activeWindow(); - if (w && w != widget) - menuBar = qFindChild(w); - } - // If we paint a menu bar draw underlines if is in the keyboardState - if (menuBar) { - if (menuBar->d_func()->keyboardState || d->altDown()) - ret = 1; - // Otherwise draw underlines if the toplevel widget has seen an alt-press - } else -#endif // QT_NO_MENUBAR - if (d->hasSeenAlt(widget)) { + const QMenuBar *menuBar = qobject_cast(widget); + if (!menuBar && qobject_cast(widget)) { + QWidget *w = QApplication::activeWindow(); + if (w && w != widget) + menuBar = qFindChild(w); + } + // If we paint a menu bar draw underlines if is in the keyboardState + if (menuBar) { + if (menuBar->d_func()->keyboardState || d->altDown()) ret = 1; - } + // Otherwise draw underlines if the toplevel widget has seen an alt-press + } else +#endif // QT_NO_MENUBAR + if (d->hasSeenAlt(widget)) { + ret = 1; } } break; + } #endif #ifndef QT_NO_RUBBERBAND case SH_RubberBand_Mask: @@ -1317,7 +1302,7 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, if ((!(opt->state & State_Sunken )) && (!(opt->state & State_Enabled) || !(opt->state & State_MouseOver && opt->state & State_AutoRaise)) - && (opt->state & State_On) && use2000style) { + && (opt->state & State_On)) { fill = QBrush(opt->palette.light().color(), Qt::Dense4Pattern); stippled = true; } else { @@ -1631,9 +1616,9 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, popupPal.setColor(QPalette::Light, frame->palette.background().color()); popupPal.setColor(QPalette::Midlight, frame->palette.light().color()); } - if (use2000style && pe == PE_Frame && (frame->state & State_Raised)) + if (pe == PE_Frame && (frame->state & State_Raised)) qDrawWinButton(p, frame->rect, popupPal, frame->state & State_Sunken); - else if (use2000style && pe == PE_Frame && (frame->state & State_Sunken)) + else if (pe == PE_Frame && (frame->state & State_Sunken)) { popupPal.setColor(QPalette::Midlight, frame->palette.background().color()); qDrawWinPanel(p, frame->rect, popupPal, frame->state & State_Sunken); @@ -1784,13 +1769,12 @@ case PE_FrameDockWidget: break; #endif // QT_NO_PROGRESSBAR - case PE_FrameTabWidget: - if (use2000style) { - QRect rect = opt->rect; - QPalette pal = opt->palette; - qDrawWinButton(p, opt->rect, opt->palette, false, 0); - break; - } + case PE_FrameTabWidget: { + QRect rect = opt->rect; + QPalette pal = opt->palette; + qDrawWinButton(p, opt->rect, opt->palette, false, 0); + break; + } default: QCommonStyle::drawPrimitive(pe, opt, p, w); } @@ -2066,10 +2050,6 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai p->setPen(light); p->drawLine(x1, y1 + 2, x1, y2 - ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness)); p->drawPoint(x1 + 1, y1 + 1); - if (!use2000style) { - p->setPen(midlight); - p->drawLine(x1 + 1, y1 + 2, x1 + 1, y2 - ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness)); - } } // Top { @@ -2077,10 +2057,6 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai int end = x2 - (nextSelected ? 0 : 2); p->setPen(light); p->drawLine(beg, y1, end, y1); - if (!use2000style) { - p->setPen(midlight); - p->drawLine(beg, y1 + 1, end, y1 + 1); - } } // Right if (lastTab || selected || onlyOne || !nextSelected) { @@ -2110,10 +2086,6 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai p->setPen(light); p->drawLine(x1, y2 - 2, x1, y1 + ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness)); p->drawPoint(x1 + 1, y2 - 1); - if (!use2000style) { - p->setPen(midlight); - p->drawLine(x1 + 1, y2 - 2, x1 + 1, y1 + ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness)); - } } // Bottom { @@ -2152,10 +2124,6 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai p->setPen(light); p->drawLine(x1 + 2, y1, x2 - ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness), y1); p->drawPoint(x1 + 1, y1 + 1); - if (!use2000style) { - p->setPen(midlight); - p->drawLine(x1 + 2, y1 + 1, x2 - ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness), y1 + 1); - } } // Left { @@ -2163,10 +2131,6 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai int end = y2 - (nextSelected ? 0 : 2); p->setPen(light); p->drawLine(x1, beg, x1, end); - if (!use2000style) { - p->setPen(midlight); - p->drawLine(x1 + 1, beg, x1 + 1, end); - } } // Bottom if (lastTab || selected || onlyOne || !nextSelected) { @@ -2198,11 +2162,6 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai p->setPen(light); p->drawLine(x2 - 2, y1, x1 + ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness), y1); p->drawPoint(x2 - 1, y1 + 1); - if (!use2000style) { - p->setPen(midlight); - p->drawLine(x2 - 3, y1 + 1, x1 + ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness), y1 + 1); - p->drawPoint(x2 - 1, y1); - } } // Right { @@ -2239,7 +2198,7 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai #ifndef QT_NO_SCROLLBAR case CE_ScrollBarSubLine: case CE_ScrollBarAddLine: { - if (use2000style && (opt->state & State_Sunken)) { + if ((opt->state & State_Sunken)) { p->setPen(opt->palette.dark().color()); p->setBrush(opt->palette.brush(QPalette::Button)); p->drawRect(opt->rect.adjusted(0, 0, -1, -1)); @@ -3027,8 +2986,7 @@ void QWindowsStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComp if ((cmb->subControls & SC_ComboBoxFrame)) { if (cmb->frame) { QPalette shadePal = opt->palette; - if (use2000style) - shadePal.setColor(QPalette::Midlight, shadePal.button().color()); + shadePal.setColor(QPalette::Midlight, shadePal.button().color()); qDrawWinPanel(p, opt->rect, shadePal, true, &editBrush); } else { @@ -3104,8 +3062,7 @@ void QWindowsStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComp QBrush editBrush = sb->palette.brush(QPalette::Base); QRect r = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxFrame, widget); QPalette shadePal = sb->palette; - if (use2000style) - shadePal.setColor(QPalette::Midlight, shadePal.button().color()); + shadePal.setColor(QPalette::Midlight, shadePal.button().color()); qDrawWinPanel(p, r, shadePal, true, &editBrush); } @@ -3234,7 +3191,7 @@ QSize QWindowsStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, + 2 * windowsItemFrame)); } int maxpmw = mi->maxIconWidth; - int tabSpacing = use2000style ? 20 :windowsTabSpacing; + int tabSpacing = 20; if (mi->text.contains(QLatin1Char('\t'))) w += tabSpacing; else if (mi->menuItemType == QStyleOptionMenuItem::SubMenu) diff --git a/src/gui/styles/qwindowsvistastyle.cpp b/src/gui/styles/qwindowsvistastyle.cpp index b131d39..3e65eef 100644 --- a/src/gui/styles/qwindowsvistastyle.cpp +++ b/src/gui/styles/qwindowsvistastyle.cpp @@ -2571,9 +2571,7 @@ void QWindowsVistaStylePrivate::startAnimation(Animation *t) bool QWindowsVistaStylePrivate::transitionsEnabled() const { BOOL animEnabled = false; - if (QT_WA_INLINE(SystemParametersInfo(SPI_GETCLIENTAREAANIMATION, 0, &animEnabled, 0), - SystemParametersInfoA(SPI_GETCLIENTAREAANIMATION, 0, &animEnabled, 0) - )) + if (SystemParametersInfo(SPI_GETCLIENTAREAANIMATION, 0, &animEnabled, 0)) { if (animEnabled) return true; diff --git a/src/gui/styles/qwindowsxpstyle.cpp b/src/gui/styles/qwindowsxpstyle.cpp index 322bfac..9c4afee 100644 --- a/src/gui/styles/qwindowsxpstyle.cpp +++ b/src/gui/styles/qwindowsxpstyle.cpp @@ -161,8 +161,7 @@ HTHEME XPThemeData::handle() htheme = QWindowsXPStylePrivate::handleMap->operator[](name); if (!htheme) { - htheme = pOpenThemeData(QWindowsXPStylePrivate::winId(widget), - (TCHAR*)name.utf16()); + htheme = pOpenThemeData(QWindowsXPStylePrivate::winId(widget), (wchar_t*)name.utf16()); if (htheme) { if (!QWindowsXPStylePrivate::handleMap) QWindowsXPStylePrivate::handleMap = new QMap; @@ -1547,11 +1546,11 @@ case PE_Frame: if (widget) { bool useGradient = true; const int maxlength = 256; - WCHAR themeFileName[maxlength]; - WCHAR themeColor[maxlength]; + wchar_t themeFileName[maxlength]; + wchar_t themeColor[maxlength]; // Due to a a scaling issue with the XP Silver theme, tab gradients are not used with it if (pGetCurrentThemeName(themeFileName, maxlength, themeColor, maxlength, NULL, 0) == S_OK) { - WCHAR* offset; + wchar_t *offset = 0; if ((offset = wcsrchr(themeFileName, QChar(QLatin1Char('\\')).unicode())) != NULL) { offset++; if (!lstrcmp(offset, L"Luna.msstyles") && !lstrcmp(offset, L"Metallic")) { diff --git a/src/gui/text/qfont_win.cpp b/src/gui/text/qfont_win.cpp index 2c27c9b..2293973 100644 --- a/src/gui/text/qfont_win.cpp +++ b/src/gui/text/qfont_win.cpp @@ -39,11 +39,6 @@ ** ****************************************************************************/ -// the miscrosoft platform SDK says that the Unicode versions of -// TextOut and GetTextExtentsPoint32 are supported on all platforms, so we use them -// exclusively to simplify code, save a lot of conversions into the local encoding -// and have generally better unicode support :) - #include "qfont.h" #include "qfont_p.h" #include "qfontengine_p.h" @@ -67,8 +62,7 @@ extern HDC shared_dc(); // common dc for all fonts // ### maybe move to qapplication_win QFont qt_LOGFONTtoQFont(LOGFONT& lf, bool /*scale*/) { - QString family = QT_WA_INLINE(QString::fromUtf16((ushort*)lf.lfFaceName), - QString::fromLocal8Bit((char*)lf.lfFaceName)); + QString family = QString::fromWCharArray(lf.lfFaceName); QFont qf(family); qf.setItalic(lf.lfItalic); if (lf.lfWeight != FW_DONTCARE) { diff --git a/src/gui/text/qfontdatabase_win.cpp b/src/gui/text/qfontdatabase_win.cpp index 2c0223b..2e8e5e4 100644 --- a/src/gui/text/qfontdatabase_win.cpp +++ b/src/gui/text/qfontdatabase_win.cpp @@ -195,21 +195,12 @@ static QString getEnglishName(const QString &familyName) QString i18n_name; HDC hdc = GetDC( 0 ); - HFONT hfont; - QT_WA( { - LOGFONTW lf; - memset( &lf, 0, sizeof( LOGFONTW ) ); - memcpy( lf.lfFaceName, familyName.utf16(), qMin(LF_FACESIZE, familyName.length())*sizeof(QChar) ); - lf.lfCharSet = DEFAULT_CHARSET; - hfont = CreateFontIndirectW( &lf ); - }, { - LOGFONTA lf; - memset( &lf, 0, sizeof( LOGFONTA ) ); - QByteArray lfam = familyName.toLocal8Bit(); - memcpy( lf.lfFaceName, lfam, qMin(LF_FACESIZE, lfam.size()) ); - lf.lfCharSet = DEFAULT_CHARSET; - hfont = CreateFontIndirectA( &lf ); - } ); + LOGFONT lf; + memset(&lf, 0, sizeof(LOGFONT)); + memcpy(lf.lfFaceName, familyName.utf16(), qMin(LF_FACESIZE, familyName.length()) * sizeof(wchar_t)); + lf.lfCharSet = DEFAULT_CHARSET; + HFONT hfont = CreateFontIndirect(&lf); + if(!hfont) { ReleaseDC(0, hdc); return QString(); @@ -245,32 +236,6 @@ error: return i18n_name; } -static void getFontSignature(const QString &familyName, - NEWTEXTMETRICEX *textmetric, - FONTSIGNATURE *signature) -{ - QT_WA({ - Q_UNUSED(familyName); - *signature = textmetric->ntmFontSig; - }, { - // the textmetric structure we get from EnumFontFamiliesEx on Win9x has - // a FONTSIGNATURE, but that one is uninitialized and doesn't work. Have to go - // the hard way and load the font to find out. - HDC hdc = GetDC(0); - LOGFONTA lf; - memset(&lf, 0, sizeof(LOGFONTA)); - QByteArray lfam = familyName.toLocal8Bit(); - memcpy(lf.lfFaceName, lfam.data(), qMin(LF_FACESIZE, lfam.length())); - lf.lfCharSet = DEFAULT_CHARSET; - HFONT hfont = CreateFontIndirectA(&lf); - HGDIOBJ oldobj = SelectObject(hdc, hfont); - GetTextCharsetInfo(hdc, signature, 0); - SelectObject(hdc, oldobj); - DeleteObject(hfont); - ReleaseDC(0, hdc); - }); -} - static void addFontToDatabase(QString familyName, const QString &scriptName, TEXTMETRIC *textmetric, @@ -288,26 +253,17 @@ void addFontToDatabase(QString familyName, const QString &scriptName, bool scalable; int size; -// QString escript = QString::fromUtf16((ushort *)f->elfScript); +// QString escript = QString::fromWCharArray(f->elfScript); // qDebug("script=%s", escript.latin1()); - QT_WA({ - NEWTEXTMETRIC *tm = (NEWTEXTMETRIC *)textmetric; - fixed = !(tm->tmPitchAndFamily & TMPF_FIXED_PITCH); - ttf = (tm->tmPitchAndFamily & TMPF_TRUETYPE); - scalable = tm->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE); - size = scalable ? SMOOTH_SCALABLE : tm->tmHeight; - italic = tm->tmItalic; - weight = tm->tmWeight; - } , { - NEWTEXTMETRICA *tm = (NEWTEXTMETRICA *)textmetric; - fixed = !(tm->tmPitchAndFamily & TMPF_FIXED_PITCH); - ttf = (tm->tmPitchAndFamily & TMPF_TRUETYPE); - scalable = tm->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE); - size = scalable ? SMOOTH_SCALABLE : tm->tmHeight; - italic = tm->tmItalic; - weight = tm->tmWeight; - }); + NEWTEXTMETRIC *tm = (NEWTEXTMETRIC *)textmetric; + fixed = !(tm->tmPitchAndFamily & TMPF_FIXED_PITCH); + ttf = (tm->tmPitchAndFamily & TMPF_TRUETYPE); + scalable = tm->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE); + size = scalable ? SMOOTH_SCALABLE : tm->tmHeight; + italic = tm->tmItalic; + weight = tm->tmWeight; + // the "@family" fonts are just the same as "family". Ignore them. if (familyName[0] != QLatin1Char('@') && !familyName.startsWith(QLatin1String("WST_"))) { QtFontStyle::Key styleKey; @@ -420,18 +376,10 @@ static int CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric, int type, LPARAM /*p*/) { - QString familyName; - QT_WA({ - familyName = QString::fromUtf16((ushort*)f->elfLogFont.lfFaceName); - },{ - ENUMLOGFONTEXA *fa = (ENUMLOGFONTEXA *)f; - familyName = QString::fromLocal8Bit(fa->elfLogFont.lfFaceName); - }); - QString script = QT_WA_INLINE(QString::fromUtf16((const ushort *)f->elfScript), - QString::fromLocal8Bit((const char *)((ENUMLOGFONTEXA *)f)->elfScript)); - - FONTSIGNATURE signature; - getFontSignature(familyName, textmetric, &signature); + QString familyName = QString::fromWCharArray(f->elfLogFont.lfFaceName); + QString script = QString::fromWCharArray(f->elfScript); + + FONTSIGNATURE signature = textmetric->ntmFontSig; // NEWTEXTMETRICEX is a NEWTEXTMETRIC, which according to the documentation is // identical to a TEXTMETRIC except for the last four members, which we don't use @@ -459,33 +407,17 @@ void populate_database(const QString& fam) HDC dummy = GetDC(0); - QT_WA({ - LOGFONT lf; - lf.lfCharSet = DEFAULT_CHARSET; - if (fam.isNull()) { - lf.lfFaceName[0] = 0; - } else { - memcpy(lf.lfFaceName, fam.utf16(), sizeof(TCHAR)*qMin(fam.length()+1,32)); // 32 = Windows hard-coded - } - lf.lfPitchAndFamily = 0; - - EnumFontFamiliesEx(dummy, &lf, - (FONTENUMPROC)storeFont, (LPARAM)privateDb(), 0); - } , { - LOGFONTA lf; - lf.lfCharSet = DEFAULT_CHARSET; - if (fam.isNull()) { - lf.lfFaceName[0] = 0; - } else { - QByteArray lname = fam.toLocal8Bit(); - memcpy(lf.lfFaceName,lname.data(), - qMin(lname.length()+1,32)); // 32 = Windows hard-coded - } - lf.lfPitchAndFamily = 0; + LOGFONT lf; + lf.lfCharSet = DEFAULT_CHARSET; + if (fam.isNull()) { + lf.lfFaceName[0] = 0; + } else { + memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded + } + lf.lfPitchAndFamily = 0; - EnumFontFamiliesExA(dummy, &lf, - (FONTENUMPROCA)storeFont, (LPARAM)privateDb(), 0); - }); + EnumFontFamiliesEx(dummy, &lf, + (FONTENUMPROC)storeFont, (LPARAM)privateDb(), 0); ReleaseDC(0, dummy); @@ -496,21 +428,11 @@ void populate_database(const QString& fam) for (int j = 0; j < fnt.families.count(); ++j) { const QString familyName = fnt.families.at(j); HDC hdc = GetDC(0); - HFONT hfont; - QT_WA({ - LOGFONTW lf; - memset(&lf, 0, sizeof(LOGFONTW)); - memcpy(lf.lfFaceName, familyName.utf16(), qMin(LF_FACESIZE, familyName.size())); - lf.lfCharSet = DEFAULT_CHARSET; - hfont = CreateFontIndirectW(&lf); - } , { - LOGFONTA lf; - memset(&lf, 0, sizeof(LOGFONTA)); - QByteArray lfam = familyName.toLocal8Bit(); - memcpy(lf.lfFaceName, lfam.data(), qMin(LF_FACESIZE, lfam.length())); - lf.lfCharSet = DEFAULT_CHARSET; - hfont = CreateFontIndirectA(&lf); - }); + LOGFONT lf; + memset(&lf, 0, sizeof(LOGFONT)); + memcpy(lf.lfFaceName, familyName.utf16(), sizeof(wchar_t) * qMin(LF_FACESIZE, familyName.size())); + lf.lfCharSet = DEFAULT_CHARSET; + HFONT hfont = CreateFontIndirect(&lf); HGDIOBJ oldobj = SelectObject(hdc, hfont); TEXTMETRIC textMetrics; @@ -598,17 +520,10 @@ static void initFontInfo(QFontEngineWin *fe, const QFontDef &request, const QFon HDC dc = ((request.styleStrategy & QFont::PreferDevice) && fp->hdc) ? fp->hdc : shared_dc(); SelectObject(dc, fe->hfont); - QT_WA({ - TCHAR n[64]; - GetTextFaceW(dc, 64, n); - fe->fontDef.family = QString::fromUtf16((ushort*)n); - fe->fontDef.fixedPitch = !(fe->tm.w.tmPitchAndFamily & TMPF_FIXED_PITCH); - } , { - char an[64]; - GetTextFaceA(dc, 64, an); - fe->fontDef.family = QString::fromLocal8Bit(an); - fe->fontDef.fixedPitch = !(fe->tm.a.tmPitchAndFamily & TMPF_FIXED_PITCH); - }); + wchar_t n[64]; + GetTextFace(dc, 64, n); + fe->fontDef.family = QString::fromWCharArray(n); + fe->fontDef.fixedPitch = !(fe->tm.tmPitchAndFamily & TMPF_FIXED_PITCH); if (fe->fontDef.pointSize < 0) { fe->fontDef.pointSize = fe->fontDef.pixelSize * 72. / fp->dpi; } else if (fe->fontDef.pixelSize == -1) { @@ -704,12 +619,7 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ HFONT hfont = 0; if (fp->rawMode) { // will choose a stock font - int f, deffnt; - // ### why different? - if ((QSysInfo::WindowsVersion & QSysInfo::WV_NT_based) || QSysInfo::WindowsVersion == QSysInfo::WV_32s) - deffnt = SYSTEM_FONT; - else - deffnt = DEFAULT_GUI_FONT; + int f, deffnt = SYSTEM_FONT; QString fam = desc->family->name.toLower(); if (fam == QLatin1String("default")) f = deffnt; @@ -778,11 +688,7 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ } else if (request.styleStrategy & QFont::PreferDevice) { strat = OUT_DEVICE_PRECIS; } else if (request.styleStrategy & QFont::PreferOutline) { - QT_WA({ - strat = OUT_OUTLINE_PRECIS; - } , { - strat = OUT_TT_PRECIS; - }); + strat = OUT_OUTLINE_PRECIS; } else if (request.styleStrategy & QFont::ForceOutline) { strat = OUT_TT_ONLY_PRECIS; #endif @@ -801,7 +707,7 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ if (request.styleStrategy & QFont::PreferAntialias) { if (QSysInfo::WindowsVersion >= QSysInfo::WV_XP) { - qual = 5; // == CLEARTYPE_QUALITY; + qual = CLEARTYPE_QUALITY; preferClearTypeAA = true; } else { qual = ANTIALIASED_QUALITY; @@ -827,16 +733,8 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ if (fam == QLatin1String("Courier") && !(request.styleStrategy & QFont::PreferBitmap)) fam = QLatin1String("Courier New"); - QT_WA({ - memcpy(lf.lfFaceName, fam.utf16(), sizeof(TCHAR)*qMin(fam.length()+1,32)); // 32 = Windows hard-coded - hfont = CreateFontIndirect(&lf); - } , { - // LOGFONTA and LOGFONTW are binary compatible - QByteArray lname = fam.toLocal8Bit(); - memcpy(lf.lfFaceName,lname.data(), - qMin(lname.length()+1,32)); // 32 = Windows hard-coded - hfont = CreateFontIndirectA((LOGFONTA*)&lf); - }); + memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded + hfont = CreateFontIndirect(&lf); if (!hfont) qErrnoWarning("QFontEngine::loadEngine: CreateFontIndirect failed"); @@ -845,17 +743,12 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ int avWidth = 0; BOOL res; HGDIOBJ oldObj = SelectObject(hdc, hfont); - QT_WA({ - TEXTMETRICW tm; - res = GetTextMetricsW(hdc, &tm); - avWidth = tm.tmAveCharWidth; - ttf = tm.tmPitchAndFamily & TMPF_TRUETYPE; - } , { - TEXTMETRICA tm; - res = GetTextMetricsA(hdc, &tm); - avWidth = tm.tmAveCharWidth; - ttf = tm.tmPitchAndFamily & TMPF_TRUETYPE; - }); + + TEXTMETRIC tm; + res = GetTextMetrics(hdc, &tm); + avWidth = tm.tmAveCharWidth; + ttf = tm.tmPitchAndFamily & TMPF_TRUETYPE; + SelectObject(hdc, oldObj); if (hfont && (!ttf || request.stretch != 100)) { @@ -863,11 +756,7 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ if (!res) qErrnoWarning("QFontEngine::loadEngine: GetTextMetrics failed"); lf.lfWidth = avWidth * request.stretch/100; - QT_WA({ - hfont = CreateFontIndirect(&lf); - } , { - hfont = CreateFontIndirectA((LOGFONTA*)&lf); - }); + hfont = CreateFontIndirect(&lf); if (!hfont) qErrnoWarning("QFontEngine::loadEngine: CreateFontIndirect with stretch failed"); } @@ -969,12 +858,6 @@ static QFontEngine *loadWin(const QFontPrivate *d, int script, const QFontDef &r // list of families to try QStringList family_list = familyList(req); - if(QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based && req.family.toLower() == QLatin1String("ms sans serif")) { - // small hack for Dos based machines to get the right font for non - // latin text when using the default font. - family_list << QLatin1String("Arial"); - } - const char *stylehint = styleHint(d->request); if (stylehint) family_list << QLatin1String(stylehint); @@ -1165,21 +1048,21 @@ static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt) HANDLE handle = 0; { -#ifdef QT_NO_TEMPORARYFILE - TCHAR lpBuffer[MAX_PATH]; +#ifdef QT_NO_TEMPORARYFILE + wchar_t lpBuffer[MAX_PATH]; GetTempPath(MAX_PATH, lpBuffer); - QString s = QString::fromUtf16((const ushort *) lpBuffer); + QString s = QString::fromWCharArray(lpBuffer); QFile tempfile(s + QLatin1String("/font") + QString::number(GetTickCount()) + QLatin1String(".ttf")); if (!tempfile.open(QIODevice::ReadWrite)) #else QTemporaryFile tempfile(QLatin1String("XXXXXXXX.ttf")); if (!tempfile.open()) -#endif +#endif // QT_NO_TEMPORARYFILE return; if (tempfile.write(fnt->data) == -1) return; -#ifndef QT_NO_TEMPORARYFILE +#ifndef QT_NO_TEMPORARYFILE tempfile.setAutoRemove(false); #endif fnt->fileName = QFileInfo(tempfile.fileName()).absoluteFilePath(); @@ -1191,13 +1074,11 @@ static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt) } #else DWORD dummy = 0; - HANDLE handle = ptrAddFontMemResourceEx((void *)fnt->data.constData(), - fnt->data.size(), - 0, - &dummy); + HANDLE handle = ptrAddFontMemResourceEx((void *)fnt->data.constData(), fnt->data.size(), 0, + &dummy); if (handle == 0) return; -#endif +#endif // Q_OS_WINCE fnt->handle = handle; fnt->data = QByteArray(); @@ -1219,12 +1100,10 @@ static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt) // supported from 2000 on, so no need to deal with the *A variant PtrAddFontResourceExW ptrAddFontResourceExW = (PtrAddFontResourceExW)QLibrary::resolve(QLatin1String("gdi32"), "AddFontResourceExW"); - if (!ptrAddFontResourceExW) + if (!ptrAddFontResourceExW + || ptrAddFontResourceExW((wchar_t*)fnt->fileName.utf16(), FR_PRIVATE, 0) == 0) return; - - if (ptrAddFontResourceExW((LPCWSTR)fnt->fileName.utf16(), FR_PRIVATE, 0) == 0) - return; -#endif +#endif // Q_OS_WINCE fnt->memoryFont = false; } @@ -1250,12 +1129,10 @@ bool QFontDatabase::removeApplicationFont(int handle) #else PtrRemoveFontMemResourceEx ptrRemoveFontMemResourceEx = (PtrRemoveFontMemResourceEx)QLibrary::resolve(QLatin1String("gdi32"), "RemoveFontMemResourceEx"); - if (!ptrRemoveFontMemResourceEx) - return false; - - if (!ptrRemoveFontMemResourceEx(font.handle)) + if (!ptrRemoveFontMemResourceEx + || !ptrRemoveFontMemResourceEx(font.handle)) return false; -#endif +#endif // Q_OS_WINCE } else { #ifdef Q_OS_WINCE if (!RemoveFontResource((LPCWSTR)font.fileName.utf16())) @@ -1263,12 +1140,10 @@ bool QFontDatabase::removeApplicationFont(int handle) #else PtrRemoveFontResourceExW ptrRemoveFontResourceExW = (PtrRemoveFontResourceExW)QLibrary::resolve(QLatin1String("gdi32"), "RemoveFontResourceExW"); - if (!ptrRemoveFontResourceExW) - return false; - - if (!ptrRemoveFontResourceExW((LPCWSTR)font.fileName.utf16(), FR_PRIVATE, 0)) + if (!ptrRemoveFontResourceExW + || !ptrRemoveFontResourceExW((LPCWSTR)font.fileName.utf16(), FR_PRIVATE, 0)) return false; -#endif +#endif // Q_OS_WINCE } db->invalidate(); diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp index 9715aef..f4adc9a 100644 --- a/src/gui/text/qfontengine_win.cpp +++ b/src/gui/text/qfontengine_win.cpp @@ -48,7 +48,6 @@ #include #include #include -#include #include #include @@ -85,8 +84,6 @@ ((quint32)(ch1)) \ ) -typedef BOOL (WINAPI *PtrGetCharWidthI)(HDC, UINT, UINT, LPWORD, LPINT); - // common DC for all fonts QT_BEGIN_NAMESPACE @@ -130,6 +127,7 @@ HDC shared_dc() static HFONT stock_sysfont = 0; +typedef BOOL (WINAPI *PtrGetCharWidthI)(HDC, UINT, UINT, LPWORD, LPINT); static PtrGetCharWidthI ptrGetCharWidthI = 0; static bool resolvedGetCharWidthI = false; @@ -141,27 +139,6 @@ static void resolveGetCharWidthI() ptrGetCharWidthI = (PtrGetCharWidthI)QLibrary::resolve(QLatin1String("gdi32"), "GetCharWidthI"); } -// Copy a LOGFONTW struct into a LOGFONTA by converting the face name to an 8 bit value. -// This is needed when calling CreateFontIndirect on non-unicode windowses. -inline static void wa_copy_logfont(LOGFONTW *lfw, LOGFONTA *lfa) -{ - lfa->lfHeight = lfw->lfHeight; - lfa->lfWidth = lfw->lfWidth; - lfa->lfEscapement = lfw->lfEscapement; - lfa->lfOrientation = lfw->lfOrientation; - lfa->lfWeight = lfw->lfWeight; - lfa->lfItalic = lfw->lfItalic; - lfa->lfUnderline = lfw->lfUnderline; - lfa->lfCharSet = lfw->lfCharSet; - lfa->lfOutPrecision = lfw->lfOutPrecision; - lfa->lfClipPrecision = lfw->lfClipPrecision; - lfa->lfQuality = lfw->lfQuality; - lfa->lfPitchAndFamily = lfw->lfPitchAndFamily; - - QString fam = QString::fromUtf16((const ushort*)lfw->lfFaceName); - memcpy(lfa->lfFaceName, fam.toLocal8Bit().constData(), fam.length() + 1); -} - // defined in qtextengine_win.cpp typedef void *SCRIPT_CACHE; typedef HRESULT (WINAPI *fScriptFreeCache)(SCRIPT_CACHE *); @@ -187,14 +164,6 @@ static inline quint16 getUShort(unsigned char *p) return val; } -static inline HFONT systemFont() -{ - if (stock_sysfont == 0) - stock_sysfont = (HFONT)GetStockObject(SYSTEM_FONT); - return stock_sysfont; -} - - // general font engine QFixed QFontEngineWin::lineThickness() const @@ -205,33 +174,18 @@ QFixed QFontEngineWin::lineThickness() const return QFontEngine::lineThickness(); } -#if defined(Q_WS_WINCE) -static OUTLINETEXTMETRICW *getOutlineTextMetric(HDC hdc) +static OUTLINETEXTMETRIC *getOutlineTextMetric(HDC hdc) { int size; - size = GetOutlineTextMetricsW(hdc, 0, 0); - OUTLINETEXTMETRICW *otm = (OUTLINETEXTMETRICW *)malloc(size); - GetOutlineTextMetricsW(hdc, size, otm); + size = GetOutlineTextMetrics(hdc, 0, 0); + OUTLINETEXTMETRIC *otm = (OUTLINETEXTMETRIC *)malloc(size); + GetOutlineTextMetrics(hdc, size, otm); return otm; } -#else -static OUTLINETEXTMETRICA *getOutlineTextMetric(HDC hdc) -{ - int size; - size = GetOutlineTextMetricsA(hdc, 0, 0); - OUTLINETEXTMETRICA *otm = (OUTLINETEXTMETRICA *)malloc(size); - GetOutlineTextMetricsA(hdc, size, otm); - return otm; -} -#endif void QFontEngineWin::getCMap() { - QT_WA({ - ttf = (bool)(tm.w.tmPitchAndFamily & TMPF_TRUETYPE); - } , { - ttf = (bool)(tm.a.tmPitchAndFamily & TMPF_TRUETYPE); - }); + ttf = (bool)(tm.tmPitchAndFamily & TMPF_TRUETYPE); HDC hdc = shared_dc(); SelectObject(hdc, hfont); bool symb = false; @@ -249,11 +203,7 @@ void QFontEngineWin::getCMap() designToDevice = 1; _faceId.index = 0; if(cmap) { -#if defined(Q_WS_WINCE) - OUTLINETEXTMETRICW *otm = getOutlineTextMetric(hdc); -#else - OUTLINETEXTMETRICA *otm = getOutlineTextMetric(hdc); -#endif + OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc); designToDevice = QFixed((int)otm->otmEMSquare)/int(otm->otmTextMetrics.tmHeight); unitsPerEm = otm->otmEMSquare; x_height = (int)otm->otmsXHeight; @@ -263,7 +213,7 @@ void QFontEngineWin::getCMap() fsType = otm->otmfsType; free(otm); } else { - unitsPerEm = tm.w.tmHeight; + unitsPerEm = tm.tmHeight; } } @@ -303,19 +253,14 @@ int QFontEngineWin::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout } } else { #endif - ushort first, last; - QT_WA({ - first = tm.w.tmFirstChar; - last = tm.w.tmLastChar; - }, { - first = tm.a.tmFirstChar; - last = tm.a.tmLastChar; - }); + wchar_t first = tm.tmFirstChar; + wchar_t last = tm.tmLastChar; + for (; i < numChars; ++i, ++glyph_pos) { uint ucs = QChar::mirroredChar(getChar(str, i, numChars)); if ( #ifdef Q_WS_WINCE - tm.w.tmFirstChar > 60000 || // see line 375 + tm.tmFirstChar > 60000 || // see line 375 #endif ucs >= first && ucs <= last) glyphs->glyphs[glyph_pos] = ucs; @@ -341,19 +286,14 @@ int QFontEngineWin::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout } } else { #endif - ushort first, last; - QT_WA({ - first = tm.w.tmFirstChar; - last = tm.w.tmLastChar; - }, { - first = tm.a.tmFirstChar; - last = tm.a.tmLastChar; - }); + wchar_t first = tm.tmFirstChar; + wchar_t last = tm.tmLastChar; + for (; i < numChars; ++i, ++glyph_pos) { uint uc = getChar(str, i, numChars); if ( #ifdef Q_WS_WINCE - tm.w.tmFirstChar > 60000 || // see comment in QFontEngineWin + tm.tmFirstChar > 60000 || // see comment in QFontEngineWin #endif uc >= first && uc <= last) glyphs->glyphs[glyph_pos] = uc; @@ -387,28 +327,14 @@ QFontEngineWin::QFontEngineWin(const QString &name, HFONT _hfont, bool stockFont lineWidth = -1; x_height = -1; - BOOL res; - QT_WA({ - res = GetTextMetricsW(hdc, &tm.w); - } , { - res = GetTextMetricsA(hdc, &tm.a); - }); - fontDef.fixedPitch = !(tm.w.tmPitchAndFamily & TMPF_FIXED_PITCH); + BOOL res = GetTextMetrics(hdc, &tm); + fontDef.fixedPitch = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH); if (!res) qErrnoWarning("QFontEngineWin: GetTextMetrics failed"); - cache_cost = tm.w.tmHeight * tm.w.tmAveCharWidth * 2000; + cache_cost = tm.tmHeight * tm.tmAveCharWidth * 2000; getCMap(); - useTextOutA = false; -#ifndef Q_OS_WINCE - // TextOutW doesn't work for symbol fonts on Windows 95! - // since we're using glyph indices we don't care for ttfs about this! - if (QSysInfo::WindowsVersion == QSysInfo::WV_95 && !ttf && - (_name == QLatin1String("Marlett") || _name == QLatin1String("Symbol") || - _name == QLatin1String("Webdings") || _name == QLatin1String("Wingdings"))) - useTextOutA = true; -#endif widthCache = 0; widthCacheSize = 0; designAdvances = 0; @@ -427,7 +353,7 @@ QFontEngineWin::~QFontEngineWin() free(widthCache); // make sure we aren't by accident still selected - SelectObject(shared_dc(), systemFont()); + SelectObject(shared_dc(), (HFONT)GetStockObject(SYSTEM_FONT)); if (!stockFont) { if (!DeleteObject(hfont)) @@ -435,39 +361,12 @@ QFontEngineWin::~QFontEngineWin() } } -HGDIOBJ QFontEngineWin::selectDesignFont(QFixed *overhang) const +HGDIOBJ QFontEngineWin::selectDesignFont() const { LOGFONT f = logfont; f.lfHeight = unitsPerEm; - HFONT designFont; - QT_WA({ - designFont = CreateFontIndirectW(&f); - }, { - LOGFONTA fa; - wa_copy_logfont(&f, &fa); - designFont = CreateFontIndirectA(&fa); - }); - HGDIOBJ oldFont = SelectObject(shared_dc(), designFont); - - if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) { - BOOL res; - QT_WA({ - TEXTMETRICW tm; - res = GetTextMetricsW(shared_dc(), &tm); - if (!res) - qErrnoWarning("QFontEngineWin: GetTextMetrics failed"); - *overhang = QFixed((int)tm.tmOverhang) / designToDevice; - } , { - TEXTMETRICA tm; - res = GetTextMetricsA(shared_dc(), &tm); - if (!res) - qErrnoWarning("QFontEngineWin: GetTextMetrics failed"); - *overhang = QFixed((int)tm.tmOverhang) / designToDevice; - }); - } else { - *overhang = 0; - } - return oldFont; + HFONT designFont = CreateFontIndirect(&f); + return SelectObject(shared_dc(), designFont); } bool QFontEngineWin::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const @@ -486,8 +385,6 @@ bool QFontEngineWin::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph HDC hdc = shared_dc(); if (flags & QTextEngine::DesignMetrics) { HGDIOBJ oldFont = 0; - QFixed overhang = 0; - int glyph_pos = 0; for(register int i = 0; i < len; i++) { bool surrogate = (str[i].unicode() >= 0xd800 && str[i].unicode() < 0xdc00 && i < len-1 @@ -502,9 +399,9 @@ bool QFontEngineWin::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph } if(designAdvances[glyph] < -999999) { if(!oldFont) - oldFont = selectDesignFont(&overhang); + oldFont = selectDesignFont(); SIZE size = {0, 0}; - GetTextExtentPoint32W(hdc, (wchar_t *)(str+i), surrogate ? 2 : 1, &size); + GetTextExtentPoint32(hdc, (wchar_t *)(str+i), surrogate ? 2 : 1, &size); designAdvances[glyph] = QFixed((int)size.cx)/designToDevice; } glyphs->advances_x[glyph_pos] = designAdvances[glyph]; @@ -538,7 +435,7 @@ bool QFontEngineWin::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph SIZE size = {0, 0}; if (!oldFont) oldFont = SelectObject(hdc, hfont); - GetTextExtentPoint32W(hdc, (wchar_t *)str + i, surrogate ? 2 : 1, &size); + GetTextExtentPoint32(hdc, (wchar_t *)str + i, surrogate ? 2 : 1, &size); glyphs->advances_x[glyph_pos] = size.cx; // if glyph's within cache range, store it for later if (size.cx > 0 && size.cx < 0x100) @@ -564,8 +461,6 @@ void QFontEngineWin::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFla HGDIOBJ oldFont = 0; HDC hdc = shared_dc(); if (ttf && (flags & QTextEngine::DesignMetrics)) { - QFixed overhang = 0; - for(int i = 0; i < glyphs->numGlyphs; i++) { unsigned int glyph = glyphs->glyphs[i]; if(int(glyph) >= designAdvancesSize) { @@ -575,35 +470,14 @@ void QFontEngineWin::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFla designAdvances[i] = -1000000; designAdvancesSize = newSize; } - if(designAdvances[glyph] < -999999) { - if(!oldFont) - oldFont = selectDesignFont(&overhang); + if (designAdvances[glyph] < -999999) { + if (!oldFont) + oldFont = selectDesignFont(); - if (ptrGetCharWidthI) { - int width = 0; + int width = 0; + if (ptrGetCharWidthI) ptrGetCharWidthI(hdc, glyph, 1, 0, &width); - - designAdvances[glyph] = QFixed(width) / designToDevice; - } else { -#ifndef Q_WS_WINCE - GLYPHMETRICS gm; - DWORD res = GDI_ERROR; - MAT2 mat; - mat.eM11.value = mat.eM22.value = 1; - mat.eM11.fract = mat.eM22.fract = 0; - mat.eM21.value = mat.eM12.value = 0; - mat.eM21.fract = mat.eM12.fract = 0; - QT_WA({ - res = GetGlyphOutlineW(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX|GGO_NATIVE, &gm, 0, 0, &mat); - } , { - res = GetGlyphOutlineA(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX|GGO_NATIVE, &gm, 0, 0, &mat); - }); - - if (res != GDI_ERROR) { - designAdvances[glyph] = QFixed(gm.gmCellIncX) / designToDevice; - } -#endif - } + designAdvances[glyph] = QFixed(width) / designToDevice; } glyphs->advances_x[i] = designAdvances[glyph]; glyphs->advances_y[i] = 0; @@ -611,8 +485,6 @@ void QFontEngineWin::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFla if(oldFont) DeleteObject(SelectObject(hdc, oldFont)); } else { - int overhang = (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) ? tm.a.tmOverhang : 0; - for(int i = 0; i < glyphs->numGlyphs; i++) { unsigned int glyph = glyphs->glyphs[i]; @@ -640,31 +512,10 @@ void QFontEngineWin::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFla ++chrLen; } SIZE size = {0, 0}; - GetTextExtentPoint32W(hdc, (wchar_t *)ch, chrLen, &size); + GetTextExtentPoint32(hdc, (wchar_t *)ch, chrLen, &size); width = size.cx; } else if (ptrGetCharWidthI) { ptrGetCharWidthI(hdc, glyph, 1, 0, &width); - - width -= overhang; - } else { -#ifndef Q_WS_WINCE - GLYPHMETRICS gm; - DWORD res = GDI_ERROR; - MAT2 mat; - mat.eM11.value = mat.eM22.value = 1; - mat.eM11.fract = mat.eM22.fract = 0; - mat.eM21.value = mat.eM12.value = 0; - mat.eM21.fract = mat.eM12.fract = 0; - QT_WA({ - res = GetGlyphOutlineW(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX, &gm, 0, 0, &mat); - } , { - res = GetGlyphOutlineA(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX, &gm, 0, 0, &mat); - }); - - if (res != GDI_ERROR) { - width = gm.gmCellIncX; - } -#endif } glyphs->advances_x[i] = width; // if glyph's within cache range, store it for later @@ -687,7 +538,7 @@ glyph_metrics_t QFontEngineWin::boundingBox(const QGlyphLayout &glyphs) for (int i = 0; i < glyphs.numGlyphs; ++i) w += glyphs.effectiveAdvance(i); - return glyph_metrics_t(0, -tm.w.tmAscent, w, tm.w.tmHeight, w, 0); + return glyph_metrics_t(0, -tm.tmAscent, w, tm.tmHeight, w, 0); } @@ -705,30 +556,13 @@ glyph_metrics_t QFontEngineWin::boundingBox(glyph_t glyph, const QTransform &t) HDC hdc = shared_dc(); SelectObject(hdc, hfont); - if(!ttf) { - SIZE s = {0, 0}; - WCHAR ch = glyph; - int width; - int overhang = 0; - static bool resolved = false; - if (!resolved) { - QLibrary lib(QLatin1String("gdi32")); - qt_GetCharABCWidthsFloat = (pGetCharABCWidthsFloat) lib.resolve("GetCharABCWidthsFloatW"); - resolved = true; - } - if (QT_WA_INLINE(true, false) && qt_GetCharABCWidthsFloat) { - ABCFLOAT abc; - qt_GetCharABCWidthsFloat(hdc, ch, ch, &abc); - width = qRound(abc.abcfB); - } else { - GetTextExtentPoint32W(hdc, &ch, 1, &s); - overhang = (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) ? tm.a.tmOverhang : 0; - width = s.cx; - } + if (!ttf) { + wchar_t ch = glyph; + ABCFLOAT abc; + GetCharABCWidthsFloat(hdc, ch, ch, &abc); + int width = qRound(abc.abcfB); - return glyph_metrics_t(0, -tm.a.tmAscent, - width, tm.a.tmHeight, - width-overhang, 0).transformed(t); + return glyph_metrics_t(0, -tm.tmAscent, width, tm.tmHeight, width, 0).transformed(t); } else { DWORD res = 0; MAT2 mat; @@ -753,11 +587,8 @@ glyph_metrics_t QFontEngineWin::boundingBox(glyph_t glyph, const QTransform &t) SetWorldTransform(hdc, &xform); } - QT_WA({ - res = GetGlyphOutlineW(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX, &gm, 0, 0, &mat); - } , { - res = GetGlyphOutlineA(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX, &gm, 0, 0, &mat); - }); + res = GetGlyphOutline(hdc, glyph, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, 0, &mat); + if (t.type() > QTransform::TxTranslate) { XFORM xform; xform.eM11 = xform.eM22 = 1; @@ -793,28 +624,28 @@ glyph_metrics_t QFontEngineWin::boundingBox(glyph_t glyph, const QTransform &t) else #endif { // fallback - width = tm.w.tmMaxCharWidth; + width = tm.tmMaxCharWidth; advance = width; } SelectObject(hdc, oldFont); - return glyph_metrics_t(0, -tm.w.tmAscent, width, tm.w.tmHeight, advance, 0).transformed(t); + return glyph_metrics_t(0, -tm.tmAscent, width, tm.tmHeight, advance, 0).transformed(t); #endif } QFixed QFontEngineWin::ascent() const { - return tm.w.tmAscent; + return tm.tmAscent; } QFixed QFontEngineWin::descent() const { - return tm.w.tmDescent; + return tm.tmDescent; } QFixed QFontEngineWin::leading() const { - return tm.w.tmExternalLeading; + return tm.tmExternalLeading; } @@ -827,12 +658,12 @@ QFixed QFontEngineWin::xHeight() const QFixed QFontEngineWin::averageCharWidth() const { - return tm.w.tmAveCharWidth; + return tm.tmAveCharWidth; } qreal QFontEngineWin::maxCharWidth() const { - return tm.w.tmMaxCharWidth; + return tm.tmMaxCharWidth; } enum { max_font_count = 256 }; @@ -879,10 +710,10 @@ qreal QFontEngineWin::minRightBearing() const SelectObject(hdc, hfont); if (ttf) { ABC *abc = 0; - int n = QT_WA_INLINE(tm.w.tmLastChar - tm.w.tmFirstChar, tm.a.tmLastChar - tm.a.tmFirstChar); + int n = tm.tmLastChar - tm.tmFirstChar; if (n <= max_font_count) { abc = new ABC[n+1]; - GetCharABCWidths(hdc, tm.w.tmFirstChar, tm.w.tmLastChar, abc); + GetCharABCWidths(hdc, tm.tmFirstChar, tm.tmLastChar, abc); } else { abc = new ABC[char_table_entries+1]; for(int i = 0; i < char_table_entries; i++) @@ -898,9 +729,6 @@ qreal QFontEngineWin::minRightBearing() const } } delete [] abc; - } else { - ml = 0; - mr = -tm.a.tmOverhang; } lbearing = ml; rbearing = mr; @@ -915,28 +743,14 @@ qreal QFontEngineWin::minRightBearing() const SelectObject(hdc, hfont); if (ttf) { ABC *abc = 0; - int n = QT_WA_INLINE(tm.w.tmLastChar - tm.w.tmFirstChar, tm.a.tmLastChar - tm.a.tmFirstChar); + int n = tm.tmLastChar - tm.tmFirstChar; if (n <= max_font_count) { abc = new ABC[n+1]; - QT_WA({ - GetCharABCWidths(hdc, tm.w.tmFirstChar, tm.w.tmLastChar, abc); - }, { - GetCharABCWidthsA(hdc,tm.a.tmFirstChar,tm.a.tmLastChar,abc); - }); + GetCharABCWidths(hdc, tm.tmFirstChar, tm.tmLastChar, abc); } else { abc = new ABC[char_table_entries+1]; - QT_WA({ - for(int i = 0; i < char_table_entries; i++) - GetCharABCWidths(hdc, char_table[i], char_table[i], abc+i); - }, { - for(int i = 0; i < char_table_entries; i++) { - QByteArray w = QString(QChar(char_table[i])).toLocal8Bit(); - if (w.length() == 1) { - uint ch8 = (uchar)w[0]; - GetCharABCWidthsA(hdc, ch8, ch8, abc+i); - } - } - }); + for(int i = 0; i < char_table_entries; i++) + GetCharABCWidths(hdc, char_table[i], char_table[i], abc + i); n = char_table_entries; } ml = abc[0].abcA; @@ -949,33 +763,28 @@ qreal QFontEngineWin::minRightBearing() const } delete [] abc; } else { - QT_WA({ - ABCFLOAT *abc = 0; - int n = tm.w.tmLastChar - tm.w.tmFirstChar+1; - if (n <= max_font_count) { - abc = new ABCFLOAT[n]; - GetCharABCWidthsFloat(hdc, tm.w.tmFirstChar, tm.w.tmLastChar, abc); - } else { - abc = new ABCFLOAT[char_table_entries]; - for(int i = 0; i < char_table_entries; i++) - GetCharABCWidthsFloat(hdc, char_table[i], char_table[i], abc+i); - n = char_table_entries; - } - float fml = abc[0].abcfA; - float fmr = abc[0].abcfC; - for (int i=1; i string->unicode() || tm.w.tmLastChar < string->unicode()) - return false; - } - }, { - while(len--) { - if (tm.a.tmFirstChar > string->unicode() || tm.a.tmLastChar < string->unicode()) - return false; - } - }); + while(len--) { + if (tm.tmFirstChar > string->unicode() || tm.tmLastChar < string->unicode()) + return false; + } } return true; } @@ -1065,11 +867,7 @@ static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc, memset(&gMetric, 0, sizeof(GLYPHMETRICS)); int bufferSize = GDI_ERROR; #if !defined(Q_WS_WINCE) - QT_WA( { - bufferSize = GetGlyphOutlineW(hdc, glyph, glyphFormat, &gMetric, 0, 0, &mat); - }, { - bufferSize = GetGlyphOutlineA(hdc, glyph, glyphFormat, &gMetric, 0, 0, &mat); - }); + bufferSize = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, 0, 0, &mat); #endif if ((DWORD)bufferSize == GDI_ERROR) { return false; @@ -1078,13 +876,7 @@ static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc, void *dataBuffer = new char[bufferSize]; DWORD ret = GDI_ERROR; #if !defined(Q_WS_WINCE) - QT_WA( { - ret = GetGlyphOutlineW(hdc, glyph, glyphFormat, &gMetric, bufferSize, - dataBuffer, &mat); - }, { - ret = GetGlyphOutlineA(hdc, glyph, glyphFormat, &gMetric, bufferSize, - dataBuffer, &mat); - } ); + ret = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, bufferSize, dataBuffer, &mat); #endif if (ret == GDI_ERROR) { delete [](char *)dataBuffer; @@ -1171,14 +963,7 @@ void QFontEngineWin::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, in // font at the correct pixel size. lf.lfHeight = -unitsPerEm; lf.lfWidth = 0; - HFONT hf; - QT_WA({ - hf = CreateFontIndirectW(&lf); - }, { - LOGFONTA lfa; - wa_copy_logfont(&lf, &lfa); - hf = CreateFontIndirectA(&lfa); - }); + HFONT hf = CreateFontIndirect(&lf); HDC hdc = shared_dc(); HGDIOBJ oldfont = SelectObject(hdc, hf); @@ -1200,7 +985,7 @@ void QFontEngineWin::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyp QPainterPath *path, QTextItem::RenderFlags flags) { #if !defined(Q_WS_WINCE) - if(tm.w.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR)) { + if(tm.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR)) { hasOutline = true; QFontEngine::addOutlineToPath(x, y, glyphs, path, flags); if (hasOutline) { @@ -1234,11 +1019,11 @@ int QFontEngineWin::synthesized() const uchar data[4]; GetFontData(hdc, HEAD, 44, &data, 4); USHORT macStyle = getUShort(data); - if (tm.w.tmItalic && !(macStyle & 2)) + if (tm.tmItalic && !(macStyle & 2)) synthesized_flags = SynthesizedItalic; if (fontDef.stretch != 100 && ttf) synthesized_flags |= SynthesizedStretch; - if (tm.w.tmWeight >= 500 && !(macStyle & 1)) + if (tm.tmWeight >= 500 && !(macStyle & 1)) synthesized_flags |= SynthesizedBold; //qDebug() << "font is" << _name << // "it=" << (macStyle & 2) << fontDef.style << "flags=" << synthesized_flags; @@ -1254,24 +1039,12 @@ QFixed QFontEngineWin::emSquareSize() const QFontEngine::Properties QFontEngineWin::properties() const { - LOGFONT lf = logfont; lf.lfHeight = unitsPerEm; - HFONT hf; - QT_WA({ - hf = CreateFontIndirectW(&lf); - }, { - LOGFONTA lfa; - wa_copy_logfont(&lf, &lfa); - hf = CreateFontIndirectA(&lfa); - }); + HFONT hf = CreateFontIndirect(&lf); HDC hdc = shared_dc(); HGDIOBJ oldfont = SelectObject(hdc, hf); -#if defined(Q_WS_WINCE) - OUTLINETEXTMETRICW *otm = getOutlineTextMetric(hdc); -#else - OUTLINETEXTMETRICA *otm = getOutlineTextMetric(hdc); -#endif + OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc); Properties p; p.emSquare = unitsPerEm; p.italicAngle = otm->otmItalicAngle; @@ -1301,14 +1074,7 @@ void QFontEngineWin::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_m if(flags & SynthesizedItalic) lf.lfItalic = false; lf.lfWidth = 0; - HFONT hf; - QT_WA({ - hf = CreateFontIndirectW(&lf); - }, { - LOGFONTA lfa; - wa_copy_logfont(&lf, &lfa); - hf = CreateFontIndirectA(&lfa); - }); + HFONT hf = CreateFontIndirect(&lf); HDC hdc = shared_dc(); HGDIOBJ oldfont = SelectObject(hdc, hf); QFixedPoint p; @@ -1377,13 +1143,7 @@ QNativeImage *QFontEngineWin::drawGDIGlyph(HFONT font, glyph_t glyph, int margin memset(&mat, 0, sizeof(mat)); mat.eM11.value = mat.eM22.value = 1; - int error = 0; - QT_WA( { - error = GetGlyphOutlineW(hdc, glyph, ggo_options, &tgm, 0, 0, &mat); - }, { - error = GetGlyphOutlineA(hdc, glyph, ggo_options, &tgm, 0, 0, &mat); - } ); - + int error = GetGlyphOutline(hdc, glyph, ggo_options, &tgm, 0, 0, &mat); if (error == GDI_ERROR) { qWarning("QWinFontEngine: unable to query transformed glyph metrics..."); return 0; @@ -1430,11 +1190,11 @@ QNativeImage *QFontEngineWin::drawGDIGlyph(HFONT font, glyph_t glyph, int margin if (has_transformation) { SetGraphicsMode(hdc, GM_ADVANCED); SetWorldTransform(hdc, &xform); - ExtTextOutW(hdc, 0, 0, options, 0, (LPCWSTR) &glyph, 1, 0); + ExtTextOut(hdc, 0, 0, options, 0, (LPCWSTR) &glyph, 1, 0); } else #endif { - ExtTextOutW(hdc, -gx + margin, -gy + margin, options, 0, (LPCWSTR) &glyph, 1, 0); + ExtTextOut(hdc, -gx + margin, -gy + margin, options, 0, (LPCWSTR) &glyph, 1, 0); } SelectObject(hdc, old_font); @@ -1450,7 +1210,7 @@ QImage QFontEngineWin::alphaMapForGlyph(glyph_t glyph, const QTransform &xform) if (qt_cleartype_enabled) { LOGFONT lf = logfont; lf.lfQuality = ANTIALIASED_QUALITY; - font = CreateFontIndirectW(&lf); + font = CreateFontIndirect(&lf); } QImage::Format mask_format = QNativeImage::systemFormat(); #ifndef Q_OS_WINCE @@ -1557,17 +1317,9 @@ void QFontEngineMultiWin::loadEngine(int at) QString fam = fallbacks.at(at-1); LOGFONT lf = static_cast(engines.at(0))->logfont; - HFONT hfont; - QT_WA({ - memcpy(lf.lfFaceName, fam.utf16(), sizeof(TCHAR)*qMin(fam.length()+1,32)); // 32 = Windows hard-coded - hfont = CreateFontIndirectW(&lf); - } , { - // LOGFONTA and LOGFONTW are binary compatible - QByteArray lname = fam.toLocal8Bit(); - memcpy(lf.lfFaceName,lname.data(), - qMin(lname.length()+1,32)); // 32 = Windows hard-coded - hfont = CreateFontIndirectA((LOGFONTA*)&lf); - }); + memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded + HFONT hfont = CreateFontIndirect(&lf); + bool stockFont = false; if (hfont == 0) { hfont = (HFONT)GetStockObject(ANSI_VAR_FONT); diff --git a/src/gui/text/qfontengine_win_p.h b/src/gui/text/qfontengine_win_p.h index a8da78a..b86bd00 100644 --- a/src/gui/text/qfontengine_win_p.h +++ b/src/gui/text/qfontengine_win_p.h @@ -80,7 +80,7 @@ public: virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs, QPainterPath *path, QTextItem::RenderFlags flags); - HGDIOBJ selectDesignFont(QFixed *) const; + HGDIOBJ selectDesignFont() const; virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs); virtual glyph_metrics_t boundingBox(glyph_t g) { return boundingBox(g, QTransform()); } @@ -109,18 +109,14 @@ public: int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs, bool mirrored) const; void getCMap(); - QString _name; - HFONT hfont; + QString _name; + HFONT hfont; LOGFONT logfont; - uint stockFont : 1; - uint useTextOutA : 1; - uint ttf : 1; + uint stockFont : 1; + uint ttf : 1; uint hasOutline : 1; - union { - TEXTMETRICW w; - TEXTMETRICA a; - } tm; - int lw; + TEXTMETRIC tm; + int lw; const unsigned char *cmap; QByteArray cmapTable; mutable qreal lbearing; diff --git a/src/gui/util/qdesktopservices_win.cpp b/src/gui/util/qdesktopservices_win.cpp index 2cc478d..e872617 100644 --- a/src/gui/util/qdesktopservices_win.cpp +++ b/src/gui/util/qdesktopservices_win.cpp @@ -62,33 +62,23 @@ QT_BEGIN_NAMESPACE -//#undef UNICODE - static bool openDocument(const QUrl &file) { if (!file.isValid()) return false; - quintptr returnValue; - QT_WA({ - returnValue = (quintptr)ShellExecute(0, 0, (TCHAR *)file.toString().utf16(), 0, 0, SW_SHOWNORMAL); - } , { - returnValue = (quintptr)ShellExecuteA(0, 0, file.toString().toLocal8Bit().constData(), 0, 0, SW_SHOWNORMAL); - }); + quintptr returnValue = (quintptr)ShellExecute(0, 0, (wchar_t*)file.toString().utf16(), 0, 0, SW_SHOWNORMAL); return (returnValue > 32); //ShellExecute returns a value greater than 32 if successful } static QString expandEnvStrings(const QString &command) { - #if defined(Q_OS_WINCE) return command; #else - QByteArray path = command.toLocal8Bit(); - char commandValue[2 * MAX_PATH] = {0}; - DWORD returnValue = ExpandEnvironmentStringsA(path.data(), commandValue, MAX_PATH); - if (returnValue) - return QString::fromLocal8Bit(commandValue); + wchar_t buffer[MAX_PATH]; + if (ExpandEnvironmentStrings((wchar_t*)command.utf16(), buffer, MAX_PATH)) + return QString::fromWCharArray(buffer); else return command; #endif @@ -129,8 +119,9 @@ static bool launchWebBrowser(const QUrl &url) command = QString::fromRawData((QChar*)keyValue, bufferSize); RegCloseKey(handle); - if(returnValue) + if (returnValue) return false; + command = expandEnvStrings(command); command = command.trimmed(); //Make sure the path for the process is in quotes @@ -152,7 +143,7 @@ static bool launchWebBrowser(const QUrl &url) ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); - returnValue = CreateProcess(NULL, (TCHAR*)command.utf16(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + returnValue = CreateProcess(NULL, (wchar_t*)command.utf16(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); if (!returnValue) return false; @@ -168,9 +159,8 @@ static bool launchWebBrowser(const QUrl &url) if (url.scheme().isEmpty()) return openDocument(url); - quintptr returnValue; - returnValue = (quintptr)ShellExecute(0, 0, (TCHAR *) QString::fromUtf8(url.toEncoded().constData()).utf16(), - 0, 0, SW_SHOWNORMAL); + quintptr returnValue = (quintptr)ShellExecute(0, 0, (wchar_t *)QString::fromUtf8(url.toEncoded().constData()).utf16(), + 0, 0, SW_SHOWNORMAL); return (returnValue > 32); } diff --git a/src/gui/util/qsystemtrayicon_win.cpp b/src/gui/util/qsystemtrayicon_win.cpp index d2ce1be..c1b7e7f 100644 --- a/src/gui/util/qsystemtrayicon_win.cpp +++ b/src/gui/util/qsystemtrayicon_win.cpp @@ -41,8 +41,7 @@ #include "qsystemtrayicon_p.h" #ifndef QT_NO_SYSTEMTRAYICON -//#define _WIN32_IE 0x0500 -#define _WIN32_IE 0x0600 //required for NOTIFYICONDATAW_V2_SIZE +#define _WIN32_IE 0x0600 //required for NOTIFYICONDATA_V2_SIZE //missing defines for MINGW : #ifndef NIN_BALLOONTIMEOUT @@ -77,25 +76,14 @@ static const UINT q_uNOTIFYICONID = 0; static uint MYWM_TASKBARCREATED = 0; #define MYWM_NOTIFYICON (WM_APP+101) -typedef BOOL (WINAPI *PtrShell_NotifyIcon)(DWORD,PNOTIFYICONDATA); -static PtrShell_NotifyIcon ptrShell_NotifyIcon = 0; +struct Q_NOTIFYICONIDENTIFIER { + DWORD cbSize; + HWND hWnd; + UINT uID; + GUID guidItem; +}; -static void resolveLibs() -{ - static bool triedResolve = false; -#if defined Q_OS_WINCE - QString libName(QLatin1String("coredll")); - const char* funcName = "Shell_NotifyIcon"; -#else - QString libName(QLatin1String("shell32")); - const char* funcName = "Shell_NotifyIconW"; -#endif - if (!triedResolve) { - QLibrary lib(libName); - triedResolve = true; - ptrShell_NotifyIcon = (PtrShell_NotifyIcon) lib.resolve(funcName); - } -} +typedef HRESULT (WINAPI *PtrShell_NotifyIconGetRect)(const Q_NOTIFYICONIDENTIFIER* identifier, RECT* iconLocation); class QSystemTrayIconSys : QWidget { @@ -103,37 +91,26 @@ public: QSystemTrayIconSys(QSystemTrayIcon *object); ~QSystemTrayIconSys(); bool winEvent( MSG *m, long *result ); - bool trayMessageA(DWORD msg); - bool trayMessageW(DWORD msg); bool trayMessage(DWORD msg); bool iconDrawItem(LPDRAWITEMSTRUCT lpdi); - void setIconContentsW(NOTIFYICONDATAW &data); - void setIconContentsA(NOTIFYICONDATAA &data); - bool showMessageW(const QString &title, const QString &message, QSystemTrayIcon::MessageIcon type, uint uSecs); - bool showMessageA(const QString &title, const QString &message, QSystemTrayIcon::MessageIcon type, uint uSecs); + void setIconContents(NOTIFYICONDATA &data); + bool showMessage(const QString &title, const QString &message, QSystemTrayIcon::MessageIcon type, uint uSecs); bool allowsMessages(); bool supportsMessages(); QRect findIconGeometry(const int a_iButtonID); - QRect findTrayGeometry(); HBITMAP createIconMask(const QBitmap &bitmap); void createIcon(); - int detectShellVersion() const; HICON hIcon; QPoint globalPos; QSystemTrayIcon *q; private: - uint notifyIconSizeW; - uint notifyIconSizeA; - int currentShellVersion; + uint notifyIconSize; int maxTipLength; }; -// Checks for the shell32 dll version number, since only version -// 5 or later of supports ballon messages bool QSystemTrayIconSys::allowsMessages() { #ifndef QT_NO_SETTINGS - QSettings settings(QLatin1String("HKEY_CURRENT_USER\\Software\\Microsoft" "\\Windows\\CurrentVersion\\Explorer\\Advanced"), QSettings::NativeFormat); return settings.value(QLatin1String("EnableBalloonTips"), true).toBool(); @@ -142,63 +119,28 @@ bool QSystemTrayIconSys::allowsMessages() #endif } -// Checks for the shell32 dll version number, since only version -// 5 or later of supports ballon messages bool QSystemTrayIconSys::supportsMessages() { -#if NOTIFYICON_VERSION >= 3 - if (currentShellVersion >= 5) - return allowsMessages(); - else -#endif - return false; -} - -//Returns the runtime major version of the shell32 dll -int QSystemTrayIconSys::detectShellVersion() const -{ #ifndef Q_OS_WINCE - int shellVersion = 4; //NT 4.0 and W95 - DLLGETVERSIONPROC pDllGetVersion = (DLLGETVERSIONPROC)QLibrary::resolve( - QLatin1String("shell32"), "DllGetVersion"); - if (pDllGetVersion) - { - DLLVERSIONINFO dvi; - HRESULT hr; - ZeroMemory(&dvi, sizeof(dvi)); - dvi.cbSize = sizeof(dvi); - hr = (*pDllGetVersion)(&dvi); - if (SUCCEEDED(hr)) { - if (dvi.dwMajorVersion >= 5) - { - shellVersion = dvi.dwMajorVersion; - } - } - } - return shellVersion; + return allowsMessages(); #endif - return 4; //No ballonMessages and MaxTipLength = 64 for WindowsCE + return false; } QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *object) : hIcon(0), q(object) { - currentShellVersion = detectShellVersion(); - notifyIconSizeA = FIELD_OFFSET(NOTIFYICONDATAA, szTip[64]); // NOTIFYICONDATAA_V1_SIZE - notifyIconSizeW = FIELD_OFFSET(NOTIFYICONDATAW, szTip[64]); // NOTIFYICONDATAW_V1_SIZE; +#ifndef Q_OS_WINCE + notifyIconSize = FIELD_OFFSET(NOTIFYICONDATA, guidItem); // NOTIFYICONDATAW_V2_SIZE; + maxTipLength = 128; +#else + notifyIconSize = FIELD_OFFSET(NOTIFYICONDATA, szTip[64]); // NOTIFYICONDATAW_V1_SIZE; maxTipLength = 64; - -#if NOTIFYICON_VERSION >= 3 - if (currentShellVersion >=5) { - notifyIconSizeA = FIELD_OFFSET(NOTIFYICONDATAA, guidItem); // NOTIFYICONDATAA_V2_SIZE - notifyIconSizeW = FIELD_OFFSET(NOTIFYICONDATAW, guidItem); // NOTIFYICONDATAW_V2_SIZE; - maxTipLength = 128; - } #endif // For restoring the tray icon after explorer crashes if (!MYWM_TASKBARCREATED) { - MYWM_TASKBARCREATED = QT_WA_INLINE(RegisterWindowMessageW(L"TaskbarCreated"),RegisterWindowMessageA("TaskbarCreated")); + MYWM_TASKBARCREATED = RegisterWindowMessage(L"TaskbarCreated"); } } @@ -208,118 +150,60 @@ QSystemTrayIconSys::~QSystemTrayIconSys() DestroyIcon(hIcon); } -void QSystemTrayIconSys::setIconContentsW(NOTIFYICONDATAW &tnd) +void QSystemTrayIconSys::setIconContents(NOTIFYICONDATA &tnd) { - tnd.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP; + tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; tnd.uCallbackMessage = MYWM_NOTIFYICON; tnd.hIcon = hIcon; QString tip = q->toolTip(); if (!tip.isNull()) { - // Tip is limited to maxTipLength - NULL; lstrcpyn appends a NULL terminator. tip = tip.left(maxTipLength - 1) + QChar(); -#if defined(Q_OS_WINCE) - wcsncpy(tnd.szTip, reinterpret_cast (tip.utf16()), qMin(tip.length()+1, maxTipLength)); -#else - lstrcpynW(tnd.szTip, (TCHAR*)tip.utf16(), qMin(tip.length()+1, maxTipLength)); -#endif - } -} - -void QSystemTrayIconSys::setIconContentsA(NOTIFYICONDATAA &tnd) -{ - tnd.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP; - tnd.uCallbackMessage = MYWM_NOTIFYICON; - tnd.hIcon = hIcon; - QString tip = q->toolTip(); - - if (!tip.isNull()) { - // Tip is limited to maxTipLength - NULL; lstrcpyn appends a NULL terminator. - tip = tip.left(maxTipLength - 1) + QChar(); -#if defined(Q_OS_WINCE) - strncpy(tnd.szTip, tip.toLocal8Bit().constData(), qMin(tip.length()+1, maxTipLength)); -#else - lstrcpynA(tnd.szTip, tip.toLocal8Bit().constData(), qMin(tip.length()+1, maxTipLength)); -#endif + memcpy(tnd.szTip, tip.utf16(), qMin(tip.length() + 1, maxTipLength) * sizeof(wchar_t)); } } int iconFlag( QSystemTrayIcon::MessageIcon icon ) { - int flag = 0; #if NOTIFYICON_VERSION >= 3 switch (icon) { - case QSystemTrayIcon::NoIcon: - break; - case QSystemTrayIcon::Critical: - flag = NIIF_ERROR; - break; - case QSystemTrayIcon::Warning: - flag = NIIF_WARNING; - break; case QSystemTrayIcon::Information: - default : // fall through - flag = NIIF_INFO; + return NIIF_INFO; + case QSystemTrayIcon::Warning: + return NIIF_WARNING; + case QSystemTrayIcon::Critical: + return NIIF_ERROR; + case QSystemTrayIcon::NoIcon: + return NIIF_NONE; + default: + Q_ASSERT("Invalid QSystemTrayIcon::MessageIcon value", false); + return NIIF_NONE; } #else Q_UNUSED(icon); + return 0; #endif - return flag; } -bool QSystemTrayIconSys::showMessageW(const QString &title, const QString &message, QSystemTrayIcon::MessageIcon type, uint uSecs) +bool QSystemTrayIconSys::showMessage(const QString &title, const QString &message, QSystemTrayIcon::MessageIcon type, uint uSecs) { -#if NOTIFYICON_VERSION>=3 +#if NOTIFYICON_VERSION >= 3 NOTIFYICONDATA tnd; - memset(&tnd, 0, notifyIconSizeW); + memset(&tnd, 0, notifyIconSize); Q_ASSERT(testAttribute(Qt::WA_WState_Created)); - setIconContentsW(tnd); -#if defined(Q_OS_WINCE) - wcsncpy(tnd.szInfo, message.utf16(), qMin(message.length() + 1, 256)); - wcsncpy(tnd.szInfoTitle, title.utf16(), qMin(title.length()+1, 64)); -#else - lstrcpynW(tnd.szInfo, (TCHAR*)message.utf16(), qMin(message.length() + 1, 256)); - lstrcpynW(tnd.szInfoTitle, (TCHAR*)title.utf16(), qMin(title.length() + 1, 64)); -#endif - tnd.uID = q_uNOTIFYICONID; - tnd.dwInfoFlags = iconFlag(type); - tnd.cbSize = notifyIconSizeW; - tnd.hWnd = winId(); - tnd.uTimeout = uSecs; - tnd.uFlags = NIF_INFO; - return ptrShell_NotifyIcon(NIM_MODIFY, &tnd); -#else - Q_UNUSED(title); - Q_UNUSED(message); - Q_UNUSED(type); - Q_UNUSED(uSecs); - return false; -#endif -} - -bool QSystemTrayIconSys::showMessageA(const QString &title, const QString &message, QSystemTrayIcon::MessageIcon type, uint uSecs) -{ -#if NOTIFYICON_VERSION>=3 - NOTIFYICONDATAA tnd; - memset(&tnd, 0, notifyIconSizeA); - Q_ASSERT(testAttribute(Qt::WA_WState_Created)); + setIconContents(tnd); + memcpy(tnd.szInfo, message.utf16(), qMin(message.length() + 1, 256) * sizeof(wchar_t)); + memcpy(tnd.szInfoTitle, title.utf16(), qMin(title.length() + 1, 64) * sizeof(wchar_t)); - setIconContentsA(tnd); -#if defined(Q_OS_WINCE) - strncpy(tnd.szInfo, message.toLocal8Bit().constData(), qMin(message.length() + 1, 256)); - strncpy(tnd.szInfoTitle, title.toLocal8Bit().constData(), qMin(title.length()+1, 64)); -#else - lstrcpynA(tnd.szInfo, message.toLocal8Bit().constData(), qMin(message.length() + 1, 256)); - lstrcpynA(tnd.szInfoTitle, title.toLocal8Bit().constData(), qMin(title.length() + 1, 64)); -#endif tnd.uID = q_uNOTIFYICONID; tnd.dwInfoFlags = iconFlag(type); - tnd.cbSize = notifyIconSizeA; + tnd.cbSize = notifyIconSize; tnd.hWnd = winId(); tnd.uTimeout = uSecs; tnd.uFlags = NIF_INFO; - return Shell_NotifyIconA(NIM_MODIFY, &tnd); + + return Shell_NotifyIcon(NIM_MODIFY, &tnd); #else Q_UNUSED(title); Q_UNUSED(message); @@ -329,53 +213,21 @@ bool QSystemTrayIconSys::showMessageA(const QString &title, const QString &messa #endif } -bool QSystemTrayIconSys::trayMessageA(DWORD msg) +bool QSystemTrayIconSys::trayMessage(DWORD msg) { -#if !defined(Q_WS_WINCE) - NOTIFYICONDATAA tnd; - memset(&tnd, 0, notifyIconSizeA); + NOTIFYICONDATA tnd; + memset(&tnd, 0, notifyIconSize); tnd.uID = q_uNOTIFYICONID; - tnd.cbSize = notifyIconSizeA; + tnd.cbSize = notifyIconSize; tnd.hWnd = winId(); - Q_ASSERT(testAttribute(Qt::WA_WState_Created)); - if (msg != NIM_DELETE) { - setIconContentsA(tnd); - } - return Shell_NotifyIconA(msg, &tnd); -#else - Q_UNUSED(msg); - return false; -#endif -} - -bool QSystemTrayIconSys::trayMessageW(DWORD msg) -{ - NOTIFYICONDATAW tnd; - memset(&tnd, 0, notifyIconSizeW); - tnd.uID = q_uNOTIFYICONID; - tnd.cbSize = notifyIconSizeW; - tnd.hWnd = winId(); Q_ASSERT(testAttribute(Qt::WA_WState_Created)); if (msg != NIM_DELETE) { - setIconContentsW(tnd); + setIconContents(tnd); } - return ptrShell_NotifyIcon(msg, &tnd); -} -bool QSystemTrayIconSys::trayMessage(DWORD msg) -{ - resolveLibs(); - if (!(ptrShell_NotifyIcon)) - return false; - - QT_WA({ - return trayMessageW(msg); - }, - { - return trayMessageA(msg); - }); + return Shell_NotifyIcon(msg, &tnd); } bool QSystemTrayIconSys::iconDrawItem(LPDRAWITEMSTRUCT lpdi) @@ -514,33 +366,6 @@ void QSystemTrayIconPrivate::install_sys() } } -//fallback on win 95/98 -QRect QSystemTrayIconSys::findTrayGeometry() -{ - //Use lower right corner as fallback - QPoint brCorner = QApplication::desktop()->screenGeometry().bottomRight(); - QRect ret(brCorner.x() - 10, brCorner.y() - 10, 10, 10); -#if defined(Q_OS_WINCE) - HWND trayHandle = FindWindowW(L"Shell_TrayWnd", NULL); -#else - HWND trayHandle = FindWindowA("Shell_TrayWnd", NULL); -#endif - if (trayHandle) { -#if defined(Q_OS_WINCE) - trayHandle = FindWindowW(L"TrayNotifyWnd", NULL); -#else - trayHandle = FindWindowExA(trayHandle, NULL, "TrayNotifyWnd", NULL); -#endif - if (trayHandle) { - RECT r; - if (GetWindowRect(trayHandle, &r)) { - ret = QRect(r.left, r.top, r.right- r.left, r.bottom - r.top); - } - } - } - return ret; -} - /* * This function tries to determine the icon geometry from the tray * @@ -548,26 +373,39 @@ QRect QSystemTrayIconSys::findTrayGeometry() */ QRect QSystemTrayIconSys::findIconGeometry(const int iconId) { + static PtrShell_NotifyIconGetRect Shell_NotifyIconGetRect = + (PtrShell_NotifyIconGetRect)QLibrary::resolve(QLatin1String("shell32"), "Shell_NotifyIconGetRect"); + + if (Shell_NotifyIconGetRect) { + Q_NOTIFYICONIDENTIFIER nid; + memset(&nid, 0, sizeof(nid)); + nid.cbSize = sizeof(nid); + nid.hWnd = winId(); + nid.uID = iconId; + + RECT rect; + HRESULT hr = Shell_NotifyIconGetRect(&nid, &rect); + if (SUCCEEDED(hr)) { + return QRect(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); + } + } + QRect ret; TBBUTTON buttonData; DWORD processID = 0; -#if defined(Q_OS_WINCE) - HWND trayHandle = FindWindowW(L"Shell_TrayWnd", NULL); -#else - HWND trayHandle = FindWindowA("Shell_TrayWnd", NULL); -#endif + HWND trayHandle = FindWindow(L"Shell_TrayWnd", NULL); //find the toolbar used in the notification area if (trayHandle) { #if defined(Q_OS_WINCE) - trayHandle = FindWindowW(L"TrayNotifyWnd", NULL); + trayHandle = FindWindow(L"TrayNotifyWnd", NULL); #else - trayHandle = FindWindowExA(trayHandle, NULL, "TrayNotifyWnd", NULL); + trayHandle = FindWindowEx(trayHandle, NULL, L"TrayNotifyWnd", NULL); #endif if (trayHandle) { #if defined(Q_OS_WINCE) - HWND hwnd = FindWindowW(L"SysPager", NULL); + HWND hwnd = FindWindow(L"SysPager", NULL); #else HWND hwnd = FindWindowEx(trayHandle, NULL, L"SysPager", NULL); #endif @@ -612,10 +450,10 @@ QRect QSystemTrayIconSys::findIconGeometry(const int iconId) DWORD appData[2] = { 0, 0 }; SendMessage(trayHandle, TB_GETBUTTON, toolbarButton , (LPARAM)data); - if(!ReadProcessMemory(trayProcess, data, &buttonData, sizeof(TBBUTTON), &numBytes)) + if (!ReadProcessMemory(trayProcess, data, &buttonData, sizeof(TBBUTTON), &numBytes)) continue; - if(!ReadProcessMemory(trayProcess, (LPVOID) buttonData.dwData, appData, sizeof(appData), &numBytes)) + if (!ReadProcessMemory(trayProcess, (LPVOID) buttonData.dwData, appData, sizeof(appData), &numBytes)) continue; int currentIconId = appData[1]; @@ -646,7 +484,6 @@ QRect QSystemTrayIconSys::findIconGeometry(const int iconId) return ret; } - void QSystemTrayIconPrivate::showMessage_sys(const QString &title, const QString &message, QSystemTrayIcon::MessageIcon type, int timeOut) { if (!sys || !sys->allowsMessages()) @@ -657,8 +494,6 @@ void QSystemTrayIconPrivate::showMessage_sys(const QString &title, const QString uSecs = 10000; //10 sec default else uSecs = (int)timeOut; - resolveLibs(); - //message is limited to 255 chars + NULL QString messageString; if (message.isEmpty() && !title.isEmpty()) @@ -670,20 +505,12 @@ void QSystemTrayIconPrivate::showMessage_sys(const QString &title, const QString QString titleString = title.left(63) + QChar(); if (sys->supportsMessages()) { - QT_WA({ - sys->showMessageW(titleString, messageString, type, (unsigned int)uSecs); - }, { - sys->showMessageA(titleString, messageString, type, (unsigned int)uSecs); - }); + sys->showMessage(titleString, messageString, type, (unsigned int)uSecs); } else { - //use fallbacks - QRect iconPos = sys->findIconGeometry(0); + //use fallback + QRect iconPos = sys->findIconGeometry(q_uNOTIFYICONID); if (iconPos.isValid()) { QBalloonTip::showBalloon(type, title, message, sys->q, iconPos.center(), uSecs, true); - } else { - QRect trayRect = sys->findTrayGeometry(); - QBalloonTip::showBalloon(type, title, message, sys->q, QPoint(trayRect.left(), - trayRect.center().y()), uSecs, false); } } } @@ -692,7 +519,7 @@ QRect QSystemTrayIconPrivate::geometry_sys() const { if (!sys) return QRect(); - return sys->findIconGeometry(0); + return sys->findIconGeometry(q_uNOTIFYICONID); } void QSystemTrayIconPrivate::remove_sys() diff --git a/src/gui/widgets/qeffects.cpp b/src/gui/widgets/qeffects.cpp index 065a2e0..d6d0a16 100644 --- a/src/gui/widgets/qeffects.cpp +++ b/src/gui/widgets/qeffects.cpp @@ -126,10 +126,9 @@ QAlphaWidget::QAlphaWidget(QWidget* w, Qt::WindowFlags f) QAlphaWidget::~QAlphaWidget() { -#ifdef Q_WS_WIN +#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE) // Restore user-defined opacity value - if (widget && QSysInfo::WindowsVersion >= QSysInfo::WV_2000 && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) - widget->setWindowOpacity(windowOpacity); + widget->setWindowOpacity(windowOpacity); #endif } @@ -160,43 +159,40 @@ void QAlphaWidget::run(int time) checkTime.start(); showWidget = true; -#if defined(Q_OS_WIN) - if (QSysInfo::WindowsVersion >= QSysInfo::WV_2000 && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) { - qApp->installEventFilter(this); - widget->setWindowOpacity(0.0); - widget->show(); +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + qApp->installEventFilter(this); + widget->setWindowOpacity(0.0); + widget->show(); + connect(&anim, SIGNAL(timeout()), this, SLOT(render())); + anim.start(1); +#else + //This is roughly equivalent to calling setVisible(true) without actually showing the widget + widget->setAttribute(Qt::WA_WState_ExplicitShowHide, true); + widget->setAttribute(Qt::WA_WState_Hidden, false); + + qApp->installEventFilter(this); + + move(widget->geometry().x(),widget->geometry().y()); + resize(widget->size().width(), widget->size().height()); + + frontImage = QPixmap::grabWidget(widget).toImage(); + backImage = QPixmap::grabWindow(QApplication::desktop()->winId(), + widget->geometry().x(), widget->geometry().y(), + widget->geometry().width(), widget->geometry().height()).toImage(); + + if (!backImage.isNull() && checkTime.elapsed() < duration / 2) { + mixedImage = backImage.copy(); + pm = QPixmap::fromImage(mixedImage); + show(); + setEnabled(false); + connect(&anim, SIGNAL(timeout()), this, SLOT(render())); anim.start(1); - } else -#endif - { - //This is roughly equivalent to calling setVisible(true) without actually showing the widget - widget->setAttribute(Qt::WA_WState_ExplicitShowHide, true); - widget->setAttribute(Qt::WA_WState_Hidden, false); - - qApp->installEventFilter(this); - - move(widget->geometry().x(),widget->geometry().y()); - resize(widget->size().width(), widget->size().height()); - - frontImage = QPixmap::grabWidget(widget).toImage(); - backImage = QPixmap::grabWindow(QApplication::desktop()->winId(), - widget->geometry().x(), widget->geometry().y(), - widget->geometry().width(), widget->geometry().height()).toImage(); - - if (!backImage.isNull() && checkTime.elapsed() < duration / 2) { - mixedImage = backImage.copy(); - pm = QPixmap::fromImage(mixedImage); - show(); - setEnabled(false); - - connect(&anim, SIGNAL(timeout()), this, SLOT(render())); - anim.start(1); - } else { - duration = 0; - render(); - } + } else { + duration = 0; + render(); } +#endif } /* @@ -270,19 +266,17 @@ void QAlphaWidget::render() else alpha = 1; -#if defined(Q_OS_WIN) - if (QSysInfo::WindowsVersion >= QSysInfo::WV_2000 && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) { - if (alpha >= windowOpacity || !showWidget) { - anim.stop(); - qApp->removeEventFilter(this); - widget->setWindowOpacity(windowOpacity); - q_blend = 0; - deleteLater(); - } else { - widget->setWindowOpacity(alpha); - } - } else -#endif +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + if (alpha >= windowOpacity || !showWidget) { + anim.stop(); + qApp->removeEventFilter(this); + widget->setWindowOpacity(windowOpacity); + q_blend = 0; + deleteLater(); + } else { + widget->setWindowOpacity(alpha); + } +#else if (alpha >= 1 || !showWidget) { anim.stop(); qApp->removeEventFilter(this); @@ -292,7 +286,7 @@ void QAlphaWidget::render() #ifdef Q_WS_WIN setEnabled(true); setFocus(); -#endif +#endif // Q_WS_WIN widget->hide(); } else { //Since we are faking the visibility of the widget @@ -309,6 +303,7 @@ void QAlphaWidget::render() pm = QPixmap::fromImage(mixedImage); repaint(); } +#endif // defined(Q_OS_WIN) && !defined(Q_OS_WINCE) } /* diff --git a/src/gui/widgets/qframe.cpp b/src/gui/widgets/qframe.cpp index b9e769d..a87ec85 100644 --- a/src/gui/widgets/qframe.cpp +++ b/src/gui/widgets/qframe.cpp @@ -135,7 +135,7 @@ inline void QFramePrivate::init() \value VLine QFrame draws a vertical line that frames nothing (useful as separator) \value WinPanel draws a rectangular panel that can be raised or - sunken like those in Windows 95. Specifying this shape sets + sunken like those in Windows 2000. Specifying this shape sets the line width to 2 pixels. WinPanel is provided for compatibility. For GUI style independence we recommend using StyledPanel instead. diff --git a/src/gui/widgets/qmdisubwindow.cpp b/src/gui/widgets/qmdisubwindow.cpp index 25bc724..24dea37 100644 --- a/src/gui/widgets/qmdisubwindow.cpp +++ b/src/gui/widgets/qmdisubwindow.cpp @@ -1946,26 +1946,21 @@ QPalette QMdiSubWindowPrivate::desktopPalette() const colorref2qrgb(GetSysColor(COLOR_CAPTIONTEXT))); newPalette.setColor(QPalette::Inactive, QPalette::HighlightedText, colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTIONTEXT))); - if (QSysInfo::WindowsVersion != QSysInfo::WV_95 - && QSysInfo::WindowsVersion != QSysInfo::WV_NT) { - colorsInitialized = true; - BOOL hasGradient; - QT_WA({ - SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &hasGradient, 0); - } , { - SystemParametersInfoA(SPI_GETGRADIENTCAPTIONS, 0, &hasGradient, 0); - }); - if (hasGradient) { - newPalette.setColor(QPalette::Active, QPalette::Base, - colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION))); - newPalette.setColor(QPalette::Inactive, QPalette::Base, - colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION))); - } else { - newPalette.setColor(QPalette::Active, QPalette::Base, - newPalette.color(QPalette::Active, QPalette::Highlight)); - newPalette.setColor(QPalette::Inactive, QPalette::Base, - newPalette.color(QPalette::Inactive, QPalette::Highlight)); - } + + colorsInitialized = true; + BOOL hasGradient = false; + SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &hasGradient, 0); + + if (hasGradient) { + newPalette.setColor(QPalette::Active, QPalette::Base, + colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION))); + newPalette.setColor(QPalette::Inactive, QPalette::Base, + colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION))); + } else { + newPalette.setColor(QPalette::Active, QPalette::Base, + newPalette.color(QPalette::Active, QPalette::Highlight)); + newPalette.setColor(QPalette::Inactive, QPalette::Base, + newPalette.color(QPalette::Inactive, QPalette::Highlight)); } } #endif // Q_WS_WIN diff --git a/src/gui/widgets/qsizegrip.cpp b/src/gui/widgets/qsizegrip.cpp index d263b9c..c6aae68 100644 --- a/src/gui/widgets/qsizegrip.cpp +++ b/src/gui/widgets/qsizegrip.cpp @@ -335,8 +335,7 @@ void QSizeGrip::mousePressEvent(QMouseEvent * e) orientation = d->atLeft() ? SZ_SIZETOPLEFT : SZ_SIZETOPRIGHT; ReleaseCapture(); - QT_WA_INLINE(PostMessageW(tlw->winId(), WM_SYSCOMMAND, orientation, 0), - PostMessageA(tlw->winId(), WM_SYSCOMMAND, orientation, 0)); + PostMessage(tlw->winId(), WM_SYSCOMMAND, orientation, 0); return; } #endif // Q_WS_WIN diff --git a/src/gui/widgets/qworkspace.cpp b/src/gui/widgets/qworkspace.cpp index 58ef1e3..2833c08 100644 --- a/src/gui/widgets/qworkspace.cpp +++ b/src/gui/widgets/qworkspace.cpp @@ -397,21 +397,17 @@ void QWorkspaceTitleBarPrivate::readColors() pal.setColor(QPalette::Inactive, QPalette::Highlight, colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTION))); pal.setColor(QPalette::Active, QPalette::HighlightedText, colorref2qrgb(GetSysColor(COLOR_CAPTIONTEXT))); pal.setColor(QPalette::Inactive, QPalette::HighlightedText, colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTIONTEXT))); - if (QSysInfo::WindowsVersion != QSysInfo::WV_95 && QSysInfo::WindowsVersion != QSysInfo::WV_NT) { - colorsInitialized = true; - BOOL gradient; - QT_WA({ - SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0); - } , { - SystemParametersInfoA(SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0); - }); - if (gradient) { - pal.setColor(QPalette::Active, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION))); - pal.setColor(QPalette::Inactive, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION))); - } else { - pal.setColor(QPalette::Active, QPalette::Base, pal.color(QPalette::Active, QPalette::Highlight)); - pal.setColor(QPalette::Inactive, QPalette::Base, pal.color(QPalette::Inactive, QPalette::Highlight)); - } + + colorsInitialized = true; + BOOL gradient = false; + SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0); + + if (gradient) { + pal.setColor(QPalette::Active, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION))); + pal.setColor(QPalette::Inactive, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION))); + } else { + pal.setColor(QPalette::Active, QPalette::Base, pal.color(QPalette::Active, QPalette::Highlight)); + pal.setColor(QPalette::Inactive, QPalette::Base, pal.color(QPalette::Inactive, QPalette::Highlight)); } } #endif // Q_WS_WIN -- cgit v0.12 From 48406f5ae81fdcb3ba2a01471678d10213a2caa9 Mon Sep 17 00:00:00 2001 From: miniak Date: Wed, 1 Jul 2009 11:49:58 +0200 Subject: src/network: Remove QT_WA and non-Unicode code paths, dropping Win9x and NT support Merge-request: 604 Reviewed-by: Marius Storm-Olsen --- src/network/kernel/qnetworkinterface_win.cpp | 15 +++---- src/network/kernel/qnetworkproxy_win.cpp | 15 +------ src/network/socket/qlocalserver.cpp | 2 - src/network/socket/qlocalserver_win.cpp | 19 ++------- src/network/socket/qlocalsocket.cpp | 2 - src/network/socket/qlocalsocket_win.cpp | 36 +++++----------- src/network/socket/qnativesocketengine_win.cpp | 58 +++++++++++--------------- 7 files changed, 43 insertions(+), 104 deletions(-) diff --git a/src/network/kernel/qnetworkinterface_win.cpp b/src/network/kernel/qnetworkinterface_win.cpp index 0165385..87902c3 100644 --- a/src/network/kernel/qnetworkinterface_win.cpp +++ b/src/network/kernel/qnetworkinterface_win.cpp @@ -66,19 +66,14 @@ static void resolveLibs() if (!done) { done = true; - HINSTANCE iphlpapiHnd; - QT_WA({ - iphlpapiHnd = LoadLibraryW(L"iphlpapi"); - }, { - iphlpapiHnd = LoadLibraryA("iphlpapi"); - }); + HINSTANCE iphlpapiHnd = LoadLibrary(L"iphlpapi"); if (iphlpapiHnd == NULL) - return; // failed to load, probably Windows 95 + return; #if defined(Q_OS_WINCE) - ptrGetAdaptersInfo = (PtrGetAdaptersInfo)GetProcAddressW(iphlpapiHnd, L"GetAdaptersInfo"); - ptrGetAdaptersAddresses = (PtrGetAdaptersAddresses)GetProcAddressW(iphlpapiHnd, L"GetAdaptersAddresses"); - ptrGetNetworkParams = (PtrGetNetworkParams)GetProcAddressW(iphlpapiHnd, L"GetNetworkParams"); + ptrGetAdaptersInfo = (PtrGetAdaptersInfo)GetProcAddress(iphlpapiHnd, L"GetAdaptersInfo"); + ptrGetAdaptersAddresses = (PtrGetAdaptersAddresses)GetProcAddress(iphlpapiHnd, L"GetAdaptersAddresses"); + ptrGetNetworkParams = (PtrGetNetworkParams)GetProcAddress(iphlpapiHnd, L"GetNetworkParams"); #else ptrGetAdaptersInfo = (PtrGetAdaptersInfo)GetProcAddress(iphlpapiHnd, "GetAdaptersInfo"); ptrGetAdaptersAddresses = (PtrGetAdaptersAddresses)GetProcAddress(iphlpapiHnd, "GetAdaptersAddresses"); diff --git a/src/network/kernel/qnetworkproxy_win.cpp b/src/network/kernel/qnetworkproxy_win.cpp index 5fda228..7052bcc2 100644 --- a/src/network/kernel/qnetworkproxy_win.cpp +++ b/src/network/kernel/qnetworkproxy_win.cpp @@ -43,8 +43,6 @@ #ifndef QT_NO_NETWORKPROXY -#if defined(UNICODE) - #include #include #include @@ -269,15 +267,13 @@ void QWindowsSystemProxy::init() if (initialized) return; initialized = true; - if (QSysInfo::windowsVersion() & QSysInfo::WV_DOS_based) - return; // no point, this library is only available on 2k, XP and up #ifdef Q_OS_WINCE // Windows CE does not have any of the following API return; #else // load the winhttp.dll library - HINSTANCE winhttpHnd = LoadLibraryW(L"winhttp"); + HINSTANCE winhttpHnd = LoadLibrary(L"winhttp"); if (!winhttpHnd) return; // failed to load @@ -401,15 +397,6 @@ QList QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro return parseServerList(query, sp->proxyServerList); } -#else // !UNICODE - -QList QNetworkProxyFactory::systemProxyForQuery(const QNetworkProxyQuery &) -{ - return QList() << QNetworkProxy::NoProxy; -} - -#endif - QT_END_NAMESPACE #endif diff --git a/src/network/socket/qlocalserver.cpp b/src/network/socket/qlocalserver.cpp index 05ef2e6..1a50dc4 100644 --- a/src/network/socket/qlocalserver.cpp +++ b/src/network/socket/qlocalserver.cpp @@ -78,8 +78,6 @@ QT_BEGIN_NAMESPACE to use it without one. In that case, you must use waitForNewConnection(), which blocks until either a connection is available or a timeout expires. - Note that this feature is not supported on Windows 9x. - \sa QLocalSocket, QTcpServer */ diff --git a/src/network/socket/qlocalserver_win.cpp b/src/network/socket/qlocalserver_win.cpp index 6af5ca5..c4f8f3c 100644 --- a/src/network/socket/qlocalserver_win.cpp +++ b/src/network/socket/qlocalserver_win.cpp @@ -62,9 +62,8 @@ bool QLocalServerPrivate::addListener() listeners << Listener(); Listener &listener = listeners.last(); - QT_WA({ - listener.handle = CreateNamedPipeW( - (TCHAR*)fullServerName.utf16(), // pipe name + listener.handle = CreateNamedPipe( + (const wchar_t *)fullServerName.utf16(), // pipe name PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, // read/write access PIPE_TYPE_MESSAGE | // message type pipe PIPE_READMODE_MESSAGE | // message-read mode @@ -74,19 +73,7 @@ bool QLocalServerPrivate::addListener() BUFSIZE, // input buffer size 3000, // client time-out NULL); - }, { - listener.handle = CreateNamedPipeA( - fullServerName.toLocal8Bit().constData(), // pipe name - PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, // read/write access - PIPE_TYPE_MESSAGE | // message type pipe - PIPE_READMODE_MESSAGE | // message-read mode - PIPE_WAIT, // blocking mode - PIPE_UNLIMITED_INSTANCES, // max. instances - BUFSIZE, // output buffer size - BUFSIZE, // input buffer size - 3000, // client time-out - NULL); - }); + if (listener.handle == INVALID_HANDLE_VALUE) { setError(QLatin1String("QLocalServerPrivate::addListener")); listeners.removeLast(); diff --git a/src/network/socket/qlocalsocket.cpp b/src/network/socket/qlocalsocket.cpp index acacdf2..c18026b 100644 --- a/src/network/socket/qlocalsocket.cpp +++ b/src/network/socket/qlocalsocket.cpp @@ -63,8 +63,6 @@ QT_BEGIN_NAMESPACE waitForReadyRead(), waitForBytesWritten(), and waitForDisconnected() which blocks until the operation is complete or the timeout expires. - Note that this feature is not supported on Window 9x. - \sa QLocalServer */ diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index 2b8d7e5..b1b69fc 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -137,25 +137,14 @@ void QLocalSocket::connectToServer(const QString &name, OpenMode openMode) forever { DWORD permissions = (openMode & QIODevice::ReadOnly) ? GENERIC_READ : 0; permissions |= (openMode & QIODevice::WriteOnly) ? GENERIC_WRITE : 0; - QT_WA({ - localSocket = CreateFileW( - (TCHAR*)d->fullServerName.utf16(), // pipe name - permissions, - 0, // no sharing - NULL, // default security attributes - OPEN_EXISTING, // opens existing pipe - FILE_FLAG_OVERLAPPED, - NULL); // no template file - }, { - localSocket = CreateFileA( - d->fullServerName.toLocal8Bit().constData(), // pipe name - permissions, - 0, // no sharing - NULL, // default security attributes - OPEN_EXISTING, // opens existing pipe - FILE_FLAG_OVERLAPPED, - NULL); // no template file - }); + localSocket = CreateFile((const wchar_t *)d->fullServerName.utf16(), // pipe name + permissions, + 0, // no sharing + NULL, // default security attributes + OPEN_EXISTING, // opens existing pipe + FILE_FLAG_OVERLAPPED, + NULL); // no template file + if (localSocket != INVALID_HANDLE_VALUE) break; DWORD error = GetLastError(); @@ -165,13 +154,8 @@ void QLocalSocket::connectToServer(const QString &name, OpenMode openMode) } // All pipe instances are busy, so wait until connected or up to 5 seconds. - QT_WA({ - if (!WaitNamedPipeW((TCHAR*)d->fullServerName.utf16(), 5000)) - break; - }, { - if (!WaitNamedPipeA(d->fullServerName.toLocal8Bit().constData(), 5000)) - break; - }); + if (!WaitNamedPipe((const wchar_t *)d->fullServerName.utf16(), 5000)) + break; } if (localSocket == INVALID_HANDLE_VALUE) { diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index 59a3b60..ce8d810 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -918,15 +918,9 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxL int wsaRet = ::WSARecvFrom(socketDescriptor, &buf, 1, &bytesRead, &flags, (struct sockaddr *) &aa, &sz,0,0); if (wsaRet == SOCKET_ERROR) { int err = WSAGetLastError(); - if (err == WSAEMSGSIZE) { - // it is ok the buffer was to small if bytesRead is larger than - // maxLength (win 9x) then assume bytes read is really maxLenth - ret = qint64(bytesRead) > maxLength ? maxLength : qint64(bytesRead); - } else { - WS_ERROR_DEBUG(err); - setError(QAbstractSocket::NetworkError, ReceiveDatagramErrorString); - ret = -1; - } + WS_ERROR_DEBUG(err); + setError(QAbstractSocket::NetworkError, ReceiveDatagramErrorString); + ret = -1; } else { ret = qint64(bytesRead); } @@ -955,36 +949,32 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l qt_socket_setPortAndAddress(socketDescriptor, &sockAddrIPv4, &sockAddrIPv6, port, address, &sockAddrPtr, &sockAddrSize); - if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based && len > qint64(qt_socket_getMaxMsgSize(socketDescriptor))) { - // WSAEMSGSIZE is not reliable enough (win 9x) so we check max size our self. - setError(QAbstractSocket::DatagramTooLargeError, DatagramTooLargeErrorString); - } else { - WSABUF buf; + WSABUF buf; #if !defined(Q_OS_WINCE) - buf.buf = len ? (char*)data : 0; + buf.buf = len ? (char*)data : 0; #else - char tmp; - buf.buf = len ? (char*)data : &tmp; + char tmp; + buf.buf = len ? (char*)data : &tmp; #endif - buf.len = len; - DWORD flags = 0; - DWORD bytesSent = 0; - if (::WSASendTo(socketDescriptor, &buf, 1, &bytesSent, flags, sockAddrPtr, sockAddrSize, 0,0) == SOCKET_ERROR) { - int err = WSAGetLastError(); - WS_ERROR_DEBUG(err); - switch (err) { - case WSAEMSGSIZE: - setError(QAbstractSocket::DatagramTooLargeError, DatagramTooLargeErrorString); - break; - default: - setError(QAbstractSocket::NetworkError, SendDatagramErrorString); - break; - } - ret = -1; - } else { - ret = qint64(bytesSent); + buf.len = len; + DWORD flags = 0; + DWORD bytesSent = 0; + if (::WSASendTo(socketDescriptor, &buf, 1, &bytesSent, flags, sockAddrPtr, sockAddrSize, 0,0) == SOCKET_ERROR) { + int err = WSAGetLastError(); + WS_ERROR_DEBUG(err); + switch (err) { + case WSAEMSGSIZE: + setError(QAbstractSocket::DatagramTooLargeError, DatagramTooLargeErrorString); + break; + default: + setError(QAbstractSocket::NetworkError, SendDatagramErrorString); + break; } + ret = -1; + } else { + ret = qint64(bytesSent); } + #if defined (QNATIVESOCKETENGINE_DEBUG) qDebug("QNativeSocketEnginePrivate::nativeSendDatagram(%p \"%s\", %li, \"%s\", %i) == %li", data, qt_prettyDebug(data, qMin(len, 16), len).data(), 0, address.toString().toLatin1().constData(), -- cgit v0.12 From d4a5ed717ae08034ffbc2377321406720a37bee9 Mon Sep 17 00:00:00 2001 From: miniak Date: Wed, 1 Jul 2009 11:50:01 +0200 Subject: src/opengl: Remove QT_WA and non-Unicode code paths, dropping Win9x and NT support Merge-request: 604 Reviewed-by: Marius Storm-Olsen --- src/opengl/qgl_win.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/opengl/qgl_win.cpp b/src/opengl/qgl_win.cpp index 40b0ce7..86dd1d8 100644 --- a/src/opengl/qgl_win.cpp +++ b/src/opengl/qgl_win.cpp @@ -642,14 +642,10 @@ public: QString windowClassName = qt_getRegisteredWndClass(); if (parent && !parent->internalWinId()) parent = parent->nativeParentWidget(); - QT_WA({ - const TCHAR *cname = (TCHAR*)windowClassName.utf16(); - dmy_id = CreateWindow(cname, 0, 0, 0, 0, 1, 1, - parent ? parent->winId() : 0, 0, qWinAppInst(), 0); - } , { - dmy_id = CreateWindowA(windowClassName.toLatin1(), 0, 0, 0, 0, 1, 1, - parent ? parent->winId() : 0, 0, qWinAppInst(), 0); - }); + + dmy_id = CreateWindow((const wchar_t *)windowClassName.utf16(), + 0, 0, 0, 0, 1, 1, + parent ? parent->winId() : 0, 0, qWinAppInst(), 0); dmy_pdc = GetDC(dmy_id); PIXELFORMATDESCRIPTOR dmy_pfd; -- cgit v0.12 From 5db6c3b72d3c28f55f14883767d29db3441b1b66 Mon Sep 17 00:00:00 2001 From: miniak Date: Wed, 1 Jul 2009 11:50:04 +0200 Subject: src/sql: Remove QT_WA and non-Unicode code paths, dropping Win9x and NT support Also remove many #ifdef UNICODE blocks Merge-request: 604 Reviewed-by: Marius Storm-Olsen --- src/sql/drivers/db2/qsql_db2.cpp | 30 +----------------------------- src/sql/drivers/odbc/qsql_odbc.cpp | 9 +-------- 2 files changed, 2 insertions(+), 37 deletions(-) diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp index 1a82377..e4f564a 100644 --- a/src/sql/drivers/db2/qsql_db2.cpp +++ b/src/sql/drivers/db2/qsql_db2.cpp @@ -51,10 +51,6 @@ #include #include -#ifndef UNICODE -#define UNICODE -#endif - #if defined(Q_CC_BOR) // DB2's sqlsystm.h (included through sqlcli1.h) defines the SQL_BIGINT_TYPE // and SQL_BIGUINT_TYPE to wrong the types for Borland; so do the defines to @@ -111,22 +107,14 @@ public: static QString qFromTChar(SQLTCHAR* str) { -#ifdef UNICODE return QString::fromUtf16(str); -#else - return QString::fromLocal8Bit((const char*) str); -#endif } // dangerous!! (but fast). Don't use in functions that // require out parameters! static SQLTCHAR* qToTChar(const QString& str) { -#ifdef UNICODE return (SQLTCHAR*)str.utf16(); -#else - return (unsigned char*) str.ascii(); -#endif } static QString qWarnDB2Handle(int handleType, SQLHANDLE handle) @@ -347,12 +335,8 @@ static QString qGetStringData(SQLHANDLE hStmt, int column, int colSize, bool& is while (true) { r = SQLGetData(hStmt, - column+1, -#ifdef UNICODE + column + 1, SQL_C_WCHAR, -#else - SQL_C_CHAR, -#endif (SQLPOINTER)buf, colSize * sizeof(SQLTCHAR), &lengthIndicator); @@ -740,7 +724,6 @@ bool QDB2Result::exec() ind); break; } case QVariant::String: -#ifdef UNICODE { QString str(values.at(i).toString()); if (*ind != SQL_NULL_DATA) @@ -774,8 +757,6 @@ bool QDB2Result::exec() } break; } -#endif - // fall through default: { QByteArray ba = values.at(i).toString().toAscii(); int len = ba.length() + 1; @@ -849,12 +830,9 @@ bool QDB2Result::exec() case QVariant::ByteArray: break; case QVariant::String: -#ifdef UNICODE if (bindValueType(i) & QSql::Out) values[i] = QString::fromUtf16((ushort*)tmpStorage.takeFirst().constData()); break; -#endif - // fall through default: { values[i] = QString::fromAscii(tmpStorage.takeFirst().constData()); break; } @@ -1542,13 +1520,7 @@ bool QDB2Driver::hasFeature(DriverFeature f) const case FinishQuery: return true; case Unicode: - // this is the query that shows the codepage for the types: - // select typename, codepage from syscat.datatypes -#ifdef UNICODE return true; -#else - return false; -#endif } return false; } diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index af0c297..c48c7cd 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -1843,14 +1843,7 @@ void QODBCDriverPrivate::checkUnicode() unicode = false; return; #endif -#if defined(Q_WS_WIN) - QT_WA( - {}, - { - unicode = false; - return; - }) -#endif + SQLRETURN r; SQLUINTEGER fFunc; -- cgit v0.12 From 22ab94871c4a924e37eca720a1620da2e1a7259d Mon Sep 17 00:00:00 2001 From: miniak Date: Wed, 1 Jul 2009 11:50:07 +0200 Subject: src/activeqt: Remove QT_WA and non-Unicode code paths, dropping Win9x and NT support Also, buffer sizes passed to Registry APIs were incorrect. Merge-request: 604 Reviewed-by: Marius Storm-Olsen --- src/activeqt/container/qaxbase.cpp | 58 +++++------ src/activeqt/container/qaxdump.cpp | 4 +- src/activeqt/container/qaxobject.cpp | 4 - src/activeqt/container/qaxscript.cpp | 22 ++--- src/activeqt/container/qaxselect.cpp | 34 +++---- src/activeqt/container/qaxwidget.cpp | 56 +++++------ src/activeqt/control/qaxfactory.cpp | 12 +-- src/activeqt/control/qaxserver.cpp | 18 ++-- src/activeqt/control/qaxserverbase.cpp | 173 +++++++++------------------------ src/activeqt/control/qaxserverdll.cpp | 4 +- src/activeqt/control/qaxservermain.cpp | 15 +-- src/activeqt/shared/qaxtypes.cpp | 13 +-- 12 files changed, 147 insertions(+), 266 deletions(-) diff --git a/src/activeqt/container/qaxbase.cpp b/src/activeqt/container/qaxbase.cpp index 62dad6b..4fc9926 100644 --- a/src/activeqt/container/qaxbase.cpp +++ b/src/activeqt/container/qaxbase.cpp @@ -39,10 +39,6 @@ //#define QAX_NO_CLASSINFO -#ifndef UNICODE -#define UNICODE -#endif - #define QT_CHECK_STATE #include "qaxobject.h" @@ -174,7 +170,7 @@ inline DISPID QAxMetaObject::dispIDofName(const QByteArray &name, IDispatch *dis if (dispid == DISPID_UNKNOWN) { // get the Dispatch ID from the object QString unicodeName = QLatin1String(name); - OLECHAR *names = (TCHAR*)unicodeName.utf16(); + OLECHAR *names = (wchar_t*)unicodeName.utf16(); disp->GetIDsOfNames(IID_NULL, &names, 1, LOCALE_USER_DEFAULT, &dispid); if (dispid != DISPID_UNKNOWN) dispIDs.insert(name, dispid); @@ -638,7 +634,7 @@ QByteArray QAxEventSink::findProperty(DISPID dispID) UINT cNames; typeinfo->GetNames(dispID, &names, 1, &cNames); if (cNames) { - propname = QString::fromUtf16((const ushort *)names).toLatin1(); + propname = QString::fromWCharArray(names).toLatin1(); SysFreeString(names); } typeinfo->Release(); @@ -972,7 +968,7 @@ bool QAxBase::setControl(const QString &c) QUuid uuid(search); if (uuid.isNull()) { CLSID clsid; - HRESULT res = CLSIDFromProgID((WCHAR*)c.utf16(), &clsid); + HRESULT res = CLSIDFromProgID((wchar_t*)c.utf16(), &clsid); if (res == S_OK) search = QUuid(clsid).toString(); else { @@ -1137,7 +1133,7 @@ QStringList QAxBase::verbs() const while (enumVerbs->Next(1, &verb, &c) == S_OK) { if (!verb.lpszVerbName) continue; - QString verbName = QString::fromUtf16((const ushort *)verb.lpszVerbName); + QString verbName = QString::fromWCharArray(verb.lpszVerbName); if (!verbName.isEmpty()) d->verbs.insert(verbName, verb.lVerb); } @@ -1265,7 +1261,7 @@ bool QAxBase::initializeLicensedHelper(void *f, const QString &key, IUnknown **p } else if (licinfo.fRuntimeKeyAvail) { BSTR licenseKey; factory2->RequestLicKey(0, &licenseKey); - QString qlicenseKey = QString::fromUtf16((const ushort *)licenseKey); + QString qlicenseKey = QString::fromWCharArray(licenseKey); SysFreeString(licenseKey); qWarning("Use license key is '%s' to create object on unlicensed machine.", qlicenseKey.toLatin1().constData()); @@ -1275,7 +1271,7 @@ bool QAxBase::initializeLicensedHelper(void *f, const QString &key, IUnknown **p if (licinfo.fRuntimeKeyAvail) { BSTR licenseKey; factory2->RequestLicKey(0, &licenseKey); - QString qlicenseKey = QString::fromUtf16((const ushort *)licenseKey); + QString qlicenseKey = QString::fromWCharArray(licenseKey); SysFreeString(licenseKey); if (qlicenseKey != key) @@ -1435,7 +1431,7 @@ bool QAxBase::initializeRemote(IUnknown** ptr) serverInfo.dwReserved1 = 0; serverInfo.dwReserved2 = 0; serverInfo.pAuthInfo = &authInfo; - serverInfo.pwszName = (WCHAR*)server.utf16(); + serverInfo.pwszName = (wchar_t*)server.utf16(); IClassFactory *factory = 0; HRESULT res = CoGetClassObject(QUuid(clsid), CLSCTX_REMOTE_SERVER, &serverInfo, IID_IClassFactory, (void**)&factory); @@ -1747,7 +1743,7 @@ QMetaObject *qax_readInterfaceInfo(ITypeLib *typeLib, ITypeInfo *typeInfo, const if (S_OK != typeInfo->GetDocumentation(-1, &bstr, 0, 0, 0)) return 0; - className = QString::fromUtf16((const ushort *)bstr); + className = QString::fromWCharArray(bstr); SysFreeString(bstr); generator.readEnumInfo(); @@ -1768,7 +1764,7 @@ QMetaObject *qax_readClassInfo(ITypeLib *typeLib, ITypeInfo *classInfo, const QM if (S_OK != classInfo->GetDocumentation(-1, &bstr, 0, 0, 0)) return 0; - className = QString::fromUtf16((const ushort *)bstr); + className = QString::fromWCharArray(bstr); SysFreeString(bstr); generator.readEnumInfo(); @@ -1795,7 +1791,7 @@ QMetaObject *qax_readClassInfo(ITypeLib *typeLib, ITypeInfo *classInfo, const QM continue; interfaceInfo->GetDocumentation(-1, &bstr, 0, 0, 0); - QString interfaceName = QString::fromUtf16((const ushort *)bstr); + QString interfaceName = QString::fromWCharArray(bstr); SysFreeString(bstr); QByteArray key; @@ -1843,7 +1839,7 @@ MetaObjectGenerator::MetaObjectGenerator(ITypeLib *tlib, ITypeInfo *tinfo) typelib->AddRef(); BSTR bstr; typelib->GetDocumentation(-1, &bstr, 0, 0, 0); - current_typelib = QString::fromUtf16((const ushort *)bstr).toLatin1(); + current_typelib = QString::fromWCharArray(bstr).toLatin1(); SysFreeString(bstr); } readClassInfo(); @@ -1891,13 +1887,13 @@ QByteArray MetaObjectGenerator::usertypeToString(const TYPEDESC &tdesc, ITypeInf // get type library name BSTR typelibname = 0; usertypelib->GetDocumentation(-1, &typelibname, 0, 0, 0); - QByteArray typeLibName = QString::fromUtf16((const ushort *)typelibname).toLatin1(); + QByteArray typeLibName = QString::fromWCharArray(typelibname).toLatin1(); SysFreeString(typelibname); // get type name BSTR usertypename = 0; usertypelib->GetDocumentation(index, &usertypename, 0, 0, 0); - QByteArray userTypeName = QString::fromUtf16((const ushort *)usertypename).toLatin1(); + QByteArray userTypeName = QString::fromWCharArray(usertypename).toLatin1(); SysFreeString(usertypename); if (hasEnum(userTypeName)) // known enum? @@ -2287,7 +2283,7 @@ void MetaObjectGenerator::readEnumInfo() BSTR enumname; QByteArray enumName; if (typelib->GetDocumentation(i, &enumname, 0, 0, 0) == S_OK) { - enumName = QString::fromUtf16((const ushort *)enumname).toLatin1(); + enumName = QString::fromWCharArray(enumname).toLatin1(); SysFreeString(enumname); } else { enumName = "enum" + QByteArray::number(++enum_serial); @@ -2310,7 +2306,7 @@ void MetaObjectGenerator::readEnumInfo() UINT maxNamesOut; enuminfo->GetNames(memid, &valuename, 1, &maxNamesOut); if (maxNamesOut) { - valueName = QString::fromUtf16((const ushort *)valuename).toLatin1(); + valueName = QString::fromWCharArray(valuename).toLatin1(); SysFreeString(valuename); } else { valueName = "value" + QByteArray::number(valueindex++); @@ -2467,7 +2463,7 @@ void MetaObjectGenerator::readFuncsInfo(ITypeInfo *typeinfo, ushort nFuncs) QList names; int p; for (p = 0; p < (int)maxNamesOut; ++p) { - names << QString::fromUtf16((const ushort *)bstrNames[p]).toLatin1(); + names << QString::fromWCharArray(bstrNames[p]).toLatin1(); SysFreeString(bstrNames[p]); } @@ -2594,7 +2590,7 @@ void MetaObjectGenerator::readFuncsInfo(ITypeInfo *typeinfo, ushort nFuncs) // get function documentation BSTR bstrDocu; info->GetDocumentation(funcdesc->memid, 0, &bstrDocu, 0, 0); - QString strDocu = QString::fromUtf16((const ushort*)bstrDocu); + QString strDocu = QString::fromWCharArray(bstrDocu); SysFreeString(bstrDocu); if (!!strDocu) desc += '[' + strDocu + ']'; @@ -2641,7 +2637,7 @@ void MetaObjectGenerator::readVarsInfo(ITypeInfo *typeinfo, ushort nVars) QByteArray variableName; uint flags = 0; - variableName = QString::fromUtf16((const ushort *)bstrName).toLatin1(); + variableName = QString::fromWCharArray(bstrName).toLatin1(); SysFreeString(bstrName); // get variable type @@ -2677,7 +2673,7 @@ void MetaObjectGenerator::readVarsInfo(ITypeInfo *typeinfo, ushort nVars) // get function documentation BSTR bstrDocu; info->GetDocumentation(vardesc->memid, 0, &bstrDocu, 0, 0); - QString strDocu = QString::fromUtf16((const ushort*)bstrDocu); + QString strDocu = QString::fromWCharArray(bstrDocu); SysFreeString(bstrDocu); if (!!strDocu) desc += '[' + strDocu + ']'; @@ -2800,7 +2796,7 @@ void MetaObjectGenerator::readEventInterface(ITypeInfo *eventinfo, IConnectionPo QList names; int p; for (p = 0; p < (int)maxNamesOut; ++p) { - names << QString::fromUtf16((const ushort *)bstrNames[p]).toLatin1(); + names << QString::fromWCharArray(bstrNames[p]).toLatin1(); SysFreeString(bstrNames[p]); } @@ -2824,7 +2820,7 @@ void MetaObjectGenerator::readEventInterface(ITypeInfo *eventinfo, IConnectionPo // get function documentation BSTR bstrDocu; eventinfo->GetDocumentation(funcdesc->memid, 0, &bstrDocu, 0, 0); - QString strDocu = QString::fromUtf16((const ushort*)bstrDocu); + QString strDocu = QString::fromWCharArray(bstrDocu); SysFreeString(bstrDocu); if (!!strDocu) desc += '[' + strDocu + ']'; @@ -2982,7 +2978,7 @@ QMetaObject *MetaObjectGenerator::metaObject(const QMetaObject *parentObject, co if (typelib) { BSTR bstr; typelib->GetDocumentation(-1, &bstr, 0, 0, 0); - current_typelib = QString::fromUtf16((const ushort *)bstr).toLatin1(); + current_typelib = QString::fromWCharArray(bstr).toLatin1(); SysFreeString(bstr); } if (d->tryCache && tryCache()) @@ -3391,9 +3387,9 @@ static bool checkHRESULT(HRESULT hres, EXCEPINFO *exc, QAxBase *that, const QStr exc->pfnDeferredFillIn(exc); code = exc->wCode ? exc->wCode : exc->scode; - source = QString::fromUtf16((const ushort *)exc->bstrSource); - desc = QString::fromUtf16((const ushort *)exc->bstrDescription); - help = QString::fromUtf16((const ushort *)exc->bstrHelpFile); + source = QString::fromWCharArray(exc->bstrSource); + desc = QString::fromWCharArray(exc->bstrDescription); + help = QString::fromWCharArray(exc->bstrHelpFile); uint helpContext = exc->dwHelpContext; if (helpContext && !help.isEmpty()) @@ -4228,7 +4224,7 @@ public: if (!var) return E_POINTER; - QString property = QString::fromUtf16((const ushort *)name); + QString property = QString::fromWCharArray(name); QVariant qvar = map.value(property); QVariantToVARIANT(qvar, *var); return S_OK; @@ -4237,7 +4233,7 @@ public: { if (!var) return E_POINTER; - QString property = QString::fromUtf16((const ushort *)name); + QString property = QString::fromWCharArray(name); QVariant qvar = VARIANTToQVariant(*var, 0); map[property] = qvar; diff --git a/src/activeqt/container/qaxdump.cpp b/src/activeqt/container/qaxdump.cpp index 39d5121..a654a8f 100644 --- a/src/activeqt/container/qaxdump.cpp +++ b/src/activeqt/container/qaxdump.cpp @@ -66,8 +66,8 @@ QString qax_docuFromName(ITypeInfo *typeInfo, const QString &name) BSTR docStringBstr, helpFileBstr; ulong helpContext; HRESULT hres = typeInfo->GetDocumentation(memId, 0, &docStringBstr, &helpContext, &helpFileBstr); - QString docString = QString::fromUtf16((const ushort *)docStringBstr); - QString helpFile = QString::fromUtf16((const ushort *)helpFileBstr); + QString docString = QString::fromWCharArray(docStringBstr); + QString helpFile = QString::fromWCharArray(helpFileBstr); SysFreeString(docStringBstr); SysFreeString(helpFileBstr); if (hres == S_OK) { diff --git a/src/activeqt/container/qaxobject.cpp b/src/activeqt/container/qaxobject.cpp index 3526f93..412c5b5 100644 --- a/src/activeqt/container/qaxobject.cpp +++ b/src/activeqt/container/qaxobject.cpp @@ -37,10 +37,6 @@ ** ****************************************************************************/ -#ifndef UNICODE -#define UNICODE -#endif - #include "qaxobject.h" #ifndef QT_NO_WIN_ACTIVEQT diff --git a/src/activeqt/container/qaxscript.cpp b/src/activeqt/container/qaxscript.cpp index dcfc84b..2ee08b3 100644 --- a/src/activeqt/container/qaxscript.cpp +++ b/src/activeqt/container/qaxscript.cpp @@ -37,10 +37,6 @@ ** ****************************************************************************/ -#ifndef UNICODE -#define UNICODE -#endif - #include "qaxscript.h" #ifndef QT_NO_WIN_ACTIVEQT @@ -194,7 +190,7 @@ HRESULT WINAPI QAxScriptSite::GetItemInfo(LPCOLESTR pstrName, DWORD mask, IUnkno else if (mask & SCRIPTINFO_ITYPEINFO) return E_POINTER; - QAxBase *object = script->findObject(QString::fromUtf16((const ushort*)pstrName)); + QAxBase *object = script->findObject(QString::fromWCharArray(pstrName)); if (!object) return TYPE_E_ELEMENTNOTFOUND; @@ -236,9 +232,9 @@ HRESULT WINAPI QAxScriptSite::OnScriptTerminate(const VARIANT *result, const EXC emit script->finished(VARIANTToQVariant(*result, 0)); if (exception) emit script->finished(exception->wCode, - QString::fromUtf16((const ushort*)exception->bstrSource), - QString::fromUtf16((const ushort*)exception->bstrDescription), - QString::fromUtf16((const ushort*)exception->bstrHelpFile) + QString::fromWCharArray(exception->bstrSource), + QString::fromWCharArray(exception->bstrDescription), + QString::fromWCharArray(exception->bstrHelpFile) ); return S_OK; } @@ -287,14 +283,14 @@ HRESULT WINAPI QAxScriptSite::OnScriptError(IActiveScriptError *error) error->GetSourcePosition(&context, &lineNumber, &charPos); HRESULT hres = error->GetSourceLineText(&bstrLineText); if (hres == S_OK) { - lineText = QString::fromUtf16((const ushort*)bstrLineText); + lineText = QString::fromWCharArray(bstrLineText); SysFreeString(bstrLineText); } SysFreeString(exception.bstrSource); SysFreeString(exception.bstrDescription); SysFreeString(exception.bstrHelpFile); - emit script->error(exception.wCode, QString::fromUtf16((const ushort*)exception.bstrDescription), lineNumber, lineText); + emit script->error(exception.wCode, QString::fromWCharArray(exception.bstrDescription), lineNumber, lineText); return S_OK; } @@ -463,7 +459,7 @@ bool QAxScriptEngine::initialize(IUnknown **ptr) return false; CLSID clsid; - HRESULT hres = CLSIDFromProgID((WCHAR*)script_language.utf16(), &clsid); + HRESULT hres = CLSIDFromProgID((wchar_t*)script_language.utf16(), &clsid); if(FAILED(hres)) return false; @@ -609,7 +605,7 @@ void QAxScriptEngine::addItem(const QString &name) if (!engine) return; - engine->AddNamedItem((WCHAR*)name.utf16(), SCRIPTITEM_ISSOURCE|SCRIPTITEM_ISVISIBLE); + engine->AddNamedItem((wchar_t*)name.utf16(), SCRIPTITEM_ISSOURCE|SCRIPTITEM_ISVISIBLE); #endif } @@ -1173,7 +1169,7 @@ bool QAxScriptManager::registerEngine(const QString &name, const QString &extens return false; CLSID clsid; - HRESULT hres = CLSIDFromProgID((WCHAR*)name.utf16(), &clsid); + HRESULT hres = CLSIDFromProgID((wchar_t*)name.utf16(), &clsid); if (hres != S_OK) return false; diff --git a/src/activeqt/container/qaxselect.cpp b/src/activeqt/container/qaxselect.cpp index 5de39e4..a0c725d 100644 --- a/src/activeqt/container/qaxselect.cpp +++ b/src/activeqt/container/qaxselect.cpp @@ -52,54 +52,46 @@ public: : QAbstractListModel(parent) { HKEY classes_key; - QT_WA_INLINE( - RegOpenKeyExW(HKEY_CLASSES_ROOT, L"CLSID", 0, KEY_READ, &classes_key), - RegOpenKeyExA(HKEY_CLASSES_ROOT, "CLSID", 0, KEY_READ, &classes_key)); + RegOpenKeyEx(HKEY_CLASSES_ROOT, L"CLSID", 0, KEY_READ, &classes_key); if (!classes_key) return; DWORD index = 0; LONG result = 0; - TCHAR buffer[256]; - DWORD szBuffer = sizeof(buffer); + wchar_t buffer[256]; + DWORD szBuffer = sizeof(buffer) / sizeof(wchar_t); FILETIME ft; do { - result = QT_WA_INLINE( - RegEnumKeyExW(classes_key, index, (wchar_t*)&buffer, &szBuffer, 0, 0, 0, &ft), - RegEnumKeyExA(classes_key, index, (char*)&buffer, &szBuffer, 0, 0, 0, &ft)); - szBuffer = sizeof(buffer); + result = RegEnumKeyEx(classes_key, index, buffer, &szBuffer, 0, 0, 0, &ft); + szBuffer = sizeof(buffer) / sizeof(wchar_t); if (result == ERROR_SUCCESS) { HKEY sub_key; - QString clsid = QT_WA_INLINE(QString::fromUtf16((ushort*)buffer), QString::fromLocal8Bit((char*)buffer)); - result = QT_WA_INLINE( - RegOpenKeyExW(classes_key, reinterpret_cast(QString(clsid + "\\Control").utf16()), 0, KEY_READ, &sub_key), - RegOpenKeyA(classes_key, QString(clsid + QLatin1String("\\Control")).toLocal8Bit(), &sub_key)); + QString clsid = QString::fromWCharArray(buffer); + result = RegOpenKeyEx(classes_key, reinterpret_cast(QString(clsid + "\\Control").utf16()), 0, KEY_READ, &sub_key); if (result == ERROR_SUCCESS) { RegCloseKey(sub_key); - QT_WA_INLINE( - RegistryQueryValueW(classes_key, buffer, (LPBYTE)buffer, &szBuffer), - RegQueryValueA(classes_key, (char*)buffer, (char*)buffer, (LONG*)&szBuffer)); - QString name = QT_WA_INLINE(QString::fromUtf16((ushort*)buffer, szBuffer / sizeof(TCHAR)) , QString::fromLocal8Bit((char*)buffer, szBuffer)); + RegistryQueryValue(classes_key, buffer, (LPBYTE)buffer, &szBuffer); + QString name = QString::fromWCharArray(buffer); controls << name; clsids.insert(name, clsid); } result = ERROR_SUCCESS; } - szBuffer = sizeof(buffer); + szBuffer = sizeof(buffer) / sizeof(wchar_t); ++index; } while (result == ERROR_SUCCESS); RegCloseKey(classes_key); controls.sort(); } - LONG RegistryQueryValueW(HKEY hKey, LPCWSTR lpSubKey, LPBYTE lpData, LPDWORD lpcbData) + LONG RegistryQueryValue(HKEY hKey, LPCWSTR lpSubKey, LPBYTE lpData, LPDWORD lpcbData) { LONG ret = ERROR_FILE_NOT_FOUND; HKEY hSubKey = NULL; - RegOpenKeyExW(hKey, lpSubKey, 0, KEY_READ, &hSubKey); + RegOpenKeyEx(hKey, lpSubKey, 0, KEY_READ, &hSubKey); if (hSubKey) { - ret = RegQueryValueExW(hSubKey, 0, 0, 0, lpData, lpcbData); + ret = RegQueryValueEx(hSubKey, 0, 0, 0, lpData, lpcbData); RegCloseKey(hSubKey); } return ret; diff --git a/src/activeqt/container/qaxwidget.cpp b/src/activeqt/container/qaxwidget.cpp index ebec872..615887f 100644 --- a/src/activeqt/container/qaxwidget.cpp +++ b/src/activeqt/container/qaxwidget.cpp @@ -37,11 +37,6 @@ ** ****************************************************************************/ -#ifndef UNICODE -#define UNICODE -#endif - - #include "qaxwidget.h" #ifndef QT_NO_WIN_ACTIVEQT @@ -470,7 +465,7 @@ static QAbstractEventDispatcher::EventFilter previous_filter = 0; #if defined(Q_WS_WINCE) static int filter_ref = 0; #else -static const char *qaxatom = "QAxContainer4_Atom"; +static const wchar_t *qaxatom = L"QAxContainer4_Atom"; #endif // The filter procedure listening to user interaction on the control @@ -714,7 +709,7 @@ bool QAxClientSite::activateObject(bool initialized, const QByteArray &data) BSTR userType; HRESULT result = m_spOleObject->GetUserType(USERCLASSTYPE_SHORT, &userType); if (result == S_OK) { - widget->setWindowTitle(QString::fromUtf16((const ushort *)userType)); + widget->setWindowTitle(QString::fromWCharArray(userType)); CoTaskMemFree(userType); } } else { @@ -984,10 +979,7 @@ HRESULT WINAPI QAxClientSite::TranslateAccelerator(LPMSG lpMsg, DWORD /*grfModif eventTranslated = false; if (lpMsg->message == WM_KEYDOWN && !lpMsg->wParam) return S_OK; - QT_WA_INLINE( - SendMessage(host->winId(), lpMsg->message, lpMsg->wParam, lpMsg->lParam), - SendMessageA(host->winId(), lpMsg->message, lpMsg->wParam, lpMsg->lParam) - ); + SendMessage(host->winId(), lpMsg->message, lpMsg->wParam, lpMsg->lParam); return S_OK; } @@ -1173,15 +1165,15 @@ HRESULT WINAPI QAxClientSite::InsertMenus(HMENU /*hmenuShared*/, LPOLEMENUGROUPW #endif } -static int menuItemEntry(HMENU menu, int index, MENUITEMINFOA item, QString &text, QPixmap &/*icon*/) +static int menuItemEntry(HMENU menu, int index, MENUITEMINFO item, QString &text, QPixmap &/*icon*/) { if (item.fType == MFT_STRING && item.cch) { - char *titlebuf = new char[item.cch+1]; + wchar_t *titlebuf = new wchar_t[item.cch + 1]; item.dwTypeData = titlebuf; item.cch++; - ::GetMenuItemInfoA(menu, index, true, &item); - text = QString::fromLocal8Bit(titlebuf); - delete []titlebuf; + ::GetMenuItemInfo(menu, index, true, &item); + text = QString::fromWCharArray(titlebuf); + delete [] titlebuf; return MFT_STRING; } #if 0 @@ -1191,7 +1183,7 @@ static int menuItemEntry(HMENU menu, int index, MENUITEMINFOA item, QString &tex GetBitmapDimensionEx(hbm, &bmsize); QPixmap pixmap(1,1); QSize sz(MAP_LOGHIM_TO_PIX(bmsize.cx, pixmap.logicalDpiX()), - MAP_LOGHIM_TO_PIX(bmsize.cy, pixmap.logicalDpiY())); + MAP_LOGHIM_TO_PIX(bmsize.cy, pixmap.logicalDpiY())); pixmap.resize(bmsize.cx, bmsize.cy); if (!pixmap.isNull()) { @@ -1215,11 +1207,11 @@ QMenu *QAxClientSite::generatePopup(HMENU subMenu, QWidget *parent) if (count) popup = new QMenu(parent); for (int i = 0; i < count; ++i) { - MENUITEMINFOA item; - memset(&item, 0, sizeof(MENUITEMINFOA)); - item.cbSize = sizeof(MENUITEMINFOA); + MENUITEMINFO item; + memset(&item, 0, sizeof(MENUITEMINFO)); + item.cbSize = sizeof(MENUITEMINFO); item.fMask = MIIM_ID | MIIM_TYPE | MIIM_SUBMENU; - ::GetMenuItemInfoA(subMenu, i, true, &item); + ::GetMenuItemInfo(subMenu, i, true, &item); QAction *action = 0; QMenu *popupMenu = 0; @@ -1295,11 +1287,11 @@ HRESULT WINAPI QAxClientSite::SetMenu(HMENU hmenuShared, HOLEMENU holemenu, HWND int count = GetMenuItemCount(hmenuShared); for (int i = 0; i < count; ++i) { - MENUITEMINFOA item; - memset(&item, 0, sizeof(MENUITEMINFOA)); - item.cbSize = sizeof(MENUITEMINFOA); + MENUITEMINFO item; + memset(&item, 0, sizeof(MENUITEMINFO)); + item.cbSize = sizeof(MENUITEMINFO); item.fMask = MIIM_ID | MIIM_TYPE | MIIM_SUBMENU; - ::GetMenuItemInfoA(hmenuShared, i, true, &item); + ::GetMenuItemInfo(hmenuShared, i, true, &item); QAction *action = 0; QMenu *popupMenu = 0; @@ -1379,7 +1371,7 @@ int QAxClientSite::qt_metacall(QMetaObject::Call call, int isignal, void **argv) OleMenuItem oleItem = menuItemMap.value(action); if (oleItem.hMenu) - ::PostMessageA(m_menuOwner, WM_COMMAND, oleItem.id, 0); + ::PostMessage(m_menuOwner, WM_COMMAND, oleItem.id, 0); return -1; #endif } @@ -1404,7 +1396,7 @@ HRESULT WINAPI QAxClientSite::RemoveMenus(HMENU /*hmenuShared*/) HRESULT WINAPI QAxClientSite::SetStatusText(LPCOLESTR pszStatusText) { - QStatusTipEvent tip(QString::fromUtf16((const ushort *)(BSTR)pszStatusText)); + QStatusTipEvent tip(QString::fromWCharArray(pszStatusText)); QApplication::sendEvent(widget, &tip); return S_OK; } @@ -1513,7 +1505,7 @@ HRESULT WINAPI QAxClientSite::SetActiveObject(IOleInPlaceActiveObject *pActiveOb AX_DEBUG(QAxClientSite::SetActiveObject); if (pszObjName && widget) - widget->setWindowTitle(QString::fromUtf16((const ushort *)(BSTR)pszObjName)); + widget->setWindowTitle(QString::fromWCharArray(pszObjName)); if (m_spInPlaceActiveObject) { if (!inPlaceModelessEnabled) @@ -1952,12 +1944,12 @@ bool QAxWidget::createHostWindow(bool initialized, const QByteArray &data) container->activateObject(initialized, data); #if !defined(Q_OS_WINCE) - ATOM filter_ref = FindAtomA(qaxatom); + ATOM filter_ref = FindAtom(qaxatom); #endif if (!filter_ref) previous_filter = QAbstractEventDispatcher::instance()->setEventFilter(axc_FilterProc); #if !defined(Q_OS_WINCE) - AddAtomA(qaxatom); + AddAtom(qaxatom); #else ++filter_ref; #endif @@ -1992,10 +1984,10 @@ void QAxWidget::clear() return; if (!control().isEmpty()) { #if !defined(Q_OS_WINCE) - ATOM filter_ref = FindAtomA(qaxatom); + ATOM filter_ref = FindAtom(qaxatom); if (filter_ref) DeleteAtom(filter_ref); - filter_ref = FindAtomA(qaxatom); + filter_ref = FindAtom(qaxatom); if (!filter_ref) { #else if (!filter_ref && !--filter_ref) { diff --git a/src/activeqt/control/qaxfactory.cpp b/src/activeqt/control/qaxfactory.cpp index c65fbb8..742e93e 100644 --- a/src/activeqt/control/qaxfactory.cpp +++ b/src/activeqt/control/qaxfactory.cpp @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE -extern char qAxModuleFilename[MAX_PATH]; +extern wchar_t qAxModuleFilename[MAX_PATH]; /*! \class QAxFactory @@ -277,7 +277,7 @@ bool QAxFactory::validateLicenseKey(const QString &key, const QString &licenseKe return true; if (licenseKey.isEmpty()) { - QString licFile(QFile::decodeName(qAxModuleFilename)); + QString licFile(QString::fromWCharArray(qAxModuleFilename)); int lastDot = licFile.lastIndexOf(QLatin1Char('.')); licFile = licFile.left(lastDot) + QLatin1String(".lic"); if (QFile::exists(licFile)) @@ -360,7 +360,7 @@ bool QAxFactory::isServer() return qAxIsServer; } -extern char qAxModuleFilename[MAX_PATH]; +extern wchar_t qAxModuleFilename[MAX_PATH]; /*! Returns the directory that contains the server binary. @@ -372,7 +372,7 @@ extern char qAxModuleFilename[MAX_PATH]; */ QString QAxFactory::serverDirPath() { - return QFileInfo(QString::fromLocal8Bit(qAxModuleFilename)).absolutePath(); + return QFileInfo(QString::fromWCharArray(qAxModuleFilename)).absolutePath(); } /*! @@ -384,7 +384,7 @@ QString QAxFactory::serverDirPath() */ QString QAxFactory::serverFilePath() { - return QString::fromLocal8Bit(qAxModuleFilename); + return QString::fromWCharArray(qAxModuleFilename); } /*! @@ -492,7 +492,7 @@ bool QAxFactory::registerActiveObject(QObject *object) if (qstricmp(object->metaObject()->classInfo(object->metaObject()->indexOfClassInfo("RegisterObject")).value(), "yes")) return false; - if (!QString::fromLocal8Bit(qAxModuleFilename).toLower().endsWith(QLatin1String(".exe"))) + if (!QString::fromWCharArray(qAxModuleFilename).toLower().endsWith(QLatin1String(".exe"))) return false; ActiveObject *active = new ActiveObject(object, qAxFactory()); diff --git a/src/activeqt/control/qaxserver.cpp b/src/activeqt/control/qaxserver.cpp index a9b3271..e6b0c17 100644 --- a/src/activeqt/control/qaxserver.cpp +++ b/src/activeqt/control/qaxserver.cpp @@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE bool qAxIsServer = false; HANDLE qAxInstance = 0; ITypeLib *qAxTypeLibrary = 0; -char qAxModuleFilename[MAX_PATH]; +wchar_t qAxModuleFilename[MAX_PATH]; bool qAxOutProcServer = false; // The QAxFactory instance @@ -116,19 +116,19 @@ QString qAxInit() InitializeCriticalSection(&qAxModuleSection); - libFile = QString::fromLocal8Bit(qAxModuleFilename); + libFile = QString::fromWCharArray(qAxModuleFilename); libFile = libFile.toLower(); - if (LoadTypeLibEx((TCHAR*)libFile.utf16(), REGKIND_NONE, &qAxTypeLibrary) == S_OK) + if (LoadTypeLibEx((wchar_t*)libFile.utf16(), REGKIND_NONE, &qAxTypeLibrary) == S_OK) return libFile; int lastDot = libFile.lastIndexOf(QLatin1Char('.')); libFile = libFile.left(lastDot) + QLatin1String(".tlb"); - if (LoadTypeLibEx((TCHAR*)libFile.utf16(), REGKIND_NONE, &qAxTypeLibrary) == S_OK) + if (LoadTypeLibEx((wchar_t*)libFile.utf16(), REGKIND_NONE, &qAxTypeLibrary) == S_OK) return libFile; lastDot = libFile.lastIndexOf(QLatin1Char('.')); libFile = libFile.left(lastDot) + QLatin1String(".olb"); - if (LoadTypeLibEx((TCHAR*)libFile.utf16(), REGKIND_NONE, &qAxTypeLibrary) == S_OK) + if (LoadTypeLibEx((wchar_t*)libFile.utf16(), REGKIND_NONE, &qAxTypeLibrary) == S_OK) return libFile; libFile = QString(); @@ -207,7 +207,7 @@ QString qax_clean_type(const QString &type, const QMetaObject *mo) HRESULT UpdateRegistry(BOOL bRegister) { qAxIsServer = false; - QString file = QString::fromLocal8Bit(qAxModuleFilename); + QString file = QString::fromWCharArray(qAxModuleFilename); QString path = file.left(file.lastIndexOf(QLatin1Char('\\'))+1); QString module = file.right(file.length() - path.length()); module = module.left(module.lastIndexOf(QLatin1Char('.'))); @@ -229,7 +229,7 @@ HRESULT UpdateRegistry(BOOL bRegister) typeLibVersion = QString::number((uint)major) + QLatin1Char('.') + QString::number((uint)minor); if (bRegister) - RegisterTypeLib(qAxTypeLibrary, (TCHAR*)libFile.utf16(), 0); + RegisterTypeLib(qAxTypeLibrary, (wchar_t*)libFile.utf16(), 0); else UnRegisterTypeLib(libAttr->guid, libAttr->wMajorVerNum, libAttr->wMinorVerNum, libAttr->lcid, libAttr->syskind); @@ -1071,7 +1071,7 @@ extern "C" HRESULT __stdcall DumpIDL(const QString &outfile, const QString &ver) QFile file(outfile); file.remove(); - QString filebase = QString::fromLocal8Bit(qAxModuleFilename); + QString filebase = QString::fromWCharArray(qAxModuleFilename); filebase = filebase.left(filebase.lastIndexOf(QLatin1Char('.'))); QString appID = qAxFactory()->appID().toString().toUpper(); @@ -1107,7 +1107,7 @@ extern "C" HRESULT __stdcall DumpIDL(const QString &outfile, const QString &ver) out << "/****************************************************************************" << endl; out << "** Interface definition generated for ActiveQt project" << endl; out << "**" << endl; - out << "** '" << qAxModuleFilename << '\'' << endl; + out << "** '" << QString::fromWCharArray(qAxModuleFilename) << '\'' << endl; out << "**" << endl; out << "** Created: " << QDateTime::currentDateTime().toString() << endl; out << "**" << endl; diff --git a/src/activeqt/control/qaxserverbase.cpp b/src/activeqt/control/qaxserverbase.cpp index 2cac004..d7a8e07 100644 --- a/src/activeqt/control/qaxserverbase.cpp +++ b/src/activeqt/control/qaxserverbase.cpp @@ -788,17 +788,9 @@ bool qax_winEventFilter(void *message) QAxServerBase *axbase = 0; while (!axbase && baseHwnd) { #ifdef GWLP_USERDATA - QT_WA({ - axbase = (QAxServerBase*)GetWindowLongPtrW(baseHwnd, GWLP_USERDATA); - }, { - axbase = (QAxServerBase*)GetWindowLongPtrA(baseHwnd, GWLP_USERDATA); - }); + axbase = (QAxServerBase*)GetWindowLongPtr(baseHwnd, GWLP_USERDATA); #else - QT_WA({ - axbase = (QAxServerBase*)GetWindowLongW(baseHwnd, GWL_USERDATA); - }, { - axbase = (QAxServerBase*)GetWindowLongA(baseHwnd, GWL_USERDATA); - }); + axbase = (QAxServerBase*)GetWindowLong(baseHwnd, GWL_USERDATA); #endif baseHwnd = ::GetParent(baseHwnd); @@ -905,11 +897,7 @@ public: // hook into eventloop; this allows a server to create his own QApplication object if (!qax_hhook && qax_ownQApp) { - QT_WA({ - qax_hhook = SetWindowsHookExW(WH_GETMESSAGE, axs_FilterProc, 0, GetCurrentThreadId()); - }, { - qax_hhook = SetWindowsHookExA(WH_GETMESSAGE, axs_FilterProc, 0, GetCurrentThreadId()); - }); + qax_hhook = SetWindowsHookEx(WH_GETMESSAGE, axs_FilterProc, 0, GetCurrentThreadId()); } HRESULT res; @@ -983,7 +971,7 @@ public: HRESULT WINAPI CreateInstanceLic(IUnknown *pUnkOuter, IUnknown *pUnkReserved, REFIID iid, BSTR bKey, PVOID *ppObject) { - QString licenseKey = QString::fromUtf16((const ushort *)bKey); + QString licenseKey = QString::fromWCharArray(bKey); if (!qAxFactory()->validateLicenseKey(className, licenseKey)) return CLASS_E_NOTLICENSED; return CreateInstanceHelper(pUnkOuter, iid, ppObject); @@ -1303,15 +1291,11 @@ bool QAxServerBase::internalCreate() internalBind(); if (isWidget) { - if (!stayTopLevel) { - QEvent e(QEvent::EmbeddingControl); - QApplication::sendEvent(qt.widget, &e); - QT_WA({ - ::SetWindowLongW(qt.widget->winId(), GWL_STYLE, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); - }, { - ::SetWindowLongA(qt.widget->winId(), GWL_STYLE, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); - }); - } + if (!stayTopLevel) { + QEvent e(QEvent::EmbeddingControl); + QApplication::sendEvent(qt.widget, &e); + ::SetWindowLong(qt.widget->winId(), GWL_STYLE, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); + } qt.widget->setAttribute(Qt::WA_QuitOnClose, false); qt.widget->move(0, 0); @@ -1368,52 +1352,26 @@ class HackWidget : public QWidget LRESULT CALLBACK QAxServerBase::ActiveXProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_CREATE) { - QAxServerBase *that; - QT_WA({ - CREATESTRUCTW *cs = (CREATESTRUCTW*)lParam; - that = (QAxServerBase*)cs->lpCreateParams; - }, { - CREATESTRUCTA *cs = (CREATESTRUCTA*)lParam; - that = (QAxServerBase*)cs->lpCreateParams; - }); + CREATESTRUCT *cs = (CREATESTRUCT*)lParam; + QAxServerBase *that = (QAxServerBase*)cs->lpCreateParams; #ifdef GWLP_USERDATA - QT_WA({ - SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)that); - }, { - SetWindowLongPtrA(hWnd, GWLP_USERDATA, (LONG_PTR)that); - }); + SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)that); #else - QT_WA({ - SetWindowLongW(hWnd, GWL_USERDATA, (LONG)that); - }, { - SetWindowLongA(hWnd, GWL_USERDATA, (LONG)that); - }); + SetWindowLong(hWnd, GWL_USERDATA, (LONG)that); #endif - that->m_hWnd = hWnd; + that->m_hWnd = hWnd; - QT_WA({ - return ::DefWindowProcW(hWnd, uMsg, wParam, lParam); - }, { - return ::DefWindowProcA(hWnd, uMsg, wParam, lParam); - }); + return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } QAxServerBase *that = 0; #ifdef GWLP_USERDATA - QT_WA({ - that = (QAxServerBase*)GetWindowLongPtrW(hWnd, GWLP_USERDATA); - }, { - that = (QAxServerBase*)GetWindowLongPtrA(hWnd, GWLP_USERDATA); - }); + that = (QAxServerBase*)GetWindowLongPtr(hWnd, GWLP_USERDATA); #else - QT_WA({ - that = (QAxServerBase*)GetWindowLongW(hWnd, GWL_USERDATA); - }, { - that = (QAxServerBase*)GetWindowLongA(hWnd, GWL_USERDATA); - }); + that = (QAxServerBase*)GetWindowLong(hWnd, GWL_USERDATA); #endif if (that) { @@ -1563,11 +1521,7 @@ LRESULT CALLBACK QAxServerBase::ActiveXProc(HWND hWnd, UINT uMsg, WPARAM wParam, } } - QT_WA({ - return ::DefWindowProcW(hWnd, uMsg, wParam, lParam); - }, { - return ::DefWindowProcA(hWnd, uMsg, wParam, lParam); - }); + return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } /*! @@ -1583,54 +1537,29 @@ HWND QAxServerBase::create(HWND hWndParent, RECT& rcPos) QString cn(QLatin1String("QAxControl")); cn += QString::number((int)ActiveXProc); if (!atom) { - QT_WA({ - WNDCLASSW wcTemp; - wcTemp.style = CS_DBLCLKS; - wcTemp.cbClsExtra = 0; - wcTemp.cbWndExtra = 0; - wcTemp.hbrBackground = 0; - wcTemp.hCursor = 0; - wcTemp.hIcon = 0; - wcTemp.hInstance = hInst; - wcTemp.lpszClassName = (wchar_t*)cn.utf16(); - wcTemp.lpszMenuName = 0; - wcTemp.lpfnWndProc = ActiveXProc; - - atom = RegisterClassW(&wcTemp); - }, { - QByteArray cna = cn.toLatin1(); - WNDCLASSA wcTemp; - wcTemp.style = CS_DBLCLKS; - wcTemp.cbClsExtra = 0; - wcTemp.cbWndExtra = 0; - wcTemp.hbrBackground = 0; - wcTemp.hCursor = 0; - wcTemp.hIcon = 0; - wcTemp.hInstance = hInst; - wcTemp.lpszClassName = cna.data(); - wcTemp.lpszMenuName = 0; - wcTemp.lpfnWndProc = ActiveXProc; - - atom = RegisterClassA(&wcTemp); - }); + WNDCLASS wcTemp; + wcTemp.style = CS_DBLCLKS; + wcTemp.cbClsExtra = 0; + wcTemp.cbWndExtra = 0; + wcTemp.hbrBackground = 0; + wcTemp.hCursor = 0; + wcTemp.hIcon = 0; + wcTemp.hInstance = hInst; + wcTemp.lpszClassName = (wchar_t*)cn.utf16(); + wcTemp.lpszMenuName = 0; + wcTemp.lpfnWndProc = ActiveXProc; + + atom = RegisterClass(&wcTemp); } LeaveCriticalSection(&createWindowSection); if (!atom && GetLastError() != ERROR_CLASS_ALREADY_EXISTS) return 0; Q_ASSERT(!m_hWnd); - HWND hWnd = 0; - QT_WA({ - hWnd = ::CreateWindowW((wchar_t*)cn.utf16(), 0, - WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, - rcPos.left, rcPos.top, rcPos.right - rcPos.left, - rcPos.bottom - rcPos.top, hWndParent, 0, hInst, this); - }, { - hWnd = ::CreateWindowA(cn.toLatin1().data(), 0, - WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, - rcPos.left, rcPos.top, rcPos.right - rcPos.left, - rcPos.bottom - rcPos.top, hWndParent, 0, hInst, this); - }); + HWND hWnd = ::CreateWindow((wchar_t*)cn.utf16(), 0, + WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, + rcPos.left, rcPos.top, rcPos.right - rcPos.left, + rcPos.bottom - rcPos.top, hWndParent, 0, hInst, this); Q_ASSERT(m_hWnd == hWnd); @@ -1676,11 +1605,7 @@ HMENU QAxServerBase::createPopup(QMenu *popup, HMENU oldMenu) actionMap.remove(itemId); actionMap.insert(itemId, action); } - QT_WA({ - AppendMenuW(popupMenu, flags, itemId, (TCHAR*)action->text().utf16()); - }, { - AppendMenuA(popupMenu, flags, itemId, action->text().toLocal8Bit()); - }); + AppendMenu(popupMenu, flags, itemId, (const wchar_t *)action->text().utf16()); } if (oldMenu) DrawMenuBar(hwndMenuOwner); @@ -1726,11 +1651,7 @@ void QAxServerBase::createMenu(QMenuBar *menuBar) itemId = static_cast(reinterpret_cast(action)); actionMap.insert(itemId, action); } - QT_WA({ - AppendMenuW(hmenuShared, flags, itemId, (TCHAR*)action->text().utf16()); - } , { - AppendMenuA(hmenuShared, flags, itemId, action->text().toLocal8Bit()); - }); + AppendMenu(hmenuShared, flags, itemId, (const wchar_t *)action->text().utf16()); } OLEMENUGROUPWIDTHS menuWidths = {0,edit,0,object,0,help}; @@ -2397,7 +2318,7 @@ HRESULT WINAPI QAxServerBase::Invoke(DISPID dispidMember, REFIID riid, if (!cname) return res; - name = QString::fromUtf16((const ushort *)bname).toLatin1(); + name = QString::fromWCharArray(bname).toLatin1(); SysFreeString(bname); } } @@ -2799,7 +2720,7 @@ HRESULT WINAPI QAxServerBase::Load(IStream *pStm) bool openAsText = false; QByteArray qtarray; if (hres == S_OK) { - QString streamName = QString::fromUtf16((const ushort *)stat.pwcsName); + QString streamName = QString::fromWCharArray(stat.pwcsName); CoTaskMemFree(stat.pwcsName); openAsText = streamName == QLatin1String("SomeStreamName"); if (stat.cbSize.HighPart) // more than 4GB - too large! @@ -2940,7 +2861,7 @@ HRESULT WINAPI QAxServerBase::Load(IStorage *pStg) */ streamName += QLatin1String("_Stream4.2"); - pStg->OpenStream((const WCHAR *)streamName.utf16(), 0, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &spStream); + pStg->OpenStream((const wchar_t *)streamName.utf16(), 0, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &spStream); if (!spStream) // support for streams saved with 4.1 and earlier pStg->OpenStream(L"SomeStreamName", 0, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &spStream); if (!spStream) @@ -2963,7 +2884,7 @@ HRESULT WINAPI QAxServerBase::Save(IStorage *pStg, BOOL fSameAsLoad) */ streamName += QLatin1String("_Stream4.2"); - pStg->CreateStream((const WCHAR *)streamName.utf16(), STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &spStream); + pStg->CreateStream((const wchar_t *)streamName.utf16(), STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &spStream); if (!spStream) return E_FAIL; @@ -3079,7 +3000,7 @@ HRESULT WINAPI QAxServerBase::SaveCompleted(LPCOLESTR fileName) if (qt.object->metaObject()->indexOfClassInfo("MIME") == -1) return E_NOTIMPL; - currentFileName = QString::fromUtf16(reinterpret_cast(fileName)); + currentFileName = QString::fromWCharArray(fileName); return S_OK; } @@ -3097,7 +3018,7 @@ HRESULT WINAPI QAxServerBase::GetCurFile(LPOLESTR *currentFile) if (!malloc) return E_OUTOFMEMORY; - *currentFile = static_cast(malloc->Alloc(currentFileName.length() * 2)); + *currentFile = static_cast(malloc->Alloc(currentFileName.length() * 2)); malloc->Release(); memcpy(*currentFile, currentFileName.unicode(), currentFileName.length() * 2); @@ -3117,7 +3038,7 @@ HRESULT WINAPI QAxServerBase::Load(LPCOLESTR fileName, DWORD mode) return E_NOTIMPL; } - QString loadFileName = QString::fromUtf16(reinterpret_cast(fileName)); + QString loadFileName = QString::fromWCharArray(fileName); QString fileExtension = loadFileName.mid(loadFileName.lastIndexOf(QLatin1Char('.')) + 1); QFile file(loadFileName); @@ -3162,7 +3083,7 @@ HRESULT WINAPI QAxServerBase::Save(LPCOLESTR fileName, BOOL fRemember) return E_NOTIMPL; } - QString saveFileName = QString::fromUtf16(reinterpret_cast(fileName)); + QString saveFileName = QString::fromWCharArray(fileName); QString fileExtension = saveFileName.mid(saveFileName.lastIndexOf(QLatin1Char('.')) + 1); QFile file(saveFileName); @@ -3220,7 +3141,7 @@ HRESULT WINAPI QAxServerBase::Draw(DWORD dwAspect, LONG lindex, void *pvAspect, bool bDeleteDC = false; if (!hicTargetDev) { - hicTargetDev = ::CreateDCA("DISPLAY", NULL, NULL, NULL); + hicTargetDev = ::CreateDC(L"DISPLAY", NULL, NULL, NULL); bDeleteDC = (hicTargetDev != hdcDraw); } @@ -3383,7 +3304,7 @@ HRESULT WINAPI QAxServerBase::OnAmbientPropertyChange(DISPID dispID) case DISPID_AMBIENT_DISPLAYNAME: if (var.vt != VT_BSTR || !isWidget) break; - qt.widget->setWindowTitle(QString::fromUtf16((const ushort *)var.bstrVal)); + qt.widget->setWindowTitle(QString::fromWCharArray(var.bstrVal)); break; case DISPID_AMBIENT_FONT: if (var.vt != VT_DISPATCH || !isWidget) diff --git a/src/activeqt/control/qaxserverdll.cpp b/src/activeqt/control/qaxserverdll.cpp index 375028d..512c408 100644 --- a/src/activeqt/control/qaxserverdll.cpp +++ b/src/activeqt/control/qaxserverdll.cpp @@ -50,7 +50,7 @@ bool qax_ownQApp = false; HHOOK qax_hhook = 0; // in qaxserver.cpp -extern char qAxModuleFilename[MAX_PATH]; +extern wchar_t qAxModuleFilename[MAX_PATH]; extern bool qAxIsServer; extern ITypeLib *qAxTypeLibrary; extern unsigned long qAxLockCount(); @@ -120,7 +120,7 @@ STDAPI DllCanUnloadNow() EXTERN_C BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpvReserved) { - GetModuleFileNameA(hInstance, qAxModuleFilename, MAX_PATH-1); + GetModuleFileName(hInstance, qAxModuleFilename, MAX_PATH); qAxInstance = hInstance; qAxIsServer = true; diff --git a/src/activeqt/control/qaxservermain.cpp b/src/activeqt/control/qaxservermain.cpp index 8f20d97..d465746 100644 --- a/src/activeqt/control/qaxservermain.cpp +++ b/src/activeqt/control/qaxservermain.cpp @@ -66,7 +66,7 @@ extern bool qAxActivity; extern HANDLE qAxInstance; extern bool qAxIsServer; extern bool qAxOutProcServer; -extern char qAxModuleFilename[MAX_PATH]; +extern wchar_t qAxModuleFilename[MAX_PATH]; extern QString qAxInit(); extern void qAxCleanup(); extern HRESULT UpdateRegistry(BOOL bRegister); @@ -105,7 +105,7 @@ static DWORD WINAPI MonitorProc(void* pv) static bool StartMonitor() { dwThreadID = GetCurrentThreadId(); - hEventShutdown = CreateEventA(0, false, false, 0); + hEventShutdown = CreateEvent(0, false, false, 0); if (hEventShutdown == 0) return false; DWORD dwThreadID; @@ -203,17 +203,10 @@ EXTERN_C int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR, QT_USE_NAMESPACE qAxOutProcServer = true; - GetModuleFileNameA(0, qAxModuleFilename, MAX_PATH-1); + GetModuleFileName(0, qAxModuleFilename, MAX_PATH); qAxInstance = hInstance; - QByteArray cmdParam; - QT_WA({ - LPTSTR cmdline = GetCommandLineW(); - cmdParam = QString::fromUtf16((const ushort *)cmdline).toLocal8Bit(); - }, { - cmdParam = GetCommandLineA(); - }); - + QByteArray cmdParam = QString::fromWCharArray(GetCommandLine()).toLocal8Bit(); QList cmds = cmdParam.split(' '); QByteArray unprocessed; diff --git a/src/activeqt/shared/qaxtypes.cpp b/src/activeqt/shared/qaxtypes.cpp index 916fcca..49aa99c 100644 --- a/src/activeqt/shared/qaxtypes.cpp +++ b/src/activeqt/shared/qaxtypes.cpp @@ -37,11 +37,6 @@ ** ****************************************************************************/ -#ifndef UNICODE -#define UNICODE -#endif - - #include #include @@ -123,7 +118,7 @@ static QFont IFontToQFont(IFont *f) f->get_Strikethrough(&strike); f->get_Underline(&underline); f->get_Weight(&weight); - QFont font(QString::fromUtf16((const ushort *)name), size.Lo/9750, weight / 97, italic); + QFont font(QString::fromWCharArray(name), size.Lo/9750, weight / 97, italic); font.setBold(bold); font.setStrikeOut(strike); font.setUnderline(underline); @@ -925,10 +920,10 @@ QVariant VARIANTToQVariant(const VARIANT &arg, const QByteArray &typeName, uint QVariant var; switch(arg.vt) { case VT_BSTR: - var = QString::fromUtf16((const ushort *)arg.bstrVal); + var = QString::fromWCharArray(arg.bstrVal); break; case VT_BSTR|VT_BYREF: - var = QString::fromUtf16((const ushort *)*arg.pbstrVal); + var = QString::fromWCharArray(*arg.pbstrVal); break; case VT_BOOL: var = QVariant((bool)arg.boolVal); @@ -1245,7 +1240,7 @@ QVariant VARIANTToQVariant(const VARIANT &arg, const QByteArray &typeName, uint for (long i = lBound; i <= uBound; ++i) { BSTR bstr; SafeArrayGetElement(array, &i, &bstr); - strings << QString::fromUtf16((const ushort *)bstr); + strings << QString::fromWCharArray(bstr); SysFreeString(bstr); } -- cgit v0.12 From 8a7fb1881afe6b358a35cec71247d7e6681efe0a Mon Sep 17 00:00:00 2001 From: miniak Date: Wed, 1 Jul 2009 11:50:10 +0200 Subject: src/qt3support: Remove QT_WA and non-Unicode code paths, dropping Win9x and NT support Merge-request: 604 Reviewed-by: Marius Storm-Olsen --- src/corelib/global/qt_windows.h | 9 + src/qt3support/dialogs/q3filedialog.cpp | 206 ++----------- src/qt3support/dialogs/q3filedialog_win.cpp | 430 +++++++--------------------- src/qt3support/network/q3dns.cpp | 70 ++--- src/qt3support/other/q3dragobject.cpp | 7 +- src/qt3support/other/q3process_win.cpp | 152 ++++------ src/qt3support/widgets/q3datetimeedit.cpp | 48 +--- src/qt3support/widgets/q3titlebar.cpp | 33 +-- 8 files changed, 231 insertions(+), 724 deletions(-) diff --git a/src/corelib/global/qt_windows.h b/src/corelib/global/qt_windows.h index 27c06e5..4f2bcf6 100644 --- a/src/corelib/global/qt_windows.h +++ b/src/corelib/global/qt_windows.h @@ -99,6 +99,9 @@ #ifndef SPI_GETKEYBOARDCUES #define SPI_GETKEYBOARDCUES 0x100A #endif +#ifndef SPI_GETGRADIENTCAPTIONS +#define SPI_GETGRADIENTCAPTIONS 0x1008 +#endif #ifndef IDC_HAND #define IDC_HAND MAKEINTRESOURCE(32649) #endif @@ -111,6 +114,12 @@ #ifndef ETO_PDY #define ETO_PDY 0x2000 #endif +#ifndef COLOR_GRADIENTACTIVECAPTION +#define COLOR_GRADIENTACTIVECAPTION 27 +#endif +#ifndef COLOR_GRADIENTINACTIVECAPTION +#define COLOR_GRADIENTINACTIVECAPTION 28 +#endif // already defined when compiled with WINVER >= 0x0600 #ifndef SPI_GETFLATMENU diff --git a/src/qt3support/dialogs/q3filedialog.cpp b/src/qt3support/dialogs/q3filedialog.cpp index 031170e..a285fd8 100644 --- a/src/qt3support/dialogs/q3filedialog.cpp +++ b/src/qt3support/dialogs/q3filedialog.cpp @@ -507,45 +507,7 @@ static void updateLastSize(Q3FileDialog *that) lastHeight = that->height() - extHeight; } -// Don't remove the lines below! -// -// resolving the W methods manually is needed, because Windows 95 doesn't include -// these methods in Shell32.lib (not even stubs!), so you'd get an unresolved symbol -// when Qt calls getEsistingDirectory(), etc. #if defined(Q_WS_WIN) - -typedef UINT (WINAPI *PtrExtractIconEx)(LPCTSTR,int,HICON*,HICON*,UINT); -static PtrExtractIconEx ptrExtractIconEx = 0; - -static void resolveLibs() -{ -#ifndef Q_OS_WINCE - static bool triedResolve = false; - - if (!triedResolve) { -#ifndef QT_NO_THREAD - // protect initialization - QMutexLocker locker(QMutexPool::globalInstanceGet(&triedResolve)); - // check triedResolve again, since another thread may have already - // done the initialization - if (triedResolve) { - // another thread did initialize the security function pointers, - // so we shouldn't do it again. - return; - } -#endif - triedResolve = true; - if (qt_winUnicode()) { - QLibrary lib(QLatin1String("shell32")); - ptrExtractIconEx = (PtrExtractIconEx) lib.resolve("ExtractIconExW"); - } - } -#endif -} -#ifdef Q_OS_WINCE -#define PtrExtractIconEx ExtractIconEx -#endif - class QWindowsIconProvider : public Q3FileIconProvider { public: @@ -2566,11 +2528,7 @@ void Q3FileDialog::init() d->modeButtons->insert(d->previewInfo); d->previewContents = new QToolButton(this, "preview info view"); -#if defined(Q_WS_WIN) && !defined(Q_OS_WINCE) - if ((qWinVersion() & Qt::WV_NT_based) > Qt::WV_NT) -#else if (!qstrcmp(style()->className(), "QWindowsStyle")) -#endif { d->goBack->setAutoRaise(true); d->cdToParent->setAutoRaise(true); @@ -4878,33 +4836,20 @@ Q3FileIconProvider * Q3FileDialog::iconProvider() static QString getWindowsRegString(HKEY key, const QString &subKey) { QString s; - QT_WA({ - char buf[1024]; - DWORD bsz = sizeof(buf); - int r = RegQueryValueEx(key, (TCHAR*)subKey.ucs2(), 0, 0, (LPBYTE)buf, &bsz); - if (r == ERROR_SUCCESS) { - s = QString::fromUcs2((unsigned short *)buf); - } else if (r == ERROR_MORE_DATA) { - char *ptr = new char[bsz+1]; - r = RegQueryValueEx(key, (TCHAR*)subKey.ucs2(), 0, 0, (LPBYTE)ptr, &bsz); - if (r == ERROR_SUCCESS) - s = QLatin1String(ptr); - delete [] ptr; - } - } , { - char buf[512]; - DWORD bsz = sizeof(buf); - int r = RegQueryValueExA(key, subKey.local8Bit(), 0, 0, (LPBYTE)buf, &bsz); - if (r == ERROR_SUCCESS) { - s = QLatin1String(buf); - } else if (r == ERROR_MORE_DATA) { - char *ptr = new char[bsz+1]; - r = RegQueryValueExA(key, subKey.local8Bit(), 0, 0, (LPBYTE)ptr, &bsz); - if (r == ERROR_SUCCESS) - s = QLatin1String(ptr); - delete [] ptr; - } - }); + + wchar_t buf[1024]; + DWORD bsz = sizeof(buf) / sizeof(wchar_t); + int r = RegQueryValueEx(key, (wchar_t*)subKey.utf16(), 0, 0, (LPBYTE)buf, &bsz); + if (r == ERROR_SUCCESS) { + s = QString::fromWCharArray(buf); + } else if (r == ERROR_MORE_DATA) { + char *ptr = new char[bsz+1]; + r = RegQueryValueEx(key, (wchar_t*)subKey.utf16(), 0, 0, (LPBYTE)ptr, &bsz); + if (r == ERROR_SUCCESS) + s = QLatin1String(ptr); + delete [] ptr; + } + return s; } @@ -4925,22 +4870,13 @@ QWindowsIconProvider::QWindowsIconProvider(QObject *parent, const char *name) HKEY k; HICON si; - int r; QString s; UINT res = 0; // ---------- get default folder pixmap const wchar_t iconFolder[] = L"folder\\DefaultIcon"; // workaround for Borland - QT_WA({ - r = RegOpenKeyEx(HKEY_CLASSES_ROOT, - iconFolder, - 0, KEY_READ, &k); - } , { - r = RegOpenKeyExA(HKEY_CLASSES_ROOT, - "folder\\DefaultIcon", - 0, KEY_READ, &k); - }); - resolveLibs(); + int r = RegOpenKeyEx(HKEY_CLASSES_ROOT, iconFolder, 0, KEY_READ, &k); + if (r == ERROR_SUCCESS) { s = getWindowsRegString(k, QString()); RegCloseKey(k); @@ -4948,21 +4884,7 @@ QWindowsIconProvider::QWindowsIconProvider(QObject *parent, const char *name) QStringList lst = QStringList::split(QLatin1String(","), s); if (lst.count() >= 2) { // don't just assume that lst has two entries -#ifndef Q_OS_WINCE - QT_WA({ - res = ptrExtractIconEx((TCHAR*)lst[0].simplifyWhiteSpace().ucs2(), - lst[1].simplifyWhiteSpace().toInt(), - 0, &si, 1); - } , { - res = ExtractIconExA(lst[0].simplifyWhiteSpace().local8Bit(), - lst[1].simplifyWhiteSpace().toInt(), - 0, &si, 1); - }); -#else - res = (UINT)ExtractIconEx((TCHAR*)lst[0].simplifyWhiteSpace().ucs2(), - lst[1].simplifyWhiteSpace().toInt(), - 0, &si, 1); -#endif + res = ExtractIconEx((wchar_t*)lst[0].simplifyWhiteSpace().utf16(), lst[1].simplifyWhiteSpace().toInt(), 0, &si, 1); } if (res) { @@ -4978,18 +4900,7 @@ QWindowsIconProvider::QWindowsIconProvider(QObject *parent, const char *name) } //------------------------------- get default file pixmap -#ifndef Q_OS_WINCE - QT_WA({ - res = ptrExtractIconEx(L"shell32.dll", - 0, 0, &si, 1); - } , { - res = ExtractIconExA("shell32.dll", - 0, 0, &si, 1); - }); -#else - res = (UINT)ExtractIconEx(L"shell32.dll", - 0, 0, &si, 1); -#endif + res = ExtractIconEx(L"shell32.dll", 0, 0, &si, 1); if (res) { defaultFile = fromHICON(si); @@ -5002,16 +4913,9 @@ QWindowsIconProvider::QWindowsIconProvider(QObject *parent, const char *name) //------------------------------- get default exe pixmap #ifndef Q_OS_WINCE - QT_WA({ - res = ptrExtractIconEx(L"shell32.dll", - 2, 0, &si, 1); - } , { - res = ExtractIconExA("shell32.dll", - 2, 0, &si, 1); - }); + res = ExtractIconEx(L"shell32.dll", 2, 0, &si, 1); #else - res = (UINT)ExtractIconEx(L"ceshell.dll", - 10, 0, &si, 1); + res = ExtractIconEx(L"ceshell.dll", 10, 0, &si, 1); #endif if (res) { @@ -5050,14 +4954,7 @@ const QPixmap * QWindowsIconProvider::pixmap(const QFileInfo &fi) return &(*it); HKEY k, k2; - int r; - QT_WA({ - r = RegOpenKeyEx(HKEY_CLASSES_ROOT, (TCHAR*)ext.ucs2(), - 0, KEY_READ, &k); - } , { - r = RegOpenKeyExA(HKEY_CLASSES_ROOT, ext.local8Bit(), - 0, KEY_READ, &k); - }); + int r = RegOpenKeyEx(HKEY_CLASSES_ROOT, (wchar_t*)ext.utf16(), 0, KEY_READ, &k); QString s; if (r == ERROR_SUCCESS) { s = getWindowsRegString(k, QString()); @@ -5068,13 +4965,8 @@ const QPixmap * QWindowsIconProvider::pixmap(const QFileInfo &fi) } RegCloseKey(k); - QT_WA({ - r = RegOpenKeyEx(HKEY_CLASSES_ROOT, (TCHAR*)QString(s + QLatin1String("\\DefaultIcon")).ucs2(), - 0, KEY_READ, &k2); - } , { - r = RegOpenKeyExA(HKEY_CLASSES_ROOT, QString(s + QLatin1String("\\DefaultIcon")).local8Bit() , - 0, KEY_READ, &k2); - }); + r = RegOpenKeyEx(HKEY_CLASSES_ROOT, (wchar_t*)QString(s + QLatin1String("\\DefaultIcon")).utf16(), + 0, KEY_READ, &k2); if (r == ERROR_SUCCESS) { s = getWindowsRegString(k2, QString()); } else { @@ -5104,19 +4996,7 @@ const QPixmap * QWindowsIconProvider::pixmap(const QFileInfo &fi) if (filepath[0] == QLatin1Char('"') && filepath[(int)filepath.length()-1] == QLatin1Char('"')) filepath = filepath.mid(1, filepath.length()-2); - resolveLibs(); -#ifndef Q_OS_WINCE - QT_WA({ - res = ptrExtractIconEx((TCHAR*)filepath.ucs2(), lst[1].stripWhiteSpace().toInt(), - 0, &si, 1); - } , { - res = ExtractIconExA(filepath.local8Bit(), lst[1].stripWhiteSpace().toInt(), - 0, &si, 1); - }); -#else - res = (UINT)ExtractIconEx((TCHAR*)filepath.ucs2(), lst[1].stripWhiteSpace().toInt(), - 0, &si, 1); -#endif + res = ExtractIconEx((wchar_t*)filepath.utf16(), lst[1].stripWhiteSpace().toInt(), 0, &si, 1); } } if (res) { @@ -5133,32 +5013,9 @@ const QPixmap * QWindowsIconProvider::pixmap(const QFileInfo &fi) HICON si; UINT res = 0; if (!fi.absFilePath().isEmpty()) { -#ifndef Q_OS_WINCE - QT_WA({ - res = ptrExtractIconEx((TCHAR*)fi.absFilePath().ucs2(), -1, - 0, 0, 1); - } , { - res = ExtractIconExA(fi.absFilePath().local8Bit(), -1, - 0, 0, 1); - }); - - if (res) { - QT_WA({ - res = ptrExtractIconEx((TCHAR*)fi.absFilePath().ucs2(), res - 1, - 0, &si, 1); - } , { - res = ExtractIconExA(fi.absFilePath().local8Bit(), res - 1, - 0, &si, 1); - }); - } -#else - res = (UINT)ExtractIconEx((TCHAR*)fi.absFilePath().ucs2(), -1, - 0, 0, 1); - if (res) - res = (UINT)ExtractIconEx((TCHAR*)fi.absFilePath().ucs2(), res - 1, - 0, &si, 1); -#endif - + res = ExtractIconEx((wchar_t*)fi.absFilePath().utf16(), -1, 0, 0, 1); + if (res) + res = ExtractIconEx((wchar_t*)fi.absFilePath().utf16(), res - 1, 0, &si, 1); } if (res) { @@ -5760,13 +5617,8 @@ void Q3FileDialog::insertEntry(const Q3ValueList &lst, Q3NetworkOperat if (!file.endsWith(QLatin1Char('/'))) file.append(QLatin1Char('/')); file += inf.name(); - QT_WA({ - if (GetFileAttributesW((TCHAR*)file.ucs2()) & FILE_ATTRIBUTE_HIDDEN) - continue; - } , { - if (GetFileAttributesA(file.local8Bit()) & FILE_ATTRIBUTE_HIDDEN) - continue; - }); + if (GetFileAttributes((wchar_t*)file.utf16()) & FILE_ATTRIBUTE_HIDDEN) + continue; } else { if (inf.name() != QLatin1String("..") && inf.name()[0] == QLatin1Char('.')) continue; diff --git a/src/qt3support/dialogs/q3filedialog_win.cpp b/src/qt3support/dialogs/q3filedialog_win.cpp index ed86fa2..487097a 100644 --- a/src/qt3support/dialogs/q3filedialog_win.cpp +++ b/src/qt3support/dialogs/q3filedialog_win.cpp @@ -64,49 +64,6 @@ QT_BEGIN_NAMESPACE -// Don't remove the lines below! -// -// resolving the W methods manually is needed, because Windows 95 doesn't include -// these methods in Shell32.lib (not even stubs!), so you'd get an unresolved symbol -// when Qt calls getEsistingDirectory(), etc. -typedef LPITEMIDLIST (WINAPI *PtrSHBrowseForFolder)(BROWSEINFO*); -static PtrSHBrowseForFolder ptrSHBrowseForFolder = 0; -typedef BOOL (WINAPI *PtrSHGetPathFromIDList)(LPITEMIDLIST,LPWSTR); -static PtrSHGetPathFromIDList ptrSHGetPathFromIDList = 0; - -static void resolveLibs() -{ -#ifndef Q_OS_WINCE - static bool triedResolve = false; - - if (!triedResolve) { -#ifndef QT_NO_THREAD - // protect initialization - QMutexLocker locker(QMutexPool::globalInstanceGet(&triedResolve)); - // check triedResolve again, since another thread may have already - // done the initialization - if (triedResolve) { - // another thread did initialize the security function pointers, - // so we shouldn't do it again. - return; - } -#endif - - triedResolve = true; - if (qt_winUnicode()) { - QLibrary lib(QLatin1String("shell32")); - ptrSHBrowseForFolder = (PtrSHBrowseForFolder) lib.resolve("SHBrowseForFolderW"); - ptrSHGetPathFromIDList = (PtrSHGetPathFromIDList) lib.resolve("SHGetPathFromIDListW"); - } - } -#endif -} -#ifdef Q_OS_WINCE -#define PtrSHBrowseForFolder SHBrowseForFolder ; -#define PtrSHGetPathFromIDList SHGetPathFromIDList; -#endif - - extern const char qt3_file_dialog_filter_reg_exp[]; // defined in qfiledialog.cpp const int maxNameLen = 1023; @@ -168,80 +125,8 @@ static QString selFilter(const QString& filter, DWORD idx) return filterLst[(int)idx - 1]; } -#ifndef Q_OS_WINCE -// Static vars for OFNA funcs: -static QByteArray aInitDir; -static QByteArray aInitSel; -static QByteArray aTitle; -static QByteArray aFilter; -// Use ANSI strings and API - -// If you change this, then make sure you change makeOFN (below) too -static -OPENFILENAMEA* makeOFNA(QWidget* parent, - const QString& initialSelection, - const QString& initialDirectory, - const QString& title, - const QString& filters, - Q3FileDialog::Mode mode) -{ - if (parent) - parent = parent->window(); - else - parent = qApp->activeWindow(); - - aTitle = title.local8Bit(); - aInitDir = QDir::toNativeSeparators(initialDirectory).local8Bit(); - if (initialSelection.isEmpty()) - aInitSel = ""; - else - aInitSel = QDir::toNativeSeparators(initialSelection).local8Bit(); - int maxLen = mode == Q3FileDialog::ExistingFiles ? maxMultiLen : maxNameLen; - aInitSel.resize(maxLen + 1); // make room for return value - aFilter = filters.local8Bit(); - - OPENFILENAMEA* ofn = new OPENFILENAMEA; - memset(ofn, 0, sizeof(OPENFILENAMEA)); - -#if defined(Q_CC_BOR) && (WINVER >= 0x0500) && (_WIN32_WINNT >= 0x0500) - // according to the MSDN, this should also be necessary for MSVC, but - // OPENFILENAME_SIZE_VERSION_400A is in not Microsoft header, as it seems - if (QApplication::winVersion()==Qt::WV_NT || QApplication::winVersion()&Qt::WV_DOS_based) { - ofn->lStructSize= OPENFILENAME_SIZE_VERSION_400A; - } else { - ofn->lStructSize= sizeof(OPENFILENAMEA); - } -#else - ofn->lStructSize = sizeof(OPENFILENAMEA); -#endif - ofn->hwndOwner = parent ? parent->winId() : 0; - ofn->lpstrFilter = aFilter; - ofn->lpstrFile = aInitSel.data(); - ofn->nMaxFile = maxLen; - ofn->lpstrInitialDir = aInitDir.data(); - ofn->lpstrTitle = aTitle.data(); - ofn->Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY); - - if (mode == Q3FileDialog::ExistingFile || - mode == Q3FileDialog::ExistingFiles) - ofn->Flags |= (OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST); - if (mode == Q3FileDialog::ExistingFiles) - ofn->Flags |= (OFN_ALLOWMULTISELECT | OFN_EXPLORER); - - return ofn; -} - -static void cleanUpOFNA(OPENFILENAMEA** ofn) -{ - delete *ofn; - *ofn = 0; -} -#endif - static QString tFilters, tTitle, tInitDir; -#ifdef UNICODE -// If you change this, then make sure you change makeOFNA (above) too static OPENFILENAME* makeOFN(QWidget* parent, const QString& initialSelection, @@ -261,33 +146,23 @@ OPENFILENAME* makeOFN(QWidget* parent, QString initSel = QDir::toNativeSeparators(initialSelection); int maxLen = mode == Q3FileDialog::ExistingFiles ? maxMultiLen : maxNameLen; - TCHAR *tInitSel = new TCHAR[maxLen+1]; + wchar_t *tInitSel = new wchar_t[maxLen+1]; if (initSel.length() > 0 && initSel.length() <= maxLen) - memcpy(tInitSel, initSel.ucs2(), (initSel.length()+1)*sizeof(QChar)); + memcpy(tInitSel, initSel.utf16(), (initSel.length() + 1) * sizeof(wchar_t)); else tInitSel[0] = 0; OPENFILENAME* ofn = new OPENFILENAME; memset(ofn, 0, sizeof(OPENFILENAME)); -#if defined(Q_CC_BOR) && (WINVER >= 0x0500) && (_WIN32_WINNT >= 0x0500) - // according to the MSDN, this should also be necessary for MSVC, but - // OPENFILENAME_SIZE_VERSION_400 is in not Microsoft header, as it seems - if (QApplication::winVersion()==Qt::WV_NT || QApplication::winVersion()&Qt::WV_DOS_based) { - ofn->lStructSize= OPENFILENAME_SIZE_VERSION_400; - } else { - ofn->lStructSize = sizeof(OPENFILENAME); - } -#else - ofn->lStructSize = sizeof(OPENFILENAME); -#endif - ofn->hwndOwner = parent ? parent->winId() : 0; - ofn->lpstrFilter = (TCHAR *)tFilters.ucs2(); - ofn->lpstrFile = tInitSel; + ofn->lStructSize = sizeof(OPENFILENAME); + ofn->hwndOwner = parent ? parent->winId() : 0; + ofn->lpstrFilter = (wchar_t*)tFilters.utf16(); + ofn->lpstrFile = tInitSel; ofn->nMaxFile = maxLen; - ofn->lpstrInitialDir = (TCHAR *)tInitDir.ucs2(); - ofn->lpstrTitle = (TCHAR *)tTitle.ucs2(); - ofn->Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY); + ofn->lpstrInitialDir = (wchar_t*)tInitDir.utf16(); + ofn->lpstrTitle = (wchar_t*)tTitle.utf16(); + ofn->Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY); if (mode == Q3FileDialog::ExistingFile || mode == Q3FileDialog::ExistingFiles) @@ -298,7 +173,6 @@ OPENFILENAME* makeOFN(QWidget* parent, return ofn; } - static void cleanUpOFN(OPENFILENAME** ofn) { delete (*ofn)->lpstrFile; @@ -306,8 +180,6 @@ static void cleanUpOFN(OPENFILENAME** ofn) *ofn = 0; } -#endif // UNICODE - QString Q3FileDialog::winGetOpenFileName(const QString &initialSelection, const QString &filter, QString* initialDirectory, @@ -349,31 +221,18 @@ QString Q3FileDialog::winGetOpenFileName(const QString &initialSelection, QApplication::sendEvent(parent, &e); QApplicationPrivate::enterModal(parent); } - QT_WA({ - // Use Unicode strings and API - OPENFILENAME* ofn = makeOFN(parent, isel, - *initialDirectory, title, - winFilter(filter), ExistingFile); - if (idx) - ofn->nFilterIndex = idx + 1; - if (GetOpenFileName(ofn)) { - result = QString::fromUcs2((ushort*)ofn->lpstrFile); - selFilIdx = ofn->nFilterIndex; - } - cleanUpOFN(&ofn); - } , { - // Use ANSI strings and API - OPENFILENAMEA* ofn = makeOFNA(parent, isel, - *initialDirectory, title, - winFilter(filter), ExistingFile); - if (idx) - ofn->nFilterIndex = idx + 1; - if (GetOpenFileNameA(ofn)) { - result = QString::fromLocal8Bit(ofn->lpstrFile); - selFilIdx = ofn->nFilterIndex; - } - cleanUpOFNA(&ofn); - }); + + OPENFILENAME* ofn = makeOFN(parent, isel, + *initialDirectory, title, + winFilter(filter), ExistingFile); + if (idx) + ofn->nFilterIndex = idx + 1; + if (GetOpenFileName(ofn)) { + result = QString::fromWCharArray(ofn->lpstrFile); + selFilIdx = ofn->nFilterIndex; + } + cleanUpOFN(&ofn); + if (parent) { QApplicationPrivate::leaveModal(parent); QEvent e(QEvent::WindowUnblocked); @@ -433,31 +292,18 @@ QString Q3FileDialog::winGetSaveFileName(const QString &initialSelection, QApplication::sendEvent(parent, &e); QApplicationPrivate::enterModal(parent); } - QT_WA({ - // Use Unicode strings and API - OPENFILENAME* ofn = makeOFN(parent, isel, - *initialDirectory, title, - winFilter(filter), AnyFile); - if (idx) - ofn->nFilterIndex = idx + 1; - if (GetSaveFileName(ofn)) { - result = QString::fromUcs2((ushort*)ofn->lpstrFile); - selFilIdx = ofn->nFilterIndex; - } - cleanUpOFN(&ofn); - } , { - // Use ANSI strings and API - OPENFILENAMEA* ofn = makeOFNA(parent, isel, - *initialDirectory, title, - winFilter(filter), AnyFile); - if (idx) - ofn->nFilterIndex = idx + 1; - if (GetSaveFileNameA(ofn)) { - result = QString::fromLocal8Bit(ofn->lpstrFile); - selFilIdx = ofn->nFilterIndex; - } - cleanUpOFNA(&ofn); - }); + + OPENFILENAME* ofn = makeOFN(parent, isel, + *initialDirectory, title, + winFilter(filter), AnyFile); + if (idx) + ofn->nFilterIndex = idx + 1; + if (GetSaveFileName(ofn)) { + result = QString::fromWCharArray(ofn->lpstrFile); + selFilIdx = ofn->nFilterIndex; + } + cleanUpOFN(&ofn); + if (parent) { QApplicationPrivate::leaveModal(parent); QEvent e(QEvent::WindowUnblocked); @@ -519,69 +365,38 @@ QStringList Q3FileDialog::winGetOpenFileNames(const QString &filter, QApplication::sendEvent(parent, &e); QApplicationPrivate::enterModal(parent); } - QT_WA({ - OPENFILENAME* ofn = makeOFN(parent, isel, - *initialDirectory, title, - winFilter(filter), ExistingFiles); - if (idx) - ofn->nFilterIndex = idx + 1; - if (GetOpenFileName(ofn)) { - QString fileOrDir = QString::fromUcs2((ushort*)ofn->lpstrFile); - selFilIdx = ofn->nFilterIndex; - int offset = fileOrDir.length() + 1; - if (ofn->lpstrFile[offset] == 0) { - // Only one file selected; has full path - fi.setFile(fileOrDir); - QString res = fi.absFilePath(); - if (!res.isEmpty()) - result.append(res); - } - else { - // Several files selected; first string is path - dir.setPath(fileOrDir); - QString f; - while(!(f = QString::fromUcs2((ushort*)ofn->lpstrFile+offset)).isEmpty()) { - fi.setFile(dir, f); - QString res = fi.absFilePath(); - if (!res.isEmpty()) - result.append(res); - offset += f.length() + 1; - } - } + + OPENFILENAME* ofn = makeOFN(parent, isel, + *initialDirectory, title, + winFilter(filter), ExistingFiles); + if (idx) + ofn->nFilterIndex = idx + 1; + if (GetOpenFileName(ofn)) { + QString fileOrDir = QString::fromWCharArray(ofn->lpstrFile); + selFilIdx = ofn->nFilterIndex; + int offset = fileOrDir.length() + 1; + if (ofn->lpstrFile[offset] == 0) { + // Only one file selected; has full path + fi.setFile(fileOrDir); + QString res = fi.absFilePath(); + if (!res.isEmpty()) + result.append(res); } - cleanUpOFN(&ofn); - } , { - OPENFILENAMEA* ofn = makeOFNA(parent, isel, - *initialDirectory, title, - winFilter(filter), ExistingFiles); - if (idx) - ofn->nFilterIndex = idx + 1; - if (GetOpenFileNameA(ofn)) { - QByteArray fileOrDir(ofn->lpstrFile); - selFilIdx = ofn->nFilterIndex; - int offset = fileOrDir.length() + 1; - if (ofn->lpstrFile[offset] == '\0') { - // Only one file selected; has full path - fi.setFile(QString::fromLocal8Bit(fileOrDir)); + else { + // Several files selected; first string is path + dir.setPath(fileOrDir); + QString f; + while (!(f = QString::fromWCharArray(ofn->lpstrFile + offset)).isEmpty()) { + fi.setFile(dir, f); QString res = fi.absFilePath(); if (!res.isEmpty()) result.append(res); + offset += f.length() + 1; } - else { - // Several files selected; first string is path - dir.setPath(QString::fromLocal8Bit(fileOrDir)); - QByteArray f; - while(!(f = QByteArray(ofn->lpstrFile + offset)).isEmpty()) { - fi.setFile(dir, QString::fromLocal8Bit(f)); - QString res = fi.absFilePath(); - if (!res.isEmpty()) - result.append(res); - offset += f.length() + 1; - } - } - cleanUpOFNA(&ofn); } - }); + } + cleanUpOFN(&ofn); + if (parent) { QApplicationPrivate::leaveModal(parent); QEvent e(QEvent::WindowUnblocked); @@ -607,34 +422,17 @@ static int __stdcall winGetExistDirCallbackProc(HWND hwnd, if (uMsg == BFFM_INITIALIZED && lpData != 0) { QString *initDir = (QString *)(lpData); if (!initDir->isEmpty()) { - // ### Lars asks: is this correct for the A version???? - QT_WA({ - SendMessage(hwnd, BFFM_SETSELECTION, TRUE, Q_ULONG(initDir->ucs2())); - } , { - SendMessageA(hwnd, BFFM_SETSELECTION, TRUE, Q_ULONG(initDir->ucs2())); - }); + SendMessage(hwnd, BFFM_SETSELECTION, TRUE, Q_ULONG(initDir->utf16())); } } else if (uMsg == BFFM_SELCHANGED) { - QT_WA({ - resolveLibs(); - TCHAR path[MAX_PATH]; - ptrSHGetPathFromIDList(LPITEMIDLIST(lParam), path); - QString tmpStr = QString::fromUcs2((ushort*)path); - if (!tmpStr.isEmpty()) - SendMessage(hwnd, BFFM_ENABLEOK, 1, 1); - else - SendMessage(hwnd, BFFM_ENABLEOK, 0, 0); - SendMessage(hwnd, BFFM_SETSTATUSTEXT, 1, Q_ULONG(path)); - } , { - char path[MAX_PATH]; - SHGetPathFromIDListA(LPITEMIDLIST(lParam), path); - QString tmpStr = QString::fromLocal8Bit(path); - if (!tmpStr.isEmpty()) - SendMessageA(hwnd, BFFM_ENABLEOK, 1, 1); - else - SendMessageA(hwnd, BFFM_ENABLEOK, 0, 0); - SendMessageA(hwnd, BFFM_SETSTATUSTEXT, 1, Q_ULONG(path)); - }); + wchar_t path[MAX_PATH]; + SHGetPathFromIDList(LPITEMIDLIST(lParam), path); + QString tmpStr = QString::fromWCharArray(path); + if (!tmpStr.isEmpty()) + SendMessage(hwnd, BFFM_ENABLEOK, 1, 1); + else + SendMessage(hwnd, BFFM_ENABLEOK, 0, 0); + SendMessage(hwnd, BFFM_SETSTATUSTEXT, 1, Q_ULONG(path)); } #endif return 0; @@ -666,76 +464,42 @@ QString Q3FileDialog::winGetExistingDirectory(const QString& initialDirectory, QApplication::sendEvent(parent, &e); QApplicationPrivate::enterModal(parent); } - QT_WA({ - resolveLibs(); - QString initDir = QDir::toNativeSeparators(initialDirectory); - TCHAR path[MAX_PATH]; - TCHAR initPath[MAX_PATH]; - initPath[0] = 0; - path[0] = 0; - tTitle = title; - BROWSEINFO bi; - bi.hwndOwner = (parent ? parent->winId() : 0); - bi.pidlRoot = NULL; - bi.lpszTitle = (TCHAR*)tTitle.ucs2(); - bi.pszDisplayName = initPath; - bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_NEWDIALOGSTYLE; - bi.lpfn = winGetExistDirCallbackProc; - bi.lParam = Q_ULONG(&initDir); - LPITEMIDLIST pItemIDList = ptrSHBrowseForFolder(&bi); - if (pItemIDList) { - ptrSHGetPathFromIDList(pItemIDList, path); - IMalloc *pMalloc; - if (SHGetMalloc(&pMalloc) != NOERROR) - result.clear(); - else { - pMalloc->Free(pItemIDList); - pMalloc->Release(); - result = QString::fromUcs2((ushort*)path); - } - } else - result.clear(); - tTitle.clear(); - } , { - QString initDir = QDir::toNativeSeparators(initialDirectory); - char path[MAX_PATH]; - char initPath[MAX_PATH]; - QByteArray ctitle = title.toLocal8Bit(); - initPath[0]=0; - path[0]=0; - BROWSEINFOA bi; - bi.hwndOwner = (parent ? parent->winId() : 0); - bi.pidlRoot = NULL; - bi.lpszTitle = ctitle; - bi.pszDisplayName = initPath; - bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_NEWDIALOGSTYLE; - bi.lpfn = winGetExistDirCallbackProc; - bi.lParam = Q_ULONG(&initDir); - LPITEMIDLIST pItemIDList = SHBrowseForFolderA(&bi); - if (pItemIDList) { - SHGetPathFromIDListA(pItemIDList, path); - IMalloc *pMalloc; - if (SHGetMalloc(&pMalloc) != NOERROR) - result.clear(); - else { - pMalloc->Free(pItemIDList); - pMalloc->Release(); - result = QString::fromLocal8Bit(path); - } - } else + + QString initDir = QDir::toNativeSeparators(initialDirectory); + wchar_t path[MAX_PATH]; + wchar_t initPath[MAX_PATH]; + initPath[0] = 0; + path[0] = 0; + tTitle = title; + BROWSEINFO bi; + bi.hwndOwner = (parent ? parent->winId() : 0); + bi.pidlRoot = NULL; + bi.lpszTitle = (wchar_t*)tTitle.utf16(); + bi.pszDisplayName = initPath; + bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_NEWDIALOGSTYLE; + bi.lpfn = winGetExistDirCallbackProc; + bi.lParam = Q_ULONG(&initDir); + LPITEMIDLIST pItemIDList = SHBrowseForFolder(&bi); + if (pItemIDList) { + SHGetPathFromIDList(pItemIDList, path); + IMalloc *pMalloc; + if (SHGetMalloc(&pMalloc) != NOERROR) result.clear(); - }); + else { + pMalloc->Free(pItemIDList); + pMalloc->Release(); + result = QString::fromWCharArray(path); + } + } else + result.clear(); + tTitle.clear(); + if (parent) { QApplicationPrivate::leaveModal(parent); QEvent e(QEvent::WindowUnblocked); QApplication::sendEvent(parent, &e); } - // Due to a bug on Windows Me, we need to reset the current - // directory - if ((qWinVersion() == Qt::WV_98 || qWinVersion() == Qt::WV_Me) && QDir::currentDirPath() != currentDir) - QDir::setCurrent(currentDir); - if (!result.isEmpty()) result.replace(QLatin1Char('\\'), QLatin1Char('/')); return result; diff --git a/src/qt3support/network/q3dns.cpp b/src/qt3support/network/q3dns.cpp index b80b76b..6d514c1 100644 --- a/src/qt3support/network/q3dns.cpp +++ b/src/qt3support/network/q3dns.cpp @@ -2242,53 +2242,31 @@ typedef struct { typedef DWORD (WINAPI *GNP)( PFIXED_INFO, PULONG ); // ### FIXME: this code is duplicated in qfiledialog.cpp -static QString getWindowsRegString( HKEY key, const QString &subKey ) +static QString getWindowsRegString(HKEY key, const QString &subKey) { QString s; - QT_WA( { - char buf[1024]; - DWORD bsz = sizeof(buf); - int r = RegQueryValueEx( key, (TCHAR*)subKey.ucs2(), 0, 0, (LPBYTE)buf, &bsz ); - if ( r == ERROR_SUCCESS ) { - s = QString::fromUcs2( (unsigned short *)buf ); - } else if ( r == ERROR_MORE_DATA ) { - char *ptr = new char[bsz+1]; - r = RegQueryValueEx( key, (TCHAR*)subKey.ucs2(), 0, 0, (LPBYTE)ptr, &bsz ); - if ( r == ERROR_SUCCESS ) - s = QLatin1String(ptr); - delete [] ptr; - } - } , { - char buf[512]; - DWORD bsz = sizeof(buf); - int r = RegQueryValueExA( key, subKey.local8Bit(), 0, 0, (LPBYTE)buf, &bsz ); - if ( r == ERROR_SUCCESS ) { - s = QLatin1String(buf); - } else if ( r == ERROR_MORE_DATA ) { - char *ptr = new char[bsz+1]; - r = RegQueryValueExA( key, subKey.local8Bit(), 0, 0, (LPBYTE)ptr, &bsz ); - if ( r == ERROR_SUCCESS ) - s = QLatin1String(ptr); - delete [] ptr; - } - } ); + + wchar_t buf[1024]; + DWORD bsz = sizeof(buf) / sizeof(wchar_t); + int r = RegQueryValueEx(key, (wchar_t*)subKey.utf16(), 0, 0, (LPBYTE)buf, &bsz); + if (r == ERROR_SUCCESS) { + s = QString::fromWCharArray(buf); + } else if (r == ERROR_MORE_DATA) { + char *ptr = new char[bsz+1]; + r = RegQueryValueEx(key, (wchar_t*)subKey.utf16(), 0, 0, (LPBYTE)ptr, &bsz); + if (r == ERROR_SUCCESS) + s = QLatin1String(ptr); + delete [] ptr; + } + return s; } static bool getDnsParamsFromRegistry( const QString &path, - QString *domainName, QString *nameServer, QString *searchList ) + QString *domainName, QString *nameServer, QString *searchList ) { HKEY k; - int r; - QT_WA( { - r = RegOpenKeyEx( HKEY_LOCAL_MACHINE, - (TCHAR*)path.ucs2(), - 0, KEY_READ, &k ); - } , { - r = RegOpenKeyExA( HKEY_LOCAL_MACHINE, - path.latin1(), - 0, KEY_READ, &k ); - } ); + int r = RegOpenKeyEx( HKEY_LOCAL_MACHINE, (wchar_t*)path.utf16(), 0, KEY_READ, &k ); if ( r == ERROR_SUCCESS ) { *domainName = getWindowsRegString( k, QLatin1String("DhcpDomain") ); @@ -2321,14 +2299,10 @@ void Q3Dns::doResInit() bool gotNetworkParams = false; // try the API call GetNetworkParams() first and use registry lookup only // as a fallback -#ifdef Q_OS_WINCE - HINSTANCE hinstLib = LoadLibraryW( L"iphlpapi" ); -#else - HINSTANCE hinstLib = LoadLibraryA( "iphlpapi" ); -#endif + HINSTANCE hinstLib = LoadLibrary( L"iphlpapi" ); if ( hinstLib != 0 ) { #ifdef Q_OS_WINCE - GNP getNetworkParams = (GNP) GetProcAddressW( hinstLib, L"GetNetworkParams" ); + GNP getNetworkParams = (GNP) GetProcAddress( hinstLib, L"GetNetworkParams" ); #else GNP getNetworkParams = (GNP) GetProcAddress( hinstLib, "GetNetworkParams" ); #endif @@ -2362,13 +2336,7 @@ void Q3Dns::doResInit() if ( getDnsParamsFromRegistry( QLatin1String("System\\CurrentControlSet\\Services\\Tcpip\\Parameters"), &domainName, &nameServer, &searchList )) { - // for NT separator = ' '; - } else if ( getDnsParamsFromRegistry( - QLatin1String("System\\CurrentControlSet\\Services\\VxD\\MSTCP"), - &domainName, &nameServer, &searchList )) { - // for Windows 98 - separator = ','; } else { // Could not access the TCP/IP parameters domainName = QLatin1String(""); diff --git a/src/qt3support/other/q3dragobject.cpp b/src/qt3support/other/q3dragobject.cpp index 0c17e0c..93a6079 100644 --- a/src/qt3support/other/q3dragobject.cpp +++ b/src/qt3support/other/q3dragobject.cpp @@ -191,8 +191,7 @@ Q3DragObject::~Q3DragObject() Set the pixmap, \a pm, to display while dragging the object. The platform-specific implementation will use this where it can - so provide a small masked pixmap, and do not assume that the user - will actually see it. For example, cursors on Windows 95 are of - limited size. + will actually see it. The \a hotspot is the point on (or off) the pixmap that should be under the cursor as it is dragged. It is relative to the top-left @@ -553,10 +552,6 @@ QTextCodec* qt_findcharset(const QByteArray& mimetype) i = cs.indexOf(';'); if (i >= 0) cs = cs.left(i); - // win98 often has charset=utf16, and we need to get the correct codec for - // it to be able to get Unicode text drops. - if (cs == "utf16") - cs = "ISO-10646-UCS-2"; // May return 0 if unknown charset return QTextCodec::codecForName(cs); } diff --git a/src/qt3support/other/q3process_win.cpp b/src/qt3support/other/q3process_win.cpp index 352e497..0952663 100644 --- a/src/qt3support/other/q3process_win.cpp +++ b/src/qt3support/other/q3process_win.cpp @@ -308,108 +308,60 @@ bool Q3Process::start( QStringList *env ) // CreateProcess() bool success; d->newPid(); -#ifdef UNICODE - if (!(QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based)) { - STARTUPINFOW startupInfo = { - sizeof( STARTUPINFO ), 0, 0, 0, - (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, - 0, 0, 0, - STARTF_USESTDHANDLES, - 0, 0, 0, - d->pipeStdin[0], d->pipeStdout[1], d->pipeStderr[1] - }; - TCHAR *applicationName; - if ( appName.isNull() ) - applicationName = 0; - else - applicationName = _wcsdup( (TCHAR*)appName.ucs2() ); - TCHAR *commandLine = _wcsdup( (TCHAR*)args.ucs2() ); - QByteArray envlist; - if ( env != 0 ) { - int pos = 0; - // add PATH if necessary (for DLL loading) - QByteArray path = qgetenv( "PATH" ); - if ( env->grep( QRegExp(QLatin1String("^PATH="),FALSE) ).empty() && !path.isNull() ) { - QString tmp = QString::fromLatin1("PATH=%1").arg(QLatin1String(path.constData())); - uint tmpSize = sizeof(TCHAR) * (tmp.length()+1); - envlist.resize( envlist.size() + tmpSize ); - memcpy( envlist.data()+pos, tmp.ucs2(), tmpSize ); - pos += tmpSize; - } - // add the user environment - for ( QStringList::Iterator it = env->begin(); it != env->end(); it++ ) { - QString tmp = *it; - uint tmpSize = sizeof(TCHAR) * (tmp.length()+1); - envlist.resize( envlist.size() + tmpSize ); - memcpy( envlist.data()+pos, tmp.ucs2(), tmpSize ); - pos += tmpSize; - } - // add the 2 terminating 0 (actually 4, just to be on the safe side) - envlist.resize( envlist.size()+4 ); - envlist[pos++] = 0; - envlist[pos++] = 0; - envlist[pos++] = 0; - envlist[pos++] = 0; - } - success = CreateProcessW( applicationName, commandLine, - 0, 0, TRUE, ( comms==0 ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW ) + + STARTUPINFOW startupInfo = { + sizeof( STARTUPINFO ), 0, 0, 0, + (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, + 0, 0, 0, + STARTF_USESTDHANDLES, + 0, 0, 0, + d->pipeStdin[0], d->pipeStdout[1], d->pipeStderr[1] + }; + wchar_t *applicationName; + if ( appName.isNull() ) + applicationName = 0; + else + applicationName = _wcsdup( (wchar_t*)appName.utf16() ); + wchar_t *commandLine = _wcsdup( (wchar_t*)args.utf16() ); + QByteArray envlist; + if ( env != 0 ) { + int pos = 0; + // add PATH if necessary (for DLL loading) + QByteArray path = qgetenv( "PATH" ); + if ( env->grep( QRegExp(QLatin1String("^PATH="),FALSE) ).empty() && !path.isNull() ) { + QString tmp = QString::fromLatin1("PATH=%1").arg(QLatin1String(path.constData())); + uint tmpSize = sizeof(wchar_t) * (tmp.length() + 1); + envlist.resize( envlist.size() + tmpSize ); + memcpy( envlist.data() + pos, tmp.utf16(), tmpSize ); + pos += tmpSize; + } + // add the user environment + for ( QStringList::Iterator it = env->begin(); it != env->end(); it++ ) { + QString tmp = *it; + uint tmpSize = sizeof(wchar_t) * (tmp.length() + 1); + envlist.resize( envlist.size() + tmpSize ); + memcpy( envlist.data() + pos, tmp.utf16(), tmpSize ); + pos += tmpSize; + } + // add the 2 terminating 0 (actually 4, just to be on the safe side) + envlist.resize( envlist.size()+4 ); + envlist[pos++] = 0; + envlist[pos++] = 0; + envlist[pos++] = 0; + envlist[pos++] = 0; + } + success = CreateProcess( applicationName, commandLine, + 0, 0, TRUE, ( comms == 0 ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW ) #ifndef Q_OS_WINCE - | CREATE_UNICODE_ENVIRONMENT + | CREATE_UNICODE_ENVIRONMENT #endif - , env==0 ? 0 : envlist.data(), - (TCHAR*)QDir::toNativeSeparators(workingDir.absPath()).ucs2(), - &startupInfo, d->pid ); - free( applicationName ); - free( commandLine ); - } else -#endif // UNICODE - { -#ifndef Q_OS_WINCE - STARTUPINFOA startupInfo = { sizeof( STARTUPINFOA ), 0, 0, 0, - (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, - 0, 0, 0, - STARTF_USESTDHANDLES, - 0, 0, 0, - d->pipeStdin[0], d->pipeStdout[1], d->pipeStderr[1] - }; - QByteArray envlist; - if ( env != 0 ) { - int pos = 0; - // add PATH if necessary (for DLL loading) - QByteArray path = qgetenv( "PATH" ); - if ( env->grep( QRegExp(QLatin1String("^PATH="),FALSE) ).empty() && !path.isNull() ) { - Q3CString tmp = QString::fromLatin1("PATH=%1").arg(QString::fromLatin1(path.constData())).local8Bit(); - uint tmpSize = tmp.length() + 1; - envlist.resize( envlist.size() + tmpSize ); - memcpy( envlist.data()+pos, tmp.data(), tmpSize ); - pos += tmpSize; - } - // add the user environment - for ( QStringList::Iterator it = env->begin(); it != env->end(); it++ ) { - Q3CString tmp = (*it).local8Bit(); - uint tmpSize = tmp.length() + 1; - envlist.resize( envlist.size() + tmpSize ); - memcpy( envlist.data()+pos, tmp.data(), tmpSize ); - pos += tmpSize; - } - // add the terminating 0 (actually 2, just to be on the safe side) - envlist.resize( envlist.size()+2 ); - envlist[pos++] = 0; - envlist[pos++] = 0; - } - char *applicationName; - if ( appName.isNull() ) - applicationName = 0; - else - applicationName = const_cast(appName.toLocal8Bit().data()); - success = CreateProcessA( applicationName, - const_cast(args.toLocal8Bit().data()), - 0, 0, TRUE, comms==0 ? CREATE_NEW_CONSOLE : DETACHED_PROCESS, - env==0 ? 0 : envlist.data(), - (const char*)QDir::toNativeSeparators(workingDir.absPath()).local8Bit(), - &startupInfo, d->pid ); -#endif // Q_OS_WINCE - } + , env == 0 ? 0 : envlist.data(), + (wchar_t*)QDir::toNativeSeparators(workingDir.absPath()).utf16(), + &startupInfo, d->pid ); + + free( applicationName ); + free( commandLine ); + if ( !success ) { d->deletePid(); return false; diff --git a/src/qt3support/widgets/q3datetimeedit.cpp b/src/qt3support/widgets/q3datetimeedit.cpp index b6e303c..4872642 100644 --- a/src/qt3support/widgets/q3datetimeedit.cpp +++ b/src/qt3support/widgets/q3datetimeedit.cpp @@ -114,39 +114,21 @@ static void readLocaleSettings() lTimeSep = new QString(); #if defined(Q_WS_WIN) - QT_WA({ - TCHAR data[10]; - GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDATE, data, 10); - *lDateSep = QString::fromUtf16((ushort*)data); - GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STIME, data, 10); - *lTimeSep = QString::fromUtf16((ushort*)data); - GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ITIME, data, 10); - lAMPM = QString::fromUtf16((ushort*)data).toInt()==0; - GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_S1159, data, 10); - QString am = QString::fromUtf16((ushort*)data); - if (!am.isEmpty()) - lAM = new QString(am); - GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_S2359, data, 10); - QString pm = QString::fromUtf16((ushort*)data); - if (!pm.isEmpty() ) - lPM = new QString(pm); - } , { - char data[10]; - GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDATE, (char*)&data, 10); - *lDateSep = QString::fromLocal8Bit(data); - GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_STIME, (char*)&data, 10); - *lTimeSep = QString::fromLocal8Bit(data); - GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_ITIME, (char*)&data, 10); - lAMPM = QString::fromLocal8Bit(data).toInt()==0; - GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_S1159, (char*)&data, 10); - QString am = QString::fromLocal8Bit(data); - if (!am.isEmpty()) - lAM = new QString(am); - GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_S2359, (char*)&data, 10); - QString pm = QString::fromLocal8Bit(data); - if (!pm.isEmpty()) - lPM = new QString(pm); - }); + wchar_t data[10]; + GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDATE, data, 10); + *lDateSep = QString::fromWCharArray(data); + GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STIME, data, 10); + *lTimeSep = QString::fromWCharArray(data); + GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ITIME, data, 10); + lAMPM = QString::fromWCharArray(data).toInt() == 0; + GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_S1159, data, 10); + QString am = QString::fromWCharArray(data); + if (!am.isEmpty()) + lAM = new QString(am); + GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_S2359, data, 10); + QString pm = QString::fromWCharArray(data); + if (!pm.isEmpty() ) + lPM = new QString(pm); #else *lDateSep = QLatin1Char('-'); *lTimeSep = QLatin1Char(':'); diff --git a/src/qt3support/widgets/q3titlebar.cpp b/src/qt3support/widgets/q3titlebar.cpp index a05e4e5..ee3decf 100644 --- a/src/qt3support/widgets/q3titlebar.cpp +++ b/src/qt3support/widgets/q3titlebar.cpp @@ -173,35 +173,20 @@ void Q3TitleBarPrivate::readColors() bool colorsInitialized = false; #ifdef Q_WS_WIN // ask system properties on windows -#ifndef SPI_GETGRADIENTCAPTIONS -#define SPI_GETGRADIENTCAPTIONS 0x1008 -#endif -#ifndef COLOR_GRADIENTACTIVECAPTION -#define COLOR_GRADIENTACTIVECAPTION 27 -#endif -#ifndef COLOR_GRADIENTINACTIVECAPTION -#define COLOR_GRADIENTINACTIVECAPTION 28 -#endif if (QApplication::desktopSettingsAware()) { pal.setColor(QPalette::Active, QPalette::Highlight, colorref2qrgb(GetSysColor(COLOR_ACTIVECAPTION))); pal.setColor(QPalette::Inactive, QPalette::Highlight, colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTION))); pal.setColor(QPalette::Active, QPalette::HighlightedText, colorref2qrgb(GetSysColor(COLOR_CAPTIONTEXT))); pal.setColor(QPalette::Inactive, QPalette::HighlightedText, colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTIONTEXT))); - if (QSysInfo::WindowsVersion != QSysInfo::WV_95 && QSysInfo::WindowsVersion != QSysInfo::WV_NT) { - colorsInitialized = true; - BOOL gradient; - QT_WA({ - SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0); - } , { - SystemParametersInfoA(SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0); - }); - if (gradient) { - pal.setColor(QPalette::Active, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION))); - pal.setColor(QPalette::Inactive, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION))); - } else { - pal.setColor(QPalette::Active, QPalette::Base, pal.color(QPalette::Active, QPalette::Highlight)); - pal.setColor(QPalette::Inactive, QPalette::Base, pal.color(QPalette::Inactive, QPalette::Highlight)); - } + colorsInitialized = true; + BOOL gradient = false; + SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0); + if (gradient) { + pal.setColor(QPalette::Active, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION))); + pal.setColor(QPalette::Inactive, QPalette::Base, colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION))); + } else { + pal.setColor(QPalette::Active, QPalette::Base, pal.color(QPalette::Active, QPalette::Highlight)); + pal.setColor(QPalette::Inactive, QPalette::Base, pal.color(QPalette::Inactive, QPalette::Highlight)); } } #endif // Q_WS_WIN -- cgit v0.12 From 70d033d033b34ed9c0dde38889062bfd8420366c Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Wed, 1 Jul 2009 11:50:13 +0200 Subject: src/testlib: LPCWSTR -> wchar_t* Merge-request: 604 Reviewed-by: Marius Storm-Olsen --- src/testlib/qplaintestlogger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testlib/qplaintestlogger.cpp b/src/testlib/qplaintestlogger.cpp index 3047326..071b55e 100644 --- a/src/testlib/qplaintestlogger.cpp +++ b/src/testlib/qplaintestlogger.cpp @@ -151,7 +151,7 @@ namespace QTest { int length = strlen(str); for (int pos = 0; pos < length; pos +=255) { QString uniText = QString::fromLatin1(str + pos, 255); - OutputDebugStringW((const LPCWSTR) uniText.utf16()); + OutputDebugString((wchar_t*)uniText.utf16()); } if (QTestLog::outputFileName()) #elif defined(Q_OS_WIN) -- cgit v0.12 From 7ae4e3c1827138cc47d14dd0f128b5999ccb30ce Mon Sep 17 00:00:00 2001 From: miniak Date: Wed, 1 Jul 2009 11:50:16 +0200 Subject: src/tools/idc: Remove QT_WA and non-Unicode code paths, dropping Win9x and NT support Merge-request: 604 Reviewed-by: Marius Storm-Olsen --- src/tools/idc/main.cpp | 69 ++++++++++++-------------------------------------- 1 file changed, 16 insertions(+), 53 deletions(-) diff --git a/src/tools/idc/main.cpp b/src/tools/idc/main.cpp index 48ce9cc..8fe8a70 100644 --- a/src/tools/idc/main.cpp +++ b/src/tools/idc/main.cpp @@ -40,7 +40,6 @@ ****************************************************************************/ #include -#include #include #include #include @@ -87,37 +86,19 @@ static bool runWithQtInEnvironment(const QString &cmd) static bool attachTypeLibrary(const QString &applicationName, int resource, const QByteArray &data, QString *errorMessage) { - HANDLE hExe = 0; - QT_WA({ - TCHAR *resourceName = MAKEINTRESOURCEW(resource); - hExe = BeginUpdateResourceW((TCHAR*)applicationName.utf16(), false); - if (hExe == 0) { - if (errorMessage) - *errorMessage = QString::fromLatin1("Failed to attach type library to binary %1 - could not open file.").arg(applicationName); - return false; - } - if (!UpdateResourceW(hExe,L"TYPELIB",resourceName,0,(void*)data.data(),data.count())) { - EndUpdateResource(hExe, true); - if (errorMessage) - *errorMessage = QString::fromLatin1("Failed to attach type library to binary %1 - could not update file.").arg(applicationName); - return false; - } - }, { - char *resourceName = MAKEINTRESOURCEA(resource); - hExe = BeginUpdateResourceA(applicationName.toLocal8Bit(), false); - if (hExe == 0) { - if (errorMessage) - *errorMessage = QString::fromLatin1("Failed to attach type library to binary %1 - could not open file.").arg(applicationName); - return false; - } - if (!UpdateResourceA(hExe,"TYPELIB",resourceName,0,(void*)data.data(),data.count())) { - EndUpdateResource(hExe, true); - if (errorMessage) - *errorMessage = QString::fromLatin1("Failed to attach type library to binary %1 - could not update file.").arg(applicationName); - return false; - } - }); - + HANDLE hExe = BeginUpdateResource((const wchar_t *)applicationName.utf16(), false); + if (hExe == 0) { + if (errorMessage) + *errorMessage = QString::fromLatin1("Failed to attach type library to binary %1 - could not open file.").arg(applicationName); + return false; + } + if (!UpdateResource(hExe, L"TYPELIB", MAKEINTRESOURCE(resource), 0, (void*)data.data(), data.count())) { + EndUpdateResource(hExe, true); + if (errorMessage) + *errorMessage = QString::fromLatin1("Failed to attach type library to binary %1 - could not update file.").arg(applicationName); + return false; + } + if (!EndUpdateResource(hExe,false)) { if (errorMessage) *errorMessage = QString::fromLatin1("Failed to attach type library to binary %1 - could not write file.").arg(applicationName); @@ -135,12 +116,7 @@ static bool registerServer(const QString &input) if (input.endsWith(QLatin1String(".exe"))) { ok = runWithQtInEnvironment(quotePath(input) + QLatin1String(" -regserver")); } else { - HMODULE hdll = 0; - QT_WA({ - hdll = LoadLibraryW((TCHAR*)input.utf16()); - }, { - hdll = LoadLibraryA(input.toLocal8Bit()); - }); + HMODULE hdll = LoadLibrary((const wchar_t *)input.utf16()); if (!hdll) { fprintf(stderr, "Couldn't load library file %s\n", (const char*)input.toLocal8Bit().data()); return false; @@ -162,12 +138,7 @@ static bool unregisterServer(const QString &input) if (input.endsWith(QLatin1String(".exe"))) { ok = runWithQtInEnvironment(quotePath(input) + QLatin1String(" -unregserver")); } else { - HMODULE hdll = 0; - QT_WA({ - hdll = LoadLibraryW((TCHAR*)input.utf16()); - }, { - hdll = LoadLibraryA(input.toLocal8Bit()); - }); + HMODULE hdll = LoadLibrary((const wchar_t *)input.utf16()); if (!hdll) { fprintf(stderr, "Couldn't load library file %s\n", (const char*)input.toLocal8Bit().data()); return false; @@ -191,12 +162,7 @@ static HRESULT dumpIdl(const QString &input, const QString &idlfile, const QStri if (runWithQtInEnvironment(quotePath(input) + QLatin1String(" -dumpidl ") + idlfile + QLatin1String(" -version ") + version)) res = S_OK; } else { - HMODULE hdll = 0; - QT_WA({ - hdll = LoadLibraryW((TCHAR*)input.utf16()); - }, { - hdll = LoadLibraryA(input.toLocal8Bit()); - }); + HMODULE hdll = LoadLibrary((const wchar_t *)input.utf16()); if (!hdll) { fprintf(stderr, "Couldn't load library file %s\n", (const char*)input.toLocal8Bit().data()); return 3; @@ -254,9 +220,6 @@ int runIdc(int argc, char **argv) else version = QLatin1String(argv[i]); } else if (p == QLatin1String("/tlb") || p == QLatin1String("-tlb")) { - if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) - fprintf(stderr, "IDC requires Windows NT/2000/XP!\n"); - ++i; if (i > argc) { error = QLatin1String("Missing name for type library file!"); -- cgit v0.12 From 24e7a5f983ead3fe722703851cf59cd0943e3964 Mon Sep 17 00:00:00 2001 From: miniak Date: Wed, 1 Jul 2009 11:50:19 +0200 Subject: src/3rdparty/phonon: Remove QT_WA and non-Unicode code paths, dropping Win9x and NT support Merge-request: 604 Reviewed-by: Marius Storm-Olsen --- src/3rdparty/phonon/ds9/qaudiocdreader.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/3rdparty/phonon/ds9/qaudiocdreader.cpp b/src/3rdparty/phonon/ds9/qaudiocdreader.cpp index b9f9fd6..d5bdce2 100644 --- a/src/3rdparty/phonon/ds9/qaudiocdreader.cpp +++ b/src/3rdparty/phonon/ds9/qaudiocdreader.cpp @@ -154,10 +154,7 @@ namespace Phonon path = QString::fromLatin1("\\\\.\\%1:").arg(drive); } - m_cddrive = QT_WA_INLINE ( - ::CreateFile( (TCHAR*)path.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ), - ::CreateFileA( path.toLocal8Bit().constData(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ) - ); + m_cddrive = ::CreateFile((const wchar_t *)path.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); qMemSet(m_toc, 0, sizeof(CDROM_TOC)); //read the TOC -- cgit v0.12 From 5ea86cfac34f65b2321ceeeb651e4e7099bf59a0 Mon Sep 17 00:00:00 2001 From: miniak Date: Wed, 1 Jul 2009 11:50:23 +0200 Subject: tools: Remove QT_WA and non-Unicode code paths, dropping Win9x and NT support Also QString::fromUtf16() -> QString::fromWCharArray() Merge-request: 604 Reviewed-by: Marius Storm-Olsen --- tools/activeqt/dumpcpp/main.cpp | 6 +- tools/configure/configure.pro | 2 +- tools/configure/configureapp.cpp | 19 +- tools/configure/environment.cpp | 218 ++++++--------------- tools/configure/tools.cpp | 4 +- .../src/plugins/activeqt/qaxwidgettaskmenu.cpp | 2 +- tools/linguist/shared/profileevaluator.cpp | 4 +- .../qtestlib/wince/cetest/activesyncconnection.cpp | 10 +- tools/xmlpatterns/main.cpp | 2 +- 9 files changed, 78 insertions(+), 189 deletions(-) diff --git a/tools/activeqt/dumpcpp/main.cpp b/tools/activeqt/dumpcpp/main.cpp index 0a4aa06..de3ec57 100644 --- a/tools/activeqt/dumpcpp/main.cpp +++ b/tools/activeqt/dumpcpp/main.cpp @@ -969,7 +969,7 @@ bool generateTypeLibrary(const QByteArray &typeLib, const QByteArray &outname, O QString libName; BSTR nameString; typelib->GetDocumentation(-1, &nameString, 0, 0, 0); - libName = QString::fromUtf16((const ushort *)nameString); + libName = QString::fromWCharArray(nameString); SysFreeString(nameString); if (!nameSpace.isEmpty()) libName = QString(nameSpace); @@ -1086,7 +1086,7 @@ bool generateTypeLibrary(const QByteArray &typeLib, const QByteArray &outname, O BSTR bstr; if (S_OK != typeinfo->GetDocumentation(-1, &bstr, 0, 0, 0)) break; - className = QString::fromUtf16((const ushort *)bstr).toLatin1(); + className = QString::fromWCharArray(bstr).toLatin1(); SysFreeString(bstr); switch (typekind) { case TKIND_RECORD: @@ -1227,7 +1227,7 @@ bool generateTypeLibrary(const QByteArray &typeLib, const QByteArray &outname, O BSTR bstr; if (S_OK != typeinfo->GetDocumentation(-1, &bstr, 0, 0, 0)) break; - className = QString::fromUtf16((const ushort *)bstr).toLatin1(); + className = QString::fromWCharArray(bstr).toLatin1(); SysFreeString(bstr); declOut << "// stub for vtable-only interface" << endl; diff --git a/tools/configure/configure.pro b/tools/configure/configure.pro index 1ce9a1b..fdeab29 100644 --- a/tools/configure/configure.pro +++ b/tools/configure/configure.pro @@ -3,7 +3,7 @@ DESTDIR = ../.. CONFIG += console flat CONFIG -= moc qt -DEFINES = QT_NODLL QT_NO_CODECS QT_NO_TEXTCODEC QT_NO_UNICODETABLES QT_LITE_COMPONENT QT_NO_STL QT_NO_COMPRESS QT_BUILD_QMAKE QT_NO_THREAD QT_NO_QOBJECT _CRT_SECURE_NO_DEPRECATE +DEFINES = UNICODE QT_NODLL QT_NO_CODECS QT_NO_TEXTCODEC QT_NO_UNICODETABLES QT_LITE_COMPONENT QT_NO_STL QT_NO_COMPRESS QT_BUILD_QMAKE QT_NO_THREAD QT_NO_QOBJECT _CRT_SECURE_NO_DEPRECATE win32 : LIBS += -lole32 -ladvapi32 diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 597cd0e..509444b 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -116,16 +116,9 @@ Configure::Configure( int& argc, char** argv ) // Get the path to the executable - QFileInfo sourcePathInfo; - QT_WA({ - unsigned short module_name[256]; - GetModuleFileNameW(0, reinterpret_cast(module_name), sizeof(module_name)); - sourcePathInfo = QString::fromUtf16(module_name); - }, { - char module_name[256]; - GetModuleFileNameA(0, module_name, sizeof(module_name)); - sourcePathInfo = QString::fromLocal8Bit(module_name); - }); + wchar_t module_name[MAX_PATH]; + GetModuleFileName(0, module_name, sizeof(module_name) / sizeof(wchar_t)); + QFileInfo sourcePathInfo = QString::fromWCharArray(module_name); sourcePath = sourcePathInfo.absolutePath(); sourceDir = sourcePathInfo.dir(); buildPath = QDir::currentPath(); @@ -2733,7 +2726,7 @@ void Configure::generateConfigfiles() tmpFile.flush(); // Replace old qconfig.h with new one - ::SetFileAttributesA(outName.toLocal8Bit(), FILE_ATTRIBUTE_NORMAL); + ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL); QFile::remove(outName); tmpFile.copy(outName); tmpFile.close(); @@ -2769,7 +2762,7 @@ void Configure::generateConfigfiles() } outName = defSpec + "/qmake.conf"; - ::SetFileAttributesA(outName.toLocal8Bit(), FILE_ATTRIBUTE_NORMAL ); + ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL ); QFile qmakeConfFile(outName); if (qmakeConfFile.open(QFile::Append | QFile::WriteOnly | QFile::Text)) { QTextStream qmakeConfStream; @@ -2837,7 +2830,7 @@ void Configure::generateConfigfiles() tmpFile2.flush(); // Replace old qconfig.cpp with new one - ::SetFileAttributesA(outName.toLocal8Bit(), FILE_ATTRIBUTE_NORMAL ); + ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL ); QFile::remove( outName ); tmpFile2.copy(outName); tmpFile2.close(); diff --git a/tools/configure/environment.cpp b/tools/configure/environment.cpp index 6dc8940..b4c61f8 100644 --- a/tools/configure/environment.cpp +++ b/tools/configure/environment.cpp @@ -146,26 +146,14 @@ QString Environment::readRegistryKey(HKEY parentHandle, const QString &rSubkey) QString rSubkeyPath = keyPath(rSubkey); HKEY handle = 0; - LONG res; - QT_WA( { - res = RegOpenKeyExW(parentHandle, (WCHAR*)rSubkeyPath.utf16(), - 0, KEY_READ, &handle); - } , { - res = RegOpenKeyExA(parentHandle, rSubkeyPath.toLocal8Bit(), - 0, KEY_READ, &handle); - } ); - + LONG res = RegOpenKeyEx(parentHandle, (wchar_t*)rSubkeyPath.utf16(), 0, KEY_READ, &handle); if (res != ERROR_SUCCESS) return QString(); // get the size and type of the value DWORD dataType; DWORD dataSize; - QT_WA( { - res = RegQueryValueExW(handle, (WCHAR*)rSubkeyName.utf16(), 0, &dataType, 0, &dataSize); - }, { - res = RegQueryValueExA(handle, rSubkeyName.toLocal8Bit(), 0, &dataType, 0, &dataSize); - } ); + res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, &dataType, 0, &dataSize); if (res != ERROR_SUCCESS) { RegCloseKey(handle); return QString(); @@ -173,13 +161,8 @@ QString Environment::readRegistryKey(HKEY parentHandle, const QString &rSubkey) // get the value QByteArray data(dataSize, 0); - QT_WA( { - res = RegQueryValueExW(handle, (WCHAR*)rSubkeyName.utf16(), 0, 0, - reinterpret_cast(data.data()), &dataSize); - }, { - res = RegQueryValueExA(handle, rSubkeyName.toLocal8Bit(), 0, 0, - reinterpret_cast(data.data()), &dataSize); - } ); + res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, 0, + reinterpret_cast(data.data()), &dataSize); if (res != ERROR_SUCCESS) { RegCloseKey(handle); return QString(); @@ -189,11 +172,7 @@ QString Environment::readRegistryKey(HKEY parentHandle, const QString &rSubkey) switch (dataType) { case REG_EXPAND_SZ: case REG_SZ: { - QT_WA( { - result = QString::fromUtf16(((const ushort*)data.constData())); - }, { - result = QString::fromLatin1(data.constData()); - } ); + result = QString::fromWCharArray(((const wchar_t *)data.constData())); break; } @@ -201,29 +180,20 @@ QString Environment::readRegistryKey(HKEY parentHandle, const QString &rSubkey) QStringList l; int i = 0; for (;;) { - QString s; - QT_WA( { - s = QString::fromUtf16((const ushort*)data.constData() + i); - }, { - s = QString::fromLatin1(data.constData() + i); - } ); + QString s = QString::fromWCharArray((const wchar_t *)data.constData() + i); i += s.length() + 1; if (s.isEmpty()) break; l.append(s); } - result = l.join(", "); + result = l.join(", "); break; } case REG_NONE: case REG_BINARY: { - QT_WA( { - result = QString::fromUtf16((const ushort*)data.constData(), data.size()/2); - }, { - result = QString::fromLatin1(data.constData(), data.size()); - } ); + result = QString::fromWCharArray((const wchar_t *)data.constData(), data.size() / 2); break; } @@ -232,7 +202,7 @@ QString Environment::readRegistryKey(HKEY parentHandle, const QString &rSubkey) Q_ASSERT(data.size() == sizeof(int)); int i; memcpy((char*)&i, data.constData(), sizeof(int)); - result = QString::number(i); + result = QString::number(i); break; } @@ -350,29 +320,14 @@ bool Environment::detectExecutable(const QString &executable) PROCESS_INFORMATION procInfo; memset(&procInfo, 0, sizeof(procInfo)); - bool couldExecute; - QT_WA({ - // Unicode version - STARTUPINFOW startInfo; - memset(&startInfo, 0, sizeof(startInfo)); - startInfo.cb = sizeof(startInfo); - - couldExecute = CreateProcessW(0, (WCHAR*)executable.utf16(), - 0, 0, false, - CREATE_NO_WINDOW | CREATE_SUSPENDED, - 0, 0, &startInfo, &procInfo); - - }, { - // Ansi version - STARTUPINFOA startInfo; - memset(&startInfo, 0, sizeof(startInfo)); - startInfo.cb = sizeof(startInfo); + STARTUPINFO startInfo; + memset(&startInfo, 0, sizeof(startInfo)); + startInfo.cb = sizeof(startInfo); - couldExecute = CreateProcessA(0, executable.toLocal8Bit().data(), + bool couldExecute = CreateProcess(0, (wchar_t*)executable.utf16(), 0, 0, false, CREATE_NO_WINDOW | CREATE_SUSPENDED, 0, 0, &startInfo, &procInfo); - }) if (couldExecute) { CloseHandle(procInfo.hThread); @@ -421,61 +376,38 @@ static QString qt_create_commandline(const QString &program, const QStringList & } /*! - Creates a QByteArray of the \a environment in either UNICODE or - ansi representation. + Creates a QByteArray of the \a environment. */ static QByteArray qt_create_environment(const QStringList &environment) { QByteArray envlist; - if (!environment.isEmpty()) { - int pos = 0; - // add PATH if necessary (for DLL loading) - QByteArray path = qgetenv("PATH"); - QT_WA({ - if (environment.filter(QRegExp("^PATH=",Qt::CaseInsensitive)).isEmpty() - && !path.isNull()) { - QString tmp = QString(QLatin1String("PATH=%1")).arg(QString::fromLocal8Bit(path)); - uint tmpSize = sizeof(TCHAR) * (tmp.length()+1); - envlist.resize(envlist.size() + tmpSize ); - memcpy(envlist.data()+pos, tmp.utf16(), tmpSize); - pos += tmpSize; - } - // add the user environment - for (QStringList::ConstIterator it = environment.begin(); it != environment.end(); it++ ) { - QString tmp = *it; - uint tmpSize = sizeof(TCHAR) * (tmp.length()+1); - envlist.resize(envlist.size() + tmpSize); - memcpy(envlist.data()+pos, tmp.utf16(), tmpSize); - pos += tmpSize; - } - // add the 2 terminating 0 (actually 4, just to be on the safe side) - envlist.resize( envlist.size()+4 ); - envlist[pos++] = 0; - envlist[pos++] = 0; - envlist[pos++] = 0; - envlist[pos++] = 0; - }, { - if (environment.filter(QRegExp("^PATH=",Qt::CaseInsensitive)).isEmpty() && !path.isNull()) { - QByteArray tmp = QString("PATH=%1").arg(QString::fromLocal8Bit(path)).toLocal8Bit(); - uint tmpSize = tmp.length() + 1; - envlist.resize(envlist.size() + tmpSize); - memcpy(envlist.data()+pos, tmp.data(), tmpSize); - pos += tmpSize; - } - // add the user environment - for (QStringList::ConstIterator it = environment.begin(); it != environment.end(); it++) { - QByteArray tmp = (*it).toLocal8Bit(); - uint tmpSize = tmp.length() + 1; - envlist.resize(envlist.size() + tmpSize); - memcpy(envlist.data()+pos, tmp.data(), tmpSize); - pos += tmpSize; - } - // add the terminating 0 (actually 2, just to be on the safe side) - envlist.resize(envlist.size()+2); - envlist[pos++] = 0; - envlist[pos++] = 0; - }) + if (environment.isEmpty()) + return envlist; + + int pos = 0; + // add PATH if necessary (for DLL loading) + QByteArray path = qgetenv("PATH"); + if (environment.filter(QRegExp("^PATH=",Qt::CaseInsensitive)).isEmpty() && !path.isNull()) { + QString tmp = QString(QLatin1String("PATH=%1")).arg(QString::fromLocal8Bit(path)); + uint tmpSize = sizeof(wchar_t) * (tmp.length() + 1); + envlist.resize(envlist.size() + tmpSize); + memcpy(envlist.data() + pos, tmp.utf16(), tmpSize); + pos += tmpSize; } + // add the user environment + for (QStringList::ConstIterator it = environment.begin(); it != environment.end(); it++ ) { + QString tmp = *it; + uint tmpSize = sizeof(wchar_t) * (tmp.length() + 1); + envlist.resize(envlist.size() + tmpSize); + memcpy(envlist.data() + pos, tmp.utf16(), tmpSize); + pos += tmpSize; + } + // add the 2 terminating 0 (actually 4, just to be on the safe side) + envlist.resize(envlist.size() + 4); + envlist[pos++] = 0; + envlist[pos++] = 0; + envlist[pos++] = 0; + envlist[pos++] = 0; return envlist; } @@ -501,46 +433,24 @@ int Environment::execute(QStringList arguments, const QStringList &additionalEnv qDebug() << " " << additionalEnv; qDebug() << " " << removeEnv; #endif -// GetEnvironmentStrings is defined to GetEnvironmentStringsW when -// UNICODE is defined. We cannot use that, since we need to -// destinguish between unicode and ansi versions of the functions. -#if defined(UNICODE) && defined(GetEnvironmentStrings) -#undef GetEnvironmentStrings -#endif - // Create the full environment from the current environment and // the additionalEnv strings, then remove all variables defined // in removeEnv QMap fullEnvMap; - QT_WA({ - LPWSTR envStrings = GetEnvironmentStringsW(); - if (envStrings) { - int strLen = 0; - for (LPWSTR envString = envStrings; *(envString); envString += strLen + 1) { - strLen = wcslen(envString); - QString str = QString((const QChar*)envString, strLen); - if (!str.startsWith("=")) { // These are added by the system - int sepIndex = str.indexOf('='); - fullEnvMap.insert(str.left(sepIndex).toUpper(), str.mid(sepIndex +1)); - } - } - } - FreeEnvironmentStringsW(envStrings); - }, { - LPSTR envStrings = GetEnvironmentStrings(); - if (envStrings) { - int strLen = 0; - for (LPSTR envString = envStrings; *(envString); envString += strLen + 1) { - strLen = strlen(envString); - QString str = QLatin1String(envString); - if (!str.startsWith("=")) { // These are added by the system - int sepIndex = str.indexOf('='); - fullEnvMap.insert(str.left(sepIndex).toUpper(), str.mid(sepIndex +1)); - } + LPWSTR envStrings = GetEnvironmentStrings(); + if (envStrings) { + int strLen = 0; + for (LPWSTR envString = envStrings; *(envString); envString += strLen + 1) { + strLen = wcslen(envString); + QString str = QString((const QChar*)envString, strLen); + if (!str.startsWith("=")) { // These are added by the system + int sepIndex = str.indexOf('='); + fullEnvMap.insert(str.left(sepIndex).toUpper(), str.mid(sepIndex +1)); } } - FreeEnvironmentStringsA(envStrings); - }) + } + FreeEnvironmentStrings(envStrings); + // Add additionalEnv variables for (int i = 0; i < additionalEnv.count(); ++i) { const QString &str = additionalEnv.at(i); @@ -569,28 +479,14 @@ int Environment::execute(QStringList arguments, const QStringList &additionalEnv PROCESS_INFORMATION procInfo; memset(&procInfo, 0, sizeof(procInfo)); - bool couldExecute; - QT_WA({ - // Unicode version - STARTUPINFOW startInfo; - memset(&startInfo, 0, sizeof(startInfo)); - startInfo.cb = sizeof(startInfo); + STARTUPINFO startInfo; + memset(&startInfo, 0, sizeof(startInfo)); + startInfo.cb = sizeof(startInfo); - couldExecute = CreateProcessW(0, (WCHAR*)args.utf16(), + bool couldExecute = CreateProcess(0, (wchar_t*)args.utf16(), 0, 0, true, CREATE_UNICODE_ENVIRONMENT, envlist.isEmpty() ? 0 : envlist.data(), 0, &startInfo, &procInfo); - }, { - // Ansi version - STARTUPINFOA startInfo; - memset(&startInfo, 0, sizeof(startInfo)); - startInfo.cb = sizeof(startInfo); - - couldExecute = CreateProcessA(0, args.toLocal8Bit().data(), - 0, 0, true, 0, - envlist.isEmpty() ? 0 : envlist.data(), - 0, &startInfo, &procInfo); - }) if (couldExecute) { WaitForSingleObject(procInfo.hProcess, INFINITE); @@ -654,7 +550,7 @@ bool Environment::cpdir(const QString &srcDir, const QString &destDir) #endif QFile::remove(destFile); intermediate = QFile::copy(entry.absoluteFilePath(), destFile); - SetFileAttributesA(destFile.toLocal8Bit(), FILE_ATTRIBUTE_NORMAL); + SetFileAttributes((wchar_t*)destFile.utf16(), FILE_ATTRIBUTE_NORMAL); } if(!intermediate) { qDebug() << "cpdir: Failure for " << entry.fileName() << entry.isDir(); diff --git a/tools/configure/tools.cpp b/tools/configure/tools.cpp index f60f72c..708a537 100644 --- a/tools/configure/tools.cpp +++ b/tools/configure/tools.cpp @@ -201,8 +201,8 @@ void Tools::checkLicense(QMap &dictionary, QMapRelease(); diff --git a/tools/linguist/shared/profileevaluator.cpp b/tools/linguist/shared/profileevaluator.cpp index ef59543..47c1ec2 100644 --- a/tools/linguist/shared/profileevaluator.cpp +++ b/tools/linguist/shared/profileevaluator.cpp @@ -1949,9 +1949,9 @@ QStringList ProFileEvaluator::Private::values(const QString &variableName, ret = QLatin1String("Windows"); } else if (type == QLatin1String("name")) { DWORD name_length = 1024; - TCHAR name[1024]; + wchar_t name[1024]; if (GetComputerName(name, &name_length)) - ret = QString::fromUtf16((ushort*)name, name_length); + ret = QString::fromWCharArray(name); } else if (type == QLatin1String("version") || type == QLatin1String("version_string")) { QSysInfo::WinVersion ver = QSysInfo::WindowsVersion; if (type == QLatin1String("version")) diff --git a/tools/qtestlib/wince/cetest/activesyncconnection.cpp b/tools/qtestlib/wince/cetest/activesyncconnection.cpp index f047b79..e8ca8f2 100644 --- a/tools/qtestlib/wince/cetest/activesyncconnection.cpp +++ b/tools/qtestlib/wince/cetest/activesyncconnection.cpp @@ -270,8 +270,8 @@ bool ActiveSyncConnection::copyDirectoryFromDevice(const QString &deviceSource, } do { - QString srcFile = deviceSource + "\\" + QString::fromUtf16(data.cFileName); - QString destFile = localDest + "\\" + QString::fromUtf16(data.cFileName); + QString srcFile = deviceSource + "\\" + QString::fromWCharArray(data.cFileName); + QString destFile = localDest + "\\" + QString::fromWCharArray(data.cFileName); if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { if (recursive && !copyDirectoryFromDevice(srcFile, destFile, recursive)) { wprintf(L"Copy of subdirectory(%s) failed\n", srcFile.utf16()); @@ -306,8 +306,8 @@ bool ActiveSyncConnection::copyDirectory(const QString &srcDirectory, const QStr } do { - QString srcFile = srcDirectory + "\\" + QString::fromUtf16(data.cFileName); - QString destFile = destDirectory + "\\" + QString::fromUtf16(data.cFileName); + QString srcFile = srcDirectory + "\\" + QString::fromWCharArray(data.cFileName); + QString destFile = destDirectory + "\\" + QString::fromWCharArray(data.cFileName); if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { if (recursive && !copyDirectory(srcFile, destFile, recursive)) { wprintf(L"Copy of subdirectory(%s) failed\n", srcFile.utf16()); @@ -341,7 +341,7 @@ bool ActiveSyncConnection::deleteDirectory(const QString &directory, bool recurs return false; do { - QString FileName = directory + "\\" + QString::fromUtf16(FindFileData.cFileName); + QString FileName = directory + "\\" + QString::fromWCharArray(FindFileData.cFileName); if((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { if (recursive) if (!deleteDirectory(FileName, recursive, failIfContentExists)) diff --git a/tools/xmlpatterns/main.cpp b/tools/xmlpatterns/main.cpp index a5c2c41..2405d5d 100644 --- a/tools/xmlpatterns/main.cpp +++ b/tools/xmlpatterns/main.cpp @@ -194,7 +194,7 @@ protected: /* If we don't open stdout in "binary" mode on Windows, it will translate * 0xA into 0xD 0xA. See Trolltech task 173619, for an example. */ _setmode(_fileno(stdout), _O_BINARY); - m_stdout = QT_WA_INLINE(_wfdopen(_fileno(stdout), L"wb"),_fdopen(_fileno(stdout), "wb")); + m_stdout = _wfdopen(_fileno(stdout), L"wb"); out->open(m_stdout, QIODevice::WriteOnly); #else out->open(stdout, QIODevice::WriteOnly); -- cgit v0.12 From c447ce31632e25fdd40404cc96b6980aa0adcef8 Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Wed, 1 Jul 2009 11:50:26 +0200 Subject: qmake: Remove QT_WA and non-Unicode code paths, dropping Win9x and NT support Also, QString::fromUtf16() -> QString::fromWCharArray() Merge-request: 604 Reviewed-by: Marius Storm-Olsen --- qmake/generators/win32/msvc_vcproj.cpp | 43 ++++++---------------------------- qmake/option.cpp | 13 +++------- qmake/project.cpp | 6 ++--- 3 files changed, 13 insertions(+), 49 deletions(-) diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 079aa9f..50f78d7 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -120,14 +120,7 @@ static QString readRegistryKey(HKEY parentHandle, const QString &rSubkey) QString rSubkeyPath = keyPath(rSubkey); HKEY handle = 0; - LONG res; - QT_WA( { - res = RegOpenKeyExW(parentHandle, (WCHAR*)rSubkeyPath.utf16(), - 0, KEY_READ, &handle); - } , { - res = RegOpenKeyExA(parentHandle, rSubkeyPath.toLocal8Bit(), - 0, KEY_READ, &handle); - } ); + LONG res = RegOpenKeyEx(parentHandle, (wchar_t*)rSubkeyPath.utf16(), 0, KEY_READ, &handle); if (res != ERROR_SUCCESS) return QString(); @@ -135,11 +128,7 @@ static QString readRegistryKey(HKEY parentHandle, const QString &rSubkey) // get the size and type of the value DWORD dataType; DWORD dataSize; - QT_WA( { - res = RegQueryValueExW(handle, (WCHAR*)rSubkeyName.utf16(), 0, &dataType, 0, &dataSize); - }, { - res = RegQueryValueExA(handle, rSubkeyName.toLocal8Bit(), 0, &dataType, 0, &dataSize); - } ); + res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, &dataType, 0, &dataSize); if (res != ERROR_SUCCESS) { RegCloseKey(handle); return QString(); @@ -147,13 +136,8 @@ static QString readRegistryKey(HKEY parentHandle, const QString &rSubkey) // get the value QByteArray data(dataSize, 0); - QT_WA( { - res = RegQueryValueExW(handle, (WCHAR*)rSubkeyName.utf16(), 0, 0, - reinterpret_cast(data.data()), &dataSize); - }, { - res = RegQueryValueExA(handle, rSubkeyName.toLocal8Bit(), 0, 0, - reinterpret_cast(data.data()), &dataSize); - } ); + res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, 0, + reinterpret_cast(data.data()), &dataSize); if (res != ERROR_SUCCESS) { RegCloseKey(handle); return QString(); @@ -163,11 +147,7 @@ static QString readRegistryKey(HKEY parentHandle, const QString &rSubkey) switch (dataType) { case REG_EXPAND_SZ: case REG_SZ: { - QT_WA( { - result = QString::fromUtf16(((const ushort*)data.constData())); - }, { - result = QString::fromLatin1(data.constData()); - } ); + result = QString::fromWCharArray(((const wchar_t *)data.constData())); break; } @@ -175,12 +155,7 @@ static QString readRegistryKey(HKEY parentHandle, const QString &rSubkey) QStringList l; int i = 0; for (;;) { - QString s; - QT_WA( { - s = QString::fromUtf16((const ushort*)data.constData() + i); - }, { - s = QString::fromLatin1(data.constData() + i); - } ); + QString s = QString::fromWCharArray((const wchar_t *)data.constData() + i); i += s.length() + 1; if (s.isEmpty()) @@ -193,11 +168,7 @@ static QString readRegistryKey(HKEY parentHandle, const QString &rSubkey) case REG_NONE: case REG_BINARY: { - QT_WA( { - result = QString::fromUtf16((const ushort*)data.constData(), data.size()/2); - }, { - result = QString::fromLatin1(data.constData(), data.size()); - } ); + result = QString::fromWCharArray((const wchar_t *)data.constData(), data.size() / 2); break; } diff --git a/qmake/option.cpp b/qmake/option.cpp index 0e4a608..5f8c4f4 100644 --- a/qmake/option.cpp +++ b/qmake/option.cpp @@ -716,16 +716,9 @@ QString qmake_libraryInfoFile() { QString ret; #if defined( Q_OS_WIN ) - QFileInfo filePath; - QT_WA({ - unsigned short module_name[256]; - GetModuleFileNameW(0, reinterpret_cast(module_name), sizeof(module_name)); - filePath = QString::fromUtf16(module_name); - }, { - char module_name[256]; - GetModuleFileNameA(0, module_name, sizeof(module_name)); - filePath = QString::fromLocal8Bit(module_name); - }); + wchar_t module_name[MAX_PATH]; + GetModuleFileName(0, module_name, MAX_PATH); + QFileInfo filePath = QString::fromWCharArray(module_name); ret = filePath.filePath(); #else QString argv0 = QFile::decodeName(QByteArray(Option::application_argv0)); diff --git a/qmake/project.cpp b/qmake/project.cpp index 047a5e3..704d8a6 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -3117,9 +3117,9 @@ QStringList &QMakeProject::values(const QString &_var, QMap Date: Wed, 1 Jul 2009 11:50:29 +0200 Subject: tests: Remove QT_WA and non-Unicode code paths, dropping Win9x and NT support Merge-request: 604 Reviewed-by: Marius Storm-Olsen --- tests/auto/qaccessibility/tst_qaccessibility.cpp | 6 +- tests/auto/qapplication/tst_qapplication.cpp | 6 +- tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp | 2 +- tests/auto/qfile/tst_qfile.cpp | 91 +++++----------- tests/auto/qfileinfo/tst_qfileinfo.cpp | 31 ++---- tests/auto/qitemview/tst_qitemview.cpp | 2 +- tests/auto/qlocale/tst_qlocale.cpp | 31 +----- tests/auto/qpixmap/tst_qpixmap.cpp | 7 +- tests/auto/qsettings/tst_qsettings.cpp | 6 -- tests/auto/qsharedmemory/src/qsystemlock_win.cpp | 26 ++--- tests/auto/qstring/tst_qstring.cpp | 8 +- tests/auto/qstyle/tst_qstyle.cpp | 2 +- tests/auto/qtcpserver/tst_qtcpserver.cpp | 120 +++++++++------------ tests/auto/qtimer/tst_qtimer.cpp | 2 +- tests/auto/qwidget/tst_qwidget.cpp | 8 +- .../qwineventnotifier/tst_qwineventnotifier.cpp | 7 +- .../auto/windowsmobile/test/tst_windowsmobile.cpp | 2 +- tests/benchmarks/qdiriterator/main.cpp | 2 +- .../qdiriterator/qfilesystemiterator.cpp | 19 +--- tests/benchmarks/qfile/main.cpp | 12 +-- 20 files changed, 133 insertions(+), 257 deletions(-) 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 2fa7584..85494af 100644 --- a/tests/auto/qapplication/tst_qapplication.cpp +++ b/tests/auto/qapplication/tst_qapplication.cpp @@ -755,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); 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); #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 (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/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 (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(buff.data()), - buff.size()/2); - } , { - cnt = GetLocaleInfoA(id, type, - buff.data(), buff.size()); - }); + cnt = GetLocaleInfo(id, type, reinterpret_cast(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(buff.data())); - } , { - result = QString::fromLocal8Bit(buff.data()); - }); - return result; + return QString::fromWCharArray(reinterpret_cast(buff.data())); } static void setWinLocaleInfo(LCTYPE type, const QString &value) { LCID id = GetThreadLocale(); - - QT_WA({ - SetLocaleInfoW(id, type, reinterpret_cast(value.utf16())); - } , { - SetLocaleInfoA(id, type, value.toLocal8Bit()); - }); + SetLocaleInfo(id, type, reinterpret_cast(value.utf16())); } class RestoreLocaleHelper { 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/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/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/tst_qstyle.cpp b/tests/auto/qstyle/tst_qstyle.cpp index 4009e66..2cb5080 100644 --- a/tests/auto/qstyle/tst_qstyle.cpp +++ b/tests/auto/qstyle/tst_qstyle.cpp @@ -91,7 +91,7 @@ #include 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 (QString::fromLatin1("Smartphone").utf16()), tszPlatform)) 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/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/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 1430146..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 (platformString.utf16()), tszPlatform)) @@ -3433,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 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/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 (platformString.utf16()), tszPlatform)) diff --git a/tests/benchmarks/qdiriterator/main.cpp b/tests/benchmarks/qdiriterator/main.cpp index 13128f7..1a5ffbb 100644 --- a/tests/benchmarks/qdiriterator/main.cpp +++ b/tests/benchmarks/qdiriterator/main.cpp @@ -107,7 +107,7 @@ static int posix_helper(const wchar_t *dirpath) wchar_t appendedPath[MAX_PATH]; wcscpy(appendedPath, dirpath); wcscat(appendedPath, L"\\*"); - hSearch = FindFirstFileW(appendedPath, &fd); + hSearch = FindFirstFile(appendedPath, &fd); appendedPath[origDirPathLength] = 0; if (hSearch == INVALID_HANDLE_VALUE) { diff --git a/tests/benchmarks/qdiriterator/qfilesystemiterator.cpp b/tests/benchmarks/qdiriterator/qfilesystemiterator.cpp index 1ef600b..47720f1 100644 --- a/tests/benchmarks/qdiriterator/qfilesystemiterator.cpp +++ b/tests/benchmarks/qdiriterator/qfilesystemiterator.cpp @@ -108,17 +108,6 @@ QT_BEGIN_NAMESPACE -#ifdef Q_OS_WIN -inline QString convertString(TCHAR* sz) -{ -#ifdef UNICODE - return QString::fromUtf16(sz); -#else - return QString::fromLocal8Bit(sz); -#endif -} -#endif - class QFileSystemIteratorPrivate { public: @@ -202,7 +191,7 @@ QFileSystemIteratorPrivate::~QFileSystemIteratorPrivate() } #ifdef Q_OS_WIN -static bool isDotOrDotDot(const TCHAR* name) +static bool isDotOrDotDot(const wchar_t* name) { if (name[0] == L'.' && name[1] == 0) return true; @@ -339,7 +328,7 @@ bool QFileSystemIteratorPrivate::advanceHelper() if (m_entry->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { QByteArray ba = m_dirPaths.top(); ba += '\\'; - ba += convertString(m_entry->cFileName); + ba += QString::fromWCharArray(m_entry->cFileName); pushSubDirectory(ba); } #else @@ -634,7 +623,7 @@ QString QFileSystemIterator::fileName() const if (d->m_currentDirShown == QFileSystemIteratorPrivate::ShowDotDotDir) return QLatin1String("@@"); #ifdef Q_OS_WIN - return convertString(d->m_entry->cFileName); + return QString::fromWCharArray(d->m_entry->cFileName); #else return QString::fromLocal8Bit(d->m_entry->d_name); #endif @@ -659,7 +648,7 @@ QString QFileSystemIterator::filePath() const else if (d->m_entry) { ba += '/'; #ifdef Q_OS_WIN - ba += convertString(d->m_entry->cFileName); + ba += QString::fromWCharArray(d->m_entry->cFileName); #else ba += d->m_entry->d_name; #endif diff --git a/tests/benchmarks/qfile/main.cpp b/tests/benchmarks/qfile/main.cpp index 2fa425d..5360eb5 100644 --- a/tests/benchmarks/qfile/main.cpp +++ b/tests/benchmarks/qfile/main.cpp @@ -275,11 +275,11 @@ void tst_qfile::readBigFile() HANDLE hndl; // ensure we don't account string conversion - TCHAR* cfilename = (TCHAR*)filename.utf16(); + wchar_t* cfilename = (wchar_t*)filename.utf16(); hndl = CreateFile(cfilename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0); Q_ASSERT(hndl); - TCHAR* nativeBuffer = new TCHAR[BUFSIZE]; + wchar_t* nativeBuffer = new wchar_t[BUFSIZE]; DWORD numberOfBytesRead; QBENCHMARK { @@ -358,7 +358,7 @@ void tst_qfile::seek() HANDLE hndl; // ensure we don't account string conversion - TCHAR* cfilename = (TCHAR*)filename.utf16(); + wchar_t* cfilename = (wchar_t*)filename.utf16(); hndl = CreateFile(cfilename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0); Q_ASSERT(hndl); @@ -441,7 +441,7 @@ void tst_qfile::open() HANDLE hndl; // ensure we don't account string conversion - TCHAR* cfilename = (TCHAR*)filename.utf16(); + wchar_t* cfilename = (wchar_t*)filename.utf16(); QBENCHMARK { hndl = CreateFile(cfilename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0); @@ -620,11 +620,11 @@ void tst_qfile::readSmallFiles() HANDLE hndl; // ensure we don't account string conversion - TCHAR* cfilename = (TCHAR*)filename.utf16(); + wchar_t* cfilename = (wchar_t*)filename.utf16(); hndl = CreateFile(cfilename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0); Q_ASSERT(hndl); - TCHAR* nativeBuffer = new TCHAR[BUFSIZE]; + wchar_t* nativeBuffer = new wchar_t[BUFSIZE]; DWORD numberOfBytesRead; QBENCHMARK { do { -- cgit v0.12 From a69160c5f4ef146f5e9922161bcff9c6fed213c7 Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Wed, 1 Jul 2009 11:50:33 +0200 Subject: examples: QString::fromUtf16() -> QString::fromWCharArray() Merge-request: 604 Reviewed-by: Marius Storm-Olsen --- examples/activeqt/dotnet/wrapper/lib/tools.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/activeqt/dotnet/wrapper/lib/tools.cpp b/examples/activeqt/dotnet/wrapper/lib/tools.cpp index 856b5c8..eac2d78 100644 --- a/examples/activeqt/dotnet/wrapper/lib/tools.cpp +++ b/examples/activeqt/dotnet/wrapper/lib/tools.cpp @@ -56,6 +56,6 @@ String *QStringToString(const QString &qstring) QString StringToQString(String *string) { const wchar_t __pin *chars = PtrToStringChars(string); - return QString::fromUtf16((const ushort *)chars); + return QString::fromWCharArray(chars); } //! [1] -- cgit v0.12 From a6e32ae1c84984041107a83db9307caffbda9849 Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Wed, 1 Jul 2009 11:50:36 +0200 Subject: Make the macros QT_WA & QT_WA_INLINE only use the unicode part Merge-request: 604 Reviewed-by: Marius Storm-Olsen --- src/corelib/global/qglobal.h | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 00a9466..a522bcf 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1420,17 +1420,9 @@ inline QT3_SUPPORT bool qt_winUnicode() { return true; } inline QT3_SUPPORT int qWinVersion() { return QSysInfo::WindowsVersion; } #endif -#ifdef Q_OS_WINCE -#define QT_WA(uni, ansi) uni -#define QT_WA_INLINE(uni, ansi) (uni) -#elif defined(UNICODE) -#define QT_WA(uni, ansi) if (!(QSysInfo::windowsVersion() & QSysInfo::WV_DOS_based)) { uni } else { ansi } +#define QT_WA(unicode, ansi) unicode +#define QT_WA_INLINE(unicode, ansi) (unicode) -#define QT_WA_INLINE(uni, ansi) (!(QSysInfo::windowsVersion() & QSysInfo::WV_DOS_based) ? uni : ansi) -#else -#define QT_WA(uni, ansi) ansi -#define QT_WA_INLINE(uni, ansi) ansi -#endif #endif /* Q_WS_WIN */ #ifndef Q_OUTOFLINE_TEMPLATE -- cgit v0.12 From 8a8c9a2f668bedc7dd7ecf1f4f025a1587ca9fc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Luthi?= Date: Wed, 1 Jul 2009 12:03:52 +0200 Subject: Fix a few typos Merge-request: 788 Reviewed-by: Norwegian Rock Cat --- src/gui/kernel/qapplication_mac.mm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm index ad9f220..e7d5a79 100644 --- a/src/gui/kernel/qapplication_mac.mm +++ b/src/gui/kernel/qapplication_mac.mm @@ -1069,7 +1069,7 @@ void qt_init(QApplicationPrivate *priv, int) if (GetCurrentProcess(&psn) == noErr) { // Jambi needs to transform itself since most people aren't "used" // to putting things in bundles, but other people may actually not - // want to tranform the process (running as a helper or somethng) + // want to tranform the process (running as a helper or something) // so don't do that for them. This means checking both LSUIElement // and LSBackgroundOnly. If you set them both... well, you // shouldn't do that. @@ -1760,7 +1760,7 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event if(window) { HIViewRef hiview; if(HIViewGetViewForMouseEvent(HIViewGetRoot(window), event, &hiview) == noErr) { - widget = QWidget::find((WId)hiview);; + widget = QWidget::find((WId)hiview); if (widget) { // Make sure we didn't pass over a widget with a "fake hole" in it. QWidget *otherWidget = QApplication::widgetAt(where.h, where.v); @@ -1878,8 +1878,8 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event QMacTabletHash *tabletHash = qt_mac_tablet_hash(); if (!tabletHash->contains(tabletPointRec.deviceID)) { - qWarning("QCocoaView handleTabletEvent: This tablet device is unknown" - " (received no proximity event for it). Discarding event."); + qWarning("handleTabletEvent: This tablet device is unknown" + " (received no proximity event for it). Discarding event."); return false; } QTabletDeviceData &deviceData = tabletHash->operator[](tabletPointRec.deviceID); @@ -1922,7 +1922,7 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event QApplication::sendSpontaneousEvent(widget, &e); if (e.isAccepted()) { #if defined(DEBUG_MOUSE_MAPS) - qDebug("Bail out early due to table acceptance"); + qDebug("Bail out early due to tablet acceptance"); #endif break; } -- cgit v0.12 From 82e825ed841bce324a6892fcbace03f9936d4f4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Luthi?= Date: Wed, 1 Jul 2009 12:03:54 +0200 Subject: Fix tablet events Tablet events should set the qt_button_down, otherwise if the tablet moves onto a widget that does not accept a tablet event, it will set qt_button_down and effectively "grab" the mouse. However, we should only do this if we accept the tablet event. Merge-request: 788 Reviewed-by: Norwegian Rock Cat --- src/gui/kernel/qapplication_mac.mm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm index e7d5a79..04f4cc9 100644 --- a/src/gui/kernel/qapplication_mac.mm +++ b/src/gui/kernel/qapplication_mac.mm @@ -1921,6 +1921,11 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event tp, rotation, z, modifiers, deviceData.tabletUniqueID); QApplication::sendSpontaneousEvent(widget, &e); if (e.isAccepted()) { + if (t == QEvent::TabletPress) { + qt_button_down = widget; + } else if (t == QEvent::TabletRelease) { + qt_button_down = 0; + } #if defined(DEBUG_MOUSE_MAPS) qDebug("Bail out early due to tablet acceptance"); #endif -- cgit v0.12 From 3618227de7036a091ea8187a20434470c0c792dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Luthi?= Date: Wed, 1 Jul 2009 12:03:55 +0200 Subject: Never discard TabletRelease events as they may be delivered *after* TabletLeaveProximity events Merge-request: 788 Reviewed-by: Norwegian Rock Cat --- src/gui/kernel/qapplication_mac.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm index 04f4cc9..ce4e422 100644 --- a/src/gui/kernel/qapplication_mac.mm +++ b/src/gui/kernel/qapplication_mac.mm @@ -1877,7 +1877,8 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event tablet_button_state = new_tablet_button_state; QMacTabletHash *tabletHash = qt_mac_tablet_hash(); - if (!tabletHash->contains(tabletPointRec.deviceID)) { + if (!tabletHash->contains(tabletPointRec.deviceID) && t != QEvent::TabletRelease) { + // Never discard TabletRelease events as they may be delivered *after* TabletLeaveProximity events qWarning("handleTabletEvent: This tablet device is unknown" " (received no proximity event for it). Discarding event."); return false; -- cgit v0.12 From ac8e76bc6d7cc3dbb1e64949bc6034697d9d9ba1 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Wed, 1 Jul 2009 12:29:26 +0200 Subject: doc: Changed wording in some stub callbacks. --- src/xml/sax/qxml.cpp | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/xml/sax/qxml.cpp b/src/xml/sax/qxml.cpp index d776cc4..6be6988 100644 --- a/src/xml/sax/qxml.cpp +++ b/src/xml/sax/qxml.cpp @@ -2403,7 +2403,7 @@ events are reported. /*! \reimp - Does nothing. + This reimplementation does nothing. */ void QXmlDefaultHandler::setDocumentLocator(QXmlLocator*) { @@ -2412,7 +2412,7 @@ void QXmlDefaultHandler::setDocumentLocator(QXmlLocator*) /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::startDocument() { @@ -2422,7 +2422,7 @@ bool QXmlDefaultHandler::startDocument() /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::endDocument() { @@ -2432,7 +2432,7 @@ bool QXmlDefaultHandler::endDocument() /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::startPrefixMapping(const QString&, const QString&) { @@ -2442,7 +2442,7 @@ bool QXmlDefaultHandler::startPrefixMapping(const QString&, const QString&) /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::endPrefixMapping(const QString&) { @@ -2452,7 +2452,7 @@ bool QXmlDefaultHandler::endPrefixMapping(const QString&) /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::startElement(const QString&, const QString&, const QString&, const QXmlAttributes&) @@ -2463,7 +2463,7 @@ bool QXmlDefaultHandler::startElement(const QString&, const QString&, /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::endElement(const QString&, const QString&, const QString&) @@ -2474,7 +2474,7 @@ bool QXmlDefaultHandler::endElement(const QString&, const QString&, /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::characters(const QString&) { @@ -2484,7 +2484,7 @@ bool QXmlDefaultHandler::characters(const QString&) /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::ignorableWhitespace(const QString&) { @@ -2494,7 +2494,7 @@ bool QXmlDefaultHandler::ignorableWhitespace(const QString&) /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::processingInstruction(const QString&, const QString&) @@ -2505,7 +2505,7 @@ bool QXmlDefaultHandler::processingInstruction(const QString&, /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::skippedEntity(const QString&) { @@ -2515,7 +2515,7 @@ bool QXmlDefaultHandler::skippedEntity(const QString&) /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::warning(const QXmlParseException&) { @@ -2525,7 +2525,7 @@ bool QXmlDefaultHandler::warning(const QXmlParseException&) /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::error(const QXmlParseException&) { @@ -2535,7 +2535,7 @@ bool QXmlDefaultHandler::error(const QXmlParseException&) /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::fatalError(const QXmlParseException&) { @@ -2545,7 +2545,7 @@ bool QXmlDefaultHandler::fatalError(const QXmlParseException&) /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::notationDecl(const QString&, const QString&, const QString&) @@ -2556,7 +2556,7 @@ bool QXmlDefaultHandler::notationDecl(const QString&, const QString&, /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::unparsedEntityDecl(const QString&, const QString&, const QString&, const QString&) @@ -2590,7 +2590,7 @@ QString QXmlDefaultHandler::errorString() const /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::startDTD(const QString&, const QString&, const QString&) { @@ -2600,7 +2600,7 @@ bool QXmlDefaultHandler::startDTD(const QString&, const QString&, const QString& /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::endDTD() { @@ -2610,7 +2610,7 @@ bool QXmlDefaultHandler::endDTD() /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::startEntity(const QString&) { @@ -2620,7 +2620,7 @@ bool QXmlDefaultHandler::startEntity(const QString&) /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::endEntity(const QString&) { @@ -2630,7 +2630,7 @@ bool QXmlDefaultHandler::endEntity(const QString&) /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::startCDATA() { @@ -2640,7 +2640,7 @@ bool QXmlDefaultHandler::startCDATA() /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::endCDATA() { @@ -2650,7 +2650,7 @@ bool QXmlDefaultHandler::endCDATA() /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::comment(const QString&) { @@ -2660,7 +2660,7 @@ bool QXmlDefaultHandler::comment(const QString&) /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::attributeDecl(const QString&, const QString&, const QString&, const QString&, const QString&) { @@ -2670,7 +2670,7 @@ bool QXmlDefaultHandler::attributeDecl(const QString&, const QString&, const QSt /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::internalEntityDecl(const QString&, const QString&) { @@ -2680,7 +2680,7 @@ bool QXmlDefaultHandler::internalEntityDecl(const QString&, const QString&) /*! \reimp - Does nothing. + This reimplementation does nothing. */ bool QXmlDefaultHandler::externalEntityDecl(const QString&, const QString&, const QString&) { -- cgit v0.12 From d43a10d6d9a5f13fc8deac052926720927e09e83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Wed, 1 Jul 2009 13:53:41 +0200 Subject: Compiler warnings. --- src/gui/graphicsview/qgraphicsitem.cpp | 2 ++ src/gui/graphicsview/qgraphicsproxywidget.cpp | 1 - src/gui/graphicsview/qgraphicsscene.cpp | 2 +- src/gui/kernel/qwidget.cpp | 2 ++ 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index e8ed97f..2223f5d 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -6329,6 +6329,8 @@ void QGraphicsItem::releaseGesture(int gestureId) */ void QGraphicsItem::setGestureEnabled(int gestureId, bool enable) { + Q_UNUSED(gestureId); + Q_UNUSED(enable); //### } diff --git a/src/gui/graphicsview/qgraphicsproxywidget.cpp b/src/gui/graphicsview/qgraphicsproxywidget.cpp index ab94679..f081222 100644 --- a/src/gui/graphicsview/qgraphicsproxywidget.cpp +++ b/src/gui/graphicsview/qgraphicsproxywidget.cpp @@ -878,7 +878,6 @@ bool QGraphicsProxyWidget::event(QEvent *event) case QEvent::GraphicsSceneGesture: { qDebug() << "QGraphicsProxyWidget: graphicsscenegesture"; if (d->widget && d->widget->isVisible()) { - QGraphicsSceneGestureEvent *ge = static_cast(event); //### TODO: widget->childAt(): decompose gesture event and find widget under hotspots. //QGestureManager::instance()->sendGestureEvent(d->widget, ge->gestures().toSet(), ge->cancelledGestures()); return true; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index d790640..e50ee94 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4122,7 +4122,6 @@ void QGraphicsScenePrivate::sendGestureEvent(const QSet &gestures, co continue; } QGesturePrivate *gd = g->d_func(); - QGraphicsItem *item = gd->graphicsItem; gd->graphicsItem = 0; //### THIS IS BS, DONT FORGET TO REWRITE THIS CODE @@ -6042,6 +6041,7 @@ void QGraphicsScenePrivate::grabGesture(QGraphicsItem *item, int gestureId) void QGraphicsScenePrivate::releaseGesture(QGraphicsItem *item, int gestureId) { + Q_UNUSED(gestureId); itemsWithGestures.remove(item); //### } diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 1b31318..9a834aa 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -11110,6 +11110,8 @@ void QWidget::releaseGesture(int gestureId) */ void QWidget::setGestureEnabled(int gestureId, bool enable) { + Q_UNUSED(gestureId); + Q_UNUSED(enable); //### } -- cgit v0.12 From 7bf505a54379388b292df528114d6e2dd8d9d4d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Wed, 1 Jul 2009 13:55:16 +0200 Subject: Fixed cleanup of glyph cache textures in the GL 2 engine. This could potentially crash when a context was destroyed before the actual font engine holding the QGLTextureGlyphCache was destroyed. Reviewed-by: Samuel --- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 29 +++++++++++++++++++--- src/opengl/qgl_p.h | 4 +++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 4bf5d4c..edc7c44 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -88,8 +88,9 @@ static const GLuint QT_IMAGE_TEXTURE_UNIT = 0; //Can be the same as brush static const GLuint QT_MASK_TEXTURE_UNIT = 1; static const GLuint QT_BACKGROUND_TEXTURE_UNIT = 2; -class QGLTextureGlyphCache : public QTextureGlyphCache +class QGLTextureGlyphCache : public QObject, public QTextureGlyphCache { + Q_OBJECT public: QGLTextureGlyphCache(QGLContext *context, QFontEngineGlyphCache::Type type, const QTransform &matrix); ~QGLTextureGlyphCache(); @@ -105,6 +106,24 @@ public: inline void setPaintEnginePrivate(QGL2PaintEngineExPrivate *p) { pex = p; } + +public Q_SLOTS: + void contextDestroyed(const QGLContext *context) { + if (context == ctx) { + QList shares = qgl_share_reg()->shares(ctx); + if (shares.isEmpty()) { + glDeleteFramebuffers(1, &m_fbo); + if (m_width || m_height) + glDeleteTextures(1, &m_texture); + } else { + // since the context holding the texture is shared, and + // about to be destroyed, we have to transfer ownership + // of the texture to one of the share contexts + ctx = const_cast(shares.at(0)); + } + } + } + private: QGLContext *ctx; @@ -126,6 +145,8 @@ QGLTextureGlyphCache::QGLTextureGlyphCache(QGLContext *context, QFontEngineGlyph , m_height(0) { glGenFramebuffers(1, &m_fbo); + connect(QGLSignalProxy::instance(), SIGNAL(aboutToDestroyContext(const QGLContext *)), + SLOT(contextDestroyed(const QGLContext *))); } QGLTextureGlyphCache::~QGLTextureGlyphCache() @@ -251,7 +272,7 @@ QGL2PaintEngineExPrivate::~QGL2PaintEngineExPrivate() void QGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id) { // glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); //### Is it always this texture unit? - if (id != -1 && id == lastTexture) + if (id != GLuint(-1) && id == lastTexture) return; lastTexture = id; @@ -1408,7 +1429,7 @@ void QGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op) if (state()->matrix.type() <= QTransform::TxScale) { rect = state()->matrix.mapRect(rect); - if (d->use_system_clip && rect.contains(d->systemClip.boundingRect()) + if ((d->use_system_clip && rect.contains(d->systemClip.boundingRect())) || rect.contains(QRect(0, 0, d->width, d->height))) return; } @@ -1606,3 +1627,5 @@ QOpenGL2PaintEngineState::~QOpenGL2PaintEngineState() } QT_END_NAMESPACE + +#include "qpaintengineex_opengl2.moc" diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 85e9bd7..ac19d64 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -421,6 +421,10 @@ public: removeShare(oldContext); } + QList shares(const QGLContext *context) { + return reg.values(context); + } + private: QGLSharingHash reg; }; -- cgit v0.12 From 145e17f6cc405dd935451f0151b1a8a451c78f71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Wed, 1 Jul 2009 14:01:54 +0200 Subject: Compiler warning. --- src/gui/graphicsview/qgraphicsscene.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 9de6598..8fdf651 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -297,8 +297,8 @@ QGraphicsScenePrivate::QGraphicsScenePrivate() allItemsIgnoreHoverEvents(true), allItemsUseDefaultCursor(true), painterStateProtection(true), - style(0), sortCacheEnabled(false), + style(0), allItemsIgnoreTouchEvents(true) { } -- cgit v0.12 From 66a281ab76303074cd9cbb6cd22dcc5f3dbe8454 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 1 Jul 2009 14:40:51 +0200 Subject: Made QPainter / OpenGL intermixing in hellogl_es2 work properly again. Need to call syncState() to let the paint engine set depth clipping state parameters back to their OpenGL defaults. Reviewed-by: Trond --- examples/opengl/hellogl_es2/glwidget.cpp | 3 +++ src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/examples/opengl/hellogl_es2/glwidget.cpp b/examples/opengl/hellogl_es2/glwidget.cpp index 6b08662..bb07b22 100644 --- a/examples/opengl/hellogl_es2/glwidget.cpp +++ b/examples/opengl/hellogl_es2/glwidget.cpp @@ -41,6 +41,7 @@ #include "glwidget.h" #include +#include #include #include "bubble.h" @@ -265,6 +266,8 @@ void GLWidget::paintGL() QPainter painter; painter.begin(this); + painter.paintEngine()->syncState(); + glClearColor(0.1f, 0.1f, 0.2f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_TEXTURE_2D); diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index edc7c44..f261ca2 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -676,6 +676,11 @@ void QGL2PaintEngineEx::sync() glDisable(GL_BLEND); glActiveTexture(GL_TEXTURE0); + glDisable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + glDepthMask(true); + glClearDepth(1); + d->needsSync = true; } -- cgit v0.12 From e14d27dc775d508dc7300e36ba6a3809eb3f61e4 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Wed, 1 Jul 2009 14:34:21 +0200 Subject: Implement hitTest Cocoa calls hitTest on our view to determine if the view should get the mouse press. We always said, "yes" and did all the logic ourselves. Turns out that we can say "no" if I'm transparent to mouse events and remove all that code where we do all the work ourselves. Big maintenance win! For the time being I've kept the "transparentViewForEvent" method since it might be useful for others, but no one is using it at the moment and we may just kill it soon. HitTest should handle this situation correctly. --- src/gui/kernel/qcocoaview_mac.mm | 17 ++++++------- src/gui/kernel/qt_cocoa_helpers_mac.mm | 44 ---------------------------------- 2 files changed, 7 insertions(+), 54 deletions(-) diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 28179b7..64cdae6 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -557,6 +557,13 @@ extern "C" { return !qwidget->testAttribute(Qt::WA_MacNoClickThrough); } +- (NSView *)hitTest:(NSPoint)aPoint +{ + if (qwidget->testAttribute(Qt::WA_TransparentForMouseEvents)) + return nil; // You cannot hit a transparent for mouse event widget. + return [super hitTest:aPoint]; +} + - (void)updateTrackingAreas { QMacCocoaAutoReleasePool pool; @@ -793,16 +800,6 @@ extern "C" { Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([theEvent modifierFlags]); QWidget *widgetToGetMouse = qwidget; - if (widgetToGetMouse->testAttribute(Qt::WA_TransparentForMouseEvents)) { - // Simulate passing the event through since Cocoa doesn't do that for us. - // Start by building a tree up. - NSView *candidateView = [self viewUnderTransparentForMouseView:self - widget:widgetToGetMouse - withWindowPoint:windowPoint]; - if (candidateView != nil) { - widgetToGetMouse = QWidget::find(WId(candidateView)); - } - } // Mouse wheel deltas seem to tick in at increments of 0.1. Qt widgets // expect the delta to be a multiple of 120. diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index f5f381e..073a00e 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -894,50 +894,6 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev NSPoint localPoint = [tmpView convertPoint:windowPoint fromView:nil]; QPoint qlocalPoint(localPoint.x, localPoint.y); - if (widgetToGetMouse->testAttribute(Qt::WA_TransparentForMouseEvents)) { - // Simulate passing the event through since Cocoa doesn't do that for us. - // Start by building a tree up. - NSView *candidateView = [theView viewUnderTransparentForMouseView:tmpView - widget:widgetToGetMouse - withWindowPoint:windowPoint]; - if (candidateView != nil) { - // Fast-track our views, since dispatching trough the normal ways - // would just end up going through here anyway. - if ([candidateView isKindOfClass:[QT_MANGLE_NAMESPACE(QCocoaView) class]]) { - return qt_mac_handleMouseEvent(candidateView, theEvent, eventType, button); - } else { - switch (eventType) { - default: - qWarning("not handled! %d", eventType); - break; - case QEvent::MouseMove: - [candidateView mouseMoved:theEvent]; - break; - case QEvent::MouseButtonPress: - if (button == Qt::LeftButton) - [candidateView mouseDown:theEvent]; - else if (button == Qt::RightButton) - [candidateView rightMouseDown:theEvent]; - else - [candidateView otherMouseDown:theEvent]; - break; - case QEvent::MouseButtonRelease: - if (button == Qt::LeftButton) - [candidateView mouseUp:theEvent]; - else if (button == Qt::RightButton) - [candidateView rightMouseUp:theEvent]; - else - [candidateView otherMouseUp:theEvent]; - break; - } - return true; // We've done the dispatching, no need go further. - } - } - // Nothing below me return false - return false; - } - - EventRef carbonEvent = static_cast(const_cast([theEvent eventRef])); if (qt_mac_sendMacEventToWidget(widgetToGetMouse, carbonEvent)) return true; -- cgit v0.12 From 1d32cdf73843ba98104fdbc6d5d0a296dbb689b0 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Wed, 1 Jul 2009 14:34:43 +0200 Subject: Remove this stale function. --- src/gui/kernel/qapplication_mac.mm | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm index ce4e422..0884976 100644 --- a/src/gui/kernel/qapplication_mac.mm +++ b/src/gui/kernel/qapplication_mac.mm @@ -1367,29 +1367,6 @@ QWidget *QApplication::topLevelAt(const QPoint &p) #endif } -static QWidget *qt_mac_recursive_widgetAt(QWidget *widget, int x, int y) -{ - if (!widget) - return 0; - const QObjectList kids = widget->children(); - for(int i = kids.size()-1; i >= 0; --i) { - if ( QWidget *kid = qobject_cast(kids.at(i)) ) { - if (kid->isVisible() && !kid->isTopLevel() && - !kid->testAttribute(Qt::WA_TransparentForMouseEvents)) { - const int wx=kid->x(), wy=kid->y(), - wx2=wx+kid->width(), wy2=wy+kid->height(); - if (x >= wx && y >= wy && x < wx2 && y < wy2) { - const QRegion mask = kid->mask(); - if (!mask.isEmpty() && !mask.contains(QPoint(x-wx, y-wy))) - continue; - return qt_mac_recursive_widgetAt(kid, x-wx, y-wy); - } - } - } - } - return widget; -} - /***************************************************************************** Main event loop *****************************************************************************/ -- cgit v0.12 From 7ab895f576b8ef8380838778958fae651a550f79 Mon Sep 17 00:00:00 2001 From: Suneel BS Date: Fri, 8 May 2009 11:09:45 +0530 Subject: Fixed inheritance of some attributes in SVG. Fixed inheritance of stroke attributes, the font-size and text-anchor attribute. Autotest added by Kim. Reviewed-by: Kim --- src/svg/qsvghandler.cpp | 244 +++++++++++++++++---------- src/svg/qsvgnode.cpp | 2 +- src/svg/qsvgstyle.cpp | 8 +- src/svg/qsvgstyle_p.h | 12 +- tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp | 124 ++++++++++++++ 5 files changed, 294 insertions(+), 96 deletions(-) diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index 345dcf3..5950fac 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -908,103 +908,155 @@ static void parsePen(QSvgNode *node, //qDebug()<<"Node "<type()<<", attrs are "<(node->styleProperty( - QSvgStyleProperty::STROKE)); - if (!inherited) - inherited = static_cast(node->parent()->styleProperty( - QSvgStyleProperty::STROKE)); - QPen pen(handler->defaultPen()); - if (inherited) - pen = inherited->qpen(); + /* All the below checks needed because g (or any container element) can have only one of these attributes. + * If it doesn't has any one of these, then processing below not needed */ + + if (!value.isEmpty() || !width.isEmpty() || !dashArray.isEmpty() || !linecap.isEmpty() || + !linejoin.isEmpty() || !miterlimit.isEmpty() || !opacity.isEmpty() || !dashOffset.isEmpty() ) { + //if (value != QLatin1String("none")) { + /* If stroke = "none" then also, we need to parse below, because elements like 'g' may + have other defined stroke attributes, which will be inherited by its children */ + QSvgStrokeStyle *inherited = + static_cast(node->parent()->styleProperty( + QSvgStyleProperty::STROKE)); + + QPen pen(handler->defaultPen()); + bool stroke = false; + if (inherited) { + pen = inherited->qpen(); + stroke = inherited->strokePresent(); + } - if (!value.isEmpty()) { - if (value.startsWith(QLatin1String("url"))) { - value = value.remove(0, 3); - QSvgStyleProperty *style = styleFromUrl(node, value); - if (style) { - if (style->type() == QSvgStyleProperty::GRADIENT) { - QBrush b(*((QSvgGradientStyle*)style)->qgradient()); - pen.setBrush(b); - } else if (style->type() == QSvgStyleProperty::SOLID_COLOR) { - pen.setColor( - ((QSvgSolidColorStyle*)style)->qcolor()); - } - } else { - qWarning() << "QSvgHandler::parsePen could not resolve property" << idFromUrl(value); + // stroke-opacity attribute handling + qreal strokeAlpha; + if (!opacity.isEmpty() && opacity != QLatin1String("inherit")) { + strokeAlpha = qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity))); + } else { + strokeAlpha = pen.color().alphaF(); + } + + //stroke attribute handling + if (!value.isEmpty() && value != QLatin1String("inherit")) { + if (value.startsWith(QLatin1String("url"))) { + value = value.remove(0, 3); + QSvgStyleProperty *style = styleFromUrl(node, value); + if (style) { + if (style->type() == QSvgStyleProperty::GRADIENT) { + QBrush b(*((QSvgGradientStyle*)style)->qgradient()); + pen.setBrush(b); + } else if (style->type() == QSvgStyleProperty::SOLID_COLOR) { + pen.setColor( + ((QSvgSolidColorStyle*)style)->qcolor()); } + pen.setStyle(Qt::SolidLine); + stroke = true; } else { - QColor color; - if (constructColor(value, opacity, color, handler)) - pen.setColor(color); + qWarning() << "QSvgHandler::parsePen could not resolve property" << idFromUrl(value); } - //since we could inherit stroke="none" - //we need to reset the style of our stroke to something - pen.setStyle(Qt::SolidLine); - } - if (!width.isEmpty()) { - QSvgHandler::LengthType lt; - qreal widthF = parseLength(width, lt, handler); - //### fixme - if (!widthF) { - pen.setStyle(Qt::NoPen); - return; + } else if (value == QLatin1String("none")) { + QColor color; //### fixme: dafalut value for color. + color.setAlphaF(strokeAlpha); + pen.setColor(color); + stroke = false; // This is required because, parent may have a valid stroke but the child may have stroke = "none" + } else { + QColor color; + if (resolveColor(value, color, handler)) { + color.setAlphaF(strokeAlpha); + pen.setColor(color); } - pen.setWidthF(widthF); - } - - if (!linejoin.isEmpty()) { - if (linejoin == QLatin1String("miter")) - pen.setJoinStyle(Qt::SvgMiterJoin); - else if (linejoin == QLatin1String("round")) - pen.setJoinStyle(Qt::RoundJoin); - else if (linejoin == QLatin1String("bevel")) - pen.setJoinStyle(Qt::BevelJoin); + stroke = true; } + } else { + QColor color = pen.color(); + color.setAlphaF(strokeAlpha); + pen.setColor(color); + } - if (!linecap.isEmpty()) { - if (linecap == QLatin1String("butt")) - pen.setCapStyle(Qt::FlatCap); - else if (linecap == QLatin1String("round")) - pen.setCapStyle(Qt::RoundCap); - else if (linecap == QLatin1String("square")) - pen.setCapStyle(Qt::SquareCap); - } + //stroke-width handling + if (!width.isEmpty() && width != QLatin1String("inherit")) { + qreal widthF; + QSvgHandler::LengthType lt; + widthF = parseLength(width, lt, handler); + pen.setWidthF(widthF); + } else if (inherited){ + qreal widthF = inherited->qpen().widthF(); + pen.setWidthF(widthF); + } - qreal penw = pen.widthF(); - if (!dashArray.isEmpty()) { - const QChar *s = dashArray.constData(); - QVector dashes = parseNumbersList(s); - qreal *d = dashes.data(); - if(penw != 0) - for (int i = 0; i < dashes.size(); ++i) { - *d /= penw; - ++d; - } + //stroke-linejoin attribute handling + if (!linejoin.isEmpty()) { + if (linejoin == QLatin1String("miter")) + pen.setJoinStyle(Qt::SvgMiterJoin); + else if (linejoin == QLatin1String("round")) + pen.setJoinStyle(Qt::RoundJoin); + else if (linejoin == QLatin1String("bevel")) + pen.setJoinStyle(Qt::BevelJoin); + } - // if the dash count is odd the dashes should be duplicated - if (dashes.size() % 2 != 0) - dashes << QVector(dashes); + //stroke-linecap attribute handling + if (!linecap.isEmpty()) { + if (linecap == QLatin1String("butt")) + pen.setCapStyle(Qt::FlatCap); + else if (linecap == QLatin1String("round")) + pen.setCapStyle(Qt::RoundCap); + else if (linecap == QLatin1String("square")) + pen.setCapStyle(Qt::SquareCap); + } - pen.setDashPattern(dashes); - } - if (!dashOffset.isEmpty()) { - qreal doffset = toDouble(dashOffset); - if (penw != 0) - doffset /= penw; - pen.setDashOffset(doffset); + //strok-dasharray attribute handling + qreal penw = pen.widthF(); + if (!dashArray.isEmpty() && dashArray != QLatin1String("inherit")) { + const QChar *s = dashArray.constData(); + QVector dashes = parseNumbersList(s); + qreal *d = dashes.data(); + if (penw != 0) + for (int i = 0; i < dashes.size(); ++i) { + *d /= penw; + ++d; + } + // if the dash count is odd the dashes should be duplicated + if (dashes.size() % 2 != 0) + dashes << QVector(dashes); + pen.setDashPattern(dashes); + } else if (inherited) { + QVector dashes(inherited->qpen().dashPattern()); + qreal *d = dashes.data(); + if (!penw) + penw = 1.0; + qreal inheritpenw = inherited->qpen().widthF(); + if (!inheritpenw) + inheritpenw = 1.0; + for ( int i = 0; i < dashes.size(); ++i) { + *d *= (inheritpenw/ penw); + ++d; } - if (!miterlimit.isEmpty()) - pen.setMiterLimit(toDouble(miterlimit)); + pen.setDashPattern(dashes); + } - node->appendStyleProperty(new QSvgStrokeStyle(pen), myId); - } else { - QPen pen(handler->defaultPen()); - pen.setStyle(Qt::NoPen); - node->appendStyleProperty(new QSvgStrokeStyle(pen), myId); + + //stroke-dashoffset attribute handling + if (!dashOffset.isEmpty() && dashOffset != QLatin1String("inherit")) { + qreal doffset = toDouble(dashOffset); + if (penw != 0) + doffset /= penw; + pen.setDashOffset(doffset); + } else if (inherited) { + qreal doffset = pen.dashOffset(); + if (!penw) + penw = 1.0; + qreal inheritpenw = inherited->qpen().widthF(); + if (!inheritpenw) + inheritpenw = 1.0; + doffset *= (inheritpenw/ penw); + pen.setDashOffset(doffset); } + + if (!miterlimit.isEmpty() && miterlimit != QLatin1String("inherit")) + pen.setMiterLimit(toDouble(miterlimit)); + + QSvgStrokeStyle *prop = new QSvgStrokeStyle(pen); + prop->setStroke(stroke); + node->appendStyleProperty(prop, myId); } } @@ -1071,10 +1123,14 @@ static bool parseQFont(const QSvgAttributes &attributes, font.setFamily(family.trimmed()); } if (!size.isEmpty()) { - QSvgHandler::LengthType dummy; // should always be pixel size - fontSize = parseLength(size, dummy, handler); - if (fontSize <= 0) - fontSize = 1; + if (size == QLatin1String("inherit")) { + //inherited already + } else { + QSvgHandler::LengthType dummy; // should always be pixel size + fontSize = parseLength(size, dummy, handler); + if (fontSize <= 0) + fontSize = 1; + } font.setPixelSize(qMax(1, int(fontSize))); } if (!style.isEmpty()) { @@ -1154,9 +1210,13 @@ static void parseFont(QSvgNode *node, font = inherited->qfont(); fontSize = inherited->pointSize(); } - if (parseQFont(attributes, font, fontSize, handler)) { + // group or any container element can have only text-anchor and should + // be processed, because its children can inherit from it. + // So checking for text-anchor before parseQfont() + QString anchor = attributes.value(QLatin1String("text-anchor")).toString(); + if (parseQFont(attributes, font, fontSize, handler) || (!anchor.isEmpty())) { QString myId = someId(attributes); - QString anchor = attributes.value(QLatin1String("text-anchor")).toString(); + //QString anchor = attributes.value(QLatin1String("text-anchor")).toString(); QSvgTinyDocument *doc = node->document(); QSvgFontStyle *fontStyle = 0; QString family = (font.family().isEmpty())?myId:font.family(); @@ -1865,7 +1925,7 @@ static bool parseDefaultTextStyle(QSvgNode *node, if (fontStyle) { font = fontStyle->qfont(); fontSize = fontStyle->pointSize(); - if (anchor.isEmpty()) + if (anchor.isEmpty() || anchor == QLatin1String("inherit")) anchor = fontStyle->textAnchor(); } @@ -3395,7 +3455,7 @@ void QSvgHandler::init() m_style = 0; m_animEnd = 0; m_defaultCoords = LT_PX; - m_defaultPen = QPen(Qt::black, 1, Qt::NoPen, Qt::FlatCap, Qt::SvgMiterJoin); + m_defaultPen = QPen(Qt::black, 1, Qt::SolidLine, Qt::FlatCap, Qt::SvgMiterJoin); m_defaultPen.setMiterLimit(4); parse(); } diff --git a/src/svg/qsvgnode.cpp b/src/svg/qsvgnode.cpp index 75c01a9..ce8b3fa 100644 --- a/src/svg/qsvgnode.cpp +++ b/src/svg/qsvgnode.cpp @@ -320,7 +320,7 @@ qreal QSvgNode::strokeWidth() const { QSvgStrokeStyle *stroke = static_cast( styleProperty(QSvgStyleProperty::STROKE)); - if (!stroke || stroke->qpen().style() == Qt::NoPen) + if (!stroke || !stroke->strokePresent()) return 0; return stroke->qpen().widthF(); } diff --git a/src/svg/qsvgstyle.cpp b/src/svg/qsvgstyle.cpp index fec6231..556201b 100644 --- a/src/svg/qsvgstyle.cpp +++ b/src/svg/qsvgstyle.cpp @@ -195,14 +195,18 @@ void QSvgFontStyle::revert(QPainter *p, QSvgExtraStates &) } QSvgStrokeStyle::QSvgStrokeStyle(const QPen &pen) - : m_stroke(pen) + : m_stroke(pen), m_strokePresent(true) { } void QSvgStrokeStyle::apply(QPainter *p, const QRectF &, QSvgNode *, QSvgExtraStates &) { m_oldStroke = p->pen(); - p->setPen(m_stroke); + if (!m_strokePresent || !m_stroke.widthF() || !m_stroke.color().alphaF()) { + p->setPen(Qt::NoPen); + } else { + p->setPen(m_stroke); + } } void QSvgStrokeStyle::revert(QPainter *p, QSvgExtraStates &) diff --git a/src/svg/qsvgstyle_p.h b/src/svg/qsvgstyle_p.h index e65b6f5..f1d0811 100644 --- a/src/svg/qsvgstyle_p.h +++ b/src/svg/qsvgstyle_p.h @@ -345,6 +345,16 @@ public: virtual void revert(QPainter *p, QSvgExtraStates &states); virtual Type type() const; + void setStroke(bool stroke) + { + m_strokePresent = stroke; + } + + bool strokePresent() const + { + return m_strokePresent; + } + const QPen & qpen() const { return m_stroke; @@ -359,8 +369,8 @@ private: // stroke-opacity v v 'inherit' | // stroke-width v v 'inherit' | QPen m_stroke; - QPen m_oldStroke; + bool m_strokePresent; }; 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. + "" + " " + " " + " " + " " + " " + " " + "", + // stroke + "" + " " + " " + " " + " " + " " + " " + "", + // stroke-width + "" + " " + " " + " " + " " + " " + " " + "", + // stroke-linecap + "" + " " + " " + " " + " " + " " + " " + "", + // stroke-linejoin + "" + " " + " " + " " + " " + " " + " " + "", + // stroke-miterlimit + "" + " " + " " + " " + " " + " " + " " + "", + // stroke-dasharray + "" + " " + " " + " " + " " + " " + " " + "", + // stroke-dashoffset + "" + " " + " " + " " + " " + " " + " " + "", + // stroke-opacity + "" + " " + " " + " " + " " + " " + " " + "" + }; + + 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" -- cgit v0.12 From 0b3eaca3f40bde96380544f19c9b8874a60bbdeb Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 1 Jul 2009 15:50:04 +0200 Subject: Make "make docs" in QTDIR work on Windows, independent of configure -debug/release/debug_and_release - build qdoc3 always into tools\qdoc3 rathern than release/debug subdirs - call it from there Reviewed-by: Marius SO --- doc/doc.pri | 11 ++--------- tools/qdoc3/qdoc3.pro | 1 + 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/doc/doc.pri b/doc/doc.pri index a4c77fe..13d481f 100644 --- a/doc/doc.pri +++ b/doc/doc.pri @@ -2,13 +2,6 @@ # Qt documentation build ##################################################################### -win32 { - QT_WINCONFIG = release/ - !CONFIG(release, debug|release) { - QT_WINCONFIG = debug/ - } -} - DOCS_GENERATION_DEFINES = -Dopensourceedition GENERATOR = $$QT_BUILD_TREE/bin/qhelpgenerator @@ -21,9 +14,9 @@ win32:!win32-g++ { } $$unixstyle { - QDOC = cd $$QT_SOURCE_TREE/tools/qdoc3/test && QT_BUILD_TREE=$$QT_BUILD_TREE QT_SOURCE_TREE=$$QT_SOURCE_TREE $$QT_BUILD_TREE/tools/qdoc3/$${QT_WINCONFIG}qdoc3 $$DOCS_GENERATION_DEFINES + QDOC = cd $$QT_SOURCE_TREE/tools/qdoc3/test && QT_BUILD_TREE=$$QT_BUILD_TREE QT_SOURCE_TREE=$$QT_SOURCE_TREE $$QT_BUILD_TREE/tools/qdoc3/qdoc3 $$DOCS_GENERATION_DEFINES } else { - QDOC = cd $$QT_SOURCE_TREE/tools/qdoc3/test && set QT_BUILD_TREE=$$QT_BUILD_TREE&& set QT_SOURCE_TREE=$$QT_SOURCE_TREE&& $$QT_BUILD_TREE/tools/qdoc3/$${QT_WINCONFIG}qdoc3.exe $$DOCS_GENERATION_DEFINES + QDOC = cd $$QT_SOURCE_TREE/tools/qdoc3/test && set QT_BUILD_TREE=$$QT_BUILD_TREE&& set QT_SOURCE_TREE=$$QT_SOURCE_TREE&& $$QT_BUILD_TREE/tools/qdoc3/qdoc3.exe $$DOCS_GENERATION_DEFINES QDOC = $$replace(QDOC, "/", "\\") } macx { diff --git a/tools/qdoc3/qdoc3.pro b/tools/qdoc3/qdoc3.pro index ed27669..6c1cfd2 100644 --- a/tools/qdoc3/qdoc3.pro +++ b/tools/qdoc3/qdoc3.pro @@ -6,6 +6,7 @@ DEFINES += QT_NO_CAST_TO_ASCII QT = core xml CONFIG += console +CONFIG -= debug_and_release_target build_all:!build_pass { CONFIG -= build_all CONFIG += release -- cgit v0.12 From 5b1f4197d380718a15b3aa176f148bd6324bb1cb Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Wed, 1 Jul 2009 12:19:19 +0200 Subject: QNAM: Direct transfer of HTTP buffer to the QNetworkReply buffer Directly put a QRingBuffer from one QRingBuffer to another QRingBuffer. Reviewed-by: Thiago Macieira --- src/corelib/tools/qringbuffer_p.h | 47 +++++++++++++++++++++++- src/network/access/qhttpnetworkreply.cpp | 8 +++- src/network/access/qhttpnetworkreply_p.h | 1 + src/network/access/qnetworkaccesshttpbackend.cpp | 16 ++++---- src/network/access/qnetworkreplyimpl.cpp | 3 +- 5 files changed, 62 insertions(+), 13 deletions(-) diff --git a/src/corelib/tools/qringbuffer_p.h b/src/corelib/tools/qringbuffer_p.h index b8e08ac..f3daca7 100644 --- a/src/corelib/tools/qringbuffer_p.h +++ b/src/corelib/tools/qringbuffer_p.h @@ -301,6 +301,51 @@ public: return read(size()); } + // read an unspecified amount (will read the first buffer) + inline QByteArray read() { + // multiple buffers, just take the first one + if (head == 0 && tailBuffer != 0) { + QByteArray qba = buffers.takeFirst(); + --tailBuffer; + bufferSize -= qba.length(); + return qba; + } + + // one buffer with good value for head. Just take it. + if (head == 0 && tailBuffer == 0) { + QByteArray qba = buffers.takeFirst(); + qba.resize(tail); + buffers << QByteArray(); + bufferSize = 0; + tail = 0; + return qba; + } + + // Bad case: We have to memcpy. + // We can avoid by initializing the QRingBuffer with basicBlockSize of 0 + // and only using this read() function. + QByteArray qba(readPointer(), nextDataBlockSize()); + buffers.takeFirst(); + head = 0; + if (tailBuffer == 0) { + buffers << QByteArray(); + tail = 0; + } else { + --tailBuffer; + } + bufferSize -= qba.length(); + return qba; + } + + // append a new buffer to the end + inline void append(const QByteArray &qba) { + buffers[tailBuffer].resize(tail); + buffers << qba; + ++tailBuffer; + tail = qba.length(); + bufferSize += qba.length(); + } + inline QByteArray peek(int maxLength) const { int bytesToRead = qMin(size(), maxLength); if(maxLength <= 0) @@ -355,7 +400,7 @@ public: private: QList buffers; int head, tail; - int tailBuffer; + int tailBuffer; // always buffers.size() - 1 int basicBlockSize; int bufferSize; }; diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index 72aec99..483589b 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -185,6 +185,12 @@ QByteArray QHttpNetworkReply::read(qint64 maxSize) return data; } +QByteArray QHttpNetworkReply::readAny() +{ + Q_D(QHttpNetworkReply); + return d->responseData.read(); +} + bool QHttpNetworkReply::isFinished() const { return d_func()->state == QHttpNetworkReplyPrivate::AllDoneState; @@ -196,7 +202,7 @@ QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl) : QHttpNetworkHeaderPrivate(newUrl), state(NothingDoneState), statusCode(100), majorVersion(0), minorVersion(0), bodyLength(0), contentRead(0), totalProgress(0), currentChunkSize(0), currentChunkRead(0), connection(0), initInflate(false), - autoDecompress(false), requestIsPrepared(false) + autoDecompress(false), responseData(0), requestIsPrepared(false) { } diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index 26e1047..b86cfaa 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -123,6 +123,7 @@ public: qint64 bytesAvailable() const; qint64 bytesAvailableNextBlock() const; QByteArray read(qint64 maxSize = -1); + QByteArray readAny(); bool isFinished() const; diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index 71808d4..db84e58 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -649,16 +649,14 @@ void QNetworkAccessHttpBackend::readFromHttp() if (!httpReply) return; - // We implement the download rate control - // Don't read from QHttpNetworkAccess more than QNetworkAccessBackend wants - // One of the two functions above will be called when we can read again + // We read possibly more than nextDownstreamBlockSize(), but + // this is not a critical thing since it is already in the + // memory anyway - qint64 bytesToRead = qBound(0, httpReply->bytesAvailable(), nextDownstreamBlockSize()); - if (!bytesToRead) - return; - - QByteArray data = httpReply->read(bytesToRead); - writeDownstreamData(data); + while (httpReply->bytesAvailable() != 0 && nextDownstreamBlockSize() != 0) { + const QByteArray data = httpReply->readAny(); + writeDownstreamData(data); + } } void QNetworkAccessHttpBackend::replyFinished() diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index 6eacdf1..de39970 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -393,8 +393,7 @@ void QNetworkReplyImplPrivate::appendDownstreamData(const QByteArray &data) if (!q->isOpen()) return; - char *ptr = readBuffer.reserve(data.size()); - memcpy(ptr, data.constData(), data.size()); + readBuffer.append(data); if (cacheEnabled && !cacheSaveDevice) { // save the meta data -- cgit v0.12 From fef6f4469d4c856abdaaefe1d914c120396ff365 Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Wed, 1 Jul 2009 16:20:52 +0200 Subject: Doc - some minor fixes to the sentences Reviewed-By: TrustMe --- doc/src/tutorials/addressbook.qdoc | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/doc/src/tutorials/addressbook.qdoc b/doc/src/tutorials/addressbook.qdoc index 23dabb3..33832da 100644 --- a/doc/src/tutorials/addressbook.qdoc +++ b/doc/src/tutorials/addressbook.qdoc @@ -818,21 +818,23 @@ \image addressbook-tutorial-part6-screenshot.png - Although browsing and searching for contacts are useful features, our address - book is not really fully ready for use until we can saving existing contacts - and load them again at a later time. - Qt provides a number of classes for \l{Input/Output and Networking}{input and output}, - but we have chosen to use two which are simple to use in combination: QFile and - QDataStream. - - A QFile object represents a file on disk that can be read from and written to. - QFile is a subclass of the more general QIODevice class which represents many - different kinds of devices. - - A QDataStream object is used to serialize binary data so that it can be stored - in a QIODevice and retrieved again later. Reading from a QIODevice and writing - to it is as simple as opening the stream - with the respective device as a - parameter - and reading from or writing to it. + Although browsing and searching for contacts are useful features, our + address book is not ready for use until we can save existing contacts and + load them again at a later time. + + Qt provides a number of classes for \l{Input/Output and Networking} + {input and output}, but we have chosen to use two which are simple to use + in combination: QFile and QDataStream. + + A QFile object represents a file on disk that can be read from and written + to. QFile is a subclass of the more general QIODevice class which + represents many different kinds of devices. + + A QDataStream object is used to serialize binary data so that it can be + stored in a QIODevice and retrieved again later. Reading from a QIODevice + and writing to it is as simple as opening the stream - with the respective + device as a parameter - and reading from or writing to it. + \section1 Defining the AddressBook Class -- cgit v0.12 From f4a95e6d6e4c046ac4857cbd54f9488d3b67ce5a Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 1 Jul 2009 17:09:17 +0200 Subject: Fix a regression with extended style option items. We basically passed an unitialized transform to construct the styleoptions for items that use the useExtendedStyleOption flag. We had an auto-test to cover that but for some reason view.show() was removed by me so the auto-test did nothing. oops. Reviewed-by:bnilsen --- src/gui/graphicsview/qgraphicsscene.cpp | 8 ++++---- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 8fdf651..8a032f4 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4312,7 +4312,8 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter * if (drawItem) { Q_ASSERT(!itemIsFullyTransparent); Q_ASSERT(itemHasContents); - item->d_ptr->initStyleOption(&styleOptionTmp, transform, exposedRegion + ENSURE_TRANSFORM_PTR + item->d_ptr->initStyleOption(&styleOptionTmp, *transformPtr, exposedRegion ? *exposedRegion : QRegion(), exposedRegion == 0); const bool itemClipsToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsToShape; @@ -4320,10 +4321,9 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter * if (savePainter) painter->save(); - if (!itemHasChildren || !itemClipsChildrenToShape) { - ENSURE_TRANSFORM_PTR + if (!itemHasChildren || !itemClipsChildrenToShape) painter->setWorldTransform(*transformPtr); - } + if (itemClipsToShape) painter->setClipPath(item->shape(), Qt::IntersectClip); painter->setOpacity(opacity); diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 7552f18..3f7a50b 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -6837,9 +6837,11 @@ public: //Doesn't use the extended style option so the exposed rect is the boundingRect if (!(flags() & QGraphicsItem::ItemUsesExtendedStyleOption)) { QCOMPARE(option->exposedRect, boundingRect()); + QCOMPARE(option->matrix, QMatrix()); } else { QVERIFY(option->exposedRect != QRect()); QVERIFY(option->exposedRect != boundingRect()); + QCOMPARE(option->matrix, sceneTransform().toAffine()); } } QGraphicsRectItem::paint(painter, option, widget); @@ -6861,6 +6863,8 @@ void tst_QGraphicsItem::itemUsesExtendedStyleOption() scene.addItem(rect); rect->setPos(200, 200); QGraphicsView view(&scene); + rect->startTrack = false; + view.show(); QTest::qWait(500); rect->startTrack = true; rect->update(10, 10, 10, 10); -- cgit v0.12 From d0299745e511640df3e0a26e8c447d0960ac4546 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 1 Jul 2009 12:14:29 +0200 Subject: QMainWindow: cleanup of code in QWidgetAnimator --- src/gui/widgets/qdockarealayout.cpp | 10 ++--- src/gui/widgets/qmainwindowlayout.cpp | 50 +++++++-------------- src/gui/widgets/qmainwindowlayout_p.h | 11 ++--- src/gui/widgets/qtoolbararealayout.cpp | 2 +- src/gui/widgets/qwidgetanimator.cpp | 79 +++++++++++++--------------------- src/gui/widgets/qwidgetanimator_p.h | 21 ++++----- 6 files changed, 66 insertions(+), 107 deletions(-) diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp index f245d64..b905ccd 100644 --- a/src/gui/widgets/qdockarealayout.cpp +++ b/src/gui/widgets/qdockarealayout.cpp @@ -1488,7 +1488,7 @@ bool QDockAreaLayoutInfo::hasFixedSize() const void QDockAreaLayoutInfo::apply(bool animate) { - QWidgetAnimator *widgetAnimator = mainWindowLayout()->widgetAnimator; + QWidgetAnimator &widgetAnimator = mainWindowLayout()->widgetAnimator; #ifndef QT_NO_TABBAR if (tabbed) { @@ -1521,7 +1521,7 @@ void QDockAreaLayoutInfo::apply(bool animate) } } - widgetAnimator->animate(tabBar, tab_rect, animate); + widgetAnimator.animate(tabBar, tab_rect, animate); } #endif // QT_NO_TABBAR @@ -1544,7 +1544,7 @@ void QDockAreaLayoutInfo::apply(bool animate) QWidget *w = item.widgetItem->widget(); QRect geo = w->geometry(); - widgetAnimator->animate(w, r, animate); + widgetAnimator.animate(w, r, animate); if (!w->isHidden()) { QDockWidget *dw = qobject_cast(w); if (!r.isValid() && geo.right() >= 0 && geo.bottom() >= 0) { @@ -3064,13 +3064,13 @@ void QDockAreaLayout::splitDockWidget(QDockWidget *after, void QDockAreaLayout::apply(bool animate) { - QWidgetAnimator *widgetAnimator + QWidgetAnimator &widgetAnimator = qobject_cast(mainWindow->layout())->widgetAnimator; for (int i = 0; i < QInternal::DockCount; ++i) docks[i].apply(animate); if (centralWidgetItem != 0 && !centralWidgetItem->isEmpty()) { - widgetAnimator->animate(centralWidgetItem->widget(), centralWidgetRect, + widgetAnimator.animate(centralWidgetItem->widget(), centralWidgetRect, animate); } diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp index 526e7a5..0318f53 100644 --- a/src/gui/widgets/qmainwindowlayout.cpp +++ b/src/gui/widgets/qmainwindowlayout.cpp @@ -1361,7 +1361,7 @@ QLayoutItem *QMainWindowLayout::takeAt(int index) if (QLayoutItem *ret = layoutState.takeAt(index, &x)) { // the widget might in fact have been destroyed by now if (QWidget *w = ret->widget()) { - widgetAnimator->abort(w); + widgetAnimator.abort(w); if (w == pluggingWidget) pluggingWidget = 0; } @@ -1542,25 +1542,9 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem) } } #endif - widgetAnimator->animate(widget, globalRect, - dockOptions & QMainWindow::AnimatedDocks); + widgetAnimator.animate(widget, globalRect, true); } else { -#ifndef QT_NO_DOCKWIDGET - if (QDockWidget *dw = qobject_cast(widget)) - dw->d_func()->plug(currentGapRect); -#endif -#ifndef QT_NO_TOOLBAR - if (QToolBar *tb = qobject_cast(widget)) - tb->d_func()->plug(currentGapRect); -#endif - applyState(layoutState); - savedState.clear(); -#ifndef QT_NO_DOCKWIDGET - parentWidget()->update(layoutState.dockAreaLayout.separatorRegion()); -#endif - currentGapPos.clear(); - updateGapIndicator(); - pluggingWidget = 0; + animationFinished(widget); } return true; @@ -1667,6 +1651,11 @@ QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow) #endif #endif #endif // QT_NO_DOCKWIDGET + , widgetAnimator(this) + , pluggingWidget(0) +#ifndef QT_NO_RUBBERBAND + , gapIndicator(QRubberBand::Rectangle, mainwindow) +#endif //QT_NO_RUBBERBAND { #ifndef QT_NO_DOCKWIDGET #ifndef QT_NO_TABBAR @@ -1680,20 +1669,13 @@ QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow) #endif // QT_NO_DOCKWIDGET #ifndef QT_NO_RUBBERBAND - gapIndicator = new QRubberBand(QRubberBand::Rectangle, mainwindow); // For accessibility to identify this special widget. - gapIndicator->setObjectName(QLatin1String("qt_rubberband")); - - gapIndicator->hide(); + gapIndicator.setObjectName(QLatin1String("qt_rubberband")); + gapIndicator.hide(); #endif pluggingWidget = 0; setObjectName(mainwindow->objectName() + QLatin1String("_layout")); - widgetAnimator = new QWidgetAnimator(this); - connect(widgetAnimator, SIGNAL(finished(QWidget*)), - this, SLOT(animationFinished(QWidget*)), Qt::QueuedConnection); - connect(widgetAnimator, SIGNAL(finishedAll()), - this, SLOT(allAnimationsFinished())); } QMainWindowLayout::~QMainWindowLayout() @@ -1795,13 +1777,13 @@ QLayoutItem *QMainWindowLayout::unplug(QWidget *widget) void QMainWindowLayout::updateGapIndicator() { #ifndef QT_NO_RUBBERBAND - if (widgetAnimator->animating() || currentGapPos.isEmpty()) { - gapIndicator->hide(); + if (widgetAnimator.animating() || currentGapPos.isEmpty()) { + gapIndicator.hide(); } else { - if (gapIndicator->geometry() != currentGapRect) - gapIndicator->setGeometry(currentGapRect); - if (!gapIndicator->isVisible()) - gapIndicator->show(); + if (gapIndicator.geometry() != currentGapRect) + gapIndicator.setGeometry(currentGapRect); + if (!gapIndicator.isVisible()) + gapIndicator.show(); } #endif } diff --git a/src/gui/widgets/qmainwindowlayout_p.h b/src/gui/widgets/qmainwindowlayout_p.h index 26f8633..5c5965a 100644 --- a/src/gui/widgets/qmainwindowlayout_p.h +++ b/src/gui/widgets/qmainwindowlayout_p.h @@ -59,10 +59,12 @@ #include "QtGui/qlayout.h" #include "QtGui/qtabbar.h" +#include "QtGui/qrubberband.h" #include "QtCore/qvector.h" #include "QtCore/qset.h" #include "QtCore/qbasictimer.h" #include "private/qlayoutengine_p.h" +#include "private/qwidgetanimator_p.h" #include "qdockarealayout_p.h" #include "qtoolbararealayout_p.h" @@ -89,7 +91,6 @@ typedef const struct __CFString * CFStringRef; QT_BEGIN_NAMESPACE class QToolBar; -class QWidgetAnimator; class QRubberBand; /* This data structure represents the state of all the tool-bars and dock-widgets. It's value based @@ -278,12 +279,12 @@ public: // animations - QWidgetAnimator *widgetAnimator; + QWidgetAnimator widgetAnimator; QList currentGapPos; QRect currentGapRect; QWidget *pluggingWidget; #ifndef QT_NO_RUBBERBAND - QRubberBand *gapIndicator; + QRubberBand gapIndicator; #endif QList hover(QLayoutItem *widgetItem, const QPoint &mousePos); @@ -295,10 +296,10 @@ public: void applyState(QMainWindowLayoutState &newState, bool animate = true); void restore(bool keepSavedState = false); void updateHIToolBarStatus(); - -private slots: void animationFinished(QWidget *widget); void allAnimationsFinished(); + +private slots: #ifndef QT_NO_DOCKWIDGET #ifndef QT_NO_TABBAR void tabChanged(); diff --git a/src/gui/widgets/qtoolbararealayout.cpp b/src/gui/widgets/qtoolbararealayout.cpp index db2afd6..0c11700 100644 --- a/src/gui/widgets/qtoolbararealayout.cpp +++ b/src/gui/widgets/qtoolbararealayout.cpp @@ -932,7 +932,7 @@ void QToolBarAreaLayout::apply(bool animate) if (visible && dock.o == Qt::Horizontal) geo = QStyle::visualRect(dir, line.rect, geo); - layout->widgetAnimator->animate(widget, geo, animate); + layout->widgetAnimator.animate(widget, geo, animate); } } } diff --git a/src/gui/widgets/qwidgetanimator.cpp b/src/gui/widgets/qwidgetanimator.cpp index c67be4a..56b3f43 100644 --- a/src/gui/widgets/qwidgetanimator.cpp +++ b/src/gui/widgets/qwidgetanimator.cpp @@ -39,12 +39,8 @@ ** ****************************************************************************/ -#include -#include #include -#include -#include -#include +#include #include "qwidgetanimator_p.h" @@ -75,18 +71,12 @@ static inline int animateHelper(int start, int stop, int step, int steps) return start + g_animate_function[x]*(stop - start)/1000; } -QWidgetAnimator::QWidgetAnimator(QObject *parent) - : QObject(parent) +QWidgetAnimator::QWidgetAnimator(QMainWindowLayout *layout) : m_mainWindowLayout(layout) { - m_time = new QTime(); - m_timer = new QTimer(this); - m_timer->setInterval(g_animation_interval); - connect(m_timer, SIGNAL(timeout()), this, SLOT(animationStep())); } QWidgetAnimator::~QWidgetAnimator() { - delete m_time; } void QWidgetAnimator::abort(QWidget *w) @@ -94,8 +84,8 @@ void QWidgetAnimator::abort(QWidget *w) if (m_animation_map.remove(w) == 0) return; if (m_animation_map.isEmpty()) { - m_timer->stop(); - emit finishedAll(); + m_timer.stop(); + m_mainWindowLayout->allAnimationsFinished(); } } @@ -107,32 +97,21 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo if (r.right() < 0 || r.bottom() < 0) r = QRect(); - if (r.isNull() || final_geometry.isNull()) + if (r.isNull() || final_geometry.isNull() || r == final_geometry) animate = false; AnimationMap::const_iterator it = m_animation_map.constFind(widget); - if (it == m_animation_map.constEnd()) { - if (r == final_geometry) { - emit finished(widget); - return; - } - } else { - if ((*it).r2 == final_geometry) - return; - } + if (it != m_animation_map.constEnd() && (*it).r2 == final_geometry) + return; if (animate) { AnimationItem item(widget, r, final_geometry); m_animation_map[widget] = item; - if (!m_timer->isActive()) { - m_timer->start(); - m_time->start(); + if (!m_timer.isActive()) { + m_timer.start(g_animation_interval, this); + m_time.start(); } } else { - m_animation_map.remove(widget); - if (m_animation_map.isEmpty()) - m_timer->stop(); - if (!final_geometry.isValid() && !widget->isWindow()) { // Make the wigdet go away by sending it to negative space QSize s = widget->size(); @@ -140,18 +119,19 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo } widget->setGeometry(final_geometry); - emit finished(widget); - - if (m_animation_map.isEmpty()) - emit finishedAll(); - - return; + if (m_animation_map.remove(widget)) { + m_mainWindowLayout->animationFinished(widget); + if (m_animation_map.isEmpty()) { + m_timer.stop(); + m_mainWindowLayout->allAnimationsFinished(); + } + } } } -void QWidgetAnimator::animationStep() +void QWidgetAnimator::timerEvent(QTimerEvent *) { - int steps = (1 + m_time->restart())/g_animation_interval; + int steps = (1 + m_time.restart())/g_animation_interval; AnimationMap::iterator it = m_animation_map.begin(); while (it != m_animation_map.end()) { AnimationItem &item = *it; @@ -159,35 +139,34 @@ void QWidgetAnimator::animationStep() item.step = qMin(item.step + steps, g_animation_steps); int x = animateHelper(item.r1.left(), item.r2.left(), - item.step, g_animation_steps); + item.step, g_animation_steps); int y = animateHelper(item.r1.top(), item.r2.top(), - item.step, g_animation_steps); + item.step, g_animation_steps); int w = animateHelper(item.r1.width(), item.r2.width(), - item.step, g_animation_steps); + item.step, g_animation_steps); int h = animateHelper(item.r1.height(), item.r2.height(), - item.step, g_animation_steps); + item.step, g_animation_steps); item.widget->setGeometry(x, y, w, h); if (item.step == g_animation_steps) { - emit finished(item.widget); - AnimationMap::iterator tmp = it; - ++it; - m_animation_map.erase(tmp); + QWidget *widget = item.widget; + it = m_animation_map.erase(it); + m_mainWindowLayout->animationFinished(widget); } else { ++it; } } if (m_animation_map.isEmpty()) { - m_timer->stop(); - emit finishedAll(); + m_timer.stop(); + m_mainWindowLayout->allAnimationsFinished(); } } bool QWidgetAnimator::animating() const { - return m_timer->isActive(); + return m_timer.isActive(); } bool QWidgetAnimator::animating(QWidget *widget) diff --git a/src/gui/widgets/qwidgetanimator_p.h b/src/gui/widgets/qwidgetanimator_p.h index 6ee150b..0c68e00 100644 --- a/src/gui/widgets/qwidgetanimator_p.h +++ b/src/gui/widgets/qwidgetanimator_p.h @@ -56,18 +56,18 @@ #include #include #include +#include +#include QT_BEGIN_NAMESPACE class QWidget; -class QTimer; -class QTime; +class QMainWindowLayout; class QWidgetAnimator : public QObject { - Q_OBJECT public: - QWidgetAnimator(QObject *parent = 0); + QWidgetAnimator(QMainWindowLayout *layout); ~QWidgetAnimator(); void animate(QWidget *widget, const QRect &final_geometry, bool animate); bool animating() const; @@ -75,12 +75,8 @@ public: void abort(QWidget *widget); -signals: - void finished(QWidget *widget); - void finishedAll(); - -private slots: - void animationStep(); +protected: + void timerEvent(QTimerEvent *e); private: struct AnimationItem { @@ -93,8 +89,9 @@ private: }; typedef QMap AnimationMap; AnimationMap m_animation_map; - QTimer *m_timer; - QTime *m_time; + QBasicTimer m_timer; + QTime m_time; + QMainWindowLayout *m_mainWindowLayout; }; QT_END_NAMESPACE -- cgit v0.12 From 5077f0be81128ee81e8c7875eb9d1e9423868808 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 1 Jul 2009 15:54:10 +0200 Subject: Animation: fixed a NOTIFY signal name that was wrong Also slightly updated a demo --- examples/animation/animatedtiles/main.cpp | 12 ++++++------ src/corelib/animation/qvariantanimation.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/animation/animatedtiles/main.cpp b/examples/animation/animatedtiles/main.cpp index 9360d7c..c0d55f3 100644 --- a/examples/animation/animatedtiles/main.cpp +++ b/examples/animation/animatedtiles/main.cpp @@ -178,7 +178,7 @@ int main(int argc, char **argv) QState *centeredState = new QState(rootState); // Values - for (int i = 0; i < 64; ++i) { + for (int i = 0; i < items.count(); ++i) { Pixmap *item = items.at(i); // Ellipse ellipseState->assignProperty(item, "pos", @@ -219,7 +219,7 @@ int main(int argc, char **argv) rootState->setInitialState(centeredState); QParallelAnimationGroup *group = new QParallelAnimationGroup; - for (int i = 0; i < 64; ++i) { + for (int i = 0; i < items.count(); ++i) { QPropertyAnimation *anim = new QPropertyAnimation(items[i], "pos"); anim->setDuration(750 + i * 25); anim->setEasingCurve(QEasingCurve::InOutBack); @@ -229,7 +229,7 @@ int main(int argc, char **argv) trans->addAnimation(group); group = new QParallelAnimationGroup; - for (int i = 0; i < 64; ++i) { + for (int i = 0; i < items.count(); ++i) { QPropertyAnimation *anim = new QPropertyAnimation(items[i], "pos"); anim->setDuration(750 + i * 25); anim->setEasingCurve(QEasingCurve::InOutBack); @@ -239,7 +239,7 @@ int main(int argc, char **argv) trans->addAnimation(group); group = new QParallelAnimationGroup; - for (int i = 0; i < 64; ++i) { + for (int i = 0; i < items.count(); ++i) { QPropertyAnimation *anim = new QPropertyAnimation(items[i], "pos"); anim->setDuration(750 + i * 25); anim->setEasingCurve(QEasingCurve::InOutBack); @@ -249,7 +249,7 @@ int main(int argc, char **argv) trans->addAnimation(group); group = new QParallelAnimationGroup; - for (int i = 0; i < 64; ++i) { + for (int i = 0; i < items.count(); ++i) { QPropertyAnimation *anim = new QPropertyAnimation(items[i], "pos"); anim->setDuration(750 + i * 25); anim->setEasingCurve(QEasingCurve::InOutBack); @@ -259,7 +259,7 @@ int main(int argc, char **argv) trans->addAnimation(group); group = new QParallelAnimationGroup; - for (int i = 0; i < 64; ++i) { + for (int i = 0; i < items.count(); ++i) { QPropertyAnimation *anim = new QPropertyAnimation(items[i], "pos"); anim->setDuration(750 + i * 25); anim->setEasingCurve(QEasingCurve::InOutBack); diff --git a/src/corelib/animation/qvariantanimation.h b/src/corelib/animation/qvariantanimation.h index b2d52d5..3e397ca 100644 --- a/src/corelib/animation/qvariantanimation.h +++ b/src/corelib/animation/qvariantanimation.h @@ -62,7 +62,7 @@ class Q_CORE_EXPORT QVariantAnimation : public QAbstractAnimation Q_OBJECT Q_PROPERTY(QVariant startValue READ startValue WRITE setStartValue) Q_PROPERTY(QVariant endValue READ endValue WRITE setEndValue) - Q_PROPERTY(QVariant currentValue READ currentValue NOTIFY currentValueChanged) + Q_PROPERTY(QVariant currentValue READ currentValue NOTIFY valueChanged) Q_PROPERTY(int duration READ duration WRITE setDuration) Q_PROPERTY(QEasingCurve easingCurve READ easingCurve WRITE setEasingCurve) -- cgit v0.12 From 0ee90990c24bf965317918074a5af683e94bdd40 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 1 Jul 2009 16:38:37 +0200 Subject: Animations: adding an autotest for jumping values when restarting The problem is that when restarting, the time is at the end. So the current value changes to the end value instead of the initial value. --- .../qpropertyanimation/tst_qpropertyanimation.cpp | 52 ++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp index a30e9f9..09e12c3 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() @@ -559,6 +560,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 +958,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" -- cgit v0.12 From 29b71240d17a1557fd9a8d2ce7dcd450b07b57a8 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 1 Jul 2009 17:15:17 +0200 Subject: QAnimation: fix a jump in values when restarting an animation --- src/corelib/animation/qabstractanimation.cpp | 47 ++++++++++------------ .../qpropertyanimation/tst_qpropertyanimation.cpp | 5 +++ 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index 3720984..75decf8 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -254,8 +254,17 @@ void QAbstractAnimationPrivate::setState(QAbstractAnimation::State newState) int oldCurrentLoop = currentLoop; QAbstractAnimation::Direction oldDirection = direction; - state = newState; + // check if we should Rewind + if ((newState == QAbstractAnimation::Paused || newState == QAbstractAnimation::Running) + && oldState == QAbstractAnimation::Stopped) { + //here we reset the time if needed + //we don't call setCurrentTime because this might change the way the animation + //behaves: changing the state or changing the current value + totalCurrentTime = currentTime =(direction == QAbstractAnimation::Forward) ? + 0 : (loopCount == -1 ? q->duration() : q->totalDuration()); + } + state = newState; QPointer guard(q); guard->updateState(oldState, newState); @@ -268,36 +277,22 @@ void QAbstractAnimationPrivate::setState(QAbstractAnimation::State newState) if (guard) emit guard->stateChanged(oldState, newState); - // Enter running state. switch (state) { case QAbstractAnimation::Paused: case QAbstractAnimation::Running: - { - // Rewind - if (oldState == QAbstractAnimation::Stopped) { - if (guard) { - if (direction == QAbstractAnimation::Forward) - q->setCurrentTime(0); - else - q->setCurrentTime(loopCount == -1 ? q->duration() : q->totalDuration()); - } - - // Check if the setCurrentTime() function called stop(). - // This can happen for a 0-duration animation - if (state == QAbstractAnimation::Stopped) - return; - } - - // Register timer if our parent is not running. - if (state == QAbstractAnimation::Running && guard) { - if (!group || group->state() == QAbstractAnimation::Stopped) { - QUnifiedTimer::instance()->registerAnimation(q); - } - } else { - //new state is paused - QUnifiedTimer::instance()->unregisterAnimation(q); + //this ensures that the value is updated now that the animation is running + if(oldState == QAbstractAnimation::Stopped && guard) + guard->setCurrentTime(currentTime); + + // Register timer if our parent is not running. + if (state == QAbstractAnimation::Running && guard) { + if (!group || group->state() == QAbstractAnimation::Stopped) { + QUnifiedTimer::instance()->registerAnimation(q); } + } else { + //new state is paused + QUnifiedTimer::instance()->unregisterAnimation(q); } break; case QAbstractAnimation::Stopped: diff --git a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp index 09e12c3..e76c8ef 100644 --- a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp +++ b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp @@ -396,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); -- cgit v0.12 From 2b9294a2b47c4a193ef83be60a07a3e61b8531b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Wed, 1 Jul 2009 17:30:46 +0200 Subject: Fixes broken BSP lookup in QGraphicsSceneBspTreeIndex. The chip demo was unbelievable slow, so I investigated and found out the bsp always returned almost all items in the tree (40 000 in this particular case). It did so because the tree was initialized with an empty sceneRect. The sceneRect was empty due to a lacking signal-slot connection, resulting in QGraphicsSceneBspTreeIndex::updateSceneRect never being invoked. Auto-test included. --- src/gui/graphicsview/qgraphicssceneindex.cpp | 17 ++++++++++++----- src/gui/graphicsview/qgraphicssceneindex_p.h | 3 ++- .../qgraphicssceneindex/tst_qgraphicssceneindex.cpp | 13 +++++++++++++ 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 2f2f05e..b317e8e 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -303,24 +303,31 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe } } +void QGraphicsSceneIndexPrivate::init() +{ + if (!scene) + return; + + QObject::connect(scene, SIGNAL(sceneRectChanged(const QRectF&)), + q_func(), SLOT(updateSceneRect(const QRectF&))); +} + /*! Constructs an abstract scene index for a given \a scene. */ QGraphicsSceneIndex::QGraphicsSceneIndex(QGraphicsScene *scene) : QObject(*new QGraphicsSceneIndexPrivate(scene), scene) { - if (scene) { - connect(scene, SIGNAL(sceneRectChanged(const QRectF&)), - this, SLOT(updateSceneRect(const QRectF&))); - } + d_func()->init(); } /*! \internal */ -QGraphicsSceneIndex::QGraphicsSceneIndex(QObjectPrivate &dd, QGraphicsScene *scene) +QGraphicsSceneIndex::QGraphicsSceneIndex(QGraphicsSceneIndexPrivate &dd, QGraphicsScene *scene) : QObject(dd, scene) { + d_func()->init(); } /*! diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index 122d7ae..aabfa79 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -114,7 +114,7 @@ protected: virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value); virtual void prepareBoundingRectChange(const QGraphicsItem *item); - QGraphicsSceneIndex(QObjectPrivate &dd, QGraphicsScene *scene); + QGraphicsSceneIndex(QGraphicsSceneIndexPrivate &dd, QGraphicsScene *scene); friend class QGraphicsScene; friend class QGraphicsScenePrivate; @@ -133,6 +133,7 @@ public: QGraphicsSceneIndexPrivate(QGraphicsScene *scene); ~QGraphicsSceneIndexPrivate(); + void init(); static bool itemCollidesWithPath(const QGraphicsItem *item, const QPainterPath &path, Qt::ItemSelectionMode mode); void recursive_items_helper(QGraphicsItem *item, QRectF exposeRect, diff --git a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp index ac21e20..9d0675d 100644 --- a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp +++ b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp @@ -64,6 +64,7 @@ private slots: void overlappedItems(); void movingItems_data(); void movingItems(); + void connectedToSceneRectChanged(); private: void common_data(); @@ -214,6 +215,18 @@ void tst_QGraphicsSceneIndex::movingItems() QCOMPARE(scene.items(QRectF(0, 0, 1000, 1000)).count(), 11); } +void tst_QGraphicsSceneIndex::connectedToSceneRectChanged() +{ + + class MyScene : public QGraphicsScene + { public: using QGraphicsScene::receivers; }; + + MyScene scene; // Uses QGraphicsSceneBspTreeIndex by default. + QCOMPARE(scene.receivers(SIGNAL(sceneRectChanged(const QRectF&))), 1); + + scene.setItemIndexMethod(QGraphicsScene::NoIndex); // QGraphicsSceneLinearIndex + QCOMPARE(scene.receivers(SIGNAL(sceneRectChanged(const QRectF&))), 1); +} QTEST_MAIN(tst_QGraphicsSceneIndex) #include "tst_qgraphicssceneindex.moc" -- cgit v0.12 From f31d2c01e5998a9fcf4345fa66e0349921e115da Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Thu, 2 Jul 2009 09:57:52 +1000 Subject: OpenVG: use the correct clip region to detect single-rect clips "Special case: if the intersection of the system clip and the region is a single rectangle, then use the scissor for clipping." It was doing the intersection but then didn't use the intersection to test for the single-rectangle case. Task-number: QT-64 Reviewed-by: trustme --- src/openvg/qpaintengine_vg.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index c7fe604..8ce3f69 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -1656,10 +1656,10 @@ void QVGPaintEngine::clip(const QRegion ®ion, Qt::ClipOperation op) clip = r; else clip = clip.intersect(r); - if (r.numRects() == 1) { + if (clip.numRects() == 1) { d->maskValid = false; d->maskIsSet = false; - d->maskRect = r.boundingRect(); + d->maskRect = clip.boundingRect(); vgSeti(VG_MASKING, VG_FALSE); updateScissor(); } else { -- cgit v0.12 From 0b5c4c4352d0419113cf152b7ae5bbee5a45fd5c Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Thu, 2 Jul 2009 10:36:19 +1000 Subject: OpenVG: override QPaintEngineEx::clip(QRect) and handle specially. This change should improve performance of single-rectangle clip regions by avoiding the overhead of creating and intersecting QRegion objects. Task-number: QT-64 Reviewed-by: trustme --- src/openvg/qpaintengine_vg.cpp | 130 ++++++++++++++++++++++++++++++++++++++++- src/openvg/qpaintengine_vg_p.h | 1 + 2 files changed, 129 insertions(+), 2 deletions(-) diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index 8ce3f69..48953ac 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -142,6 +142,8 @@ public: void ensureMask(QVGPaintEngine *engine, int width, int height); void modifyMask (QVGPaintEngine *engine, VGMaskOperation op, const QRegion& region); + void modifyMask + (QVGPaintEngine *engine, VGMaskOperation op, const QRect& rect); #endif VGint maxScissorRects; // Maximum scissor rectangles for clipping. @@ -1611,13 +1613,106 @@ void QVGPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) void QVGPaintEngine::clip(const QRect &rect, Qt::ClipOperation op) { - clip(QRegion(rect), op); + Q_D(QVGPaintEngine); + + d->dirty |= QPaintEngine::DirtyClipRegion; + + // If we have a non-simple transform, then use path-based clipping. + if (op != Qt::NoClip && !clipTransformIsSimple(d->transform)) { + QPaintEngineEx::clip(rect, op); + return; + } + + switch (op) { + case Qt::NoClip: + { + d->maskValid = false; + d->maskIsSet = true; + d->maskRect = QRect(); + vgSeti(VG_MASKING, VG_FALSE); + } + break; + + case Qt::ReplaceClip: + { + QRect r = d->transform.mapRect(rect); + if (isDefaultClipRect(r)) { + // Replacing the clip with a full-window region is the + // same as turning off clipping. + if (d->maskValid) + vgSeti(VG_MASKING, VG_FALSE); + d->maskValid = false; + d->maskIsSet = true; + d->maskRect = QRect(); + } else { + // Special case: if the intersection of the system + // clip and "r" is a single rectangle, then use the + // scissor for clipping. We try to avoid allocating a + // QRegion copy on the heap for the test if we can. + QRegion clip = d->systemClip; // Reference-counted, no alloc. + QRect clipRect; + if (clip.numRects() == 1) { + clipRect = clip.boundingRect().intersected(r); + } else if (clip.isEmpty()) { + clipRect = r; + } else { + clip = clip.intersect(r); + if (clip.numRects() != 1) { + d->maskValid = false; + d->maskIsSet = false; + d->maskRect = QRect(); + d->modifyMask(this, VG_FILL_MASK, r); + break; + } + clipRect = clip.boundingRect(); + } + d->maskValid = false; + d->maskIsSet = false; + d->maskRect = clipRect; + vgSeti(VG_MASKING, VG_FALSE); + updateScissor(); + } + } + break; + + case Qt::IntersectClip: + { + QRect r = d->transform.mapRect(rect); + if (d->maskIsSet && isDefaultClipRect(r)) { + // Intersecting a full-window clip with a full-window + // region is the same as turning off clipping. + if (d->maskValid) + vgSeti(VG_MASKING, VG_FALSE); + d->maskValid = false; + d->maskIsSet = true; + d->maskRect = QRect(); + } else { + d->modifyMask(this, VG_INTERSECT_MASK, r); + } + } + break; + + case Qt::UniteClip: + { + // If we already have a full-window clip, then uniting a + // region with it will do nothing. Otherwise union. + if (!(d->maskIsSet)) + d->modifyMask(this, VG_UNION_MASK, d->transform.mapRect(rect)); + } + break; + } } void QVGPaintEngine::clip(const QRegion ®ion, Qt::ClipOperation op) { Q_D(QVGPaintEngine); + // Use the QRect case if the region consists of a single rectangle. + if (region.numRects() == 1) { + clip(region.boundingRect(), op); + return; + } + d->dirty |= QPaintEngine::DirtyClipRegion; // If we have a non-simple transform, then use path-based clipping. @@ -1765,7 +1860,7 @@ void QVGPaintEnginePrivate::ensureMask maskRect = QRect(); } else { vgMask(VG_INVALID_HANDLE, VG_CLEAR_MASK, 0, 0, width, height); - if (!maskRect.isNull()) { + if (maskRect.isValid()) { vgMask(VG_INVALID_HANDLE, VG_FILL_MASK, maskRect.x(), height - maskRect.y() - maskRect.height(), maskRect.width(), maskRect.height()); @@ -1797,6 +1892,27 @@ void QVGPaintEnginePrivate::modifyMask maskIsSet = false; } +void QVGPaintEnginePrivate::modifyMask + (QVGPaintEngine *engine, VGMaskOperation op, const QRect& rect) +{ + QPaintDevice *pdev = engine->paintDevice(); + int width = pdev->width(); + int height = pdev->height(); + + if (!maskValid) + ensureMask(engine, width, height); + + if (rect.isValid()) { + vgMask(VG_INVALID_HANDLE, op, + rect.x(), height - rect.y() - rect.height(), + rect.width(), rect.height()); + } + + vgSeti(VG_MASKING, VG_TRUE); + maskValid = true; + maskIsSet = false; +} + #endif // !QVG_SCISSOR_CLIP void QVGPaintEngine::updateScissor() @@ -1892,6 +2008,16 @@ bool QVGPaintEngine::isDefaultClipRegion(const QRegion& region) rect.width() == width && rect.height() == height); } +bool QVGPaintEngine::isDefaultClipRect(const QRect& rect) +{ + QPaintDevice *pdev = paintDevice(); + int width = pdev->width(); + int height = pdev->height(); + + return (rect.x() == 0 && rect.y() == 0 && + rect.width() == width && rect.height() == height); +} + void QVGPaintEngine::clipEnabledChanged() { #if defined(QVG_SCISSOR_CLIP) diff --git a/src/openvg/qpaintengine_vg_p.h b/src/openvg/qpaintengine_vg_p.h index a390c80..bde06e5 100644 --- a/src/openvg/qpaintengine_vg_p.h +++ b/src/openvg/qpaintengine_vg_p.h @@ -154,6 +154,7 @@ private: void updateScissor(); QRegion defaultClipRegion(); bool isDefaultClipRegion(const QRegion& region); + bool isDefaultClipRect(const QRect& rect); bool clearRect(const QRectF &rect, const QColor &color); }; -- cgit v0.12 From 6c9647f6673fd5738001c5bbe416b116442fbc41 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Thu, 2 Jul 2009 10:50:03 +1000 Subject: OpenVG: short-cut clipping for QPainterPath's that are just rects If the QPainterPath contains a structure that looks like a simple rectangle, then use the faster clip(QRect) function instead of a full VGPath-based render call. Task-number: QT-64 Reviewed-by: trustme --- src/openvg/qpaintengine_vg.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index 48953ac..7a962e4 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -1802,11 +1802,61 @@ void QVGPaintEngine::clip(const QRegion ®ion, Qt::ClipOperation op) } } +#if !defined(QVG_NO_RENDER_TO_MASK) + +// Copied from qpathclipper.cpp. +static bool qt_vg_pathToRect(const QPainterPath &path, QRectF *rect) +{ + if (path.elementCount() != 5) + return false; + + const bool mightBeRect = path.elementAt(0).isMoveTo() + && path.elementAt(1).isLineTo() + && path.elementAt(2).isLineTo() + && path.elementAt(3).isLineTo() + && path.elementAt(4).isLineTo(); + + if (!mightBeRect) + return false; + + const qreal x1 = path.elementAt(0).x; + const qreal y1 = path.elementAt(0).y; + + const qreal x2 = path.elementAt(1).x; + const qreal y2 = path.elementAt(2).y; + + if (path.elementAt(1).y != y1) + return false; + + if (path.elementAt(2).x != x2) + return false; + + if (path.elementAt(3).x != x1 || path.elementAt(3).y != y2) + return false; + + if (path.elementAt(4).x != x1 || path.elementAt(4).y != y1) + return false; + + if (rect) + *rect = QRectF(QPointF(x1, y1), QPointF(x2, y2)); + + return true; +} + +#endif + void QVGPaintEngine::clip(const QPainterPath &path, Qt::ClipOperation op) { #if !defined(QVG_NO_RENDER_TO_MASK) Q_D(QVGPaintEngine); + // If the path is a simple rectangle, then use clip(QRect) instead. + QRectF simpleRect; + if (qt_vg_pathToRect(path, &simpleRect)) { + clip(simpleRect.toRect(), op); + return; + } + d->dirty |= QPaintEngine::DirtyClipRegion; if (op == Qt::NoClip) { -- cgit v0.12 From cdfb2ed5096053314c0e23482609a1a491636ac1 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 2 Jul 2009 10:16:20 +1000 Subject: Improve cetest error reporting. Reviewed-by: Michael Goddard --- .../qtestlib/wince/cetest/activesyncconnection.cpp | 6 ++-- tools/qtestlib/wince/cetest/remoteconnection.cpp | 32 ++++++++++++++++++++++ tools/qtestlib/wince/cetest/remoteconnection.h | 2 ++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/tools/qtestlib/wince/cetest/activesyncconnection.cpp b/tools/qtestlib/wince/cetest/activesyncconnection.cpp index e8ca8f2..76e4a41 100644 --- a/tools/qtestlib/wince/cetest/activesyncconnection.cpp +++ b/tools/qtestlib/wince/cetest/activesyncconnection.cpp @@ -113,6 +113,8 @@ bool ActiveSyncConnection::copyFileToDevice(const QString &localSource, const QS CeCloseHandle(deviceHandle); return true; } + } else { + qWarning("Could not open %s: %s", qPrintable(localSource), qPrintable(file.errorString())); } return false; } @@ -120,7 +122,7 @@ bool ActiveSyncConnection::copyFileToDevice(const QString &localSource, const QS deleteFile(deviceDest); HANDLE deviceHandle = CeCreateFile(deviceDest.utf16(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if (deviceHandle == INVALID_HANDLE_VALUE) { - debugOutput(QString::fromLatin1(" Could not create target file"), 2); + qWarning("Could not create %s: %s", qPrintable(deviceDest), strwinerror(CeGetLastError()).constData()); return false; } @@ -144,7 +146,7 @@ bool ActiveSyncConnection::copyFileToDevice(const QString &localSource, const QS if (toWrite == 0) break; if (!CeWriteFile(deviceHandle, data.data() , toWrite, &written, NULL)) { - debugOutput(QString::fromLatin1(" Could not write File"), 2); + qWarning("Could not write to %s: %s", qPrintable(deviceDest), strwinerror(CeGetLastError()).constData()); return false; } currentPos += written; diff --git a/tools/qtestlib/wince/cetest/remoteconnection.cpp b/tools/qtestlib/wince/cetest/remoteconnection.cpp index 547b211..75788e2 100644 --- a/tools/qtestlib/wince/cetest/remoteconnection.cpp +++ b/tools/qtestlib/wince/cetest/remoteconnection.cpp @@ -41,6 +41,38 @@ #include "remoteconnection.h" +QByteArray strwinerror(DWORD errorcode) +{ + QByteArray out(512, 0); + + DWORD ok = FormatMessageA( + FORMAT_MESSAGE_FROM_SYSTEM, + 0, + errorcode, + 0, + out.data(), + out.size(), + 0 + ); + + if (!ok) { + qsnprintf(out.data(), out.size(), + "(error %d; additionally, error %d while looking up error string)", + (int)errorcode, (int)GetLastError()); + } + else { + out.resize(qstrlen(out.constData())); + if (out.endsWith("\r\n")) + out.chop(2); + + /* Append error number to error message for good measure */ + out.append(" ("); + out.append(QByteArray::number((int)errorcode)); + out.append(")"); + } + return out; +} + AbstractRemoteConnection::AbstractRemoteConnection() { } diff --git a/tools/qtestlib/wince/cetest/remoteconnection.h b/tools/qtestlib/wince/cetest/remoteconnection.h index 9c3e63d..f517009 100644 --- a/tools/qtestlib/wince/cetest/remoteconnection.h +++ b/tools/qtestlib/wince/cetest/remoteconnection.h @@ -79,4 +79,6 @@ public: virtual bool execute(QString program, QString arguments = QString(), int timeout = -1, int *returnValue = NULL) = 0; }; +QByteArray strwinerror(DWORD); + #endif -- cgit v0.12 From fb1fa68ae8555deeaeaf6f193c678269c85ffc4d Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 2 Jul 2009 11:42:25 +1000 Subject: Let QtRemote report the error code to cetest when creating the test process fails. This gives some hint to the user in the case of problems like missing DLLs, as opposed to silent failure. Reviewed-by: Michael Goddard --- tools/qtestlib/wince/cetest/activesyncconnection.cpp | 14 ++++++++++++-- tools/qtestlib/wince/remotelib/commands.cpp | 10 ++++++++-- tools/qtestlib/wince/remotelib/commands.h | 2 +- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/tools/qtestlib/wince/cetest/activesyncconnection.cpp b/tools/qtestlib/wince/cetest/activesyncconnection.cpp index 76e4a41..99fac2c 100644 --- a/tools/qtestlib/wince/cetest/activesyncconnection.cpp +++ b/tools/qtestlib/wince/cetest/activesyncconnection.cpp @@ -382,6 +382,7 @@ bool ActiveSyncConnection::execute(QString program, QString arguments, int timeo BYTE* output; IRAPIStream *stream; int returned = 0; + DWORD error = 0; HRESULT res = CeRapiInvoke(dllLocation.utf16(), functionName.utf16(), 0, 0, &outputSize, &output, &stream, 0); if (S_OK != res) { if (S_OK != CeGetLastError()) @@ -416,9 +417,18 @@ bool ActiveSyncConnection::execute(QString program, QString arguments, int timeo if (S_OK != stream->Read(&returned, sizeof(returned), &written)) { qWarning(" Could not access return value of process"); } - result = true; - } + if (S_OK != stream->Read(&error, sizeof(error), &written)) { + qWarning(" Could not access error code"); + } + if (error) { + qWarning() << "Error on target:" << strwinerror(error); + result = false; + } + else { + result = true; + } + } if (returnValue) *returnValue = returned; diff --git a/tools/qtestlib/wince/remotelib/commands.cpp b/tools/qtestlib/wince/remotelib/commands.cpp index 3aed2d6..f2176dd 100644 --- a/tools/qtestlib/wince/remotelib/commands.cpp +++ b/tools/qtestlib/wince/remotelib/commands.cpp @@ -56,6 +56,7 @@ int qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream) wchar_t* arguments = 0; int timeout = -1; int returnValue = -2; + DWORD error = 0; if (S_OK != stream->Read(&appLength, sizeof(appLength), &bytesRead)) CLEAN_FAIL(-2); @@ -74,11 +75,13 @@ int qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream) if (S_OK != stream->Read(&timeout, sizeof(timeout), &bytesRead)) CLEAN_FAIL(-2); - bool result = qRemoteExecute(appName, arguments, &returnValue, timeout); + bool result = qRemoteExecute(appName, arguments, &returnValue, &error, timeout); if (timeout != 0) { if (S_OK != stream->Write(&returnValue, sizeof(returnValue), &bytesRead)) CLEAN_FAIL(-4); + if (S_OK != stream->Write(&error, sizeof(error), &bytesRead)) + CLEAN_FAIL(-5); } delete appName; delete arguments; @@ -90,13 +93,16 @@ int qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream) } -bool qRemoteExecute(const wchar_t* program, const wchar_t* arguments, int *returnValue, int timeout) +bool qRemoteExecute(const wchar_t* program, const wchar_t* arguments, int *returnValue, DWORD* error, int timeout) { + *error = 0; + if (!program) return false; PROCESS_INFORMATION pid; if (!CreateProcess(program, arguments, NULL, NULL, false, 0, NULL, NULL, NULL, &pid)) { + *error = GetLastError(); wprintf(L"Could not launch: %s\n", program); return false; } diff --git a/tools/qtestlib/wince/remotelib/commands.h b/tools/qtestlib/wince/remotelib/commands.h index 9f0b2e3..5275f2c 100644 --- a/tools/qtestlib/wince/remotelib/commands.h +++ b/tools/qtestlib/wince/remotelib/commands.h @@ -45,7 +45,7 @@ extern "C" { int __declspec(dllexport) qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream*); - bool __declspec(dllexport) qRemoteExecute(const wchar_t* program, const wchar_t* arguments = NULL, int *returnValue = NULL , int timeout = -1); + bool __declspec(dllexport) qRemoteExecute(const wchar_t* program, const wchar_t* arguments = NULL, int *returnValue = NULL , DWORD* error = NULL, int timeout = -1); } #endif -- cgit v0.12 From f126b8cc5733d2cd37dd2aad9119e482b0d4a0e6 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 2 Jul 2009 08:39:57 +0200 Subject: doc: Corrected several qdoc warnings. --- src/gui/graphicsview/qgraphicssceneevent.cpp | 35 ++++++++++++++-------------- src/gui/itemviews/qheaderview.h | 2 +- src/gui/kernel/qapplication.cpp | 2 +- src/qt3support/widgets/q3datetimeedit.cpp | 7 +++--- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/gui/graphicsview/qgraphicssceneevent.cpp b/src/gui/graphicsview/qgraphicssceneevent.cpp index 7906fb8..338f12a 100644 --- a/src/gui/graphicsview/qgraphicssceneevent.cpp +++ b/src/gui/graphicsview/qgraphicssceneevent.cpp @@ -1875,12 +1875,12 @@ void QGraphicsSceneGestureEvent::setGestures(const QSet &gestures) } /*! - Sets the accept flag of the all gestures inside the event object, - the equivalent of calling \l{QEvent::accept()}{accept()} or - \l{QEvent::setAccepted()}{setAccepted(true)}. + Sets the accept flag of the all gestures for the event object. + This is the equivalent of calling \l{QEvent::accept()} {accept()} + or \l{QEvent::setAccepted()}{setAccepted(true)}. - Setting the accept parameter indicates that the event receiver - wants the gesture. Unwanted gestures might be propagated to the parent + Setting the accept flag indicates that the event receiver wants + the gesture. Unwanted gestures might be propagated to the parent widget. */ void QGraphicsSceneGestureEvent::acceptAll() @@ -1893,13 +1893,14 @@ void QGraphicsSceneGestureEvent::acceptAll() } /*! - Sets the accept flag of the specified gesture inside the event - object, the equivalent of calling - \l{QGestureEvent::gesture()}{gesture(type)}->\l{QGesture::accept()}{accept()} - Setting the accept parameter indicates that the event receiver - wants the gesture. Unwanted gestures might be propagated to the parent - widget. + Sets the accept flag of the gesture specified by \a type. This is + equivalent to calling \l{QGestureEvent::gesture()} {gesture(type)}-> + \l{QGesture::accept()}{accept()} + + Setting the accept flag indicates that the event receiver + wants the gesture. Unwanted gestures might be propagated to the parent + widget. */ void QGraphicsSceneGestureEvent::accept(Qt::GestureType type) { @@ -1908,13 +1909,13 @@ void QGraphicsSceneGestureEvent::accept(Qt::GestureType type) } /*! - Sets the accept flag of the specified gesture inside the event - object, the equivalent of calling - \l{QGestureEvent::gesture()}{gesture(type)}->\l{QGesture::accept()}{accept()} - Setting the accept parameter indicates that the event receiver - wants the gesture. Unwanted gestures might be propagated to the parent - widget. + Sets the accept flag of the gesture specified by \a type. This is + equivalent to calling \l{QGestureEvent::gesture()} {gesture(type)}-> + \l{QGesture::accept()}{accept()} + + Setting the accept flag indicates that the event receiver wants the + gesture. Unwanted gestures might be propagated to the parent widget. */ void QGraphicsSceneGestureEvent::accept(const QString &type) { diff --git a/src/gui/itemviews/qheaderview.h b/src/gui/itemviews/qheaderview.h index f752ae2..bf92667 100644 --- a/src/gui/itemviews/qheaderview.h +++ b/src/gui/itemviews/qheaderview.h @@ -221,7 +221,7 @@ protected: bool isIndexHidden(const QModelIndex &index) const; QModelIndex moveCursor(CursorAction, Qt::KeyboardModifiers); - void setSelection(const QRect&, QItemSelectionModel::SelectionFlags); + void setSelection(const QRect& rect, QItemSelectionModel::SelectionFlags flags); QRegion visualRegionForSelection(const QItemSelection &selection) const; void initStyleOption(QStyleOptionHeader *option) const; diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 15ddce8..60c69cc 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -5096,7 +5096,7 @@ void QApplication::removeGestureRecognizer(QGestureRecognizer *recognizer) The delay allows to postpone widget's input event handling until gestures framework can successfully recognize a gesture. - \sa QWidget::grabGesture + \sa QWidget::grabGesture() */ void QApplication::setEventDeliveryDelayForGestures(int delay) { diff --git a/src/qt3support/widgets/q3datetimeedit.cpp b/src/qt3support/widgets/q3datetimeedit.cpp index 4872642..9c2f289 100644 --- a/src/qt3support/widgets/q3datetimeedit.cpp +++ b/src/qt3support/widgets/q3datetimeedit.cpp @@ -2648,13 +2648,12 @@ Q3DateTimeEdit::~Q3DateTimeEdit() } -/*! +/*! \fn void Q3DateTimeEdit::resizeEvent(QResizeEvent *event) \reimp - Intercepts and handles resize events which have special meaning - for the Q3DateTimeEdit. + Intercepts and handles the resize \a event, which hase a + special meaning for the Q3DateTimeEdit. */ - void Q3DateTimeEdit::resizeEvent(QResizeEvent *) { int dw = de->sizeHint().width(); -- cgit v0.12 From 058c4f1cfd0536779ec99f3d89bdd90bf52ae20e Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 2 Jul 2009 12:58:51 +1000 Subject: Let cetest deploy libraries other than for Qt to make it usable for running unit tests for projects outside of Qt. Let cetest look in the paths given with `-L' in LIBS, and to deploy libraries whose names don't start with `Qt'. This also fixes deployment of Qt autotests which link against phonon (the only Qt library whose name doesn't start with `Qt'). Reviewed-by: mauricek --- tools/qtestlib/wince/cetest/deployment.cpp | 34 +++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/tools/qtestlib/wince/cetest/deployment.cpp b/tools/qtestlib/wince/cetest/deployment.cpp index fec2735..68f0197 100644 --- a/tools/qtestlib/wince/cetest/deployment.cpp +++ b/tools/qtestlib/wince/cetest/deployment.cpp @@ -125,13 +125,37 @@ void DeploymentHandler::initQtDeploy(QMakeProject *project, DeploymentList &depl if (!project->values("QMAKE_QT_DLL").isEmpty() && !project->values("QMAKE_LIBDIR").isEmpty()) { QStringList libs = project->values("LIBS"); QStringList qtLibs; + QStringList libPaths; foreach (QString item, libs) { - if (item.startsWith("-lQt")) { - qtLibs += project->values("QMAKE_LIBDIR").at(0) + QDir::separator() + item.mid(2) + QLatin1String("4.dll"); + + if (item.startsWith("-L")) { + // -L -> a directory containing DLLs + libPaths << item.mid(2); + continue; + } + + QStringList libCandidates; + + if (item.startsWith("-l")) { + // -l -> a library located within one of the standard library paths + QString lib = item.mid(2); + + // Check if it's a Qt library first, then check in all paths given with -L. + // Note Qt libraries get a `4' appended to them, others don't. + libCandidates << project->values("QMAKE_LIBDIR").at(0) + QDir::separator() + lib + QLatin1String("4.dll"); + foreach (QString const& libPath, libPaths) { + libCandidates << libPath + QDir::separator() + lib + QLatin1String(".dll"); + } } else { - QFileInfo info(item); - if (info.exists() && info.isAbsolute() && info.fileName().startsWith(QLatin1String("Qt"))) - qtLibs += info.dir().absoluteFilePath(info.fileName().replace(QLatin1String(".lib"), QLatin1String(".dll"))); + libCandidates << item.replace(".lib",".dll"); + } + + foreach (QString const& file, libCandidates) { + QFileInfo info(file); + if (info.exists()) { + qtLibs += info.dir().absoluteFilePath(info.fileName()); + break; + } } } for (QStringList::ConstIterator it = qtLibs.constBegin(); it != qtLibs.constEnd(); ++it) { -- cgit v0.12 From b4028f5a2195a432059ff26c288d772af47bc14d Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 2 Jul 2009 17:03:31 +1000 Subject: Fixed cetest compile. --- tools/qtestlib/wince/cetest/activesyncconnection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/qtestlib/wince/cetest/activesyncconnection.cpp b/tools/qtestlib/wince/cetest/activesyncconnection.cpp index 99fac2c..0f98619 100644 --- a/tools/qtestlib/wince/cetest/activesyncconnection.cpp +++ b/tools/qtestlib/wince/cetest/activesyncconnection.cpp @@ -422,7 +422,7 @@ bool ActiveSyncConnection::execute(QString program, QString arguments, int timeo } if (error) { - qWarning() << "Error on target:" << strwinerror(error); + qWarning("Error on target: %s", strwinerror(error).constData()); result = false; } else { -- cgit v0.12 From 5fc3fe2e3f04475ac8c0e3287af6042bd8b67c57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Thu, 2 Jul 2009 09:56:13 +0200 Subject: Dont include untransformable graphics items twice. This revertes d39a62720ba67a0fa6e4e37519d22f14c7b7404e (we had to do it with the old implementation, but the new one have untransformable items included in the indexed list. The only difference is that untransformable items are also in the untransformable list; otherwise in the bsp tree). Auto-test included. --- .../graphicsview/qgraphicsscenebsptreeindex.cpp | 1 - .../tst_qgraphicssceneindex.cpp | 39 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index ff9a3da..c8d755e 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -606,7 +606,6 @@ QList QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order) co itemList << item; } } - itemList += d->untransformableItems; if (order != -1) { //We sort descending order d->sortItems(&itemList, order, d->sortCacheEnabled); diff --git a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp index 9d0675d..3ce5b16 100644 --- a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp +++ b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp @@ -65,6 +65,7 @@ private slots: void movingItems_data(); void movingItems(); void connectedToSceneRectChanged(); + void items(); private: void common_data(); @@ -228,5 +229,43 @@ void tst_QGraphicsSceneIndex::connectedToSceneRectChanged() QCOMPARE(scene.receivers(SIGNAL(sceneRectChanged(const QRectF&))), 1); } +void tst_QGraphicsSceneIndex::items() +{ + QGraphicsScene scene; + QGraphicsItem *item1 = scene.addRect(0, 0, 10, 10); + QGraphicsItem *item2 = scene.addRect(10, 10, 10, 10); + QCOMPARE(scene.items().size(), 2); + + // Move from unindexed items into bsp tree. + QTest::qWait(50); + QCOMPARE(scene.items().size(), 2); + + // Add untransformable item. + QGraphicsItem *item3 = new QGraphicsRectItem(QRectF(20, 20, 10, 10)); + item3->setFlag(QGraphicsItem::ItemIgnoresTransformations); + scene.addItem(item3); + QCOMPARE(scene.items().size(), 3); + + // Move from unindexed items into untransformable items. + QTest::qWait(50); + QCOMPARE(scene.items().size(), 3); + + // Move from untransformable items into unindexed items. + item3->setFlag(QGraphicsItem::ItemIgnoresTransformations, false); + QCOMPARE(scene.items().size(), 3); + QTest::qWait(50); + QCOMPARE(scene.items().size(), 3); + + // Make all items untransformable. + item1->setFlag(QGraphicsItem::ItemIgnoresTransformations); + item2->setParentItem(item1); + item3->setParentItem(item2); + QCOMPARE(scene.items().size(), 3); + + // Move from unindexed items into untransformable items. + QTest::qWait(50); + QCOMPARE(scene.items().size(), 3); +} + QTEST_MAIN(tst_QGraphicsSceneIndex) #include "tst_qgraphicssceneindex.moc" -- cgit v0.12 From 69083610b09aaabbff5e8a177fac713a6a6d46ba Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 2 Jul 2009 10:38:08 +0200 Subject: doc: Corrected several qdoc warnings. --- src/gui/graphicsview/qgraphicssceneevent.cpp | 5 ++++- src/gui/kernel/qevent.cpp | 4 ++++ src/gui/kernel/qgesturerecognizer.cpp | 7 ++++--- src/qt3support/sql/q3datatable.cpp | 2 -- tools/qdoc3/test/qt-cpp-ignore.qdocconf | 3 ++- tools/qdoc3/test/qt-inc.qdocconf | 3 ++- 6 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/gui/graphicsview/qgraphicssceneevent.cpp b/src/gui/graphicsview/qgraphicssceneevent.cpp index 338f12a..27a2d7e 100644 --- a/src/gui/graphicsview/qgraphicssceneevent.cpp +++ b/src/gui/graphicsview/qgraphicssceneevent.cpp @@ -1892,8 +1892,11 @@ void QGraphicsSceneGestureEvent::acceptAll() setAccepted(true); } -/*! +/*! \fn void QGraphicsSceneGestureEvent::accept() + Calls QEvent::accept(). +*/ +/*! Sets the accept flag of the gesture specified by \a type. This is equivalent to calling \l{QGestureEvent::gesture()} {gesture(type)}-> \l{QGesture::accept()}{accept()} diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index e40ad9d..a7a7f2d 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -3628,6 +3628,10 @@ QSet QGestureEvent::cancelledGestures() const return m_cancelledGestures; } +/*! \fn void QGestureEvent::accept() + Calls QEvent::accept(). +*/ + /*! Sets the accept flag of the all gestures inside the event object, the equivalent of calling \l{QEvent::accept()}{accept()} or diff --git a/src/gui/kernel/qgesturerecognizer.cpp b/src/gui/kernel/qgesturerecognizer.cpp index c330663..30889d7 100644 --- a/src/gui/kernel/qgesturerecognizer.cpp +++ b/src/gui/kernel/qgesturerecognizer.cpp @@ -97,8 +97,8 @@ QString qt_getStandardGestureTypeName(Qt::GestureType gestureType); This is a pure virtual function that needs to be implemented in subclasses. - Parses input \a event and returns the result, which specifies if - the event sequence is a gesture or not. + Parses input \a event and returns the result, which specifies + whether the event sequence is a gesture or not. */ /*! \fn QGesture* QGestureRecognizer::getGesture() @@ -123,7 +123,8 @@ QString qt_getStandardGestureTypeName(Qt::GestureType gestureType); The gesture recognizer might emit the stateChanged() signal when the gesture state changes asynchronously, i.e. without any event - being filtered through filterEvent(). + being filtered through filterEvent(). \a result specifies whether + the event sequence is a gesture or not. */ QGestureRecognizerPrivate::QGestureRecognizerPrivate() diff --git a/src/qt3support/sql/q3datatable.cpp b/src/qt3support/sql/q3datatable.cpp index 638aff8..d8d3c2b 100644 --- a/src/qt3support/sql/q3datatable.cpp +++ b/src/qt3support/sql/q3datatable.cpp @@ -1726,8 +1726,6 @@ void Q3DataTable::repaintCell( int row, int col ) the content coordinate system. If \a selected is true the cell has been selected and would normally be rendered differently than an unselected cell. - - \sa QSql::isNull() */ void Q3DataTable::paintCell( QPainter * p, int row, int col, const QRect & cr, diff --git a/tools/qdoc3/test/qt-cpp-ignore.qdocconf b/tools/qdoc3/test/qt-cpp-ignore.qdocconf index 9a18abe..709e336 100644 --- a/tools/qdoc3/test/qt-cpp-ignore.qdocconf +++ b/tools/qdoc3/test/qt-cpp-ignore.qdocconf @@ -68,7 +68,8 @@ Cpp.ignoretokens = QAXFACTORY_EXPORT \ QT_END_NAMESPACE \ QT_END_INCLUDE_NAMESPACE \ PHONON_EXPORT \ - Q_GADGET + Q_GADGET \ + QWEBKIT_EXPORT Cpp.ignoredirectives = Q_DECLARE_HANDLE \ Q_DECLARE_INTERFACE \ Q_DECLARE_METATYPE \ diff --git a/tools/qdoc3/test/qt-inc.qdocconf b/tools/qdoc3/test/qt-inc.qdocconf index 01b07b3..542c7ca 100644 --- a/tools/qdoc3/test/qt-inc.qdocconf +++ b/tools/qdoc3/test/qt-inc.qdocconf @@ -100,7 +100,8 @@ Cpp.ignoretokens = QAXFACTORY_EXPORT \ Q_TYPENAME \ Q_XML_EXPORT \ QDBUS_EXPORT \ - Q_GADGET + Q_GADGET \ + QWEBKIT_EXPORT Cpp.ignoredirectives = Q_DECLARE_HANDLE \ Q_DECLARE_INTERFACE \ Q_DECLARE_METATYPE \ -- cgit v0.12 From 6d71de4283c05b1b42ef26fe4c23334ad34c8a54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Thu, 2 Jul 2009 10:46:37 +0200 Subject: Kill dead BSP tree code in graphics view. --- src/gui/graphicsview/qgraphicsscene_bsp.cpp | 41 ----------------------------- src/gui/graphicsview/qgraphicsscene_bsp_p.h | 3 --- 2 files changed, 44 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene_bsp.cpp b/src/gui/graphicsview/qgraphicsscene_bsp.cpp index 5858eab..7d30749 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp.cpp +++ b/src/gui/graphicsview/qgraphicsscene_bsp.cpp @@ -154,17 +154,6 @@ QList QGraphicsSceneBspTree::items(const QRectF &rect) const return tmp; } -QList QGraphicsSceneBspTree::items(const QPointF &pos) const -{ - QList tmp; - findVisitor->foundItems = &tmp; - climbTree(findVisitor, pos); - // Reset discovery bits. - for (int i = 0; i < tmp.size(); ++i) - tmp.at(i)->d_ptr->itemDiscovered = 0; - return tmp; -} - int QGraphicsSceneBspTree::leafCount() const { return leafCnt; @@ -241,36 +230,6 @@ void QGraphicsSceneBspTree::initialize(const QRectF &rect, int depth, int index) } } -void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QPointF &pos, int index) const -{ - if (nodes.isEmpty()) - return; - - const Node &node = nodes.at(index); - const int childIndex = firstChildIndex(index); - - switch (node.type) { - case Node::Leaf: { - visitor->visit(const_cast*>(&leaves[node.leafIndex])); - break; - } - case Node::Vertical: - if (pos.x() < node.offset) { - climbTree(visitor, pos, childIndex); - } else { - climbTree(visitor, pos, childIndex + 1); - } - break; - case Node::Horizontal: - if (pos.y() < node.offset) { - climbTree(visitor, pos, childIndex); - } else { - climbTree(visitor, pos, childIndex + 1); - } - break; - } -} - void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QRectF &rect, int index) const { if (nodes.isEmpty()) diff --git a/src/gui/graphicsview/qgraphicsscene_bsp_p.h b/src/gui/graphicsview/qgraphicsscene_bsp_p.h index 323cf04..24b926c 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp_p.h +++ b/src/gui/graphicsview/qgraphicsscene_bsp_p.h @@ -93,7 +93,6 @@ public: void removeItems(const QSet &items); QList items(const QRectF &rect) const; - QList items(const QPointF &pos) const; int leafCount() const; inline int firstChildIndex(int index) const @@ -106,11 +105,9 @@ public: private: void initialize(const QRectF &rect, int depth, int index); - void climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QPointF &pos, int index = 0) const; void climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QRectF &rect, int index = 0) const; void findItems(QList *foundItems, const QRectF &rect, int index); - void findItems(QList *foundItems, const QPointF &pos, int index); QRectF rectForIndex(int index) const; QVector nodes; -- cgit v0.12 From ad637177fa62f6ac92b653735bc2f743d7af2851 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 2 Jul 2009 11:10:36 +0200 Subject: add a few QObject binding tests --- tests/auto/qscriptqobject/tst_qscriptqobject.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/auto/qscriptqobject/tst_qscriptqobject.cpp b/tests/auto/qscriptqobject/tst_qscriptqobject.cpp index 14d3283..ee914ab 100644 --- a/tests/auto/qscriptqobject/tst_qscriptqobject.cpp +++ b/tests/auto/qscriptqobject/tst_qscriptqobject.cpp @@ -605,6 +605,12 @@ void tst_QScriptExtQObject::getSetStaticProperty() QVERIFY(!(mobj.propertyFlags("mySlot") & QScriptValue::Undeletable)); QVERIFY(!(mobj.propertyFlags("mySlot") & QScriptValue::SkipInEnumeration)); QVERIFY(mobj.propertyFlags("mySlot") & QScriptValue::QObjectMember); + + // signature-based property + QVERIFY(!(mobj.propertyFlags("mySlot()") & QScriptValue::ReadOnly)); + QVERIFY(!(mobj.propertyFlags("mySlot()") & QScriptValue::Undeletable)); + QVERIFY(!(mobj.propertyFlags("mySlot()") & QScriptValue::SkipInEnumeration)); + QVERIFY(mobj.propertyFlags("mySlot()") & QScriptValue::QObjectMember); } // property change in C++ should be reflected in script @@ -847,6 +853,9 @@ void tst_QScriptExtQObject::getSetStaticProperty() QVERIFY(slot.isFunction()); QScriptValue sameSlot = m_engine->evaluate("myObject.mySlot"); QVERIFY(sameSlot.strictlyEquals(slot)); + sameSlot = m_engine->evaluate("myObject['mySlot()']"); + QEXPECT_FAIL("", "Signature-based method lookup creates new function wrapper object", Continue); + QVERIFY(sameSlot.strictlyEquals(slot)); } } @@ -897,6 +906,20 @@ void tst_QScriptExtQObject::getSetChildren() QCOMPARE(m_engine->evaluate("myObject.hasOwnProperty('child')") .strictlyEquals(QScriptValue(m_engine, true)), true); + QScriptValue mobj = m_engine->evaluate("myObject"); + QVERIFY(mobj.propertyFlags("child") & QScriptValue::ReadOnly); + QVERIFY(mobj.propertyFlags("child") & QScriptValue::Undeletable); + QVERIFY(mobj.propertyFlags("child") & QScriptValue::SkipInEnumeration); + QVERIFY(!(mobj.propertyFlags("child") & QScriptValue::QObjectMember)); + + { + QScriptValue scriptChild = m_engine->evaluate("myObject.child"); + QVERIFY(scriptChild.isQObject()); + QCOMPARE(scriptChild.toQObject(), (QObject*)child); + QScriptValue sameChild = m_engine->evaluate("myObject.child"); + QVERIFY(sameChild.strictlyEquals(scriptChild)); + } + // add a grandchild MyQObject *grandChild = new MyQObject(child); grandChild->setObjectName("grandChild"); -- cgit v0.12 From cd4901b1e3a545d025628e881a143b8f240d2690 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 2 Jul 2009 11:37:53 +0200 Subject: doc: Corrected several qdoc warnings. --- doc/src/qnamespace.qdoc | 3 +++ src/gui/kernel/qapplication.cpp | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/src/qnamespace.qdoc b/doc/src/qnamespace.qdoc index 805855a..e77cc7e 100644 --- a/doc/src/qnamespace.qdoc +++ b/doc/src/qnamespace.qdoc @@ -1208,6 +1208,9 @@ handle touch events. Without this attribute set, events from a touch device will be sent as mouse events. + \value WA_TouchPadAcceptSingleTouchEvents Allows touchpad single + touch events to be sent to the widget. + \omitvalue WA_SetLayoutDirection \omitvalue WA_InputMethodTransparent \omitvalue WA_WState_CompressKeys diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 60c69cc..a7b7a0a 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -5064,7 +5064,7 @@ bool QApplicationPrivate::shouldSetFocus(QWidget *w, Qt::FocusPolicy policy) Qt takes ownership of the provided \a recognizer. - \sa Qt::AA_EnableGestures, QGestureEvent + \sa QGestureEvent */ void QApplication::addGestureRecognizer(QGestureRecognizer *recognizer) { @@ -5076,7 +5076,7 @@ void QApplication::addGestureRecognizer(QGestureRecognizer *recognizer) Removes custom gesture \a recognizer object. - \sa Qt::AA_EnableGestures, QGestureEvent + \sa QGestureEvent */ void QApplication::removeGestureRecognizer(QGestureRecognizer *recognizer) { -- cgit v0.12 From 11ef1b9bae383c46f7893db0d26c99d354642609 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2009 20:50:32 +0200 Subject: Add a function to check if an interface is implemented by an object. Also reorganise a bit, moving the function to create the interface name from an object's class name to qdbusmisc.cpp too. Reviewed-By: Trust Me --- src/dbus/qdbusconnection_p.h | 5 ++--- src/dbus/qdbusintegrator.cpp | 8 ++----- src/dbus/qdbusmisc.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++ src/dbus/qdbusxmlgenerator.cpp | 37 --------------------------------- 4 files changed, 51 insertions(+), 46 deletions(-) diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index 5c37509..a156a71 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -300,6 +300,8 @@ public: extern int qDBusParametersForMethod(const QMetaMethod &mm, QList& metaTypes); extern int qDBusNameToTypeId(const char *name); extern bool qDBusCheckAsyncTag(const char *tag); +extern bool qDBusInterfaceInObject(QObject *obj, const QString &interface_name); +extern QString qDBusInterfaceFromMetaObject(const QMetaObject *mo); // in qdbusinternalfilters.cpp extern QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node); @@ -310,9 +312,6 @@ extern QDBusMessage qDBusPropertySet(const QDBusConnectionPrivate::ObjectTreeNod extern QDBusMessage qDBusPropertyGetAll(const QDBusConnectionPrivate::ObjectTreeNode &node, const QDBusMessage &msg); -// in qdbusxmlgenerator.cpp -extern QString qDBusInterfaceFromMetaObject(const QMetaObject *mo); - QT_END_NAMESPACE #endif diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 0578bf1..76179c9 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1359,12 +1359,8 @@ void QDBusConnectionPrivate::activateObject(ObjectTreeNode &node, const QDBusMes // try the object itself: if (node.flags & (QDBusConnection::ExportScriptableSlots|QDBusConnection::ExportNonScriptableSlots)) { bool interfaceFound = true; - if (!msg.interface().isEmpty()) { - // check if the interface name matches anything in the class hierarchy - const QMetaObject *mo = node.obj->metaObject(); - for ( ; !interfaceFound && mo != &QObject::staticMetaObject; mo = mo->superClass()) - interfaceFound = msg.interface() == qDBusInterfaceFromMetaObject(mo); - } + if (!msg.interface().isEmpty()) + interfaceFound = qDBusInterfaceInObject(node.obj, msg.interface()); if (interfaceFound) { if (!activateCall(node.obj, node.flags, msg)) diff --git a/src/dbus/qdbusmisc.cpp b/src/dbus/qdbusmisc.cpp index e5c1da6..1b77a9b 100644 --- a/src/dbus/qdbusmisc.cpp +++ b/src/dbus/qdbusmisc.cpp @@ -41,12 +41,14 @@ #include +#include #include #include #include "qdbusutil_p.h" #include "qdbusconnection_p.h" #include "qdbusmetatype_p.h" +#include "qdbusabstractadaptor_p.h" // for QCLASSINFO_DBUS_* QT_BEGIN_NAMESPACE @@ -73,6 +75,51 @@ int qDBusNameToTypeId(const char *name) return id; } +QString qDBusInterfaceFromMetaObject(const QMetaObject *mo) +{ + QString interface; + + int idx = mo->indexOfClassInfo(QCLASSINFO_DBUS_INTERFACE); + if (idx >= mo->classInfoOffset()) { + interface = QLatin1String(mo->classInfo(idx).value()); + } else { + interface = QLatin1String(mo->className()); + interface.replace(QLatin1String("::"), QLatin1String(".")); + + if (interface.startsWith(QLatin1String("QDBus"))) { + interface.prepend(QLatin1String("com.trolltech.QtDBus.")); + } else if (interface.startsWith(QLatin1Char('Q')) && + interface.length() >= 2 && interface.at(1).isUpper()) { + // assume it's Qt + interface.prepend(QLatin1String("com.trolltech.Qt.")); + } else if (!QCoreApplication::instance()|| + QCoreApplication::instance()->applicationName().isEmpty()) { + interface.prepend(QLatin1String("local.")); + } else { + interface.prepend(QLatin1Char('.')).prepend(QCoreApplication::instance()->applicationName()); + QStringList domainName = + QCoreApplication::instance()->organizationDomain().split(QLatin1Char('.'), + QString::SkipEmptyParts); + if (domainName.isEmpty()) + interface.prepend(QLatin1String("local.")); + else + for (int i = 0; i < domainName.count(); ++i) + interface.prepend(QLatin1Char('.')).prepend(domainName.at(i)); + } + } + + return interface; +} + +bool qDBusInterfaceInObject(QObject *obj, const QString &interface_name) +{ + const QMetaObject *mo = obj->metaObject(); + for ( ; mo != &QObject::staticMetaObject; mo = mo->superClass()) + if (interface_name == qDBusInterfaceFromMetaObject(mo)) + return true; + return false; +} + // calculates the metatypes for the method // the slot must have the parameters in the following form: // - zero or more value or const-ref parameters of any kind diff --git a/src/dbus/qdbusxmlgenerator.cpp b/src/dbus/qdbusxmlgenerator.cpp index 82bd762..b426abd 100644 --- a/src/dbus/qdbusxmlgenerator.cpp +++ b/src/dbus/qdbusxmlgenerator.cpp @@ -39,7 +39,6 @@ ** ****************************************************************************/ -#include #include #include @@ -232,42 +231,6 @@ static QString generateInterfaceXml(const QMetaObject *mo, int flags, int method return retval; } -QString qDBusInterfaceFromMetaObject(const QMetaObject *mo) -{ - QString interface; - - int idx = mo->indexOfClassInfo(QCLASSINFO_DBUS_INTERFACE); - if (idx >= mo->classInfoOffset()) { - interface = QLatin1String(mo->classInfo(idx).value()); - } else { - interface = QLatin1String(mo->className()); - interface.replace(QLatin1String("::"), QLatin1String(".")); - - if (interface.startsWith(QLatin1String("QDBus"))) { - interface.prepend(QLatin1String("com.trolltech.QtDBus.")); - } else if (interface.startsWith(QLatin1Char('Q')) && - interface.length() >= 2 && interface.at(1).isUpper()) { - // assume it's Qt - interface.prepend(QLatin1String("com.trolltech.Qt.")); - } else if (!QCoreApplication::instance()|| - QCoreApplication::instance()->applicationName().isEmpty()) { - interface.prepend(QLatin1String("local.")); - } else { - interface.prepend(QLatin1Char('.')).prepend(QCoreApplication::instance()->applicationName()); - QStringList domainName = - QCoreApplication::instance()->organizationDomain().split(QLatin1Char('.'), - QString::SkipEmptyParts); - if (domainName.isEmpty()) - interface.prepend(QLatin1String("local.")); - else - for (int i = 0; i < domainName.count(); ++i) - interface.prepend(QLatin1Char('.')).prepend(domainName.at(i)); - } - } - - return interface; - } - QString qDBusGenerateMetaObjectXml(QString interface, const QMetaObject *mo, const QMetaObject *base, int flags) { -- cgit v0.12 From 6bd18f891b4bbc265e5ddd18ba57095886b36e38 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 29 Jun 2009 15:32:26 +0200 Subject: Add some new error codes for indicating invalid D-Bus parameters. I'm wondering if I should be adding com.trolltech.QtDBus stuff now. But since there's already one there, I don't see why not... Reviewed-By: Harald Fernengel --- src/dbus/qdbuserror.cpp | 11 ++++++++++- src/dbus/qdbuserror.h | 6 +++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/dbus/qdbuserror.cpp b/src/dbus/qdbuserror.cpp index 817356d..7509ded 100644 --- a/src/dbus/qdbuserror.cpp +++ b/src/dbus/qdbuserror.cpp @@ -91,6 +91,10 @@ org.freedesktop.DBus.Error.InvalidSignature org.freedesktop.DBus.Error.UnknownInterface com.trolltech.QtDBus.Error.InternalError org.freedesktop.DBus.Error.UnknownObject +com.trolltech.QtDBus.Error.InvalidService +com.trolltech.QtDBus.Error.InvalidObjectPath +com.trolltech.QtDBus.Error.InvalidInterface +com.trolltech.QtDBus.Error.InvalidMember */ // in the same order as KnownErrors! @@ -116,12 +120,17 @@ static const char errorMessages_string[] = "org.freedesktop.DBus.Error.UnknownInterface\0" "com.trolltech.QtDBus.Error.InternalError\0" "org.freedesktop.DBus.Error.UnknownObject\0" + "com.trolltech.QtDBus.Error.InvalidService\0" + "com.trolltech.QtDBus.Error.InvalidObjectPath\0" + "com.trolltech.QtDBus.Error.InvalidInterface\0" + "com.trolltech.QtDBus.Error.InvalidMember\0" "\0"; static const int errorMessages_indices[] = { 0, 6, 40, 76, 118, 153, 191, 231, 273, 313, 349, 384, 421, 461, 501, 540, - 581, 617, 661, 705, 746, 0 + 581, 617, 661, 705, 746, 787, 829, 874, + 918, 0 }; static const int errorMessages_count = sizeof errorMessages_indices / diff --git a/src/dbus/qdbuserror.h b/src/dbus/qdbuserror.h index 7b77fd5..4e348dd 100644 --- a/src/dbus/qdbuserror.h +++ b/src/dbus/qdbuserror.h @@ -81,10 +81,14 @@ public: UnknownInterface, InternalError, UnknownObject, + InvalidService, + InvalidObjectPath, + InvalidInterface, + InvalidMember, #ifndef Q_QDOC // don't use this one! - LastErrorType = UnknownObject + LastErrorType = InvalidMember #endif }; -- cgit v0.12 From 96152ee50dfca7adf47b81b14015355260564a22 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 29 Jun 2009 17:52:33 +0200 Subject: Add central validation code to QDBusUtil. These tests are useful in QDBusMessage and QDBusAbstractInterface. It avoids having the same messages all over the place. Reviewed-By: Harald Fernengel --- src/dbus/qdbusutil_p.h | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/dbus/qdbusutil_p.h b/src/dbus/qdbusutil_p.h index 13031fd..5c1e4cd 100644 --- a/src/dbus/qdbusutil_p.h +++ b/src/dbus/qdbusutil_p.h @@ -57,6 +57,7 @@ #include #include +#include QT_BEGIN_HEADER @@ -83,6 +84,73 @@ namespace QDBusUtil QDBUS_EXPORT bool isValidSingleSignature(const QString &signature); QDBUS_EXPORT QString argumentToString(const QVariant &variant); + + enum AllowEmptyFlag { + EmptyAllowed, + EmptyNotAllowed + }; + + inline bool checkInterfaceName(const QString &name, AllowEmptyFlag empty, QDBusError *error) + { + if (name.isEmpty()) { + if (empty == EmptyAllowed) return true; + *error = QDBusError(QDBusError::InvalidInterface, QLatin1String("Interface name cannot be empty")); + return false; + } + if (isValidInterfaceName(name)) return true; + *error = QDBusError(QDBusError::InvalidInterface, QString::fromLatin1("Invalid interface class: %1").arg(name)); + return false; + } + + inline bool checkBusName(const QString &name, AllowEmptyFlag empty, QDBusError *error) + { + if (name.isEmpty()) { + if (empty == EmptyAllowed) return true; + *error = QDBusError(QDBusError::InvalidService, QLatin1String("Service name cannot be empty")); + return false; + } + if (isValidBusName(name)) return true; + *error = QDBusError(QDBusError::InvalidService, QString::fromLatin1("Invalid service name: %1").arg(name)); + return false; + } + + inline bool checkObjectPath(const QString &path, AllowEmptyFlag empty, QDBusError *error) + { + if (path.isEmpty()) { + if (empty == EmptyAllowed) return true; + *error = QDBusError(QDBusError::InvalidObjectPath, QLatin1String("Object path cannot be empty")); + return false; + } + if (isValidObjectPath(path)) return true; + *error = QDBusError(QDBusError::InvalidObjectPath, QString::fromLatin1("Invalid object path: %1").arg(path)); + return false; + } + + inline bool checkMemberName(const QString &name, AllowEmptyFlag empty, QDBusError *error, const char *nameType = 0) + { + if (!nameType) nameType = "member"; + if (name.isEmpty()) { + if (empty == EmptyAllowed) return true; + *error = QDBusError(QDBusError::InvalidMember, QLatin1String(nameType) + QLatin1String(" name cannot be empty")); + return false; + } + if (isValidMemberName(name)) return true; + *error = QDBusError(QDBusError::InvalidMember, QString::fromLatin1("Invalid %1 name: %2") + .arg(QString::fromLatin1(nameType), name)); + return false; + } + + inline bool checkErrorName(const QString &name, AllowEmptyFlag empty, QDBusError *error) + { + if (name.isEmpty()) { + if (empty == EmptyAllowed) return true; + *error = QDBusError(QDBusError::InvalidInterface, QLatin1String("Error name cannot be empty")); + return false; + } + if (isValidErrorName(name)) return true; + *error = QDBusError(QDBusError::InvalidInterface, QString::fromLatin1("Invalid error name: %1").arg(name)); + return false; + } } QT_END_NAMESPACE -- cgit v0.12 From bda9c20a556aa6ab6ccba978f7fc1ffe02c50813 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 29 Jun 2009 16:31:09 +0200 Subject: Add support for error messages in the D-Bus marshaller. Reviewed-By: Harald Fernengel --- src/dbus/qdbusargument_p.h | 3 ++- src/dbus/qdbusmarshaller.cpp | 35 ++++++++++++++++++++++------------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/dbus/qdbusargument_p.h b/src/dbus/qdbusargument_p.h index b49a517..78bc683 100644 --- a/src/dbus/qdbusargument_p.h +++ b/src/dbus/qdbusargument_p.h @@ -130,7 +130,7 @@ public: QDBusMarshaller *endCommon(); void open(QDBusMarshaller &sub, int code, const char *signature); void close(); - void error(); + void error(const QString &message); bool appendVariantInternal(const QVariant &arg); bool appendRegisteredType(const QVariant &arg); @@ -140,6 +140,7 @@ public: DBusMessageIter iterator; QDBusMarshaller *parent; QByteArray *ba; + QString errorString; char closeCode; bool ok; diff --git a/src/dbus/qdbusmarshaller.cpp b/src/dbus/qdbusmarshaller.cpp index 7ada1ed..bb7fa6b 100644 --- a/src/dbus/qdbusmarshaller.cpp +++ b/src/dbus/qdbusmarshaller.cpp @@ -121,7 +121,7 @@ inline void QDBusMarshaller::append(const QDBusObjectPath &arg) { QByteArray data = arg.path().toUtf8(); if (!ba && data.isEmpty()) - error(); + error(QLatin1String("Invalid object path passed in arguments")); const char *cdata = data.constData(); qIterAppend(&iterator, ba, DBUS_TYPE_OBJECT_PATH, &cdata); } @@ -130,7 +130,7 @@ inline void QDBusMarshaller::append(const QDBusSignature &arg) { QByteArray data = arg.signature().toUtf8(); if (!ba && data.isEmpty()) - error(); + error(QLatin1String("Invalid signature passed in arguments")); const char *cdata = data.constData(); qIterAppend(&iterator, ba, DBUS_TYPE_SIGNATURE, &cdata); } @@ -161,7 +161,7 @@ inline bool QDBusMarshaller::append(const QDBusVariant &arg) QVariant::Type id = QVariant::Type(value.userType()); if (id == QVariant::Invalid) { qWarning("QDBusMarshaller: cannot add a null QDBusVariant"); - error(); + error(QLatin1String("Variant containing QVariant::Invalid passed in arguments")); return false; } @@ -180,7 +180,8 @@ inline bool QDBusMarshaller::append(const QDBusVariant &arg) qWarning("QDBusMarshaller: type `%s' (%d) is not registered with D-BUS. " "Use qDBusRegisterMetaType to register it", QVariant::typeToName( id ), id); - error(); + error(QString::fromLatin1("Unregistered type %1 passed in arguments") + .arg(QLatin1String(QVariant::typeToName(id)))); return false; } @@ -220,7 +221,8 @@ inline QDBusMarshaller *QDBusMarshaller::beginArray(int id) qWarning("QDBusMarshaller: type `%s' (%d) is not registered with D-BUS. " "Use qDBusRegisterMetaType to register it", QVariant::typeToName( QVariant::Type(id) ), id); - error(); + error(QString::fromLatin1("Unregistered type %1 passed in arguments") + .arg(QLatin1String(QVariant::typeToName(QVariant::Type(id))))); return this; } @@ -234,22 +236,26 @@ inline QDBusMarshaller *QDBusMarshaller::beginMap(int kid, int vid) qWarning("QDBusMarshaller: type `%s' (%d) is not registered with D-BUS. " "Use qDBusRegisterMetaType to register it", QVariant::typeToName( QVariant::Type(kid) ), kid); - error(); + error(QString::fromLatin1("Unregistered type %1 passed in arguments") + .arg(QLatin1String(QVariant::typeToName(QVariant::Type(kid))))); return this; } if (ksignature[1] != 0 || !q_dbus_type_is_basic(*ksignature)) { qWarning("QDBusMarshaller: type '%s' (%d) cannot be used as the key type in a D-BUS map.", QVariant::typeToName( QVariant::Type(kid) ), kid); - error(); + error(QString::fromLatin1("Type %1 passed in arguments cannot be used as a key in a map") + .arg(QLatin1String(QVariant::typeToName(QVariant::Type(kid))))); return this; } const char *vsignature = QDBusMetaType::typeToSignature( QVariant::Type(vid) ); if (!vsignature) { + const char *typeName = QVariant::typeToName(QVariant::Type(vid)); qWarning("QDBusMarshaller: type `%s' (%d) is not registered with D-BUS. " "Use qDBusRegisterMetaType to register it", - QVariant::typeToName( QVariant::Type(vid) ), vid); - error(); + typeName, vid); + error(QString::fromLatin1("Unregistered type %1 passed in arguments") + .arg(QLatin1String(typeName))); return this; } @@ -328,11 +334,13 @@ void QDBusMarshaller::close() } } -void QDBusMarshaller::error() +void QDBusMarshaller::error(const QString &msg) { ok = false; if (parent) - parent->error(); + parent->error(msg); + else + errorString = msg; } bool QDBusMarshaller::appendVariantInternal(const QVariant &arg) @@ -340,7 +348,7 @@ bool QDBusMarshaller::appendVariantInternal(const QVariant &arg) int id = arg.userType(); if (id == QVariant::Invalid) { qWarning("QDBusMarshaller: cannot add an invalid QVariant"); - error(); + error(QLatin1String("Variant containing QVariant::Invalid passed in arguments")); return false; } @@ -371,7 +379,8 @@ bool QDBusMarshaller::appendVariantInternal(const QVariant &arg) qWarning("QDBusMarshaller: type `%s' (%d) is not registered with D-BUS. " "Use qDBusRegisterMetaType to register it", QVariant::typeToName( QVariant::Type(id) ), id); - error(); + error(QString::fromLatin1("Unregistered type %1 passed in arguments") + .arg(QLatin1String(QVariant::typeToName(QVariant::Type(id))))); return false; } -- cgit v0.12 From 6b0b1a3eefe60dbeed3f56770fb58d487852e45b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2009 11:47:46 +0200 Subject: Adapt the message-sending code to return error messages from the marshalling code. Reviewed-By: Harald Fernengel --- src/dbus/qdbusintegrator.cpp | 89 +++++++++++++++----------- src/dbus/qdbusmessage.cpp | 48 ++++++++++---- src/dbus/qdbusmessage_p.h | 2 +- tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp | 16 ++++- 4 files changed, 104 insertions(+), 51 deletions(-) diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 76179c9..704d2e3 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1144,9 +1144,12 @@ void QDBusConnectionPrivate::relaySignal(QObject *obj, const QMetaObject *mo, in QDBusMessage message = QDBusMessage::createSignal(QLatin1String("/"), interface, QLatin1String(memberName)); message.setArguments(args); - DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message); + QDBusError error; + DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message, &error); if (!msg) { - qWarning("QDBusConnection: Could not emit signal %s.%s", qPrintable(interface), memberName.constData()); + qWarning("QDBusConnection: Could not emit signal %s.%s: %s", qPrintable(interface), memberName.constData(), + qPrintable(error.message())); + lastError = error; return; } @@ -1698,21 +1701,26 @@ int QDBusConnectionPrivate::send(const QDBusMessage& message) return -1; // don't send; the reply will be retrieved by the caller // through the d_ptr->localReply link - DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message); + QDBusError error; + DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message, &error); if (!msg) { if (message.type() == QDBusMessage::MethodCallMessage) - qWarning("QDBusConnection: error: could not send message to service \"%s\" path \"%s\" interface \"%s\" member \"%s\"", + qWarning("QDBusConnection: error: could not send message to service \"%s\" path \"%s\" interface \"%s\" member \"%s\": %s", qPrintable(message.service()), qPrintable(message.path()), - qPrintable(message.interface()), qPrintable(message.member())); + qPrintable(message.interface()), qPrintable(message.member()), + qPrintable(error.message())); else if (message.type() == QDBusMessage::SignalMessage) - qWarning("QDBusConnection: error: could not send signal path \"%s\" interface \"%s\" member \"%s\"", + qWarning("QDBusConnection: error: could not send signal path \"%s\" interface \"%s\" member \"%s\": %s", qPrintable(message.path()), qPrintable(message.interface()), - qPrintable(message.member())); + qPrintable(message.member()), + qPrintable(error.message())); else - qWarning("QDBusConnection: error: could not send %s message to service \"%s\"", + qWarning("QDBusConnection: error: could not send %s message to service \"%s\": %s", message.type() == QDBusMessage::ReplyMessage ? "reply" : message.type() == QDBusMessage::ErrorMessage ? "error" : - "invalid", qPrintable(message.service())); + "invalid", qPrintable(message.service()), + qPrintable(error.message())); + lastError = error; return 0; } @@ -1739,12 +1747,15 @@ QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message, return sendWithReplyLocal(message); if (!QCoreApplication::instance() || sendMode == QDBus::Block) { - DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message); + QDBusError err; + DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message, &err); if (!msg) { - qWarning("QDBusConnection: error: could not send message to service \"%s\" path \"%s\" interface \"%s\" member \"%s\"", + qWarning("QDBusConnection: error: could not send message to service \"%s\" path \"%s\" interface \"%s\" member \"%s\": %s", qPrintable(message.service()), qPrintable(message.path()), - qPrintable(message.interface()), qPrintable(message.member())); - return QDBusMessage(); + qPrintable(message.interface()), qPrintable(message.member()), + qPrintable(err.message())); + lastError = err; + return QDBusMessage::createError(err); } qDBusDebug() << QThread::currentThread() << "sending message (blocking):" << message; @@ -1754,9 +1765,8 @@ QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message, q_dbus_message_unref(msg); if (!!error) { - QDBusError qe = error; - lastError = qe; - return QDBusMessage::createError(qe); + lastError = err = error; + return QDBusMessage::createError(err); } QDBusMessage amsg = QDBusMessagePrivate::fromDBusMessage(reply); @@ -1766,16 +1776,17 @@ QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message, return amsg; } else { // use the event loop QDBusPendingCallPrivate *pcall = sendWithReplyAsync(message, timeout); - if (!pcall) - return QDBusMessage(); + Q_ASSERT(pcall); - pcall->watcherHelper = new QDBusPendingCallWatcherHelper; - QEventLoop loop; - loop.connect(pcall->watcherHelper, SIGNAL(reply(QDBusMessage)), SLOT(quit())); - loop.connect(pcall->watcherHelper, SIGNAL(error(QDBusError,QDBusMessage)), SLOT(quit())); + if (pcall->replyMessage.type() != QDBusMessage::InvalidMessage) { + pcall->watcherHelper = new QDBusPendingCallWatcherHelper; + QEventLoop loop; + loop.connect(pcall->watcherHelper, SIGNAL(reply(QDBusMessage)), SLOT(quit())); + loop.connect(pcall->watcherHelper, SIGNAL(error(QDBusError,QDBusMessage)), SLOT(quit())); - // enter the event loop and wait for a reply - loop.exec(QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents); + // enter the event loop and wait for a reply + loop.exec(QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents); + } QDBusMessage reply = pcall->replyMessage; lastError = reply; // set or clear error @@ -1831,20 +1842,25 @@ QDBusPendingCallPrivate *QDBusConnectionPrivate::sendWithReplyAsync(const QDBusM return pcall; } - DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message); + checkThread(); + QDBusPendingCallPrivate *pcall = new QDBusPendingCallPrivate; + pcall->sentMessage = message; + pcall->ref = 0; + + QDBusError error; + DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message, &error); if (!msg) { - qWarning("QDBusConnection: error: could not send message to service \"%s\" path \"%s\" interface \"%s\" member \"%s\"", + qWarning("QDBusConnection: error: could not send message to service \"%s\" path \"%s\" interface \"%s\" member \"%s\": %s", qPrintable(message.service()), qPrintable(message.path()), - qPrintable(message.interface()), qPrintable(message.member())); - return 0; + qPrintable(message.interface()), qPrintable(message.member()), + qPrintable(error.message())); + pcall->replyMessage = QDBusMessage::createError(error); + lastError = error; + return pcall; } - checkThread(); qDBusDebug() << QThread::currentThread() << "sending message (async):" << message; DBusPendingCall *pending = 0; - QDBusPendingCallPrivate *pcall = new QDBusPendingCallPrivate; - pcall->sentMessage = message; - pcall->ref = 0; QDBusDispatchLocker locker(SendWithReplyAsyncAction, this); if (q_dbus_connection_send_with_reply(connection, msg, &pending, timeout)) { @@ -1858,14 +1874,14 @@ QDBusPendingCallPrivate *QDBusConnectionPrivate::sendWithReplyAsync(const QDBusM return pcall; } else { // we're probably disconnected at this point - lastError = QDBusError(QDBusError::Disconnected, QLatin1String("Not connected to server")); + lastError = error = QDBusError(QDBusError::Disconnected, QLatin1String("Not connected to server")); } } else { - lastError = QDBusError(QDBusError::NoMemory, QLatin1String("Out of memory")); + lastError = error = QDBusError(QDBusError::NoMemory, QLatin1String("Out of memory")); } q_dbus_message_unref(msg); - pcall->replyMessage = QDBusMessage::createError(lastError); + pcall->replyMessage = QDBusMessage::createError(error); return pcall; } @@ -1874,8 +1890,7 @@ int QDBusConnectionPrivate::sendWithReplyAsync(const QDBusMessage &message, QObj int timeout) { QDBusPendingCallPrivate *pcall = sendWithReplyAsync(message, timeout); - if (!pcall) - return 0; + Q_ASSERT(pcall); // has it already finished (dispatched locally)? if (pcall->replyMessage.type() == QDBusMessage::ReplyMessage) { diff --git a/src/dbus/qdbusmessage.cpp b/src/dbus/qdbusmessage.cpp index 9150295..eb09de9 100644 --- a/src/dbus/qdbusmessage.cpp +++ b/src/dbus/qdbusmessage.cpp @@ -94,11 +94,17 @@ QString QDBusMessage::errorMessage() const \internal Constructs a DBusMessage object from this object. The returned value must be de-referenced with q_dbus_message_unref. + + The \a error object is set to indicate the error if anything went wrong with the + marshalling. Usually, this error message will be placed in the reply, as if the call failed. + The \a error pointer must not be null. */ -DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message) +DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDBusError *error) { - if (!qdbus_loadLibDBus()) + if (!qdbus_loadLibDBus()) { + *error = QDBusError(QDBusError::Failed, QLatin1String("Could not open lidbus-1 library")); return 0; + } DBusMessage *msg = 0; const QDBusMessagePrivate *d_ptr = message.d_ptr; @@ -108,10 +114,17 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message) //qDebug() << "QDBusMessagePrivate::toDBusMessage" << "message is invalid"; break; case DBUS_MESSAGE_TYPE_METHOD_CALL: - // only interface can be empty - if (d_ptr->service.isEmpty() || d_ptr->path.isEmpty() || d_ptr->name.isEmpty()) - break; - msg = q_dbus_message_new_method_call(d_ptr->service.toUtf8(), d_ptr->path.toUtf8(), + // only service and interface can be empty -> path and name must not be empty + if (!QDBusUtil::checkBusName(d_ptr->service, QDBusUtil::EmptyAllowed, error)) + return 0; + if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error)) + return 0; + if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error)) + return 0; + if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method")) + return 0; + + msg = q_dbus_message_new_method_call(data(d_ptr->service.toUtf8()), d_ptr->path.toUtf8(), data(d_ptr->interface.toUtf8()), d_ptr->name.toUtf8()); break; case DBUS_MESSAGE_TYPE_METHOD_RETURN: @@ -123,8 +136,9 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message) break; case DBUS_MESSAGE_TYPE_ERROR: // error name can't be empty - if (d_ptr->name.isEmpty()) - break; + if (!QDBusUtil::checkErrorName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error)) + return 0; + msg = q_dbus_message_new(DBUS_MESSAGE_TYPE_ERROR); q_dbus_message_set_error_name(msg, d_ptr->name.toUtf8()); if (!d_ptr->localMessage) { @@ -134,8 +148,13 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message) break; case DBUS_MESSAGE_TYPE_SIGNAL: // nothing can be empty here - if (d_ptr->path.isEmpty() || d_ptr->interface.isEmpty() || d_ptr->name.isEmpty()) - break; + if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error)) + return 0; + if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error)) + return 0; + if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method")) + return 0; + msg = q_dbus_message_new_signal(d_ptr->path.toUtf8(), d_ptr->interface.toUtf8(), d_ptr->name.toUtf8()); break; @@ -170,6 +189,7 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message) // not ok; q_dbus_message_unref(msg); + *error = QDBusError(QDBusError::Failed, QLatin1String("Marshalling failed: ") + marshaller.errorString); return 0; } @@ -247,7 +267,13 @@ QDBusMessage QDBusMessagePrivate::makeLocal(const QDBusConnectionPrivate &conn, // yes, we are // we must marshall and demarshall again so as to create QDBusArgument // entries for the complex types - DBusMessage *message = toDBusMessage(asSent); + QDBusError error; + DBusMessage *message = toDBusMessage(asSent, &error); + if (!message) { + // failed to marshall, so it's a call error + return QDBusMessage::createError(error); + } + q_dbus_message_set_sender(message, conn.baseService.toUtf8()); QDBusMessage retval = fromDBusMessage(message); diff --git a/src/dbus/qdbusmessage_p.h b/src/dbus/qdbusmessage_p.h index 12a9500..a0a681f 100644 --- a/src/dbus/qdbusmessage_p.h +++ b/src/dbus/qdbusmessage_p.h @@ -80,7 +80,7 @@ public: mutable uint delayedReply : 1; uint localMessage : 1; - static DBusMessage *toDBusMessage(const QDBusMessage &message); + static DBusMessage *toDBusMessage(const QDBusMessage &message, QDBusError *error); static QDBusMessage fromDBusMessage(DBusMessage *dmsg); static bool isLocal(const QDBusMessage &msg); diff --git a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp index e5b2ebb..3ba789a 100644 --- a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp +++ b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp @@ -793,7 +793,7 @@ void tst_QDBusMarshall::sendErrors() "signalName"); msg << qVariantFromValue(QDBusObjectPath()); - QTest::ignoreMessage(QtWarningMsg, "QDBusConnection: error: could not send signal path \"/foo\" interface \"local.interfaceName\" member \"signalName\""); + QTest::ignoreMessage(QtWarningMsg, "QDBusConnection: error: could not send signal path \"/foo\" interface \"local.interfaceName\" member \"signalName\": Marshalling failed: Invalid object path passed in arguments"); QVERIFY(!con.send(msg)); msg.setArguments(QVariantList()); @@ -803,7 +803,19 @@ void tst_QDBusMarshall::sendErrors() path.setPath("abc"); msg << qVariantFromValue(path); - QTest::ignoreMessage(QtWarningMsg, "QDBusConnection: error: could not send signal path \"/foo\" interface \"local.interfaceName\" member \"signalName\""); + QTest::ignoreMessage(QtWarningMsg, "QDBusConnection: error: could not send signal path \"/foo\" interface \"local.interfaceName\" member \"signalName\": Marshalling failed: Invalid object path passed in arguments"); + QVERIFY(!con.send(msg)); + + QDBusSignature sig; + msg.setArguments(QVariantList() << qVariantFromValue(sig)); + QTest::ignoreMessage(QtWarningMsg, "QDBusConnection: error: could not send signal path \"/foo\" interface \"local.interfaceName\" member \"signalName\": Marshalling failed: Invalid signature passed in arguments"); + QVERIFY(!con.send(msg)); + + QTest::ignoreMessage(QtWarningMsg, "QDBusSignature: invalid signature \"a\""); + sig.setSignature("a"); + msg.setArguments(QVariantList()); + msg << qVariantFromValue(sig); + QTest::ignoreMessage(QtWarningMsg, "QDBusConnection: error: could not send signal path \"/foo\" interface \"local.interfaceName\" member \"signalName\": Marshalling failed: Invalid signature passed in arguments"); QVERIFY(!con.send(msg)); } -- cgit v0.12 From 8d4657764b0c4362dc25aa79a6e2853b8c98f0ad Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 29 Jun 2009 15:20:33 +0200 Subject: Keep creation failure errors for QDBusAbstractInterface. In case the object creation fails, set isValid to false. This will prevent any outgoing calls to be made with invalid information. In that case, lastError will never change either. This required adding a method to QDBusPendingCall, to be able to create one such object from an existing QDBusError. Reviewed-By: Marius Bugge Monsen --- src/dbus/qdbusabstractinterface.cpp | 140 ++++++++++++++++++------------------ src/dbus/qdbusabstractinterface_p.h | 4 ++ src/dbus/qdbuspendingcall.cpp | 36 ++++++++++ src/dbus/qdbuspendingcall.h | 3 + src/dbus/qdbuspendingcall_p.h | 3 + 5 files changed, 116 insertions(+), 70 deletions(-) diff --git a/src/dbus/qdbusabstractinterface.cpp b/src/dbus/qdbusabstractinterface.cpp index 85c3274..a4097c6 100644 --- a/src/dbus/qdbusabstractinterface.cpp +++ b/src/dbus/qdbusabstractinterface.cpp @@ -52,82 +52,66 @@ QT_BEGIN_NAMESPACE +static QDBusError checkIfValid(const QString &service, const QString &path, + const QString &interface, bool isDynamic) +{ + // We should be throwing exceptions here... oh well + QDBusError error; + + // dynamic interfaces (QDBusInterface) can have empty interfaces, but not service and object paths + // non-dynamic is the opposite: service and object paths can be empty, but not the interface + if (!isDynamic) { + // use assertion here because this should never happen, at all + Q_ASSERT_X(!interface.isEmpty(), "QDBusAbstractInterface", "Interface name cannot be empty"); + } + if (!QDBusUtil::checkBusName(service, isDynamic ? QDBusUtil::EmptyNotAllowed : QDBusUtil::EmptyAllowed, &error)) + return error; + if (!QDBusUtil::checkObjectPath(path, isDynamic ? QDBusUtil::EmptyNotAllowed : QDBusUtil::EmptyAllowed, &error)) + return error; + if (!QDBusUtil::checkInterfaceName(interface, QDBusUtil::EmptyAllowed, &error)) + return error; + + // no error + return QDBusError(); +} + QDBusAbstractInterfacePrivate::QDBusAbstractInterfacePrivate(const QString &serv, const QString &p, const QString &iface, const QDBusConnection& con, bool isDynamic) - : connection(con), service(serv), path(p), interface(iface), isValid(true) + : connection(con), service(serv), path(p), interface(iface), + lastError(checkIfValid(serv, p, iface, isDynamic)), + isValid(!lastError.isValid()) { - if (isDynamic) { - // QDBusInterface: service and object path can't be empty, but interface can -#if 0 - Q_ASSERT_X(QDBusUtil::isValidBusName(service), - "QDBusInterface::QDBusInterface", "Invalid service name"); - Q_ASSERT_X(QDBusUtil::isValidObjectPath(path), - "QDBusInterface::QDBusInterface", "Invalid object path given"); - Q_ASSERT_X(interface.isEmpty() || QDBusUtil::isValidInterfaceName(interface), - "QDBusInterface::QDBusInterface", "Invalid interface name"); -#else - if (!QDBusUtil::isValidBusName(service)) { - lastError = QDBusError(QDBusError::Disconnected, - QLatin1String("Invalid service name")); - isValid = false; - } else if (!QDBusUtil::isValidObjectPath(path)) { - lastError = QDBusError(QDBusError::Disconnected, - QLatin1String("Invalid object name given")); - isValid = false; - } else if (!interface.isEmpty() && !QDBusUtil::isValidInterfaceName(interface)) { - lastError = QDBusError(QDBusError::Disconnected, - QLatin1String("Invalid interface name")); - isValid = false; - } -#endif - } else { - // all others: service and path can be empty here, but interface can't -#if 0 - Q_ASSERT_X(service.isEmpty() || QDBusUtil::isValidBusName(service), - "QDBusAbstractInterface::QDBusAbstractInterface", "Invalid service name"); - Q_ASSERT_X(path.isEmpty() || QDBusUtil::isValidObjectPath(path), - "QDBusAbstractInterface::QDBusAbstractInterface", "Invalid object path given"); - Q_ASSERT_X(QDBusUtil::isValidInterfaceName(interface), - "QDBusAbstractInterface::QDBusAbstractInterface", "Invalid interface class!"); -#else - if (!service.isEmpty() && !QDBusUtil::isValidBusName(service)) { - lastError = QDBusError(QDBusError::Disconnected, - QLatin1String("Invalid service name")); - isValid = false; - } else if (!path.isEmpty() && !QDBusUtil::isValidObjectPath(path)) { - lastError = QDBusError(QDBusError::Disconnected, - QLatin1String("Invalid object path given")); - isValid = false; - } else if (!QDBusUtil::isValidInterfaceName(interface)) { - lastError = QDBusError(QDBusError::Disconnected, - QLatin1String("Invalid interface class")); - isValid = false; - } -#endif - } - if (!isValid) return; if (!connection.isConnected()) { lastError = QDBusError(QDBusError::Disconnected, QLatin1String("Not connected to D-Bus server")); - isValid = false; } else if (!service.isEmpty()) { currentOwner = connectionPrivate()->getNameOwner(service); // verify the name owner if (currentOwner.isEmpty()) { - isValid = false; lastError = connectionPrivate()->lastError; } } } +bool QDBusAbstractInterfacePrivate::canMakeCalls() const +{ + // recheck only if we have a wildcard (i.e. empty) service or path + // if any are empty, set the error message according to QDBusUtil + if (service.isEmpty()) + return QDBusUtil::checkBusName(service, QDBusUtil::EmptyNotAllowed, &lastError); + if (path.isEmpty()) + return QDBusUtil::checkObjectPath(path, QDBusUtil::EmptyNotAllowed, &lastError); + return true; +} + QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const { - if (!connection.isConnected()) // not connected + if (!isValid || !canMakeCalls()) // can't make calls return QVariant(); // is this metatype registered? @@ -144,6 +128,9 @@ QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const qWarning("QDBusAbstractInterface: type %s must be registered with QtDBus before it can be " "used to read property %s.%s", mp.typeName(), qPrintable(interface), mp.name()); + lastError = QDBusError(QDBusError::Failed, + QString::fromLatin1("Unregistered type %1 cannot be handled") + .arg(QLatin1String(mp.typeName()))); return QVariant(); } } @@ -208,7 +195,7 @@ QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const void QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const QVariant &value) { - if (!connection.isConnected()) // not connected + if (!isValid || !canMakeCalls()) // can't make calls return; // send the value @@ -230,7 +217,6 @@ void QDBusAbstractInterfacePrivate::_q_serviceOwnerChanged(const QString &name, //qDebug() << "QDBusAbstractInterfacePrivate serviceOwnerChanged" << name << oldOwner << newOwner; if (name == service) { currentOwner = newOwner; - isValid = !newOwner.isEmpty(); } } @@ -261,7 +247,7 @@ QDBusAbstractInterface::QDBusAbstractInterface(QDBusAbstractInterfacePrivate &d, : QObject(d, parent) { // keep track of the service owner - if (d_func()->isValid) + if (!d_func()->currentOwner.isEmpty()) QObject::connect(d_func()->connectionPrivate(), SIGNAL(serviceOwnerChanged(QString,QString,QString)), this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); } @@ -300,7 +286,7 @@ QDBusAbstractInterface::~QDBusAbstractInterface() */ bool QDBusAbstractInterface::isValid() const { - return d_func()->isValid; + return !d_func()->currentOwner.isEmpty(); } /*! @@ -367,6 +353,9 @@ QDBusMessage QDBusAbstractInterface::callWithArgumentList(QDBus::CallMode mode, { Q_D(QDBusAbstractInterface); + if (!d->isValid || !d->canMakeCalls()) + return QDBusMessage::createError(d->lastError); + QString m = method; // split out the signature from the method int pos = method.indexOf(QLatin1Char('.')); @@ -425,6 +414,9 @@ QDBusPendingCall QDBusAbstractInterface::asyncCallWithArgumentList(const QString { Q_D(QDBusAbstractInterface); + if (!d->isValid || !d->canMakeCalls()) + return QDBusPendingCall::fromError(d->lastError); + QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(), interface(), method); msg.setArguments(args); return d->connection.asyncCall(msg); @@ -440,7 +432,8 @@ QDBusPendingCall QDBusAbstractInterface::asyncCallWithArgumentList(const QString This function returns true if the queueing succeeds. It does not indicate that the executed call succeeded. If it fails, - the \a errorMethod is called. + the \a errorMethod is called. If the queueing failed, this + function returns false and no slot will be called. The \a returnMethod must have as its parameters the types returned by the function call. Optionally, it may have a QDBusMessage @@ -453,22 +446,25 @@ QDBusPendingCall QDBusAbstractInterface::asyncCallWithArgumentList(const QString bool QDBusAbstractInterface::callWithCallback(const QString &method, const QList &args, QObject *receiver, - const char *returnMethod, + const char *returnMethod, const char *errorMethod) { Q_D(QDBusAbstractInterface); + if (!d->isValid || !d->canMakeCalls()) + return false; + QDBusMessage msg = QDBusMessage::createMethodCall(service(), - path(), - interface(), - method); + path(), + interface(), + method); msg.setArguments(args); d->lastError = 0; return d->connection.callWithCallback(msg, - receiver, - returnMethod, - errorMethod); + receiver, + returnMethod, + errorMethod); } /*! @@ -492,7 +488,7 @@ bool QDBusAbstractInterface::callWithCallback(const QString &method, bool QDBusAbstractInterface::callWithCallback(const QString &method, const QList &args, QObject *receiver, - const char *slot) + const char *slot) { return callWithCallback(method, args, receiver, slot, 0); } @@ -503,13 +499,15 @@ bool QDBusAbstractInterface::callWithCallback(const QString &method, */ void QDBusAbstractInterface::connectNotify(const char *signal) { + // someone connecting to one of our signals + Q_D(QDBusAbstractInterface); + if (!d->isValid) + return; + // we end up recursing here, so optimise away if (qstrcmp(signal + 1, "destroyed(QObject*)") == 0) return; - // someone connecting to one of our signals - Q_D(QDBusAbstractInterface); - QDBusConnectionPrivate *conn = d->connectionPrivate(); if (conn) conn->connectRelay(d->service, d->currentOwner, d->path, d->interface, @@ -524,6 +522,8 @@ void QDBusAbstractInterface::disconnectNotify(const char *signal) { // someone disconnecting from one of our signals Q_D(QDBusAbstractInterface); + if (!d->isValid) + return; QDBusConnectionPrivate *conn = d->connectionPrivate(); if (conn) diff --git a/src/dbus/qdbusabstractinterface_p.h b/src/dbus/qdbusabstractinterface_p.h index e2ea058..e5822b3 100644 --- a/src/dbus/qdbusabstractinterface_p.h +++ b/src/dbus/qdbusabstractinterface_p.h @@ -75,11 +75,15 @@ public: QString path; QString interface; mutable QDBusError lastError; + + // this is set during creation and never changed + // it can't be const because QDBusInterfacePrivate has one more check bool isValid; QDBusAbstractInterfacePrivate(const QString &serv, const QString &p, const QString &iface, const QDBusConnection& con, bool dynamic); virtual ~QDBusAbstractInterfacePrivate() { } + bool canMakeCalls() const; // these functions do not check if the property is valid QVariant property(const QMetaProperty &mp) const; diff --git a/src/dbus/qdbuspendingcall.cpp b/src/dbus/qdbuspendingcall.cpp index 1797ed0..7807543 100644 --- a/src/dbus/qdbuspendingcall.cpp +++ b/src/dbus/qdbuspendingcall.cpp @@ -409,6 +409,42 @@ bool QDBusPendingCall::setReplyCallback(QObject *target, const char *member) } #endif +/*! + Creates a QDBusPendingCall object based on the error condition + \a error. The resulting pending call object will be in the + "finished" state and QDBusPendingReply::isError() will return true. + + \sa fromCompletedCall() +*/ +QDBusPendingCall QDBusPendingCall::fromError(const QDBusError &error) +{ + return fromCompletedCall(QDBusMessage::createError(error)); +} + +/*! + Creates a QDBusPendingCall object based on the message \a msg. + The message must be of type QDBusMessage::ErrorMessage or + QDBusMessage::ReplyMessage (that is, a message that is typical + of a completed call). + + This function is useful for code that requires simulating a pending + call, but that has already finished. + + \sa fromError() +*/ +QDBusPendingCall QDBusPendingCall::fromCompletedCall(const QDBusMessage &msg) +{ + QDBusPendingCallPrivate *d = 0; + if (msg.type() == QDBusMessage::ErrorMessage || + msg.type() == QDBusMessage::ReplyMessage) { + d = new QDBusPendingCallPrivate; + d->replyMessage = msg; + d->connection = 0; + } + + return QDBusPendingCall(d); +} + class QDBusPendingCallWatcherPrivate: public QObjectPrivate { diff --git a/src/dbus/qdbuspendingcall.h b/src/dbus/qdbuspendingcall.h index 8881920..8dbbb3c 100644 --- a/src/dbus/qdbuspendingcall.h +++ b/src/dbus/qdbuspendingcall.h @@ -78,6 +78,9 @@ public: QDBusMessage reply() const; #endif + static QDBusPendingCall fromError(const QDBusError &error); + static QDBusPendingCall fromCompletedCall(const QDBusMessage &message); + protected: QExplicitlySharedDataPointer d; friend class QDBusPendingCallPrivate; diff --git a/src/dbus/qdbuspendingcall_p.h b/src/dbus/qdbuspendingcall_p.h index 7136f67..5577451 100644 --- a/src/dbus/qdbuspendingcall_p.h +++ b/src/dbus/qdbuspendingcall_p.h @@ -63,6 +63,7 @@ QT_BEGIN_NAMESPACE +class QDBusPendingCall; class QDBusPendingCallWatcher; class QDBusPendingCallWatcherHelper; class QDBusConnectionPrivate; @@ -94,6 +95,8 @@ public: void waitForFinished(); void setMetaTypes(int count, const int *types); void checkReceivedSignature(); + + static QDBusPendingCall fromMessage(const QDBusMessage &msg); }; class QDBusPendingCallWatcherHelper: public QObject -- cgit v0.12 From e7ca74ed8a41eb4c05f436007417d160b6cf94f7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2009 11:13:47 +0200 Subject: Avoid revalidating message parameters. This is a small performance improvement when making a call: we don't need to validate what we already know to be valid because we either designed it to be so or because we've already validated. The D-Bus library unfortunately validates again and there's nothing we can do about it. But we can avoid doing it twice in our own code. Reviewed-By: Marius Bugge Monsen --- src/dbus/qdbusabstractinterface.cpp | 6 ++++ src/dbus/qdbusintegrator.cpp | 3 ++ src/dbus/qdbusinternalfilters.cpp | 2 +- src/dbus/qdbusmessage.cpp | 60 +++++++++++++++++++++---------------- src/dbus/qdbusmessage.h | 6 ++-- src/dbus/qdbusmessage_p.h | 9 ++++++ 6 files changed, 55 insertions(+), 31 deletions(-) diff --git a/src/dbus/qdbusabstractinterface.cpp b/src/dbus/qdbusabstractinterface.cpp index a4097c6..08da997 100644 --- a/src/dbus/qdbusabstractinterface.cpp +++ b/src/dbus/qdbusabstractinterface.cpp @@ -44,6 +44,7 @@ #include "qdbusargument.h" #include "qdbuspendingcall.h" +#include "qdbusmessage_p.h" #include "qdbusmetaobject_p.h" #include "qdbusmetatype_p.h" #include "qdbusutil_p.h" @@ -139,6 +140,7 @@ QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const QDBusMessage msg = QDBusMessage::createMethodCall(service, path, QLatin1String(DBUS_INTERFACE_PROPERTIES), QLatin1String("Get")); + QDBusMessagePrivate::setParametersValidated(msg, true); msg << interface << QString::fromUtf8(mp.name()); QDBusMessage reply = connection.call(msg, QDBus::Block); @@ -202,6 +204,7 @@ void QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const Q QDBusMessage msg = QDBusMessage::createMethodCall(service, path, QLatin1String(DBUS_INTERFACE_PROPERTIES), QLatin1String("Set")); + QDBusMessagePrivate::setParametersValidated(msg, true); msg << interface << QString::fromUtf8(mp.name()) << qVariantFromValue(QDBusVariant(value)); QDBusMessage reply = connection.call(msg, QDBus::Block); @@ -386,6 +389,7 @@ QDBusMessage QDBusAbstractInterface::callWithArgumentList(QDBus::CallMode mode, // qDebug() << "QDBusAbstractInterface" << "Service" << service() << "Path:" << path(); QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(), interface(), m); + QDBusMessagePrivate::setParametersValidated(msg, true); msg.setArguments(args); QDBusMessage reply = d->connection.call(msg, mode); @@ -418,6 +422,7 @@ QDBusPendingCall QDBusAbstractInterface::asyncCallWithArgumentList(const QString return QDBusPendingCall::fromError(d->lastError); QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(), interface(), method); + QDBusMessagePrivate::setParametersValidated(msg, true); msg.setArguments(args); return d->connection.asyncCall(msg); } @@ -458,6 +463,7 @@ bool QDBusAbstractInterface::callWithCallback(const QString &method, path(), interface(), method); + QDBusMessagePrivate::setParametersValidated(msg, true); msg.setArguments(args); d->lastError = 0; diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 704d2e3..a0903ed 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1143,6 +1143,7 @@ void QDBusConnectionPrivate::relaySignal(QObject *obj, const QMetaObject *mo, in QDBusReadLocker locker(RelaySignalAction, this); QDBusMessage message = QDBusMessage::createSignal(QLatin1String("/"), interface, QLatin1String(memberName)); + QDBusMessagePrivate::setParametersValidated(message, true); message.setArguments(args); QDBusError error; DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message, &error); @@ -2092,6 +2093,7 @@ QString QDBusConnectionPrivate::getNameOwner(const QString& serviceName) QDBusMessage msg = QDBusMessage::createMethodCall(QLatin1String(DBUS_SERVICE_DBUS), QLatin1String(DBUS_PATH_DBUS), QLatin1String(DBUS_INTERFACE_DBUS), QLatin1String("GetNameOwner")); + QDBusMessagePrivate::setParametersValidated(msg, true); msg << serviceName; QDBusMessage reply = sendWithReply(msg, QDBus::Block); if (reply.type() == QDBusMessage::ReplyMessage) @@ -2115,6 +2117,7 @@ QDBusConnectionPrivate::findMetaObject(const QString &service, const QString &pa QDBusMessage msg = QDBusMessage::createMethodCall(service, path, QLatin1String(DBUS_INTERFACE_INTROSPECTABLE), QLatin1String("Introspect")); + QDBusMessagePrivate::setParametersValidated(msg, true); QDBusMessage reply = sendWithReply(msg, QDBus::Block); diff --git a/src/dbus/qdbusinternalfilters.cpp b/src/dbus/qdbusinternalfilters.cpp index 416144d..762a49b 100644 --- a/src/dbus/qdbusinternalfilters.cpp +++ b/src/dbus/qdbusinternalfilters.cpp @@ -179,7 +179,7 @@ QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node static QDBusMessage qDBusPropertyError(const QDBusMessage &msg, const QString &interface_name) { - return msg.createErrorReply(QLatin1String(DBUS_ERROR_INVALID_ARGS), + return msg.createErrorReply(QDBusError::InvalidArgs, QString::fromLatin1("Interface %1 was not found in object %2") .arg(interface_name) .arg(msg.path())); diff --git a/src/dbus/qdbusmessage.cpp b/src/dbus/qdbusmessage.cpp index eb09de9..78de6d9 100644 --- a/src/dbus/qdbusmessage.cpp +++ b/src/dbus/qdbusmessage.cpp @@ -62,7 +62,8 @@ static inline const char *data(const QByteArray &arr) QDBusMessagePrivate::QDBusMessagePrivate() : msg(0), reply(0), type(DBUS_MESSAGE_TYPE_INVALID), - timeout(-1), localReply(0), ref(1), delayedReply(false), localMessage(false) + timeout(-1), localReply(0), ref(1), delayedReply(false), localMessage(false), + parametersValidated(false) { } @@ -115,14 +116,16 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDB break; case DBUS_MESSAGE_TYPE_METHOD_CALL: // only service and interface can be empty -> path and name must not be empty - if (!QDBusUtil::checkBusName(d_ptr->service, QDBusUtil::EmptyAllowed, error)) - return 0; - if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error)) - return 0; - if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error)) - return 0; - if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method")) - return 0; + if (!d_ptr->parametersValidated) { + if (!QDBusUtil::checkBusName(d_ptr->service, QDBusUtil::EmptyAllowed, error)) + return 0; + if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error)) + return 0; + if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error)) + return 0; + if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method")) + return 0; + } msg = q_dbus_message_new_method_call(data(d_ptr->service.toUtf8()), d_ptr->path.toUtf8(), data(d_ptr->interface.toUtf8()), d_ptr->name.toUtf8()); @@ -136,7 +139,8 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDB break; case DBUS_MESSAGE_TYPE_ERROR: // error name can't be empty - if (!QDBusUtil::checkErrorName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error)) + if (!d_ptr->parametersValidated + && !QDBusUtil::checkErrorName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error)) return 0; msg = q_dbus_message_new(DBUS_MESSAGE_TYPE_ERROR); @@ -148,12 +152,14 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDB break; case DBUS_MESSAGE_TYPE_SIGNAL: // nothing can be empty here - if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error)) - return 0; - if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error)) - return 0; - if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method")) - return 0; + if (!d_ptr->parametersValidated) { + if (!QDBusUtil::checkObjectPath(d_ptr->path, QDBusUtil::EmptyNotAllowed, error)) + return 0; + if (!QDBusUtil::checkInterfaceName(d_ptr->interface, QDBusUtil::EmptyAllowed, error)) + return 0; + if (!QDBusUtil::checkMemberName(d_ptr->name, QDBusUtil::EmptyNotAllowed, error, "method")) + return 0; + } msg = q_dbus_message_new_signal(d_ptr->path.toUtf8(), d_ptr->interface.toUtf8(), d_ptr->name.toUtf8()); @@ -162,16 +168,11 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDB Q_ASSERT(false); break; } -#if 0 - DBusError err; - q_dbus_error_init(&err); - if (q_dbus_error_is_set(&err)) { - QDBusError qe(&err); - qDebug() << "QDBusMessagePrivate::toDBusMessage" << qe; - } -#endif - if (!msg) - return 0; + + // if we got here, the parameters validated + // and since the message parameters cannot be changed once the message is created + // we can record this fact + d_ptr->parametersValidated = true; QDBusMarshaller marshaller; QVariantList::ConstIterator it = d_ptr->arguments.constBegin(); @@ -492,6 +493,13 @@ QDBusMessage QDBusMessage::createErrorReply(const QString name, const QString &m Constructs a new DBus reply message for the error type \a type using the message \a msg. Returns the DBus message. */ +QDBusMessage QDBusMessage::createErrorReply(QDBusError::ErrorType atype, const QString &amsg) const +{ + QDBusMessage msg = createErrorReply(QDBusError::errorString(atype), amsg); + msg.d_ptr->parametersValidated = true; + return msg; +} + /*! Constructs an empty, invalid QDBusMessage object. diff --git a/src/dbus/qdbusmessage.h b/src/dbus/qdbusmessage.h index 55f388a..34b1635 100644 --- a/src/dbus/qdbusmessage.h +++ b/src/dbus/qdbusmessage.h @@ -87,8 +87,9 @@ public: QDBusMessage createErrorReply(const QString name, const QString &msg) const; inline QDBusMessage createErrorReply(const QDBusError &err) const { return createErrorReply(err.name(), err.message()); } - inline QDBusMessage createErrorReply(QDBusError::ErrorType type, const QString &msg) const; + QDBusMessage createErrorReply(QDBusError::ErrorType type, const QString &msg) const; + // there are no setters; if this changes, see qdbusmessage_p.h QString service() const; QString path() const; QString interface() const; @@ -113,9 +114,6 @@ private: QDBusMessagePrivate *d_ptr; }; -inline QDBusMessage QDBusMessage::createErrorReply(QDBusError::ErrorType atype, const QString &amsg) const -{ return createErrorReply(QDBusError::errorString(atype), amsg); } - #ifndef QT_NO_DEBUG_STREAM QDBUS_EXPORT QDebug operator<<(QDebug, const QDBusMessage &); #endif diff --git a/src/dbus/qdbusmessage_p.h b/src/dbus/qdbusmessage_p.h index a0a681f..b8f23dc 100644 --- a/src/dbus/qdbusmessage_p.h +++ b/src/dbus/qdbusmessage_p.h @@ -55,6 +55,7 @@ #include #include +#include struct DBusMessage; @@ -69,7 +70,11 @@ public: ~QDBusMessagePrivate(); QList arguments; + + // the following parameters are "const": they are not changed after the constructors + // the parametersValidated member below controls whether they've been validated already QString service, path, interface, name, message, signature; + DBusMessage *msg; DBusMessage *reply; int type; @@ -79,6 +84,10 @@ public: mutable uint delayedReply : 1; uint localMessage : 1; + mutable uint parametersValidated : 1; + + static void setParametersValidated(QDBusMessage &msg, bool enable) + { msg.d_ptr->parametersValidated = enable; } static DBusMessage *toDBusMessage(const QDBusMessage &message, QDBusError *error); static QDBusMessage fromDBusMessage(DBusMessage *dmsg); -- cgit v0.12 From 485b2afb790444a0c6c2b32fbac65421e652dbe4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2009 18:27:11 +0200 Subject: Use an "int status" extra parameter in property reading/writing. When calling qt_metacall with the ReadProperty or WriteProperty, the data is on argv[0] like it was before, but now the QVariant itself is on argv[1] and there's an extra parameter in argv[2] which the meta code can use to indicate result. This allows QtDBus to process properties much more easily. In the case of property reading, we need to be able to modify the variant itself, because copying types when we don't have the data isn't very easy. As for setting, we need to be able to tell setProperty to return true or false depending on whether we succeeded in setting the property or not. Reviewed-By: Kent Hansen Reviewed-By: Marius Bugge Monsen --- src/corelib/kernel/qmetaobject.cpp | 23 ++++++++++++++++----- src/dbus/qdbusabstractinterface.cpp | 40 ++++++++++++++++++++++++++++++++----- src/dbus/qdbusabstractinterface.h | 18 ++++++++++++++++- src/dbus/qdbusabstractinterface_p.h | 2 +- src/dbus/qdbusinterface.cpp | 20 ------------------- 5 files changed, 71 insertions(+), 32 deletions(-) diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 71dd5ff..34f580b 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -2131,8 +2131,15 @@ QVariant QMetaProperty::read(const QObject *object) const return QVariant(); } } + + // the status variable is changed by qt_metacall to indicate what it did + // this feature is currently only used by QtDBus and should not be depended + // upon. Don't change it without looking into QDBusAbstractInterface first + // -1 (unchanged): normal qt_metacall, result stored in argv[0] + // changed: result stored directly in value + int status = -1; QVariant value; - void *argv[2] = { 0, &value }; + void *argv[] = { 0, &value, &status }; if (t == QVariant::LastType) { argv[0] = &value; } else { @@ -2142,8 +2149,8 @@ QVariant QMetaProperty::read(const QObject *object) const const_cast(object)->qt_metacall(QMetaObject::ReadProperty, idx + mobj->propertyOffset(), argv); - if (argv[1] == 0) - // "value" was changed + + if (status != -1) return value; if (t != QVariant::LastType && argv[0] != value.data()) // pointer or reference @@ -2201,13 +2208,19 @@ bool QMetaProperty::write(QObject *object, const QVariant &value) const return false; } - void *argv[2] = { 0, &v }; + // the status variable is changed by qt_metacall to indicate what it did + // this feature is currently only used by QtDBus and should not be depended + // upon. Don't change it without looking into QDBusAbstractInterface first + // -1 (unchanged): normal qt_metacall, result stored in argv[0] + // changed: result stored directly in value, return the value of status + int status = -1; + void *argv[] = { 0, &v, &status }; if (t == QVariant::LastType) argv[0] = &v; else argv[0] = v.data(); object->qt_metacall(QMetaObject::WriteProperty, idx + mobj->propertyOffset(), argv); - return true; + return status; } /*! diff --git a/src/dbus/qdbusabstractinterface.cpp b/src/dbus/qdbusabstractinterface.cpp index 08da997..9bef2dd 100644 --- a/src/dbus/qdbusabstractinterface.cpp +++ b/src/dbus/qdbusabstractinterface.cpp @@ -195,10 +195,10 @@ QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const return QVariant(); } -void QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const QVariant &value) +bool QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const QVariant &value) { if (!isValid || !canMakeCalls()) // can't make calls - return; + return false; // send the value QDBusMessage msg = QDBusMessage::createMethodCall(service, path, @@ -208,8 +208,11 @@ void QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const Q msg << interface << QString::fromUtf8(mp.name()) << qVariantFromValue(QDBusVariant(value)); QDBusMessage reply = connection.call(msg, QDBus::Block); - if (reply.type() != QDBusMessage::ReplyMessage) + if (reply.type() != QDBusMessage::ReplyMessage) { lastError = reply; + return false; + } + return true; } void QDBusAbstractInterfacePrivate::_q_serviceOwnerChanged(const QString &name, @@ -223,6 +226,33 @@ void QDBusAbstractInterfacePrivate::_q_serviceOwnerChanged(const QString &name, } } +QDBusAbstractInterfaceBase::QDBusAbstractInterfaceBase(QDBusAbstractInterfacePrivate &d, QObject *parent) + : QObject(d, parent) +{ +} + +int QDBusAbstractInterfaceBase::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + int saved_id = _id; + _id = QObject::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + + if (_c == QMetaObject::ReadProperty || _c == QMetaObject::WriteProperty) { + QMetaProperty mp = metaObject()->property(saved_id); + int &status = *reinterpret_cast(_a[2]); + QVariant &variant = *reinterpret_cast(_a[1]); + + if (_c == QMetaObject::WriteProperty) { + status = d_func()->setProperty(mp, variant) ? 1 : 0; + } else { + variant = d_func()->property(mp); + status = variant.isValid() ? 1 : 0; + } + _id = -1; + } + return _id; +} /*! \class QDBusAbstractInterface @@ -247,7 +277,7 @@ void QDBusAbstractInterfacePrivate::_q_serviceOwnerChanged(const QString &name, This is the constructor called from QDBusInterface::QDBusInterface. */ QDBusAbstractInterface::QDBusAbstractInterface(QDBusAbstractInterfacePrivate &d, QObject *parent) - : QObject(d, parent) + : QDBusAbstractInterfaceBase(d, parent) { // keep track of the service owner if (!d_func()->currentOwner.isEmpty()) @@ -263,7 +293,7 @@ QDBusAbstractInterface::QDBusAbstractInterface(QDBusAbstractInterfacePrivate &d, QDBusAbstractInterface::QDBusAbstractInterface(const QString &service, const QString &path, const char *interface, const QDBusConnection &con, QObject *parent) - : QObject(*new QDBusAbstractInterfacePrivate(service, path, QString::fromLatin1(interface), + : QDBusAbstractInterfaceBase(*new QDBusAbstractInterfacePrivate(service, path, QString::fromLatin1(interface), con, false), parent) { // keep track of the service owner diff --git a/src/dbus/qdbusabstractinterface.h b/src/dbus/qdbusabstractinterface.h index 6400b26..e525f77 100644 --- a/src/dbus/qdbusabstractinterface.h +++ b/src/dbus/qdbusabstractinterface.h @@ -61,7 +61,23 @@ class QDBusError; class QDBusPendingCall; class QDBusAbstractInterfacePrivate; -class QDBUS_EXPORT QDBusAbstractInterface: public QObject + +class QDBUS_EXPORT QDBusAbstractInterfaceBase: public QObject +{ +public: + int qt_metacall(QMetaObject::Call, int, void**); +protected: + QDBusAbstractInterfaceBase(QDBusAbstractInterfacePrivate &dd, QObject *parent); +private: + Q_DECLARE_PRIVATE(QDBusAbstractInterface) +}; + +class QDBUS_EXPORT QDBusAbstractInterface: +#ifdef Q_QDOC + public QObject +#else + public QDBusAbstractInterfaceBase +#endif { Q_OBJECT diff --git a/src/dbus/qdbusabstractinterface_p.h b/src/dbus/qdbusabstractinterface_p.h index e5822b3..e577898 100644 --- a/src/dbus/qdbusabstractinterface_p.h +++ b/src/dbus/qdbusabstractinterface_p.h @@ -87,7 +87,7 @@ public: // these functions do not check if the property is valid QVariant property(const QMetaProperty &mp) const; - void setProperty(const QMetaProperty &mp, const QVariant &value); + bool setProperty(const QMetaProperty &mp, const QVariant &value); // return conn's d pointer inline QDBusConnectionPrivate *connectionPrivate() const diff --git a/src/dbus/qdbusinterface.cpp b/src/dbus/qdbusinterface.cpp index 211b717..6f61847 100644 --- a/src/dbus/qdbusinterface.cpp +++ b/src/dbus/qdbusinterface.cpp @@ -205,26 +205,6 @@ int QDBusInterfacePrivate::metacall(QMetaObject::Call c, int id, void **argv) // done return -1; } - } else if (c == QMetaObject::ReadProperty) { - // Qt doesn't support non-readable properties - // we have to re-check - QMetaProperty mp = metaObject->property(id + metaObject->propertyOffset()); - if (!mp.isReadable()) - return -1; // don't read - - QVariant *value = reinterpret_cast(argv[1]); - argv[1] = 0; - *value = property(mp); - - return -1; // handled, error or not - } else if (c == QMetaObject::WriteProperty) { - // QMetaProperty::write has already checked that we're writable - // it has also checked that the type is right - QVariant *value = reinterpret_cast(argv[1]); - QMetaProperty mp = metaObject->property(id + metaObject->propertyOffset()); - - setProperty(mp, *value); - return -1; } return id; } -- cgit v0.12 From c4fa498f447bd569ee91e16f07bdb7954b5adc76 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2009 20:52:35 +0200 Subject: Fix setting of complex/custom properties and error messages. Complex properties require demarshalling before passing on to QMetaProperty::write(). We can't pass on a QVariant containing an un-demarshalled QDBusArgument. So add a new function that does the decoding properly, as well as error checking. Also take the opportunity to properly check the interface name in the case of setting a property exported from the object itself (not an adaptor). Task-number: 240608 Reviewed-by: Marius Bugge Monsen --- src/dbus/qdbusinternalfilters.cpp | 167 +++++++++++++++++++++++++++++++------- 1 file changed, 136 insertions(+), 31 deletions(-) diff --git a/src/dbus/qdbusinternalfilters.cpp b/src/dbus/qdbusinternalfilters.cpp index 762a49b..45cbbb0 100644 --- a/src/dbus/qdbusinternalfilters.cpp +++ b/src/dbus/qdbusinternalfilters.cpp @@ -53,6 +53,7 @@ #include "qdbusextratypes.h" #include "qdbusmessage.h" #include "qdbusmetatype.h" +#include "qdbusmetatype_p.h" #include "qdbusmessage_p.h" #include "qdbusutil_p.h" @@ -177,14 +178,25 @@ QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node // implement the D-Bus interface org.freedesktop.DBus.Properties -static QDBusMessage qDBusPropertyError(const QDBusMessage &msg, const QString &interface_name) +static inline QDBusMessage interfaceNotFoundError(const QDBusMessage &msg, const QString &interface_name) { - return msg.createErrorReply(QDBusError::InvalidArgs, + return msg.createErrorReply(QDBusError::UnknownInterface, QString::fromLatin1("Interface %1 was not found in object %2") .arg(interface_name) .arg(msg.path())); } +static inline QDBusMessage +propertyNotFoundError(const QDBusMessage &msg, const QString &interface_name, const QByteArray &property_name) +{ + return msg.createErrorReply(QDBusError::InvalidArgs, + QString::fromLatin1("Property %1%2%3 was not found in object %4") + .arg(interface_name, + QString::fromLatin1(interface_name.isEmpty() ? "" : "."), + QString::fromLatin1(property_name), + msg.path())); +} + QDBusMessage qDBusPropertyGet(const QDBusConnectionPrivate::ObjectTreeNode &node, const QDBusMessage &msg) { @@ -198,6 +210,7 @@ QDBusMessage qDBusPropertyGet(const QDBusConnectionPrivate::ObjectTreeNode &node QDBusAdaptorConnector *connector; QVariant value; + bool interfaceFound = false; if (node.flags & QDBusConnection::ExportAdaptors && (connector = qDBusFindAdaptorConnector(node.obj))) { @@ -217,31 +230,122 @@ QDBusMessage qDBusPropertyGet(const QDBusConnectionPrivate::ObjectTreeNode &node QDBusAdaptorConnector::AdaptorMap::ConstIterator it; it = qLowerBound(connector->adaptors.constBegin(), connector->adaptors.constEnd(), interface_name); - if (it != connector->adaptors.constEnd() && interface_name == QLatin1String(it->interface)) + if (it != connector->adaptors.constEnd() && interface_name == QLatin1String(it->interface)) { + interfaceFound = true; value = it->adaptor->property(property_name); + } } } - if (!value.isValid() && node.flags & (QDBusConnection::ExportAllProperties | - QDBusConnection::ExportNonScriptableProperties)) { + if (!interfaceFound && !value.isValid() + && node.flags & (QDBusConnection::ExportAllProperties | + QDBusConnection::ExportNonScriptableProperties)) { // try the object itself - int pidx = node.obj->metaObject()->indexOfProperty(property_name); - if (pidx != -1) { - QMetaProperty mp = node.obj->metaObject()->property(pidx); - if ((mp.isScriptable() && (node.flags & QDBusConnection::ExportScriptableProperties)) || - (!mp.isScriptable() && (node.flags & QDBusConnection::ExportNonScriptableProperties))) - value = mp.read(node.obj); + if (!interface_name.isEmpty()) + interfaceFound = qDBusInterfaceInObject(node.obj, interface_name); + + if (interfaceFound) { + int pidx = node.obj->metaObject()->indexOfProperty(property_name); + if (pidx != -1) { + QMetaProperty mp = node.obj->metaObject()->property(pidx); + if ((mp.isScriptable() && (node.flags & QDBusConnection::ExportScriptableProperties)) || + (!mp.isScriptable() && (node.flags & QDBusConnection::ExportNonScriptableProperties))) + value = mp.read(node.obj); + } } } if (!value.isValid()) { // the property was not found - return qDBusPropertyError(msg, interface_name); + if (!interfaceFound) + return interfaceNotFoundError(msg, interface_name); + return propertyNotFoundError(msg, interface_name, property_name); } return msg.createReply(qVariantFromValue(QDBusVariant(value))); } +enum PropertyWriteResult { + PropertyWriteSuccess = 0, + PropertyNotFound, + PropertyTypeMismatch, + PropertyWriteFailed +}; + +static QDBusMessage propertyWriteReply(const QDBusMessage &msg, const QString &interface_name, + const QByteArray &property_name, int status) +{ + switch (status) { + case PropertyNotFound: + return propertyNotFoundError(msg, interface_name, property_name); + case PropertyTypeMismatch: + return msg.createErrorReply(QDBusError::InvalidArgs, + QString::fromLatin1("Invalid arguments for writing to property %1%2%3") + .arg(interface_name, + QString::fromLatin1(interface_name.isEmpty() ? "" : "."), + QString::fromLatin1(property_name))); + case PropertyWriteFailed: + return msg.createErrorReply(QDBusError::InternalError, + QString::fromLatin1("Internal error")); + + case PropertyWriteSuccess: + return msg.createReply(); + } + Q_ASSERT_X(false, "", "Should not be reached"); + return QDBusMessage(); +} + +static int writeProperty(QObject *obj, const QByteArray &property_name, QVariant value, + int propFlags = QDBusConnection::ExportAllProperties) +{ + const QMetaObject *mo = obj->metaObject(); + int pidx = mo->indexOfProperty(property_name); + if (pidx == -1) { + // this object has no property by that name + return PropertyNotFound; + } + + QMetaProperty mp = mo->property(pidx); + + // check if this property is exported + bool isScriptable = mp.isScriptable(); + if (!(propFlags & QDBusConnection::ExportScriptableProperties) && isScriptable) + return PropertyNotFound; + if (!(propFlags & QDBusConnection::ExportNonScriptableProperties) && !isScriptable) + return PropertyNotFound; + + // we found our property + // do we have the right type? + int id = mp.type(); + if (id == QVariant::UserType) { + // dynamic type + id = qDBusNameToTypeId(mp.typeName()); + if (id == -1) { + // type not registered? + qWarning("QDBusConnection: Unable to handle unregistered datatype '%s' for property '%s::%s'", + mp.typeName(), mo->className(), property_name.constData()); + return PropertyWriteFailed; + } + } + + if (id != 0xff && value.userType() == QDBusMetaTypeId::argument) { + // we have to demarshall before writing + void *null = 0; + QVariant other(id, null); + if (!QDBusMetaType::demarshall(qVariantValue(value), id, other.data())) { + qWarning("QDBusConnection: type `%s' (%d) is not registered with QtDBus. " + "Use qDBusRegisterMetaType to register it", + mp.typeName(), id); + return PropertyWriteFailed; + } + + value = other; + } + + // the property type here should match + return mp.write(obj, value) ? PropertyWriteSuccess : PropertyWriteFailed; +} + QDBusMessage qDBusPropertySet(const QDBusConnectionPrivate::ObjectTreeNode &node, const QDBusMessage &msg) { @@ -263,38 +367,39 @@ QDBusMessage qDBusPropertySet(const QDBusConnectionPrivate::ObjectTreeNode &node if (interface_name.isEmpty()) { for (QDBusAdaptorConnector::AdaptorMap::ConstIterator it = connector->adaptors.constBegin(), end = connector->adaptors.constEnd(); it != end; ++it) { - const QMetaObject *mo = it->adaptor->metaObject(); - int pidx = mo->indexOfProperty(property_name); - if (pidx != -1) { - mo->property(pidx).write(it->adaptor, value); - return msg.createReply(); - } + int status = writeProperty(it->adaptor, property_name, value); + if (status == PropertyNotFound) + continue; + return propertyWriteReply(msg, interface_name, property_name, status); } } else { QDBusAdaptorConnector::AdaptorMap::ConstIterator it; it = qLowerBound(connector->adaptors.constBegin(), connector->adaptors.constEnd(), interface_name); - if (it != connector->adaptors.end() && interface_name == QLatin1String(it->interface)) - if (it->adaptor->setProperty(property_name, value)) - return msg.createReply(); + if (it != connector->adaptors.end() && interface_name == QLatin1String(it->interface)) { + return propertyWriteReply(msg, interface_name, property_name, + writeProperty(it->adaptor, property_name, value)); + } } } if (node.flags & (QDBusConnection::ExportScriptableProperties | QDBusConnection::ExportNonScriptableProperties)) { // try the object itself - int pidx = node.obj->metaObject()->indexOfProperty(property_name); - if (pidx != -1) { - QMetaProperty mp = node.obj->metaObject()->property(pidx); - if ((mp.isScriptable() && (node.flags & QDBusConnection::ExportScriptableProperties)) || - (!mp.isScriptable() && (node.flags & QDBusConnection::ExportNonScriptableProperties))) - if (mp.write(node.obj, value)) - return msg.createReply(); + bool interfaceFound = true; + if (!interface_name.isEmpty()) + interfaceFound = qDBusInterfaceInObject(node.obj, interface_name); + + if (interfaceFound) { + return propertyWriteReply(msg, interface_name, property_name, + writeProperty(node.obj, property_name, value, node.flags)); } } - // the property was not found or not written to - return qDBusPropertyError(msg, interface_name); + // the property was not found + if (!interface_name.isEmpty()) + return interfaceNotFoundError(msg, interface_name); + return propertyWriteReply(msg, interface_name, property_name, PropertyNotFound); } // unite two QVariantMaps, but don't generate duplicate keys @@ -385,7 +490,7 @@ QDBusMessage qDBusPropertyGetAll(const QDBusConnectionPrivate::ObjectTreeNode &n if (!interfaceFound && !interface_name.isEmpty()) { // the interface was not found - return qDBusPropertyError(msg, interface_name); + return interfaceNotFoundError(msg, interface_name); } return msg.createReply(qVariantFromValue(result)); -- cgit v0.12 From a80d8f015f68cb2b6d5f4cc8b2893543122c5d2b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 29 Jun 2009 16:16:57 +0200 Subject: Autotest: make sure we create the QDBusInterface after the object exists. The current code allows making calls to QDBusInterface objects that failed to introspect. It's technically a valid condition. You won't be able to connect to signals, get or set properties, but making calls was possible. I don't know if I want to keep this change in behaviour. --- .../tst_qdbusabstractadaptor.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/tests/auto/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp b/tests/auto/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp index c70c619..5d08c63 100644 --- a/tests/auto/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp +++ b/tests/auto/qdbusabstractadaptor/tst_qdbusabstractadaptor.cpp @@ -609,19 +609,22 @@ void tst_QDBusAbstractAdaptor::methodCalls() QVERIFY(con.isConnected()); //QDBusInterface emptycon.baseService(), "/", QString()); - QDBusInterface if1(con.baseService(), "/", "local.Interface1", con); - QDBusInterface if2(con.baseService(), "/", "local.Interface2", con); - QDBusInterface if3(con.baseService(), "/", "local.Interface3", con); - QDBusInterface if4(con.baseService(), "/", "local.Interface4", con); - // must fail: no object - //QCOMPARE(empty->call("method").type(), QDBusMessage::ErrorMessage); - QCOMPARE(if1.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ErrorMessage); + { + // must fail: no object + QDBusInterface if1(con.baseService(), "/", "local.Interface1", con); + QCOMPARE(if1.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ErrorMessage); + } QFETCH(int, nInterfaces); MyObject obj(nInterfaces); con.registerObject("/", &obj); + QDBusInterface if1(con.baseService(), "/", "local.Interface1", con); + QDBusInterface if2(con.baseService(), "/", "local.Interface2", con); + QDBusInterface if3(con.baseService(), "/", "local.Interface3", con); + QDBusInterface if4(con.baseService(), "/", "local.Interface4", con); + // must fail: no such method QCOMPARE(if1.call(QDBus::BlockWithGui, "method").type(), QDBusMessage::ErrorMessage); if (!nInterfaces--) @@ -670,11 +673,11 @@ void tst_QDBusAbstractAdaptor::methodCallScriptable() QDBusConnection con = QDBusConnection::sessionBus(); QVERIFY(con.isConnected()); - QDBusInterface if2(con.baseService(), "/", "local.Interface2", con); - MyObject obj(2); con.registerObject("/", &obj); + QDBusInterface if2(con.baseService(), "/", "local.Interface2", con); + QCOMPARE(if2.call(QDBus::BlockWithGui,"scriptableMethod").type(), QDBusMessage::ReplyMessage); QCOMPARE(slotSpy, "void Interface2::scriptableMethod()"); } -- cgit v0.12 From d675a1f752f6acb57c66082b9b25e1b8aa337f8a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2009 11:15:22 +0200 Subject: Autotest: add tests for method call errors --- tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp | 105 ++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 2 deletions(-) diff --git a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp index 3ba789a..e304712 100644 --- a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp +++ b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp @@ -84,12 +84,17 @@ private slots: void sendArgument_data(); void sendArgument(); - void sendErrors(); + void sendSignalErrors(); + void sendCallErrors_data(); + void sendCallErrors(); private: QProcess proc; }; +struct UnregisteredType { }; +Q_DECLARE_METATYPE(UnregisteredType) + class WaitForQPong: public QObject { Q_OBJECT @@ -784,7 +789,7 @@ void tst_QDBusMarshall::sendArgument() QCOMPARE(extracted, value); } -void tst_QDBusMarshall::sendErrors() +void tst_QDBusMarshall::sendSignalErrors() { QDBusConnection con = QDBusConnection::sessionBus(); @@ -819,5 +824,101 @@ void tst_QDBusMarshall::sendErrors() QVERIFY(!con.send(msg)); } +void tst_QDBusMarshall::sendCallErrors_data() +{ + QTest::addColumn("service"); + QTest::addColumn("path"); + QTest::addColumn("interface"); + QTest::addColumn("method"); + QTest::addColumn("arguments"); + QTest::addColumn("errorName"); + QTest::addColumn("errorMsg"); + QTest::addColumn("ignoreMsg"); + + // this error comes from the bus server + QTest::newRow("empty-service") << "" << objectPath << interfaceName << "ping" << QVariantList() + << "org.freedesktop.DBus.Error.UnknownMethod" + << "Method \"ping\" with signature \"\" on interface \"com.trolltech.autotests.qpong\" doesn't exist\n" << (const char*)0; + + QTest::newRow("invalid-service") << "this isn't valid" << objectPath << interfaceName << "ping" << QVariantList() + << "com.trolltech.QtDBus.Error.InvalidService" + << "Invalid service name: this isn't valid" << ""; + + QTest::newRow("empty-path") << serviceName << "" << interfaceName << "ping" << QVariantList() + << "com.trolltech.QtDBus.Error.InvalidObjectPath" + << "Object path cannot be empty" << ""; + QTest::newRow("invalid-path") << serviceName << "//" << interfaceName << "ping" << QVariantList() + << "com.trolltech.QtDBus.Error.InvalidObjectPath" + << "Invalid object path: //" << ""; + + // empty interfaces are valid + QTest::newRow("invalid-interface") << serviceName << objectPath << "this isn't valid" << "ping" << QVariantList() + << "com.trolltech.QtDBus.Error.InvalidInterface" + << "Invalid interface class: this isn't valid" << ""; + + QTest::newRow("empty-method") << serviceName << objectPath << interfaceName << "" << QVariantList() + << "com.trolltech.QtDBus.Error.InvalidMember" + << "method name cannot be empty" << ""; + QTest::newRow("invalid-method") << serviceName << objectPath << interfaceName << "this isn't valid" << QVariantList() + << "com.trolltech.QtDBus.Error.InvalidMember" + << "Invalid method name: this isn't valid" << ""; + + QTest::newRow("invalid-variant1") << serviceName << objectPath << interfaceName << "ping" + << (QVariantList() << QVariant()) + << "org.freedesktop.DBus.Error.Failed" + << "Marshalling failed: Variant containing QVariant::Invalid passed in arguments" + << "QDBusMarshaller: cannot add an invalid QVariant"; + QTest::newRow("invalid-variant1") << serviceName << objectPath << interfaceName << "ping" + << (QVariantList() << qVariantFromValue(QDBusVariant())) + << "org.freedesktop.DBus.Error.Failed" + << "Marshalling failed: Variant containing QVariant::Invalid passed in arguments" + << "QDBusMarshaller: cannot add a null QDBusVariant"; + + QTest::newRow("builtin-unregistered") << serviceName << objectPath << interfaceName << "ping" + << (QVariantList() << QLocale::c()) + << "org.freedesktop.DBus.Error.Failed" + << "Marshalling failed: Unregistered type QLocale passed in arguments" + << "QDBusMarshaller: type `QLocale' (18) is not registered with D-BUS. Use qDBusRegisterMetaType to register it"; + + // this type is known to the meta type system, but not registered with D-Bus + qRegisterMetaType(); + QTest::newRow("extra-unregistered") << serviceName << objectPath << interfaceName << "ping" + << (QVariantList() << qVariantFromValue(UnregisteredType())) + << "org.freedesktop.DBus.Error.Failed" + << "Marshalling failed: Unregistered type UnregisteredType passed in arguments" + << QString("QDBusMarshaller: type `UnregisteredType' (%1) is not registered with D-BUS. Use qDBusRegisterMetaType to register it") + .arg(qMetaTypeId()); +} + +void tst_QDBusMarshall::sendCallErrors() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); + + QFETCH(QString, service); + QFETCH(QString, path); + QFETCH(QString, interface); + QFETCH(QString, method); + QFETCH(QVariantList, arguments); + QFETCH(QString, errorMsg); + + QFETCH(QString, ignoreMsg); + if (!ignoreMsg.isEmpty()) + QTest::ignoreMessage(QtWarningMsg, ignoreMsg.toLatin1()); + if (!ignoreMsg.isNull()) + QTest::ignoreMessage(QtWarningMsg, + QString("QDBusConnection: error: could not send message to service \"%1\" path \"%2\" interface \"%3\" member \"%4\": %5") + .arg(service, path, interface, method, errorMsg) + .toLatin1()); + + QDBusMessage msg = QDBusMessage::createMethodCall(service, path, interface, method); + msg.setArguments(arguments); + + QDBusMessage reply = con.call(msg, QDBus::Block); + QCOMPARE(reply.type(), QDBusMessage::ErrorMessage); + QTEST(reply.errorName(), "errorName"); + QCOMPARE(reply.errorMessage(), errorMsg); +} + QTEST_MAIN(tst_QDBusMarshall) #include "tst_qdbusmarshall.moc" -- cgit v0.12 From 202167643206bbfb50cce605fdfbd4cfef843bad Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2009 16:21:44 +0200 Subject: Autotest: Add testing of QDBusAbstractInterface --- tests/auto/auto.pro | 1 + .../com.trolltech.QtDBus.Pinger.xml | 29 ++ tests/auto/qdbusabstractinterface/interface.cpp | 48 ++ tests/auto/qdbusabstractinterface/interface.h | 109 +++++ tests/auto/qdbusabstractinterface/pinger.cpp | 67 +++ tests/auto/qdbusabstractinterface/pinger.h | 139 ++++++ .../qdbusabstractinterface.pro | 15 + .../tst_qdbusabstractinterface.cpp | 529 +++++++++++++++++++++ 8 files changed, 937 insertions(+) create mode 100644 tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml create mode 100644 tests/auto/qdbusabstractinterface/interface.cpp create mode 100644 tests/auto/qdbusabstractinterface/interface.h create mode 100644 tests/auto/qdbusabstractinterface/pinger.cpp create mode 100644 tests/auto/qdbusabstractinterface/pinger.h create mode 100644 tests/auto/qdbusabstractinterface/qdbusabstractinterface.pro create mode 100644 tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index fd887fd..8bc2ed9 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -419,6 +419,7 @@ xmlpatternsxslts.depends = xmlpatternsxqts unix:!embedded:contains(QT_CONFIG, dbus):SUBDIRS += \ qdbusabstractadaptor \ + qdbusabstractinterface \ qdbusconnection \ qdbusinterface \ qdbuslocalcalls \ diff --git a/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml b/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml new file mode 100644 index 0000000..8909675 --- /dev/null +++ b/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/qdbusabstractinterface/interface.cpp b/tests/auto/qdbusabstractinterface/interface.cpp new file mode 100644 index 0000000..1c391ce --- /dev/null +++ b/tests/auto/qdbusabstractinterface/interface.cpp @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** 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 "interface.h" + +Interface::Interface() +{ +} + +#include "moc_interface.cpp" diff --git a/tests/auto/qdbusabstractinterface/interface.h b/tests/auto/qdbusabstractinterface/interface.h new file mode 100644 index 0000000..86e0dc4 --- /dev/null +++ b/tests/auto/qdbusabstractinterface/interface.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef INTERFACE_H +#define INTERFACE_H + +#include +#include + +struct RegisteredType +{ + inline RegisteredType(const QString &str = QString()) : s(str) {} + inline bool operator==(const RegisteredType &other) const { return s == other.s; } + QString s; +}; +Q_DECLARE_METATYPE(RegisteredType) + +inline QDBusArgument &operator<<(QDBusArgument &s, const RegisteredType &data) +{ + s.beginStructure(); + s << data.s; + s.endStructure(); + return s; +} + +inline const QDBusArgument &operator>>(const QDBusArgument &s, RegisteredType &data) +{ + s.beginStructure(); + s >> data.s; + s.endStructure(); + return s; +} + +struct UnregisteredType +{ + QString s; +}; +Q_DECLARE_METATYPE(UnregisteredType) + +class Interface: public QObject +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.trolltech.QtDBus.Pinger") + Q_PROPERTY(QString stringProp READ stringProp WRITE setStringProp SCRIPTABLE true) + Q_PROPERTY(RegisteredType complexProp READ complexProp WRITE setComplexProp SCRIPTABLE true) + + friend class tst_QDBusAbstractInterface; + QString m_stringProp; + RegisteredType m_complexProp; + +public: + Interface(); + + QString stringProp() const { return m_stringProp; } + void setStringProp(const QString &s) { m_stringProp = s; } + RegisteredType complexProp() const { return m_complexProp; } + void setComplexProp(const RegisteredType &r) { m_complexProp = r; } + +public slots: + Q_SCRIPTABLE void voidMethod() {} + Q_SCRIPTABLE QString stringMethod() { return "Hello, world"; } + Q_SCRIPTABLE RegisteredType complexMethod() { return RegisteredType("Hello, world"); } + Q_SCRIPTABLE QString multiOutMethod(int &value) { value = 42; return "Hello, world"; } + +signals: + Q_SCRIPTABLE void voidSignal(); + Q_SCRIPTABLE void stringSignal(const QString &); + Q_SCRIPTABLE void complexSignal(RegisteredType); +}; + +#endif // INTERFACE_H diff --git a/tests/auto/qdbusabstractinterface/pinger.cpp b/tests/auto/qdbusabstractinterface/pinger.cpp new file mode 100644 index 0000000..4fcb89a --- /dev/null +++ b/tests/auto/qdbusabstractinterface/pinger.cpp @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDBus 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$ +** +****************************************************************************/ + +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -i interface.h -p pinger com.trolltech.QtDBus.Pinger.xml + * + * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "pinger.h" + +/* + * Implementation of interface class ComTrolltechQtDBusPingerInterface + */ + +ComTrolltechQtDBusPingerInterface::ComTrolltechQtDBusPingerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +ComTrolltechQtDBusPingerInterface::~ComTrolltechQtDBusPingerInterface() +{ +} + diff --git a/tests/auto/qdbusabstractinterface/pinger.h b/tests/auto/qdbusabstractinterface/pinger.h new file mode 100644 index 0000000..3ff218c --- /dev/null +++ b/tests/auto/qdbusabstractinterface/pinger.h @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDBus 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$ +** +****************************************************************************/ + +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -i interface.h -p pinger com.trolltech.QtDBus.Pinger.xml + * + * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef PINGER_H_1246371899 +#define PINGER_H_1246371899 + +#include +#include +#include +#include +#include +#include +#include +#include +#include "interface.h" + +/* + * Proxy class for interface com.trolltech.QtDBus.Pinger + */ +class ComTrolltechQtDBusPingerInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.trolltech.QtDBus.Pinger"; } + +public: + ComTrolltechQtDBusPingerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); + + ~ComTrolltechQtDBusPingerInterface(); + + Q_PROPERTY(RegisteredType complexProp READ complexProp WRITE setComplexProp) + inline RegisteredType complexProp() const + { return qvariant_cast< RegisteredType >(internalPropGet("complexProp")); } + inline void setComplexProp(RegisteredType value) + { internalPropSet("complexProp", qVariantFromValue(value)); } + + Q_PROPERTY(QString stringProp READ stringProp WRITE setStringProp) + inline QString stringProp() const + { return qvariant_cast< QString >(internalPropGet("stringProp")); } + inline void setStringProp(const QString &value) + { internalPropSet("stringProp", qVariantFromValue(value)); } + +public Q_SLOTS: // METHODS + inline QDBusPendingReply complexMethod() + { + QList argumentList; + return asyncCallWithArgumentList(QLatin1String("complexMethod"), argumentList); + } + + inline QDBusPendingReply multiOutMethod() + { + QList argumentList; + return asyncCallWithArgumentList(QLatin1String("multiOutMethod"), argumentList); + } + inline QDBusReply multiOutMethod(int &out1) + { + QList argumentList; + QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("multiOutMethod"), argumentList); + if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 2) { + out1 = qdbus_cast(reply.arguments().at(1)); + } + return reply; + } + + inline QDBusPendingReply stringMethod() + { + QList argumentList; + return asyncCallWithArgumentList(QLatin1String("stringMethod"), argumentList); + } + + inline QDBusPendingReply<> voidMethod() + { + QList argumentList; + return asyncCallWithArgumentList(QLatin1String("voidMethod"), argumentList); + } + +Q_SIGNALS: // SIGNALS + void complexSignal(RegisteredType in0); + void stringSignal(const QString &in0); + void voidSignal(); +}; + +namespace com { + namespace trolltech { + namespace QtDBus { + typedef ::ComTrolltechQtDBusPingerInterface Pinger; + } + } +} +#endif diff --git a/tests/auto/qdbusabstractinterface/qdbusabstractinterface.pro b/tests/auto/qdbusabstractinterface/qdbusabstractinterface.pro new file mode 100644 index 0000000..a4853b8 --- /dev/null +++ b/tests/auto/qdbusabstractinterface/qdbusabstractinterface.pro @@ -0,0 +1,15 @@ +load(qttest_p4) +QT = core +contains(QT_CONFIG,dbus): { + SOURCES += tst_qdbusabstractinterface.cpp interface.cpp + HEADERS += interface.h + QT += dbus + + # These are generated sources + # To regenerate, see the command-line at the top of the files + SOURCES += pinger.cpp + HEADERS += pinger.h +} +else:SOURCES += ../qdbusmarshall/dummy.cpp + +OTHER_FILES += com.trolltech.QtDBus.Pinger.xml diff --git a/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp b/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp new file mode 100644 index 0000000..4aee089 --- /dev/null +++ b/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp @@ -0,0 +1,529 @@ +/**************************************************************************** +** +** 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 +#include +#include + +#include + +#include + +#include "interface.h" +#include "pinger.h" + +typedef QSharedPointer Pinger; + +class tst_QDBusAbstractInterface: public QObject +{ + Q_OBJECT + Interface targetObj; + + Pinger getPinger(QString service = "", const QString &path = "/") + { + QDBusConnection con = QDBusConnection::sessionBus(); + if (!con.isConnected()) + return Pinger(); + if (service.isEmpty() && !service.isNull()) + service = con.baseService(); + return Pinger(new com::trolltech::QtDBus::Pinger(service, path, con)); + } + +public: + tst_QDBusAbstractInterface(); + +private slots: + void initTestCase(); + + void makeVoidCall(); + void makeStringCall(); + void makeComplexCall(); + void makeMultiOutCall(); + + void makeAsyncVoidCall(); + void makeAsyncStringCall(); + void makeAsyncComplexCall(); + void makeAsyncMultiOutCall(); + + void stringPropRead(); + void stringPropWrite(); + void complexPropRead(); + void complexPropWrite(); + + void stringPropDirectRead(); + void stringPropDirectWrite(); + void complexPropDirectRead(); + void complexPropDirectWrite(); + + void getVoidSignal_data(); + void getVoidSignal(); + void getStringSignal_data(); + void getStringSignal(); + void getComplexSignal_data(); + void getComplexSignal(); + + void createErrors_data(); + void createErrors(); + + void callErrors_data(); + void callErrors(); + void asyncCallErrors_data(); + void asyncCallErrors(); + + void propertyReadErrors_data(); + void propertyReadErrors(); + void propertyWriteErrors_data(); + void propertyWriteErrors(); + void directPropertyReadErrors_data(); + void directPropertyReadErrors(); + void directPropertyWriteErrors_data(); + void directPropertyWriteErrors(); +}; + +tst_QDBusAbstractInterface::tst_QDBusAbstractInterface() +{ + // register the meta types + qDBusRegisterMetaType(); + qRegisterMetaType(); +} + +void tst_QDBusAbstractInterface::initTestCase() +{ + // register the object + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); + con.registerObject("/", &targetObj, QDBusConnection::ExportScriptableContents); +} + +void tst_QDBusAbstractInterface::makeVoidCall() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusReply r = p->voidMethod(); + QVERIFY(r.isValid()); +} + +void tst_QDBusAbstractInterface::makeStringCall() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusReply r = p->stringMethod(); + QVERIFY(r.isValid()); + QCOMPARE(r.value(), targetObj.stringMethod()); +} + +void tst_QDBusAbstractInterface::makeComplexCall() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusReply r = p->complexMethod(); + QVERIFY(r.isValid()); + QCOMPARE(r.value(), targetObj.complexMethod()); +} + +void tst_QDBusAbstractInterface::makeMultiOutCall() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + int value; + QDBusReply r = p->multiOutMethod(value); + QVERIFY(r.isValid()); + + int expectedValue; + QCOMPARE(r.value(), targetObj.multiOutMethod(expectedValue)); + QCOMPARE(value, expectedValue); +} + +void tst_QDBusAbstractInterface::makeAsyncVoidCall() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusPendingReply r = p->voidMethod(); + r.waitForFinished(); + QVERIFY(r.isValid()); +} + +void tst_QDBusAbstractInterface::makeAsyncStringCall() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusPendingReply r = p->stringMethod(); + r.waitForFinished(); + QVERIFY(r.isValid()); + QCOMPARE(r.value(), targetObj.stringMethod()); +} + +void tst_QDBusAbstractInterface::makeAsyncComplexCall() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusPendingReply r = p->complexMethod(); + r.waitForFinished(); + QVERIFY(r.isValid()); + QCOMPARE(r.value(), targetObj.complexMethod()); +} + +void tst_QDBusAbstractInterface::makeAsyncMultiOutCall() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusPendingReply r = p->multiOutMethod(); + r.waitForFinished(); + QVERIFY(r.isValid()); + + int expectedValue; + QCOMPARE(r.value(), targetObj.multiOutMethod(expectedValue)); + QCOMPARE(r.argumentAt<1>(), expectedValue); +} + +void tst_QDBusAbstractInterface::stringPropRead() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QString expectedValue = targetObj.m_stringProp = "This is a test"; + QVariant v = p->property("stringProp"); + QVERIFY(v.isValid()); + QCOMPARE(v.toString(), expectedValue); +} + +void tst_QDBusAbstractInterface::stringPropWrite() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QString expectedValue = "This is a value"; + QVERIFY(p->setProperty("stringProp", expectedValue)); + QCOMPARE(targetObj.m_stringProp, expectedValue); +} + +void tst_QDBusAbstractInterface::complexPropRead() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + RegisteredType expectedValue = targetObj.m_complexProp = RegisteredType("This is a test"); + QVariant v = p->property("complexProp"); + QVERIFY(v.userType() == qMetaTypeId()); + QCOMPARE(v.value(), targetObj.m_complexProp); +} + +void tst_QDBusAbstractInterface::complexPropWrite() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + RegisteredType expectedValue = RegisteredType("This is a value"); + QVERIFY(p->setProperty("complexProp", qVariantFromValue(expectedValue))); + QCOMPARE(targetObj.m_complexProp, expectedValue); +} + +void tst_QDBusAbstractInterface::stringPropDirectRead() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QString expectedValue = targetObj.m_stringProp = "This is a test"; + QCOMPARE(p->stringProp(), expectedValue); +} + +void tst_QDBusAbstractInterface::stringPropDirectWrite() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QString expectedValue = "This is a value"; + p->setStringProp(expectedValue); + QCOMPARE(targetObj.m_stringProp, expectedValue); +} + +void tst_QDBusAbstractInterface::complexPropDirectRead() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + RegisteredType expectedValue = targetObj.m_complexProp = RegisteredType("This is a test"); + QCOMPARE(p->complexProp(), targetObj.m_complexProp); +} + +void tst_QDBusAbstractInterface::complexPropDirectWrite() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + RegisteredType expectedValue = RegisteredType("This is a value"); + p->setComplexProp(expectedValue); + QCOMPARE(targetObj.m_complexProp, expectedValue); +} + +void tst_QDBusAbstractInterface::getVoidSignal_data() +{ + QTest::addColumn("service"); + QTest::addColumn("path"); + + QTest::newRow("specific") << QDBusConnection::sessionBus().baseService() << "/"; + QTest::newRow("service-wildcard") << QString() << "/"; + QTest::newRow("path-wildcard") << QDBusConnection::sessionBus().baseService() << QString(); + QTest::newRow("full-wildcard") << QString() << QString(); +} + +void tst_QDBusAbstractInterface::getVoidSignal() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we need to connect the signal somewhere in order for D-Bus to enable the rules + QTestEventLoop::instance().connect(p.data(), SIGNAL(voidSignal()), SLOT(exitLoop())); + QSignalSpy s(p.data(), SIGNAL(voidSignal())); + + emit targetObj.voidSignal(); + QTestEventLoop::instance().enterLoop(2); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(s.size() == 1); + QVERIFY(s.at(0).size() == 0); +} + +void tst_QDBusAbstractInterface::getStringSignal_data() +{ + getVoidSignal_data(); +} + +void tst_QDBusAbstractInterface::getStringSignal() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we need to connect the signal somewhere in order for D-Bus to enable the rules + QTestEventLoop::instance().connect(p.data(), SIGNAL(stringSignal(QString)), SLOT(exitLoop())); + QSignalSpy s(p.data(), SIGNAL(stringSignal(QString))); + + QString expectedValue = "Good morning"; + emit targetObj.stringSignal(expectedValue); + QTestEventLoop::instance().enterLoop(2); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(s.size() == 1); + QVERIFY(s[0].size() == 1); + QCOMPARE(s[0][0].userType(), int(QVariant::String)); + QCOMPARE(s[0][0].toString(), expectedValue); +} + +void tst_QDBusAbstractInterface::getComplexSignal_data() +{ + getVoidSignal_data(); +} + +void tst_QDBusAbstractInterface::getComplexSignal() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we need to connect the signal somewhere in order for D-Bus to enable the rules + QTestEventLoop::instance().connect(p.data(), SIGNAL(complexSignal(RegisteredType)), SLOT(exitLoop())); + QSignalSpy s(p.data(), SIGNAL(complexSignal(RegisteredType))); + + RegisteredType expectedValue("Good evening"); + emit targetObj.complexSignal(expectedValue); + QTestEventLoop::instance().enterLoop(2); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(s.size() == 1); + QVERIFY(s[0].size() == 1); + QCOMPARE(s[0][0].userType(), qMetaTypeId()); + QCOMPARE(s[0][0].value(), expectedValue); +} + +void tst_QDBusAbstractInterface::createErrors_data() +{ + QTest::addColumn("service"); + QTest::addColumn("path"); + QTest::addColumn("errorName"); + + QTest::newRow("invalid-service") << "this isn't valid" << "/" << "com.trolltech.QtDBus.Error.InvalidService"; + QTest::newRow("invalid-path") << QDBusConnection::sessionBus().baseService() << "this isn't valid" + << "com.trolltech.QtDBus.Error.InvalidObjectPath"; +} + +void tst_QDBusAbstractInterface::createErrors() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + QVERIFY(!p->isValid()); + QTEST(p->lastError().name(), "errorName"); +} + +void tst_QDBusAbstractInterface::callErrors_data() +{ + createErrors_data(); + QTest::newRow("service-wildcard") << QString() << "/" << "com.trolltech.QtDBus.Error.InvalidService"; + QTest::newRow("path-wildcard") << QDBusConnection::sessionBus().baseService() << QString() + << "com.trolltech.QtDBus.Error.InvalidObjectPath"; + QTest::newRow("full-wildcard") << QString() << QString() << "com.trolltech.QtDBus.Error.InvalidService"; +} + +void tst_QDBusAbstractInterface::callErrors() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we shouldn't be able to make this call: + QDBusReply r = p->stringMethod(); + QVERIFY(!r.isValid()); + QTEST(r.error().name(), "errorName"); + QCOMPARE(p->lastError().name(), r.error().name()); +} + +void tst_QDBusAbstractInterface::asyncCallErrors_data() +{ + callErrors_data(); +} + +void tst_QDBusAbstractInterface::asyncCallErrors() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we shouldn't be able to make this call: + QDBusPendingReply r = p->stringMethod(); + QVERIFY(r.isError()); + QTEST(r.error().name(), "errorName"); + QCOMPARE(p->lastError().name(), r.error().name()); +} + +void tst_QDBusAbstractInterface::propertyReadErrors_data() +{ + callErrors_data(); +} + +void tst_QDBusAbstractInterface::propertyReadErrors() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we shouldn't be able to get this value: + QVariant v = p->property("stringProp"); + QVERIFY(v.isNull()); + QVERIFY(!v.isValid()); + QTEST(p->lastError().name(), "errorName"); +} + +void tst_QDBusAbstractInterface::propertyWriteErrors_data() +{ + callErrors_data(); +} + +void tst_QDBusAbstractInterface::propertyWriteErrors() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we shouldn't be able to get this value: + if (p->isValid()) + QCOMPARE(int(p->lastError().type()), int(QDBusError::NoError)); + QVERIFY(!p->setProperty("stringProp", "")); + QTEST(p->lastError().name(), "errorName"); +} + +void tst_QDBusAbstractInterface::directPropertyReadErrors_data() +{ + callErrors_data(); +} + +void tst_QDBusAbstractInterface::directPropertyReadErrors() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we shouldn't be able to get this value: + QString v = p->stringProp(); + QVERIFY(v.isNull()); + QTEST(p->lastError().name(), "errorName"); +} + +void tst_QDBusAbstractInterface::directPropertyWriteErrors_data() +{ + callErrors_data(); +} + +void tst_QDBusAbstractInterface::directPropertyWriteErrors() +{ + QFETCH(QString, service); + QFETCH(QString, path); + Pinger p = getPinger(service, path); + QVERIFY2(p, "Not connected to D-Bus"); + + // we shouldn't be able to get this value: + // but there's no direct way of verifying that the setting failed + if (p->isValid()) + QCOMPARE(int(p->lastError().type()), int(QDBusError::NoError)); + p->setStringProp(""); + QTEST(p->lastError().name(), "errorName"); +} + +QTEST_MAIN(tst_QDBusAbstractInterface) +#include "tst_qdbusabstractinterface.moc" -- cgit v0.12 From 826c03c1c010a9d612007aa85ce3a5188edb0cb8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jun 2009 19:27:16 +0200 Subject: Autotest: Add property-setting and getting tests to QDBusInterface --- tests/auto/qdbusinterface/tst_qdbusinterface.cpp | 102 ++++++++++++++++++++++- 1 file changed, 100 insertions(+), 2 deletions(-) diff --git a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp index c4d4b08..718ba18 100644 --- a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp +++ b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp @@ -60,6 +60,9 @@ class MyObject: public QObject Q_CLASSINFO("D-Bus Introspection", "" " \n" " \n" +" \n" +" \n" +" \n" " \n" " \n" " \n" @@ -75,6 +78,9 @@ class MyObject: public QObject " \n" " \n" "") + Q_PROPERTY(int prop1 READ prop1 WRITE setProp1) + Q_PROPERTY(QList complexProp READ complexProp WRITE setComplexProp) + public: static int callCount; static QVariantList callArgs; @@ -84,6 +90,30 @@ public: subObject->setObjectName("subObject"); } + int m_prop1; + int prop1() const + { + ++callCount; + return m_prop1; + } + void setProp1(int value) + { + ++callCount; + m_prop1 = value; + } + + QList m_complexProp; + QList complexProp() const + { + ++callCount; + return m_complexProp; + } + void setComplexProp(const QList &value) + { + ++callCount; + m_complexProp = value; + } + public slots: void ping(QDBusMessage msg) @@ -146,6 +176,11 @@ private slots: void invokeMethod(); void signal(); + + void propertyRead(); + void propertyWrite(); + void complexPropertyRead(); + void complexPropertyWrite(); }; void tst_QDBusInterface::initTestCase() @@ -154,7 +189,7 @@ void tst_QDBusInterface::initTestCase() QVERIFY(con.isConnected()); QTest::qWait(500); - con.registerObject("/", &obj, QDBusConnection::ExportAdaptors + con.registerObject("/", &obj, QDBusConnection::ExportAllProperties | QDBusConnection::ExportAllSlots | QDBusConnection::ExportChildObjects); } @@ -231,8 +266,9 @@ void tst_QDBusInterface::introspect() QCOMPARE(mo->methodCount() - mo->methodOffset(), 3); QVERIFY(mo->indexOfSignal(TEST_SIGNAL_NAME "(QString)") != -1); - QCOMPARE(mo->propertyCount() - mo->propertyOffset(), 1); + QCOMPARE(mo->propertyCount() - mo->propertyOffset(), 2); QVERIFY(mo->indexOfProperty("prop1") != -1); + QVERIFY(mo->indexOfProperty("complexProp") != -1); } void tst_QDBusInterface::callMethod() @@ -322,6 +358,68 @@ void tst_QDBusInterface::signal() } } +void tst_QDBusInterface::propertyRead() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"), + TEST_INTERFACE_NAME); + + int arg = obj.m_prop1 = 42; + MyObject::callCount = 0; + + QVariant v = iface.property("prop1"); + QVERIFY(v.isValid()); + QCOMPARE(v.userType(), int(QVariant::Int)); + QCOMPARE(v.toInt(), arg); + QCOMPARE(MyObject::callCount, 1); +} + +void tst_QDBusInterface::propertyWrite() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"), + TEST_INTERFACE_NAME); + + int arg = 42; + obj.m_prop1 = 0; + MyObject::callCount = 0; + + QVERIFY(iface.setProperty("prop1", arg)); + QCOMPARE(MyObject::callCount, 1); + QCOMPARE(obj.m_prop1, arg); +} + +void tst_QDBusInterface::complexPropertyRead() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"), + TEST_INTERFACE_NAME); + + QList arg = obj.m_complexProp = QList() << 42 << -47; + MyObject::callCount = 0; + + QVariant v = iface.property("complexProp"); + QVERIFY(v.isValid()); + QCOMPARE(v.userType(), qMetaTypeId >()); + QCOMPARE(v.value >(), arg); + QCOMPARE(MyObject::callCount, 1); +} + +void tst_QDBusInterface::complexPropertyWrite() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"), + TEST_INTERFACE_NAME); + + QList arg = QList() << -47 << 42; + obj.m_complexProp.clear(); + MyObject::callCount = 0; + + QVERIFY(iface.setProperty("complexProp", qVariantFromValue(arg))); + QCOMPARE(MyObject::callCount, 1); + QCOMPARE(obj.m_complexProp, arg); +} + QTEST_MAIN(tst_QDBusInterface) #include "tst_qdbusinterface.moc" -- cgit v0.12 From 962b7fde5194a08a83609b9b4367425e52f76614 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 1 Jul 2009 17:44:56 +0200 Subject: Improve the code a bit more by using the variant that QMetaProperty creates. This works for the case of complex types that have to be demarshalled. We don't need to instantiate a new type because QMetaProperty has already done that for us. Also, fix the handling of properties of type variant. I have verified as well that the sending of those properties on the wire use a double-variant encoding (i.e., a variant containing a variant containing some data, the same that Qt 4.5 uses). It's a bit pedantic and it's hard to use when reading stuff, because you get a QVariant containing a QDBusVariant which contains data, but I can't change this anymore. Reviewed-By: Marius Bugge Monsen --- src/dbus/qdbusabstractinterface.cpp | 70 +++++++++++++++---------------------- src/dbus/qdbusabstractinterface_p.h | 2 +- 2 files changed, 29 insertions(+), 43 deletions(-) diff --git a/src/dbus/qdbusabstractinterface.cpp b/src/dbus/qdbusabstractinterface.cpp index 9bef2dd..7c520df 100644 --- a/src/dbus/qdbusabstractinterface.cpp +++ b/src/dbus/qdbusabstractinterface.cpp @@ -110,21 +110,17 @@ bool QDBusAbstractInterfacePrivate::canMakeCalls() const return true; } -QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const +void QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp, QVariant &where) const { - if (!isValid || !canMakeCalls()) // can't make calls - return QVariant(); + if (!isValid || !canMakeCalls()) { // can't make calls + where.clear(); + return; + } // is this metatype registered? - int mid; - const char *expectedSignature; - if (mp.type() == QVariant::LastType) { - // We're asking to read a QVariant - mid = qMetaTypeId(); - expectedSignature = "v"; - } else { - mid = QMetaType::type(mp.typeName()); - expectedSignature = QDBusMetaType::typeToSignature(mid); + const char *expectedSignature = ""; + if (mp.type() != 0xff) { + expectedSignature = QDBusMetaType::typeToSignature(where.userType()); if (expectedSignature == 0) { qWarning("QDBusAbstractInterface: type %s must be registered with QtDBus before it can be " "used to read property %s.%s", @@ -132,7 +128,8 @@ QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const lastError = QDBusError(QDBusError::Failed, QString::fromLatin1("Unregistered type %1 cannot be handled") .arg(QLatin1String(mp.typeName()))); - return QVariant(); + where.clear(); + return; } } @@ -146,21 +143,27 @@ QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const if (reply.type() != QDBusMessage::ReplyMessage) { lastError = reply; - return QVariant(); + where.clear(); + return; } if (reply.signature() != QLatin1String("v")) { QString errmsg = QLatin1String("Invalid signature `%1' in return from call to " DBUS_INTERFACE_PROPERTIES); lastError = QDBusError(QDBusError::InvalidSignature, errmsg.arg(reply.signature())); - return QVariant(); + where.clear(); + return; } QByteArray foundSignature; const char *foundType = 0; QVariant value = qvariant_cast(reply.arguments().at(0)).variant(); - if (value.userType() == mid) - return value; // simple match + if (value.userType() == where.userType() || mp.type() == 0xff + || (expectedSignature[0] == 'v' && expectedSignature[1] == '\0')) { + // simple match + where = value; + return; + } if (value.userType() == qMetaTypeId()) { QDBusArgument arg = qvariant_cast(value); @@ -168,14 +171,9 @@ QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const foundType = "user type"; foundSignature = arg.currentSignature().toLatin1(); if (foundSignature == expectedSignature) { - void *null = 0; - QVariant result(mid, null); - QDBusMetaType::demarshall(arg, mid, result.data()); - - if (mp.type() == QVariant::LastType) - // special case: QVariant - return qvariant_cast(result).variant(); - return result; + // signatures match, we can demarshall + QDBusMetaType::demarshall(arg, where.userType(), where.data()); + return; } } else { foundType = value.typeName(); @@ -192,7 +190,8 @@ QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const QString::fromUtf8(mp.name()), QString::fromLatin1(mp.typeName()), QString::fromLatin1(expectedSignature))); - return QVariant(); + where.clear(); + return; } bool QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const QVariant &value) @@ -246,7 +245,7 @@ int QDBusAbstractInterfaceBase::qt_metacall(QMetaObject::Call _c, int _id, void if (_c == QMetaObject::WriteProperty) { status = d_func()->setProperty(mp, variant) ? 1 : 0; } else { - variant = d_func()->property(mp); + d_func()->property(mp, variant); status = variant.isValid() ? 1 : 0; } _id = -1; @@ -576,11 +575,7 @@ QVariant QDBusAbstractInterface::internalPropGet(const char *propname) const // assume this property exists and is readable // we're only called from generated code anyways - int idx = metaObject()->indexOfProperty(propname); - if (idx != -1) - return d_func()->property(metaObject()->property(idx)); - qWarning("QDBusAbstractInterface::internalPropGet called with unknown property '%s'", propname); - return QVariant(); // error + return property(propname); } /*! @@ -589,16 +584,7 @@ QVariant QDBusAbstractInterface::internalPropGet(const char *propname) const */ void QDBusAbstractInterface::internalPropSet(const char *propname, const QVariant &value) { - Q_D(QDBusAbstractInterface); - - // assume this property exists and is writeable - // we're only called from generated code anyways - - int idx = metaObject()->indexOfProperty(propname); - if (idx != -1) - d->setProperty(metaObject()->property(idx), value); - else - qWarning("QDBusAbstractInterface::internalPropGet called with unknown property '%s'", propname); + setProperty(propname, value); } /*! diff --git a/src/dbus/qdbusabstractinterface_p.h b/src/dbus/qdbusabstractinterface_p.h index e577898..65df902 100644 --- a/src/dbus/qdbusabstractinterface_p.h +++ b/src/dbus/qdbusabstractinterface_p.h @@ -86,7 +86,7 @@ public: bool canMakeCalls() const; // these functions do not check if the property is valid - QVariant property(const QMetaProperty &mp) const; + void property(const QMetaProperty &mp, QVariant &where) const; bool setProperty(const QMetaProperty &mp, const QVariant &value); // return conn's d pointer -- cgit v0.12 From 43a760280edd49382d01eb1e23ae2a08933b6bf7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 1 Jul 2009 17:45:17 +0200 Subject: Autotest: add tests for checking variant properties --- .../com.trolltech.QtDBus.Pinger.xml | 1 + tests/auto/qdbusabstractinterface/interface.h | 4 ++ tests/auto/qdbusabstractinterface/pinger.h | 10 ++++- .../tst_qdbusabstractinterface.cpp | 47 ++++++++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) diff --git a/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml b/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml index 8909675..fb2aab8 100644 --- a/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml +++ b/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml @@ -2,6 +2,7 @@ + diff --git a/tests/auto/qdbusabstractinterface/interface.h b/tests/auto/qdbusabstractinterface/interface.h index 86e0dc4..f6d34a7 100644 --- a/tests/auto/qdbusabstractinterface/interface.h +++ b/tests/auto/qdbusabstractinterface/interface.h @@ -80,10 +80,12 @@ class Interface: public QObject Q_OBJECT Q_CLASSINFO("D-Bus Interface", "com.trolltech.QtDBus.Pinger") Q_PROPERTY(QString stringProp READ stringProp WRITE setStringProp SCRIPTABLE true) + Q_PROPERTY(QDBusVariant variantProp READ variantProp WRITE setVariantProp SCRIPTABLE true) Q_PROPERTY(RegisteredType complexProp READ complexProp WRITE setComplexProp SCRIPTABLE true) friend class tst_QDBusAbstractInterface; QString m_stringProp; + QDBusVariant m_variantProp; RegisteredType m_complexProp; public: @@ -91,6 +93,8 @@ public: QString stringProp() const { return m_stringProp; } void setStringProp(const QString &s) { m_stringProp = s; } + QDBusVariant variantProp() const { return m_variantProp; } + void setVariantProp(const QDBusVariant &v) { m_variantProp = v; } RegisteredType complexProp() const { return m_complexProp; } void setComplexProp(const RegisteredType &r) { m_complexProp = r; } diff --git a/tests/auto/qdbusabstractinterface/pinger.h b/tests/auto/qdbusabstractinterface/pinger.h index 3ff218c..6e92e65 100644 --- a/tests/auto/qdbusabstractinterface/pinger.h +++ b/tests/auto/qdbusabstractinterface/pinger.h @@ -49,8 +49,8 @@ * Do not edit! All changes made to it will be lost. */ -#ifndef PINGER_H_1246371899 -#define PINGER_H_1246371899 +#ifndef PINGER_H_1246460303 +#define PINGER_H_1246460303 #include #include @@ -89,6 +89,12 @@ public: inline void setStringProp(const QString &value) { internalPropSet("stringProp", qVariantFromValue(value)); } + Q_PROPERTY(QDBusVariant variantProp READ variantProp WRITE setVariantProp) + inline QDBusVariant variantProp() const + { return qvariant_cast< QDBusVariant >(internalPropGet("variantProp")); } + inline void setVariantProp(const QDBusVariant &value) + { internalPropSet("variantProp", qVariantFromValue(value)); } + public Q_SLOTS: // METHODS inline QDBusPendingReply complexMethod() { diff --git a/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp b/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp index 4aee089..fa5e332 100644 --- a/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp +++ b/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp @@ -84,11 +84,15 @@ private slots: void stringPropRead(); void stringPropWrite(); + void variantPropRead(); + void variantPropWrite(); void complexPropRead(); void complexPropWrite(); void stringPropDirectRead(); void stringPropDirectWrite(); + void variantPropDirectRead(); + void variantPropDirectWrite(); void complexPropDirectRead(); void complexPropDirectWrite(); @@ -242,6 +246,29 @@ void tst_QDBusAbstractInterface::stringPropWrite() QCOMPARE(targetObj.m_stringProp, expectedValue); } +void tst_QDBusAbstractInterface::variantPropRead() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusVariant expectedValue = targetObj.m_variantProp = QDBusVariant(QVariant(42)); + QVariant v = p->property("variantProp"); + QVERIFY(v.isValid()); + QDBusVariant value = v.value(); + QCOMPARE(value.variant().userType(), expectedValue.variant().userType()); + QCOMPARE(value.variant(), expectedValue.variant()); +} + +void tst_QDBusAbstractInterface::variantPropWrite() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusVariant expectedValue = QDBusVariant(Q_INT64_C(-47)); + QVERIFY(p->setProperty("variantProp", qVariantFromValue(expectedValue))); + QCOMPARE(targetObj.m_variantProp.variant(), expectedValue.variant()); +} + void tst_QDBusAbstractInterface::complexPropRead() { Pinger p = getPinger(); @@ -282,6 +309,26 @@ void tst_QDBusAbstractInterface::stringPropDirectWrite() QCOMPARE(targetObj.m_stringProp, expectedValue); } +void tst_QDBusAbstractInterface::variantPropDirectRead() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusVariant expectedValue = targetObj.m_variantProp = QDBusVariant(42); + QCOMPARE(p->variantProp().variant(), expectedValue.variant()); +} + +void tst_QDBusAbstractInterface::variantPropDirectWrite() +{ + Pinger p = getPinger(); + QVERIFY2(p, "Not connected to D-Bus"); + + QDBusVariant expectedValue = QDBusVariant(Q_INT64_C(-47)); + p->setVariantProp(expectedValue); + QCOMPARE(targetObj.m_variantProp.variant().userType(), expectedValue.variant().userType()); + QCOMPARE(targetObj.m_variantProp.variant(), expectedValue.variant()); +} + void tst_QDBusAbstractInterface::complexPropDirectRead() { Pinger p = getPinger(); -- cgit v0.12 From 232f7af78d152518ccdcaaf1f42f89abb048ae5f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 1 Jul 2009 17:52:48 +0200 Subject: Replace internalPropGet and internalPropSet with the QObject versions in QDBusAbstractInterface. They're now good enough and as fast. Reviewed-By: Marius Bugge Monsen --- tests/auto/qdbusabstractinterface/pinger.h | 16 ++++++++-------- tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp | 11 ++++------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/tests/auto/qdbusabstractinterface/pinger.h b/tests/auto/qdbusabstractinterface/pinger.h index 6e92e65..fb8adda 100644 --- a/tests/auto/qdbusabstractinterface/pinger.h +++ b/tests/auto/qdbusabstractinterface/pinger.h @@ -49,8 +49,8 @@ * Do not edit! All changes made to it will be lost. */ -#ifndef PINGER_H_1246460303 -#define PINGER_H_1246460303 +#ifndef PINGER_H_1246463415 +#define PINGER_H_1246463415 #include #include @@ -79,21 +79,21 @@ public: Q_PROPERTY(RegisteredType complexProp READ complexProp WRITE setComplexProp) inline RegisteredType complexProp() const - { return qvariant_cast< RegisteredType >(internalPropGet("complexProp")); } + { return qvariant_cast< RegisteredType >(property("complexProp")); } inline void setComplexProp(RegisteredType value) - { internalPropSet("complexProp", qVariantFromValue(value)); } + { setProperty("complexProp", qVariantFromValue(value)); } Q_PROPERTY(QString stringProp READ stringProp WRITE setStringProp) inline QString stringProp() const - { return qvariant_cast< QString >(internalPropGet("stringProp")); } + { return qvariant_cast< QString >(property("stringProp")); } inline void setStringProp(const QString &value) - { internalPropSet("stringProp", qVariantFromValue(value)); } + { setProperty("stringProp", qVariantFromValue(value)); } Q_PROPERTY(QDBusVariant variantProp READ variantProp WRITE setVariantProp) inline QDBusVariant variantProp() const - { return qvariant_cast< QDBusVariant >(internalPropGet("variantProp")); } + { return qvariant_cast< QDBusVariant >(property("variantProp")); } inline void setVariantProp(const QDBusVariant &value) - { internalPropSet("variantProp", qVariantFromValue(value)); } + { setProperty("variantProp", qVariantFromValue(value)); } public Q_SLOTS: // METHODS inline QDBusPendingReply complexMethod() diff --git a/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp b/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp index 5d1ac32..b8b9338 100644 --- a/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp +++ b/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp @@ -613,18 +613,15 @@ static void writeProxy(const QString &filename, const QDBusIntrospection::Interf // getter: if (property.access != QDBusIntrospection::Property::Write) { - hs << " inline " << type << " " << getter << "() const" << endl; - if (type != "QVariant") - hs << " { return qvariant_cast< " << type << " >(internalPropGet(\"" - << property.name << "\")); }" << endl; - else - hs << " { return internalPropGet(\"" << property.name << "\"); }" << endl; + hs << " inline " << type << " " << getter << "() const" << endl + << " { return qvariant_cast< " << type << " >(property(\"" + << property.name << "\")); }" << endl; } // setter: if (property.access != QDBusIntrospection::Property::Read) { hs << " inline void " << setter << "(" << constRefArg(type) << "value)" << endl - << " { internalPropSet(\"" << property.name + << " { setProperty(\"" << property.name << "\", qVariantFromValue(value)); }" << endl; } -- cgit v0.12 From 200286b8e83918e785b61e4695443a3b77ebeaea Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 1 Jul 2009 18:24:56 +0200 Subject: Implement a support for getting return arguments out of invokeMethod with QDBusInterface. The problem was that I didn't know how to implement the operator= for all types. But it turns out that this was possible all along: the only types I have to implement the operator= for are the basic types, which are already demarshalled. The complex types are left in QDBusArgument semi-demarshalling, but we have QDBusMetaType::demarshall, which takes a void* to an already-constructed type and demarshalls into it. That's exactly what the doctor ordered. Task-number: 206765 Reviewed-By: Marius Bugge Monsen --- src/dbus/qdbusinterface.cpp | 126 +++++++++++++++++++++-- tests/auto/qdbusinterface/tst_qdbusinterface.cpp | 92 ++++++++++++++++- 2 files changed, 209 insertions(+), 9 deletions(-) diff --git a/src/dbus/qdbusinterface.cpp b/src/dbus/qdbusinterface.cpp index 6f61847..5f6df0a 100644 --- a/src/dbus/qdbusinterface.cpp +++ b/src/dbus/qdbusinterface.cpp @@ -51,6 +51,102 @@ QT_BEGIN_NAMESPACE +static void copyArgument(void *to, int id, const QVariant &arg) +{ + if (id == arg.userType()) { + switch (id) { + case QVariant::Bool: + *reinterpret_cast(to) = arg.toBool(); + return; + + case QMetaType::UChar: + *reinterpret_cast(to) = arg.value(); + return; + + case QMetaType::Short: + *reinterpret_cast(to) = arg.value(); + return; + + case QMetaType::UShort: + *reinterpret_cast(to) = arg.value(); + return; + + case QVariant::Int: + *reinterpret_cast(to) = arg.toInt(); + return; + + case QVariant::UInt: + *reinterpret_cast(to) = arg.toUInt(); + return; + + case QVariant::LongLong: + *reinterpret_cast(to) = arg.toLongLong(); + return; + + case QVariant::ULongLong: + *reinterpret_cast(to) = arg.toULongLong(); + return; + + case QVariant::Double: + *reinterpret_cast(to) = arg.toDouble(); + return; + + case QVariant::String: + *reinterpret_cast(to) = arg.toString(); + return; + + case QVariant::ByteArray: + *reinterpret_cast(to) = arg.toByteArray(); + return; + + case QVariant::StringList: + *reinterpret_cast(to) = arg.toStringList(); + return; + } + + if (id == QDBusMetaTypeId::variant) { + *reinterpret_cast(to) = arg.value(); + return; + } else if (id == QDBusMetaTypeId::objectpath) { + *reinterpret_cast(to) = arg.value(); + return; + } else if (id == QDBusMetaTypeId::signature) { + *reinterpret_cast(to) = arg.value(); + return; + } + + // those above are the only types possible + // the demarshaller code doesn't demarshall anything else + qFatal("Found a decoded basic type in a D-Bus reply that shouldn't be there"); + } + + // if we got here, it's either an un-dermarshalled type or a mismatch + if (arg.userType() != QDBusMetaTypeId::argument) { + // it's a mismatch + //qWarning? + return; + } + + // is this type registered? + const char *userSignature = QDBusMetaType::typeToSignature(id); + if (!userSignature || !*userSignature) { + // type not registered + //qWarning? + return; + } + + // is it the same signature? + QDBusArgument dbarg = arg.value(); + if (dbarg.currentSignature() != QLatin1String(userSignature)) { + // not the same signature, another mismatch + //qWarning? + return; + } + + // we can demarshall + QDBusMetaType::demarshall(dbarg, id, to); +} + QDBusInterfacePrivate::QDBusInterfacePrivate(const QString &serv, const QString &p, const QString &iface, const QDBusConnection &con) : QDBusAbstractInterfacePrivate(serv, p, iface, con, true), metaObject(0) @@ -186,23 +282,37 @@ int QDBusInterfacePrivate::metacall(QMetaObject::Call c, int id, void **argv) // we will assume that the input arguments were passed correctly QVariantList args; - for (int i = 1; i <= inputTypesCount; ++i) + int i = 1; + for ( ; i <= inputTypesCount; ++i) args << QVariant(inputTypes[i], argv[i]); // make the call - QPointer qq = q; QDBusMessage reply = q->callWithArgumentList(QDBus::Block, methodName, args); - args.clear(); - // we ignore return values + if (reply.type() == QDBusMessage::ReplyMessage) { + // attempt to demarshall the return values + args = reply.arguments(); + QVariantList::ConstIterator it = args.constBegin(); + const int *outputTypes = metaObject->outputTypesForMethod(id); + int outputTypesCount = *outputTypes++; + + if (*mm.typeName()) { + // this method has a return type + if (argv[0] && it != args.constEnd()) + copyArgument(argv[0], *outputTypes++, *it); - // access to "this" or to "q" below this point must check for "qq" - // we may have been deleted! + // skip this argument even if we didn't copy it + --outputTypesCount; + ++it; + } - if (!qq.isNull()) - lastError = reply; + for (int j = 0; j < outputTypesCount && it != args.constEnd(); ++i, ++j, ++it) { + copyArgument(argv[i], outputTypes[j], *it); + } + } // done + lastError = reply; return -1; } } diff --git a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp index 718ba18..60afe4e 100644 --- a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp +++ b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp @@ -76,6 +76,12 @@ class MyObject: public QObject " \n" " \n" " \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" " \n" "") Q_PROPERTY(int prop1 READ prop1 WRITE setProp1) @@ -174,6 +180,9 @@ private slots: void introspect(); void callMethod(); void invokeMethod(); + void invokeMethodWithReturn(); + void invokeMethodWithMultiReturn(); + void invokeMethodWithComplexReturn(); void signal(); @@ -263,7 +272,7 @@ void tst_QDBusInterface::introspect() const QMetaObject *mo = iface.metaObject(); - QCOMPARE(mo->methodCount() - mo->methodOffset(), 3); + QCOMPARE(mo->methodCount() - mo->methodOffset(), 4); QVERIFY(mo->indexOfSignal(TEST_SIGNAL_NAME "(QString)") != -1); QCOMPARE(mo->propertyCount() - mo->propertyOffset(), 2); @@ -317,6 +326,87 @@ void tst_QDBusInterface::invokeMethod() QCOMPARE(dv.variant().toString(), QString("foo")); } +void tst_QDBusInterface::invokeMethodWithReturn() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"), + TEST_INTERFACE_NAME); + + // make the call without a return type + MyObject::callCount = 0; + QDBusVariant arg("foo"); + QDBusVariant retArg; + QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QDBusVariant, retArg), Q_ARG(QDBusVariant, arg))); + QCOMPARE(MyObject::callCount, 1); + + // verify what the callee received + QCOMPARE(MyObject::callArgs.count(), 1); + QVariant v = MyObject::callArgs.at(0); + QDBusVariant dv = qdbus_cast(v); + QCOMPARE(dv.variant().type(), QVariant::String); + QCOMPARE(dv.variant().toString(), arg.variant().toString()); + + // verify that we got the reply as expected + QCOMPARE(retArg.variant(), arg.variant()); +} + +void tst_QDBusInterface::invokeMethodWithMultiReturn() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"), + TEST_INTERFACE_NAME); + + // make the call without a return type + MyObject::callCount = 0; + QDBusVariant arg("foo"), arg2("bar"); + QDBusVariant retArg, retArg2; + QVERIFY(QMetaObject::invokeMethod(&iface, "ping", + Q_RETURN_ARG(QDBusVariant, retArg), + Q_ARG(QDBusVariant, arg), + Q_ARG(QDBusVariant, arg2), + Q_ARG(QDBusVariant&, retArg2))); + QCOMPARE(MyObject::callCount, 1); + + // verify what the callee received + QCOMPARE(MyObject::callArgs.count(), 2); + QVariant v = MyObject::callArgs.at(0); + QDBusVariant dv = qdbus_cast(v); + QCOMPARE(dv.variant().type(), QVariant::String); + QCOMPARE(dv.variant().toString(), arg.variant().toString()); + + v = MyObject::callArgs.at(1); + dv = qdbus_cast(v); + QCOMPARE(dv.variant().type(), QVariant::String); + QCOMPARE(dv.variant().toString(), arg2.variant().toString()); + + // verify that we got the replies as expected + QCOMPARE(retArg.variant(), arg.variant()); + QCOMPARE(retArg2.variant(), arg2.variant()); +} + +void tst_QDBusInterface::invokeMethodWithComplexReturn() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"), + TEST_INTERFACE_NAME); + + // make the call without a return type + MyObject::callCount = 0; + QList arg = QList() << 42 << -47; + QList retArg; + QVERIFY(QMetaObject::invokeMethod(&iface, "ping", Q_RETURN_ARG(QList, retArg), Q_ARG(QList, arg))); + QCOMPARE(MyObject::callCount, 1); + + // verify what the callee received + QCOMPARE(MyObject::callArgs.count(), 1); + QVariant v = MyObject::callArgs.at(0); + QCOMPARE(v.userType(), qMetaTypeId()); + QCOMPARE(qdbus_cast >(v), arg); + + // verify that we got the reply as expected + QCOMPARE(retArg, arg); +} + void tst_QDBusInterface::signal() { QDBusConnection con = QDBusConnection::sessionBus(); -- cgit v0.12 From 9a90dab23bd1bd37bd4a7aace588896d2ae7e9d9 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 1 Jul 2009 10:53:23 +0200 Subject: add support for attaching meta data to translatable messages Requirement: QT-457 --- .../snippets/code/src_corelib_kernel_qobject.cpp | 9 ++++++ src/corelib/kernel/qobject.cpp | 28 +++++++++++++++++ .../lupdate/testdata/good/parsecpp/main.cpp | 19 ++++++++++++ .../testdata/good/parsecpp/project.ts.result | 21 +++++++++++++ tools/linguist/lupdate/cpp.cpp | 35 ++++++++++++++++++---- 5 files changed, 107 insertions(+), 5 deletions(-) diff --git a/doc/src/snippets/code/src_corelib_kernel_qobject.cpp b/doc/src/snippets/code/src_corelib_kernel_qobject.cpp index 5a7c5a7..5c0f80c 100644 --- a/doc/src/snippets/code/src_corelib_kernel_qobject.cpp +++ b/doc/src/snippets/code/src_corelib_kernel_qobject.cpp @@ -376,6 +376,15 @@ hostNameLabel->setText(tr("Name:")); QString example = tr("Example"); //! [40] +//! [meta data] +//: This is a comment for the translator. +//= qtn_foo_bar +//~ loc-layout_id foo_dialog +//~ loc-blank False +//~ magic-stuff This might mean something magic. +QString text = MyMagicClass::tr("Sim sala bim."); +//! [meta data] + //! [explicit tr context] QString text = QScrollBar::tr("Page up"); //! [explicit tr context] diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 9dc25c7..9e87b3b 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -2086,6 +2086,34 @@ void QObject::deleteLater() \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 17 + \section1 Meta Data + + Additional data can be attached to each translatable message. + The syntax: + + \tt{//= } + + can be used to give the message a unique identifier to support tools + which need it. + The syntax: + + \tt{//~ } + + can be used to attach meta data to the message. The field name should consist + of a domain prefix (possibly the conventional file extension of the file format + the field is inspired by), a hyphen and the actual field name in + underscore-delimited notation. For storage in TS files, the field name together + with the prefix "extra-" will form an XML element name. The field contents will + be XML-escaped, but otherwise appear verbatim as the element's contents. + Any number of unique fields can be added to each message. + + Example: + + \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp meta data + + Meta data appearing right in front of a magic TRANSLATOR comment applies to the + whole TS file. + \section1 Character Encodings You can set the encoding for \a sourceText by calling QTextCodec::setCodecForTr(). diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp index df75baf..9fb43fe 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp +++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp @@ -156,3 +156,22 @@ 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") + + +class TestingTake17 : QObject { + Q_OBJECT + + int function(void) + { + //: random comment + //= this_is_an_id + //~ loc-layout_id fooish_bar + //~ po-ignore_me totally foo-barred nonsense + tr("something cool"); + + tr("less cool"); + + //= another_id + tr("even more cool"); + } +}; diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result index 9386c19..5bd7525 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result +++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result @@ -239,6 +239,27 @@ + TestingTake17 + + + something cool + random comment + + totally foo-barred nonsense + fooish_bar + + + + less cool + + + + + even more cool + + + + scope diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index 09148e7..b1d2d01 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -180,7 +180,8 @@ private: QString transcode(const QString &str, bool utf8); void recordMessage( int line, const QString &context, const QString &text, const QString &comment, - const QString &extracomment, bool utf8, bool plural); + const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra, + bool utf8, bool plural); void processInclude(const QString &file, ConversionData &cd, QSet &inclusions); @@ -1299,13 +1300,16 @@ QString CppParser::transcode(const QString &str, bool utf8) void CppParser::recordMessage( int line, const QString &context, const QString &text, const QString &comment, - const QString &extracomment, bool utf8, bool plural) + const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra, + bool utf8, bool plural) { TranslatorMessage msg( transcode(context, utf8), transcode(text, utf8), transcode(comment, utf8), QString(), yyFileName, line, QStringList(), TranslatorMessage::Unfinished, plural); msg.setExtraComment(transcode(extracomment.simplified(), utf8)); + msg.setId(msgid); + msg.setExtras(extra); if ((utf8 || yyForceUtf8) && !yyCodecIsUtf8 && msg.needs8Bit()) msg.setUtf8(true); results->tor->append(msg); @@ -1332,6 +1336,8 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) QString text; QString comment; QString extracomment; + QString msgid; + TranslatorMessage::ExtraData extra; QString prefix; #ifdef DIAGNOSE_RETRANSLATABILITY QString functionName; @@ -1604,9 +1610,11 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) prefix.clear(); } - recordMessage(line, context, text, comment, extracomment, utf8, plural); + recordMessage(line, context, text, comment, extracomment, msgid, extra, utf8, plural); } extracomment.clear(); + msgid.clear(); + extra.clear(); break; case Tok_translateUtf8: case Tok_translate: @@ -1655,9 +1663,11 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) break; } } - recordMessage(line, context, text, comment, extracomment, utf8, plural); + recordMessage(line, context, text, comment, extracomment, msgid, extra, utf8, plural); } extracomment.clear(); + msgid.clear(); + extra.clear(); break; case Tok_Q_DECLARE_TR_FUNCTIONS: case Tok_Q_OBJECT: @@ -1679,6 +1689,15 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) if (yyComment.startsWith(QLatin1Char(':'))) { yyComment.remove(0, 1); extracomment.append(yyComment); + } else if (yyComment.startsWith(QLatin1Char('='))) { + yyComment.remove(0, 1); + msgid = yyComment.simplified(); + } else if (yyComment.startsWith(QLatin1Char('~'))) { + yyComment.remove(0, 1); + yyComment = yyComment.trimmed(); + int k = yyComment.indexOf(QLatin1Char(' ')); + if (k > -1) + extra.insert(yyComment.left(k), yyComment.mid(k + 1).trimmed()); } else { comment = yyComment.simplified(); if (comment.startsWith(QLatin1String(MagicComment))) { @@ -1689,7 +1708,11 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) } else { context = comment.left(k); comment.remove(0, k + 1); - recordMessage(yyLineNo, context, QString(), comment, extracomment, false, false); + recordMessage(yyLineNo, context, QString(), comment, extracomment, + QString(), TranslatorMessage::ExtraData(), false, false); + extracomment.clear(); + results->tor->setExtras(extra); + extra.clear(); } } } @@ -1739,6 +1762,8 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) prospectiveContext.clear(); prefix.clear(); extracomment.clear(); + msgid.clear(); + extra.clear(); yyTokColonSeen = false; yyTok = getToken(); break; -- cgit v0.12 From ebfdbff7712e230c19fc2a990632038e3fc79ef2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 2 Jul 2009 13:27:21 +0200 Subject: Doc: indicate that these methods are added in 4.6 --- src/dbus/qdbuspendingcall.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dbus/qdbuspendingcall.cpp b/src/dbus/qdbuspendingcall.cpp index 7807543..0ec1a26 100644 --- a/src/dbus/qdbuspendingcall.cpp +++ b/src/dbus/qdbuspendingcall.cpp @@ -410,6 +410,7 @@ bool QDBusPendingCall::setReplyCallback(QObject *target, const char *member) #endif /*! + \since 4.6 Creates a QDBusPendingCall object based on the error condition \a error. The resulting pending call object will be in the "finished" state and QDBusPendingReply::isError() will return true. @@ -422,6 +423,7 @@ QDBusPendingCall QDBusPendingCall::fromError(const QDBusError &error) } /*! + \since 4.6 Creates a QDBusPendingCall object based on the message \a msg. The message must be of type QDBusMessage::ErrorMessage or QDBusMessage::ReplyMessage (that is, a message that is typical -- cgit v0.12 From c5f83fbd89d6bb950fb012c285879f6c88b5bdf3 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Apr 2009 16:47:12 +0200 Subject: Add qcore_unix_p.h containing mostly safe versions of Unix functions. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most of these functions are from unistd.h and need to have a loop around the actual call because the calls can be interrupted by a signal delivery. Some special calls (open, dup2, pipe) require an extra flag to support thread-safe execution: the file descriptor must be created from the operating system with the FD_CLOEXEC flag already set. The O_CLOEXEC flag is specified in POSIX.1-2008, but the rest is Linux-specific. Reviewed-By: João Abecasis --- src/corelib/kernel/kernel.pri | 1 + src/corelib/kernel/qcore_unix_p.h | 246 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 247 insertions(+) create mode 100644 src/corelib/kernel/qcore_unix_p.h diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index ecef555..6f28029 100644 --- a/src/corelib/kernel/kernel.pri +++ b/src/corelib/kernel/kernel.pri @@ -92,6 +92,7 @@ unix { kernel/qsharedmemory_unix.cpp \ kernel/qsystemsemaphore_unix.cpp HEADERS += \ + kernel/qcore_unix_p.h \ kernel/qcrashhandler_p.h contains(QT_CONFIG, glib) { diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h new file mode 100644 index 0000000..4e3158a --- /dev/null +++ b/src/corelib/kernel/qcore_unix_p.h @@ -0,0 +1,246 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore 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 qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QCORE_UNIX_P_H +#define QCORE_UNIX_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of Qt code on Unix. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qplatformdefs.h" + +#ifndef Q_OS_UNIX +# error "qcore_unix_p.h included on a non-Unix system" +#endif + +#include +#include +#include + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +#if defined(Q_OS_LINUX) && defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0209 +# define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 1 +#else +# define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 0 +#endif + +#define EINTR_LOOP(var, cmd) \ + do { \ + var = cmd; \ + } while (var == -1 && errno == EINTR) + + +// don't call QT_OPEN or ::open +// call qt_safe_open +static inline int qt_safe_open(const char *pathname, int flags, mode_t mode = 0777) +{ +#ifdef O_CLOEXEC + flags |= O_CLOEXEC; +#endif + register int fd; + EINTR_LOOP(fd, QT_OPEN(pathname, flags, mode)); + + // unknown flags are ignored, so we have no way of verifying if + // O_CLOEXEC was accepted + if (fd != -1) + ::fcntl(fd, F_SETFD, FD_CLOEXEC); + return fd; +} +#undef QT_OPEN +#define QT_OPEN qt_safe_open + +// don't call ::pipe +// call qt_safe_pipe +static inline int qt_safe_pipe(int pipefd[2], int flags = 0) +{ +#ifdef O_CLOEXEC + Q_ASSERT((flags & ~(O_CLOEXEC | O_NONBLOCK)) == 0); +#else + Q_ASSERT((flags & ~O_NONBLOCK) == 0); +#endif + + register int ret; +#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC + // use pipe2 + flags |= O_CLOEXEC; + ret = ::pipe2(pipefd, flags); // pipe2 is Linux-specific and is documented not to return EINTR + if (ret == 0 || errno != ENOSYS) + return ret; +#endif + + ret = ::pipe(pipefd); + if (ret == -1) + return -1; + + ::fcntl(pipefd[0], F_SETFD, FD_CLOEXEC); + ::fcntl(pipefd[1], F_SETFD, FD_CLOEXEC); + + // set non-block too? + if (flags & O_NONBLOCK) { + ::fcntl(pipefd[0], F_SETFL, ::fcntl(pipefd[0], F_GETFL) | O_NONBLOCK); + ::fcntl(pipefd[1], F_SETFL, ::fcntl(pipefd[1], F_GETFL) | O_NONBLOCK); + } + + return 0; +} + +// don't call dup or fcntl(F_DUPFD) +static inline int qt_safe_dup(int oldfd, int atleast = 0, int flags = FD_CLOEXEC) +{ + Q_ASSERT(flags == FD_CLOEXEC || flags == 0); + + register int ret; +#ifdef F_DUPFD_CLOEXEC + // use this fcntl + if (flags & FD_CLOEXEC) { + ret = ::fcntl(oldfd, F_DUPFD_CLOEXEC, atleast); + if (ret != -1 || errno != EINVAL) + return ret; + } +#endif + + // use F_DUPFD + ret = ::fcntl(oldfd, F_DUPFD, atleast); + + if (flags && ret != -1) + ::fcntl(ret, F_SETFD, flags); + return ret; +} + +// don't call dup2 +// call qt_safe_dup2 +static inline int qt_safe_dup2(int oldfd, int newfd, int flags = FD_CLOEXEC) +{ + Q_ASSERT(flags == FD_CLOEXEC || flags == 0); + + register int ret; +#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC + // use dup3 + if (flags & FD_CLOEXEC) { + EINTR_LOOP(ret, ::dup3(oldfd, newfd, O_CLOEXEC)); + if (ret == 0 || errno != ENOSYS) + return ret; + } +#endif + EINTR_LOOP(ret, ::dup2(oldfd, newfd)); + if (ret == -1) + return -1; + + if (flags) + ::fcntl(newfd, F_SETFD, flags); + return 0; +} + +static inline qint64 qt_safe_read(int fd, char *data, qint64 maxlen) +{ + qint64 ret = 0; + EINTR_LOOP(ret, QT_READ(fd, data, maxlen)); + return ret; +} +#undef QT_READ +#define QT_READ qt_safe_read + +static inline qint64 qt_safe_write(int fd, const char *data, qint64 len) +{ + qint64 ret = 0; + EINTR_LOOP(ret, QT_WRITE(fd, data, len)); + return ret; +} +#undef QT_WRITE +#define QT_WRITE qt_safe_write + +static inline int qt_safe_close(int fd) +{ + register int ret; + EINTR_LOOP(ret, QT_CLOSE(fd)); + return ret; +} +#undef QT_CLOSE +#define QT_CLOSE qt_safe_close + +static inline int qt_safe_execve(const char *filename, char *const argv[], + char *const envp[]) +{ + register int ret; + EINTR_LOOP(ret, ::execve(filename, argv, envp)); + return ret; +} + +static inline int qt_safe_execv(const char *path, char *const argv[]) +{ + register int ret; + EINTR_LOOP(ret, ::execv(path, argv)); + return ret; +} + +static inline int qt_safe_execvp(const char *file, char *const argv[]) +{ + register int ret; + EINTR_LOOP(ret, ::execvp(file, argv)); + return ret; +} + +static inline pid_t qt_safe_waitpid(pid_t pid, int *status, int options) +{ + register int ret; + EINTR_LOOP(ret, ::waitpid(pid, status, options)); + return ret; +} + +Q_CORE_EXPORT int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, + const struct timeval *tv); + +QT_END_NAMESPACE + +#endif -- cgit v0.12 From 29302d2429ed81f4396155383b602e7bde4edd3b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Apr 2009 17:30:51 +0200 Subject: Port most uses of ::open and QT_OPEN to the safe version. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This ensures that we're calling the open64 version of this function as well as handling the O_CLOEXEC flag and EINTR errors. Reviewed-By: João Abecasis --- src/corelib/io/qfilesystemwatcher_kqueue.cpp | 5 +++-- src/corelib/io/qfsfileengine_unix.cpp | 18 +++++++----------- src/corelib/io/qresource.cpp | 4 ++++ src/corelib/io/qtemporaryfile.cpp | 17 ++++++----------- src/corelib/kernel/qsharedmemory_unix.cpp | 4 +++- src/corelib/kernel/qtranslator.cpp | 1 + 6 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher_kqueue.cpp b/src/corelib/io/qfilesystemwatcher_kqueue.cpp index ed42c34..721f52c 100644 --- a/src/corelib/io/qfilesystemwatcher_kqueue.cpp +++ b/src/corelib/io/qfilesystemwatcher_kqueue.cpp @@ -43,6 +43,7 @@ #include "qfilesystemwatcher.h" #include "qfilesystemwatcher_kqueue_p.h" +#include "qcore_unix_p.h" #include #include @@ -124,9 +125,9 @@ QStringList QKqueueFileSystemWatcherEngine::addPaths(const QStringList &paths, QString path = it.next(); int fd; #if defined(O_EVTONLY) - fd = ::open(QFile::encodeName(path), O_EVTONLY); + fd = qt_safe_open(QFile::encodeName(path), O_EVTONLY); #else - fd = ::open(QFile::encodeName(path), O_RDONLY); + fd = qt_safe_open(QFile::encodeName(path), O_RDONLY); #endif if (fd == -1) { perror("QKqueueFileSystemWatcherEngine::addPaths: open"); diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 4743a47..5708e9f 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -42,6 +42,7 @@ #include "qplatformdefs.h" #include "qabstractfileengine.h" #include "private/qfsfileengine_p.h" +#include "private/qcore_unix_p.h" #ifndef QT_NO_FSFILEENGINE @@ -90,6 +91,12 @@ static QByteArray openModeToFopenMode(QIODevice::OpenMode flags, const QString & if (flags & QIODevice::ReadOnly) mode += '+'; } + +#if defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0207 + // must be glibc >= 2.7 + mode += 'e'; +#endif + return mode; } @@ -118,12 +125,6 @@ static int openModeToOpenFlags(QIODevice::OpenMode mode) oflags |= QT_OPEN_TRUNC; } -#ifdef O_CLOEXEC - // supported on Linux >= 2.6.23; avoids one extra system call - // and avoids a race condition: if another thread forks, we could - // end up leaking a file descriptor... - oflags |= O_CLOEXEC; -#endif return oflags; } @@ -177,11 +178,6 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) } } -#ifndef O_CLOEXEC - // not needed on Linux >= 2.6.23 - setCloseOnExec(fd); // ignore failure -#endif - // Seek to the end when in Append mode. if (flags & QFile::Append) { int ret; diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index fe8764d..a70b92f 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -56,6 +56,10 @@ #include #include "private/qabstractfileengine_p.h" +#ifdef Q_OS_UNIX +# include "private/qcore_unix_p.h" +#endif + //#define DEBUG_RESOURCE_MATCH QT_BEGIN_NAMESPACE diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index 62ab0c4..2ae4611 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -60,6 +60,10 @@ #include #include +#if defined(Q_OS_UNIX) +# include "private/qcore_unix_p.h" +#endif + #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) # include # if defined(_MSC_VER) && _MSC_VER >= 1400 @@ -72,7 +76,6 @@ # include "qfunctions_wince.h" #endif - QT_BEGIN_NAMESPACE /* @@ -208,8 +211,9 @@ static int _gettemp(char *path, int *doopen, int domkdir, int slen) if ((*doopen = QT_OPEN(targetPath.toLocal8Bit(), O_CREAT|O_EXCL|O_RDWR # else // CE + // this is Unix if ((*doopen = - open(path, QT_OPEN_CREAT|O_EXCL|QT_OPEN_RDWR + qt_safe_open(path, QT_OPEN_CREAT|O_EXCL|QT_OPEN_RDWR # endif # ifdef QT_LARGEFILE_SUPPORT |QT_OPEN_LARGEFILE @@ -219,18 +223,9 @@ static int _gettemp(char *path, int *doopen, int domkdir, int slen) # elif defined(Q_OS_WIN) |O_BINARY # endif -# ifdef O_CLOEXEC - // supported on Linux >= 2.6.23; avoids one extra system call - // and avoids a race condition: if another thread forks, we could - // end up leaking a file descriptor... - |O_CLOEXEC -# endif , 0600)) >= 0) #endif // WIN && !CE { -#if defined(Q_OS_UNIX) && !defined(O_CLOEXEC) - fcntl(*doopen, F_SETFD, FD_CLOEXEC); -#endif return 1; } if (errno != EEXIST) diff --git a/src/corelib/kernel/qsharedmemory_unix.cpp b/src/corelib/kernel/qsharedmemory_unix.cpp index 5299972..04739ff 100644 --- a/src/corelib/kernel/qsharedmemory_unix.cpp +++ b/src/corelib/kernel/qsharedmemory_unix.cpp @@ -59,6 +59,8 @@ #include #include +#include "private/qcore_unix_p.h" + QT_BEGIN_NAMESPACE QSharedMemoryPrivate::QSharedMemoryPrivate() @@ -153,7 +155,7 @@ int QSharedMemoryPrivate::createUnixKeyFile(const QString &fileName) if (QFile::exists(fileName)) return 0; - int fd = open(QFile::encodeName(fileName).constData(), + int fd = qt_safe_open(QFile::encodeName(fileName).constData(), O_EXCL | O_CREAT | O_RDWR, 0640); if (-1 == fd) { if (errno == EEXIST) diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index 64cf16e..4aed2b2 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -58,6 +58,7 @@ #if defined(Q_OS_UNIX) #define QT_USE_MMAP +#include "private/qcore_unix_p.h" #endif // most of the headers below are already included in qplatformdefs.h -- cgit v0.12 From 557258e8f944f0003e9b71e5fe11fcb458db71d8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Apr 2009 18:01:05 +0200 Subject: Make the inotify_init call also use FD_CLOEXEC-safe version of the system call Reviewed-By: ossi --- src/corelib/io/qfilesystemwatcher_inotify.cpp | 40 +++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher_inotify.cpp b/src/corelib/io/qfilesystemwatcher_inotify.cpp index 401e545..9d08228 100644 --- a/src/corelib/io/qfilesystemwatcher_inotify.cpp +++ b/src/corelib/io/qfilesystemwatcher_inotify.cpp @@ -44,6 +44,8 @@ #ifndef QT_NO_FILESYSTEMWATCHER +#include "private/qcore_unix_p.h" + #include #include #include @@ -62,62 +64,80 @@ # define __NR_inotify_init 291 # define __NR_inotify_add_watch 292 # define __NR_inotify_rm_watch 293 +# define __NR_inotify_init1 332 #elif defined(__x86_64__) # define __NR_inotify_init 253 # define __NR_inotify_add_watch 254 # define __NR_inotify_rm_watch 255 +# define __NR_inotify_init1 294 #elif defined(__powerpc__) || defined(__powerpc64__) # define __NR_inotify_init 275 # define __NR_inotify_add_watch 276 # define __NR_inotify_rm_watch 277 +# define __NR_inotify_init1 318 #elif defined (__ia64__) # define __NR_inotify_init 1277 # define __NR_inotify_add_watch 1278 # define __NR_inotify_rm_watch 1279 +# define __NR_inotify_init1 1318 #elif defined (__s390__) || defined (__s390x__) # define __NR_inotify_init 284 # define __NR_inotify_add_watch 285 # define __NR_inotify_rm_watch 286 +# define __NR_inotify_init1 324 #elif defined (__alpha__) # define __NR_inotify_init 444 # define __NR_inotify_add_watch 445 # define __NR_inotify_rm_watch 446 +// no inotify_init1 for the Alpha #elif defined (__sparc__) || defined (__sparc64__) # define __NR_inotify_init 151 # define __NR_inotify_add_watch 152 # define __NR_inotify_rm_watch 156 +# define __NR_inotify_init1 322 #elif defined (__arm__) # define __NR_inotify_init 316 # define __NR_inotify_add_watch 317 # define __NR_inotify_rm_watch 318 +# define __NR_inotify_init1 360 #elif defined (__sh__) # define __NR_inotify_init 290 # define __NR_inotify_add_watch 291 # define __NR_inotify_rm_watch 292 +# define __NR_inotify_init1 332 #elif defined (__sh64__) # define __NR_inotify_init 318 # define __NR_inotify_add_watch 319 # define __NR_inotify_rm_watch 320 +# define __NR_inotify_init1 360 #elif defined (__mips__) # define __NR_inotify_init 284 # define __NR_inotify_add_watch 285 # define __NR_inotify_rm_watch 286 +# define __NR_inotify_init1 329 #elif defined (__hppa__) # define __NR_inotify_init 269 # define __NR_inotify_add_watch 270 # define __NR_inotify_rm_watch 271 +# define __NR_inotify_init1 314 #elif defined (__avr32__) # define __NR_inotify_init 240 # define __NR_inotify_add_watch 241 # define __NR_inotify_rm_watch 242 +// no inotify_init1 for AVR32 #elif defined (__mc68000__) # define __NR_inotify_init 284 # define __NR_inotify_add_watch 285 # define __NR_inotify_rm_watch 286 +# define __NR_inotify_init1 328 #else # error "This architecture is not supported. Please talk to qt-bugs@trolltech.com" #endif +#if !defined(IN_CLOEXEC) && defined(O_CLOEXEC) && defined(__NR_inotify_init1) +# define IN_CLOEXEC O_CLOEXEC +#endif + QT_BEGIN_NAMESPACE #ifdef QT_LINUXBASE @@ -140,6 +160,13 @@ static inline int inotify_rm_watch(int fd, __u32 wd) return syscall(__NR_inotify_rm_watch, fd, wd); } +#ifdef IN_CLOEXEC +static inline int inotify_init1(int flags) +{ + return syscall(__NR_inotify_init1, flags); +} +#endif + // the following struct and values are documented in linux/inotify.h extern "C" { @@ -185,9 +212,16 @@ QT_BEGIN_NAMESPACE QInotifyFileSystemWatcherEngine *QInotifyFileSystemWatcherEngine::create() { - int fd = inotify_init(); - if (fd <= 0) - return 0; + register int fd = -1; +#ifdef IN_CLOEXEC + fd = inotify_init1(IN_CLOEXEC); +#endif + if (fd == -1) { + fd = inotify_init(); + if (fd == -1) + return 0; + ::fcntl(fd, F_SETFD, FD_CLOEXEC); + } return new QInotifyFileSystemWatcherEngine(fd); } -- cgit v0.12 From 1d965e189dfd5c9977565ca0c20224806aa7473d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Apr 2009 19:02:32 +0200 Subject: Use the safe versions in these system calls I've just introduced. Reviewed-By: ossi --- src/corelib/io/qfilesystemwatcher_dnotify.cpp | 20 ++++++++++---------- src/corelib/io/qfsfileengine.cpp | 3 +++ src/corelib/io/qfsfileengine_unix.cpp | 2 +- src/corelib/kernel/qeventdispatcher_unix.cpp | 12 +++++++----- src/gui/painting/qpdf.cpp | 20 ++++++++++++-------- 5 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher_dnotify.cpp b/src/corelib/io/qfilesystemwatcher_dnotify.cpp index c68af85..6df3746 100644 --- a/src/corelib/io/qfilesystemwatcher_dnotify.cpp +++ b/src/corelib/io/qfilesystemwatcher_dnotify.cpp @@ -59,6 +59,8 @@ #include #include +#include "private/qcore_unix_p.h" + #ifdef QT_LINUXBASE /* LSB doesn't standardize these */ @@ -80,7 +82,7 @@ static void (*qfswd_old_sigio_handler)(int) = 0; static void (*qfswd_old_sigio_action)(int, siginfo_t *, void *) = 0; static void qfswd_sigio_monitor(int signum, siginfo_t *i, void *v) { - ::write(qfswd_fileChanged_pipe[1], &i->si_fd, sizeof(int)); + qt_safe_write(qfswd_fileChanged_pipe[1], reinterpret_cast(&i->si_fd), sizeof(int)); if (qfswd_old_sigio_handler && qfswd_old_sigio_handler != SIG_IGN) qfswd_old_sigio_handler(signum); @@ -121,9 +123,7 @@ QDnotifySignalThread::QDnotifySignalThread() { moveToThread(this); - ::pipe(qfswd_fileChanged_pipe); - ::fcntl(qfswd_fileChanged_pipe[0], F_SETFL, - ::fcntl(qfswd_fileChanged_pipe[0], F_GETFL) | O_NONBLOCK); + qt_safe_pipe(qfswd_fileChanged_pipe, O_NONBLOCK); struct sigaction oldAction; struct sigaction action; @@ -181,7 +181,7 @@ void QDnotifySignalThread::run() void QDnotifySignalThread::readFromDnotify() { int fd; - int readrv = ::read(qfswd_fileChanged_pipe[0], &fd,sizeof(int)); + int readrv = qt_safe_read(qfswd_fileChanged_pipe[0], reinterpret_cast(&fd), sizeof(int)); // Only expect EAGAIN or EINTR. Other errors are assumed to be impossible. if(readrv != -1) { Q_ASSERT(readrv == sizeof(int)); @@ -207,9 +207,9 @@ QDnotifyFileSystemWatcherEngine::~QDnotifyFileSystemWatcherEngine() for(QHash::ConstIterator iter = fdToDirectory.constBegin(); iter != fdToDirectory.constEnd(); ++iter) { - ::close(iter->fd); + qt_safe_close(iter->fd); if(iter->parentFd) - ::close(iter->parentFd); + qt_safe_close(iter->parentFd); } } @@ -353,7 +353,7 @@ QStringList QDnotifyFileSystemWatcherEngine::removePaths(const QStringList &path if(!directory.isMonitored && directory.files.isEmpty()) { // No longer needed - ::close(directory.fd); + qt_safe_close(directory.fd); pathToFD.remove(directory.path); fdToDirectory.remove(fd); } @@ -419,9 +419,9 @@ void QDnotifyFileSystemWatcherEngine::refresh(int fd) } if(!directory.isMonitored && directory.files.isEmpty()) { - ::close(directory.fd); + qt_safe_close(directory.fd); if(directory.parentFd) { - ::close(directory.parentFd); + qt_safe_close(directory.parentFd); parentToFD.remove(directory.parentFd); } fdToDirectory.erase(iter); diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index e32b818..beafe72 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -50,6 +50,9 @@ #if !defined(Q_OS_WINCE) #include #endif +#if defined(Q_OS_UNIX) +#include "private/qcore_unix_p.h" +#endif #include QT_BEGIN_NAMESPACE diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 5708e9f..47e3db0 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -458,7 +458,7 @@ bool QFSFileEngine::caseSensitive() const bool QFSFileEngine::setCurrentPath(const QString &path) { int r; - r = ::chdir(QFile::encodeName(path)); + r = QT_CHDIR(QFile::encodeName(path)); return r >= 0; } diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp index 161398e..0eeea04 100644 --- a/src/corelib/kernel/qeventdispatcher_unix.cpp +++ b/src/corelib/kernel/qeventdispatcher_unix.cpp @@ -49,6 +49,7 @@ #include "qeventdispatcher_unix_p.h" #include #include +#include #include #include @@ -76,6 +77,7 @@ static void signalHandler(int sig) } +#ifdef Q_OS_INTEGRITY static void initThreadPipeFD(int fd) { int ret = fcntl(fd, F_SETFD, FD_CLOEXEC); @@ -90,7 +92,7 @@ static void initThreadPipeFD(int fd) if (ret == -1) perror("QEventDispatcherUNIXPrivate: Unable to set flags on thread pipe"); } - +#endif QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate() { @@ -102,13 +104,13 @@ QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate() // INTEGRITY doesn't like a "select" on pipes, so use socketpair instead if (socketpair(AF_INET, SOCK_STREAM, PF_INET, thread_pipe) == -1) perror("QEventDispatcherUNIXPrivate(): Unable to create socket pair"); -#else - if (pipe(thread_pipe) == -1) - perror("QEventDispatcherUNIXPrivate(): Unable to create thread pipe"); -#endif initThreadPipeFD(thread_pipe[0]); initThreadPipeFD(thread_pipe[1]); +#else + if (qt_safe_pipe(thread_pipe, O_NONBLOCK) == -1) + perror("QEventDispatcherUNIXPrivate(): Unable to create thread pipe"); +#endif sn_highest = -1; diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index a6ecd4e..178d519 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -48,6 +48,10 @@ #include "qprinterinfo.h" #include +#ifdef Q_OS_UNIX +#include "private/qcore_unix_p.h" // overrides QT_OPEN +#endif + QT_BEGIN_NAMESPACE extern int qt_defaultDpi(); @@ -1647,7 +1651,7 @@ static void closeAllOpenFds() #endif // leave stdin/out/err untouched while(--i > 2) - ::close(i); + QT_CLOSE(i); } #endif @@ -1681,7 +1685,7 @@ bool QPdfBaseEnginePrivate::openPrintDevice() if (!printerName.isEmpty()) pr = printerName; int fds[2]; - if (pipe(fds) != 0) { + if (qt_safe_pipe(fds) != 0) { qWarning("QPdfPrinter: Could not open pipe to print"); return false; } @@ -1700,9 +1704,9 @@ bool QPdfBaseEnginePrivate::openPrintDevice() (void)execlp("true", "true", (char *)0); (void)execl("/bin/true", "true", (char *)0); (void)execl("/usr/bin/true", "true", (char *)0); - ::exit(0); + ::_exit(0); } - dup2(fds[0], 0); + qt_safe_dup2(fds[0], 0, 0); closeAllOpenFds(); @@ -1769,14 +1773,14 @@ bool QPdfBaseEnginePrivate::openPrintDevice() // wait for a second so the parent process (the // child of the GUI process) has exited. then // exit. - ::close(0); + QT_CLOSE(0); (void)::sleep(1); - ::exit(0); + ::_exit(0); } // parent process - ::close(fds[0]); + QT_CLOSE(fds[0]); fd = fds[1]; - (void)::waitpid(pid, 0, 0); + (void)qt_safe_waitpid(pid, 0, 0); if (fd < 0) return false; -- cgit v0.12 From de05f9a40e41deb79daf5c4935b2645d70d7f322 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Apr 2009 19:04:32 +0200 Subject: Port QProcess to use the EINTR-safe and thread-safe functions Reviewed-By: ossi --- src/corelib/io/qprocess_unix.cpp | 213 ++++++++++++--------------------------- 1 file changed, 65 insertions(+), 148 deletions(-) diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 49869a4..c81da44 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -84,6 +84,7 @@ QT_END_NAMESPACE #include "qprocess.h" #include "qprocess_p.h" +#include "private/qcore_unix_p.h" #ifdef Q_OS_MAC #include @@ -114,78 +115,11 @@ static inline char *strdup(const char *data) } #endif -static qint64 qt_native_read(int fd, char *data, qint64 maxlen) -{ - qint64 ret = 0; - do { - ret = ::read(fd, data, maxlen); - } while (ret == -1 && errno == EINTR); - return ret; -} - -static qint64 qt_native_write(int fd, const char *data, qint64 len) -{ - qint64 ret = 0; - do { - ret = ::write(fd, data, len); - } while (ret == -1 && errno == EINTR); - return ret; -} - -static void qt_native_close(int fd) -{ - int ret; - do { - ret = ::close(fd); - } while (ret == -1 && errno == EINTR); -} - -static void qt_native_dup2(int oldfd, int newfd) -{ - int ret; - do { - ret = ::dup2(oldfd, newfd); - } while (ret == -1 && errno == EINTR); -} - -static void qt_native_chdir(const char *path) -{ - int ret; - do { - ret = ::chdir(path); - } while (ret == -1 && errno == EINTR); -} - -static void qt_native_execve(const char *filename, char *const argv[], - char *const envp[]) -{ - int ret; - do { - ret = ::execve(filename, argv, envp); - } while (ret == -1 && errno == EINTR); -} - -static void qt_native_execv(const char *path, char *const argv[]) -{ - int ret; - do { - ret = ::execv(path, argv); - } while (ret == -1 && errno == EINTR); -} - -static void qt_native_execvp(const char *file, char *const argv[]) -{ - int ret; - do { - ret = ::execvp(file, argv); - } while (ret == -1 && errno == EINTR); -} - static int qt_qprocess_deadChild_pipe[2]; static void (*qt_sa_old_sigchld_handler)(int) = 0; static void qt_sa_sigchld_handler(int signum) { - qt_native_write(qt_qprocess_deadChild_pipe[1], "", 1); + qt_safe_write(qt_qprocess_deadChild_pipe[1], "", 1); #if defined (QPROCESS_DEBUG) fprintf(stderr, "*** SIGCHLD\n"); #endif @@ -231,13 +165,7 @@ QProcessManager::QProcessManager() // initialize the dead child pipe and make it non-blocking. in the // extremely unlikely event that the pipe fills up, we do not under any // circumstances want to block. - ::pipe(qt_qprocess_deadChild_pipe); - ::fcntl(qt_qprocess_deadChild_pipe[0], F_SETFD, FD_CLOEXEC); - ::fcntl(qt_qprocess_deadChild_pipe[1], F_SETFD, FD_CLOEXEC); - ::fcntl(qt_qprocess_deadChild_pipe[0], F_SETFL, - ::fcntl(qt_qprocess_deadChild_pipe[0], F_GETFL) | O_NONBLOCK); - ::fcntl(qt_qprocess_deadChild_pipe[1], F_SETFL, - ::fcntl(qt_qprocess_deadChild_pipe[1], F_GETFL) | O_NONBLOCK); + qt_safe_pipe(qt_qprocess_deadChild_pipe, O_NONBLOCK); // set up the SIGCHLD handler, which writes a single byte to the dead // child pipe every time a child dies. @@ -254,13 +182,13 @@ QProcessManager::QProcessManager() QProcessManager::~QProcessManager() { // notify the thread that we're shutting down. - qt_native_write(qt_qprocess_deadChild_pipe[1], "@", 1); - qt_native_close(qt_qprocess_deadChild_pipe[1]); + qt_safe_write(qt_qprocess_deadChild_pipe[1], "@", 1); + qt_safe_close(qt_qprocess_deadChild_pipe[1]); wait(); // on certain unixes, closing the reading end of the pipe will cause // select in run() to block forever, rather than return with EBADF. - qt_native_close(qt_qprocess_deadChild_pipe[0]); + qt_safe_close(qt_qprocess_deadChild_pipe[0]); qt_qprocess_deadChild_pipe[0] = -1; qt_qprocess_deadChild_pipe[1] = -1; @@ -304,7 +232,7 @@ void QProcessManager::run() // signals may have been delivered in the meantime, to avoid race // conditions. char c; - if (qt_native_read(qt_qprocess_deadChild_pipe[0], &c, 1) < 0 || c == '@') + if (qt_safe_read(qt_qprocess_deadChild_pipe[0], &c, 1) < 0 || c == '@') break; // catch any and all children that we can. @@ -323,7 +251,7 @@ void QProcessManager::catchDeadChildren() // notify all children that they may have died. they need to run // waitpid() in their own thread. QProcessInfo *info = it.value(); - qt_native_write(info->deathPipe, "", 1); + qt_safe_write(info->deathPipe, "", 1); #if defined (QPROCESS_DEBUG) qDebug() << "QProcessManager::run() sending death notice to" << info->process; @@ -382,25 +310,23 @@ void QProcessManager::unlock() static void qt_create_pipe(int *pipe) { if (pipe[0] != -1) - qt_native_close(pipe[0]); + qt_safe_close(pipe[0]); if (pipe[1] != -1) - qt_native_close(pipe[1]); - if (::pipe(pipe) != 0) { + qt_safe_close(pipe[1]); + if (qt_safe_pipe(pipe) != 0) { qWarning("QProcessPrivate::createPipe: Cannot create pipe %p: %s", pipe, qPrintable(qt_error_string(errno))); } - ::fcntl(pipe[0], F_SETFD, FD_CLOEXEC); - ::fcntl(pipe[1], F_SETFD, FD_CLOEXEC); } void QProcessPrivate::destroyPipe(int *pipe) { if (pipe[1] != -1) { - qt_native_close(pipe[1]); + qt_safe_close(pipe[1]); pipe[1] = -1; } if (pipe[0] != -1) { - qt_native_close(pipe[0]); + qt_safe_close(pipe[0]); pipe[0] = -1; } } @@ -453,7 +379,7 @@ bool QProcessPrivate::createChannel(Channel &channel) if (&channel == &stdinChannel) { // try to open in read-only mode channel.pipe[1] = -1; - if ( (channel.pipe[0] = QT_OPEN(fname, O_RDONLY)) != -1) + if ( (channel.pipe[0] = qt_safe_open(fname, O_RDONLY)) != -1) return true; // success q->setErrorString(QProcess::tr("Could not open input redirection for reading")); @@ -465,7 +391,7 @@ bool QProcessPrivate::createChannel(Channel &channel) mode |= O_TRUNC; channel.pipe[0] = -1; - if ( (channel.pipe[1] = QT_OPEN(fname, mode, 0666)) != -1) + if ( (channel.pipe[1] = qt_safe_open(fname, mode, 0666)) != -1) return true; // success q->setErrorString(QProcess::tr("Could not open output redirection for writing")); @@ -586,8 +512,6 @@ void QProcessPrivate::startProcess() return; qt_create_pipe(childStartedPipe); qt_create_pipe(deathPipe); - ::fcntl(deathPipe[0], F_SETFD, FD_CLOEXEC); - ::fcntl(deathPipe[1], F_SETFD, FD_CLOEXEC); if (threadData->eventDispatcher) { startupSocketNotifier = new QSocketNotifier(childStartedPipe[0], @@ -728,11 +652,11 @@ void QProcessPrivate::startProcess() // parent // close the ends we don't use and make all pipes non-blocking ::fcntl(deathPipe[0], F_SETFL, ::fcntl(deathPipe[0], F_GETFL) | O_NONBLOCK); - qt_native_close(childStartedPipe[1]); + qt_safe_close(childStartedPipe[1]); childStartedPipe[1] = -1; if (stdinChannel.pipe[0] != -1) { - qt_native_close(stdinChannel.pipe[0]); + qt_safe_close(stdinChannel.pipe[0]); stdinChannel.pipe[0] = -1; } @@ -740,7 +664,7 @@ void QProcessPrivate::startProcess() ::fcntl(stdinChannel.pipe[1], F_SETFL, ::fcntl(stdinChannel.pipe[1], F_GETFL) | O_NONBLOCK); if (stdoutChannel.pipe[1] != -1) { - qt_native_close(stdoutChannel.pipe[1]); + qt_safe_close(stdoutChannel.pipe[1]); stdoutChannel.pipe[1] = -1; } @@ -748,7 +672,7 @@ void QProcessPrivate::startProcess() ::fcntl(stdoutChannel.pipe[0], F_SETFL, ::fcntl(stdoutChannel.pipe[0], F_GETFL) | O_NONBLOCK); if (stderrChannel.pipe[1] != -1) { - qt_native_close(stderrChannel.pipe[1]); + qt_safe_close(stderrChannel.pipe[1]); stderrChannel.pipe[1] = -1; } if (stderrChannel.pipe[0] != -1) @@ -761,35 +685,34 @@ void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv Q_Q(QProcess); - // copy the stdin socket - qt_native_dup2(stdinChannel.pipe[0], fileno(stdin)); + // copy the stdin socket (without closing on exec) + qt_safe_dup2(stdinChannel.pipe[0], fileno(stdin), 0); // copy the stdout and stderr if asked to if (processChannelMode != QProcess::ForwardedChannels) { - qt_native_dup2(stdoutChannel.pipe[1], fileno(stdout)); + qt_safe_dup2(stdoutChannel.pipe[1], fileno(stdout), 0); // merge stdout and stderr if asked to if (processChannelMode == QProcess::MergedChannels) { - qt_native_dup2(fileno(stdout), fileno(stderr)); + qt_safe_dup2(fileno(stdout), fileno(stderr), 0); } else { - qt_native_dup2(stderrChannel.pipe[1], fileno(stderr)); + qt_safe_dup2(stderrChannel.pipe[1], fileno(stderr), 0); } } // make sure this fd is closed if execvp() succeeds - qt_native_close(childStartedPipe[0]); - ::fcntl(childStartedPipe[1], F_SETFD, FD_CLOEXEC); + qt_safe_close(childStartedPipe[0]); // enter the working directory if (workingDir) - qt_native_chdir(workingDir); + QT_CHDIR(workingDir); // this is a virtual call, and it base behavior is to do nothing. q->setupChildProcess(); // execute the process if (!envp) { - qt_native_execvp(argv[0], argv); + qt_safe_execvp(argv[0], argv); } else { if (path) { char **arg = path; @@ -798,14 +721,14 @@ void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv #if defined (QPROCESS_DEBUG) fprintf(stderr, "QProcessPrivate::execChild() searching / starting %s\n", argv[0]); #endif - qt_native_execve(argv[0], argv, envp); + qt_safe_execve(argv[0], argv, envp); ++arg; } } else { #if defined (QPROCESS_DEBUG) fprintf(stderr, "QProcessPrivate::execChild() starting %s\n", argv[0]); #endif - qt_native_execve(argv[0], argv, envp); + qt_safe_execve(argv[0], argv, envp); } } @@ -813,21 +736,21 @@ void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv #if defined (QPROCESS_DEBUG) fprintf(stderr, "QProcessPrivate::execChild() failed, notifying parent process\n"); #endif - qt_native_write(childStartedPipe[1], "", 1); - qt_native_close(childStartedPipe[1]); + qt_safe_write(childStartedPipe[1], "", 1); + qt_safe_close(childStartedPipe[1]); childStartedPipe[1] = -1; } bool QProcessPrivate::processStarted() { char c; - int i = qt_native_read(childStartedPipe[0], &c, 1); + int i = qt_safe_read(childStartedPipe[0], &c, 1); if (startupSocketNotifier) { startupSocketNotifier->setEnabled(false); startupSocketNotifier->deleteLater(); startupSocketNotifier = 0; } - qt_native_close(childStartedPipe[0]); + qt_safe_close(childStartedPipe[0]); childStartedPipe[0] = -1; #if defined (QPROCESS_DEBUG) @@ -862,7 +785,7 @@ qint64 QProcessPrivate::bytesAvailableFromStderr() const qint64 QProcessPrivate::readFromStdout(char *data, qint64 maxlen) { - qint64 bytesRead = qt_native_read(stdoutChannel.pipe[0], data, maxlen); + qint64 bytesRead = qt_safe_read(stdoutChannel.pipe[0], data, maxlen); #if defined QPROCESS_DEBUG qDebug("QProcessPrivate::readFromStdout(%p \"%s\", %lld) == %lld", data, qt_prettyDebug(data, bytesRead, 16).constData(), maxlen, bytesRead); @@ -872,7 +795,7 @@ qint64 QProcessPrivate::readFromStdout(char *data, qint64 maxlen) qint64 QProcessPrivate::readFromStderr(char *data, qint64 maxlen) { - qint64 bytesRead = qt_native_read(stderrChannel.pipe[0], data, maxlen); + qint64 bytesRead = qt_safe_read(stderrChannel.pipe[0], data, maxlen); #if defined QPROCESS_DEBUG qDebug("QProcessPrivate::readFromStderr(%p \"%s\", %lld) == %lld", data, qt_prettyDebug(data, bytesRead, 16).constData(), maxlen, bytesRead); @@ -896,7 +819,7 @@ qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen) { qt_ignore_sigpipe(); - qint64 written = qt_native_write(stdinChannel.pipe[1], data, maxlen); + qint64 written = qt_safe_write(stdinChannel.pipe[1], data, maxlen); #if defined QPROCESS_DEBUG qDebug("QProcessPrivate::writeToStdin(%p \"%s\", %lld) == %lld", data, qt_prettyDebug(data, maxlen, 16).constData(), maxlen, written); @@ -922,7 +845,7 @@ void QProcessPrivate::killProcess() ::kill(pid_t(pid), SIGKILL); } -static int qt_native_select(fd_set *fdread, fd_set *fdwrite, int timeout) +static int qt_safe_select(fd_set *fdread, fd_set *fdwrite, int timeout) { struct timeval tv; tv.tv_sec = timeout / 1000; @@ -962,7 +885,7 @@ bool QProcessPrivate::waitForStarted(int msecs) FD_SET(childStartedPipe[0], &fds); int ret; do { - ret = qt_native_select(&fds, 0, msecs); + ret = qt_safe_select(&fds, 0, msecs); } while (ret < 0 && errno == EINTR); if (ret == 0) { processError = QProcess::Timedout; @@ -1011,7 +934,7 @@ bool QProcessPrivate::waitForReadyRead(int msecs) FD_SET(stdinChannel.pipe[1], &fdwrite); int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); - int ret = qt_native_select(&fdread, &fdwrite, timeout); + int ret = qt_safe_select(&fdread, &fdwrite, timeout); if (ret < 0) { if (errno == EINTR) continue; @@ -1084,7 +1007,7 @@ bool QProcessPrivate::waitForBytesWritten(int msecs) FD_SET(stdinChannel.pipe[1], &fdwrite); int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); - int ret = qt_native_select(&fdread, &fdwrite, timeout); + int ret = qt_safe_select(&fdread, &fdwrite, timeout); if (ret < 0) { if (errno == EINTR) continue; @@ -1152,7 +1075,7 @@ bool QProcessPrivate::waitForFinished(int msecs) FD_SET(stdinChannel.pipe[1], &fdwrite); int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); - int ret = qt_native_select(&fdread, &fdwrite, timeout); + int ret = qt_safe_select(&fdread, &fdwrite, timeout); if (ret < 0) { if (errno == EINTR) continue; @@ -1193,7 +1116,7 @@ bool QProcessPrivate::waitForWrite(int msecs) int ret; do { - ret = qt_native_select(0, &fdwrite, msecs < 0 ? 0 : msecs) == 1; + ret = qt_safe_select(0, &fdwrite, msecs < 0 ? 0 : msecs) == 1; } while (ret < 0 && errno == EINTR); return ret == 1; } @@ -1210,15 +1133,11 @@ bool QProcessPrivate::waitForDeadChild() // read a byte from the death pipe char c; - qt_native_read(deathPipe[0], &c, 1); + qt_safe_read(deathPipe[0], &c, 1); // check if our process is dead int exitStatus; - pid_t waitResult = 0; - do { - waitResult = waitpid(pid_t(pid), &exitStatus, WNOHANG); - } while ((waitResult == -1 && errno == EINTR)); - if (waitResult > 0) { + if (qt_safe_waitpid(pid_t(pid), &exitStatus, WNOHANG) > 0) { processManager()->remove(q); crashed = !WIFEXITED(exitStatus); exitCode = WEXITSTATUS(exitStatus); @@ -1262,16 +1181,15 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a ::setsid(); - qt_native_close(startedPipe[0]); - qt_native_close(pidPipe[0]); + qt_safe_close(startedPipe[0]); + qt_safe_close(pidPipe[0]); pid_t doubleForkPid = qt_fork(); if (doubleForkPid == 0) { - ::fcntl(startedPipe[1], F_SETFD, FD_CLOEXEC); - qt_native_close(pidPipe[1]); + qt_safe_close(pidPipe[1]); if (!encodedWorkingDirectory.isEmpty()) - qt_native_chdir(encodedWorkingDirectory.constData()); + QT_CHDIR(encodedWorkingDirectory.constData()); char **argv = new char *[arguments.size() + 2]; for (int i = 0; i < arguments.size(); ++i) { @@ -1292,13 +1210,13 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a if (!tmp.endsWith('/')) tmp += '/'; tmp += QFile::encodeName(program); argv[0] = tmp.data(); - qt_native_execv(argv[0], argv); + qt_safe_execv(argv[0], argv); } } } else { QByteArray tmp = QFile::encodeName(program); argv[0] = tmp.data(); - qt_native_execv(argv[0], argv); + qt_safe_execv(argv[0], argv); } struct sigaction noaction; @@ -1308,8 +1226,8 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a // '\1' means execv failed char c = '\1'; - qt_native_write(startedPipe[1], &c, 1); - qt_native_close(startedPipe[1]); + qt_safe_write(startedPipe[1], &c, 1); + qt_safe_close(startedPipe[1]); ::_exit(1); } else if (doubleForkPid == -1) { struct sigaction noaction; @@ -1319,40 +1237,39 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a // '\2' means internal error char c = '\2'; - qt_native_write(startedPipe[1], &c, 1); + qt_safe_write(startedPipe[1], &c, 1); } - qt_native_close(startedPipe[1]); - qt_native_write(pidPipe[1], (const char *)&doubleForkPid, sizeof(pid_t)); - qt_native_chdir("/"); + qt_safe_close(startedPipe[1]); + qt_safe_write(pidPipe[1], (const char *)&doubleForkPid, sizeof(pid_t)); + QT_CHDIR("/"); ::_exit(1); } - qt_native_close(startedPipe[1]); - qt_native_close(pidPipe[1]); + qt_safe_close(startedPipe[1]); + qt_safe_close(pidPipe[1]); if (childPid == -1) { - qt_native_close(startedPipe[0]); - qt_native_close(pidPipe[0]); + qt_safe_close(startedPipe[0]); + qt_safe_close(pidPipe[0]); return false; } char reply = '\0'; - int startResult = qt_native_read(startedPipe[0], &reply, 1); + int startResult = qt_safe_read(startedPipe[0], &reply, 1); int result; - qt_native_close(startedPipe[0]); - while (::waitpid(childPid, &result, 0) == -1 && errno == EINTR) - { } + qt_safe_close(startedPipe[0]); + qt_safe_waitpid(childPid, &result, 0); bool success = (startResult != -1 && reply == '\0'); if (success && pid) { pid_t actualPid = 0; - if (qt_native_read(pidPipe[0], (char *)&actualPid, sizeof(pid_t)) == sizeof(pid_t)) { + if (qt_safe_read(pidPipe[0], (char *)&actualPid, sizeof(pid_t)) == sizeof(pid_t)) { *pid = actualPid; } else { *pid = 0; } } - qt_native_close(pidPipe[0]); + qt_safe_close(pidPipe[0]); return success; } -- cgit v0.12 From 27fc6ef5dfb7d58af778de162298fdc4da34459f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Apr 2009 20:54:17 +0200 Subject: Add a properly-safe version of select(2). Do the timeout handling the right and cross-platform way. The code that was in QProcess worked only on Linux, where the kernel sets the remainder in the returned timeval structure. Reviewed-By: ossi --- src/corelib/io/qprocess_unix.cpp | 80 ++++++++-------- src/corelib/kernel/kernel.pri | 1 + src/corelib/kernel/qcore_unix.cpp | 121 ++++++++++++++++++++++++ src/network/socket/qnativesocketengine_unix.cpp | 53 ++--------- 4 files changed, 165 insertions(+), 90 deletions(-) create mode 100644 src/corelib/kernel/qcore_unix.cpp diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index c81da44..fafce07 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -128,6 +128,13 @@ static void qt_sa_sigchld_handler(int signum) qt_sa_old_sigchld_handler(signum); } +static inline void add_fd(int &nfds, int fd, fd_set *fdset) +{ + FD_SET(fd, fdset); + if ((fd) > nfds) + nfds = fd; +} + struct QProcessInfo { QProcess *process; int deathPipe; @@ -845,17 +852,15 @@ void QProcessPrivate::killProcess() ::kill(pid_t(pid), SIGKILL); } -static int qt_safe_select(fd_set *fdread, fd_set *fdwrite, int timeout) +static int select_msecs(int nfds, fd_set *fdread, fd_set *fdwrite, int timeout) { + if (timeout < 0) + return qt_safe_select(nfds, fdread, fdwrite, 0, 0); + struct timeval tv; tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; - - int ret; - do { - ret = select(FD_SETSIZE, fdread, fdwrite, 0, timeout < 0 ? 0 : &tv); - } while (ret < 0 && (errno == EINTR)); - return ret; + return qt_safe_select(nfds, fdread, fdwrite, 0, &tv); } /* @@ -883,11 +888,7 @@ bool QProcessPrivate::waitForStarted(int msecs) fd_set fds; FD_ZERO(&fds); FD_SET(childStartedPipe[0], &fds); - int ret; - do { - ret = qt_safe_select(&fds, 0, msecs); - } while (ret < 0 && errno == EINTR); - if (ret == 0) { + if (select_msecs(childStartedPipe[0] + 1, &fds, 0, msecs) == 0) { processError = QProcess::Timedout; q->setErrorString(QProcess::tr("Process operation timed out")); #if defined (QPROCESS_DEBUG) @@ -920,24 +921,23 @@ bool QProcessPrivate::waitForReadyRead(int msecs) FD_ZERO(&fdread); FD_ZERO(&fdwrite); + int nfds = deathPipe[0]; + FD_SET(deathPipe[0], &fdread); + if (processState == QProcess::Starting) - FD_SET(childStartedPipe[0], &fdread); + add_fd(nfds, childStartedPipe[0], &fdread); if (stdoutChannel.pipe[0] != -1) - FD_SET(stdoutChannel.pipe[0], &fdread); + add_fd(nfds, stdoutChannel.pipe[0], &fdread); if (stderrChannel.pipe[0] != -1) - FD_SET(stderrChannel.pipe[0], &fdread); - - FD_SET(deathPipe[0], &fdread); + add_fd(nfds, stderrChannel.pipe[0], &fdread); if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1) - FD_SET(stdinChannel.pipe[1], &fdwrite); + add_fd(nfds, stdinChannel.pipe[1], &fdwrite); int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); - int ret = qt_safe_select(&fdread, &fdwrite, timeout); + int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout); if (ret < 0) { - if (errno == EINTR) - continue; break; } if (ret == 0) { @@ -993,24 +993,24 @@ bool QProcessPrivate::waitForBytesWritten(int msecs) FD_ZERO(&fdread); FD_ZERO(&fdwrite); + int nfds = deathPipe[0]; + FD_SET(deathPipe[0], &fdread); + if (processState == QProcess::Starting) - FD_SET(childStartedPipe[0], &fdread); + add_fd(nfds, childStartedPipe[0], &fdread); if (stdoutChannel.pipe[0] != -1) - FD_SET(stdoutChannel.pipe[0], &fdread); + add_fd(nfds, stdoutChannel.pipe[0], &fdread); if (stderrChannel.pipe[0] != -1) - FD_SET(stderrChannel.pipe[0], &fdread); + add_fd(nfds, stderrChannel.pipe[0], &fdread); - FD_SET(deathPipe[0], &fdread); if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1) - FD_SET(stdinChannel.pipe[1], &fdwrite); + add_fd(nfds, stdinChannel.pipe[1], &fdwrite); int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); - int ret = qt_safe_select(&fdread, &fdwrite, timeout); + int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout); if (ret < 0) { - if (errno == EINTR) - continue; break; } @@ -1056,29 +1056,28 @@ bool QProcessPrivate::waitForFinished(int msecs) forever { fd_set fdread; fd_set fdwrite; + int nfds = -1; FD_ZERO(&fdread); FD_ZERO(&fdwrite); if (processState == QProcess::Starting) - FD_SET(childStartedPipe[0], &fdread); + add_fd(nfds, childStartedPipe[0], &fdread); if (stdoutChannel.pipe[0] != -1) - FD_SET(stdoutChannel.pipe[0], &fdread); + add_fd(nfds, stdoutChannel.pipe[0], &fdread); if (stderrChannel.pipe[0] != -1) - FD_SET(stderrChannel.pipe[0], &fdread); + add_fd(nfds, stderrChannel.pipe[0], &fdread); if (processState == QProcess::Running) - FD_SET(deathPipe[0], &fdread); + add_fd(nfds, deathPipe[0], &fdread); if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1) - FD_SET(stdinChannel.pipe[1], &fdwrite); + add_fd(nfds, stdinChannel.pipe[1], &fdwrite); int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); - int ret = qt_safe_select(&fdread, &fdwrite, timeout); + int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout); if (ret < 0) { - if (errno == EINTR) - continue; break; } if (ret == 0) { @@ -1113,12 +1112,7 @@ bool QProcessPrivate::waitForWrite(int msecs) fd_set fdwrite; FD_ZERO(&fdwrite); FD_SET(stdinChannel.pipe[1], &fdwrite); - - int ret; - do { - ret = qt_safe_select(0, &fdwrite, msecs < 0 ? 0 : msecs) == 1; - } while (ret < 0 && errno == EINTR); - return ret == 1; + return select_msecs(stdinChannel.pipe[1] + 1, 0, &fdwrite, msecs < 0 ? 0 : msecs) == 1; } void QProcessPrivate::findExitCode() diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index 6f28029..8759578 100644 --- a/src/corelib/kernel/kernel.pri +++ b/src/corelib/kernel/kernel.pri @@ -88,6 +88,7 @@ mac { unix { SOURCES += \ + kernel/qcore_unix.cpp \ kernel/qcrashhandler.cpp \ kernel/qsharedmemory_unix.cpp \ kernel/qsystemsemaphore_unix.cpp diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp new file mode 100644 index 0000000..ffaf958 --- /dev/null +++ b/src/corelib/kernel/qcore_unix.cpp @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore 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 qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcore_unix_p.h" + +#include +#include +#include + +#include "qeventdispatcher_unix_p.h" // for the timeval operators + +#if !defined(QT_NO_CLOCK_MONOTONIC) +# if defined(QT_BOOTSTRAPPED) +# define QT_NO_CLOCK_MONOTONIC +# endif +#endif + +QT_BEGIN_NAMESPACE + +static inline timeval gettime() +{ + timeval tv; +#ifndef QT_NO_CLOCK_MONOTONIC + // use the monotonic clock + static volatile bool monotonicClockDisabled = false; + struct timespec ts; + if (!monotonicClockDisabled) { + if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) { + monotonicClockDisabled = true; + } else { + tv.tv_sec = ts.tv_sec; + tv.tv_usec = ts.tv_nsec / 1000; + return tv; + } + } +#endif + // use gettimeofday + ::gettimeofday(&tv, 0); + return tv; +} + +static inline bool time_update(struct timeval *tv, const struct timeval &start, + const struct timeval &timeout) +{ + struct timeval now = gettime(); + if (now < start) { + // clock reset, give up + return false; + } + + *tv = timeout + start - now; + return true; +} + +int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, + const struct timeval *orig_timeout) +{ + if (!orig_timeout) { + // no timeout -> block forever + register int ret; + EINTR_LOOP(ret, select(nfds, fdread, fdwrite, fdexcept, 0)); + return ret; + } + + timeval start = gettime(); + timeval timeout = *orig_timeout; + + // loop and recalculate the timeout as needed + int ret; + forever { + ret = ::select(nfds, fdread, fdwrite, fdexcept, &timeout); + if (ret != -1 || errno != EINTR) + return ret; + + // recalculate the timeout + if (!time_update(&timeout, start, *orig_timeout)) { + // clock reset, fake timeout error + return 0; + } + } +} + +QT_END_NAMESPACE diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index b130a9b..6eafe05 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -42,6 +42,7 @@ //#define QNATIVESOCKETENGINE_DEBUG #include "qnativesocketengine_p.h" +#include "private/qcore_unix_p.h" #include "qiodevice.h" #include "qhostaddress.h" #include "qvarlengtharray.h" @@ -833,33 +834,11 @@ int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool selectForRead) co tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; - QTime timer; - timer.start(); - int retval; - do { - if (selectForRead) - retval = select(socketDescriptor + 1, &fds, 0, 0, timeout < 0 ? 0 : &tv); - else - retval = select(socketDescriptor + 1, 0, &fds, 0, timeout < 0 ? 0 : &tv); - - if (retval != -1 || errno != EINTR) - break; - - if (timeout > 0) { - // recalculate the timeout - int t = timeout - timer.elapsed(); - if (t < 0) { - // oops, timeout turned negative? - retval = -1; - break; - } - - tv.tv_sec = t / 1000; - tv.tv_usec = (t % 1000) * 1000; - } - } while (true); - + if (selectForRead) + retval = qt_safe_select(socketDescriptor + 1, &fds, 0, 0, timeout < 0 ? 0 : &tv); + else + retval = qt_safe_select(socketDescriptor + 1, 0, &fds, 0, timeout < 0 ? 0 : &tv); return retval; } @@ -880,28 +859,8 @@ int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool checkRead, bool c tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; - QTime timer; - timer.start(); - int ret; - do { - ret = select(socketDescriptor + 1, &fdread, &fdwrite, 0, timeout < 0 ? 0 : &tv); - if (ret != -1 || errno != EINTR) - break; - - if (timeout > 0) { - // recalculate the timeout - int t = timeout - timer.elapsed(); - if (t < 0) { - // oops, timeout turned negative? - ret = -1; - break; - } - - tv.tv_sec = t / 1000; - tv.tv_usec = (t % 1000) * 1000; - } - } while (true); + ret = qt_safe_select(socketDescriptor + 1, &fdread, &fdwrite, 0, timeout < 0 ? 0 : &tv); if (ret <= 0) return ret; -- cgit v0.12 From cad1bf4c902899ec1a8277d46272afa23fc2b34b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 23 Apr 2009 11:55:02 +0200 Subject: Port gui/embedded to the EINTR-safe functions. I think I found two file descriptor that aren't closed. One seems like a genuine leak, the other seems intentional. Reviewed-By: ossi --- src/gui/embedded/qkbdlinuxinput_qws.cpp | 1 + src/gui/embedded/qkbdsl5000_qws.cpp | 6 +++-- src/gui/embedded/qkbdtty_qws.cpp | 4 ++++ src/gui/embedded/qkbdvfb_qws.cpp | 9 ++++---- src/gui/embedded/qkbdvr41xx_qws.cpp | 7 +++--- src/gui/embedded/qkbdyopy_qws.cpp | 10 +++++---- src/gui/embedded/qlock.cpp | 6 +++-- src/gui/embedded/qmousebus_qws.cpp | 11 +++++----- src/gui/embedded/qmouselinuxtp_qws.cpp | 7 +++--- src/gui/embedded/qmousepc_qws.cpp | 39 +++++++++++++++++---------------- src/gui/embedded/qmousevfb_qws.cpp | 9 ++++---- src/gui/embedded/qmousevr41xx_qws.cpp | 11 +++++----- src/gui/embedded/qmouseyopy_qws.cpp | 7 +++--- src/gui/embedded/qscreenlinuxfb_qws.cpp | 20 ++++++++++------- src/gui/embedded/qsoundqss_qws.cpp | 9 ++++---- src/gui/embedded/qtransportauth_qws.cpp | 7 +++--- src/gui/embedded/qunixsocket.cpp | 18 ++++++++++----- src/gui/text/qfontdatabase_qws.cpp | 5 +++-- src/gui/text/qfontengine_qpf.cpp | 11 +++++----- src/gui/text/qfontengine_qws.cpp | 5 +++-- 20 files changed, 118 insertions(+), 84 deletions(-) diff --git a/src/gui/embedded/qkbdlinuxinput_qws.cpp b/src/gui/embedded/qkbdlinuxinput_qws.cpp index d5720f7..e552731 100644 --- a/src/gui/embedded/qkbdlinuxinput_qws.cpp +++ b/src/gui/embedded/qkbdlinuxinput_qws.cpp @@ -47,6 +47,7 @@ #include #include +#include // overrides QT_OPEN #include #include diff --git a/src/gui/embedded/qkbdsl5000_qws.cpp b/src/gui/embedded/qkbdsl5000_qws.cpp index 36cb903..cf82c10 100644 --- a/src/gui/embedded/qkbdsl5000_qws.cpp +++ b/src/gui/embedded/qkbdsl5000_qws.cpp @@ -51,6 +51,8 @@ #include "qnamespace.h" #include "qtimer.h" +#include // overrides QT_OPEN + #include #include #include @@ -207,14 +209,14 @@ QWSSL5000KeyboardHandler::QWSSL5000KeyboardHandler(const QString &device) numLock = false; sharp_kbdctl_modifstat st; - int dev = ::open(device.isEmpty()?"/dev/sharp_kbdctl":device.toLocal8Bit().constData(), O_RDWR); + int dev = QT_OPEN(device.isEmpty()?"/dev/sharp_kbdctl":device.toLocal8Bit().constData(), O_RDWR); if (dev >= 0) { memset(&st, 0, sizeof(st)); st.which = 3; int ret = ioctl(dev, SHARP_KBDCTL_GETMODIFSTAT, (char*)&st); if(!ret) numLock = (bool)st.stat; - ::close(dev); + QT_CLOSE(dev); } } diff --git a/src/gui/embedded/qkbdtty_qws.cpp b/src/gui/embedded/qkbdtty_qws.cpp index 33777eb..8c1e79b 100644 --- a/src/gui/embedded/qkbdtty_qws.cpp +++ b/src/gui/embedded/qkbdtty_qws.cpp @@ -47,6 +47,7 @@ #include #include +#include // overrides QT_OPEN #include #include @@ -213,6 +214,9 @@ QWSTtyKbPrivate::~QWSTtyKbPrivate() ::ioctl(m_tty_fd, KDSKBMODE, m_originalKbdMode); #endif tcsetattr(m_tty_fd, TCSANOW, &m_tty_attr); + + // we're leaking m_tty_fd here? + //QT_CLOSE(m_tty_fd); } } diff --git a/src/gui/embedded/qkbdvfb_qws.cpp b/src/gui/embedded/qkbdvfb_qws.cpp index 082aac1..a44183b 100644 --- a/src/gui/embedded/qkbdvfb_qws.cpp +++ b/src/gui/embedded/qkbdvfb_qws.cpp @@ -55,6 +55,7 @@ #include #include #include +#include // overrides QT_OPEN QT_BEGIN_NAMESPACE @@ -69,13 +70,13 @@ QVFbKeyboardHandler::QVFbKeyboardHandler(const QString &device) kbdBufferLen = sizeof(QVFbKeyData) * 5; kbdBuffer = new unsigned char [kbdBufferLen]; - if ((kbdFD = open(terminalName.toLatin1().constData(), O_RDONLY | O_NDELAY)) < 0) { + if ((kbdFD = QT_OPEN(terminalName.toLatin1().constData(), O_RDONLY | O_NDELAY)) < 0) { qWarning("Cannot open %s (%s)", terminalName.toLatin1().constData(), strerror(errno)); } else { // Clear pending input char buf[2]; - while (read(kbdFD, buf, 1) > 0) { } + while (QT_READ(kbdFD, buf, 1) > 0) { } notifier = new QSocketNotifier(kbdFD, QSocketNotifier::Read, this); connect(notifier, SIGNAL(activated(int)),this, SLOT(readKeyboardData())); @@ -85,7 +86,7 @@ QVFbKeyboardHandler::QVFbKeyboardHandler(const QString &device) QVFbKeyboardHandler::~QVFbKeyboardHandler() { if (kbdFD >= 0) - close(kbdFD); + QT_CLOSE(kbdFD); delete [] kbdBuffer; } @@ -94,7 +95,7 @@ void QVFbKeyboardHandler::readKeyboardData() { int n; do { - n = read(kbdFD, kbdBuffer+kbdIdx, kbdBufferLen - kbdIdx); + n = QT_READ(kbdFD, kbdBuffer+kbdIdx, kbdBufferLen - kbdIdx); if (n > 0) kbdIdx += n; } while (n > 0); diff --git a/src/gui/embedded/qkbdvr41xx_qws.cpp b/src/gui/embedded/qkbdvr41xx_qws.cpp index 03c2a67..6d8299b 100644 --- a/src/gui/embedded/qkbdvr41xx_qws.cpp +++ b/src/gui/embedded/qkbdvr41xx_qws.cpp @@ -52,6 +52,7 @@ #include #include +#include // overrides QT_OPEN QT_BEGIN_NAMESPACE @@ -95,7 +96,7 @@ QWSVr41xxKbPrivate::QWSVr41xxKbPrivate(QWSVr41xxKeyboardHandler *h, const QStrin buttonFD = -1; notifier = 0; - buttonFD = open(terminalName.toLatin1().constData(), O_RDWR | O_NDELAY, 0);; + buttonFD = QT_OPEN(terminalName.toLatin1().constData(), O_RDWR | O_NDELAY, 0);; if (buttonFD < 0) { qWarning("Cannot open %s\n", qPrintable(terminalName)); return; @@ -115,7 +116,7 @@ QWSVr41xxKbPrivate::QWSVr41xxKbPrivate(QWSVr41xxKeyboardHandler *h, const QStrin QWSVr41xxKbPrivate::~QWSVr41xxKbPrivate() { if (buttonFD > 0) { - ::close(buttonFD); + QT_CLOSE(buttonFD); buttonFD = -1; } delete notifier; @@ -127,7 +128,7 @@ void QWSVr41xxKbPrivate::readKeyboardData() { int n = 0; do { - n = read(buttonFD, kbdBuffer+kbdIdx, kbdBufferLen - kbdIdx); + n = QT_READ(buttonFD, kbdBuffer+kbdIdx, kbdBufferLen - kbdIdx); if (n > 0) kbdIdx += n; } while (n > 0); diff --git a/src/gui/embedded/qkbdyopy_qws.cpp b/src/gui/embedded/qkbdyopy_qws.cpp index 5c9d28d..edb732c 100644 --- a/src/gui/embedded/qkbdyopy_qws.cpp +++ b/src/gui/embedded/qkbdyopy_qws.cpp @@ -60,6 +60,8 @@ #include #include +#include // overrides QT_OPEN + extern "C" { int getpgid(int); } @@ -105,7 +107,7 @@ QWSYopyKbPrivate::QWSYopyKbPrivate(QWSYopyKeyboardHandler *h, const QString &dev buttonFD = -1; notifier = 0; - buttonFD = ::open(terminalName.toLatin1().constData(), O_RDWR | O_NDELAY, 0); + buttonFD = QT_OPEN(terminalName.toLatin1().constData(), O_RDWR | O_NDELAY, 0); if (buttonFD < 0) { qWarning("Cannot open %s\n", qPrintable(terminalName)); return; @@ -177,10 +179,10 @@ void QWSYopyKbPrivate::readKeyboardData() case 40: k=Qt::Key_Up; break; // prev case 45: k=Qt::Key_Down; break; // next case 35: if(!press) { - fd = open("/proc/sys/pm/sleep",O_RDWR,0); + fd = QT_OPEN("/proc/sys/pm/sleep",O_RDWR,0); if(fd >= 0) { - write(fd,&c,sizeof(c)); - close(fd); + QT_WRITE(fd,&c,sizeof(c)); + QT_CLOSE(fd); // // Updates all widgets. // diff --git a/src/gui/embedded/qlock.cpp b/src/gui/embedded/qlock.cpp index c23608f..305832c 100644 --- a/src/gui/embedded/qlock.cpp +++ b/src/gui/embedded/qlock.cpp @@ -73,6 +73,8 @@ union semun { #endif // QT_NO_QWS_MULTIPROCESS +#include // overrides QT_OPEN + #define MAX_LOCKS 200 // maximum simultaneous read locks QT_BEGIN_NAMESPACE @@ -134,7 +136,7 @@ QLock::QLock(const QString &filename, char id, bool create) #ifdef Q_NO_SEMAPHORE data->file = QString(filename+id).toLocal8Bit().constData(); for(int x = 0; x < 2; x++) { - data->id = open(data->file, O_RDWR | (x ? O_CREAT : 0), S_IRWXU); + data->id = QT_OPEN(data->file, O_RDWR | (x ? O_CREAT : 0), S_IRWXU); if(data->id != -1 || !create) { data->owned = x; break; @@ -177,7 +179,7 @@ QLock::~QLock() unlock(); #ifdef Q_NO_SEMAPHORE if(isValid()) { - close(data->id); + QT_CLOSE(data->id); if(data->owned) unlink(data->file); } diff --git a/src/gui/embedded/qmousebus_qws.cpp b/src/gui/embedded/qmousebus_qws.cpp index a88ca5b..0b674b6 100644 --- a/src/gui/embedded/qmousebus_qws.cpp +++ b/src/gui/embedded/qmousebus_qws.cpp @@ -47,6 +47,7 @@ #include "qsocketnotifier.h" #include "qapplication.h" +#include // overrides QT_OPEN #include #include @@ -119,9 +120,9 @@ QWSBusMouseHandlerPrivate::QWSBusMouseHandlerPrivate(QWSBusMouseHandler *h, mouseDev = QLatin1String("/dev/mouse"); obstate = -1; mouseFD = -1; - mouseFD = open(mouseDev.toLocal8Bit(), O_RDWR | O_NDELAY); + mouseFD = QT_OPEN(mouseDev.toLocal8Bit(), O_RDWR | O_NDELAY); if (mouseFD < 0) - mouseFD = open(mouseDev.toLocal8Bit(), O_RDONLY | O_NDELAY); + mouseFD = QT_OPEN(mouseDev.toLocal8Bit(), O_RDONLY | O_NDELAY); if (mouseFD < 0) qDebug("Cannot open %s (%s)", qPrintable(mouseDev), strerror(errno)); @@ -130,7 +131,7 @@ QWSBusMouseHandlerPrivate::QWSBusMouseHandlerPrivate(QWSBusMouseHandler *h, usleep(50000); char buf[100]; // busmouse driver will not read if bufsize < 3, YYD - while (read(mouseFD, buf, 100) > 0) { } // eat unwanted replies + while (QT_READ(mouseFD, buf, 100) > 0) { } // eat unwanted replies mouseIdx = 0; @@ -142,7 +143,7 @@ QWSBusMouseHandlerPrivate::~QWSBusMouseHandlerPrivate() { if (mouseFD >= 0) { tcflush(mouseFD,TCIFLUSH); // yyd. - close(mouseFD); + QT_CLOSE(mouseFD); } } @@ -167,7 +168,7 @@ void QWSBusMouseHandlerPrivate::readMouseData() for (;;) { if (mouseBufSize - mouseIdx < 3) break; - n = read(mouseFD, mouseBuf+mouseIdx, 3); + n = QT_READ(mouseFD, mouseBuf+mouseIdx, 3); if (n != 3) break; mouseIdx += 3; diff --git a/src/gui/embedded/qmouselinuxtp_qws.cpp b/src/gui/embedded/qmouselinuxtp_qws.cpp index 1b4d96e..e64407e 100644 --- a/src/gui/embedded/qmouselinuxtp_qws.cpp +++ b/src/gui/embedded/qmouselinuxtp_qws.cpp @@ -47,6 +47,7 @@ #include "qtimer.h" #include "qapplication.h" #include "qscreen_qws.h" +#include // overrides QT_OPEN #include #include @@ -190,7 +191,7 @@ QWSLinuxTPMouseHandlerPrivate::QWSLinuxTPMouseHandlerPrivate(QWSLinuxTPMouseHand } else { mousedev = device; } - if ((mouseFD = open(mousedev.toLatin1().constData(), O_RDONLY | O_NDELAY)) < 0) { + if ((mouseFD = QT_OPEN(mousedev.toLatin1().constData(), O_RDONLY | O_NDELAY)) < 0) { qWarning("Cannot open %s (%s)", qPrintable(mousedev), strerror(errno)); return; } @@ -205,7 +206,7 @@ QWSLinuxTPMouseHandlerPrivate::QWSLinuxTPMouseHandlerPrivate(QWSLinuxTPMouseHand QWSLinuxTPMouseHandlerPrivate::~QWSLinuxTPMouseHandlerPrivate() { if (mouseFD >= 0) - close(mouseFD); + QT_CLOSE(mouseFD); } void QWSLinuxTPMouseHandlerPrivate::suspend() @@ -233,7 +234,7 @@ void QWSLinuxTPMouseHandlerPrivate::readMouseData() int n; do { - n = read(mouseFD, mouseBuf+mouseIdx, mouseBufSize-mouseIdx); + n = QT_READ(mouseFD, mouseBuf+mouseIdx, mouseBufSize-mouseIdx); if (n > 0) mouseIdx += n; } while (n > 0 && mouseIdx < mouseBufSize); diff --git a/src/gui/embedded/qmousepc_qws.cpp b/src/gui/embedded/qmousepc_qws.cpp index a9f2bc8..317bb8a 100644 --- a/src/gui/embedded/qmousepc_qws.cpp +++ b/src/gui/embedded/qmousepc_qws.cpp @@ -55,6 +55,7 @@ #include "qfile.h" #include "qtextstream.h" #include "qstringlist.h" +#include // overrides QT_OPEN #include #include @@ -107,7 +108,7 @@ public: { if (fd != f) { f = fd; - close(fd); + QT_CLOSE(fd); } } @@ -170,7 +171,7 @@ public: } static const uchar initseq[] = { 243, 200, 243, 100, 243, 80 }; static const uchar query[] = { 0xf2 }; - if (write(fd, initseq, sizeof(initseq))!=sizeof(initseq)) { + if (QT_WRITE(fd, initseq, sizeof(initseq))!=sizeof(initseq)) { badness = 100; return; } @@ -180,12 +181,12 @@ public: perror("QWSPcMouseSubHandler_intellimouse: post-init tcflush"); #endif } - if (write(fd, query, sizeof(query))!=sizeof(query)) { + if (QT_WRITE(fd, query, sizeof(query))!=sizeof(query)) { badness = 100; return; } usleep(10000); - n = read(fd, reply, 20); + n = QT_READ(fd, reply, 20); if (n > 0) { goodness = 10; switch (reply[n-1]) { @@ -256,13 +257,13 @@ public: perror("QWSPcMouseSubHandler_mouseman: initial tcflush"); #endif } - write(fd,"",1); + QT_WRITE(fd,"",1); usleep(50000); - write(fd,"@EeI!",5); + QT_WRITE(fd,"@EeI!",5); usleep(10000); static const char ibuf[] = { 246, 244 }; - write(fd,ibuf,1); - write(fd,ibuf+1,1); + QT_WRITE(fd,ibuf,1); + QT_WRITE(fd,ibuf+1,1); if (tcflush(fd,TCIOFLUSH) == -1) { #ifdef QWS_MOUSE_DEBUG perror("QWSPcMouseSubHandler_mouseman: tcflush"); @@ -271,7 +272,7 @@ public: usleep(10000); char buf[100]; - while (read(fd, buf, 100) > 0) { } // eat unwanted replies + while (QT_READ(fd, buf, 100) > 0) { } // eat unwanted replies } int tryData() @@ -350,7 +351,7 @@ private: for (int n = 0; n < 4; n++) { setflags(CSTOPB | speed[n]); - write(fd, "*q", 2); + QT_WRITE(fd, "*q", 2); usleep(10000); } } @@ -369,7 +370,7 @@ public: { setflags(B1200|CS8|CSTOPB); // 60Hz - if (write(fd, "R", 1)!=1) { + if (QT_WRITE(fd, "R", 1)!=1) { badness = 100; return; } @@ -418,7 +419,7 @@ public: { setflags(B1200|CS7); // 60Hz - if (write(fd, "R", 1)!=1) { + if (QT_WRITE(fd, "R", 1)!=1) { badness = 100; return; } @@ -648,25 +649,25 @@ void QWSPcMouseHandlerPrivate::openDevices() if (drv == QLatin1String("intellimouse")) { if (dev.isEmpty()) dev = "/dev/psaux"; - fd = open(dev, O_RDWR | O_NDELAY); + fd = QT_OPEN(dev, O_RDWR | O_NDELAY); if (fd >= 0) sub[nsub++] = new QWSPcMouseSubHandler_intellimouse(fd); } else if (drv == QLatin1String("microsoft")) { if (dev.isEmpty()) dev = "/dev/ttyS0"; - fd = open(dev, O_RDWR | O_NDELAY); + fd = QT_OPEN(dev, O_RDWR | O_NDELAY); if (fd >= 0) sub[nsub++] = new QWSPcMouseSubHandler_ms(fd); } else if (drv == QLatin1String("mousesystems")) { if (dev.isEmpty()) dev = "/dev/ttyS0"; - fd = open(dev, O_RDWR | O_NDELAY); + fd = QT_OPEN(dev, O_RDWR | O_NDELAY); if (fd >= 0) sub[nsub++] = new QWSPcMouseSubHandler_mousesystems(fd); } else if (drv == QLatin1String("mouseman")) { if (dev.isEmpty()) dev = "/dev/psaux"; - fd = open(dev, O_RDWR | O_NDELAY); + fd = QT_OPEN(dev, O_RDWR | O_NDELAY); if (fd >= 0) sub[nsub++] = new QWSPcMouseSubHandler_mouseman(fd); } @@ -677,12 +678,12 @@ void QWSPcMouseHandlerPrivate::openDevices() dev.constData(), strerror(errno)); } else { // Try automatically - fd = open("/dev/psaux", O_RDWR | O_NDELAY); + fd = QT_OPEN("/dev/psaux", O_RDWR | O_NDELAY); if (fd >= 0) { sub[nsub++] = new QWSPcMouseSubHandler_intellimouse(fd); notify(fd); } - fd = open("/dev/input/mice", O_RDWR | O_NDELAY); + fd = QT_OPEN("/dev/input/mice", O_RDWR | O_NDELAY); if (fd >= 0) { sub[nsub++] = new QWSPcMouseSubHandler_intellimouse(fd); notify(fd); @@ -694,7 +695,7 @@ void QWSPcMouseHandlerPrivate::openDevices() #if 0 const char fn[4][11] = { "/dev/ttyS0", "/dev/ttyS1", "/dev/ttyS2", "/dev/ttyS3" }; for (int ch = 0; ch < 4; ++ch) { - fd = open(fn[ch], O_RDWR | O_NDELAY); + fd = QT_OPEN(fn[ch], O_RDWR | O_NDELAY); if (fd >= 0) { //sub[nsub++] = new QWSPcMouseSubHandler_intellimouse(fd); sub[nsub++] = new QWSPcMouseSubHandler_mousesystems(fd); diff --git a/src/gui/embedded/qmousevfb_qws.cpp b/src/gui/embedded/qmousevfb_qws.cpp index 17d051f..dd553bc 100644 --- a/src/gui/embedded/qmousevfb_qws.cpp +++ b/src/gui/embedded/qmousevfb_qws.cpp @@ -54,6 +54,7 @@ #include #include #include +#include // overrides QT_OPEN QT_BEGIN_NAMESPACE @@ -64,7 +65,7 @@ QVFbMouseHandler::QVFbMouseHandler(const QString &driver, const QString &device) if (device.isEmpty()) mouseDev = QLatin1String("/dev/vmouse"); - mouseFD = open(mouseDev.toLatin1().constData(), O_RDWR | O_NDELAY); + mouseFD = QT_OPEN(mouseDev.toLatin1().constData(), O_RDWR | O_NDELAY); if (mouseFD == -1) { perror("QVFbMouseHandler::QVFbMouseHandler"); qWarning("QVFbMouseHander: Unable to open device %s", @@ -74,7 +75,7 @@ QVFbMouseHandler::QVFbMouseHandler(const QString &driver, const QString &device) // Clear pending input char buf[2]; - while (read(mouseFD, buf, 1) > 0) { } + while (QT_READ(mouseFD, buf, 1) > 0) { } mouseIdx = 0; @@ -85,7 +86,7 @@ QVFbMouseHandler::QVFbMouseHandler(const QString &driver, const QString &device) QVFbMouseHandler::~QVFbMouseHandler() { if (mouseFD >= 0) - close(mouseFD); + QT_CLOSE(mouseFD); } void QVFbMouseHandler::resume() @@ -102,7 +103,7 @@ void QVFbMouseHandler::readMouseData() { int n; do { - n = read(mouseFD, mouseBuf+mouseIdx, mouseBufSize-mouseIdx); + n = QT_READ(mouseFD, mouseBuf+mouseIdx, mouseBufSize-mouseIdx); if (n > 0) mouseIdx += n; } while (n > 0); diff --git a/src/gui/embedded/qmousevr41xx_qws.cpp b/src/gui/embedded/qmousevr41xx_qws.cpp index 8748055..b7491d9 100644 --- a/src/gui/embedded/qmousevr41xx_qws.cpp +++ b/src/gui/embedded/qmousevr41xx_qws.cpp @@ -49,6 +49,7 @@ #include "qscreen_qws.h" #include #include +#include // overrides QT_OPEN #include #include @@ -144,7 +145,7 @@ QWSVr41xxMouseHandlerPrivate::QWSVr41xxMouseHandlerPrivate(QWSVr41xxMouseHandler else dev = options.first(); - if ((mouseFD = open(dev.toLocal8Bit().constData(), O_RDONLY)) < 0) { + if ((mouseFD = QT_OPEN(dev.toLocal8Bit().constData(), O_RDONLY)) < 0) { qWarning("Cannot open %s (%s)", qPrintable(dev), strerror(errno)); return; } @@ -167,7 +168,7 @@ QWSVr41xxMouseHandlerPrivate::QWSVr41xxMouseHandlerPrivate(QWSVr41xxMouseHandler QWSVr41xxMouseHandlerPrivate::~QWSVr41xxMouseHandlerPrivate() { if (mouseFD >= 0) - close(mouseFD); + QT_CLOSE(mouseFD); } void QWSVr41xxMouseHandlerPrivate::suspend() @@ -190,9 +191,9 @@ void QWSVr41xxMouseHandlerPrivate::sendRelease() bool QWSVr41xxMouseHandlerPrivate::getSample() { - const int n = read(mouseFD, - reinterpret_cast(currSample) + currLength, - sizeof(currSample) - currLength); + const int n = QT_READ(mouseFD, + reinterpret_cast(currSample) + currLength, + sizeof(currSample) - currLength); if (n > 0) currLength += n; diff --git a/src/gui/embedded/qmouseyopy_qws.cpp b/src/gui/embedded/qmouseyopy_qws.cpp index 7b1141a..3a541d3 100644 --- a/src/gui/embedded/qmouseyopy_qws.cpp +++ b/src/gui/embedded/qmouseyopy_qws.cpp @@ -46,6 +46,7 @@ #include "qsocketnotifier.h" #include "qapplication.h" #include "qscreen_qws.h" +#include // overrides QT_OPEN #include #include @@ -103,7 +104,7 @@ void QWSYopyMouseHandler::suspend() QWSYopyMouseHandlerPrivate::QWSYopyMouseHandlerPrivate(QWSYopyMouseHandler *h) : handler(h) { - if ((mouseFD = open("/dev/ts", O_RDONLY)) < 0) { + if ((mouseFD = QT_OPEN("/dev/ts", O_RDONLY)) < 0) { qWarning("Cannot open /dev/ts (%s)", strerror(errno)); return; } else { @@ -118,7 +119,7 @@ QWSYopyMouseHandlerPrivate::QWSYopyMouseHandlerPrivate(QWSYopyMouseHandler *h) QWSYopyMouseHandlerPrivate::~QWSYopyMouseHandlerPrivate() { if (mouseFD >= 0) - close(mouseFD); + QT_CLOSE(mouseFD); } #define YOPY_XPOS(d) (d[1]&0x3FF) @@ -156,7 +157,7 @@ void QWSYopyMouseHandlerPrivate::readMouseData() int ret; - ret=read(mouseFD,&yopDat,sizeof(yopDat)); + ret=QT_READ(mouseFD,&yopDat,sizeof(yopDat)); if(ret) { data.status= (YOPY_PRES(yopDat)) ? 1 : 0; diff --git a/src/gui/embedded/qscreenlinuxfb_qws.cpp b/src/gui/embedded/qscreenlinuxfb_qws.cpp index 42c4fcd..2845842 100644 --- a/src/gui/embedded/qscreenlinuxfb_qws.cpp +++ b/src/gui/embedded/qscreenlinuxfb_qws.cpp @@ -46,6 +46,7 @@ #include "qwsdisplay_qws.h" #include "qpixmap.h" #include +#include // overrides QT_OPEN #include #include @@ -122,12 +123,12 @@ void QLinuxFbScreenPrivate::openTty() if (ttyDevice.isEmpty()) { for (const char * const *dev = devs; *dev; ++dev) { - ttyfd = ::open(*dev, O_RDWR); + ttyfd = QT_OPEN(*dev, O_RDWR); if (ttyfd != -1) break; } } else { - ttyfd = ::open(ttyDevice.toAscii().constData(), O_RDWR); + ttyfd = QT_OPEN(ttyDevice.toAscii().constData(), O_RDWR); } if (ttyfd == -1) @@ -144,7 +145,7 @@ void QLinuxFbScreenPrivate::openTty() // No blankin' screen, no blinkin' cursor!, no cursor! const char termctl[] = "\033[9;0]\033[?33l\033[?25l\033[?1c"; - ::write(ttyfd, termctl, sizeof(termctl)); + QT_WRITE(ttyfd, termctl, sizeof(termctl)); } void QLinuxFbScreenPrivate::closeTty() @@ -157,9 +158,9 @@ void QLinuxFbScreenPrivate::closeTty() // Blankin' screen, blinkin' cursor! const char termctl[] = "\033[9;15]\033[?33h\033[?25h\033[?0c"; - ::write(ttyfd, termctl, sizeof(termctl)); + QT_WRITE(ttyfd, termctl, sizeof(termctl)); - ::close(ttyfd); + QT_CLOSE(ttyfd); ttyfd = -1; } @@ -281,7 +282,7 @@ bool QLinuxFbScreen::connect(const QString &displaySpec) dev = QLatin1String("/dev/fb0"); if (access(dev.toLatin1().constData(), R_OK|W_OK) == 0) - d_ptr->fd = open(dev.toLatin1().constData(), O_RDWR); + d_ptr->fd = QT_OPEN(dev.toLatin1().constData(), O_RDWR); if (d_ptr->fd == -1) { if (QApplication::type() == QApplication::GuiServer) { perror("QScreenLinuxFb::connect"); @@ -289,7 +290,7 @@ bool QLinuxFbScreen::connect(const QString &displaySpec) return false; } if (access(dev.toLatin1().constData(), R_OK) == 0) - d_ptr->fd = open(dev.toLatin1().constData(), O_RDONLY); + d_ptr->fd = QT_OPEN(dev.toLatin1().constData(), O_RDONLY); } fb_fix_screeninfo finfo; @@ -681,7 +682,7 @@ bool QLinuxFbScreen::initDevice() #ifdef __i386__ // Now init mtrr if(!::getenv("QWS_NOMTRR")) { - int mfd=open("/proc/mtrr",O_WRONLY,0); + int mfd=QT_OPEN("/proc/mtrr",O_WRONLY,0); // MTRR entry goes away when file is closed - i.e. // hopefully when QWS is killed if(mfd != -1) { @@ -702,6 +703,9 @@ bool QLinuxFbScreen::initDevice() //sentry.base,sentry.size,strerror(errno)); } } + + // Should we close mfd here? + //QT_CLOSE(mfd); } #endif if ((vinfo.bits_per_pixel==8) || (vinfo.bits_per_pixel==4) || (finfo.visual==FB_VISUAL_DIRECTCOLOR)) diff --git a/src/gui/embedded/qsoundqss_qws.cpp b/src/gui/embedded/qsoundqss_qws.cpp index ac0ac9d..a45d0fe 100644 --- a/src/gui/embedded/qsoundqss_qws.cpp +++ b/src/gui/embedded/qsoundqss_qws.cpp @@ -53,6 +53,7 @@ #include #include #include +#include // overrides QT_OPEN #include #include @@ -1137,7 +1138,7 @@ void QWSSoundServerPrivate::sendCompletedSignals() int QWSSoundServerPrivate::openFile(int wid, int sid, const QString& filename) { stopFile(wid, sid); // close and re-open. - int f = ::open(QFile::encodeName(filename), O_RDONLY|O_NONBLOCK); + int f = QT_OPEN(QFile::encodeName(filename), O_RDONLY|O_NONBLOCK); if (f == -1) { // XXX check ferror, check reason. qDebug("Failed opening \"%s\"",filename.toLatin1().data()); @@ -1157,7 +1158,7 @@ bool QWSSoundServerPrivate::openDevice() { if (fd < 0) { if( silent ) { - fd = ::open( "/dev/null", O_WRONLY ); + fd = QT_OPEN( "/dev/null", O_WRONLY ); // Emulate write to audio device int delay = 1000*(sound_buffer_size>>(sound_stereo+sound_16bit))/sound_speed/2; timerId = startTimer(delay); @@ -1168,7 +1169,7 @@ bool QWSSoundServerPrivate::openDevice() // Don't block open right away. // bool openOkay = false; - if ((fd = ::open("/dev/dsp", O_WRONLY|O_NONBLOCK)) != -1) { + if ((fd = QT_OPEN("/dev/dsp", O_WRONLY|O_NONBLOCK)) != -1) { int flags = fcntl(fd, F_GETFL); flags &= ~O_NONBLOCK; openOkay = (fcntl(fd, F_SETFL, flags) == 0); @@ -1222,7 +1223,7 @@ bool QWSSoundServerPrivate::openDevice() // // Check system volume // - int mixerHandle = ::open( "/dev/mixer", O_RDWR|O_NONBLOCK ); + int mixerHandle = QT_OPEN( "/dev/mixer", O_RDWR|O_NONBLOCK ); if ( mixerHandle >= 0 ) { int volume; ioctl( mixerHandle, MIXER_READ(0), &volume ); diff --git a/src/gui/embedded/qtransportauth_qws.cpp b/src/gui/embedded/qtransportauth_qws.cpp index 05dce11..8523e27 100644 --- a/src/gui/embedded/qtransportauth_qws.cpp +++ b/src/gui/embedded/qtransportauth_qws.cpp @@ -56,6 +56,7 @@ #include "qlibraryinfo.h" #include "qfile.h" #include "qdebug.h" +#include // overrides QT_OPEN #include #include @@ -572,7 +573,7 @@ bool QTransportAuth::authorizeRequest( QTransportAuth::Data &d, const QString &r //get cmdline from proc/pid/cmdline snprintf( cmdlinePath, BUF_SIZE, "/proc/%d/cmdline", d.processId ); - int cmdlineFd = open( cmdlinePath, O_RDONLY ); + int cmdlineFd = QT_OPEN( cmdlinePath, O_RDONLY ); if ( cmdlineFd == -1 ) { qWarning( "SXE:- Error encountered in opening /proc/%u/cmdline: %s", @@ -581,13 +582,13 @@ bool QTransportAuth::authorizeRequest( QTransportAuth::Data &d, const QString &r } else { - if ( -1 == ::read(cmdlineFd, cmdline, BUF_SIZE - 1 ) ) + if ( -1 == QT_READ(cmdlineFd, cmdline, BUF_SIZE - 1 ) ) { qWarning( "SXE:- Error encountered in reading /proc/%u/cmdline : %s", d.processId, strerror(errno) ); snprintf( cmdline, BUF_SIZE, "%s", "Unknown" ); } - close( cmdlineFd ); + QT_CLOSE( cmdlineFd ); } syslog( LOG_ERR | LOG_LOCAL6, "%s // PID:%u // ProgId:%u // Exe:%s // Request:%s // Cmdline:%s", diff --git a/src/gui/embedded/qunixsocket.cpp b/src/gui/embedded/qunixsocket.cpp index 070d3cf..57a4a11 100644 --- a/src/gui/embedded/qunixsocket.cpp +++ b/src/gui/embedded/qunixsocket.cpp @@ -46,6 +46,7 @@ #include #include #include +#include "private/qcore_unix_p.h" // overrides QT_OPEN #ifdef QUNIXSOCKET_DEBUG #include @@ -131,7 +132,7 @@ struct QUnixSocketRightsPrivate : public QSharedData #ifdef QUNIXSOCKET_DEBUG int closerv = #endif - ::close(fd); + QT_CLOSE(fd); #ifdef QUNIXSOCKET_DEBUG if(0 != closerv) { qDebug() << "QUnixSocketRightsPrivate: Unable to close managed" @@ -162,7 +163,7 @@ QUnixSocketRights::QUnixSocketRights(int fd) if(-1 == fd) { d->fd = -1; } else { - d->fd = ::dup(fd); + d->fd = qt_safe_dup(fd); #ifdef QUNIXSOCKET_DEBUG if(-1 == d->fd) { qDebug() << "QUnixSocketRights: Unable to duplicate fd " @@ -232,7 +233,7 @@ int QUnixSocketRights::dupFd() const { if(-1 == d->fd) return -1; - int rv = ::dup(d->fd); + int rv = qt_safe_dup(d->fd); #ifdef QUNIXSOCKET_DEBUG if(-1 == rv) @@ -825,7 +826,7 @@ public: int numFds = (h->cmsg_len - CMSG_LEN(0)) / sizeof(int); for(int ii = 0; ii < numFds; ++ii) - ::close(fds[ii]); + QT_CLOSE(fds[ii]); } h = (::cmsghdr *)CMSG_NXTHDR(&(message), h); @@ -1017,7 +1018,7 @@ connect_error: // Cleanup failed connection #ifdef QUNIXSOCKET_DEBUG int closerv = #endif - ::close(d->fd); + QT_CLOSE(d->fd); #ifdef QUNIXSOCKET_DEBUG if(0 != closerv) { qDebug() << "QUnixSocket: Unable to close file descriptor after " @@ -1762,7 +1763,12 @@ void QUnixSocketPrivate::readActivated() message.msg_controllen = ancillaryBufferCapacity(); message.msg_control = ancillaryBuffer; - int recvrv = ::recvmsg(fd, &message, 0); + int flags = 0; +#ifdef MSG_CMSG_CLOEXEC + flags = MSG_CMSG_CLOEXEC; +#endif + + int recvrv = ::recvmsg(fd, &message, flags); #ifdef QUNIXSOCKET_DEBUG qDebug() << "QUnixSocket: Received message (" << recvrv << ')'; #endif diff --git a/src/gui/text/qfontdatabase_qws.cpp b/src/gui/text/qfontdatabase_qws.cpp index 2c359ba..d348e1b 100644 --- a/src/gui/text/qfontdatabase_qws.cpp +++ b/src/gui/text/qfontdatabase_qws.cpp @@ -55,6 +55,7 @@ #endif #include "qfontengine_qpf_p.h" #include "private/qfactoryloader_p.h" +#include "private/qcore_unix_p.h" // overrides QT_OPEN #include "qabstractfontengine_qws.h" #include "qabstractfontengine_p.h" #include @@ -128,7 +129,7 @@ void QFontDatabasePrivate::addQPF2File(const QByteArray &file) struct stat st; if (stat(file.constData(), &st)) return; - int f = ::open(file, O_RDONLY, 0); + int f = QT_OPEN(file, O_RDONLY, 0); if (f < 0) return; const uchar *data = (const uchar *)mmap(0, st.st_size, PROT_READ, MAP_SHARED, f, 0); @@ -176,7 +177,7 @@ void QFontDatabasePrivate::addQPF2File(const QByteArray &file) #endif } #ifndef QT_FONTS_ARE_RESOURCES - ::close(f); + QT_CLOSE(f); #endif } #endif diff --git a/src/gui/text/qfontengine_qpf.cpp b/src/gui/text/qfontengine_qpf.cpp index 2df4095..b255694 100644 --- a/src/gui/text/qfontengine_qpf.cpp +++ b/src/gui/text/qfontengine_qpf.cpp @@ -51,6 +51,7 @@ #if !defined(QT_NO_FREETYPE) #include "private/qfontengine_ft_p.h" #endif +#include "private/qcore_unix_p.h" // overrides QT_OPEN // for mmap #include @@ -252,7 +253,7 @@ QList QFontEngineQPF::cleanUpAfterClientCrash(const QList &cras for (int i = 0; i < int(dir.count()); ++i) { const QByteArray fileName = QFile::encodeName(dir.absoluteFilePath(dir[i])); - int fd = ::open(fileName.constData(), O_RDONLY, 0); + int fd = QT_OPEN(fileName.constData(), O_RDONLY, 0); if (fd >= 0) { void *header = ::mmap(0, sizeof(QFontEngineQPF::Header), PROT_READ, MAP_SHARED, fd, 0); if (header && header != MAP_FAILED) { @@ -265,7 +266,7 @@ QList QFontEngineQPF::cleanUpAfterClientCrash(const QList &cras ::munmap(header, sizeof(QFontEngineQPF::Header)); } - ::close(fd); + QT_CLOSE(fd); } } if (!removedFonts.isEmpty()) @@ -331,15 +332,15 @@ QFontEngineQPF::QFontEngineQPF(const QFontDef &def, int fileDescriptor, QFontEng qDebug() << "found existing qpf:" << fileName; #endif if (::access(encodedName, W_OK | R_OK) == 0) - fd = ::open(encodedName, O_RDWR, 0); + fd = QT_OPEN(encodedName, O_RDWR, 0); else if (::access(encodedName, R_OK) == 0) - fd = ::open(encodedName, O_RDONLY, 0); + fd = QT_OPEN(encodedName, O_RDONLY, 0); } else { #if defined(DEBUG_FONTENGINE) qDebug() << "creating qpf on the fly:" << fileName; #endif if (::access(QFile::encodeName(qws_fontCacheDir()), W_OK) == 0) { - fd = ::open(encodedName, O_RDWR | O_EXCL | O_CREAT, 0644); + fd = QT_OPEN(encodedName, O_RDWR | O_EXCL | O_CREAT, 0644); QBuffer buffer; buffer.open(QIODevice::ReadWrite); diff --git a/src/gui/text/qfontengine_qws.cpp b/src/gui/text/qfontengine_qws.cpp index 6fb4f15..70ce8f9 100644 --- a/src/gui/text/qfontengine_qws.cpp +++ b/src/gui/text/qfontengine_qws.cpp @@ -47,6 +47,7 @@ #include #include #include "qtextengine_p.h" +#include "private/qcore_unix_p.h" // overrides QT_OPEN #include @@ -387,7 +388,7 @@ QFontEngineQPF1::QFontEngineQPF1(const QFontDef&, const QString &fn) { cache_cost = 1; - int f = ::open( QFile::encodeName(fn), O_RDONLY, 0); + int f = QT_OPEN( QFile::encodeName(fn), O_RDONLY, 0); Q_ASSERT(f>=0); QT_STATBUF st; if ( QT_FSTAT( f, &st ) ) @@ -406,7 +407,7 @@ QFontEngineQPF1::QFontEngineQPF1(const QFontDef&, const QString &fn) #endif if ( !data || data == (uchar*)MAP_FAILED ) qFatal("Failed to mmap %s",QFile::encodeName(fn).data()); - ::close(f); + QT_CLOSE(f); d = new QFontEngineQPF1Data; memcpy(reinterpret_cast(&d->fm),data,sizeof(d->fm)); -- cgit v0.12 From d7d0d20469d447933c827d169651c3751c7069ad Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 23 Apr 2009 20:07:34 +0200 Subject: Add the support for the EINTR- and CLOEXEC-safe network calls too. The SOCK_NONBLOCK, SOCK_CLOEXEC and accept4(2) calls are Linux-specific. Other platforms get the same behaviour through emulation. Reviewed-By: ossi --- src/network/socket/qnet_unix_p.h | 153 +++++++++++++++++++++++++++++++++++++++ src/network/socket/socket.pri | 3 +- 2 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 src/network/socket/qnet_unix_p.h diff --git a/src/network/socket/qnet_unix_p.h b/src/network/socket/qnet_unix_p.h new file mode 100644 index 0000000..5256131 --- /dev/null +++ b/src/network/socket/qnet_unix_p.h @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtNetwork 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 qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QNET_UNIX_P_H +#define QNET_UNIX_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of Qt code on Unix. This header file may change from version to +// version to version without notice, or even be removed. +// +// We mean it. +// + +#include "private/qcore_unix_p.h" + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +// Almost always the same. If not, specify in qplatformdefs.h. +#if !defined(QT_SOCKOPTLEN_T) +# define QT_SOCKOPTLEN_T QT_SOCKLEN_T +#endif + +// UnixWare 7 redefines socket -> _socket +static inline int qt_safe_socket(int domain, int type, int protocol, int flags = 0) +{ + Q_ASSERT((flags & ~O_NONBLOCK) == 0); + + register int fd; +#ifdef SOCK_CLOEXEC + int newtype = type | SOCK_CLOEXEC; + if (flags & O_NONBLOCK) + newtype |= SOCK_NONBLOCK; + fd = ::socket(domain, newtype, protocol); + if (fd != -1 || errno != EINVAL) + return fd; +#endif + + fd = ::socket(domain, type, protocol); + if (fd == -1) + return -1; + + ::fcntl(fd, F_SETFD, FD_CLOEXEC); + + // set non-block too? + if (flags & O_NONBLOCK) + ::fcntl(fd, F_SETFL, ::fcntl(fd, F_GETFL) | O_NONBLOCK); + + return fd; +} + +// Tru64 redefines accept -> _accept with _XOPEN_SOURCE_EXTENDED +static inline int qt_safe_accept(int s, struct sockaddr *addr, QT_SOCKLEN_T *addrlen, int flags = 0) +{ + Q_ASSERT((flags & ~O_NONBLOCK) == 0); + + register int fd; +#if 0 // no released version of glibc contains accept4 yet + // use accept4 + int sockflags = SOCK_CLOEXEC; + if (flags & O_NONBLOCK) + sockflags |= SOCK_NONBLOCK; + fd = ::accept4(s, addr, static_cast(addrlen), sockflags); + if (fd != -1 || !(errno == ENOSYS || errno == EINVAL)) + return fd; +#endif + + fd = ::accept(s, addr, static_cast(addrlen)); + if (fd == -1) + return -1; + + ::fcntl(fd, F_SETFD, FD_CLOEXEC); + + // set non-block too? + if (flags & O_NONBLOCK) + ::fcntl(fd, F_SETFL, ::fcntl(fd, F_GETFL) | O_NONBLOCK); + + return fd; +} + +// UnixWare 7 redefines listen -> _listen +static inline int qt_safe_listen(int s, int backlog) +{ + return ::listen(s, backlog); +} + +static inline int qt_safe_connect(int sockfd, const struct sockaddr *addr, QT_SOCKLEN_T addrlen) +{ + register int ret; + EINTR_LOOP(ret, QT_SOCKET_CONNECT(sockfd, addr, addrlen)); + return ret; +} +#undef QT_SOCKET_CONNECT +#define QT_SOCKET_CONNECT qt_safe_connect + +#if defined(socket) +# undef socket +#endif +#if defined(accept) +# undef accept +#endif +#if defined(listen) +# undef listen +#endif + +QT_END_NAMESPACE + +#endif // QNET_UNIX_P_H diff --git a/src/network/socket/socket.pri b/src/network/socket/socket.pri index b1fe64a..17e49d2 100644 --- a/src/network/socket/socket.pri +++ b/src/network/socket/socket.pri @@ -28,7 +28,8 @@ SOURCES += socket/qabstractsocketengine.cpp \ unix:SOURCES += socket/qnativesocketengine_unix.cpp \ socket/qlocalsocket_unix.cpp \ socket/qlocalserver_unix.cpp - +unix:HEADERS += \ + socket/qnet_unix_p.h win32:SOURCES += socket/qnativesocketengine_win.cpp \ socket/qlocalsocket_win.cpp \ -- cgit v0.12 From 0b757d0c1b6f64d17086621ec692369d37fd62fc Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 23 Apr 2009 20:07:47 +0200 Subject: Use the safe versions of the network system calls I have just added. Reviewed-By: ossi --- src/corelib/kernel/qcore_unix.cpp | 63 +++++++++++++++++++++++++ src/corelib/kernel/qcore_unix_p.h | 13 ++++- src/network/socket/qlocalserver_unix.cpp | 9 ++-- src/network/socket/qlocalsocket_p.h | 37 --------------- src/network/socket/qlocalsocket_unix.cpp | 5 +- src/network/socket/qnativesocketengine_unix.cpp | 8 ++-- src/network/socket/qnet_unix_p.h | 2 +- 7 files changed, 88 insertions(+), 49 deletions(-) diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp index ffaf958..2549f77 100644 --- a/src/corelib/kernel/qcore_unix.cpp +++ b/src/corelib/kernel/qcore_unix.cpp @@ -119,3 +119,66 @@ int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, } QT_END_NAMESPACE + +#ifdef Q_OS_LINUX +// Don't wait for libc to supply the calls we need +// Make syscalls directly + +# if defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0204 +// glibc 2.4 has syscall(...) +# include +# include +# else +// no syscall(...) +static inline int syscall(...) { errno = ENOSYS; return -1;} +# endif + +# ifndef __NR_dup3 +# if defined(__i386__) +# define __NR_dup3 330 +# define __NR_pipe2 331 +# elif defined(__x86_64__) +# define __NR_accept4 288 +# define __NR_dup3 292 +# define __NR_pipe2 293 +# elif defined(__ia64__) +# define __NR_accept4 -1 +# define __NR_dup3 1316 +# define __NR_pipe2 1317 +# else +// set the syscalls to absurd numbers so that they'll cause ENOSYS errors +# warning "Please port the pipe2/dup3/accept4 code to this platform" +# define __NR_accept4 -1 +# define __NR_dup3 -1 +# define __NR_pipe2 -1 +# endif +# endif + +QT_BEGIN_NAMESPACE +namespace QtLibcSupplement { + int pipe2(int pipes[], int flags) + { + return syscall(__NR_pipe2, pipes, flags); + } + + int dup3(int oldfd, int newfd, int flags) + { + return syscall(__NR_dup3, oldfd, newfd, flags); + } + + int accept4(int s, sockaddr *addr, QT_SOCKLEN_T *addrlen, int flags) + { +# if defined(__NR_socketcall) + // This platform uses socketcall() instead of raw syscalls + // the SYS_ACCEPT4 number is cross-platform: 18 + return syscall(__NR_socketcall, 18, &s); +# else + return syscall(__NR_accept4, s, addr, addrlen, flags); +# endif + + Q_UNUSED(addr); Q_UNUSED(addrlen); Q_UNUSED(flags); // they're actually used + } +} +QT_END_NAMESPACE +#endif // Q_OS_LINUX + diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index 4e3158a..6ae4ff0 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -67,10 +67,21 @@ #include #include +struct sockaddr; + QT_BEGIN_NAMESPACE -#if defined(Q_OS_LINUX) && defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0209 +#if defined(Q_OS_LINUX) && defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0204 +// Linux supports thread-safe FD_CLOEXEC # define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 1 + +namespace QtLibcSupplement { + Q_CORE_EXPORT int accept4(int, sockaddr *, QT_SOCKLEN_T *, int flags); + Q_CORE_EXPORT int dup3(int oldfd, int newfd, int flags); + Q_CORE_EXPORT int pipe2(int pipes[], int flags); +} + +using namespace QtLibcSupplement; #else # define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 0 #endif diff --git a/src/network/socket/qlocalserver_unix.cpp b/src/network/socket/qlocalserver_unix.cpp index 1cb804a..c2e05cd 100644 --- a/src/network/socket/qlocalserver_unix.cpp +++ b/src/network/socket/qlocalserver_unix.cpp @@ -43,6 +43,7 @@ #include "qlocalserver_p.h" #include "qlocalsocket.h" #include "qlocalsocket_p.h" +#include "qnet_unix_p.h" #ifndef QT_NO_LOCALSERVER @@ -88,7 +89,7 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName) serverName = requestedServerName; // create the unix socket - listenSocket = qSocket(PF_UNIX, SOCK_STREAM, 0); + listenSocket = qt_safe_socket(PF_UNIX, SOCK_STREAM, 0); if (-1 == listenSocket) { setError(QLatin1String("QLocalServer::listen")); closeServer(); @@ -107,7 +108,7 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName) fullServerName.toLatin1().size() + 1); // bind - if(-1 == qBind(listenSocket, (sockaddr *)&addr, sizeof(sockaddr_un))) { + if(-1 == QT_SOCKET_BIND(listenSocket, (sockaddr *)&addr, sizeof(sockaddr_un))) { setError(QLatin1String("QLocalServer::listen")); // if address is in use already, just close the socket, but do not delete the file if(errno == EADDRINUSE) @@ -120,7 +121,7 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName) } // listen for connections - if (-1 == qListen(listenSocket, 50)) { + if (-1 == qt_safe_listen(listenSocket, 50)) { setError(QLatin1String("QLocalServer::listen")); closeServer(); listenSocket = -1; @@ -172,7 +173,7 @@ void QLocalServerPrivate::_q_onNewConnection() ::sockaddr_un addr; QT_SOCKLEN_T length = sizeof(sockaddr_un); - int connectedSocket = qAccept(listenSocket, (sockaddr *)&addr, &length); + int connectedSocket = qt_safe_accept(listenSocket, (sockaddr *)&addr, &length); if(-1 == connectedSocket) { setError(QLatin1String("QLocalSocket::activated")); closeServer(); diff --git a/src/network/socket/qlocalsocket_p.h b/src/network/socket/qlocalsocket_p.h index 24b5dd6..bdbba42 100644 --- a/src/network/socket/qlocalsocket_p.h +++ b/src/network/socket/qlocalsocket_p.h @@ -74,43 +74,6 @@ QT_BEGIN_NAMESPACE -#if !defined(Q_OS_WIN) && !defined(QT_LOCALSOCKET_TCP) -static inline int qSocket(int af, int socketype, int proto) -{ - int ret; - while((ret = qt_socket_socket(af, socketype, proto)) == -1 && errno == EINTR){} - return ret; -} - -static inline int qBind(int fd, const sockaddr *sa, int len) -{ - int ret; - while((ret = QT_SOCKET_BIND(fd, (sockaddr*)sa, len)) == -1 && errno == EINTR){} - return ret; -} - -static inline int qConnect(int fd, const sockaddr *sa, int len) -{ - int ret; - while((ret = QT_SOCKET_CONNECT(fd, (sockaddr*)sa, len)) == -1 && errno == EINTR){} - return ret; -} - -static inline int qListen(int fd, int backlog) -{ - int ret; - while((ret = qt_socket_listen(fd, backlog)) == -1 && errno == EINTR){} - return ret; -} - -static inline int qAccept(int fd, struct sockaddr *addr, QT_SOCKLEN_T *addrlen) -{ - int ret; - while((ret = qt_socket_accept(fd, addr, addrlen)) == -1 && errno == EINTR){} - return ret; -} -#endif //#if !defined(Q_OS_WIN) && !defined(QT_LOCALSOCKET_TCP) - #if !defined(Q_OS_WIN) || defined(QT_LOCALSOCKET_TCP) class QLocalUnixSocket : public QTcpSocket { diff --git a/src/network/socket/qlocalsocket_unix.cpp b/src/network/socket/qlocalsocket_unix.cpp index 41dac3c..d038794 100644 --- a/src/network/socket/qlocalsocket_unix.cpp +++ b/src/network/socket/qlocalsocket_unix.cpp @@ -41,6 +41,7 @@ #include "qlocalsocket.h" #include "qlocalsocket_p.h" +#include "qnet_unix_p.h" #ifndef QT_NO_LOCALSOCKET @@ -232,7 +233,7 @@ void QLocalSocket::connectToServer(const QString &name, OpenMode openMode) } // create the socket - if (-1 == (d->connectingSocket = qSocket(PF_UNIX, SOCK_STREAM, 0))) { + if (-1 == (d->connectingSocket = qt_safe_socket(PF_UNIX, SOCK_STREAM, 0))) { d->errorOccurred(UnsupportedSocketOperationError, QLatin1String("QLocalSocket::connectToServer")); return; @@ -282,7 +283,7 @@ void QLocalSocketPrivate::_q_connectToSocket() } ::memcpy(name.sun_path, connectingPathName.toLatin1().data(), connectingPathName.toLatin1().size() + 1); - if (-1 == qConnect(connectingSocket, (struct sockaddr *)&name, sizeof(name))) { + if (-1 == qt_safe_connect(connectingSocket, (struct sockaddr *)&name, sizeof(name))) { QString function = QLatin1String("QLocalSocket::connectToServer"); switch (errno) { diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 6eafe05..0c1fa19 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -42,7 +42,7 @@ //#define QNATIVESOCKETENGINE_DEBUG #include "qnativesocketengine_p.h" -#include "private/qcore_unix_p.h" +#include "private/qnet_unix_p.h" #include "qiodevice.h" #include "qhostaddress.h" #include "qvarlengtharray.h" @@ -162,7 +162,7 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc int protocol = AF_INET; #endif int type = (socketType == QAbstractSocket::UdpSocket) ? SOCK_DGRAM : SOCK_STREAM; - int socket = qt_socket_socket(protocol, type, 0); + int socket = qt_safe_socket(protocol, type, 0); if (socket <= 0) { switch (errno) { @@ -467,7 +467,7 @@ bool QNativeSocketEnginePrivate::nativeBind(const QHostAddress &address, quint16 bool QNativeSocketEnginePrivate::nativeListen(int backlog) { - if (qt_socket_listen(socketDescriptor, backlog) < 0) { + if (qt_safe_listen(socketDescriptor, backlog) < 0) { switch (errno) { case EADDRINUSE: setError(QAbstractSocket::AddressInUseError, @@ -494,7 +494,7 @@ bool QNativeSocketEnginePrivate::nativeListen(int backlog) int QNativeSocketEnginePrivate::nativeAccept() { - int acceptedDescriptor = qt_socket_accept(socketDescriptor, 0, 0); + int acceptedDescriptor = qt_safe_accept(socketDescriptor, 0, 0); #if defined (QNATIVESOCKETENGINE_DEBUG) qDebug("QNativeSocketEnginePrivate::nativeAccept() == %i", acceptedDescriptor); #endif diff --git a/src/network/socket/qnet_unix_p.h b/src/network/socket/qnet_unix_p.h index 5256131..80a4c58 100644 --- a/src/network/socket/qnet_unix_p.h +++ b/src/network/socket/qnet_unix_p.h @@ -100,7 +100,7 @@ static inline int qt_safe_accept(int s, struct sockaddr *addr, QT_SOCKLEN_T *add Q_ASSERT((flags & ~O_NONBLOCK) == 0); register int fd; -#if 0 // no released version of glibc contains accept4 yet +#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC // use accept4 int sockflags = SOCK_CLOEXEC; if (flags & O_NONBLOCK) -- cgit v0.12 From a32019f4c2f56a84172bde739d7ea174be0db381 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 25 Jun 2009 17:22:53 +0200 Subject: Add qobject_cast for QSharedPointer. This obviously only works for classes that derive from QObject. And you must remember that QSharedPointer controls the QObject's lifetime, not the QObject parent-child relationship. Reviewed-by: dt Reviewed-by: Bradley T. Hughes --- src/corelib/tools/qsharedpointer.cpp | 56 +++++++++++ src/corelib/tools/qsharedpointer.h | 3 + src/corelib/tools/qsharedpointer_impl.h | 51 ++++++++++ tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 123 +++++++++++++++++++++++ 4 files changed, 233 insertions(+) diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index ba62ce1..71bf318 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -340,6 +340,23 @@ */ /*! + \fn QSharedPointer QSharedPointer::objectCast() const + + Performs a \ref qobject_cast from this pointer's type to \tt X and + returns a QSharedPointer that shares the reference. If this + function is used to up-cast, then QSharedPointer will perform a \tt + qobject_cast, which means that if the object being pointed by this + QSharedPointer is not of type \tt X, the returned object will be + null. + + Note: the template type \c X must have the same const and volatile + qualifiers as the template of this object, or the cast will + fail. Use constCast() if you need to drop those qualifiers. + + \sa qSharedPointerObjectCast() +*/ + +/*! \fn QWeakPointer QSharedPointer::toWeakRef() const Returns a weak reference object that shares the pointer referenced @@ -718,6 +735,45 @@ */ /*! + \fn QSharedPointer qSharedPointerObjectCast(const QSharedPointer &other) + \relates QSharedPointer + + Returns a shared pointer to the pointer held by \a other, using a + \ref qobject_cast to type \tt X to obtain an internal pointer of the + appropriate type. If the \tt qobject_cast fails, the object + returned will be null. + + Note that \tt X must have the same cv-qualifiers (\tt const and + \tt volatile) that \tt T has, or the code will fail to + compile. Use qSharedPointerConstCast to cast away the constness. + + \sa QSharedPointer::objectCast(), qSharedPointerCast(), qSharedPointerConstCast() +*/ + +/*! + \fn QSharedPointer qSharedPointerObjectCast(const QWeakPointer &other) + \relates QSharedPointer + \relates QWeakPointer + + Returns a shared pointer to the pointer held by \a other, using a + \ref qobject_cast to type \tt X to obtain an internal pointer of the + appropriate type. If the \tt qobject_cast fails, the object + returned will be null. + + The \a other object is converted first to a strong reference. If + that conversion fails (because the object it's pointing to has + already been deleted), this function also returns a null + QSharedPointer. + + Note that \tt X must have the same cv-qualifiers (\tt const and + \tt volatile) that \tt T has, or the code will fail to + compile. Use qSharedPointerConstCast to cast away the constness. + + \sa QWeakPointer::toStrongRef(), qSharedPointerCast(), qSharedPointerConstCast() +*/ + + +/*! \fn QWeakPointer qWeakPointerCast(const QWeakPointer &other) \relates QWeakPointer diff --git a/src/corelib/tools/qsharedpointer.h b/src/corelib/tools/qsharedpointer.h index cd6bc62..abd83ad 100644 --- a/src/corelib/tools/qsharedpointer.h +++ b/src/corelib/tools/qsharedpointer.h @@ -93,6 +93,7 @@ public: template QSharedPointer staticCast() const; template QSharedPointer dynamicCast() const; template QSharedPointer constCast() const; + template QSharedPointer objectCast() const; }; template @@ -136,6 +137,8 @@ template QSharedPointer qSharedPointerDynamicCast(const QS template QSharedPointer qSharedPointerDynamicCast(const QWeakPointer &src); template QSharedPointer qSharedPointerConstCast(const QSharedPointer &src); template QSharedPointer qSharedPointerConstCast(const QWeakPointer &src); +template QSharedPointer qSharedPointerObjectCast(const QSharedPointer &src); +template QSharedPointer qSharedPointerObjectCast(const QWeakPointer &src); template QWeakPointer qWeakPointerCast(const QWeakPointer &src); diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 2797622..df31fec 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -49,6 +49,7 @@ #endif #include +#include // for qobject_cast QT_BEGIN_HEADER @@ -83,6 +84,11 @@ QSharedPointer qSharedPointerDynamicCast(const QSharedPointer &ptr); template QSharedPointer qSharedPointerConstCast(const QSharedPointer &ptr); +#ifndef QT_NO_QOBJECT +template +QSharedPointer qSharedPointerObjectCast(const QSharedPointer &ptr); +#endif + namespace QtSharedPointer { template class InternalRefCount; template class ExternalRefCount; @@ -330,6 +336,14 @@ public: return qSharedPointerConstCast(*this); } +#ifndef QT_NO_QOBJECT + template + QSharedPointer objectCast() const + { + return qSharedPointerObjectCast(*this); + } +#endif + inline void clear() { *this = QSharedPointer(); } QWeakPointer toWeakRef() const; @@ -545,6 +559,43 @@ QWeakPointer qWeakPointerCast(const QSharedPointer &src) return qSharedPointerCast(src).toWeakRef(); } +#ifndef QT_NO_QOBJECT +template +Q_INLINE_TEMPLATE QSharedPointer qSharedPointerObjectCast(const QSharedPointer &src) +{ + register X *ptr = qobject_cast(src.data()); + return QtSharedPointer::copyAndSetPointer(ptr, src); +} +template +Q_INLINE_TEMPLATE QSharedPointer qSharedPointerObjectCast(const QWeakPointer &src) +{ + return qSharedPointerObjectCast(src.toStrongRef()); +} + +# ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION +namespace QtSharedPointer { + template struct RemovePointer; + template struct RemovePointer { typedef T Type; }; + template struct RemovePointer > { typedef T Type; }; + template struct RemovePointer > { typedef T Type; }; +} + +template +inline QSharedPointer::Type> +qobject_cast(const QSharedPointer &src) +{ + return qSharedPointerObjectCast::Type, T>(src); +} +template +inline QSharedPointer::Type> +qobject_cast(const QWeakPointer &src) +{ + return qSharedPointerObjectCast::Type, T>(src); +} +# endif + +#endif + QT_END_NAMESPACE QT_END_HEADER diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index db93fc9..57ebdce 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -56,6 +56,7 @@ private slots: void memoryManagement(); void downCast(); void upCast(); + void objectCast(); void differentPointers(); void virtualBaseDifferentPointers(); #ifndef QTEST_NO_RTTI @@ -424,6 +425,109 @@ void tst_QSharedPointer::upCast() QCOMPARE(int(baseptr.d->strongref), 1); } +class OtherObject: public QObject +{ + Q_OBJECT +}; + +void tst_QSharedPointer::objectCast() +{ + { + OtherObject *data = new OtherObject; + QSharedPointer baseptr = QSharedPointer(data); + QVERIFY(baseptr == data); + QVERIFY(data == baseptr); + + // perform object cast + QSharedPointer ptr = qSharedPointerObjectCast(baseptr); + QVERIFY(!ptr.isNull()); + QCOMPARE(ptr.data(), data); + QVERIFY(ptr == data); + + // again: + ptr = baseptr.objectCast(); + QVERIFY(ptr == data); + +#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION + // again: + ptr = qobject_cast(baseptr); + QVERIFY(ptr == data); + + // again: + ptr = qobject_cast >(baseptr); + QVERIFY(ptr == data); +#endif + } + + { + const OtherObject *data = new OtherObject; + QSharedPointer baseptr = QSharedPointer(data); + QVERIFY(baseptr == data); + QVERIFY(data == baseptr); + + // perform object cast + QSharedPointer ptr = qSharedPointerObjectCast(baseptr); + QVERIFY(!ptr.isNull()); + QCOMPARE(ptr.data(), data); + QVERIFY(ptr == data); + + // again: + ptr = baseptr.objectCast(); + QVERIFY(ptr == data); + +#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION + // again: + ptr = qobject_cast(baseptr); + QVERIFY(ptr == data); + + // again: + ptr = qobject_cast >(baseptr); + QVERIFY(ptr == data); +#endif + } + + { + OtherObject *data = new OtherObject; + QPointer qptr = data; + QSharedPointer ptr = QSharedPointer(data); + QWeakPointer weakptr = ptr; + + { + // perform object cast + QSharedPointer otherptr = qSharedPointerObjectCast(weakptr); + QVERIFY(otherptr == ptr); + + // again: + otherptr = qobject_cast(weakptr); + QVERIFY(otherptr == ptr); + + // again: + otherptr = qobject_cast >(weakptr); + QVERIFY(otherptr == ptr); + } + + // drop the reference: + ptr.clear(); + QVERIFY(ptr.isNull()); + QVERIFY(qptr.isNull()); + QVERIFY(weakptr.toStrongRef().isNull()); + + // verify that the object casts fail without crash + QSharedPointer otherptr = qSharedPointerObjectCast(weakptr); + QVERIFY(otherptr.isNull()); + +#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION + // again: + otherptr = qobject_cast(weakptr); + QVERIFY(otherptr.isNull()); + + // again: + otherptr = qobject_cast >(weakptr); + QVERIFY(otherptr.isNull()); +#endif + } +} + void tst_QSharedPointer::differentPointers() { { @@ -939,6 +1043,20 @@ void tst_QSharedPointer::invalidConstructs_data() << "QSharedPointer baseptr = QSharedPointer(new Data);\n" "QSharedPointer ptr;" "ptr = baseptr;"; + QTest::newRow("const-dropping-static-cast") + << &QTest::QExternalTest::tryCompileFail + << "QSharedPointer baseptr = QSharedPointer(new Data);\n" + "qSharedPointerCast(baseptr);"; +#ifndef QTEST_NO_RTTI + QTest::newRow("const-dropping-dynamic-cast") + << &QTest::QExternalTest::tryCompileFail + << "QSharedPointer baseptr = QSharedPointer(new Data);\n" + "qSharedPointerDynamicCast(baseptr);"; +#endif + QTest::newRow("const-dropping-object-cast") + << &QTest::QExternalTest::tryCompileFail + << "QSharedPointer baseptr = QSharedPointer(new QObject);\n" + "qSharedPointerObjectCast(baseptr);"; // arithmethics through automatic cast operators QTest::newRow("arithmethic1") @@ -982,6 +1100,10 @@ void tst_QSharedPointer::invalidConstructs_data() << &QTest::QExternalTest::tryCompileFail << "QSharedPointer ptr1;\n" "QSharedPointer ptr2 = qSharedPointerConstCast(ptr1);"; + QTest::newRow("invalid-cast4") + << &QTest::QExternalTest::tryCompileFail + << "QSharedPointer ptr1;\n" + "QSharedPointer ptr2 = qSharedPointerObjectCast(ptr1);"; } void tst_QSharedPointer::invalidConstructs() @@ -999,6 +1121,7 @@ void tst_QSharedPointer::invalidConstructs() test.setProgramHeader( "#define QT_SHAREDPOINTER_TRACK_POINTERS\n" "#include \n" + "#include \n" "\n" "struct Data { int i; };\n" "struct DerivedData: public Data { int j; };\n" -- cgit v0.12 From fb51a10ee0451274a430227566ae26efb2ac4474 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 25 Jun 2009 20:52:36 +0200 Subject: Add support for creating the object alongside the Data structure in one go. This avoids one memory allocation. Currently, we only support calling the default constructors. I will *NOT* implement argument passing for C++03. I will implement it with rvalue references for C++0x-capable compilers. --- src/corelib/tools/qsharedpointer_impl.h | 47 +++++++++++ tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 102 ++++++++++++++++++++++- 2 files changed, 147 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index df31fec..cb78f29 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -48,6 +48,7 @@ #pragma qt_sync_stop_processing #endif +#include #include #include // for qobject_cast @@ -190,6 +191,34 @@ namespace QtSharedPointer { }; template + struct ExternalRefCountWithContiguousData: public ExternalRefCountData + { +#ifdef Q_DECL_ALIGN +# ifdef Q_ALIGNOF +# define QSP_ALIGNOF(T) Q_ALIGNOF(T) +# else +# define QSP_ALIGNOF(T) (sizeof(T) >= 16 ? 16 : sizeof(T) >= 8 ? 8 : sizeof(T) >= 4 ? 4 : sizeof(T) >= 2 ? 2 : 1) +# endif + + char data[sizeof(T)] Q_DECL_ALIGN(QSP_ALIGNOF(T)); + inline T *pointer() { return reinterpret_cast(data); } + +# undef QSP_ALIGNOF +#else + union { + char data[sizeof(T) + 16]; + double dummy1; +# ifndef Q_OS_DARWIN + long double dummy2; +# endif + }; + inline T *pointer() { return reinterpret_cast(data + 16 - (quintptr(data) & 0xf)); } +#endif + + inline bool destroy() { this->pointer()->~T(); return true; } + }; + + template class ExternalRefCount: public Basic { typedef ExternalRefCountData Data; @@ -220,6 +249,16 @@ namespace QtSharedPointer { d = new ExternalRefCountWithSpecializedDeleter(ptr, deleter); } + inline void internalCreate() + { + ExternalRefCountWithContiguousData *dd = new ExternalRefCountWithContiguousData; + T *ptr = dd->pointer(); + new (ptr) T(); // create + + Basic::internalConstruct(ptr); + d = dd; + } + inline ExternalRefCount() : d(0) { } inline ~ExternalRefCount() { if (d && !deref()) delete d; } inline ExternalRefCount(const ExternalRefCount &other) : Basic(other), d(other.d) @@ -347,6 +386,14 @@ public: inline void clear() { *this = QSharedPointer(); } QWeakPointer toWeakRef() const; + +public: + static QSharedPointer create() + { + QSharedPointer result; + result.internalCreate(); + return result; + } }; template diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index 57ebdce..d6321c7 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -65,8 +65,9 @@ private slots: void dynamicCastVirtualBase(); void dynamicCastFailure(); #endif - void customDeleter(); void constCorrectness(); + void customDeleter(); + void creating(); void validConstructs(); void invalidConstructs_data(); void invalidConstructs(); @@ -104,6 +105,8 @@ public: { delete this; } + + virtual int classLevel() { return 1; } }; int Data::generationCounter = 0; int Data::destructorCounter = 0; @@ -311,6 +314,8 @@ public: { delete this; } + + virtual int classLevel() { return 2; } }; int DerivedData::derivedDestructorCounter = 0; @@ -318,15 +323,23 @@ class Stuffing { public: char buffer[16]; + Stuffing() { for (uint i = 0; i < sizeof buffer; ++i) buffer[i] = 16 - i; } virtual ~Stuffing() { } }; class DiffPtrDerivedData: public Stuffing, public Data { +public: + virtual int classLevel() { return 3; } }; class VirtualDerived: virtual public Data { +public: + int moreData; + + VirtualDerived() : moreData(0xc0ffee) { } + virtual int classLevel() { return 4; } }; void tst_QSharedPointer::downCast() @@ -972,6 +985,82 @@ void tst_QSharedPointer::customDeleter() QCOMPARE(derivedDataDeleter.callCount, 1); } +void tst_QSharedPointer::creating() +{ + Data::generationCounter = Data::destructorCounter = 0; + { + QSharedPointer ptr = QSharedPointer::create(); + QVERIFY(ptr.data()); + QCOMPARE(Data::generationCounter, 1); + QCOMPARE(ptr->generation, 1); + QCOMPARE(Data::destructorCounter, 0); + + QCOMPARE(ptr->classLevel(), 1); + + ptr.clear(); + QCOMPARE(Data::destructorCounter, 1); + } + + Data::generationCounter = Data::destructorCounter = 0; + { + QSharedPointer ptr = QSharedPointer::create(); + QWeakPointer weakptr = ptr; + QtSharedPointer::ExternalRefCountData *d = ptr.d; + + ptr.clear(); + QVERIFY(ptr.isNull()); + QCOMPARE(Data::destructorCounter, 1); + + // valgrind will complain here if something happened to the pointer + QVERIFY(d->weakref == 1); + QVERIFY(d->strongref == 0); + } + + Data::generationCounter = Data::destructorCounter = 0; + DerivedData::derivedDestructorCounter = 0; + { + QSharedPointer ptr = QSharedPointer::create(); + QCOMPARE(ptr->classLevel(), 2); + QCOMPARE(ptr.staticCast()->moreData, 0); + ptr.clear(); + + QCOMPARE(Data::destructorCounter, 1); + QCOMPARE(DerivedData::derivedDestructorCounter, 1); + } + + { + QSharedPointer ptr = QSharedPointer::create(); + QCOMPARE(ptr->classLevel(), 3); + QCOMPARE(ptr.staticCast()->buffer[7]+0, 16-7); + QCOMPARE(ptr.staticCast()->buffer[3]+0, 16-3); + QCOMPARE(ptr.staticCast()->buffer[0]+0, 16); + } + + { + QSharedPointer ptr = QSharedPointer::create(); + QCOMPARE(ptr->classLevel(), 4); + QCOMPARE(ptr->moreData, 0xc0ffee); + + QSharedPointer baseptr = ptr; + QCOMPARE(baseptr->classLevel(), 4); + } + + { + QSharedPointer ptr = QSharedPointer::create(); + QCOMPARE(ptr->metaObject(), &QObject::staticMetaObject); + + QPointer qptr = ptr.data(); + ptr.clear(); + + QVERIFY(qptr.isNull()); + } + + { + QSharedPointer ptr = QSharedPointer::create(); + QCOMPARE(ptr->metaObject(), &OtherObject::staticMetaObject); + } +} + void tst_QSharedPointer::validConstructs() { { @@ -1021,6 +1110,9 @@ void tst_QSharedPointer::invalidConstructs_data() QTest::newRow("forward-declaration") << &QTest::QExternalTest::tryCompileFail << "QSharedPointer ptr;"; + QTest::newRow("creating-forward-declaration") + << &QTest::QExternalTest::tryCompileFail + << "QSharedPointer::create();"; // upcast without cast operator: QTest::newRow("upcast1") @@ -1053,10 +1145,16 @@ void tst_QSharedPointer::invalidConstructs_data() << "QSharedPointer baseptr = QSharedPointer(new Data);\n" "qSharedPointerDynamicCast(baseptr);"; #endif - QTest::newRow("const-dropping-object-cast") + QTest::newRow("const-dropping-object-cast1") << &QTest::QExternalTest::tryCompileFail << "QSharedPointer baseptr = QSharedPointer(new QObject);\n" "qSharedPointerObjectCast(baseptr);"; +#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION + QTest::newRow("const-dropping-object-cast2") + << &QTest::QExternalTest::tryCompileFail + << "QSharedPointer baseptr = QSharedPointer(new QObject);\n" + "qobject_cast(baseptr);"; +#endif // arithmethics through automatic cast operators QTest::newRow("arithmethic1") -- cgit v0.12 From 6f673e2cf55755a97aeb8971994ab9fc62fb794e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 25 Jun 2009 21:01:24 +0200 Subject: Experimental: allow QSharedPointer to be used with forward declarations that are declared in this file. The one-definition rule allows the forward declaration appearing below to apply to code that was earlier. Therefore, if the compiler finds out how to delete the object, we can allow a QSharedPointer of a forward- declared-type. This means the actual problem is just a warning with g++. To catch the error, we need a separate .cpp file and I'd rather run this as an external test. --- src/corelib/tools/qsharedpointer_impl.h | 2 +- tests/auto/qsharedpointer/externaltests.cpp | 20 ++++++++- tests/auto/qsharedpointer/externaltests.h | 4 ++ tests/auto/qsharedpointer/externaltests.pri | 1 + tests/auto/qsharedpointer/forwarddeclaration.cpp | 52 +++++++++++++++++++++++ tests/auto/qsharedpointer/forwarddeclared.cpp | 53 +++++++++++++++++++++++ tests/auto/qsharedpointer/forwarddeclared.h | 54 ++++++++++++++++++++++++ tests/auto/qsharedpointer/qsharedpointer.pro | 9 ++-- tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 42 +++++++++++++++--- 9 files changed, 224 insertions(+), 13 deletions(-) create mode 100644 tests/auto/qsharedpointer/forwarddeclaration.cpp create mode 100644 tests/auto/qsharedpointer/forwarddeclared.cpp create mode 100644 tests/auto/qsharedpointer/forwarddeclared.h diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index cb78f29..2fa9eb2 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -129,7 +129,7 @@ namespace QtSharedPointer { inline T *operator->() const { return data(); } protected: - inline Basic() : value(0 * sizeof(T)) { } + inline Basic() : value(0) { } // ~Basic(); inline void verifyReconstruction(const T *ptr) diff --git a/tests/auto/qsharedpointer/externaltests.cpp b/tests/auto/qsharedpointer/externaltests.cpp index 75ac5f1..8077b84 100644 --- a/tests/auto/qsharedpointer/externaltests.cpp +++ b/tests/auto/qsharedpointer/externaltests.cpp @@ -59,7 +59,7 @@ static QString makespec() { static const char default_makespec[] = DEFAULT_MAKESPEC; const char *p; - for (p = default_makespec + sizeof(default_makespec); p >= default_makespec; --p) + for (p = default_makespec + sizeof(default_makespec) - 1; p >= default_makespec; --p) if (*p == '/' || *p == '\\') break; @@ -122,6 +122,7 @@ namespace QTest { enum Target { Compile, Link, Run }; QList qmakeLines; + QStringList extraProgramSources; QByteArray programHeader; QExternalTest::QtModules qtModules; QExternalTest::ApplicationType appType; @@ -199,6 +200,16 @@ namespace QTest { d->appType = type; } + QStringList QExternalTest::extraProgramSources() const + { + return d->extraProgramSources; + } + + void QExternalTest::setExtraProgramSources(const QStringList &extra) + { + d->extraProgramSources = extra; + } + QByteArray QExternalTest::programHeader() const { return d->programHeader; @@ -483,6 +494,13 @@ namespace QTest { else projectFile.write("\nCONFIG += release\n"); + QByteArray extraSources = QFile::encodeName(extraProgramSources.join(" ")); + if (!extraSources.isEmpty()) { + projectFile.write("SOURCES += "); + projectFile.write(extraSources); + projectFile.putChar('\n'); + } + // Add Qt modules if (qtModules & QExternalTest::QtCore) projectFile.write("QT += core\n"); diff --git a/tests/auto/qsharedpointer/externaltests.h b/tests/auto/qsharedpointer/externaltests.h index 24a3236..ecc107e 100644 --- a/tests/auto/qsharedpointer/externaltests.h +++ b/tests/auto/qsharedpointer/externaltests.h @@ -45,6 +45,7 @@ #include #include +#include QT_BEGIN_NAMESPACE namespace QTest { @@ -102,6 +103,9 @@ namespace QTest { ApplicationType applicationType() const; void setApplicationType(ApplicationType type); + QStringList extraProgramSources() const; + void setExtraProgramSources(const QStringList &list); + QByteArray programHeader() const; void setProgramHeader(const QByteArray &header); diff --git a/tests/auto/qsharedpointer/externaltests.pri b/tests/auto/qsharedpointer/externaltests.pri index 717acac..1fdcf65 100644 --- a/tests/auto/qsharedpointer/externaltests.pri +++ b/tests/auto/qsharedpointer/externaltests.pri @@ -1,4 +1,5 @@ SOURCES += $$PWD/externaltests.cpp +HEADERS += $$PWD/externaltests.h cleanedQMAKESPEC = $$replace(QMAKESPEC, \\\\, /) DEFINES += DEFAULT_MAKESPEC=\\\"$$cleanedQMAKESPEC\\\" diff --git a/tests/auto/qsharedpointer/forwarddeclaration.cpp b/tests/auto/qsharedpointer/forwarddeclaration.cpp new file mode 100644 index 0000000..1dbbeec --- /dev/null +++ b/tests/auto/qsharedpointer/forwarddeclaration.cpp @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#define QT_SHAREDPOINTER_TRACK_POINTERS +#include "qsharedpointer.h" + +class ForwardDeclared; +ForwardDeclared *forwardPointer(); + +void externalForwardDeclaration() +{ + struct Wrapper { QSharedPointer pointer; }; +} + diff --git a/tests/auto/qsharedpointer/forwarddeclared.cpp b/tests/auto/qsharedpointer/forwarddeclared.cpp new file mode 100644 index 0000000..4ab467a --- /dev/null +++ b/tests/auto/qsharedpointer/forwarddeclared.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** 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 "forwarddeclared.h" + +ForwardDeclared *forwardPointer() +{ + return new ForwardDeclared; +} + +int forwardDeclaredDestructorRunCount; +ForwardDeclared::~ForwardDeclared() +{ + ++forwardDeclaredDestructorRunCount; +} diff --git a/tests/auto/qsharedpointer/forwarddeclared.h b/tests/auto/qsharedpointer/forwarddeclared.h new file mode 100644 index 0000000..a4cc2b4 --- /dev/null +++ b/tests/auto/qsharedpointer/forwarddeclared.h @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef FORWARDDECLARED_H +#define FORWARDDECLARED_H + +extern int forwardDeclaredDestructorRunCount; +class ForwardDeclared +{ +public: + ~ForwardDeclared(); +}; + +ForwardDeclared *forwardPointer(); + +#endif // FORWARDDECLARED_H diff --git a/tests/auto/qsharedpointer/qsharedpointer.pro b/tests/auto/qsharedpointer/qsharedpointer.pro index e329803..30c81cb 100644 --- a/tests/auto/qsharedpointer/qsharedpointer.pro +++ b/tests/auto/qsharedpointer/qsharedpointer.pro @@ -1,7 +1,8 @@ load(qttest_p4) - -SOURCES += tst_qsharedpointer.cpp +SOURCES += tst_qsharedpointer.cpp \ + forwarddeclaration.cpp \ + forwarddeclared.cpp QT = core -DEFINES += SRCDIR=\\\"$$PWD\\\" - +DEFINES += SRCDIR=\\\"$$PWD/\\\" include(externaltests.pri) +HEADERS += forwarddeclared.h diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index d6321c7..dd53e3c 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -225,16 +225,37 @@ void tst_QSharedPointer::basics() } class ForwardDeclared; +ForwardDeclared *forwardPointer(); +void externalForwardDeclaration(); +extern int forwardDeclaredDestructorRunCount; + void tst_QSharedPointer::forwardDeclaration1() { - class Wrapper { QSharedPointer pointer; }; + externalForwardDeclaration(); + + struct Wrapper { QSharedPointer pointer; }; + + forwardDeclaredDestructorRunCount = 0; + { + Wrapper w; + w.pointer = QSharedPointer(forwardPointer()); + QVERIFY(!w.pointer.isNull()); + } + QCOMPARE(forwardDeclaredDestructorRunCount, 1); } -class ForwardDeclared { }; +#include "forwarddeclared.h" + void tst_QSharedPointer::forwardDeclaration2() { - class Wrapper { QSharedPointer pointer; }; - Wrapper w; + forwardDeclaredDestructorRunCount = 0; + { + struct Wrapper { QSharedPointer pointer; }; + Wrapper w1, w2; + w1.pointer = QSharedPointer(forwardPointer()); + QVERIFY(!w1.pointer.isNull()); + } + QCOMPARE(forwardDeclaredDestructorRunCount, 1); } void tst_QSharedPointer::memoryManagement() @@ -1108,8 +1129,10 @@ void tst_QSharedPointer::invalidConstructs_data() // use of forward-declared class QTest::newRow("forward-declaration") - << &QTest::QExternalTest::tryCompileFail - << "QSharedPointer ptr;"; + << &QTest::QExternalTest::tryRun + << "forwardDeclaredDestructorRunCount = 0;\n" + "{ QSharedPointer ptr = QSharedPointer(forwardPointer()); }\n" + "exit(forwardDeclaredDestructorRunCount);"; QTest::newRow("creating-forward-declaration") << &QTest::QExternalTest::tryCompileFail << "QSharedPointer::create();"; @@ -1216,6 +1239,7 @@ void tst_QSharedPointer::invalidConstructs() QTest::QExternalTest test; test.setDebugMode(true); test.setQtModules(QTest::QExternalTest::QtCore); + test.setExtraProgramSources(QStringList() << SRCDIR "forwarddeclared.cpp"); test.setProgramHeader( "#define QT_SHAREDPOINTER_TRACK_POINTERS\n" "#include \n" @@ -1223,7 +1247,11 @@ void tst_QSharedPointer::invalidConstructs() "\n" "struct Data { int i; };\n" "struct DerivedData: public Data { int j; };\n" - "struct ForwardDeclared;"); + "\n" + "extern int forwardDeclaredDestructorRunCount;\n" + "struct ForwardDeclared;\n" + "ForwardDeclared *forwardPointer();\n" + ); QFETCH(QString, code); static bool sane = true; -- cgit v0.12 From d70839d4fd855d6d5f6bf8d982b677402f71e5ba Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 2 Jul 2009 14:14:51 +0200 Subject: These files don't have to have CRLF line-termination. The other files here don't, so I see no reason why these should --- examples/tools/codecs/encodedfiles/.gitattributes | 2 -- examples/tools/codecs/encodedfiles/iso-8859-1.txt | 12 ++++++------ examples/tools/codecs/encodedfiles/iso-8859-15.txt | 16 ++++++++-------- 3 files changed, 14 insertions(+), 16 deletions(-) delete mode 100644 examples/tools/codecs/encodedfiles/.gitattributes diff --git a/examples/tools/codecs/encodedfiles/.gitattributes b/examples/tools/codecs/encodedfiles/.gitattributes deleted file mode 100644 index 996aab2..0000000 --- a/examples/tools/codecs/encodedfiles/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -iso-8859-15.txt -crlf -iso-8859-1.txt -crlf diff --git a/examples/tools/codecs/encodedfiles/iso-8859-1.txt b/examples/tools/codecs/encodedfiles/iso-8859-1.txt index 4a7ebe3..d7fcaca 100644 --- a/examples/tools/codecs/encodedfiles/iso-8859-1.txt +++ b/examples/tools/codecs/encodedfiles/iso-8859-1.txt @@ -1,6 +1,6 @@ -Paulo Coelho: O Gênio e as Rosas -Anna Hallström, Urban Östberg: Svår svenska -Darrell Huff: How to Lie with Statistics -Franz Kafka: Das Schloß -Walter Moers: Die 13½ Leben des Käpt'n Blaubär -Dag Solstad: Forsøk på å beskrive det ugjennomtrengelige +Paulo Coelho: O Gênio e as Rosas +Anna Hallström, Urban Östberg: Svår svenska +Darrell Huff: How to Lie with Statistics +Franz Kafka: Das Schloß +Walter Moers: Die 13½ Leben des Käpt'n Blaubär +Dag Solstad: Forsøk på å beskrive det ugjennomtrengelige diff --git a/examples/tools/codecs/encodedfiles/iso-8859-15.txt b/examples/tools/codecs/encodedfiles/iso-8859-15.txt index cd43ea3..be2d83c 100644 --- a/examples/tools/codecs/encodedfiles/iso-8859-15.txt +++ b/examples/tools/codecs/encodedfiles/iso-8859-15.txt @@ -1,8 +1,8 @@ -Paulo Coelho: O Gênio e as Rosas -Jean-Pierre Coffe: À table en famille avec 15 ¤ par jour -Anna Hallström, Urban Östberg: Svår svenska -Darrell Huff: How to Lie with Statistics -Franz Kafka: Das Schloß -Helena Lehecková: T¨ekkiä suomalaisille -Arthur Rimbaud: ¼uvres complètes -Dag Solstad: Forsøk på å beskrive det ugjennomtrengelige +Paulo Coelho: O Gênio e as Rosas +Jean-Pierre Coffe: À table en famille avec 15 ¤ par jour +Anna Hallström, Urban Östberg: Svår svenska +Darrell Huff: How to Lie with Statistics +Franz Kafka: Das Schloß +Helena Lehecková: T¨ekkiä suomalaisille +Arthur Rimbaud: ¼uvres complètes +Dag Solstad: Forsøk på å beskrive det ugjennomtrengelige -- cgit v0.12 From c4ae87721e011fe44f301c4039f0651a05394162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Thu, 2 Jul 2009 14:59:51 +0200 Subject: Speedup item-lookup in Graphics View. We don't have to do a stable sort anymore because the lessThan operator now accounts for the insertion order. This also means we don't have to sort all top-level items to preserve the insertion order in QGraphicsScenePrivate::topLevelItemsInStackingOrder. Reviewed-by: Andreas --- src/gui/graphicsview/qgraphicsitem.cpp | 5 +++ src/gui/graphicsview/qgraphicsitem_p.h | 17 +++++++ src/gui/graphicsview/qgraphicsscene.cpp | 52 ++++++++++------------ src/gui/graphicsview/qgraphicsscene_p.h | 8 ++++ .../graphicsview/qgraphicsscenebsptreeindex.cpp | 12 ++--- .../graphicsview/qgraphicsscenebsptreeindex_p.h | 18 +++----- src/gui/graphicsview/qgraphicssceneindex.cpp | 5 +-- 7 files changed, 65 insertions(+), 52 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 002eab9..9a27ef5 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -4310,6 +4310,7 @@ void QGraphicsItemPrivate::resolveDepth(int parentDepth) void QGraphicsItemPrivate::addChild(QGraphicsItem *child) { needSortChildren = 1; + child->d_ptr->siblingIndex = children.size(); children.append(child); } @@ -4319,6 +4320,10 @@ void QGraphicsItemPrivate::addChild(QGraphicsItem *child) void QGraphicsItemPrivate::removeChild(QGraphicsItem *child) { children.removeOne(child); + // NB! Do not use children.removeAt(child->d_ptr->siblingIndex) because + // the child is not guaranteed to be at the index after the list is sorted. + // (see ensureSortedChildren()). + child->d_ptr->siblingIndex = -1; } /*! diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index a4b2c25..99865b0 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -126,6 +126,7 @@ public: parent(0), transformData(0), index(-1), + siblingIndex(-1), depth(0), acceptedMouseButtons(0x1f), visible(1), @@ -386,6 +387,7 @@ public: } inline QTransform transformToParent() const; + inline void ensureSortedChildren(); QPainterPath cachedClipPath; QRectF childrenBoundingRect; @@ -401,6 +403,7 @@ public: TransformData *transformData; QTransform sceneTransform; int index; + int siblingIndex; int depth; inline QGestureExtraData* extraGestures() const @@ -517,6 +520,12 @@ struct QGraphicsItemPrivate::TransformData { } }; +/*! + \internal +*/ +static inline bool qt_notclosestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2) +{ return qt_closestLeaf(item2, item1); } + /* return the full transform of the item to the parent. This include the position and all the transform data */ @@ -527,6 +536,14 @@ inline QTransform QGraphicsItemPrivate::transformToParent() const return matrix; } +inline void QGraphicsItemPrivate::ensureSortedChildren() +{ + if (needSortChildren) { + qSort(children.begin(), children.end(), qt_notclosestLeaf); + needSortChildren = 0; + } +} + QT_END_NAMESPACE #endif // QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 8a032f4..3b1c8ad 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -375,6 +375,7 @@ void QGraphicsScenePrivate::_q_emitUpdated() void QGraphicsScenePrivate::registerTopLevelItem(QGraphicsItem *item) { needSortTopLevelItems = true; + item->d_ptr->siblingIndex = topLevelItems.size(); topLevelItems.append(item); } @@ -384,6 +385,10 @@ void QGraphicsScenePrivate::registerTopLevelItem(QGraphicsItem *item) void QGraphicsScenePrivate::unregisterTopLevelItem(QGraphicsItem *item) { topLevelItems.removeOne(item); + // NB! Do not use topLevelItems.removeAt(item->d_ptr->siblingIndex) because + // the item is not guaranteed to be at the index after the list is sorted + // (see ensureSortedTopLevelItems()). + item->d_ptr->siblingIndex = -1; } /*! @@ -1084,37 +1089,29 @@ QList QGraphicsScenePrivate::topLevelItemsInStackingOrder(const const QRectF &sceneRect) { if (indexMethod == QGraphicsScene::NoIndex || sceneRect.isNull()) { - if (needSortTopLevelItems) { - needSortTopLevelItems = false; - qStableSort(topLevelItems.begin(), topLevelItems.end(), qt_notclosestLeaf); - } + ensureSortedTopLevelItems(); return topLevelItems; } - QList tmp = index->estimateItems(sceneRect, Qt::SortOrder(-1), - viewTransform ? *viewTransform : QTransform()); - for (int i = 0; i < tmp.size(); ++i) - tmp.at(i)->topLevelItem()->d_ptr->itemDiscovered = 1; - - // Sort if the toplevel list is unsorted. - if (needSortTopLevelItems) { - needSortTopLevelItems = false; - qStableSort(topLevelItems.begin(), topLevelItems.end(), qt_notclosestLeaf); - } - + const QList tmp = index->estimateItems(sceneRect, Qt::SortOrder(-1), + viewTransform ? *viewTransform : QTransform()); + // estimateItems returns a list of *all* items, but we are only interested + // in the top-levels (those that are within the rect themselves and those that + // have descendants within the rect). + // ### Look into how we can add this feature to the BSP. QList tli; - for (int i = 0; i < topLevelItems.size(); ++i) { - // ### Investigate smarter ways. Looping through all top level - // items is not optimal. If the BSP tree is to have maximum - // effect, it should be possible to sort the subset of items - // quickly. We must use this approach for now, as it's the only - // current way to keep the stable sorting order (insertion order). - QGraphicsItem *item = topLevelItems.at(i); - if (item->d_ptr->itemDiscovered) { - item->d_ptr->itemDiscovered = 0; - tli << item; + for (int i = 0; i < tmp.size(); ++i) { + QGraphicsItem *topLevelItem = tmp.at(i)->topLevelItem(); + if (!topLevelItem->d_ptr->itemDiscovered) { + tli << topLevelItem; + topLevelItem->d_ptr->itemDiscovered = 1; } } + // Reset discovered bit. + for (int i = 0; i < tli.size(); ++i) + tli.at(i)->d_ptr->itemDiscovered = 0; + + qSort(tli.begin(), tli.end(), qt_notclosestLeaf); return tli; } @@ -4283,10 +4280,7 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter * int i = 0; if (itemHasChildren) { - if (item->d_ptr->needSortChildren) { - item->d_ptr->needSortChildren = 0; - qStableSort(item->d_ptr->children.begin(), item->d_ptr->children.end(), qt_notclosestLeaf); - } + item->d_ptr->ensureSortedChildren(); if (itemClipsChildrenToShape) { painter->save(); diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 4842e72..23b0dd5 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -234,6 +234,14 @@ public: item->d_ptr->ignoreOpacity = 0; } + inline void ensureSortedTopLevelItems() + { + if (needSortTopLevelItems) { + qSort(topLevelItems.begin(), topLevelItems.end(), qt_notclosestLeaf); + needSortTopLevelItems = false; + } + } + QStyle *style; QFont font; void setFont_helper(const QFont &font); diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index c8d755e..0688cb1 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -242,7 +242,7 @@ void QGraphicsSceneBspTreeIndexPrivate::climbTree(QGraphicsItem *item, int *stac { if (!item->d_ptr->children.isEmpty()) { QList childList = item->d_ptr->children; - qStableSort(childList.begin(), childList.end(), qt_closestLeaf); + qSort(childList.begin(), childList.end(), qt_closestLeaf); for (int i = 0; i < childList.size(); ++i) { QGraphicsItem *item = childList.at(i); if (!(item->flags() & QGraphicsItem::ItemStacksBehindParent)) @@ -281,7 +281,7 @@ void QGraphicsSceneBspTreeIndexPrivate::_q_updateSortCache() topLevels << item; } - qStableSort(topLevels.begin(), topLevels.end(), qt_closestLeaf); + qSort(topLevels.begin(), topLevels.end(), qt_closestLeaf); for (int i = 0; i < topLevels.size(); ++i) climbTree(topLevels.at(i), &stackingOrder); } @@ -446,15 +446,15 @@ void QGraphicsSceneBspTreeIndexPrivate::sortItems(QList *itemLi { if (sortCacheEnabled) { if (order == Qt::AscendingOrder) { - qStableSort(itemList->begin(), itemList->end(), closestItemFirst_withCache); + qSort(itemList->begin(), itemList->end(), closestItemFirst_withCache); } else if (order == Qt::DescendingOrder) { - qStableSort(itemList->begin(), itemList->end(), closestItemLast_withCache); + qSort(itemList->begin(), itemList->end(), closestItemLast_withCache); } } else { if (order == Qt::AscendingOrder) { - qStableSort(itemList->begin(), itemList->end(), closestItemFirst_withoutCache); + qSort(itemList->begin(), itemList->end(), closestItemFirst_withoutCache); } else if (order == Qt::DescendingOrder) { - qStableSort(itemList->begin(), itemList->end(), closestItemLast_withoutCache); + qSort(itemList->begin(), itemList->end(), closestItemLast_withoutCache); } } } diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 7b431e6..437b17d 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -173,21 +173,13 @@ inline bool qt_closestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item const QGraphicsItemPrivate *d2 = item2->d_ptr; bool f1 = d1->flags & QGraphicsItem::ItemStacksBehindParent; bool f2 = d2->flags & QGraphicsItem::ItemStacksBehindParent; - if (f1 != f2) return f2; - qreal z1 = d1->z; - qreal z2 = d2->z; - return z1 > z2; + if (f1 != f2) + return f2; + if (d1->z != d2->z) + return d1->z > d2->z; + return d1->siblingIndex > d2->siblingIndex; } -/*! - \internal -*/ -static inline bool qt_notclosestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2) -{ - return qt_closestLeaf(item2, item1); -} - - static inline bool QRectF_intersects(const QRectF &s, const QRectF &r) { qreal xp = s.left(); diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index b317e8e..d6281e2 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -266,10 +266,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe int i = 0; if (itemHasChildren) { // Sort children. - if (item->d_ptr->needSortChildren) { - item->d_ptr->needSortChildren = 0; - qStableSort(item->d_ptr->children.begin(), item->d_ptr->children.end(), qt_notclosestLeaf); - } + item->d_ptr->ensureSortedChildren(); // Clip to shape. if (itemClipsChildrenToShape) -- cgit v0.12 From 501d1395bd3fc6c67e50216345959d31c0db7707 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 2 Jul 2009 15:44:17 +0200 Subject: Revert "Add support for creating the object alongside the Data structure in QSharedPointer" This reverts commit fb51a10ee0451274a430227566ae26efb2ac4474. Sorry, it didn't work. I can fix the MSVC error, but the problem is that older GCC versions (4.2) fail with the following code: template struct Buffer { char buffer[128] __attribute__((aligned(__alignof__(T)))); }; The same works fine in GCC 4.4. --- src/corelib/tools/qsharedpointer_impl.h | 47 ----------- tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 102 +---------------------- 2 files changed, 2 insertions(+), 147 deletions(-) diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 2fa9eb2..739a949 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -48,7 +48,6 @@ #pragma qt_sync_stop_processing #endif -#include #include #include // for qobject_cast @@ -191,34 +190,6 @@ namespace QtSharedPointer { }; template - struct ExternalRefCountWithContiguousData: public ExternalRefCountData - { -#ifdef Q_DECL_ALIGN -# ifdef Q_ALIGNOF -# define QSP_ALIGNOF(T) Q_ALIGNOF(T) -# else -# define QSP_ALIGNOF(T) (sizeof(T) >= 16 ? 16 : sizeof(T) >= 8 ? 8 : sizeof(T) >= 4 ? 4 : sizeof(T) >= 2 ? 2 : 1) -# endif - - char data[sizeof(T)] Q_DECL_ALIGN(QSP_ALIGNOF(T)); - inline T *pointer() { return reinterpret_cast(data); } - -# undef QSP_ALIGNOF -#else - union { - char data[sizeof(T) + 16]; - double dummy1; -# ifndef Q_OS_DARWIN - long double dummy2; -# endif - }; - inline T *pointer() { return reinterpret_cast(data + 16 - (quintptr(data) & 0xf)); } -#endif - - inline bool destroy() { this->pointer()->~T(); return true; } - }; - - template class ExternalRefCount: public Basic { typedef ExternalRefCountData Data; @@ -249,16 +220,6 @@ namespace QtSharedPointer { d = new ExternalRefCountWithSpecializedDeleter(ptr, deleter); } - inline void internalCreate() - { - ExternalRefCountWithContiguousData *dd = new ExternalRefCountWithContiguousData; - T *ptr = dd->pointer(); - new (ptr) T(); // create - - Basic::internalConstruct(ptr); - d = dd; - } - inline ExternalRefCount() : d(0) { } inline ~ExternalRefCount() { if (d && !deref()) delete d; } inline ExternalRefCount(const ExternalRefCount &other) : Basic(other), d(other.d) @@ -386,14 +347,6 @@ public: inline void clear() { *this = QSharedPointer(); } QWeakPointer toWeakRef() const; - -public: - static QSharedPointer create() - { - QSharedPointer result; - result.internalCreate(); - return result; - } }; template diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index dd53e3c..5cb435a 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -65,9 +65,8 @@ private slots: void dynamicCastVirtualBase(); void dynamicCastFailure(); #endif - void constCorrectness(); void customDeleter(); - void creating(); + void constCorrectness(); void validConstructs(); void invalidConstructs_data(); void invalidConstructs(); @@ -105,8 +104,6 @@ public: { delete this; } - - virtual int classLevel() { return 1; } }; int Data::generationCounter = 0; int Data::destructorCounter = 0; @@ -335,8 +332,6 @@ public: { delete this; } - - virtual int classLevel() { return 2; } }; int DerivedData::derivedDestructorCounter = 0; @@ -344,23 +339,15 @@ class Stuffing { public: char buffer[16]; - Stuffing() { for (uint i = 0; i < sizeof buffer; ++i) buffer[i] = 16 - i; } virtual ~Stuffing() { } }; class DiffPtrDerivedData: public Stuffing, public Data { -public: - virtual int classLevel() { return 3; } }; class VirtualDerived: virtual public Data { -public: - int moreData; - - VirtualDerived() : moreData(0xc0ffee) { } - virtual int classLevel() { return 4; } }; void tst_QSharedPointer::downCast() @@ -1006,82 +993,6 @@ void tst_QSharedPointer::customDeleter() QCOMPARE(derivedDataDeleter.callCount, 1); } -void tst_QSharedPointer::creating() -{ - Data::generationCounter = Data::destructorCounter = 0; - { - QSharedPointer ptr = QSharedPointer::create(); - QVERIFY(ptr.data()); - QCOMPARE(Data::generationCounter, 1); - QCOMPARE(ptr->generation, 1); - QCOMPARE(Data::destructorCounter, 0); - - QCOMPARE(ptr->classLevel(), 1); - - ptr.clear(); - QCOMPARE(Data::destructorCounter, 1); - } - - Data::generationCounter = Data::destructorCounter = 0; - { - QSharedPointer ptr = QSharedPointer::create(); - QWeakPointer weakptr = ptr; - QtSharedPointer::ExternalRefCountData *d = ptr.d; - - ptr.clear(); - QVERIFY(ptr.isNull()); - QCOMPARE(Data::destructorCounter, 1); - - // valgrind will complain here if something happened to the pointer - QVERIFY(d->weakref == 1); - QVERIFY(d->strongref == 0); - } - - Data::generationCounter = Data::destructorCounter = 0; - DerivedData::derivedDestructorCounter = 0; - { - QSharedPointer ptr = QSharedPointer::create(); - QCOMPARE(ptr->classLevel(), 2); - QCOMPARE(ptr.staticCast()->moreData, 0); - ptr.clear(); - - QCOMPARE(Data::destructorCounter, 1); - QCOMPARE(DerivedData::derivedDestructorCounter, 1); - } - - { - QSharedPointer ptr = QSharedPointer::create(); - QCOMPARE(ptr->classLevel(), 3); - QCOMPARE(ptr.staticCast()->buffer[7]+0, 16-7); - QCOMPARE(ptr.staticCast()->buffer[3]+0, 16-3); - QCOMPARE(ptr.staticCast()->buffer[0]+0, 16); - } - - { - QSharedPointer ptr = QSharedPointer::create(); - QCOMPARE(ptr->classLevel(), 4); - QCOMPARE(ptr->moreData, 0xc0ffee); - - QSharedPointer baseptr = ptr; - QCOMPARE(baseptr->classLevel(), 4); - } - - { - QSharedPointer ptr = QSharedPointer::create(); - QCOMPARE(ptr->metaObject(), &QObject::staticMetaObject); - - QPointer qptr = ptr.data(); - ptr.clear(); - - QVERIFY(qptr.isNull()); - } - - { - QSharedPointer ptr = QSharedPointer::create(); - QCOMPARE(ptr->metaObject(), &OtherObject::staticMetaObject); - } -} - void tst_QSharedPointer::validConstructs() { { @@ -1133,9 +1044,6 @@ void tst_QSharedPointer::invalidConstructs_data() << "forwardDeclaredDestructorRunCount = 0;\n" "{ QSharedPointer ptr = QSharedPointer(forwardPointer()); }\n" "exit(forwardDeclaredDestructorRunCount);"; - QTest::newRow("creating-forward-declaration") - << &QTest::QExternalTest::tryCompileFail - << "QSharedPointer::create();"; // upcast without cast operator: QTest::newRow("upcast1") @@ -1168,16 +1076,10 @@ void tst_QSharedPointer::invalidConstructs_data() << "QSharedPointer baseptr = QSharedPointer(new Data);\n" "qSharedPointerDynamicCast(baseptr);"; #endif - QTest::newRow("const-dropping-object-cast1") + QTest::newRow("const-dropping-object-cast") << &QTest::QExternalTest::tryCompileFail << "QSharedPointer baseptr = QSharedPointer(new QObject);\n" "qSharedPointerObjectCast(baseptr);"; -#ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION - QTest::newRow("const-dropping-object-cast2") - << &QTest::QExternalTest::tryCompileFail - << "QSharedPointer baseptr = QSharedPointer(new QObject);\n" - "qobject_cast(baseptr);"; -#endif // arithmethics through automatic cast operators QTest::newRow("arithmethic1") -- cgit v0.12 From d9b28812d0065227e6f66817cd9bf917dfadb0f0 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 2 Jul 2009 15:49:49 +0200 Subject: Don't compile the FD_CLOEXEC-safe accept4 call if we don't know about SOCK_CLOEXEC --- src/network/socket/qnet_unix_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/socket/qnet_unix_p.h b/src/network/socket/qnet_unix_p.h index 80a4c58..ffd5b39 100644 --- a/src/network/socket/qnet_unix_p.h +++ b/src/network/socket/qnet_unix_p.h @@ -100,7 +100,7 @@ static inline int qt_safe_accept(int s, struct sockaddr *addr, QT_SOCKLEN_T *add Q_ASSERT((flags & ~O_NONBLOCK) == 0); register int fd; -#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC +#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC && defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) // use accept4 int sockflags = SOCK_CLOEXEC; if (flags & O_NONBLOCK) -- cgit v0.12 From f30f3e7bdc846baf49ef51721a5b11d31be22cf2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 2 Jul 2009 16:43:40 +0200 Subject: Fix build with MSVC2003: apparently the code path I thought was Unix was also older MSVC --- src/corelib/io/qtemporaryfile.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index 2ae4611..b520bee 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -61,7 +61,7 @@ #include #if defined(Q_OS_UNIX) -# include "private/qcore_unix_p.h" +# include "private/qcore_unix_p.h" // overrides QT_OPEN #endif #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) @@ -211,9 +211,9 @@ static int _gettemp(char *path, int *doopen, int domkdir, int slen) if ((*doopen = QT_OPEN(targetPath.toLocal8Bit(), O_CREAT|O_EXCL|O_RDWR # else // CE - // this is Unix + // this is Unix or older MSVC if ((*doopen = - qt_safe_open(path, QT_OPEN_CREAT|O_EXCL|QT_OPEN_RDWR + QT_OPEN(path, QT_OPEN_CREAT|O_EXCL|QT_OPEN_RDWR # endif # ifdef QT_LARGEFILE_SUPPORT |QT_OPEN_LARGEFILE -- cgit v0.12 From 8dbdcc129a7bb5f924aeb451799bc4d7495714ba Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 2 Jul 2009 16:41:53 +0200 Subject: QHeaderView: the sizeHint for section now takes the indicator into account for all sections is sorting is enabled. Task-number: 208320 --- src/gui/itemviews/qheaderview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp index b35c30b..aea288b 100644 --- a/src/gui/itemviews/qheaderview.cpp +++ b/src/gui/itemviews/qheaderview.cpp @@ -2540,7 +2540,7 @@ QSize QHeaderView::sectionSizeFromContents(int logicalIndex) const if (opt.icon.isNull()) opt.icon = qvariant_cast(variant); QSize size = style()->sizeFromContents(QStyle::CT_HeaderSection, &opt, QSize(), this); - if (isSortIndicatorShown() && sortIndicatorSection() == logicalIndex) { + if (isSortIndicatorShown()) { int margin = style()->pixelMetric(QStyle::PM_HeaderMargin, &opt, this); if (d->orientation == Qt::Horizontal) size.rwidth() += size.height() + margin; -- cgit v0.12 From 8b8e6a7e12e7f5769b60d827f7c8443aa71c339a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 2 Jul 2009 17:03:59 +0200 Subject: Use void* in the read/write replacements That's what unistd.h uses: void* can receive any pointer, while char* can't --- src/corelib/kernel/qcore_unix_p.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index 6ae4ff0..1f3fe39 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -193,7 +193,7 @@ static inline int qt_safe_dup2(int oldfd, int newfd, int flags = FD_CLOEXEC) return 0; } -static inline qint64 qt_safe_read(int fd, char *data, qint64 maxlen) +static inline qint64 qt_safe_read(int fd, void *data, qint64 maxlen) { qint64 ret = 0; EINTR_LOOP(ret, QT_READ(fd, data, maxlen)); @@ -202,7 +202,7 @@ static inline qint64 qt_safe_read(int fd, char *data, qint64 maxlen) #undef QT_READ #define QT_READ qt_safe_read -static inline qint64 qt_safe_write(int fd, const char *data, qint64 len) +static inline qint64 qt_safe_write(int fd, const void *data, qint64 len) { qint64 ret = 0; EINTR_LOOP(ret, QT_WRITE(fd, data, len)); -- cgit v0.12 From 27360dd89f0ea72610cf2cd725c62f7a7dd2ea91 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 2 Jul 2009 17:09:59 +0200 Subject: Correct #include path for qcore_unix_p.h --- src/corelib/io/qfilesystemwatcher_kqueue.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemwatcher_kqueue.cpp b/src/corelib/io/qfilesystemwatcher_kqueue.cpp index 721f52c..dfed6a4 100644 --- a/src/corelib/io/qfilesystemwatcher_kqueue.cpp +++ b/src/corelib/io/qfilesystemwatcher_kqueue.cpp @@ -43,7 +43,7 @@ #include "qfilesystemwatcher.h" #include "qfilesystemwatcher_kqueue_p.h" -#include "qcore_unix_p.h" +#include "private/qcore_unix_p.h" #include #include -- cgit v0.12 From 099a32d121cbc80a1a234c3146f4be9b5237e7e8 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Thu, 2 Jul 2009 11:46:42 +0200 Subject: Don't insert text into a text widget when a modifier is pressed. For example when an unhandled key sequence (i.e. that has now shortcut assosiated with it) like Alt-L is pressed, we shouldn't insert the 'L' text from the QKeyEvent::text() into the text widget. Reviewed-by: Thomas Zander --- src/gui/text/qtextcontrol.cpp | 3 ++- src/gui/widgets/qlineedit.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp index b2ad686..2a590fd 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -1245,7 +1245,8 @@ void QTextControlPrivate::keyPressEvent(QKeyEvent *e) process: { QString text = e->text(); - if (!text.isEmpty() && (text.at(0).isPrint() || text.at(0) == QLatin1Char('\t'))) { + if (!text.isEmpty() && (text.at(0).isPrint() || text.at(0) == QLatin1Char('\t')) && + ((e->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier)) == Qt::NoModifier)) { if (overwriteMode // no need to call deleteChar() if we have a selection, insertText // does it already diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index c7f3e97..d1067a8 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -2169,7 +2169,8 @@ void QLineEdit::keyPressEvent(QKeyEvent *event) if (unknown && !d->readOnly) { QString t = event->text(); - if (!t.isEmpty() && t.at(0).isPrint()) { + if (!t.isEmpty() && t.at(0).isPrint() && + ((event->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier)) == Qt::NoModifier)) { insert(t); #ifndef QT_NO_COMPLETER d->complete(event->key()); -- cgit v0.12 From 60e965fd35037f4a27816d2aeccafdff0d6ae9d6 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Mon, 15 Jun 2009 16:00:46 +0200 Subject: Refactored gesture api Rewritten the api almost from scratch, making it simplier and more flexible at the same time. The current implementation will not have complex gseturemanager class inside Qt, but the QGesture base class, which represents both a gesture recognizer and a gesture itself with a set of properties. A set of common gestures that can use used in third-party applications (and in Qt itself internally) is supposed to be found in qstandardgestures.h, and a base class for user-defined gestures is in qgesture.h Gesture implementation for Pan on Windows7 has also been added as a reference implementation for platform gestures. --- doc/src/qnamespace.qdoc | 38 +- examples/gestures/browser/Info_mac.plist | 43 - examples/gestures/browser/addbookmarkdialog.ui | 98 -- examples/gestures/browser/autosaver.cpp | 94 -- examples/gestures/browser/autosaver.h | 76 -- examples/gestures/browser/bookmarks.cpp | 987 --------------- examples/gestures/browser/bookmarks.h | 310 ----- examples/gestures/browser/bookmarks.ui | 106 -- examples/gestures/browser/browser.icns | Bin 50218 -> 0 bytes examples/gestures/browser/browser.ico | Bin 15374 -> 0 bytes examples/gestures/browser/browser.pro | 91 -- examples/gestures/browser/browser.rc | 2 - examples/gestures/browser/browserapplication.cpp | 447 ------- examples/gestures/browser/browserapplication.h | 119 -- examples/gestures/browser/browsermainwindow.cpp | 991 --------------- examples/gestures/browser/browsermainwindow.h | 169 --- examples/gestures/browser/chasewidget.cpp | 142 --- examples/gestures/browser/chasewidget.h | 85 -- examples/gestures/browser/cookiejar.cpp | 733 ----------- examples/gestures/browser/cookiejar.h | 204 ---- examples/gestures/browser/cookies.ui | 106 -- examples/gestures/browser/cookiesexceptions.ui | 184 --- examples/gestures/browser/data/addtab.png | Bin 469 -> 0 bytes examples/gestures/browser/data/browser.svg | 411 ------- examples/gestures/browser/data/closetab.png | Bin 516 -> 0 bytes examples/gestures/browser/data/data.qrc | 11 - .../gestures/browser/data/defaultbookmarks.xbel | 40 - examples/gestures/browser/data/defaulticon.png | Bin 1473 -> 0 bytes examples/gestures/browser/data/history.png | Bin 1527 -> 0 bytes examples/gestures/browser/data/loading.gif | Bin 847 -> 0 bytes examples/gestures/browser/downloaditem.ui | 134 -- examples/gestures/browser/downloadmanager.cpp | 579 --------- examples/gestures/browser/downloadmanager.h | 162 --- examples/gestures/browser/downloads.ui | 83 -- examples/gestures/browser/edittableview.cpp | 78 -- examples/gestures/browser/edittableview.h | 61 - examples/gestures/browser/edittreeview.cpp | 77 -- examples/gestures/browser/edittreeview.h | 61 - examples/gestures/browser/history.cpp | 1282 -------------------- examples/gestures/browser/history.h | 350 ------ examples/gestures/browser/history.ui | 106 -- examples/gestures/browser/htmls/htmls.qrc | 5 - examples/gestures/browser/htmls/notfound.html | 63 - examples/gestures/browser/main.cpp | 53 - examples/gestures/browser/modelmenu.cpp | 227 ---- examples/gestures/browser/modelmenu.h | 105 -- examples/gestures/browser/networkaccessmanager.cpp | 171 --- examples/gestures/browser/networkaccessmanager.h | 68 -- examples/gestures/browser/passworddialog.ui | 111 -- examples/gestures/browser/proxy.ui | 104 -- examples/gestures/browser/searchlineedit.cpp | 238 ---- examples/gestures/browser/searchlineedit.h | 103 -- examples/gestures/browser/settings.cpp | 324 ----- examples/gestures/browser/settings.h | 74 -- examples/gestures/browser/settings.ui | 614 ---------- examples/gestures/browser/squeezelabel.cpp | 61 - examples/gestures/browser/squeezelabel.h | 60 - examples/gestures/browser/tabwidget.cpp | 830 ------------- examples/gestures/browser/tabwidget.h | 224 ---- examples/gestures/browser/toolbarsearch.cpp | 161 --- examples/gestures/browser/toolbarsearch.h | 84 -- examples/gestures/browser/urllineedit.cpp | 340 ------ examples/gestures/browser/urllineedit.h | 115 -- examples/gestures/browser/webview.cpp | 363 ------ examples/gestures/browser/webview.h | 124 -- examples/gestures/browser/xbel.cpp | 320 ----- examples/gestures/browser/xbel.h | 113 -- examples/gestures/collidingmice/collidingmice.pro | 18 - .../collidingmice/gesturerecognizerlinjazax.cpp | 213 ---- .../collidingmice/gesturerecognizerlinjazax.h | 106 -- examples/gestures/collidingmice/images/cheese.jpg | Bin 3029 -> 0 bytes examples/gestures/collidingmice/linjazaxgesture.h | 102 -- examples/gestures/collidingmice/main.cpp | 163 --- examples/gestures/collidingmice/mice.qrc | 5 - examples/gestures/collidingmice/mouse.cpp | 200 --- examples/gestures/collidingmice/mouse.h | 72 -- examples/gestures/gestures.pro | 9 +- examples/gestures/graphicsview/graphicsview.pro | 2 - examples/gestures/graphicsview/main.cpp | 150 --- examples/gestures/imageviewer/imagewidget.cpp | 79 +- examples/gestures/imageviewer/imagewidget.h | 14 +- examples/gestures/pannablewebview/main.cpp | 90 -- .../gestures/pannablewebview/pannablewebview.pro | 4 - src/corelib/global/qnamespace.h | 29 - src/corelib/kernel/qcoreevent.cpp | 3 +- src/corelib/kernel/qcoreevent.h | 3 +- src/gui/graphicsview/qgraphicsitem.cpp | 119 -- src/gui/graphicsview/qgraphicsitem.h | 5 - src/gui/graphicsview/qgraphicsitem_p.h | 33 +- src/gui/graphicsview/qgraphicsproxywidget.cpp | 13 - src/gui/graphicsview/qgraphicsscene.cpp | 127 -- src/gui/graphicsview/qgraphicsscene.h | 1 - src/gui/graphicsview/qgraphicsscene_p.h | 8 - src/gui/graphicsview/qgraphicssceneevent.cpp | 249 ---- src/gui/graphicsview/qgraphicssceneevent.h | 43 - src/gui/graphicsview/qgraphicsview.cpp | 14 - src/gui/kernel/kernel.pri | 13 +- src/gui/kernel/qapplication.cpp | 84 +- src/gui/kernel/qapplication.h | 9 - src/gui/kernel/qapplication_p.h | 121 +- src/gui/kernel/qapplication_win.cpp | 89 ++ src/gui/kernel/qdirectionrecognizer.cpp | 182 --- src/gui/kernel/qdirectionrecognizer_p.h | 105 -- src/gui/kernel/qdirectionsimplificator_p.h | 172 --- src/gui/kernel/qevent.cpp | 156 --- src/gui/kernel/qevent.h | 35 - src/gui/kernel/qevent_p.h | 16 + src/gui/kernel/qgesture.cpp | 308 ++--- src/gui/kernel/qgesture.h | 82 +- src/gui/kernel/qgesture_p.h | 35 +- src/gui/kernel/qgesturemanager.cpp | 644 ---------- src/gui/kernel/qgesturemanager_p.h | 126 -- src/gui/kernel/qgesturerecognizer.cpp | 160 --- src/gui/kernel/qgesturerecognizer.h | 87 -- src/gui/kernel/qgesturerecognizer_p.h | 72 -- src/gui/kernel/qgesturestandardrecognizers.cpp | 306 ----- src/gui/kernel/qgesturestandardrecognizers_p.h | 131 -- src/gui/kernel/qstandardgestures.cpp | 254 ++++ src/gui/kernel/qstandardgestures.h | 102 ++ src/gui/kernel/qstandardgestures_p.h | 91 ++ src/gui/kernel/qwidget.cpp | 163 +-- src/gui/kernel/qwidget.h | 7 - src/gui/kernel/qwidget_p.h | 5 - src/gui/widgets/qabstractscrollarea.cpp | 34 +- src/gui/widgets/qabstractscrollarea_p.h | 5 + src/gui/widgets/qplaintextedit.cpp | 32 + src/gui/widgets/qplaintextedit.h | 1 + src/gui/widgets/qplaintextedit_p.h | 5 + src/gui/widgets/qtextedit.cpp | 26 + src/gui/widgets/qtextedit.h | 1 + src/gui/widgets/qtextedit_p.h | 5 +- tests/auto/gestures/tst_gestures.cpp | 29 +- 132 files changed, 1091 insertions(+), 17991 deletions(-) delete mode 100644 examples/gestures/browser/Info_mac.plist delete mode 100644 examples/gestures/browser/addbookmarkdialog.ui delete mode 100644 examples/gestures/browser/autosaver.cpp delete mode 100644 examples/gestures/browser/autosaver.h delete mode 100644 examples/gestures/browser/bookmarks.cpp delete mode 100644 examples/gestures/browser/bookmarks.h delete mode 100644 examples/gestures/browser/bookmarks.ui delete mode 100644 examples/gestures/browser/browser.icns delete mode 100644 examples/gestures/browser/browser.ico delete mode 100644 examples/gestures/browser/browser.pro delete mode 100644 examples/gestures/browser/browser.rc delete mode 100644 examples/gestures/browser/browserapplication.cpp delete mode 100644 examples/gestures/browser/browserapplication.h delete mode 100644 examples/gestures/browser/browsermainwindow.cpp delete mode 100644 examples/gestures/browser/browsermainwindow.h delete mode 100644 examples/gestures/browser/chasewidget.cpp delete mode 100644 examples/gestures/browser/chasewidget.h delete mode 100644 examples/gestures/browser/cookiejar.cpp delete mode 100644 examples/gestures/browser/cookiejar.h delete mode 100644 examples/gestures/browser/cookies.ui delete mode 100644 examples/gestures/browser/cookiesexceptions.ui delete mode 100644 examples/gestures/browser/data/addtab.png delete mode 100644 examples/gestures/browser/data/browser.svg delete mode 100644 examples/gestures/browser/data/closetab.png delete mode 100644 examples/gestures/browser/data/data.qrc delete mode 100644 examples/gestures/browser/data/defaultbookmarks.xbel delete mode 100644 examples/gestures/browser/data/defaulticon.png delete mode 100644 examples/gestures/browser/data/history.png delete mode 100644 examples/gestures/browser/data/loading.gif delete mode 100644 examples/gestures/browser/downloaditem.ui delete mode 100644 examples/gestures/browser/downloadmanager.cpp delete mode 100644 examples/gestures/browser/downloadmanager.h delete mode 100644 examples/gestures/browser/downloads.ui delete mode 100644 examples/gestures/browser/edittableview.cpp delete mode 100644 examples/gestures/browser/edittableview.h delete mode 100644 examples/gestures/browser/edittreeview.cpp delete mode 100644 examples/gestures/browser/edittreeview.h delete mode 100644 examples/gestures/browser/history.cpp delete mode 100644 examples/gestures/browser/history.h delete mode 100644 examples/gestures/browser/history.ui delete mode 100644 examples/gestures/browser/htmls/htmls.qrc delete mode 100644 examples/gestures/browser/htmls/notfound.html delete mode 100644 examples/gestures/browser/main.cpp delete mode 100644 examples/gestures/browser/modelmenu.cpp delete mode 100644 examples/gestures/browser/modelmenu.h delete mode 100644 examples/gestures/browser/networkaccessmanager.cpp delete mode 100644 examples/gestures/browser/networkaccessmanager.h delete mode 100644 examples/gestures/browser/passworddialog.ui delete mode 100644 examples/gestures/browser/proxy.ui delete mode 100644 examples/gestures/browser/searchlineedit.cpp delete mode 100644 examples/gestures/browser/searchlineedit.h delete mode 100644 examples/gestures/browser/settings.cpp delete mode 100644 examples/gestures/browser/settings.h delete mode 100644 examples/gestures/browser/settings.ui delete mode 100644 examples/gestures/browser/squeezelabel.cpp delete mode 100644 examples/gestures/browser/squeezelabel.h delete mode 100644 examples/gestures/browser/tabwidget.cpp delete mode 100644 examples/gestures/browser/tabwidget.h delete mode 100644 examples/gestures/browser/toolbarsearch.cpp delete mode 100644 examples/gestures/browser/toolbarsearch.h delete mode 100644 examples/gestures/browser/urllineedit.cpp delete mode 100644 examples/gestures/browser/urllineedit.h delete mode 100644 examples/gestures/browser/webview.cpp delete mode 100644 examples/gestures/browser/webview.h delete mode 100644 examples/gestures/browser/xbel.cpp delete mode 100644 examples/gestures/browser/xbel.h delete mode 100644 examples/gestures/collidingmice/collidingmice.pro delete mode 100644 examples/gestures/collidingmice/gesturerecognizerlinjazax.cpp delete mode 100644 examples/gestures/collidingmice/gesturerecognizerlinjazax.h delete mode 100644 examples/gestures/collidingmice/images/cheese.jpg delete mode 100644 examples/gestures/collidingmice/linjazaxgesture.h delete mode 100644 examples/gestures/collidingmice/main.cpp delete mode 100644 examples/gestures/collidingmice/mice.qrc delete mode 100644 examples/gestures/collidingmice/mouse.cpp delete mode 100644 examples/gestures/collidingmice/mouse.h delete mode 100644 examples/gestures/graphicsview/graphicsview.pro delete mode 100644 examples/gestures/graphicsview/main.cpp delete mode 100644 examples/gestures/pannablewebview/main.cpp delete mode 100644 examples/gestures/pannablewebview/pannablewebview.pro delete mode 100644 src/gui/kernel/qdirectionrecognizer.cpp delete mode 100644 src/gui/kernel/qdirectionrecognizer_p.h delete mode 100644 src/gui/kernel/qdirectionsimplificator_p.h delete mode 100644 src/gui/kernel/qgesturemanager.cpp delete mode 100644 src/gui/kernel/qgesturemanager_p.h delete mode 100644 src/gui/kernel/qgesturerecognizer.cpp delete mode 100644 src/gui/kernel/qgesturerecognizer.h delete mode 100644 src/gui/kernel/qgesturerecognizer_p.h delete mode 100644 src/gui/kernel/qgesturestandardrecognizers.cpp delete mode 100644 src/gui/kernel/qgesturestandardrecognizers_p.h create mode 100644 src/gui/kernel/qstandardgestures.cpp create mode 100644 src/gui/kernel/qstandardgestures.h create mode 100644 src/gui/kernel/qstandardgestures_p.h diff --git a/doc/src/qnamespace.qdoc b/doc/src/qnamespace.qdoc index e77cc7e..b691ac7 100644 --- a/doc/src/qnamespace.qdoc +++ b/doc/src/qnamespace.qdoc @@ -2700,20 +2700,6 @@ \internal */ -/*! \enum Qt::GestureType - \since 4.6 - - This enum lists standard gestures. - - \value UnknownGesture An unknown gesture. This enum value shouldn't be used. - \value TapGesture A single tap gesture. - \value DoubleTapGesture A double tap gesture. - \value TrippleTapGesture A tripple tap gesture. - \value TapAndHoldGesture A tap-and-hold (long tap) gesture. - \value PanGesture A pan gesture. - \value PinchGesture A pinch gesture. -*/ - /*! \enum Qt::GestureState \since 4.6 @@ -2722,30 +2708,8 @@ \omitvalue NoGesture \value GestureStarted A continuous gesture has started. - \value GestureUpdated A gesture continiues. + \value GestureUpdated A gesture continues. \value GestureFinished A gesture has finished. \sa QGesture */ - -/*! - \enum Qt::DirectionType - \since 4.6 - - This enum type describes directions. This could be used by the - gesture recognizers. - - \value NoDirection Non-specific direction. - \value LeftDownDirection - \value DownLeftDirection - \value DownDirection - \value RightDownDirection - \value DownRightDirection - \value LeftDirection - \value RightDirection - \value LeftUpDirection - \value UpLeftDirection - \value UpDirection - \value RightUpDirection - \value UpRightDirection -*/ diff --git a/examples/gestures/browser/Info_mac.plist b/examples/gestures/browser/Info_mac.plist deleted file mode 100644 index 5648631..0000000 --- a/examples/gestures/browser/Info_mac.plist +++ /dev/null @@ -1,43 +0,0 @@ - - - - - CFBundleIconFile - @ICON@ - CFBundlePackageType - APPL - CFBundleGetInfoString - Created by Qt/QMake - CFBundleIdentifier - com.trolltech.DemoBrowser - CFBundleSignature - ttxt - CFBundleExecutable - @EXECUTABLE@ - CFBundleDocumentTypes - - - CFBundleTypeExtensions - - html - htm - shtml - xht - xhtml - - CFBundleTypeIconFile - @ICON@ - CFBundleTypeName - HTML Document - CFBundleTypeOSTypes - - HTML - - CFBundleTypeRole - Viewer - - - NOTE - DemoBrowser by Nokia Corporation and/or its subsidiary(-ies) - - diff --git a/examples/gestures/browser/addbookmarkdialog.ui b/examples/gestures/browser/addbookmarkdialog.ui deleted file mode 100644 index 3460d7b..0000000 --- a/examples/gestures/browser/addbookmarkdialog.ui +++ /dev/null @@ -1,98 +0,0 @@ - - AddBookmarkDialog - - - - 0 - 0 - 240 - 168 - - - - Add Bookmark - - - - - - Type a name for the bookmark, and choose where to keep it. - - - Qt::PlainText - - - true - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 2 - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - false - - - - - - - - - buttonBox - accepted() - AddBookmarkDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - AddBookmarkDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/examples/gestures/browser/autosaver.cpp b/examples/gestures/browser/autosaver.cpp deleted file mode 100644 index 77888ce..0000000 --- a/examples/gestures/browser/autosaver.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 "autosaver.h" - -#include -#include -#include -#include - -#define AUTOSAVE_IN 1000 * 3 // seconds -#define MAXWAIT 1000 * 15 // seconds - -AutoSaver::AutoSaver(QObject *parent) : QObject(parent) -{ - Q_ASSERT(parent); -} - -AutoSaver::~AutoSaver() -{ - if (m_timer.isActive()) - qWarning() << "AutoSaver: still active when destroyed, changes not saved."; -} - -void AutoSaver::changeOccurred() -{ - if (m_firstChange.isNull()) - m_firstChange.start(); - - if (m_firstChange.elapsed() > MAXWAIT) { - saveIfNeccessary(); - } else { - m_timer.start(AUTOSAVE_IN, this); - } -} - -void AutoSaver::timerEvent(QTimerEvent *event) -{ - if (event->timerId() == m_timer.timerId()) { - saveIfNeccessary(); - } else { - QObject::timerEvent(event); - } -} - -void AutoSaver::saveIfNeccessary() -{ - if (!m_timer.isActive()) - return; - m_timer.stop(); - m_firstChange = QTime(); - if (!QMetaObject::invokeMethod(parent(), "save", Qt::DirectConnection)) { - qWarning() << "AutoSaver: error invoking slot save() on parent"; - } -} - diff --git a/examples/gestures/browser/autosaver.h b/examples/gestures/browser/autosaver.h deleted file mode 100644 index e6b44ed..0000000 --- a/examples/gestures/browser/autosaver.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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$ -** -****************************************************************************/ - -#ifndef AUTOSAVER_H -#define AUTOSAVER_H - -#include -#include -#include - -/* - This class will call the save() slot on the parent object when the parent changes. - It will wait several seconds after changed() to combining multiple changes and - prevent continuous writing to disk. - */ -class AutoSaver : public QObject { - -Q_OBJECT - -public: - AutoSaver(QObject *parent); - ~AutoSaver(); - void saveIfNeccessary(); - -public slots: - void changeOccurred(); - -protected: - void timerEvent(QTimerEvent *event); - -private: - QBasicTimer m_timer; - QTime m_firstChange; - -}; - -#endif // AUTOSAVER_H - diff --git a/examples/gestures/browser/bookmarks.cpp b/examples/gestures/browser/bookmarks.cpp deleted file mode 100644 index 125bcbe..0000000 --- a/examples/gestures/browser/bookmarks.cpp +++ /dev/null @@ -1,987 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 "bookmarks.h" - -#include "autosaver.h" -#include "browserapplication.h" -#include "history.h" -#include "xbel.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#define BOOKMARKBAR "Bookmarks Bar" -#define BOOKMARKMENU "Bookmarks Menu" - -BookmarksManager::BookmarksManager(QObject *parent) - : QObject(parent) - , m_loaded(false) - , m_saveTimer(new AutoSaver(this)) - , m_bookmarkRootNode(0) - , m_bookmarkModel(0) -{ - connect(this, SIGNAL(entryAdded(BookmarkNode *)), - m_saveTimer, SLOT(changeOccurred())); - connect(this, SIGNAL(entryRemoved(BookmarkNode *, int, BookmarkNode *)), - m_saveTimer, SLOT(changeOccurred())); - connect(this, SIGNAL(entryChanged(BookmarkNode *)), - m_saveTimer, SLOT(changeOccurred())); -} - -BookmarksManager::~BookmarksManager() -{ - m_saveTimer->saveIfNeccessary(); -} - -void BookmarksManager::changeExpanded() -{ - m_saveTimer->changeOccurred(); -} - -void BookmarksManager::load() -{ - if (m_loaded) - return; - m_loaded = true; - - QString dir = QDesktopServices::storageLocation(QDesktopServices::DataLocation); - QString bookmarkFile = dir + QLatin1String("/bookmarks.xbel"); - if (!QFile::exists(bookmarkFile)) - bookmarkFile = QLatin1String(":defaultbookmarks.xbel"); - - XbelReader reader; - m_bookmarkRootNode = reader.read(bookmarkFile); - if (reader.error() != QXmlStreamReader::NoError) { - QMessageBox::warning(0, QLatin1String("Loading Bookmark"), - tr("Error when loading bookmarks on line %1, column %2:\n" - "%3").arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString())); - } - - BookmarkNode *toolbar = 0; - BookmarkNode *menu = 0; - QList others; - for (int i = m_bookmarkRootNode->children().count() - 1; i >= 0; --i) { - BookmarkNode *node = m_bookmarkRootNode->children().at(i); - if (node->type() == BookmarkNode::Folder) { - // Automatically convert - if (node->title == tr("Toolbar Bookmarks") && !toolbar) { - node->title = tr(BOOKMARKBAR); - } - if (node->title == tr(BOOKMARKBAR) && !toolbar) { - toolbar = node; - } - - // Automatically convert - if (node->title == tr("Menu") && !menu) { - node->title = tr(BOOKMARKMENU); - } - if (node->title == tr(BOOKMARKMENU) && !menu) { - menu = node; - } - } else { - others.append(node); - } - m_bookmarkRootNode->remove(node); - } - Q_ASSERT(m_bookmarkRootNode->children().count() == 0); - if (!toolbar) { - toolbar = new BookmarkNode(BookmarkNode::Folder, m_bookmarkRootNode); - toolbar->title = tr(BOOKMARKBAR); - } else { - m_bookmarkRootNode->add(toolbar); - } - - if (!menu) { - menu = new BookmarkNode(BookmarkNode::Folder, m_bookmarkRootNode); - menu->title = tr(BOOKMARKMENU); - } else { - m_bookmarkRootNode->add(menu); - } - - for (int i = 0; i < others.count(); ++i) - menu->add(others.at(i)); -} - -void BookmarksManager::save() const -{ - if (!m_loaded) - return; - - XbelWriter writer; - QString dir = QDesktopServices::storageLocation(QDesktopServices::DataLocation); - QString bookmarkFile = dir + QLatin1String("/bookmarks.xbel"); - if (!writer.write(bookmarkFile, m_bookmarkRootNode)) - qWarning() << "BookmarkManager: error saving to" << bookmarkFile; -} - -void BookmarksManager::addBookmark(BookmarkNode *parent, BookmarkNode *node, int row) -{ - if (!m_loaded) - return; - Q_ASSERT(parent); - InsertBookmarksCommand *command = new InsertBookmarksCommand(this, parent, node, row); - m_commands.push(command); -} - -void BookmarksManager::removeBookmark(BookmarkNode *node) -{ - if (!m_loaded) - return; - - Q_ASSERT(node); - BookmarkNode *parent = node->parent(); - int row = parent->children().indexOf(node); - RemoveBookmarksCommand *command = new RemoveBookmarksCommand(this, parent, row); - m_commands.push(command); -} - -void BookmarksManager::setTitle(BookmarkNode *node, const QString &newTitle) -{ - if (!m_loaded) - return; - - Q_ASSERT(node); - ChangeBookmarkCommand *command = new ChangeBookmarkCommand(this, node, newTitle, true); - m_commands.push(command); -} - -void BookmarksManager::setUrl(BookmarkNode *node, const QString &newUrl) -{ - if (!m_loaded) - return; - - Q_ASSERT(node); - ChangeBookmarkCommand *command = new ChangeBookmarkCommand(this, node, newUrl, false); - m_commands.push(command); -} - -BookmarkNode *BookmarksManager::bookmarks() -{ - if (!m_loaded) - load(); - return m_bookmarkRootNode; -} - -BookmarkNode *BookmarksManager::menu() -{ - if (!m_loaded) - load(); - - for (int i = m_bookmarkRootNode->children().count() - 1; i >= 0; --i) { - BookmarkNode *node = m_bookmarkRootNode->children().at(i); - if (node->title == tr(BOOKMARKMENU)) - return node; - } - Q_ASSERT(false); - return 0; -} - -BookmarkNode *BookmarksManager::toolbar() -{ - if (!m_loaded) - load(); - - for (int i = m_bookmarkRootNode->children().count() - 1; i >= 0; --i) { - BookmarkNode *node = m_bookmarkRootNode->children().at(i); - if (node->title == tr(BOOKMARKBAR)) - return node; - } - Q_ASSERT(false); - return 0; -} - -BookmarksModel *BookmarksManager::bookmarksModel() -{ - if (!m_bookmarkModel) - m_bookmarkModel = new BookmarksModel(this, this); - return m_bookmarkModel; -} - -void BookmarksManager::importBookmarks() -{ - QString fileName = QFileDialog::getOpenFileName(0, tr("Open File"), - QString(), - tr("XBEL (*.xbel *.xml)")); - if (fileName.isEmpty()) - return; - - XbelReader reader; - BookmarkNode *importRootNode = reader.read(fileName); - if (reader.error() != QXmlStreamReader::NoError) { - QMessageBox::warning(0, QLatin1String("Loading Bookmark"), - tr("Error when loading bookmarks on line %1, column %2:\n" - "%3").arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString())); - } - - importRootNode->setType(BookmarkNode::Folder); - importRootNode->title = (tr("Imported %1").arg(QDate::currentDate().toString(Qt::SystemLocaleShortDate))); - addBookmark(menu(), importRootNode); -} - -void BookmarksManager::exportBookmarks() -{ - QString fileName = QFileDialog::getSaveFileName(0, tr("Save File"), - tr("%1 Bookmarks.xbel").arg(QCoreApplication::applicationName()), - tr("XBEL (*.xbel *.xml)")); - if (fileName.isEmpty()) - return; - - XbelWriter writer; - if (!writer.write(fileName, m_bookmarkRootNode)) - QMessageBox::critical(0, tr("Export error"), tr("error saving bookmarks")); -} - -RemoveBookmarksCommand::RemoveBookmarksCommand(BookmarksManager *m_bookmarkManagaer, BookmarkNode *parent, int row) - : QUndoCommand(BookmarksManager::tr("Remove Bookmark")) - , m_row(row) - , m_bookmarkManagaer(m_bookmarkManagaer) - , m_node(parent->children().value(row)) - , m_parent(parent) - , m_done(false) -{ -} - -RemoveBookmarksCommand::~RemoveBookmarksCommand() -{ - if (m_done && !m_node->parent()) { - delete m_node; - } -} - -void RemoveBookmarksCommand::undo() -{ - m_parent->add(m_node, m_row); - emit m_bookmarkManagaer->entryAdded(m_node); - m_done = false; -} - -void RemoveBookmarksCommand::redo() -{ - m_parent->remove(m_node); - emit m_bookmarkManagaer->entryRemoved(m_parent, m_row, m_node); - m_done = true; -} - -InsertBookmarksCommand::InsertBookmarksCommand(BookmarksManager *m_bookmarkManagaer, - BookmarkNode *parent, BookmarkNode *node, int row) - : RemoveBookmarksCommand(m_bookmarkManagaer, parent, row) -{ - setText(BookmarksManager::tr("Insert Bookmark")); - m_node = node; -} - -ChangeBookmarkCommand::ChangeBookmarkCommand(BookmarksManager *m_bookmarkManagaer, BookmarkNode *node, - const QString &newValue, bool title) - : QUndoCommand() - , m_bookmarkManagaer(m_bookmarkManagaer) - , m_title(title) - , m_newValue(newValue) - , m_node(node) -{ - if (m_title) { - m_oldValue = m_node->title; - setText(BookmarksManager::tr("Name Change")); - } else { - m_oldValue = m_node->url; - setText(BookmarksManager::tr("Address Change")); - } -} - -void ChangeBookmarkCommand::undo() -{ - if (m_title) - m_node->title = m_oldValue; - else - m_node->url = m_oldValue; - emit m_bookmarkManagaer->entryChanged(m_node); -} - -void ChangeBookmarkCommand::redo() -{ - if (m_title) - m_node->title = m_newValue; - else - m_node->url = m_newValue; - emit m_bookmarkManagaer->entryChanged(m_node); -} - -BookmarksModel::BookmarksModel(BookmarksManager *bookmarkManager, QObject *parent) - : QAbstractItemModel(parent) - , m_endMacro(false) - , m_bookmarksManager(bookmarkManager) -{ - connect(bookmarkManager, SIGNAL(entryAdded(BookmarkNode *)), - this, SLOT(entryAdded(BookmarkNode *))); - connect(bookmarkManager, SIGNAL(entryRemoved(BookmarkNode *, int, BookmarkNode *)), - this, SLOT(entryRemoved(BookmarkNode *, int, BookmarkNode *))); - connect(bookmarkManager, SIGNAL(entryChanged(BookmarkNode *)), - this, SLOT(entryChanged(BookmarkNode *))); -} - -QModelIndex BookmarksModel::index(BookmarkNode *node) const -{ - BookmarkNode *parent = node->parent(); - if (!parent) - return QModelIndex(); - return createIndex(parent->children().indexOf(node), 0, node); -} - -void BookmarksModel::entryAdded(BookmarkNode *item) -{ - Q_ASSERT(item && item->parent()); - int row = item->parent()->children().indexOf(item); - BookmarkNode *parent = item->parent(); - // item was already added so remove beore beginInsertRows is called - parent->remove(item); - beginInsertRows(index(parent), row, row); - parent->add(item, row); - endInsertRows(); -} - -void BookmarksModel::entryRemoved(BookmarkNode *parent, int row, BookmarkNode *item) -{ - // item was already removed, re-add so beginRemoveRows works - parent->add(item, row); - beginRemoveRows(index(parent), row, row); - parent->remove(item); - endRemoveRows(); -} - -void BookmarksModel::entryChanged(BookmarkNode *item) -{ - QModelIndex idx = index(item); - emit dataChanged(idx, idx); -} - -bool BookmarksModel::removeRows(int row, int count, const QModelIndex &parent) -{ - if (row < 0 || count <= 0 || row + count > rowCount(parent)) - return false; - - BookmarkNode *bookmarkNode = node(parent); - for (int i = row + count - 1; i >= row; --i) { - BookmarkNode *node = bookmarkNode->children().at(i); - if (node == m_bookmarksManager->menu() - || node == m_bookmarksManager->toolbar()) - continue; - - m_bookmarksManager->removeBookmark(node); - } - if (m_endMacro) { - m_bookmarksManager->undoRedoStack()->endMacro(); - m_endMacro = false; - } - return true; -} - -QVariant BookmarksModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { - switch (section) { - case 0: return tr("Title"); - case 1: return tr("Address"); - } - } - return QAbstractItemModel::headerData(section, orientation, role); -} - -QVariant BookmarksModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid() || index.model() != this) - return QVariant(); - - const BookmarkNode *bookmarkNode = node(index); - switch (role) { - case Qt::EditRole: - case Qt::DisplayRole: - if (bookmarkNode->type() == BookmarkNode::Separator) { - switch (index.column()) { - case 0: return QString(50, 0xB7); - case 1: return QString(); - } - } - - switch (index.column()) { - case 0: return bookmarkNode->title; - case 1: return bookmarkNode->url; - } - break; - case BookmarksModel::UrlRole: - return QUrl(bookmarkNode->url); - break; - case BookmarksModel::UrlStringRole: - return bookmarkNode->url; - break; - case BookmarksModel::TypeRole: - return bookmarkNode->type(); - break; - case BookmarksModel::SeparatorRole: - return (bookmarkNode->type() == BookmarkNode::Separator); - break; - case Qt::DecorationRole: - if (index.column() == 0) { - if (bookmarkNode->type() == BookmarkNode::Folder) - return QApplication::style()->standardIcon(QStyle::SP_DirIcon); - return BrowserApplication::instance()->icon(bookmarkNode->url); - } - } - - return QVariant(); -} - -int BookmarksModel::columnCount(const QModelIndex &parent) const -{ - return (parent.column() > 0) ? 0 : 2; -} - -int BookmarksModel::rowCount(const QModelIndex &parent) const -{ - if (parent.column() > 0) - return 0; - - if (!parent.isValid()) - return m_bookmarksManager->bookmarks()->children().count(); - - const BookmarkNode *item = static_cast(parent.internalPointer()); - return item->children().count(); -} - -QModelIndex BookmarksModel::index(int row, int column, const QModelIndex &parent) const -{ - if (row < 0 || column < 0 || row >= rowCount(parent) || column >= columnCount(parent)) - return QModelIndex(); - - // get the parent node - BookmarkNode *parentNode = node(parent); - return createIndex(row, column, parentNode->children().at(row)); -} - -QModelIndex BookmarksModel::parent(const QModelIndex &index) const -{ - if (!index.isValid()) - return QModelIndex(); - - BookmarkNode *itemNode = node(index); - BookmarkNode *parentNode = (itemNode ? itemNode->parent() : 0); - if (!parentNode || parentNode == m_bookmarksManager->bookmarks()) - return QModelIndex(); - - // get the parent's row - BookmarkNode *grandParentNode = parentNode->parent(); - int parentRow = grandParentNode->children().indexOf(parentNode); - Q_ASSERT(parentRow >= 0); - return createIndex(parentRow, 0, parentNode); -} - -bool BookmarksModel::hasChildren(const QModelIndex &parent) const -{ - if (!parent.isValid()) - return true; - const BookmarkNode *parentNode = node(parent); - return (parentNode->type() == BookmarkNode::Folder); -} - -Qt::ItemFlags BookmarksModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - return Qt::NoItemFlags; - - Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled; - - BookmarkNode *bookmarkNode = node(index); - - if (bookmarkNode != m_bookmarksManager->menu() - && bookmarkNode != m_bookmarksManager->toolbar()) { - flags |= Qt::ItemIsDragEnabled; - if (bookmarkNode->type() != BookmarkNode::Separator) - flags |= Qt::ItemIsEditable; - } - if (hasChildren(index)) - flags |= Qt::ItemIsDropEnabled; - return flags; -} - -Qt::DropActions BookmarksModel::supportedDropActions () const -{ - return Qt::CopyAction | Qt::MoveAction; -} - -#define MIMETYPE QLatin1String("application/bookmarks.xbel") - -QStringList BookmarksModel::mimeTypes() const -{ - QStringList types; - types << MIMETYPE; - return types; -} - -QMimeData *BookmarksModel::mimeData(const QModelIndexList &indexes) const -{ - QMimeData *mimeData = new QMimeData(); - QByteArray data; - QDataStream stream(&data, QIODevice::WriteOnly); - foreach (QModelIndex index, indexes) { - if (index.column() != 0 || !index.isValid()) - continue; - QByteArray encodedData; - QBuffer buffer(&encodedData); - buffer.open(QBuffer::ReadWrite); - XbelWriter writer; - const BookmarkNode *parentNode = node(index); - writer.write(&buffer, parentNode); - stream << encodedData; - } - mimeData->setData(MIMETYPE, data); - return mimeData; -} - -bool BookmarksModel::dropMimeData(const QMimeData *data, - Qt::DropAction action, int row, int column, const QModelIndex &parent) -{ - if (action == Qt::IgnoreAction) - return true; - - if (!data->hasFormat(MIMETYPE) - || column > 0) - return false; - - QByteArray ba = data->data(MIMETYPE); - QDataStream stream(&ba, QIODevice::ReadOnly); - if (stream.atEnd()) - return false; - - QUndoStack *undoStack = m_bookmarksManager->undoRedoStack(); - undoStack->beginMacro(QLatin1String("Move Bookmarks")); - - while (!stream.atEnd()) { - QByteArray encodedData; - stream >> encodedData; - QBuffer buffer(&encodedData); - buffer.open(QBuffer::ReadOnly); - - XbelReader reader; - BookmarkNode *rootNode = reader.read(&buffer); - QList children = rootNode->children(); - for (int i = 0; i < children.count(); ++i) { - BookmarkNode *bookmarkNode = children.at(i); - rootNode->remove(bookmarkNode); - row = qMax(0, row); - BookmarkNode *parentNode = node(parent); - m_bookmarksManager->addBookmark(parentNode, bookmarkNode, row); - m_endMacro = true; - } - delete rootNode; - } - return true; -} - -bool BookmarksModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (!index.isValid() || (flags(index) & Qt::ItemIsEditable) == 0) - return false; - - BookmarkNode *item = node(index); - - switch (role) { - case Qt::EditRole: - case Qt::DisplayRole: - if (index.column() == 0) { - m_bookmarksManager->setTitle(item, value.toString()); - break; - } - if (index.column() == 1) { - m_bookmarksManager->setUrl(item, value.toString()); - break; - } - return false; - case BookmarksModel::UrlRole: - m_bookmarksManager->setUrl(item, value.toUrl().toString()); - break; - case BookmarksModel::UrlStringRole: - m_bookmarksManager->setUrl(item, value.toString()); - break; - default: - break; - return false; - } - - return true; -} - -BookmarkNode *BookmarksModel::node(const QModelIndex &index) const -{ - BookmarkNode *itemNode = static_cast(index.internalPointer()); - if (!itemNode) - return m_bookmarksManager->bookmarks(); - return itemNode; -} - - -AddBookmarkProxyModel::AddBookmarkProxyModel(QObject *parent) - : QSortFilterProxyModel(parent) -{ -} - -int AddBookmarkProxyModel::columnCount(const QModelIndex &parent) const -{ - return qMin(1, QSortFilterProxyModel::columnCount(parent)); -} - -bool AddBookmarkProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const -{ - QModelIndex idx = sourceModel()->index(source_row, 0, source_parent); - return sourceModel()->hasChildren(idx); -} - -AddBookmarkDialog::AddBookmarkDialog(const QString &url, const QString &title, QWidget *parent, BookmarksManager *bookmarkManager) - : QDialog(parent) - , m_url(url) - , m_bookmarksManager(bookmarkManager) -{ - setWindowFlags(Qt::Sheet); - if (!m_bookmarksManager) - m_bookmarksManager = BrowserApplication::bookmarksManager(); - setupUi(this); - QTreeView *view = new QTreeView(this); - m_proxyModel = new AddBookmarkProxyModel(this); - BookmarksModel *model = m_bookmarksManager->bookmarksModel(); - m_proxyModel->setSourceModel(model); - view->setModel(m_proxyModel); - view->expandAll(); - view->header()->setStretchLastSection(true); - view->header()->hide(); - view->setItemsExpandable(false); - view->setRootIsDecorated(false); - view->setIndentation(10); - location->setModel(m_proxyModel); - view->show(); - location->setView(view); - BookmarkNode *menu = m_bookmarksManager->menu(); - QModelIndex idx = m_proxyModel->mapFromSource(model->index(menu)); - view->setCurrentIndex(idx); - location->setCurrentIndex(idx.row()); - name->setText(title); -} - -void AddBookmarkDialog::accept() -{ - QModelIndex index = location->view()->currentIndex(); - index = m_proxyModel->mapToSource(index); - if (!index.isValid()) - index = m_bookmarksManager->bookmarksModel()->index(0, 0); - BookmarkNode *parent = m_bookmarksManager->bookmarksModel()->node(index); - BookmarkNode *bookmark = new BookmarkNode(BookmarkNode::Bookmark); - bookmark->url = m_url; - bookmark->title = name->text(); - m_bookmarksManager->addBookmark(parent, bookmark); - QDialog::accept(); -} - -BookmarksMenu::BookmarksMenu(QWidget *parent) - : ModelMenu(parent) - , m_bookmarksManager(0) -{ - connect(this, SIGNAL(activated(const QModelIndex &)), - this, SLOT(activated(const QModelIndex &))); - setMaxRows(-1); - setHoverRole(BookmarksModel::UrlStringRole); - setSeparatorRole(BookmarksModel::SeparatorRole); -} - -void BookmarksMenu::activated(const QModelIndex &index) -{ - emit openUrl(index.data(BookmarksModel::UrlRole).toUrl()); -} - -bool BookmarksMenu::prePopulated() -{ - m_bookmarksManager = BrowserApplication::bookmarksManager(); - setModel(m_bookmarksManager->bookmarksModel()); - setRootIndex(m_bookmarksManager->bookmarksModel()->index(1, 0)); - // initial actions - for (int i = 0; i < m_initialActions.count(); ++i) - addAction(m_initialActions.at(i)); - if (!m_initialActions.isEmpty()) - addSeparator(); - createMenu(model()->index(0, 0), 1, this); - return true; -} - -void BookmarksMenu::setInitialActions(QList actions) -{ - m_initialActions = actions; - for (int i = 0; i < m_initialActions.count(); ++i) - addAction(m_initialActions.at(i)); -} - -BookmarksDialog::BookmarksDialog(QWidget *parent, BookmarksManager *manager) - : QDialog(parent) -{ - m_bookmarksManager = manager; - if (!m_bookmarksManager) - m_bookmarksManager = BrowserApplication::bookmarksManager(); - setupUi(this); - - tree->setUniformRowHeights(true); - tree->setSelectionBehavior(QAbstractItemView::SelectRows); - tree->setSelectionMode(QAbstractItemView::ContiguousSelection); - tree->setTextElideMode(Qt::ElideMiddle); - m_bookmarksModel = m_bookmarksManager->bookmarksModel(); - m_proxyModel = new TreeProxyModel(this); - connect(search, SIGNAL(textChanged(QString)), - m_proxyModel, SLOT(setFilterFixedString(QString))); - connect(removeButton, SIGNAL(clicked()), tree, SLOT(removeOne())); - m_proxyModel->setSourceModel(m_bookmarksModel); - tree->setModel(m_proxyModel); - tree->setDragDropMode(QAbstractItemView::InternalMove); - tree->setExpanded(m_proxyModel->index(0, 0), true); - tree->setAlternatingRowColors(true); - QFontMetrics fm(font()); - int header = fm.width(QLatin1Char('m')) * 40; - tree->header()->resizeSection(0, header); - tree->header()->setStretchLastSection(true); - connect(tree, SIGNAL(activated(const QModelIndex&)), - this, SLOT(open())); - tree->setContextMenuPolicy(Qt::CustomContextMenu); - connect(tree, SIGNAL(customContextMenuRequested(const QPoint &)), - this, SLOT(customContextMenuRequested(const QPoint &))); - connect(addFolderButton, SIGNAL(clicked()), - this, SLOT(newFolder())); - expandNodes(m_bookmarksManager->bookmarks()); - setAttribute(Qt::WA_DeleteOnClose); -} - -BookmarksDialog::~BookmarksDialog() -{ - if (saveExpandedNodes(tree->rootIndex())) - m_bookmarksManager->changeExpanded(); -} - -bool BookmarksDialog::saveExpandedNodes(const QModelIndex &parent) -{ - bool changed = false; - for (int i = 0; i < m_proxyModel->rowCount(parent); ++i) { - QModelIndex child = m_proxyModel->index(i, 0, parent); - QModelIndex sourceIndex = m_proxyModel->mapToSource(child); - BookmarkNode *childNode = m_bookmarksModel->node(sourceIndex); - bool wasExpanded = childNode->expanded; - if (tree->isExpanded(child)) { - childNode->expanded = true; - changed |= saveExpandedNodes(child); - } else { - childNode->expanded = false; - } - changed |= (wasExpanded != childNode->expanded); - } - return changed; -} - -void BookmarksDialog::expandNodes(BookmarkNode *node) -{ - for (int i = 0; i < node->children().count(); ++i) { - BookmarkNode *childNode = node->children()[i]; - if (childNode->expanded) { - QModelIndex idx = m_bookmarksModel->index(childNode); - idx = m_proxyModel->mapFromSource(idx); - tree->setExpanded(idx, true); - expandNodes(childNode); - } - } -} - -void BookmarksDialog::customContextMenuRequested(const QPoint &pos) -{ - QMenu menu; - QModelIndex index = tree->indexAt(pos); - index = index.sibling(index.row(), 0); - if (index.isValid() && !tree->model()->hasChildren(index)) { - menu.addAction(tr("Open"), this, SLOT(open())); - menu.addSeparator(); - } - menu.addAction(tr("Delete"), tree, SLOT(removeOne())); - menu.exec(QCursor::pos()); -} - -void BookmarksDialog::open() -{ - QModelIndex index = tree->currentIndex(); - if (!index.parent().isValid()) - return; - emit openUrl(index.sibling(index.row(), 1).data(BookmarksModel::UrlRole).toUrl()); -} - -void BookmarksDialog::newFolder() -{ - QModelIndex currentIndex = tree->currentIndex(); - QModelIndex idx = currentIndex; - if (idx.isValid() && !idx.model()->hasChildren(idx)) - idx = idx.parent(); - if (!idx.isValid()) - idx = tree->rootIndex(); - idx = m_proxyModel->mapToSource(idx); - BookmarkNode *parent = m_bookmarksManager->bookmarksModel()->node(idx); - BookmarkNode *node = new BookmarkNode(BookmarkNode::Folder); - node->title = tr("New Folder"); - m_bookmarksManager->addBookmark(parent, node, currentIndex.row() + 1); -} - -BookmarksToolBar::BookmarksToolBar(BookmarksModel *model, QWidget *parent) - : QToolBar(tr("Bookmark"), parent) - , m_bookmarksModel(model) -{ - connect(this, SIGNAL(actionTriggered(QAction*)), this, SLOT(triggered(QAction*))); - setRootIndex(model->index(0, 0)); - connect(m_bookmarksModel, SIGNAL(modelReset()), this, SLOT(build())); - connect(m_bookmarksModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(build())); - connect(m_bookmarksModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(build())); - connect(m_bookmarksModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(build())); - setAcceptDrops(true); -} - -void BookmarksToolBar::dragEnterEvent(QDragEnterEvent *event) -{ - const QMimeData *mimeData = event->mimeData(); - if (mimeData->hasUrls()) - event->acceptProposedAction(); - QToolBar::dragEnterEvent(event); -} - -void BookmarksToolBar::dropEvent(QDropEvent *event) -{ - const QMimeData *mimeData = event->mimeData(); - if (mimeData->hasUrls() && mimeData->hasText()) { - QList urls = mimeData->urls(); - QAction *action = actionAt(event->pos()); - QString dropText; - if (action) - dropText = action->text(); - int row = -1; - QModelIndex parentIndex = m_root; - for (int i = 0; i < m_bookmarksModel->rowCount(m_root); ++i) { - QModelIndex idx = m_bookmarksModel->index(i, 0, m_root); - QString title = idx.data().toString(); - if (title == dropText) { - row = i; - if (m_bookmarksModel->hasChildren(idx)) { - parentIndex = idx; - row = -1; - } - break; - } - } - BookmarkNode *bookmark = new BookmarkNode(BookmarkNode::Bookmark); - bookmark->url = urls.at(0).toString(); - bookmark->title = mimeData->text(); - - BookmarkNode *parent = m_bookmarksModel->node(parentIndex); - BookmarksManager *bookmarksManager = m_bookmarksModel->bookmarksManager(); - bookmarksManager->addBookmark(parent, bookmark, row); - event->acceptProposedAction(); - } - QToolBar::dropEvent(event); -} - - -void BookmarksToolBar::setRootIndex(const QModelIndex &index) -{ - m_root = index; - build(); -} - -QModelIndex BookmarksToolBar::rootIndex() const -{ - return m_root; -} - -void BookmarksToolBar::build() -{ - clear(); - for (int i = 0; i < m_bookmarksModel->rowCount(m_root); ++i) { - QModelIndex idx = m_bookmarksModel->index(i, 0, m_root); - if (m_bookmarksModel->hasChildren(idx)) { - QToolButton *button = new QToolButton(this); - button->setPopupMode(QToolButton::InstantPopup); - button->setArrowType(Qt::DownArrow); - button->setText(idx.data().toString()); - ModelMenu *menu = new ModelMenu(this); - connect(menu, SIGNAL(activated(const QModelIndex &)), - this, SLOT(activated(const QModelIndex &))); - menu->setModel(m_bookmarksModel); - menu->setRootIndex(idx); - menu->addAction(new QAction(menu)); - button->setMenu(menu); - button->setToolButtonStyle(Qt::ToolButtonTextOnly); - QAction *a = addWidget(button); - a->setText(idx.data().toString()); - } else { - QAction *action = addAction(idx.data().toString()); - action->setData(idx.data(BookmarksModel::UrlRole)); - } - } -} - -void BookmarksToolBar::triggered(QAction *action) -{ - QVariant v = action->data(); - if (v.canConvert()) { - emit openUrl(v.toUrl()); - } -} - -void BookmarksToolBar::activated(const QModelIndex &index) -{ - emit openUrl(index.data(BookmarksModel::UrlRole).toUrl()); -} - diff --git a/examples/gestures/browser/bookmarks.h b/examples/gestures/browser/bookmarks.h deleted file mode 100644 index 7fcdae1..0000000 --- a/examples/gestures/browser/bookmarks.h +++ /dev/null @@ -1,310 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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$ -** -****************************************************************************/ - -#ifndef BOOKMARKS_H -#define BOOKMARKS_H - -#include -#include - -#include - -/*! - Bookmark manager, owner of the bookmarks, loads, saves and basic tasks - */ -class AutoSaver; -class BookmarkNode; -class BookmarksModel; -class BookmarksManager : public QObject -{ - Q_OBJECT - -signals: - void entryAdded(BookmarkNode *item); - void entryRemoved(BookmarkNode *parent, int row, BookmarkNode *item); - void entryChanged(BookmarkNode *item); - -public: - BookmarksManager(QObject *parent = 0); - ~BookmarksManager(); - - void addBookmark(BookmarkNode *parent, BookmarkNode *node, int row = -1); - void removeBookmark(BookmarkNode *node); - void setTitle(BookmarkNode *node, const QString &newTitle); - void setUrl(BookmarkNode *node, const QString &newUrl); - void changeExpanded(); - - BookmarkNode *bookmarks(); - BookmarkNode *menu(); - BookmarkNode *toolbar(); - - BookmarksModel *bookmarksModel(); - QUndoStack *undoRedoStack() { return &m_commands; }; - -public slots: - void importBookmarks(); - void exportBookmarks(); - -private slots: - void save() const; - -private: - void load(); - - bool m_loaded; - AutoSaver *m_saveTimer; - BookmarkNode *m_bookmarkRootNode; - BookmarksModel *m_bookmarkModel; - QUndoStack m_commands; - - friend class RemoveBookmarksCommand; - friend class ChangeBookmarkCommand; -}; - -class RemoveBookmarksCommand : public QUndoCommand -{ - -public: - RemoveBookmarksCommand(BookmarksManager *m_bookmarkManagaer, BookmarkNode *parent, int row); - ~RemoveBookmarksCommand(); - void undo(); - void redo(); - -protected: - int m_row; - BookmarksManager *m_bookmarkManagaer; - BookmarkNode *m_node; - BookmarkNode *m_parent; - bool m_done; -}; - -class InsertBookmarksCommand : public RemoveBookmarksCommand -{ - -public: - InsertBookmarksCommand(BookmarksManager *m_bookmarkManagaer, - BookmarkNode *parent, BookmarkNode *node, int row); - void undo() { RemoveBookmarksCommand::redo(); } - void redo() { RemoveBookmarksCommand::undo(); } - -}; - -class ChangeBookmarkCommand : public QUndoCommand -{ - -public: - ChangeBookmarkCommand(BookmarksManager *m_bookmarkManagaer, - BookmarkNode *node, const QString &newValue, bool title); - void undo(); - void redo(); - -private: - BookmarksManager *m_bookmarkManagaer; - bool m_title; - QString m_oldValue; - QString m_newValue; - BookmarkNode *m_node; -}; - -/*! - BookmarksModel is a QAbstractItemModel wrapper around the BookmarkManager - */ -#include -class BookmarksModel : public QAbstractItemModel -{ - Q_OBJECT - -public slots: - void entryAdded(BookmarkNode *item); - void entryRemoved(BookmarkNode *parent, int row, BookmarkNode *item); - void entryChanged(BookmarkNode *item); - -public: - enum Roles { - TypeRole = Qt::UserRole + 1, - UrlRole = Qt::UserRole + 2, - UrlStringRole = Qt::UserRole + 3, - SeparatorRole = Qt::UserRole + 4 - }; - - BookmarksModel(BookmarksManager *bookmarkManager, QObject *parent = 0); - inline BookmarksManager *bookmarksManager() const { return m_bookmarksManager; } - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - QModelIndex index(int, int, const QModelIndex& = QModelIndex()) const; - QModelIndex parent(const QModelIndex& index= QModelIndex()) const; - Qt::ItemFlags flags(const QModelIndex &index) const; - Qt::DropActions supportedDropActions () const; - bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - QMimeData *mimeData(const QModelIndexList &indexes) const; - QStringList mimeTypes() const; - bool dropMimeData(const QMimeData *data, - Qt::DropAction action, int row, int column, const QModelIndex &parent); - bool hasChildren(const QModelIndex &parent = QModelIndex()) const; - - BookmarkNode *node(const QModelIndex &index) const; - QModelIndex index(BookmarkNode *node) const; - -private: - - bool m_endMacro; - BookmarksManager *m_bookmarksManager; -}; - -// Menu that is dynamically populated from the bookmarks -#include "modelmenu.h" -class BookmarksMenu : public ModelMenu -{ - Q_OBJECT - -signals: - void openUrl(const QUrl &url); - -public: - BookmarksMenu(QWidget *parent = 0); - void setInitialActions(QList actions); - -protected: - bool prePopulated(); - -private slots: - void activated(const QModelIndex &index); - -private: - BookmarksManager *m_bookmarksManager; - QList m_initialActions; -}; - -/* - Proxy model that filters out the bookmarks so only the folders - are left behind. Used in the add bookmark dialog combobox. - */ -#include -class AddBookmarkProxyModel : public QSortFilterProxyModel -{ - Q_OBJECT -public: - AddBookmarkProxyModel(QObject * parent = 0); - int columnCount(const QModelIndex & parent = QModelIndex()) const; - -protected: - bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; -}; - -/*! - Add bookmark dialog - */ -#include "ui_addbookmarkdialog.h" -class AddBookmarkDialog : public QDialog, public Ui_AddBookmarkDialog -{ - Q_OBJECT - -public: - AddBookmarkDialog(const QString &url, const QString &title, QWidget *parent = 0, BookmarksManager *bookmarkManager = 0); - -private slots: - void accept(); - -private: - QString m_url; - BookmarksManager *m_bookmarksManager; - AddBookmarkProxyModel *m_proxyModel; -}; - -#include "ui_bookmarks.h" -class TreeProxyModel; -class BookmarksDialog : public QDialog, public Ui_BookmarksDialog -{ - Q_OBJECT - -signals: - void openUrl(const QUrl &url); - -public: - BookmarksDialog(QWidget *parent = 0, BookmarksManager *manager = 0); - ~BookmarksDialog(); - -private slots: - void customContextMenuRequested(const QPoint &pos); - void open(); - void newFolder(); - -private: - void expandNodes(BookmarkNode *node); - bool saveExpandedNodes(const QModelIndex &parent); - - BookmarksManager *m_bookmarksManager; - BookmarksModel *m_bookmarksModel; - TreeProxyModel *m_proxyModel; -}; - -#include -class BookmarksToolBar : public QToolBar -{ - Q_OBJECT - -signals: - void openUrl(const QUrl &url); - -public: - BookmarksToolBar(BookmarksModel *model, QWidget *parent = 0); - void setRootIndex(const QModelIndex &index); - QModelIndex rootIndex() const; - -protected: - void dragEnterEvent(QDragEnterEvent *event); - void dropEvent(QDropEvent *event); - -private slots: - void triggered(QAction *action); - void activated(const QModelIndex &index); - void build(); - -private: - BookmarksModel *m_bookmarksModel; - QPersistentModelIndex m_root; -}; - -#endif // BOOKMARKS_H diff --git a/examples/gestures/browser/bookmarks.ui b/examples/gestures/browser/bookmarks.ui deleted file mode 100644 index c893e94..0000000 --- a/examples/gestures/browser/bookmarks.ui +++ /dev/null @@ -1,106 +0,0 @@ - - BookmarksDialog - - - - 0 - 0 - 758 - 450 - - - - Bookmarks - - - - - - Qt::Horizontal - - - - 252 - 20 - - - - - - - - - - - - - - - - &Remove - - - - - - - Add Folder - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - QDialogButtonBox::Ok - - - - - - - - - - SearchLineEdit - QLineEdit -
searchlineedit.h
-
- - EditTreeView - QTreeView -
edittreeview.h
-
-
- - - - buttonBox - accepted() - BookmarksDialog - accept() - - - 472 - 329 - - - 461 - 356 - - - - -
diff --git a/examples/gestures/browser/browser.icns b/examples/gestures/browser/browser.icns deleted file mode 100644 index f591ae4..0000000 Binary files a/examples/gestures/browser/browser.icns and /dev/null differ diff --git a/examples/gestures/browser/browser.ico b/examples/gestures/browser/browser.ico deleted file mode 100644 index 7f9be93..0000000 Binary files a/examples/gestures/browser/browser.ico and /dev/null differ diff --git a/examples/gestures/browser/browser.pro b/examples/gestures/browser/browser.pro deleted file mode 100644 index d970f99..0000000 --- a/examples/gestures/browser/browser.pro +++ /dev/null @@ -1,91 +0,0 @@ -TEMPLATE = app -TARGET = browser -QT += webkit network - -CONFIG += qt warn_on -contains(QT_BUILD_PARTS, tools): CONFIG += uitools -else: DEFINES += QT_NO_UITOOLS - -FORMS += \ - addbookmarkdialog.ui \ - bookmarks.ui \ - cookies.ui \ - cookiesexceptions.ui \ - downloaditem.ui \ - downloads.ui \ - history.ui \ - passworddialog.ui \ - proxy.ui \ - settings.ui - -HEADERS += \ - autosaver.h \ - bookmarks.h \ - browserapplication.h \ - browsermainwindow.h \ - chasewidget.h \ - cookiejar.h \ - downloadmanager.h \ - edittableview.h \ - edittreeview.h \ - history.h \ - modelmenu.h \ - networkaccessmanager.h \ - searchlineedit.h \ - settings.h \ - squeezelabel.h \ - tabwidget.h \ - toolbarsearch.h \ - urllineedit.h \ - webview.h \ - xbel.h - -SOURCES += \ - autosaver.cpp \ - bookmarks.cpp \ - browserapplication.cpp \ - browsermainwindow.cpp \ - chasewidget.cpp \ - cookiejar.cpp \ - downloadmanager.cpp \ - edittableview.cpp \ - edittreeview.cpp \ - history.cpp \ - modelmenu.cpp \ - networkaccessmanager.cpp \ - searchlineedit.cpp \ - settings.cpp \ - squeezelabel.cpp \ - tabwidget.cpp \ - toolbarsearch.cpp \ - urllineedit.cpp \ - webview.cpp \ - xbel.cpp \ - main.cpp - -RESOURCES += data/data.qrc htmls/htmls.qrc - -build_all:!build_pass { - CONFIG -= build_all - CONFIG += release -} - -win32 { - RC_FILE = browser.rc -} - -mac { - ICON = browser.icns - QMAKE_INFO_PLIST = Info_mac.plist - TARGET = Browser -} - -wince*: { - DEPLOYMENT_PLUGIN += qjpeg qgif -} - -# install -target.path = $$[QT_INSTALL_DEMOS]/browser -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS *.plist *.icns *.ico *.rc *.pro *.html *.doc images htmls -sources.path = $$[QT_INSTALL_DEMOS]/browser -INSTALLS += target sources diff --git a/examples/gestures/browser/browser.rc b/examples/gestures/browser/browser.rc deleted file mode 100644 index 89a237c..0000000 --- a/examples/gestures/browser/browser.rc +++ /dev/null @@ -1,2 +0,0 @@ -IDI_ICON1 ICON DISCARDABLE "browser.ico" - diff --git a/examples/gestures/browser/browserapplication.cpp b/examples/gestures/browser/browserapplication.cpp deleted file mode 100644 index 718a8ec..0000000 --- a/examples/gestures/browser/browserapplication.cpp +++ /dev/null @@ -1,447 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 "browserapplication.h" - -#include "bookmarks.h" -#include "browsermainwindow.h" -#include "cookiejar.h" -#include "downloadmanager.h" -#include "history.h" -#include "networkaccessmanager.h" -#include "tabwidget.h" -#include "webview.h" - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include - -#include - -DownloadManager *BrowserApplication::s_downloadManager = 0; -HistoryManager *BrowserApplication::s_historyManager = 0; -NetworkAccessManager *BrowserApplication::s_networkAccessManager = 0; -BookmarksManager *BrowserApplication::s_bookmarksManager = 0; - -BrowserApplication::BrowserApplication(int &argc, char **argv) - : QApplication(argc, argv) - , m_localServer(0) -{ - QCoreApplication::setOrganizationName(QLatin1String("Trolltech")); - QCoreApplication::setApplicationName(QLatin1String("demobrowser")); - QCoreApplication::setApplicationVersion(QLatin1String("0.1")); -#ifdef Q_WS_QWS - // Use a different server name for QWS so we can run an X11 - // browser and a QWS browser in parallel on the same machine for - // debugging - QString serverName = QCoreApplication::applicationName() + QLatin1String("_qws"); -#else - QString serverName = QCoreApplication::applicationName(); -#endif - QLocalSocket socket; - socket.connectToServer(serverName); - if (socket.waitForConnected(500)) { - QTextStream stream(&socket); - QStringList args = QCoreApplication::arguments(); - if (args.count() > 1) - stream << args.last(); - else - stream << QString(); - stream.flush(); - socket.waitForBytesWritten(); - return; - } - -#if defined(Q_WS_MAC) - QApplication::setQuitOnLastWindowClosed(false); -#else - QApplication::setQuitOnLastWindowClosed(true); -#endif - - m_localServer = new QLocalServer(this); - connect(m_localServer, SIGNAL(newConnection()), - this, SLOT(newLocalSocketConnection())); - if (!m_localServer->listen(serverName)) { - if (m_localServer->serverError() == QAbstractSocket::AddressInUseError - && QFile::exists(m_localServer->serverName())) { - QFile::remove(m_localServer->serverName()); - m_localServer->listen(serverName); - } - } - - QDesktopServices::setUrlHandler(QLatin1String("http"), this, "openUrl"); - QString localSysName = QLocale::system().name(); - - installTranslator(QLatin1String("qt_") + localSysName); - - QSettings settings; - settings.beginGroup(QLatin1String("sessions")); - m_lastSession = settings.value(QLatin1String("lastSession")).toByteArray(); - settings.endGroup(); - -#if defined(Q_WS_MAC) - connect(this, SIGNAL(lastWindowClosed()), - this, SLOT(lastWindowClosed())); -#endif - - QTimer::singleShot(0, this, SLOT(postLaunch())); -} - -BrowserApplication::~BrowserApplication() -{ - delete s_downloadManager; - for (int i = 0; i < m_mainWindows.size(); ++i) { - BrowserMainWindow *window = m_mainWindows.at(i); - delete window; - } - delete s_networkAccessManager; - delete s_bookmarksManager; -} - -#if defined(Q_WS_MAC) -void BrowserApplication::lastWindowClosed() -{ - clean(); - BrowserMainWindow *mw = new BrowserMainWindow; - mw->slotHome(); - m_mainWindows.prepend(mw); -} -#endif - -BrowserApplication *BrowserApplication::instance() -{ - return (static_cast(QCoreApplication::instance())); -} - -#if defined(Q_WS_MAC) -#include -void BrowserApplication::quitBrowser() -{ - clean(); - int tabCount = 0; - for (int i = 0; i < m_mainWindows.count(); ++i) { - tabCount =+ m_mainWindows.at(i)->tabWidget()->count(); - } - - if (tabCount > 1) { - int ret = QMessageBox::warning(mainWindow(), QString(), - tr("There are %1 windows and %2 tabs open\n" - "Do you want to quit anyway?").arg(m_mainWindows.count()).arg(tabCount), - QMessageBox::Yes | QMessageBox::No, - QMessageBox::No); - if (ret == QMessageBox::No) - return; - } - - exit(0); -} -#endif - -/*! - Any actions that can be delayed until the window is visible - */ -void BrowserApplication::postLaunch() -{ - QString directory = QDesktopServices::storageLocation(QDesktopServices::DataLocation); - if (directory.isEmpty()) - directory = QDir::homePath() + QLatin1String("/.") + QCoreApplication::applicationName(); - QWebSettings::setIconDatabasePath(directory); - - setWindowIcon(QIcon(QLatin1String(":browser.svg"))); - - loadSettings(); - - // newMainWindow() needs to be called in main() for this to happen - if (m_mainWindows.count() > 0) { - QStringList args = QCoreApplication::arguments(); - if (args.count() > 1) - mainWindow()->loadPage(args.last()); - else - mainWindow()->slotHome(); - } - BrowserApplication::historyManager(); -} - -void BrowserApplication::loadSettings() -{ - QSettings settings; - settings.beginGroup(QLatin1String("websettings")); - - QWebSettings *defaultSettings = QWebSettings::globalSettings(); - QString standardFontFamily = defaultSettings->fontFamily(QWebSettings::StandardFont); - int standardFontSize = defaultSettings->fontSize(QWebSettings::DefaultFontSize); - QFont standardFont = QFont(standardFontFamily, standardFontSize); - standardFont = qVariantValue(settings.value(QLatin1String("standardFont"), standardFont)); - defaultSettings->setFontFamily(QWebSettings::StandardFont, standardFont.family()); - defaultSettings->setFontSize(QWebSettings::DefaultFontSize, standardFont.pointSize()); - - QString fixedFontFamily = defaultSettings->fontFamily(QWebSettings::FixedFont); - int fixedFontSize = defaultSettings->fontSize(QWebSettings::DefaultFixedFontSize); - QFont fixedFont = QFont(fixedFontFamily, fixedFontSize); - fixedFont = qVariantValue(settings.value(QLatin1String("fixedFont"), fixedFont)); - defaultSettings->setFontFamily(QWebSettings::FixedFont, fixedFont.family()); - defaultSettings->setFontSize(QWebSettings::DefaultFixedFontSize, fixedFont.pointSize()); - - defaultSettings->setAttribute(QWebSettings::JavascriptEnabled, settings.value(QLatin1String("enableJavascript"), true).toBool()); - defaultSettings->setAttribute(QWebSettings::PluginsEnabled, settings.value(QLatin1String("enablePlugins"), true).toBool()); - - QUrl url = settings.value(QLatin1String("userStyleSheet")).toUrl(); - defaultSettings->setUserStyleSheetUrl(url); - - settings.endGroup(); -} - -QList BrowserApplication::mainWindows() -{ - clean(); - QList list; - for (int i = 0; i < m_mainWindows.count(); ++i) - list.append(m_mainWindows.at(i)); - return list; -} - -void BrowserApplication::clean() -{ - // cleanup any deleted main windows first - for (int i = m_mainWindows.count() - 1; i >= 0; --i) - if (m_mainWindows.at(i).isNull()) - m_mainWindows.removeAt(i); -} - -void BrowserApplication::saveSession() -{ - QWebSettings *globalSettings = QWebSettings::globalSettings(); - if (globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled)) - return; - - clean(); - - QSettings settings; - settings.beginGroup(QLatin1String("sessions")); - - QByteArray data; - QBuffer buffer(&data); - QDataStream stream(&buffer); - buffer.open(QIODevice::ReadWrite); - - stream << m_mainWindows.count(); - for (int i = 0; i < m_mainWindows.count(); ++i) - stream << m_mainWindows.at(i)->saveState(); - settings.setValue(QLatin1String("lastSession"), data); - settings.endGroup(); -} - -bool BrowserApplication::canRestoreSession() const -{ - return !m_lastSession.isEmpty(); -} - -void BrowserApplication::restoreLastSession() -{ - QList windows; - QBuffer buffer(&m_lastSession); - QDataStream stream(&buffer); - buffer.open(QIODevice::ReadOnly); - int windowCount; - stream >> windowCount; - for (int i = 0; i < windowCount; ++i) { - QByteArray windowState; - stream >> windowState; - windows.append(windowState); - } - for (int i = 0; i < windows.count(); ++i) { - BrowserMainWindow *newWindow = 0; - if (m_mainWindows.count() == 1 - && mainWindow()->tabWidget()->count() == 1 - && mainWindow()->currentTab()->url() == QUrl()) { - newWindow = mainWindow(); - } else { - newWindow = newMainWindow(); - } - newWindow->restoreState(windows.at(i)); - } -} - -bool BrowserApplication::isTheOnlyBrowser() const -{ - return (m_localServer != 0); -} - -void BrowserApplication::installTranslator(const QString &name) -{ - QTranslator *translator = new QTranslator(this); - translator->load(name, QLibraryInfo::location(QLibraryInfo::TranslationsPath)); - QApplication::installTranslator(translator); -} - -#if defined(Q_WS_MAC) -bool BrowserApplication::event(QEvent* event) -{ - switch (event->type()) { - case QEvent::ApplicationActivate: { - clean(); - if (!m_mainWindows.isEmpty()) { - BrowserMainWindow *mw = mainWindow(); - if (mw && !mw->isMinimized()) { - mainWindow()->show(); - } - return true; - } - } - case QEvent::FileOpen: - if (!m_mainWindows.isEmpty()) { - mainWindow()->loadPage(static_cast(event)->file()); - return true; - } - default: - break; - } - return QApplication::event(event); -} -#endif - -void BrowserApplication::openUrl(const QUrl &url) -{ - mainWindow()->loadPage(url.toString()); -} - -BrowserMainWindow *BrowserApplication::newMainWindow() -{ - BrowserMainWindow *browser = new BrowserMainWindow(); - m_mainWindows.prepend(browser); - browser->show(); - return browser; -} - -BrowserMainWindow *BrowserApplication::mainWindow() -{ - clean(); - if (m_mainWindows.isEmpty()) - newMainWindow(); - return m_mainWindows[0]; -} - -void BrowserApplication::newLocalSocketConnection() -{ - QLocalSocket *socket = m_localServer->nextPendingConnection(); - if (!socket) - return; - socket->waitForReadyRead(1000); - QTextStream stream(socket); - QString url; - stream >> url; - if (!url.isEmpty()) { - QSettings settings; - settings.beginGroup(QLatin1String("general")); - int openLinksIn = settings.value(QLatin1String("openLinksIn"), 0).toInt(); - settings.endGroup(); - if (openLinksIn == 1) - newMainWindow(); - else - mainWindow()->tabWidget()->newTab(); - openUrl(url); - } - delete socket; - mainWindow()->raise(); - mainWindow()->activateWindow(); -} - -CookieJar *BrowserApplication::cookieJar() -{ - return (CookieJar*)networkAccessManager()->cookieJar(); -} - -DownloadManager *BrowserApplication::downloadManager() -{ - if (!s_downloadManager) { - s_downloadManager = new DownloadManager(); - } - return s_downloadManager; -} - -NetworkAccessManager *BrowserApplication::networkAccessManager() -{ - if (!s_networkAccessManager) { - s_networkAccessManager = new NetworkAccessManager(); - s_networkAccessManager->setCookieJar(new CookieJar); - } - return s_networkAccessManager; -} - -HistoryManager *BrowserApplication::historyManager() -{ - if (!s_historyManager) { - s_historyManager = new HistoryManager(); - QWebHistoryInterface::setDefaultInterface(s_historyManager); - } - return s_historyManager; -} - -BookmarksManager *BrowserApplication::bookmarksManager() -{ - if (!s_bookmarksManager) { - s_bookmarksManager = new BookmarksManager; - } - return s_bookmarksManager; -} - -QIcon BrowserApplication::icon(const QUrl &url) const -{ - QIcon icon = QWebSettings::iconForUrl(url); - if (!icon.isNull()) - return icon.pixmap(16, 16); - if (m_defaultIcon.isNull()) - m_defaultIcon = QIcon(QLatin1String(":defaulticon.png")); - return m_defaultIcon.pixmap(16, 16); -} - diff --git a/examples/gestures/browser/browserapplication.h b/examples/gestures/browser/browserapplication.h deleted file mode 100644 index db83a85..0000000 --- a/examples/gestures/browser/browserapplication.h +++ /dev/null @@ -1,119 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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$ -** -****************************************************************************/ - -#ifndef BROWSERAPPLICATION_H -#define BROWSERAPPLICATION_H - -#include - -#include -#include - -#include - -QT_BEGIN_NAMESPACE -class QLocalServer; -QT_END_NAMESPACE - -class BookmarksManager; -class BrowserMainWindow; -class CookieJar; -class DownloadManager; -class HistoryManager; -class NetworkAccessManager; -class BrowserApplication : public QApplication -{ - Q_OBJECT - -public: - BrowserApplication(int &argc, char **argv); - ~BrowserApplication(); - static BrowserApplication *instance(); - void loadSettings(); - - bool isTheOnlyBrowser() const; - BrowserMainWindow *mainWindow(); - QList mainWindows(); - QIcon icon(const QUrl &url) const; - - void saveSession(); - bool canRestoreSession() const; - - static HistoryManager *historyManager(); - static CookieJar *cookieJar(); - static DownloadManager *downloadManager(); - static NetworkAccessManager *networkAccessManager(); - static BookmarksManager *bookmarksManager(); - -#if defined(Q_WS_MAC) - bool event(QEvent *event); -#endif - -public slots: - BrowserMainWindow *newMainWindow(); - void restoreLastSession(); -#if defined(Q_WS_MAC) - void lastWindowClosed(); - void quitBrowser(); -#endif - -private slots: - void postLaunch(); - void openUrl(const QUrl &url); - void newLocalSocketConnection(); - -private: - void clean(); - void installTranslator(const QString &name); - - static HistoryManager *s_historyManager; - static DownloadManager *s_downloadManager; - static NetworkAccessManager *s_networkAccessManager; - static BookmarksManager *s_bookmarksManager; - - QList > m_mainWindows; - QLocalServer *m_localServer; - QByteArray m_lastSession; - mutable QIcon m_defaultIcon; -}; - -#endif // BROWSERAPPLICATION_H - diff --git a/examples/gestures/browser/browsermainwindow.cpp b/examples/gestures/browser/browsermainwindow.cpp deleted file mode 100644 index c6fe82d..0000000 --- a/examples/gestures/browser/browsermainwindow.cpp +++ /dev/null @@ -1,991 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 "browsermainwindow.h" - -#include "autosaver.h" -#include "bookmarks.h" -#include "browserapplication.h" -#include "chasewidget.h" -#include "downloadmanager.h" -#include "history.h" -#include "settings.h" -#include "tabwidget.h" -#include "toolbarsearch.h" -#include "ui_passworddialog.h" -#include "webview.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -BrowserMainWindow::BrowserMainWindow(QWidget *parent, Qt::WindowFlags flags) - : QMainWindow(parent, flags) - , m_tabWidget(new TabWidget(this)) - , m_autoSaver(new AutoSaver(this)) - , m_historyBack(0) - , m_historyForward(0) - , m_stop(0) - , m_reload(0) -{ - setAttribute(Qt::WA_DeleteOnClose, true); - statusBar()->setSizeGripEnabled(true); - setupMenu(); - setupToolBar(); - - QWidget *centralWidget = new QWidget(this); - BookmarksModel *boomarksModel = BrowserApplication::bookmarksManager()->bookmarksModel(); - m_bookmarksToolbar = new BookmarksToolBar(boomarksModel, this); - connect(m_bookmarksToolbar, SIGNAL(openUrl(const QUrl&)), - m_tabWidget, SLOT(loadUrlInCurrentTab(const QUrl&))); - connect(m_bookmarksToolbar->toggleViewAction(), SIGNAL(toggled(bool)), - this, SLOT(updateBookmarksToolbarActionText(bool))); - - QVBoxLayout *layout = new QVBoxLayout; - layout->setSpacing(0); - layout->setMargin(0); -#if defined(Q_WS_MAC) - layout->addWidget(m_bookmarksToolbar); - layout->addWidget(new QWidget); // <- OS X tab widget style bug -#else - addToolBarBreak(); - addToolBar(m_bookmarksToolbar); -#endif - layout->addWidget(m_tabWidget); - centralWidget->setLayout(layout); - setCentralWidget(centralWidget); - - connect(m_tabWidget, SIGNAL(loadPage(const QString &)), - this, SLOT(loadPage(const QString &))); - connect(m_tabWidget, SIGNAL(setCurrentTitle(const QString &)), - this, SLOT(slotUpdateWindowTitle(const QString &))); - connect(m_tabWidget, SIGNAL(showStatusBarMessage(const QString&)), - statusBar(), SLOT(showMessage(const QString&))); - connect(m_tabWidget, SIGNAL(linkHovered(const QString&)), - statusBar(), SLOT(showMessage(const QString&))); - connect(m_tabWidget, SIGNAL(loadProgress(int)), - this, SLOT(slotLoadProgress(int))); - connect(m_tabWidget, SIGNAL(tabsChanged()), - m_autoSaver, SLOT(changeOccurred())); - connect(m_tabWidget, SIGNAL(geometryChangeRequested(const QRect &)), - this, SLOT(geometryChangeRequested(const QRect &))); - connect(m_tabWidget, SIGNAL(printRequested(QWebFrame *)), - this, SLOT(printRequested(QWebFrame *))); - connect(m_tabWidget, SIGNAL(menuBarVisibilityChangeRequested(bool)), - menuBar(), SLOT(setVisible(bool))); - connect(m_tabWidget, SIGNAL(statusBarVisibilityChangeRequested(bool)), - statusBar(), SLOT(setVisible(bool))); - connect(m_tabWidget, SIGNAL(toolBarVisibilityChangeRequested(bool)), - m_navigationBar, SLOT(setVisible(bool))); - connect(m_tabWidget, SIGNAL(toolBarVisibilityChangeRequested(bool)), - m_bookmarksToolbar, SLOT(setVisible(bool))); -#if defined(Q_WS_MAC) - connect(m_tabWidget, SIGNAL(lastTabClosed()), - this, SLOT(close())); -#else - connect(m_tabWidget, SIGNAL(lastTabClosed()), - m_tabWidget, SLOT(newTab())); -#endif - - slotUpdateWindowTitle(); - loadDefaultState(); - m_tabWidget->newTab(); - - int size = m_tabWidget->lineEditStack()->sizeHint().height(); - m_navigationBar->setIconSize(QSize(size, size)); - -} - -BrowserMainWindow::~BrowserMainWindow() -{ - m_autoSaver->changeOccurred(); - m_autoSaver->saveIfNeccessary(); -} - -void BrowserMainWindow::loadDefaultState() -{ - QSettings settings; - settings.beginGroup(QLatin1String("BrowserMainWindow")); - QByteArray data = settings.value(QLatin1String("defaultState")).toByteArray(); - restoreState(data); - settings.endGroup(); -} - -QSize BrowserMainWindow::sizeHint() const -{ - QRect desktopRect = QApplication::desktop()->screenGeometry(); - QSize size = desktopRect.size() * qreal(0.9); - return size; -} - -void BrowserMainWindow::save() -{ - BrowserApplication::instance()->saveSession(); - - QSettings settings; - settings.beginGroup(QLatin1String("BrowserMainWindow")); - QByteArray data = saveState(false); - settings.setValue(QLatin1String("defaultState"), data); - settings.endGroup(); -} - -static const qint32 BrowserMainWindowMagic = 0xba; - -QByteArray BrowserMainWindow::saveState(bool withTabs) const -{ - int version = 2; - QByteArray data; - QDataStream stream(&data, QIODevice::WriteOnly); - - stream << qint32(BrowserMainWindowMagic); - stream << qint32(version); - - stream << size(); - stream << !m_navigationBar->isHidden(); - stream << !m_bookmarksToolbar->isHidden(); - stream << !statusBar()->isHidden(); - if (withTabs) - stream << tabWidget()->saveState(); - else - stream << QByteArray(); - return data; -} - -bool BrowserMainWindow::restoreState(const QByteArray &state) -{ - int version = 2; - QByteArray sd = state; - QDataStream stream(&sd, QIODevice::ReadOnly); - if (stream.atEnd()) - return false; - - qint32 marker; - qint32 v; - stream >> marker; - stream >> v; - if (marker != BrowserMainWindowMagic || v != version) - return false; - - QSize size; - bool showToolbar; - bool showBookmarksBar; - bool showStatusbar; - QByteArray tabState; - - stream >> size; - stream >> showToolbar; - stream >> showBookmarksBar; - stream >> showStatusbar; - stream >> tabState; - - resize(size); - - m_navigationBar->setVisible(showToolbar); - updateToolbarActionText(showToolbar); - - m_bookmarksToolbar->setVisible(showBookmarksBar); - updateBookmarksToolbarActionText(showBookmarksBar); - - statusBar()->setVisible(showStatusbar); - updateStatusbarActionText(showStatusbar); - - if (!tabWidget()->restoreState(tabState)) - return false; - - return true; -} - -void BrowserMainWindow::setupMenu() -{ - new QShortcut(QKeySequence(Qt::Key_F6), this, SLOT(slotSwapFocus())); - - // File - QMenu *fileMenu = menuBar()->addMenu(tr("&File")); - - fileMenu->addAction(tr("&New Window"), this, SLOT(slotFileNew()), QKeySequence::New); - fileMenu->addAction(m_tabWidget->newTabAction()); - fileMenu->addAction(tr("&Open File..."), this, SLOT(slotFileOpen()), QKeySequence::Open); - fileMenu->addAction(tr("Open &Location..."), this, - SLOT(slotSelectLineEdit()), QKeySequence(Qt::ControlModifier + Qt::Key_L)); - fileMenu->addSeparator(); - fileMenu->addAction(m_tabWidget->closeTabAction()); - fileMenu->addSeparator(); - fileMenu->addAction(tr("&Save As..."), this, - SLOT(slotFileSaveAs()), QKeySequence(QKeySequence::Save)); - fileMenu->addSeparator(); - BookmarksManager *bookmarksManager = BrowserApplication::bookmarksManager(); - fileMenu->addAction(tr("&Import Bookmarks..."), bookmarksManager, SLOT(importBookmarks())); - fileMenu->addAction(tr("&Export Bookmarks..."), bookmarksManager, SLOT(exportBookmarks())); - fileMenu->addSeparator(); - fileMenu->addAction(tr("P&rint Preview..."), this, SLOT(slotFilePrintPreview())); - fileMenu->addAction(tr("&Print..."), this, SLOT(slotFilePrint()), QKeySequence::Print); - fileMenu->addSeparator(); - QAction *action = fileMenu->addAction(tr("Private &Browsing..."), this, SLOT(slotPrivateBrowsing())); - action->setCheckable(true); - fileMenu->addSeparator(); - -#if defined(Q_WS_MAC) - fileMenu->addAction(tr("&Quit"), BrowserApplication::instance(), SLOT(quitBrowser()), QKeySequence(Qt::CTRL | Qt::Key_Q)); -#else - fileMenu->addAction(tr("&Quit"), this, SLOT(close()), QKeySequence(Qt::CTRL | Qt::Key_Q)); -#endif - - // Edit - QMenu *editMenu = menuBar()->addMenu(tr("&Edit")); - QAction *m_undo = editMenu->addAction(tr("&Undo")); - m_undo->setShortcuts(QKeySequence::Undo); - m_tabWidget->addWebAction(m_undo, QWebPage::Undo); - QAction *m_redo = editMenu->addAction(tr("&Redo")); - m_redo->setShortcuts(QKeySequence::Redo); - m_tabWidget->addWebAction(m_redo, QWebPage::Redo); - editMenu->addSeparator(); - QAction *m_cut = editMenu->addAction(tr("Cu&t")); - m_cut->setShortcuts(QKeySequence::Cut); - m_tabWidget->addWebAction(m_cut, QWebPage::Cut); - QAction *m_copy = editMenu->addAction(tr("&Copy")); - m_copy->setShortcuts(QKeySequence::Copy); - m_tabWidget->addWebAction(m_copy, QWebPage::Copy); - QAction *m_paste = editMenu->addAction(tr("&Paste")); - m_paste->setShortcuts(QKeySequence::Paste); - m_tabWidget->addWebAction(m_paste, QWebPage::Paste); - editMenu->addSeparator(); - - QAction *m_find = editMenu->addAction(tr("&Find")); - m_find->setShortcuts(QKeySequence::Find); - connect(m_find, SIGNAL(triggered()), this, SLOT(slotEditFind())); - new QShortcut(QKeySequence(Qt::Key_Slash), this, SLOT(slotEditFind())); - - QAction *m_findNext = editMenu->addAction(tr("&Find Next")); - m_findNext->setShortcuts(QKeySequence::FindNext); - connect(m_findNext, SIGNAL(triggered()), this, SLOT(slotEditFindNext())); - - QAction *m_findPrevious = editMenu->addAction(tr("&Find Previous")); - m_findPrevious->setShortcuts(QKeySequence::FindPrevious); - connect(m_findPrevious, SIGNAL(triggered()), this, SLOT(slotEditFindPrevious())); - - editMenu->addSeparator(); - editMenu->addAction(tr("&Preferences"), this, SLOT(slotPreferences()), tr("Ctrl+,")); - - // View - QMenu *viewMenu = menuBar()->addMenu(tr("&View")); - - m_viewBookmarkBar = new QAction(this); - updateBookmarksToolbarActionText(true); - m_viewBookmarkBar->setShortcut(tr("Shift+Ctrl+B")); - connect(m_viewBookmarkBar, SIGNAL(triggered()), this, SLOT(slotViewBookmarksBar())); - viewMenu->addAction(m_viewBookmarkBar); - - m_viewToolbar = new QAction(this); - updateToolbarActionText(true); - m_viewToolbar->setShortcut(tr("Ctrl+|")); - connect(m_viewToolbar, SIGNAL(triggered()), this, SLOT(slotViewToolbar())); - viewMenu->addAction(m_viewToolbar); - - m_viewStatusbar = new QAction(this); - updateStatusbarActionText(true); - m_viewStatusbar->setShortcut(tr("Ctrl+/")); - connect(m_viewStatusbar, SIGNAL(triggered()), this, SLOT(slotViewStatusbar())); - viewMenu->addAction(m_viewStatusbar); - - viewMenu->addSeparator(); - - m_stop = viewMenu->addAction(tr("&Stop")); - QList shortcuts; - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Period)); - shortcuts.append(Qt::Key_Escape); - m_stop->setShortcuts(shortcuts); - m_tabWidget->addWebAction(m_stop, QWebPage::Stop); - - m_reload = viewMenu->addAction(tr("Reload Page")); - m_reload->setShortcuts(QKeySequence::Refresh); - m_tabWidget->addWebAction(m_reload, QWebPage::Reload); - - viewMenu->addAction(tr("Zoom &In"), this, SLOT(slotViewZoomIn()), QKeySequence(Qt::CTRL | Qt::Key_Plus)); - viewMenu->addAction(tr("Zoom &Out"), this, SLOT(slotViewZoomOut()), QKeySequence(Qt::CTRL | Qt::Key_Minus)); - viewMenu->addAction(tr("Reset &Zoom"), this, SLOT(slotViewResetZoom()), QKeySequence(Qt::CTRL | Qt::Key_0)); - QAction *zoomTextOnlyAction = viewMenu->addAction(tr("Zoom &Text Only")); - connect(zoomTextOnlyAction, SIGNAL(toggled(bool)), this, SLOT(slotViewZoomTextOnly(bool))); - zoomTextOnlyAction->setCheckable(true); - zoomTextOnlyAction->setChecked(false); - - viewMenu->addSeparator(); - viewMenu->addAction(tr("Page S&ource"), this, SLOT(slotViewPageSource()), tr("Ctrl+Alt+U")); - QAction *a = viewMenu->addAction(tr("&Full Screen"), this, SLOT(slotViewFullScreen(bool)), Qt::Key_F11); - a->setCheckable(true); - - // History - HistoryMenu *historyMenu = new HistoryMenu(this); - connect(historyMenu, SIGNAL(openUrl(const QUrl&)), - m_tabWidget, SLOT(loadUrlInCurrentTab(const QUrl&))); - connect(historyMenu, SIGNAL(hovered(const QString&)), this, - SLOT(slotUpdateStatusbar(const QString&))); - historyMenu->setTitle(tr("Hi&story")); - menuBar()->addMenu(historyMenu); - QList historyActions; - - m_historyBack = new QAction(tr("Back"), this); - m_tabWidget->addWebAction(m_historyBack, QWebPage::Back); - m_historyBack->setShortcuts(QKeySequence::Back); - m_historyBack->setIconVisibleInMenu(false); - - m_historyForward = new QAction(tr("Forward"), this); - m_tabWidget->addWebAction(m_historyForward, QWebPage::Forward); - m_historyForward->setShortcuts(QKeySequence::Forward); - m_historyForward->setIconVisibleInMenu(false); - - QAction *m_historyHome = new QAction(tr("Home"), this); - connect(m_historyHome, SIGNAL(triggered()), this, SLOT(slotHome())); - m_historyHome->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_H)); - - m_restoreLastSession = new QAction(tr("Restore Last Session"), this); - connect(m_restoreLastSession, SIGNAL(triggered()), BrowserApplication::instance(), SLOT(restoreLastSession())); - m_restoreLastSession->setEnabled(BrowserApplication::instance()->canRestoreSession()); - - historyActions.append(m_historyBack); - historyActions.append(m_historyForward); - historyActions.append(m_historyHome); - historyActions.append(m_tabWidget->recentlyClosedTabsAction()); - historyActions.append(m_restoreLastSession); - historyMenu->setInitialActions(historyActions); - - // Bookmarks - BookmarksMenu *bookmarksMenu = new BookmarksMenu(this); - connect(bookmarksMenu, SIGNAL(openUrl(const QUrl&)), - m_tabWidget, SLOT(loadUrlInCurrentTab(const QUrl&))); - connect(bookmarksMenu, SIGNAL(hovered(const QString&)), - this, SLOT(slotUpdateStatusbar(const QString&))); - bookmarksMenu->setTitle(tr("&Bookmarks")); - menuBar()->addMenu(bookmarksMenu); - - QList bookmarksActions; - - QAction *showAllBookmarksAction = new QAction(tr("Show All Bookmarks"), this); - connect(showAllBookmarksAction, SIGNAL(triggered()), this, SLOT(slotShowBookmarksDialog())); - m_addBookmark = new QAction(QIcon(QLatin1String(":addbookmark.png")), tr("Add Bookmark..."), this); - m_addBookmark->setIconVisibleInMenu(false); - - connect(m_addBookmark, SIGNAL(triggered()), this, SLOT(slotAddBookmark())); - m_addBookmark->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_D)); - - bookmarksActions.append(showAllBookmarksAction); - bookmarksActions.append(m_addBookmark); - bookmarksMenu->setInitialActions(bookmarksActions); - - // Window - m_windowMenu = menuBar()->addMenu(tr("&Window")); - connect(m_windowMenu, SIGNAL(aboutToShow()), - this, SLOT(slotAboutToShowWindowMenu())); - slotAboutToShowWindowMenu(); - - QMenu *toolsMenu = menuBar()->addMenu(tr("&Tools")); - toolsMenu->addAction(tr("Web &Search"), this, SLOT(slotWebSearch()), QKeySequence(tr("Ctrl+K", "Web Search"))); -#ifndef Q_CC_MINGW - a = toolsMenu->addAction(tr("Enable Web &Inspector"), this, SLOT(slotToggleInspector(bool))); - a->setCheckable(true); -#endif - - QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); - helpMenu->addAction(tr("About &Qt"), qApp, SLOT(aboutQt())); - helpMenu->addAction(tr("About &Demo Browser"), this, SLOT(slotAboutApplication())); -} - -void BrowserMainWindow::setupToolBar() -{ - setUnifiedTitleAndToolBarOnMac(true); - m_navigationBar = addToolBar(tr("Navigation")); - connect(m_navigationBar->toggleViewAction(), SIGNAL(toggled(bool)), - this, SLOT(updateToolbarActionText(bool))); - - m_historyBack->setIcon(style()->standardIcon(QStyle::SP_ArrowBack, 0, this)); - m_historyBackMenu = new QMenu(this); - m_historyBack->setMenu(m_historyBackMenu); - connect(m_historyBackMenu, SIGNAL(aboutToShow()), - this, SLOT(slotAboutToShowBackMenu())); - connect(m_historyBackMenu, SIGNAL(triggered(QAction *)), - this, SLOT(slotOpenActionUrl(QAction *))); - m_navigationBar->addAction(m_historyBack); - - m_historyForward->setIcon(style()->standardIcon(QStyle::SP_ArrowForward, 0, this)); - m_historyForwardMenu = new QMenu(this); - connect(m_historyForwardMenu, SIGNAL(aboutToShow()), - this, SLOT(slotAboutToShowForwardMenu())); - connect(m_historyForwardMenu, SIGNAL(triggered(QAction *)), - this, SLOT(slotOpenActionUrl(QAction *))); - m_historyForward->setMenu(m_historyForwardMenu); - m_navigationBar->addAction(m_historyForward); - - m_stopReload = new QAction(this); - m_reloadIcon = style()->standardIcon(QStyle::SP_BrowserReload); - m_stopReload->setIcon(m_reloadIcon); - - m_navigationBar->addAction(m_stopReload); - - m_navigationBar->addWidget(m_tabWidget->lineEditStack()); - - m_toolbarSearch = new ToolbarSearch(m_navigationBar); - m_navigationBar->addWidget(m_toolbarSearch); - connect(m_toolbarSearch, SIGNAL(search(const QUrl&)), SLOT(loadUrl(const QUrl&))); - - m_chaseWidget = new ChaseWidget(this); - m_navigationBar->addWidget(m_chaseWidget); -} - -void BrowserMainWindow::slotShowBookmarksDialog() -{ - BookmarksDialog *dialog = new BookmarksDialog(this); - connect(dialog, SIGNAL(openUrl(const QUrl&)), - m_tabWidget, SLOT(loadUrlInCurrentTab(const QUrl&))); - dialog->show(); -} - -void BrowserMainWindow::slotAddBookmark() -{ - WebView *webView = currentTab(); - QString url = webView->url().toString(); - QString title = webView->title(); - AddBookmarkDialog dialog(url, title); - dialog.exec(); -} - -void BrowserMainWindow::slotViewToolbar() -{ - if (m_navigationBar->isVisible()) { - updateToolbarActionText(false); - m_navigationBar->close(); - } else { - updateToolbarActionText(true); - m_navigationBar->show(); - } - m_autoSaver->changeOccurred(); -} - -void BrowserMainWindow::slotViewBookmarksBar() -{ - if (m_bookmarksToolbar->isVisible()) { - updateBookmarksToolbarActionText(false); - m_bookmarksToolbar->close(); - } else { - updateBookmarksToolbarActionText(true); - m_bookmarksToolbar->show(); - } - m_autoSaver->changeOccurred(); -} - -void BrowserMainWindow::updateStatusbarActionText(bool visible) -{ - m_viewStatusbar->setText(!visible ? tr("Show Status Bar") : tr("Hide Status Bar")); -} - -void BrowserMainWindow::updateToolbarActionText(bool visible) -{ - m_viewToolbar->setText(!visible ? tr("Show Toolbar") : tr("Hide Toolbar")); -} - -void BrowserMainWindow::updateBookmarksToolbarActionText(bool visible) -{ - m_viewBookmarkBar->setText(!visible ? tr("Show Bookmarks bar") : tr("Hide Bookmarks bar")); -} - -void BrowserMainWindow::slotViewStatusbar() -{ - if (statusBar()->isVisible()) { - updateStatusbarActionText(false); - statusBar()->close(); - } else { - updateStatusbarActionText(true); - statusBar()->show(); - } - m_autoSaver->changeOccurred(); -} - -QUrl BrowserMainWindow::guessUrlFromString(const QString &string) -{ - QString urlStr = string.trimmed(); - QRegExp test(QLatin1String("^[a-zA-Z]+\\:.*")); - - // Check if it looks like a qualified URL. Try parsing it and see. - bool hasSchema = test.exactMatch(urlStr); - if (hasSchema) { - QUrl url = QUrl::fromEncoded(urlStr.toUtf8(), QUrl::TolerantMode); - if (url.isValid()) - return url; - } - - // Might be a file. - if (QFile::exists(urlStr)) { - QFileInfo info(urlStr); - return QUrl::fromLocalFile(info.absoluteFilePath()); - } - - // Might be a shorturl - try to detect the schema. - if (!hasSchema) { - int dotIndex = urlStr.indexOf(QLatin1Char('.')); - if (dotIndex != -1) { - QString prefix = urlStr.left(dotIndex).toLower(); - QByteArray schema = (prefix == QLatin1String("ftp")) ? prefix.toLatin1() : "http"; - QUrl url = - QUrl::fromEncoded(schema + "://" + urlStr.toUtf8(), QUrl::TolerantMode); - if (url.isValid()) - return url; - } - } - - // Fall back to QUrl's own tolerant parser. - QUrl url = QUrl::fromEncoded(string.toUtf8(), QUrl::TolerantMode); - - // finally for cases where the user just types in a hostname add http - if (url.scheme().isEmpty()) - url = QUrl::fromEncoded("http://" + string.toUtf8(), QUrl::TolerantMode); - return url; -} - -void BrowserMainWindow::loadUrl(const QUrl &url) -{ - if (!currentTab() || !url.isValid()) - return; - - m_tabWidget->currentLineEdit()->setText(QString::fromUtf8(url.toEncoded())); - m_tabWidget->loadUrlInCurrentTab(url); -} - -void BrowserMainWindow::slotDownloadManager() -{ - BrowserApplication::downloadManager()->show(); -} - -void BrowserMainWindow::slotSelectLineEdit() -{ - m_tabWidget->currentLineEdit()->selectAll(); - m_tabWidget->currentLineEdit()->setFocus(); -} - -void BrowserMainWindow::slotFileSaveAs() -{ - BrowserApplication::downloadManager()->download(currentTab()->url(), true); -} - -void BrowserMainWindow::slotPreferences() -{ - SettingsDialog *s = new SettingsDialog(this); - s->show(); -} - -void BrowserMainWindow::slotUpdateStatusbar(const QString &string) -{ - statusBar()->showMessage(string, 2000); -} - -void BrowserMainWindow::slotUpdateWindowTitle(const QString &title) -{ - if (title.isEmpty()) { - setWindowTitle(tr("Qt Demo Browser")); - } else { -#if defined(Q_WS_MAC) - setWindowTitle(title); -#else - setWindowTitle(tr("%1 - Qt Demo Browser", "Page title and Browser name").arg(title)); -#endif - } -} - -void BrowserMainWindow::slotAboutApplication() -{ - QMessageBox::about(this, tr("About"), tr( - "Version %1" - "

This demo demonstrates Qt's " - "webkit facilities in action, providing an example " - "browser for you to experiment with.

" - "

QtWebKit is based on the Open Source WebKit Project developed at http://webkit.org/." - ).arg(QCoreApplication::applicationVersion())); -} - -void BrowserMainWindow::slotFileNew() -{ - BrowserApplication::instance()->newMainWindow(); - BrowserMainWindow *mw = BrowserApplication::instance()->mainWindow(); - mw->slotHome(); -} - -void BrowserMainWindow::slotFileOpen() -{ - QString file = QFileDialog::getOpenFileName(this, tr("Open Web Resource"), QString(), - tr("Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*)")); - - if (file.isEmpty()) - return; - - loadPage(file); -} - -void BrowserMainWindow::slotFilePrintPreview() -{ -#ifndef QT_NO_PRINTER - if (!currentTab()) - return; - QPrintPreviewDialog *dialog = new QPrintPreviewDialog(this); - connect(dialog, SIGNAL(paintRequested(QPrinter *)), - currentTab(), SLOT(print(QPrinter *))); - dialog->exec(); -#endif -} - -void BrowserMainWindow::slotFilePrint() -{ - if (!currentTab()) - return; - printRequested(currentTab()->page()->mainFrame()); -} - -void BrowserMainWindow::printRequested(QWebFrame *frame) -{ -#ifndef QT_NO_PRINTER - QPrinter printer; - QPrintDialog *dialog = new QPrintDialog(&printer, this); - dialog->setWindowTitle(tr("Print Document")); - if (dialog->exec() != QDialog::Accepted) - return; - frame->print(&printer); -#endif -} - -void BrowserMainWindow::slotPrivateBrowsing() -{ - QWebSettings *settings = QWebSettings::globalSettings(); - bool pb = settings->testAttribute(QWebSettings::PrivateBrowsingEnabled); - if (!pb) { - QString title = tr("Are you sure you want to turn on private browsing?"); - QString text = tr("%1

When private browsing in turned on," - " webpages are not added to the history," - " items are automatically removed from the Downloads window," \ - " new cookies are not stored, current cookies can't be accessed," \ - " site icons wont be stored, session wont be saved, " \ - " and searches are not addded to the pop-up menu in the Google search box." \ - " Until you close the window, you can still click the Back and Forward buttons" \ - " to return to the webpages you have opened.").arg(title); - - QMessageBox::StandardButton button = QMessageBox::question(this, QString(), text, - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Ok); - if (button == QMessageBox::Ok) { - settings->setAttribute(QWebSettings::PrivateBrowsingEnabled, true); - } - } else { - settings->setAttribute(QWebSettings::PrivateBrowsingEnabled, false); - - QList windows = BrowserApplication::instance()->mainWindows(); - for (int i = 0; i < windows.count(); ++i) { - BrowserMainWindow *window = windows.at(i); - window->m_lastSearch = QString::null; - window->tabWidget()->clear(); - } - } -} - -void BrowserMainWindow::closeEvent(QCloseEvent *event) -{ - if (m_tabWidget->count() > 1) { - int ret = QMessageBox::warning(this, QString(), - tr("Are you sure you want to close the window?" - " There are %1 tab open").arg(m_tabWidget->count()), - QMessageBox::Yes | QMessageBox::No, - QMessageBox::No); - if (ret == QMessageBox::No) { - event->ignore(); - return; - } - } - event->accept(); - deleteLater(); -} - -void BrowserMainWindow::slotEditFind() -{ - if (!currentTab()) - return; - bool ok; - QString search = QInputDialog::getText(this, tr("Find"), - tr("Text:"), QLineEdit::Normal, - m_lastSearch, &ok); - if (ok && !search.isEmpty()) { - m_lastSearch = search; - if (!currentTab()->findText(m_lastSearch)) - slotUpdateStatusbar(tr("\"%1\" not found.").arg(m_lastSearch)); - } -} - -void BrowserMainWindow::slotEditFindNext() -{ - if (!currentTab() && !m_lastSearch.isEmpty()) - return; - currentTab()->findText(m_lastSearch); -} - -void BrowserMainWindow::slotEditFindPrevious() -{ - if (!currentTab() && !m_lastSearch.isEmpty()) - return; - currentTab()->findText(m_lastSearch, QWebPage::FindBackward); -} - -void BrowserMainWindow::slotViewZoomIn() -{ - if (!currentTab()) - return; - currentTab()->setZoomFactor(currentTab()->zoomFactor() + 0.1); -} - -void BrowserMainWindow::slotViewZoomOut() -{ - if (!currentTab()) - return; - currentTab()->setZoomFactor(currentTab()->zoomFactor() - 0.1); -} - -void BrowserMainWindow::slotViewResetZoom() -{ - if (!currentTab()) - return; - currentTab()->setZoomFactor(1.0); -} - -void BrowserMainWindow::slotViewZoomTextOnly(bool enable) -{ - if (!currentTab()) - return; - currentTab()->page()->settings()->setAttribute(QWebSettings::ZoomTextOnly, enable); -} - -void BrowserMainWindow::slotViewFullScreen(bool makeFullScreen) -{ - if (makeFullScreen) { - showFullScreen(); - } else { - if (isMinimized()) - showMinimized(); - else if (isMaximized()) - showMaximized(); - else showNormal(); - } -} - -void BrowserMainWindow::slotViewPageSource() -{ - if (!currentTab()) - return; - - QString markup = currentTab()->page()->mainFrame()->toHtml(); - QPlainTextEdit *view = new QPlainTextEdit(markup); - view->setWindowTitle(tr("Page Source of %1").arg(currentTab()->title())); - view->setMinimumWidth(640); - view->setAttribute(Qt::WA_DeleteOnClose); - view->show(); -} - -void BrowserMainWindow::slotHome() -{ - QSettings settings; - settings.beginGroup(QLatin1String("MainWindow")); - QString home = settings.value(QLatin1String("home"), QLatin1String("http://qtsoftware.com/")).toString(); - loadPage(home); -} - -void BrowserMainWindow::slotWebSearch() -{ - m_toolbarSearch->lineEdit()->selectAll(); - m_toolbarSearch->lineEdit()->setFocus(); -} - -void BrowserMainWindow::slotToggleInspector(bool enable) -{ - QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, enable); - if (enable) { - int result = QMessageBox::question(this, tr("Web Inspector"), - tr("The web inspector will only work correctly for pages that were loaded after enabling.\n" - "Do you want to reload all pages?"), - QMessageBox::Yes | QMessageBox::No); - if (result == QMessageBox::Yes) { - m_tabWidget->reloadAllTabs(); - } - } -} - -void BrowserMainWindow::slotSwapFocus() -{ - if (currentTab()->hasFocus()) - m_tabWidget->currentLineEdit()->setFocus(); - else - currentTab()->setFocus(); -} - -void BrowserMainWindow::loadPage(const QString &page) -{ - QUrl url = guessUrlFromString(page); - loadUrl(url); -} - -TabWidget *BrowserMainWindow::tabWidget() const -{ - return m_tabWidget; -} - -WebView *BrowserMainWindow::currentTab() const -{ - return m_tabWidget->currentWebView(); -} - -void BrowserMainWindow::slotLoadProgress(int progress) -{ - if (progress < 100 && progress > 0) { - m_chaseWidget->setAnimated(true); - disconnect(m_stopReload, SIGNAL(triggered()), m_reload, SLOT(trigger())); - if (m_stopIcon.isNull()) - m_stopIcon = style()->standardIcon(QStyle::SP_BrowserStop); - m_stopReload->setIcon(m_stopIcon); - connect(m_stopReload, SIGNAL(triggered()), m_stop, SLOT(trigger())); - m_stopReload->setToolTip(tr("Stop loading the current page")); - } else { - m_chaseWidget->setAnimated(false); - disconnect(m_stopReload, SIGNAL(triggered()), m_stop, SLOT(trigger())); - m_stopReload->setIcon(m_reloadIcon); - connect(m_stopReload, SIGNAL(triggered()), m_reload, SLOT(trigger())); - m_stopReload->setToolTip(tr("Reload the current page")); - } -} - -void BrowserMainWindow::slotAboutToShowBackMenu() -{ - m_historyBackMenu->clear(); - if (!currentTab()) - return; - QWebHistory *history = currentTab()->history(); - int historyCount = history->count(); - for (int i = history->backItems(historyCount).count() - 1; i >= 0; --i) { - QWebHistoryItem item = history->backItems(history->count()).at(i); - QAction *action = new QAction(this); - action->setData(-1*(historyCount-i-1)); - QIcon icon = BrowserApplication::instance()->icon(item.url()); - action->setIcon(icon); - action->setText(item.title()); - m_historyBackMenu->addAction(action); - } -} - -void BrowserMainWindow::slotAboutToShowForwardMenu() -{ - m_historyForwardMenu->clear(); - if (!currentTab()) - return; - QWebHistory *history = currentTab()->history(); - int historyCount = history->count(); - for (int i = 0; i < history->forwardItems(history->count()).count(); ++i) { - QWebHistoryItem item = history->forwardItems(historyCount).at(i); - QAction *action = new QAction(this); - action->setData(historyCount-i); - QIcon icon = BrowserApplication::instance()->icon(item.url()); - action->setIcon(icon); - action->setText(item.title()); - m_historyForwardMenu->addAction(action); - } -} - -void BrowserMainWindow::slotAboutToShowWindowMenu() -{ - m_windowMenu->clear(); - m_windowMenu->addAction(m_tabWidget->nextTabAction()); - m_windowMenu->addAction(m_tabWidget->previousTabAction()); - m_windowMenu->addSeparator(); - m_windowMenu->addAction(tr("Downloads"), this, SLOT(slotDownloadManager()), QKeySequence(tr("Alt+Ctrl+L", "Download Manager"))); - - m_windowMenu->addSeparator(); - QList windows = BrowserApplication::instance()->mainWindows(); - for (int i = 0; i < windows.count(); ++i) { - BrowserMainWindow *window = windows.at(i); - QAction *action = m_windowMenu->addAction(window->windowTitle(), this, SLOT(slotShowWindow())); - action->setData(i); - action->setCheckable(true); - if (window == this) - action->setChecked(true); - } -} - -void BrowserMainWindow::slotShowWindow() -{ - if (QAction *action = qobject_cast(sender())) { - QVariant v = action->data(); - if (v.canConvert()) { - int offset = qvariant_cast(v); - QList windows = BrowserApplication::instance()->mainWindows(); - windows.at(offset)->activateWindow(); - windows.at(offset)->currentTab()->setFocus(); - } - } -} - -void BrowserMainWindow::slotOpenActionUrl(QAction *action) -{ - int offset = action->data().toInt(); - QWebHistory *history = currentTab()->history(); - if (offset < 0) - history->goToItem(history->backItems(-1*offset).first()); // back - else if (offset > 0) - history->goToItem(history->forwardItems(history->count() - offset + 1).back()); // forward - } - -void BrowserMainWindow::geometryChangeRequested(const QRect &geometry) -{ - setGeometry(geometry); -} - diff --git a/examples/gestures/browser/browsermainwindow.h b/examples/gestures/browser/browsermainwindow.h deleted file mode 100644 index 04f6c0c..0000000 --- a/examples/gestures/browser/browsermainwindow.h +++ /dev/null @@ -1,169 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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$ -** -****************************************************************************/ - -#ifndef BROWSERMAINWINDOW_H -#define BROWSERMAINWINDOW_H - -#include -#include -#include - -class AutoSaver; -class BookmarksToolBar; -class ChaseWidget; -class QWebFrame; -class TabWidget; -class ToolbarSearch; -class WebView; - -/*! - The MainWindow of the Browser Application. - - Handles the tab widget and all the actions - */ -class BrowserMainWindow : public QMainWindow { - Q_OBJECT - -public: - BrowserMainWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0); - ~BrowserMainWindow(); - QSize sizeHint() const; - -public: - static QUrl guessUrlFromString(const QString &url); - TabWidget *tabWidget() const; - WebView *currentTab() const; - QByteArray saveState(bool withTabs = true) const; - bool restoreState(const QByteArray &state); - -public slots: - void loadPage(const QString &url); - void slotHome(); - -protected: - void closeEvent(QCloseEvent *event); - -private slots: - void save(); - - void slotLoadProgress(int); - void slotUpdateStatusbar(const QString &string); - void slotUpdateWindowTitle(const QString &title = QString()); - - void loadUrl(const QUrl &url); - void slotPreferences(); - - void slotFileNew(); - void slotFileOpen(); - void slotFilePrintPreview(); - void slotFilePrint(); - void slotPrivateBrowsing(); - void slotFileSaveAs(); - void slotEditFind(); - void slotEditFindNext(); - void slotEditFindPrevious(); - void slotShowBookmarksDialog(); - void slotAddBookmark(); - void slotViewZoomIn(); - void slotViewZoomOut(); - void slotViewResetZoom(); - void slotViewZoomTextOnly(bool enable); - void slotViewToolbar(); - void slotViewBookmarksBar(); - void slotViewStatusbar(); - void slotViewPageSource(); - void slotViewFullScreen(bool enable); - - void slotWebSearch(); - void slotToggleInspector(bool enable); - void slotAboutApplication(); - void slotDownloadManager(); - void slotSelectLineEdit(); - - void slotAboutToShowBackMenu(); - void slotAboutToShowForwardMenu(); - void slotAboutToShowWindowMenu(); - void slotOpenActionUrl(QAction *action); - void slotShowWindow(); - void slotSwapFocus(); - - void printRequested(QWebFrame *frame); - void geometryChangeRequested(const QRect &geometry); - void updateToolbarActionText(bool visible); - void updateBookmarksToolbarActionText(bool visible); - -private: - void loadDefaultState(); - void setupMenu(); - void setupToolBar(); - void updateStatusbarActionText(bool visible); - -private: - QToolBar *m_navigationBar; - ToolbarSearch *m_toolbarSearch; - BookmarksToolBar *m_bookmarksToolbar; - ChaseWidget *m_chaseWidget; - TabWidget *m_tabWidget; - AutoSaver *m_autoSaver; - - QAction *m_historyBack; - QMenu *m_historyBackMenu; - QAction *m_historyForward; - QMenu *m_historyForwardMenu; - QMenu *m_windowMenu; - - QAction *m_stop; - QAction *m_reload; - QAction *m_stopReload; - QAction *m_viewToolbar; - QAction *m_viewBookmarkBar; - QAction *m_viewStatusbar; - QAction *m_restoreLastSession; - QAction *m_addBookmark; - - QIcon m_reloadIcon; - QIcon m_stopIcon; - - QString m_lastSearch; -}; - -#endif // BROWSERMAINWINDOW_H - diff --git a/examples/gestures/browser/chasewidget.cpp b/examples/gestures/browser/chasewidget.cpp deleted file mode 100644 index de6c90b..0000000 --- a/examples/gestures/browser/chasewidget.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 "chasewidget.h" - -#include - -#include -#include -#include -#include -#include - -ChaseWidget::ChaseWidget(QWidget *parent, QPixmap pixmap, bool pixmapEnabled) - : QWidget(parent) - , m_segment(0) - , m_delay(100) - , m_step(40) - , m_timerId(-1) - , m_animated(false) - , m_pixmap(pixmap) - , m_pixmapEnabled(pixmapEnabled) -{ -} - -void ChaseWidget::setAnimated(bool value) -{ - if (m_animated == value) - return; - m_animated = value; - if (m_timerId != -1) { - killTimer(m_timerId); - m_timerId = -1; - } - if (m_animated) { - m_segment = 0; - m_timerId = startTimer(m_delay); - } - update(); -} - -void ChaseWidget::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - QPainter p(this); - if (m_pixmapEnabled && !m_pixmap.isNull()) { - p.drawPixmap(0, 0, m_pixmap); - return; - } - - const int extent = qMin(width() - 8, height() - 8); - const int displ = extent / 4; - const int ext = extent / 4 - 1; - - p.setRenderHint(QPainter::Antialiasing, true); - - if(m_animated) - p.setPen(Qt::gray); - else - p.setPen(QPen(palette().dark().color())); - - p.translate(width() / 2, height() / 2); // center - - for (int segment = 0; segment < segmentCount(); ++segment) { - p.rotate(QApplication::isRightToLeft() ? m_step : -m_step); - if(m_animated) - p.setBrush(colorForSegment(segment)); - else - p.setBrush(palette().background()); - p.drawEllipse(QRect(displ, -ext / 2, ext, ext)); - } -} - -QSize ChaseWidget::sizeHint() const -{ - return QSize(32, 32); -} - -void ChaseWidget::timerEvent(QTimerEvent *event) -{ - if (event->timerId() == m_timerId) { - ++m_segment; - update(); - } - QWidget::timerEvent(event); -} - -QColor ChaseWidget::colorForSegment(int seg) const -{ - int index = ((seg + m_segment) % segmentCount()); - int comp = qMax(0, 255 - (index * (255 / segmentCount()))); - return QColor(comp, comp, comp, 255); -} - -int ChaseWidget::segmentCount() const -{ - return 360 / m_step; -} - -void ChaseWidget::setPixmapEnabled(bool enable) -{ - m_pixmapEnabled = enable; -} - diff --git a/examples/gestures/browser/chasewidget.h b/examples/gestures/browser/chasewidget.h deleted file mode 100644 index 5b983e4..0000000 --- a/examples/gestures/browser/chasewidget.h +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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$ -** -****************************************************************************/ - -#ifndef CHASEWIDGET_H -#define CHASEWIDGET_H - -#include - -#include -#include -#include - -QT_BEGIN_NAMESPACE -class QHideEvent; -class QShowEvent; -class QPaintEvent; -class QTimerEvent; -QT_END_NAMESPACE - -class ChaseWidget : public QWidget -{ - Q_OBJECT -public: - ChaseWidget(QWidget *parent = 0, QPixmap pixmap = QPixmap(), bool pixmapEnabled = false); - - void setAnimated(bool value); - void setPixmapEnabled(bool enable); - QSize sizeHint() const; - -protected: - void paintEvent(QPaintEvent *event); - void timerEvent(QTimerEvent *event); - -private: - int segmentCount() const; - QColor colorForSegment(int segment) const; - - int m_segment; - int m_delay; - int m_step; - int m_timerId; - bool m_animated; - QPixmap m_pixmap; - bool m_pixmapEnabled; -}; - -#endif diff --git a/examples/gestures/browser/cookiejar.cpp b/examples/gestures/browser/cookiejar.cpp deleted file mode 100644 index 3ae443f..0000000 --- a/examples/gestures/browser/cookiejar.cpp +++ /dev/null @@ -1,733 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 "cookiejar.h" - -#include "autosaver.h" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -static const unsigned int JAR_VERSION = 23; - -QT_BEGIN_NAMESPACE -QDataStream &operator<<(QDataStream &stream, const QList &list) -{ - stream << JAR_VERSION; - stream << quint32(list.size()); - for (int i = 0; i < list.size(); ++i) - stream << list.at(i).toRawForm(); - return stream; -} - -QDataStream &operator>>(QDataStream &stream, QList &list) -{ - list.clear(); - - quint32 version; - stream >> version; - - if (version != JAR_VERSION) - return stream; - - quint32 count; - stream >> count; - for(quint32 i = 0; i < count; ++i) - { - QByteArray value; - stream >> value; - QList newCookies = QNetworkCookie::parseCookies(value); - if (newCookies.count() == 0 && value.length() != 0) { - qWarning() << "CookieJar: Unable to parse saved cookie:" << value; - } - for (int j = 0; j < newCookies.count(); ++j) - list.append(newCookies.at(j)); - if (stream.atEnd()) - break; - } - return stream; -} -QT_END_NAMESPACE - -CookieJar::CookieJar(QObject *parent) - : QNetworkCookieJar(parent) - , m_loaded(false) - , m_saveTimer(new AutoSaver(this)) - , m_acceptCookies(AcceptOnlyFromSitesNavigatedTo) -{ -} - -CookieJar::~CookieJar() -{ - if (m_keepCookies == KeepUntilExit) - clear(); - m_saveTimer->saveIfNeccessary(); -} - -void CookieJar::clear() -{ - setAllCookies(QList()); - m_saveTimer->changeOccurred(); - emit cookiesChanged(); -} - -void CookieJar::load() -{ - if (m_loaded) - return; - // load cookies and exceptions - qRegisterMetaTypeStreamOperators >("QList"); - QSettings cookieSettings(QDesktopServices::storageLocation(QDesktopServices::DataLocation) + QLatin1String("/cookies.ini"), QSettings::IniFormat); - setAllCookies(qvariant_cast >(cookieSettings.value(QLatin1String("cookies")))); - cookieSettings.beginGroup(QLatin1String("Exceptions")); - m_exceptions_block = cookieSettings.value(QLatin1String("block")).toStringList(); - m_exceptions_allow = cookieSettings.value(QLatin1String("allow")).toStringList(); - m_exceptions_allowForSession = cookieSettings.value(QLatin1String("allowForSession")).toStringList(); - qSort(m_exceptions_block.begin(), m_exceptions_block.end()); - qSort(m_exceptions_allow.begin(), m_exceptions_allow.end()); - qSort(m_exceptions_allowForSession.begin(), m_exceptions_allowForSession.end()); - - loadSettings(); -} - -void CookieJar::loadSettings() -{ - QSettings settings; - settings.beginGroup(QLatin1String("cookies")); - QByteArray value = settings.value(QLatin1String("acceptCookies"), - QLatin1String("AcceptOnlyFromSitesNavigatedTo")).toByteArray(); - QMetaEnum acceptPolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("AcceptPolicy")); - m_acceptCookies = acceptPolicyEnum.keyToValue(value) == -1 ? - AcceptOnlyFromSitesNavigatedTo : - static_cast(acceptPolicyEnum.keyToValue(value)); - - value = settings.value(QLatin1String("keepCookiesUntil"), QLatin1String("KeepUntilExpire")).toByteArray(); - QMetaEnum keepPolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("KeepPolicy")); - m_keepCookies = keepPolicyEnum.keyToValue(value) == -1 ? - KeepUntilExpire : - static_cast(keepPolicyEnum.keyToValue(value)); - - if (m_keepCookies == KeepUntilExit) - setAllCookies(QList()); - - m_loaded = true; - emit cookiesChanged(); -} - -void CookieJar::save() -{ - if (!m_loaded) - return; - purgeOldCookies(); - QString directory = QDesktopServices::storageLocation(QDesktopServices::DataLocation); - if (directory.isEmpty()) - directory = QDir::homePath() + QLatin1String("/.") + QCoreApplication::applicationName(); - if (!QFile::exists(directory)) { - QDir dir; - dir.mkpath(directory); - } - QSettings cookieSettings(directory + QLatin1String("/cookies.ini"), QSettings::IniFormat); - QList cookies = allCookies(); - for (int i = cookies.count() - 1; i >= 0; --i) { - if (cookies.at(i).isSessionCookie()) - cookies.removeAt(i); - } - cookieSettings.setValue(QLatin1String("cookies"), qVariantFromValue >(cookies)); - cookieSettings.beginGroup(QLatin1String("Exceptions")); - cookieSettings.setValue(QLatin1String("block"), m_exceptions_block); - cookieSettings.setValue(QLatin1String("allow"), m_exceptions_allow); - cookieSettings.setValue(QLatin1String("allowForSession"), m_exceptions_allowForSession); - - // save cookie settings - QSettings settings; - settings.beginGroup(QLatin1String("cookies")); - QMetaEnum acceptPolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("AcceptPolicy")); - settings.setValue(QLatin1String("acceptCookies"), QLatin1String(acceptPolicyEnum.valueToKey(m_acceptCookies))); - - QMetaEnum keepPolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("KeepPolicy")); - settings.setValue(QLatin1String("keepCookiesUntil"), QLatin1String(keepPolicyEnum.valueToKey(m_keepCookies))); -} - -void CookieJar::purgeOldCookies() -{ - QList cookies = allCookies(); - if (cookies.isEmpty()) - return; - int oldCount = cookies.count(); - QDateTime now = QDateTime::currentDateTime(); - for (int i = cookies.count() - 1; i >= 0; --i) { - if (!cookies.at(i).isSessionCookie() && cookies.at(i).expirationDate() < now) - cookies.removeAt(i); - } - if (oldCount == cookies.count()) - return; - setAllCookies(cookies); - emit cookiesChanged(); -} - -QList CookieJar::cookiesForUrl(const QUrl &url) const -{ - CookieJar *that = const_cast(this); - if (!m_loaded) - that->load(); - - QWebSettings *globalSettings = QWebSettings::globalSettings(); - if (globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled)) { - QList noCookies; - return noCookies; - } - - return QNetworkCookieJar::cookiesForUrl(url); -} - -bool CookieJar::setCookiesFromUrl(const QList &cookieList, const QUrl &url) -{ - if (!m_loaded) - load(); - - QWebSettings *globalSettings = QWebSettings::globalSettings(); - if (globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled)) - return false; - - QString host = url.host(); - bool eBlock = qBinaryFind(m_exceptions_block.begin(), m_exceptions_block.end(), host) != m_exceptions_block.end(); - bool eAllow = qBinaryFind(m_exceptions_allow.begin(), m_exceptions_allow.end(), host) != m_exceptions_allow.end(); - bool eAllowSession = qBinaryFind(m_exceptions_allowForSession.begin(), m_exceptions_allowForSession.end(), host) != m_exceptions_allowForSession.end(); - - bool addedCookies = false; - // pass exceptions - bool acceptInitially = (m_acceptCookies != AcceptNever); - if ((acceptInitially && !eBlock) - || (!acceptInitially && (eAllow || eAllowSession))) { - // pass url domain == cookie domain - QDateTime soon = QDateTime::currentDateTime(); - soon = soon.addDays(90); - foreach(QNetworkCookie cookie, cookieList) { - QList lst; - if (m_keepCookies == KeepUntilTimeLimit - && !cookie.isSessionCookie() - && cookie.expirationDate() > soon) { - cookie.setExpirationDate(soon); - } - lst += cookie; - if (QNetworkCookieJar::setCookiesFromUrl(lst, url)) { - addedCookies = true; - } else { - // finally force it in if wanted - if (m_acceptCookies == AcceptAlways) { - QList cookies = allCookies(); - cookies += cookie; - setAllCookies(cookies); - addedCookies = true; - } -#if 0 - else - qWarning() << "setCookiesFromUrl failed" << url << cookieList.value(0).toRawForm(); -#endif - } - } - } - - if (addedCookies) { - m_saveTimer->changeOccurred(); - emit cookiesChanged(); - } - return addedCookies; -} - -CookieJar::AcceptPolicy CookieJar::acceptPolicy() const -{ - if (!m_loaded) - (const_cast(this))->load(); - return m_acceptCookies; -} - -void CookieJar::setAcceptPolicy(AcceptPolicy policy) -{ - if (!m_loaded) - load(); - if (policy == m_acceptCookies) - return; - m_acceptCookies = policy; - m_saveTimer->changeOccurred(); -} - -CookieJar::KeepPolicy CookieJar::keepPolicy() const -{ - if (!m_loaded) - (const_cast(this))->load(); - return m_keepCookies; -} - -void CookieJar::setKeepPolicy(KeepPolicy policy) -{ - if (!m_loaded) - load(); - if (policy == m_keepCookies) - return; - m_keepCookies = policy; - m_saveTimer->changeOccurred(); -} - -QStringList CookieJar::blockedCookies() const -{ - if (!m_loaded) - (const_cast(this))->load(); - return m_exceptions_block; -} - -QStringList CookieJar::allowedCookies() const -{ - if (!m_loaded) - (const_cast(this))->load(); - return m_exceptions_allow; -} - -QStringList CookieJar::allowForSessionCookies() const -{ - if (!m_loaded) - (const_cast(this))->load(); - return m_exceptions_allowForSession; -} - -void CookieJar::setBlockedCookies(const QStringList &list) -{ - if (!m_loaded) - load(); - m_exceptions_block = list; - qSort(m_exceptions_block.begin(), m_exceptions_block.end()); - m_saveTimer->changeOccurred(); -} - -void CookieJar::setAllowedCookies(const QStringList &list) -{ - if (!m_loaded) - load(); - m_exceptions_allow = list; - qSort(m_exceptions_allow.begin(), m_exceptions_allow.end()); - m_saveTimer->changeOccurred(); -} - -void CookieJar::setAllowForSessionCookies(const QStringList &list) -{ - if (!m_loaded) - load(); - m_exceptions_allowForSession = list; - qSort(m_exceptions_allowForSession.begin(), m_exceptions_allowForSession.end()); - m_saveTimer->changeOccurred(); -} - -CookieModel::CookieModel(CookieJar *cookieJar, QObject *parent) - : QAbstractTableModel(parent) - , m_cookieJar(cookieJar) -{ - connect(m_cookieJar, SIGNAL(cookiesChanged()), this, SLOT(cookiesChanged())); - m_cookieJar->load(); -} - -QVariant CookieModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (role == Qt::SizeHintRole) { - QFont font; - font.setPointSize(10); - QFontMetrics fm(font); - int height = fm.height() + fm.height()/3; - int width = fm.width(headerData(section, orientation, Qt::DisplayRole).toString()); - return QSize(width, height); - } - - if (orientation == Qt::Horizontal) { - if (role != Qt::DisplayRole) - return QVariant(); - - switch (section) { - case 0: - return tr("Website"); - case 1: - return tr("Name"); - case 2: - return tr("Path"); - case 3: - return tr("Secure"); - case 4: - return tr("Expires"); - case 5: - return tr("Contents"); - default: - return QVariant(); - } - } - return QAbstractTableModel::headerData(section, orientation, role); -} - -QVariant CookieModel::data(const QModelIndex &index, int role) const -{ - QList lst; - if (m_cookieJar) - lst = m_cookieJar->allCookies(); - if (index.row() < 0 || index.row() >= lst.size()) - return QVariant(); - - switch (role) { - case Qt::DisplayRole: - case Qt::EditRole: { - QNetworkCookie cookie = lst.at(index.row()); - switch (index.column()) { - case 0: - return cookie.domain(); - case 1: - return cookie.name(); - case 2: - return cookie.path(); - case 3: - return cookie.isSecure(); - case 4: - return cookie.expirationDate(); - case 5: - return cookie.value(); - } - } - case Qt::FontRole:{ - QFont font; - font.setPointSize(10); - return font; - } - } - - return QVariant(); -} - -int CookieModel::columnCount(const QModelIndex &parent) const -{ - return (parent.isValid()) ? 0 : 6; -} - -int CookieModel::rowCount(const QModelIndex &parent) const -{ - return (parent.isValid() || !m_cookieJar) ? 0 : m_cookieJar->allCookies().count(); -} - -bool CookieModel::removeRows(int row, int count, const QModelIndex &parent) -{ - if (parent.isValid() || !m_cookieJar) - return false; - int lastRow = row + count - 1; - beginRemoveRows(parent, row, lastRow); - QList lst = m_cookieJar->allCookies(); - for (int i = lastRow; i >= row; --i) { - lst.removeAt(i); - } - m_cookieJar->setAllCookies(lst); - endRemoveRows(); - return true; -} - -void CookieModel::cookiesChanged() -{ - reset(); -} - -CookiesDialog::CookiesDialog(CookieJar *cookieJar, QWidget *parent) : QDialog(parent) -{ - setupUi(this); - setWindowFlags(Qt::Sheet); - CookieModel *model = new CookieModel(cookieJar, this); - m_proxyModel = new QSortFilterProxyModel(this); - connect(search, SIGNAL(textChanged(QString)), - m_proxyModel, SLOT(setFilterFixedString(QString))); - connect(removeButton, SIGNAL(clicked()), cookiesTable, SLOT(removeOne())); - connect(removeAllButton, SIGNAL(clicked()), cookiesTable, SLOT(removeAll())); - m_proxyModel->setSourceModel(model); - cookiesTable->verticalHeader()->hide(); - cookiesTable->setSelectionBehavior(QAbstractItemView::SelectRows); - cookiesTable->setModel(m_proxyModel); - cookiesTable->setAlternatingRowColors(true); - cookiesTable->setTextElideMode(Qt::ElideMiddle); - cookiesTable->setShowGrid(false); - cookiesTable->setSortingEnabled(true); - QFont f = font(); - f.setPointSize(10); - QFontMetrics fm(f); - int height = fm.height() + fm.height()/3; - cookiesTable->verticalHeader()->setDefaultSectionSize(height); - cookiesTable->verticalHeader()->setMinimumSectionSize(-1); - for (int i = 0; i < model->columnCount(); ++i){ - int header = cookiesTable->horizontalHeader()->sectionSizeHint(i); - switch (i) { - case 0: - header = fm.width(QLatin1String("averagehost.domain.com")); - break; - case 1: - header = fm.width(QLatin1String("_session_id")); - break; - case 4: - header = fm.width(QDateTime::currentDateTime().toString(Qt::LocalDate)); - break; - } - int buffer = fm.width(QLatin1String("xx")); - header += buffer; - cookiesTable->horizontalHeader()->resizeSection(i, header); - } - cookiesTable->horizontalHeader()->setStretchLastSection(true); -} - - - -CookieExceptionsModel::CookieExceptionsModel(CookieJar *cookiejar, QObject *parent) - : QAbstractTableModel(parent) - , m_cookieJar(cookiejar) -{ - m_allowedCookies = m_cookieJar->allowedCookies(); - m_blockedCookies = m_cookieJar->blockedCookies(); - m_sessionCookies = m_cookieJar->allowForSessionCookies(); -} - -QVariant CookieExceptionsModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (role == Qt::SizeHintRole) { - QFont font; - font.setPointSize(10); - QFontMetrics fm(font); - int height = fm.height() + fm.height()/3; - int width = fm.width(headerData(section, orientation, Qt::DisplayRole).toString()); - return QSize(width, height); - } - - if (orientation == Qt::Horizontal - && role == Qt::DisplayRole) { - switch (section) { - case 0: - return tr("Website"); - case 1: - return tr("Status"); - } - } - return QAbstractTableModel::headerData(section, orientation, role); -} - -QVariant CookieExceptionsModel::data(const QModelIndex &index, int role) const -{ - if (index.row() < 0 || index.row() >= rowCount()) - return QVariant(); - - switch (role) { - case Qt::DisplayRole: - case Qt::EditRole: { - int row = index.row(); - if (row < m_allowedCookies.count()) { - switch (index.column()) { - case 0: - return m_allowedCookies.at(row); - case 1: - return tr("Allow"); - } - } - row = row - m_allowedCookies.count(); - if (row < m_blockedCookies.count()) { - switch (index.column()) { - case 0: - return m_blockedCookies.at(row); - case 1: - return tr("Block"); - } - } - row = row - m_blockedCookies.count(); - if (row < m_sessionCookies.count()) { - switch (index.column()) { - case 0: - return m_sessionCookies.at(row); - case 1: - return tr("Allow For Session"); - } - } - } - case Qt::FontRole:{ - QFont font; - font.setPointSize(10); - return font; - } - } - return QVariant(); -} - -int CookieExceptionsModel::columnCount(const QModelIndex &parent) const -{ - return (parent.isValid()) ? 0 : 2; -} - -int CookieExceptionsModel::rowCount(const QModelIndex &parent) const -{ - return (parent.isValid() || !m_cookieJar) ? 0 : m_allowedCookies.count() + m_blockedCookies.count() + m_sessionCookies.count(); -} - -bool CookieExceptionsModel::removeRows(int row, int count, const QModelIndex &parent) -{ - if (parent.isValid() || !m_cookieJar) - return false; - - int lastRow = row + count - 1; - beginRemoveRows(parent, row, lastRow); - for (int i = lastRow; i >= row; --i) { - if (i < m_allowedCookies.count()) { - m_allowedCookies.removeAt(row); - continue; - } - i = i - m_allowedCookies.count(); - if (i < m_blockedCookies.count()) { - m_blockedCookies.removeAt(row); - continue; - } - i = i - m_blockedCookies.count(); - if (i < m_sessionCookies.count()) { - m_sessionCookies.removeAt(row); - continue; - } - } - m_cookieJar->setAllowedCookies(m_allowedCookies); - m_cookieJar->setBlockedCookies(m_blockedCookies); - m_cookieJar->setAllowForSessionCookies(m_sessionCookies); - endRemoveRows(); - return true; -} - -CookiesExceptionsDialog::CookiesExceptionsDialog(CookieJar *cookieJar, QWidget *parent) - : QDialog(parent) - , m_cookieJar(cookieJar) -{ - setupUi(this); - setWindowFlags(Qt::Sheet); - connect(removeButton, SIGNAL(clicked()), exceptionTable, SLOT(removeOne())); - connect(removeAllButton, SIGNAL(clicked()), exceptionTable, SLOT(removeAll())); - exceptionTable->verticalHeader()->hide(); - exceptionTable->setSelectionBehavior(QAbstractItemView::SelectRows); - exceptionTable->setAlternatingRowColors(true); - exceptionTable->setTextElideMode(Qt::ElideMiddle); - exceptionTable->setShowGrid(false); - exceptionTable->setSortingEnabled(true); - m_exceptionsModel = new CookieExceptionsModel(cookieJar, this); - m_proxyModel = new QSortFilterProxyModel(this); - m_proxyModel->setSourceModel(m_exceptionsModel); - connect(search, SIGNAL(textChanged(QString)), - m_proxyModel, SLOT(setFilterFixedString(QString))); - exceptionTable->setModel(m_proxyModel); - - CookieModel *cookieModel = new CookieModel(cookieJar, this); - domainLineEdit->setCompleter(new QCompleter(cookieModel, domainLineEdit)); - - connect(domainLineEdit, SIGNAL(textChanged(const QString &)), - this, SLOT(textChanged(const QString &))); - connect(blockButton, SIGNAL(clicked()), this, SLOT(block())); - connect(allowButton, SIGNAL(clicked()), this, SLOT(allow())); - connect(allowForSessionButton, SIGNAL(clicked()), this, SLOT(allowForSession())); - - QFont f = font(); - f.setPointSize(10); - QFontMetrics fm(f); - int height = fm.height() + fm.height()/3; - exceptionTable->verticalHeader()->setDefaultSectionSize(height); - exceptionTable->verticalHeader()->setMinimumSectionSize(-1); - for (int i = 0; i < m_exceptionsModel->columnCount(); ++i){ - int header = exceptionTable->horizontalHeader()->sectionSizeHint(i); - switch (i) { - case 0: - header = fm.width(QLatin1String("averagebiglonghost.domain.com")); - break; - case 1: - header = fm.width(QLatin1String("Allow For Session")); - break; - } - int buffer = fm.width(QLatin1String("xx")); - header += buffer; - exceptionTable->horizontalHeader()->resizeSection(i, header); - } -} - -void CookiesExceptionsDialog::textChanged(const QString &text) -{ - bool enabled = !text.isEmpty(); - blockButton->setEnabled(enabled); - allowButton->setEnabled(enabled); - allowForSessionButton->setEnabled(enabled); -} - -void CookiesExceptionsDialog::block() -{ - if (domainLineEdit->text().isEmpty()) - return; - m_exceptionsModel->m_blockedCookies.append(domainLineEdit->text()); - m_cookieJar->setBlockedCookies(m_exceptionsModel->m_blockedCookies); - m_exceptionsModel->reset(); -} - -void CookiesExceptionsDialog::allow() -{ - if (domainLineEdit->text().isEmpty()) - return; - m_exceptionsModel->m_allowedCookies.append(domainLineEdit->text()); - m_cookieJar->setAllowedCookies(m_exceptionsModel->m_allowedCookies); - m_exceptionsModel->reset(); -} - -void CookiesExceptionsDialog::allowForSession() -{ - if (domainLineEdit->text().isEmpty()) - return; - m_exceptionsModel->m_sessionCookies.append(domainLineEdit->text()); - m_cookieJar->setAllowForSessionCookies(m_exceptionsModel->m_sessionCookies); - m_exceptionsModel->reset(); -} - diff --git a/examples/gestures/browser/cookiejar.h b/examples/gestures/browser/cookiejar.h deleted file mode 100644 index 55ba185..0000000 --- a/examples/gestures/browser/cookiejar.h +++ /dev/null @@ -1,204 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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$ -** -****************************************************************************/ - -#ifndef COOKIEJAR_H -#define COOKIEJAR_H - -#include - -#include -#include - -#include -#include - -QT_BEGIN_NAMESPACE -class QSortFilterProxyModel; -class QKeyEvent; -QT_END_NAMESPACE - -class AutoSaver; - -class CookieJar : public QNetworkCookieJar -{ - friend class CookieModel; - Q_OBJECT - Q_PROPERTY(AcceptPolicy acceptPolicy READ acceptPolicy WRITE setAcceptPolicy) - Q_PROPERTY(KeepPolicy keepPolicy READ keepPolicy WRITE setKeepPolicy) - Q_PROPERTY(QStringList blockedCookies READ blockedCookies WRITE setBlockedCookies) - Q_PROPERTY(QStringList allowedCookies READ allowedCookies WRITE setAllowedCookies) - Q_PROPERTY(QStringList allowForSessionCookies READ allowForSessionCookies WRITE setAllowForSessionCookies) - Q_ENUMS(KeepPolicy) - Q_ENUMS(AcceptPolicy) - -signals: - void cookiesChanged(); - -public: - enum AcceptPolicy { - AcceptAlways, - AcceptNever, - AcceptOnlyFromSitesNavigatedTo - }; - - enum KeepPolicy { - KeepUntilExpire, - KeepUntilExit, - KeepUntilTimeLimit - }; - - CookieJar(QObject *parent = 0); - ~CookieJar(); - - QList cookiesForUrl(const QUrl &url) const; - bool setCookiesFromUrl(const QList &cookieList, const QUrl &url); - - AcceptPolicy acceptPolicy() const; - void setAcceptPolicy(AcceptPolicy policy); - - KeepPolicy keepPolicy() const; - void setKeepPolicy(KeepPolicy policy); - - QStringList blockedCookies() const; - QStringList allowedCookies() const; - QStringList allowForSessionCookies() const; - - void setBlockedCookies(const QStringList &list); - void setAllowedCookies(const QStringList &list); - void setAllowForSessionCookies(const QStringList &list); - -public slots: - void clear(); - void loadSettings(); - -private slots: - void save(); - -private: - void purgeOldCookies(); - void load(); - bool m_loaded; - AutoSaver *m_saveTimer; - - AcceptPolicy m_acceptCookies; - KeepPolicy m_keepCookies; - - QStringList m_exceptions_block; - QStringList m_exceptions_allow; - QStringList m_exceptions_allowForSession; -}; - -class CookieModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - CookieModel(CookieJar *jar, QObject *parent = 0); - QVariant headerData(int section, Qt::Orientation orientation, int role) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); - -private slots: - void cookiesChanged(); - -private: - CookieJar *m_cookieJar; -}; - -#include "ui_cookies.h" -#include "ui_cookiesexceptions.h" - -class CookiesDialog : public QDialog, public Ui_CookiesDialog -{ - Q_OBJECT - -public: - CookiesDialog(CookieJar *cookieJar, QWidget *parent = 0); - -private: - QSortFilterProxyModel *m_proxyModel; -}; - -class CookieExceptionsModel : public QAbstractTableModel -{ - Q_OBJECT - friend class CookiesExceptionsDialog; - -public: - CookieExceptionsModel(CookieJar *cookieJar, QObject *parent = 0); - QVariant headerData(int section, Qt::Orientation orientation, int role) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); - -private: - CookieJar *m_cookieJar; - - // Domains we allow, Domains we block, Domains we allow for this session - QStringList m_allowedCookies; - QStringList m_blockedCookies; - QStringList m_sessionCookies; -}; - -class CookiesExceptionsDialog : public QDialog, public Ui_CookiesExceptionsDialog -{ - Q_OBJECT - -public: - CookiesExceptionsDialog(CookieJar *cookieJar, QWidget *parent = 0); - -private slots: - void block(); - void allow(); - void allowForSession(); - void textChanged(const QString &text); - -private: - CookieExceptionsModel *m_exceptionsModel; - QSortFilterProxyModel *m_proxyModel; - CookieJar *m_cookieJar; -}; - -#endif // COOKIEJAR_H - diff --git a/examples/gestures/browser/cookies.ui b/examples/gestures/browser/cookies.ui deleted file mode 100644 index c4bccc5..0000000 --- a/examples/gestures/browser/cookies.ui +++ /dev/null @@ -1,106 +0,0 @@ - - CookiesDialog - - - - 0 - 0 - 550 - 370 - - - - Cookies - - - - - - Qt::Horizontal - - - - 252 - 20 - - - - - - - - - - - - - - - - &Remove - - - - - - - Remove &All Cookies - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - QDialogButtonBox::Ok - - - - - - - - - - SearchLineEdit - QLineEdit -

searchlineedit.h
- - - EditTableView - QTableView -
edittableview.h
-
- - - - - buttonBox - accepted() - CookiesDialog - accept() - - - 472 - 329 - - - 461 - 356 - - - - - diff --git a/examples/gestures/browser/cookiesexceptions.ui b/examples/gestures/browser/cookiesexceptions.ui deleted file mode 100644 index 3d9ef62..0000000 --- a/examples/gestures/browser/cookiesexceptions.ui +++ /dev/null @@ -1,184 +0,0 @@ - - CookiesExceptionsDialog - - - - 0 - 0 - 466 - 446 - - - - Cookie Exceptions - - - - - - New Exception - - - - - - - - Domain: - - - - - - - - - - - - - - Qt::Horizontal - - - - 81 - 25 - - - - - - - - false - - - Block - - - - - - - false - - - Allow For Session - - - - - - - false - - - Allow - - - - - - - - - - - - Exceptions - - - - - - Qt::Horizontal - - - - 252 - 20 - - - - - - - - - - - - - - &Remove - - - - - - - Remove &All - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Ok - - - - - - - - SearchLineEdit - QLineEdit -
searchlineedit.h
-
- - EditTableView - QTableView -
edittableview.h
-
-
- - - - buttonBox - accepted() - CookiesExceptionsDialog - accept() - - - 381 - 428 - - - 336 - 443 - - - - -
diff --git a/examples/gestures/browser/data/addtab.png b/examples/gestures/browser/data/addtab.png deleted file mode 100644 index 20928fb..0000000 Binary files a/examples/gestures/browser/data/addtab.png and /dev/null differ diff --git a/examples/gestures/browser/data/browser.svg b/examples/gestures/browser/data/browser.svg deleted file mode 100644 index 4b0fa72..0000000 --- a/examples/gestures/browser/data/browser.svg +++ /dev/null @@ -1,411 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - Qt Browser - - - Jens Bache-Wiig - - - - - Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/gestures/browser/data/closetab.png b/examples/gestures/browser/data/closetab.png deleted file mode 100644 index ab9d669..0000000 Binary files a/examples/gestures/browser/data/closetab.png and /dev/null differ diff --git a/examples/gestures/browser/data/data.qrc b/examples/gestures/browser/data/data.qrc deleted file mode 100644 index c7d0294..0000000 --- a/examples/gestures/browser/data/data.qrc +++ /dev/null @@ -1,11 +0,0 @@ - - - addtab.png - closetab.png - history.png - browser.svg - defaultbookmarks.xbel - loading.gif - defaulticon.png - - diff --git a/examples/gestures/browser/data/defaultbookmarks.xbel b/examples/gestures/browser/data/defaultbookmarks.xbel deleted file mode 100644 index a168244..0000000 --- a/examples/gestures/browser/data/defaultbookmarks.xbel +++ /dev/null @@ -1,40 +0,0 @@ - - - - - Bookmarks Bar - - Qt Software - - - WebKit.org - - - Qt Documentation - - - Qt Quarterly - - - Qt Labs - - - Qt Centre - - - Qt-Apps.org - - - qtnode - - - xkcd - - - - Bookmarks Menu - - reddit.com: what's new online! - - - diff --git a/examples/gestures/browser/data/defaulticon.png b/examples/gestures/browser/data/defaulticon.png deleted file mode 100644 index 01a0920..0000000 Binary files a/examples/gestures/browser/data/defaulticon.png and /dev/null differ diff --git a/examples/gestures/browser/data/history.png b/examples/gestures/browser/data/history.png deleted file mode 100644 index 552a1cb..0000000 Binary files a/examples/gestures/browser/data/history.png and /dev/null differ diff --git a/examples/gestures/browser/data/loading.gif b/examples/gestures/browser/data/loading.gif deleted file mode 100644 index c1545eb..0000000 Binary files a/examples/gestures/browser/data/loading.gif and /dev/null differ diff --git a/examples/gestures/browser/downloaditem.ui b/examples/gestures/browser/downloaditem.ui deleted file mode 100644 index 4a0a0fd..0000000 --- a/examples/gestures/browser/downloaditem.ui +++ /dev/null @@ -1,134 +0,0 @@ - - DownloadItem - - - - 0 - 0 - 423 - 110 - - - - Form - - - - 0 - - - - - - 0 - 0 - - - - Ico - - - - - - - - - - 0 - 0 - - - - Filename - - - - - - - 0 - - - - - - - - 0 - 0 - - - - - - - - - - - - - - - Qt::Vertical - - - - 17 - 1 - - - - - - - - false - - - Try Again - - - - - - - Stop - - - - - - - Open - - - - - - - Qt::Vertical - - - - 17 - 5 - - - - - - - - - - - SqueezeLabel - QWidget -
squeezelabel.h
-
-
- - -
diff --git a/examples/gestures/browser/downloadmanager.cpp b/examples/gestures/browser/downloadmanager.cpp deleted file mode 100644 index 8e23795..0000000 --- a/examples/gestures/browser/downloadmanager.cpp +++ /dev/null @@ -1,579 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 "downloadmanager.h" - -#include "autosaver.h" -#include "browserapplication.h" -#include "networkaccessmanager.h" - -#include - -#include -#include - -#include -#include -#include -#include - -#include - -#include - -/*! - DownloadItem is a widget that is displayed in the download manager list. - It moves the data from the QNetworkReply into the QFile as well - as update the information/progressbar and report errors. - */ -DownloadItem::DownloadItem(QNetworkReply *reply, bool requestFileName, QWidget *parent) - : QWidget(parent) - , m_reply(reply) - , m_requestFileName(requestFileName) - , m_bytesReceived(0) -{ - setupUi(this); - QPalette p = downloadInfoLabel->palette(); - p.setColor(QPalette::Text, Qt::darkGray); - downloadInfoLabel->setPalette(p); - progressBar->setMaximum(0); - tryAgainButton->hide(); - connect(stopButton, SIGNAL(clicked()), this, SLOT(stop())); - connect(openButton, SIGNAL(clicked()), this, SLOT(open())); - connect(tryAgainButton, SIGNAL(clicked()), this, SLOT(tryAgain())); - - init(); -} - -void DownloadItem::init() -{ - if (!m_reply) - return; - - // attach to the m_reply - m_url = m_reply->url(); - m_reply->setParent(this); - connect(m_reply, SIGNAL(readyRead()), this, SLOT(downloadReadyRead())); - connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)), - this, SLOT(error(QNetworkReply::NetworkError))); - connect(m_reply, SIGNAL(downloadProgress(qint64, qint64)), - this, SLOT(downloadProgress(qint64, qint64))); - connect(m_reply, SIGNAL(metaDataChanged()), - this, SLOT(metaDataChanged())); - connect(m_reply, SIGNAL(finished()), - this, SLOT(finished())); - - // reset info - downloadInfoLabel->clear(); - progressBar->setValue(0); - getFileName(); - - // start timer for the download estimation - m_downloadTime.start(); - - if (m_reply->error() != QNetworkReply::NoError) { - error(m_reply->error()); - finished(); - } -} - -void DownloadItem::getFileName() -{ - QSettings settings; - settings.beginGroup(QLatin1String("downloadmanager")); - QString defaultLocation = QDesktopServices::storageLocation(QDesktopServices::DesktopLocation); - QString downloadDirectory = settings.value(QLatin1String("downloadDirectory"), defaultLocation).toString(); - if (!downloadDirectory.isEmpty()) - downloadDirectory += QLatin1Char('/'); - - QString defaultFileName = saveFileName(downloadDirectory); - QString fileName = defaultFileName; - if (m_requestFileName) { - fileName = QFileDialog::getSaveFileName(this, tr("Save File"), defaultFileName); - if (fileName.isEmpty()) { - m_reply->close(); - fileNameLabel->setText(tr("Download canceled: %1").arg(QFileInfo(defaultFileName).fileName())); - return; - } - } - m_output.setFileName(fileName); - fileNameLabel->setText(QFileInfo(m_output.fileName()).fileName()); - if (m_requestFileName) - downloadReadyRead(); -} - -QString DownloadItem::saveFileName(const QString &directory) const -{ - // Move this function into QNetworkReply to also get file name sent from the server - QString path = m_url.path(); - QFileInfo info(path); - QString baseName = info.completeBaseName(); - QString endName = info.suffix(); - - if (baseName.isEmpty()) { - baseName = QLatin1String("unnamed_download"); - qDebug() << "DownloadManager:: downloading unknown file:" << m_url; - } - QString name = directory + baseName + QLatin1Char('.') + endName; - if (QFile::exists(name)) { - // already exists, don't overwrite - int i = 1; - do { - name = directory + baseName + QLatin1Char('-') + QString::number(i++) + QLatin1Char('.') + endName; - } while (QFile::exists(name)); - } - return name; -} - - -void DownloadItem::stop() -{ - setUpdatesEnabled(false); - stopButton->setEnabled(false); - stopButton->hide(); - tryAgainButton->setEnabled(true); - tryAgainButton->show(); - setUpdatesEnabled(true); - m_reply->abort(); -} - -void DownloadItem::open() -{ - QFileInfo info(m_output); - QUrl url = QUrl::fromLocalFile(info.absolutePath()); - QDesktopServices::openUrl(url); -} - -void DownloadItem::tryAgain() -{ - if (!tryAgainButton->isEnabled()) - return; - - tryAgainButton->setEnabled(false); - tryAgainButton->setVisible(false); - stopButton->setEnabled(true); - stopButton->setVisible(true); - progressBar->setVisible(true); - - QNetworkReply *r = BrowserApplication::networkAccessManager()->get(QNetworkRequest(m_url)); - if (m_reply) - m_reply->deleteLater(); - if (m_output.exists()) - m_output.remove(); - m_reply = r; - init(); - emit statusChanged(); -} - -void DownloadItem::downloadReadyRead() -{ - if (m_requestFileName && m_output.fileName().isEmpty()) - return; - if (!m_output.isOpen()) { - // in case someone else has already put a file there - if (!m_requestFileName) - getFileName(); - if (!m_output.open(QIODevice::WriteOnly)) { - downloadInfoLabel->setText(tr("Error opening save file: %1") - .arg(m_output.errorString())); - stopButton->click(); - emit statusChanged(); - return; - } - emit statusChanged(); - } - if (-1 == m_output.write(m_reply->readAll())) { - downloadInfoLabel->setText(tr("Error saving: %1") - .arg(m_output.errorString())); - stopButton->click(); - } -} - -void DownloadItem::error(QNetworkReply::NetworkError) -{ - qDebug() << "DownloadItem::error" << m_reply->errorString() << m_url; - downloadInfoLabel->setText(tr("Network Error: %1").arg(m_reply->errorString())); - tryAgainButton->setEnabled(true); - tryAgainButton->setVisible(true); -} - -void DownloadItem::metaDataChanged() -{ - qDebug() << "DownloadItem::metaDataChanged: not handled."; -} - -void DownloadItem::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) -{ - m_bytesReceived = bytesReceived; - if (bytesTotal == -1) { - progressBar->setValue(0); - progressBar->setMaximum(0); - } else { - progressBar->setValue(bytesReceived); - progressBar->setMaximum(bytesTotal); - } - updateInfoLabel(); -} - -void DownloadItem::updateInfoLabel() -{ - if (m_reply->error() == QNetworkReply::NoError) - return; - - qint64 bytesTotal = progressBar->maximum(); - bool running = !downloadedSuccessfully(); - - // update info label - double speed = m_bytesReceived * 1000.0 / m_downloadTime.elapsed(); - double timeRemaining = ((double)(bytesTotal - m_bytesReceived)) / speed; - QString timeRemainingString = tr("seconds"); - if (timeRemaining > 60) { - timeRemaining = timeRemaining / 60; - timeRemainingString = tr("minutes"); - } - timeRemaining = floor(timeRemaining); - - // When downloading the eta should never be 0 - if (timeRemaining == 0) - timeRemaining = 1; - - QString info; - if (running) { - QString remaining; - if (bytesTotal != 0) - remaining = tr("- %4 %5 remaining") - .arg(timeRemaining) - .arg(timeRemainingString); - info = QString(tr("%1 of %2 (%3/sec) %4")) - .arg(dataString(m_bytesReceived)) - .arg(bytesTotal == 0 ? tr("?") : dataString(bytesTotal)) - .arg(dataString((int)speed)) - .arg(remaining); - } else { - if (m_bytesReceived == bytesTotal) - info = dataString(m_output.size()); - else - info = tr("%1 of %2 - Stopped") - .arg(dataString(m_bytesReceived)) - .arg(dataString(bytesTotal)); - } - downloadInfoLabel->setText(info); -} - -QString DownloadItem::dataString(int size) const -{ - QString unit; - if (size < 1024) { - unit = tr("bytes"); - } else if (size < 1024*1024) { - size /= 1024; - unit = tr("kB"); - } else { - size /= 1024*1024; - unit = tr("MB"); - } - return QString(QLatin1String("%1 %2")).arg(size).arg(unit); -} - -bool DownloadItem::downloading() const -{ - return (progressBar->isVisible()); -} - -bool DownloadItem::downloadedSuccessfully() const -{ - return (stopButton->isHidden() && tryAgainButton->isHidden()); -} - -void DownloadItem::finished() -{ - progressBar->hide(); - stopButton->setEnabled(false); - stopButton->hide(); - m_output.close(); - updateInfoLabel(); - emit statusChanged(); -} - -/*! - DownloadManager is a Dialog that contains a list of DownloadItems - - It is a basic download manager. It only downloads the file, doesn't do BitTorrent, - extract zipped files or anything fancy. - */ -DownloadManager::DownloadManager(QWidget *parent) - : QDialog(parent) - , m_autoSaver(new AutoSaver(this)) - , m_manager(BrowserApplication::networkAccessManager()) - , m_iconProvider(0) - , m_removePolicy(Never) -{ - setupUi(this); - downloadsView->setShowGrid(false); - downloadsView->verticalHeader()->hide(); - downloadsView->horizontalHeader()->hide(); - downloadsView->setAlternatingRowColors(true); - downloadsView->horizontalHeader()->setStretchLastSection(true); - m_model = new DownloadModel(this); - downloadsView->setModel(m_model); - connect(cleanupButton, SIGNAL(clicked()), this, SLOT(cleanup())); - load(); -} - -DownloadManager::~DownloadManager() -{ - m_autoSaver->changeOccurred(); - m_autoSaver->saveIfNeccessary(); - if (m_iconProvider) - delete m_iconProvider; -} - -int DownloadManager::activeDownloads() const -{ - int count = 0; - for (int i = 0; i < m_downloads.count(); ++i) { - if (m_downloads.at(i)->stopButton->isEnabled()) - ++count; - } - return count; -} - -void DownloadManager::download(const QNetworkRequest &request, bool requestFileName) -{ - if (request.url().isEmpty()) - return; - handleUnsupportedContent(m_manager->get(request), requestFileName); -} - -void DownloadManager::handleUnsupportedContent(QNetworkReply *reply, bool requestFileName) -{ - if (!reply || reply->url().isEmpty()) - return; - QVariant header = reply->header(QNetworkRequest::ContentLengthHeader); - bool ok; - int size = header.toInt(&ok); - if (ok && size == 0) - return; - - qDebug() << "DownloadManager::handleUnsupportedContent" << reply->url() << "requestFileName" << requestFileName; - DownloadItem *item = new DownloadItem(reply, requestFileName, this); - addItem(item); -} - -void DownloadManager::addItem(DownloadItem *item) -{ - connect(item, SIGNAL(statusChanged()), this, SLOT(updateRow())); - int row = m_downloads.count(); - m_model->beginInsertRows(QModelIndex(), row, row); - m_downloads.append(item); - m_model->endInsertRows(); - updateItemCount(); - if (row == 0) - show(); - downloadsView->setIndexWidget(m_model->index(row, 0), item); - QIcon icon = style()->standardIcon(QStyle::SP_FileIcon); - item->fileIcon->setPixmap(icon.pixmap(48, 48)); - downloadsView->setRowHeight(row, item->sizeHint().height()); -} - -void DownloadManager::updateRow() -{ - DownloadItem *item = qobject_cast(sender()); - int row = m_downloads.indexOf(item); - if (-1 == row) - return; - if (!m_iconProvider) - m_iconProvider = new QFileIconProvider(); - QIcon icon = m_iconProvider->icon(item->m_output.fileName()); - if (icon.isNull()) - icon = style()->standardIcon(QStyle::SP_FileIcon); - item->fileIcon->setPixmap(icon.pixmap(48, 48)); - downloadsView->setRowHeight(row, item->minimumSizeHint().height()); - - bool remove = false; - QWebSettings *globalSettings = QWebSettings::globalSettings(); - if (!item->downloading() - && globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled)) - remove = true; - - if (item->downloadedSuccessfully() - && removePolicy() == DownloadManager::SuccessFullDownload) { - remove = true; - } - if (remove) - m_model->removeRow(row); - - cleanupButton->setEnabled(m_downloads.count() - activeDownloads() > 0); -} - -DownloadManager::RemovePolicy DownloadManager::removePolicy() const -{ - return m_removePolicy; -} - -void DownloadManager::setRemovePolicy(RemovePolicy policy) -{ - if (policy == m_removePolicy) - return; - m_removePolicy = policy; - m_autoSaver->changeOccurred(); -} - -void DownloadManager::save() const -{ - QSettings settings; - settings.beginGroup(QLatin1String("downloadmanager")); - QMetaEnum removePolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("RemovePolicy")); - settings.setValue(QLatin1String("removeDownloadsPolicy"), QLatin1String(removePolicyEnum.valueToKey(m_removePolicy))); - settings.setValue(QLatin1String("size"), size()); - if (m_removePolicy == Exit) - return; - - for (int i = 0; i < m_downloads.count(); ++i) { - QString key = QString(QLatin1String("download_%1_")).arg(i); - settings.setValue(key + QLatin1String("url"), m_downloads[i]->m_url); - settings.setValue(key + QLatin1String("location"), QFileInfo(m_downloads[i]->m_output).filePath()); - settings.setValue(key + QLatin1String("done"), m_downloads[i]->downloadedSuccessfully()); - } - int i = m_downloads.count(); - QString key = QString(QLatin1String("download_%1_")).arg(i); - while (settings.contains(key + QLatin1String("url"))) { - settings.remove(key + QLatin1String("url")); - settings.remove(key + QLatin1String("location")); - settings.remove(key + QLatin1String("done")); - key = QString(QLatin1String("download_%1_")).arg(++i); - } -} - -void DownloadManager::load() -{ - QSettings settings; - settings.beginGroup(QLatin1String("downloadmanager")); - QSize size = settings.value(QLatin1String("size")).toSize(); - if (size.isValid()) - resize(size); - QByteArray value = settings.value(QLatin1String("removeDownloadsPolicy"), QLatin1String("Never")).toByteArray(); - QMetaEnum removePolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("RemovePolicy")); - m_removePolicy = removePolicyEnum.keyToValue(value) == -1 ? - Never : - static_cast(removePolicyEnum.keyToValue(value)); - - int i = 0; - QString key = QString(QLatin1String("download_%1_")).arg(i); - while (settings.contains(key + QLatin1String("url"))) { - QUrl url = settings.value(key + QLatin1String("url")).toUrl(); - QString fileName = settings.value(key + QLatin1String("location")).toString(); - bool done = settings.value(key + QLatin1String("done"), true).toBool(); - if (!url.isEmpty() && !fileName.isEmpty()) { - DownloadItem *item = new DownloadItem(0, this); - item->m_output.setFileName(fileName); - item->fileNameLabel->setText(QFileInfo(item->m_output.fileName()).fileName()); - item->m_url = url; - item->stopButton->setVisible(false); - item->stopButton->setEnabled(false); - item->tryAgainButton->setVisible(!done); - item->tryAgainButton->setEnabled(!done); - item->progressBar->setVisible(!done); - addItem(item); - } - key = QString(QLatin1String("download_%1_")).arg(++i); - } - cleanupButton->setEnabled(m_downloads.count() - activeDownloads() > 0); -} - -void DownloadManager::cleanup() -{ - if (m_downloads.isEmpty()) - return; - m_model->removeRows(0, m_downloads.count()); - updateItemCount(); - if (m_downloads.isEmpty() && m_iconProvider) { - delete m_iconProvider; - m_iconProvider = 0; - } - m_autoSaver->changeOccurred(); -} - -void DownloadManager::updateItemCount() -{ - int count = m_downloads.count(); - itemCount->setText(count == 1 ? tr("1 Download") : tr("%1 Downloads").arg(count)); -} - -DownloadModel::DownloadModel(DownloadManager *downloadManager, QObject *parent) - : QAbstractListModel(parent) - , m_downloadManager(downloadManager) -{ -} - -QVariant DownloadModel::data(const QModelIndex &index, int role) const -{ - if (index.row() < 0 || index.row() >= rowCount(index.parent())) - return QVariant(); - if (role == Qt::ToolTipRole) - if (!m_downloadManager->m_downloads.at(index.row())->downloadedSuccessfully()) - return m_downloadManager->m_downloads.at(index.row())->downloadInfoLabel->text(); - return QVariant(); -} - -int DownloadModel::rowCount(const QModelIndex &parent) const -{ - return (parent.isValid()) ? 0 : m_downloadManager->m_downloads.count(); -} - -bool DownloadModel::removeRows(int row, int count, const QModelIndex &parent) -{ - if (parent.isValid()) - return false; - - int lastRow = row + count - 1; - for (int i = lastRow; i >= row; --i) { - if (m_downloadManager->m_downloads.at(i)->downloadedSuccessfully() - || m_downloadManager->m_downloads.at(i)->tryAgainButton->isEnabled()) { - beginRemoveRows(parent, i, i); - m_downloadManager->m_downloads.takeAt(i)->deleteLater(); - endRemoveRows(); - } - } - m_downloadManager->m_autoSaver->changeOccurred(); - return true; -} - diff --git a/examples/gestures/browser/downloadmanager.h b/examples/gestures/browser/downloadmanager.h deleted file mode 100644 index af13fec..0000000 --- a/examples/gestures/browser/downloadmanager.h +++ /dev/null @@ -1,162 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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$ -** -****************************************************************************/ - -#ifndef DOWNLOADMANAGER_H -#define DOWNLOADMANAGER_H - -#include "ui_downloads.h" -#include "ui_downloaditem.h" - -#include - -#include -#include - -class DownloadItem : public QWidget, public Ui_DownloadItem -{ - Q_OBJECT - -signals: - void statusChanged(); - -public: - DownloadItem(QNetworkReply *reply = 0, bool requestFileName = false, QWidget *parent = 0); - bool downloading() const; - bool downloadedSuccessfully() const; - - QUrl m_url; - - QFile m_output; - QNetworkReply *m_reply; - -private slots: - void stop(); - void tryAgain(); - void open(); - - void downloadReadyRead(); - void error(QNetworkReply::NetworkError code); - void downloadProgress(qint64 bytesReceived, qint64 bytesTotal); - void metaDataChanged(); - void finished(); - -private: - void getFileName(); - void init(); - void updateInfoLabel(); - QString dataString(int size) const; - - QString saveFileName(const QString &directory) const; - - bool m_requestFileName; - qint64 m_bytesReceived; - QTime m_downloadTime; -}; - -class AutoSaver; -class DownloadModel; -QT_BEGIN_NAMESPACE -class QFileIconProvider; -QT_END_NAMESPACE - -class DownloadManager : public QDialog, public Ui_DownloadDialog -{ - Q_OBJECT - Q_PROPERTY(RemovePolicy removePolicy READ removePolicy WRITE setRemovePolicy) - Q_ENUMS(RemovePolicy) - -public: - enum RemovePolicy { - Never, - Exit, - SuccessFullDownload - }; - - DownloadManager(QWidget *parent = 0); - ~DownloadManager(); - int activeDownloads() const; - - RemovePolicy removePolicy() const; - void setRemovePolicy(RemovePolicy policy); - -public slots: - void download(const QNetworkRequest &request, bool requestFileName = false); - inline void download(const QUrl &url, bool requestFileName = false) - { download(QNetworkRequest(url), requestFileName); } - void handleUnsupportedContent(QNetworkReply *reply, bool requestFileName = false); - void cleanup(); - -private slots: - void save() const; - void updateRow(); - -private: - void addItem(DownloadItem *item); - void updateItemCount(); - void load(); - - AutoSaver *m_autoSaver; - DownloadModel *m_model; - QNetworkAccessManager *m_manager; - QFileIconProvider *m_iconProvider; - QList m_downloads; - RemovePolicy m_removePolicy; - friend class DownloadModel; -}; - -class DownloadModel : public QAbstractListModel -{ - friend class DownloadManager; - Q_OBJECT - -public: - DownloadModel(DownloadManager *downloadManager, QObject *parent = 0); - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); - -private: - DownloadManager *m_downloadManager; - -}; - -#endif // DOWNLOADMANAGER_H - diff --git a/examples/gestures/browser/downloads.ui b/examples/gestures/browser/downloads.ui deleted file mode 100644 index a2e2569..0000000 --- a/examples/gestures/browser/downloads.ui +++ /dev/null @@ -1,83 +0,0 @@ - - DownloadDialog - - - - 0 - 0 - 332 - 252 - - - - Downloads - - - - 0 - - - 0 - - - - - - - - - - false - - - Clean up - - - - - - - Qt::Horizontal - - - - 58 - 24 - - - - - - - - - - 0 Items - - - - - - - Qt::Horizontal - - - - 148 - 20 - - - - - - - - - EditTableView - QTableView -
edittableview.h
-
-
- - -
diff --git a/examples/gestures/browser/edittableview.cpp b/examples/gestures/browser/edittableview.cpp deleted file mode 100644 index f7d5e67..0000000 --- a/examples/gestures/browser/edittableview.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 "edittableview.h" -#include - -EditTableView::EditTableView(QWidget *parent) - : QTableView(parent) -{ -} - -void EditTableView::keyPressEvent(QKeyEvent *event) -{ - if ((event->key() == Qt::Key_Delete - || event->key() == Qt::Key_Backspace) - && model()) { - removeOne(); - } else { - QAbstractItemView::keyPressEvent(event); - } -} - -void EditTableView::removeOne() -{ - if (!model() || !selectionModel()) - return; - int row = currentIndex().row(); - model()->removeRow(row, rootIndex()); - QModelIndex idx = model()->index(row, 0, rootIndex()); - if (!idx.isValid()) - idx = model()->index(row - 1, 0, rootIndex()); - selectionModel()->select(idx, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); -} - -void EditTableView::removeAll() -{ - if (model()) - model()->removeRows(0, model()->rowCount(rootIndex()), rootIndex()); -} - diff --git a/examples/gestures/browser/edittableview.h b/examples/gestures/browser/edittableview.h deleted file mode 100644 index fb033ce..0000000 --- a/examples/gestures/browser/edittableview.h +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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$ -** -****************************************************************************/ - -#ifndef EDITTABLEVIEW_H -#define EDITTABLEVIEW_H - -#include - -class EditTableView : public QTableView -{ - Q_OBJECT - -public: - EditTableView(QWidget *parent = 0); - void keyPressEvent(QKeyEvent *event); - -public slots: - void removeOne(); - void removeAll(); -}; - -#endif // EDITTABLEVIEW_H - diff --git a/examples/gestures/browser/edittreeview.cpp b/examples/gestures/browser/edittreeview.cpp deleted file mode 100644 index c7cefe6..0000000 --- a/examples/gestures/browser/edittreeview.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 "edittreeview.h" - -#include - -EditTreeView::EditTreeView(QWidget *parent) - : QTreeView(parent) -{ -} - -void EditTreeView::keyPressEvent(QKeyEvent *event) -{ - if ((event->key() == Qt::Key_Delete - || event->key() == Qt::Key_Backspace) - && model()) { - removeOne(); - } else { - QAbstractItemView::keyPressEvent(event); - } -} - -void EditTreeView::removeOne() -{ - if (!model()) - return; - QModelIndex ci = currentIndex(); - int row = ci.row(); - model()->removeRow(row, ci.parent()); -} - -void EditTreeView::removeAll() -{ - if (!model()) - return; - model()->removeRows(0, model()->rowCount(rootIndex()), rootIndex()); -} - diff --git a/examples/gestures/browser/edittreeview.h b/examples/gestures/browser/edittreeview.h deleted file mode 100644 index 3a6fcaf..0000000 --- a/examples/gestures/browser/edittreeview.h +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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$ -** -****************************************************************************/ - -#ifndef EDITTREEVIEW_H -#define EDITTREEVIEW_H - -#include - -class EditTreeView : public QTreeView -{ - Q_OBJECT - -public: - EditTreeView(QWidget *parent = 0); - void keyPressEvent(QKeyEvent *event); - -public slots: - void removeOne(); - void removeAll(); -}; - -#endif // EDITTREEVIEW_H - diff --git a/examples/gestures/browser/history.cpp b/examples/gestures/browser/history.cpp deleted file mode 100644 index 0e0652d..0000000 --- a/examples/gestures/browser/history.cpp +++ /dev/null @@ -1,1282 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 "history.h" - -#include "autosaver.h" -#include "browserapplication.h" - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include -#include - -#include - -static const unsigned int HISTORY_VERSION = 23; - -HistoryManager::HistoryManager(QObject *parent) - : QWebHistoryInterface(parent) - , m_saveTimer(new AutoSaver(this)) - , m_historyLimit(30) - , m_historyModel(0) - , m_historyFilterModel(0) - , m_historyTreeModel(0) -{ - m_expiredTimer.setSingleShot(true); - connect(&m_expiredTimer, SIGNAL(timeout()), - this, SLOT(checkForExpired())); - connect(this, SIGNAL(entryAdded(const HistoryItem &)), - m_saveTimer, SLOT(changeOccurred())); - connect(this, SIGNAL(entryRemoved(const HistoryItem &)), - m_saveTimer, SLOT(changeOccurred())); - load(); - - m_historyModel = new HistoryModel(this, this); - m_historyFilterModel = new HistoryFilterModel(m_historyModel, this); - m_historyTreeModel = new HistoryTreeModel(m_historyFilterModel, this); - - // QWebHistoryInterface will delete the history manager - QWebHistoryInterface::setDefaultInterface(this); -} - -HistoryManager::~HistoryManager() -{ - m_saveTimer->saveIfNeccessary(); -} - -QList HistoryManager::history() const -{ - return m_history; -} - -bool HistoryManager::historyContains(const QString &url) const -{ - return m_historyFilterModel->historyContains(url); -} - -void HistoryManager::addHistoryEntry(const QString &url) -{ - QUrl cleanUrl(url); - cleanUrl.setPassword(QString()); - cleanUrl.setHost(cleanUrl.host().toLower()); - HistoryItem item(cleanUrl.toString(), QDateTime::currentDateTime()); - addHistoryItem(item); -} - -void HistoryManager::setHistory(const QList &history, bool loadedAndSorted) -{ - m_history = history; - - // verify that it is sorted by date - if (!loadedAndSorted) - qSort(m_history.begin(), m_history.end()); - - checkForExpired(); - - if (loadedAndSorted) { - m_lastSavedUrl = m_history.value(0).url; - } else { - m_lastSavedUrl = QString(); - m_saveTimer->changeOccurred(); - } - emit historyReset(); -} - -HistoryModel *HistoryManager::historyModel() const -{ - return m_historyModel; -} - -HistoryFilterModel *HistoryManager::historyFilterModel() const -{ - return m_historyFilterModel; -} - -HistoryTreeModel *HistoryManager::historyTreeModel() const -{ - return m_historyTreeModel; -} - -void HistoryManager::checkForExpired() -{ - if (m_historyLimit < 0 || m_history.isEmpty()) - return; - - QDateTime now = QDateTime::currentDateTime(); - int nextTimeout = 0; - - while (!m_history.isEmpty()) { - QDateTime checkForExpired = m_history.last().dateTime; - checkForExpired.setDate(checkForExpired.date().addDays(m_historyLimit)); - if (now.daysTo(checkForExpired) > 7) { - // check at most in a week to prevent int overflows on the timer - nextTimeout = 7 * 86400; - } else { - nextTimeout = now.secsTo(checkForExpired); - } - if (nextTimeout > 0) - break; - HistoryItem item = m_history.takeLast(); - // remove from saved file also - m_lastSavedUrl = QString(); - emit entryRemoved(item); - } - - if (nextTimeout > 0) - m_expiredTimer.start(nextTimeout * 1000); -} - -void HistoryManager::addHistoryItem(const HistoryItem &item) -{ - QWebSettings *globalSettings = QWebSettings::globalSettings(); - if (globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled)) - return; - - m_history.prepend(item); - emit entryAdded(item); - if (m_history.count() == 1) - checkForExpired(); -} - -void HistoryManager::updateHistoryItem(const QUrl &url, const QString &title) -{ - for (int i = 0; i < m_history.count(); ++i) { - if (url == m_history.at(i).url) { - m_history[i].title = title; - m_saveTimer->changeOccurred(); - if (m_lastSavedUrl.isEmpty()) - m_lastSavedUrl = m_history.at(i).url; - emit entryUpdated(i); - break; - } - } -} - -int HistoryManager::historyLimit() const -{ - return m_historyLimit; -} - -void HistoryManager::setHistoryLimit(int limit) -{ - if (m_historyLimit == limit) - return; - m_historyLimit = limit; - checkForExpired(); - m_saveTimer->changeOccurred(); -} - -void HistoryManager::clear() -{ - m_history.clear(); - m_lastSavedUrl = QString(); - m_saveTimer->changeOccurred(); - m_saveTimer->saveIfNeccessary(); - historyReset(); -} - -void HistoryManager::loadSettings() -{ - // load settings - QSettings settings; - settings.beginGroup(QLatin1String("history")); - m_historyLimit = settings.value(QLatin1String("historyLimit"), 30).toInt(); -} - -void HistoryManager::load() -{ - loadSettings(); - - QFile historyFile(QDesktopServices::storageLocation(QDesktopServices::DataLocation) - + QLatin1String("/history")); - if (!historyFile.exists()) - return; - if (!historyFile.open(QFile::ReadOnly)) { - qWarning() << "Unable to open history file" << historyFile.fileName(); - return; - } - - QList list; - QDataStream in(&historyFile); - // Double check that the history file is sorted as it is read in - bool needToSort = false; - HistoryItem lastInsertedItem; - QByteArray data; - QDataStream stream; - QBuffer buffer; - stream.setDevice(&buffer); - while (!historyFile.atEnd()) { - in >> data; - buffer.close(); - buffer.setBuffer(&data); - buffer.open(QIODevice::ReadOnly); - quint32 ver; - stream >> ver; - if (ver != HISTORY_VERSION) - continue; - HistoryItem item; - stream >> item.url; - stream >> item.dateTime; - stream >> item.title; - - if (!item.dateTime.isValid()) - continue; - - if (item == lastInsertedItem) { - if (lastInsertedItem.title.isEmpty() && !list.isEmpty()) - list[0].title = item.title; - continue; - } - - if (!needToSort && !list.isEmpty() && lastInsertedItem < item) - needToSort = true; - - list.prepend(item); - lastInsertedItem = item; - } - if (needToSort) - qSort(list.begin(), list.end()); - - setHistory(list, true); - - // If we had to sort re-write the whole history sorted - if (needToSort) { - m_lastSavedUrl = QString(); - m_saveTimer->changeOccurred(); - } -} - -void HistoryManager::save() -{ - QSettings settings; - settings.beginGroup(QLatin1String("history")); - settings.setValue(QLatin1String("historyLimit"), m_historyLimit); - - bool saveAll = m_lastSavedUrl.isEmpty(); - int first = m_history.count() - 1; - if (!saveAll) { - // find the first one to save - for (int i = 0; i < m_history.count(); ++i) { - if (m_history.at(i).url == m_lastSavedUrl) { - first = i - 1; - break; - } - } - } - if (first == m_history.count() - 1) - saveAll = true; - - QString directory = QDesktopServices::storageLocation(QDesktopServices::DataLocation); - if (directory.isEmpty()) - directory = QDir::homePath() + QLatin1String("/.") + QCoreApplication::applicationName(); - if (!QFile::exists(directory)) { - QDir dir; - dir.mkpath(directory); - } - - QFile historyFile(directory + QLatin1String("/history")); - // When saving everything use a temporary file to prevent possible data loss. - QTemporaryFile tempFile; - tempFile.setAutoRemove(false); - bool open = false; - if (saveAll) { - open = tempFile.open(); - } else { - open = historyFile.open(QFile::Append); - } - - if (!open) { - qWarning() << "Unable to open history file for saving" - << (saveAll ? tempFile.fileName() : historyFile.fileName()); - return; - } - - QDataStream out(saveAll ? &tempFile : &historyFile); - for (int i = first; i >= 0; --i) { - QByteArray data; - QDataStream stream(&data, QIODevice::WriteOnly); - HistoryItem item = m_history.at(i); - stream << HISTORY_VERSION << item.url << item.dateTime << item.title; - out << data; - } - tempFile.close(); - - if (saveAll) { - if (historyFile.exists() && !historyFile.remove()) - qWarning() << "History: error removing old history." << historyFile.errorString(); - if (!tempFile.rename(historyFile.fileName())) - qWarning() << "History: error moving new history over old." << tempFile.errorString() << historyFile.fileName(); - } - m_lastSavedUrl = m_history.value(0).url; -} - -HistoryModel::HistoryModel(HistoryManager *history, QObject *parent) - : QAbstractTableModel(parent) - , m_history(history) -{ - Q_ASSERT(m_history); - connect(m_history, SIGNAL(historyReset()), - this, SLOT(historyReset())); - connect(m_history, SIGNAL(entryRemoved(const HistoryItem &)), - this, SLOT(historyReset())); - - connect(m_history, SIGNAL(entryAdded(const HistoryItem &)), - this, SLOT(entryAdded())); - connect(m_history, SIGNAL(entryUpdated(int)), - this, SLOT(entryUpdated(int))); -} - -void HistoryModel::historyReset() -{ - reset(); -} - -void HistoryModel::entryAdded() -{ - beginInsertRows(QModelIndex(), 0, 0); - endInsertRows(); -} - -void HistoryModel::entryUpdated(int offset) -{ - QModelIndex idx = index(offset, 0); - emit dataChanged(idx, idx); -} - -QVariant HistoryModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (orientation == Qt::Horizontal - && role == Qt::DisplayRole) { - switch (section) { - case 0: return tr("Title"); - case 1: return tr("Address"); - } - } - return QAbstractTableModel::headerData(section, orientation, role); -} - -QVariant HistoryModel::data(const QModelIndex &index, int role) const -{ - QList lst = m_history->history(); - if (index.row() < 0 || index.row() >= lst.size()) - return QVariant(); - - const HistoryItem &item = lst.at(index.row()); - switch (role) { - case DateTimeRole: - return item.dateTime; - case DateRole: - return item.dateTime.date(); - case UrlRole: - return QUrl(item.url); - case UrlStringRole: - return item.url; - case Qt::DisplayRole: - case Qt::EditRole: { - switch (index.column()) { - case 0: - // when there is no title try to generate one from the url - if (item.title.isEmpty()) { - QString page = QFileInfo(QUrl(item.url).path()).fileName(); - if (!page.isEmpty()) - return page; - return item.url; - } - return item.title; - case 1: - return item.url; - } - } - case Qt::DecorationRole: - if (index.column() == 0) { - return BrowserApplication::instance()->icon(item.url); - } - } - return QVariant(); -} - -int HistoryModel::columnCount(const QModelIndex &parent) const -{ - return (parent.isValid()) ? 0 : 2; -} - -int HistoryModel::rowCount(const QModelIndex &parent) const -{ - return (parent.isValid()) ? 0 : m_history->history().count(); -} - -bool HistoryModel::removeRows(int row, int count, const QModelIndex &parent) -{ - if (parent.isValid()) - return false; - int lastRow = row + count - 1; - beginRemoveRows(parent, row, lastRow); - QList lst = m_history->history(); - for (int i = lastRow; i >= row; --i) - lst.removeAt(i); - disconnect(m_history, SIGNAL(historyReset()), this, SLOT(historyReset())); - m_history->setHistory(lst); - connect(m_history, SIGNAL(historyReset()), this, SLOT(historyReset())); - endRemoveRows(); - return true; -} - -#define MOVEDROWS 15 - -/* - Maps the first bunch of items of the source model to the root -*/ -HistoryMenuModel::HistoryMenuModel(HistoryTreeModel *sourceModel, QObject *parent) - : QAbstractProxyModel(parent) - , m_treeModel(sourceModel) -{ - setSourceModel(sourceModel); -} - -int HistoryMenuModel::bumpedRows() const -{ - QModelIndex first = m_treeModel->index(0, 0); - if (!first.isValid()) - return 0; - return qMin(m_treeModel->rowCount(first), MOVEDROWS); -} - -int HistoryMenuModel::columnCount(const QModelIndex &parent) const -{ - return m_treeModel->columnCount(mapToSource(parent)); -} - -int HistoryMenuModel::rowCount(const QModelIndex &parent) const -{ - if (parent.column() > 0) - return 0; - - if (!parent.isValid()) { - int folders = sourceModel()->rowCount(); - int bumpedItems = bumpedRows(); - if (bumpedItems <= MOVEDROWS - && bumpedItems == sourceModel()->rowCount(sourceModel()->index(0, 0))) - --folders; - return bumpedItems + folders; - } - - if (parent.internalId() == -1) { - if (parent.row() < bumpedRows()) - return 0; - } - - QModelIndex idx = mapToSource(parent); - int defaultCount = sourceModel()->rowCount(idx); - if (idx == sourceModel()->index(0, 0)) - return defaultCount - bumpedRows(); - return defaultCount; -} - -QModelIndex HistoryMenuModel::mapFromSource(const QModelIndex &sourceIndex) const -{ - // currently not used or autotested - Q_ASSERT(false); - int sr = m_treeModel->mapToSource(sourceIndex).row(); - return createIndex(sourceIndex.row(), sourceIndex.column(), sr); -} - -QModelIndex HistoryMenuModel::mapToSource(const QModelIndex &proxyIndex) const -{ - if (!proxyIndex.isValid()) - return QModelIndex(); - - if (proxyIndex.internalId() == -1) { - int bumpedItems = bumpedRows(); - if (proxyIndex.row() < bumpedItems) - return m_treeModel->index(proxyIndex.row(), proxyIndex.column(), m_treeModel->index(0, 0)); - if (bumpedItems <= MOVEDROWS && bumpedItems == sourceModel()->rowCount(m_treeModel->index(0, 0))) - --bumpedItems; - return m_treeModel->index(proxyIndex.row() - bumpedItems, proxyIndex.column()); - } - - QModelIndex historyIndex = m_treeModel->sourceModel()->index(proxyIndex.internalId(), proxyIndex.column()); - QModelIndex treeIndex = m_treeModel->mapFromSource(historyIndex); - return treeIndex; -} - -QModelIndex HistoryMenuModel::index(int row, int column, const QModelIndex &parent) const -{ - if (row < 0 - || column < 0 || column >= columnCount(parent) - || parent.column() > 0) - return QModelIndex(); - if (!parent.isValid()) - return createIndex(row, column, -1); - - QModelIndex treeIndexParent = mapToSource(parent); - - int bumpedItems = 0; - if (treeIndexParent == m_treeModel->index(0, 0)) - bumpedItems = bumpedRows(); - QModelIndex treeIndex = m_treeModel->index(row + bumpedItems, column, treeIndexParent); - QModelIndex historyIndex = m_treeModel->mapToSource(treeIndex); - int historyRow = historyIndex.row(); - if (historyRow == -1) - historyRow = treeIndex.row(); - return createIndex(row, column, historyRow); -} - -QModelIndex HistoryMenuModel::parent(const QModelIndex &index) const -{ - int offset = index.internalId(); - if (offset == -1 || !index.isValid()) - return QModelIndex(); - - QModelIndex historyIndex = m_treeModel->sourceModel()->index(index.internalId(), 0); - QModelIndex treeIndex = m_treeModel->mapFromSource(historyIndex); - QModelIndex treeIndexParent = treeIndex.parent(); - - int sr = m_treeModel->mapToSource(treeIndexParent).row(); - int bumpedItems = bumpedRows(); - if (bumpedItems <= MOVEDROWS && bumpedItems == sourceModel()->rowCount(sourceModel()->index(0, 0))) - --bumpedItems; - return createIndex(bumpedItems + treeIndexParent.row(), treeIndexParent.column(), sr); -} - - -HistoryMenu::HistoryMenu(QWidget *parent) - : ModelMenu(parent) - , m_history(0) -{ - connect(this, SIGNAL(activated(const QModelIndex &)), - this, SLOT(activated(const QModelIndex &))); - setHoverRole(HistoryModel::UrlStringRole); -} - -void HistoryMenu::activated(const QModelIndex &index) -{ - emit openUrl(index.data(HistoryModel::UrlRole).toUrl()); -} - -bool HistoryMenu::prePopulated() -{ - if (!m_history) { - m_history = BrowserApplication::historyManager(); - m_historyMenuModel = new HistoryMenuModel(m_history->historyTreeModel(), this); - setModel(m_historyMenuModel); - } - // initial actions - for (int i = 0; i < m_initialActions.count(); ++i) - addAction(m_initialActions.at(i)); - if (!m_initialActions.isEmpty()) - addSeparator(); - setFirstSeparator(m_historyMenuModel->bumpedRows()); - - return false; -} - -void HistoryMenu::postPopulated() -{ - if (m_history->history().count() > 0) - addSeparator(); - - QAction *showAllAction = new QAction(tr("Show All History"), this); - connect(showAllAction, SIGNAL(triggered()), this, SLOT(showHistoryDialog())); - addAction(showAllAction); - - QAction *clearAction = new QAction(tr("Clear History"), this); - connect(clearAction, SIGNAL(triggered()), m_history, SLOT(clear())); - addAction(clearAction); -} - -void HistoryMenu::showHistoryDialog() -{ - HistoryDialog *dialog = new HistoryDialog(this); - connect(dialog, SIGNAL(openUrl(const QUrl&)), - this, SIGNAL(openUrl(const QUrl&))); - dialog->show(); -} - -void HistoryMenu::setInitialActions(QList actions) -{ - m_initialActions = actions; - for (int i = 0; i < m_initialActions.count(); ++i) - addAction(m_initialActions.at(i)); -} - -TreeProxyModel::TreeProxyModel(QObject *parent) : QSortFilterProxyModel(parent) -{ - setSortRole(HistoryModel::DateTimeRole); - setFilterCaseSensitivity(Qt::CaseInsensitive); -} - -bool TreeProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const -{ - if (!source_parent.isValid()) - return true; - return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); -} - -HistoryDialog::HistoryDialog(QWidget *parent, HistoryManager *setHistory) : QDialog(parent) -{ - HistoryManager *history = setHistory; - if (!history) - history = BrowserApplication::historyManager(); - setupUi(this); - tree->setUniformRowHeights(true); - tree->setSelectionBehavior(QAbstractItemView::SelectRows); - tree->setTextElideMode(Qt::ElideMiddle); - QAbstractItemModel *model = history->historyTreeModel(); - TreeProxyModel *proxyModel = new TreeProxyModel(this); - connect(search, SIGNAL(textChanged(QString)), - proxyModel, SLOT(setFilterFixedString(QString))); - connect(removeButton, SIGNAL(clicked()), tree, SLOT(removeOne())); - connect(removeAllButton, SIGNAL(clicked()), history, SLOT(clear())); - proxyModel->setSourceModel(model); - tree->setModel(proxyModel); - tree->setExpanded(proxyModel->index(0, 0), true); - tree->setAlternatingRowColors(true); - QFontMetrics fm(font()); - int header = fm.width(QLatin1Char('m')) * 40; - tree->header()->resizeSection(0, header); - tree->header()->setStretchLastSection(true); - connect(tree, SIGNAL(activated(const QModelIndex&)), - this, SLOT(open())); - tree->setContextMenuPolicy(Qt::CustomContextMenu); - connect(tree, SIGNAL(customContextMenuRequested(const QPoint &)), - this, SLOT(customContextMenuRequested(const QPoint &))); -} - -void HistoryDialog::customContextMenuRequested(const QPoint &pos) -{ - QMenu menu; - QModelIndex index = tree->indexAt(pos); - index = index.sibling(index.row(), 0); - if (index.isValid() && !tree->model()->hasChildren(index)) { - menu.addAction(tr("Open"), this, SLOT(open())); - menu.addSeparator(); - menu.addAction(tr("Copy"), this, SLOT(copy())); - } - menu.addAction(tr("Delete"), tree, SLOT(removeOne())); - menu.exec(QCursor::pos()); -} - -void HistoryDialog::open() -{ - QModelIndex index = tree->currentIndex(); - if (!index.parent().isValid()) - return; - emit openUrl(index.data(HistoryModel::UrlRole).toUrl()); -} - -void HistoryDialog::copy() -{ - QModelIndex index = tree->currentIndex(); - if (!index.parent().isValid()) - return; - QString url = index.data(HistoryModel::UrlStringRole).toString(); - - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(url); -} - -HistoryFilterModel::HistoryFilterModel(QAbstractItemModel *sourceModel, QObject *parent) - : QAbstractProxyModel(parent), - m_loaded(false) -{ - setSourceModel(sourceModel); -} - -int HistoryFilterModel::historyLocation(const QString &url) const -{ - load(); - if (!m_historyHash.contains(url)) - return 0; - return sourceModel()->rowCount() - m_historyHash.value(url); -} - -QVariant HistoryFilterModel::data(const QModelIndex &index, int role) const -{ - return QAbstractProxyModel::data(index, role); -} - -void HistoryFilterModel::setSourceModel(QAbstractItemModel *newSourceModel) -{ - if (sourceModel()) { - disconnect(sourceModel(), SIGNAL(modelReset()), this, SLOT(sourceReset())); - disconnect(sourceModel(), SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), - this, SLOT(dataChanged(const QModelIndex &, const QModelIndex &))); - disconnect(sourceModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), - this, SLOT(sourceRowsInserted(const QModelIndex &, int, int))); - disconnect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(sourceRowsRemoved(const QModelIndex &, int, int))); - } - - QAbstractProxyModel::setSourceModel(newSourceModel); - - if (sourceModel()) { - m_loaded = false; - connect(sourceModel(), SIGNAL(modelReset()), this, SLOT(sourceReset())); - connect(sourceModel(), SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), - this, SLOT(sourceDataChanged(const QModelIndex &, const QModelIndex &))); - connect(sourceModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), - this, SLOT(sourceRowsInserted(const QModelIndex &, int, int))); - connect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(sourceRowsRemoved(const QModelIndex &, int, int))); - } -} - -void HistoryFilterModel::sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) -{ - emit dataChanged(mapFromSource(topLeft), mapFromSource(bottomRight)); -} - -QVariant HistoryFilterModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - return sourceModel()->headerData(section, orientation, role); -} - -void HistoryFilterModel::sourceReset() -{ - m_loaded = false; - reset(); -} - -int HistoryFilterModel::rowCount(const QModelIndex &parent) const -{ - load(); - if (parent.isValid()) - return 0; - return m_historyHash.count(); -} - -int HistoryFilterModel::columnCount(const QModelIndex &parent) const -{ - return (parent.isValid()) ? 0 : 2; -} - -QModelIndex HistoryFilterModel::mapToSource(const QModelIndex &proxyIndex) const -{ - load(); - int sourceRow = sourceModel()->rowCount() - proxyIndex.internalId(); - return sourceModel()->index(sourceRow, proxyIndex.column()); -} - -QModelIndex HistoryFilterModel::mapFromSource(const QModelIndex &sourceIndex) const -{ - load(); - QString url = sourceIndex.data(HistoryModel::UrlStringRole).toString(); - if (!m_historyHash.contains(url)) - return QModelIndex(); - - // This can be done in a binary search, but we can't use qBinary find - // because it can't take: qBinaryFind(m_sourceRow.end(), m_sourceRow.begin(), v); - // so if this is a performance bottlneck then convert to binary search, until then - // the cleaner/easier to read code wins the day. - int realRow = -1; - int sourceModelRow = sourceModel()->rowCount() - sourceIndex.row(); - - for (int i = 0; i < m_sourceRow.count(); ++i) { - if (m_sourceRow.at(i) == sourceModelRow) { - realRow = i; - break; - } - } - if (realRow == -1) - return QModelIndex(); - - return createIndex(realRow, sourceIndex.column(), sourceModel()->rowCount() - sourceIndex.row()); -} - -QModelIndex HistoryFilterModel::index(int row, int column, const QModelIndex &parent) const -{ - load(); - if (row < 0 || row >= rowCount(parent) - || column < 0 || column >= columnCount(parent)) - return QModelIndex(); - - return createIndex(row, column, m_sourceRow[row]); -} - -QModelIndex HistoryFilterModel::parent(const QModelIndex &) const -{ - return QModelIndex(); -} - -void HistoryFilterModel::load() const -{ - if (m_loaded) - return; - m_sourceRow.clear(); - m_historyHash.clear(); - m_historyHash.reserve(sourceModel()->rowCount()); - for (int i = 0; i < sourceModel()->rowCount(); ++i) { - QModelIndex idx = sourceModel()->index(i, 0); - QString url = idx.data(HistoryModel::UrlStringRole).toString(); - if (!m_historyHash.contains(url)) { - m_sourceRow.append(sourceModel()->rowCount() - i); - m_historyHash[url] = sourceModel()->rowCount() - i; - } - } - m_loaded = true; -} - -void HistoryFilterModel::sourceRowsInserted(const QModelIndex &parent, int start, int end) -{ - Q_ASSERT(start == end && start == 0); - Q_UNUSED(end); - if (!m_loaded) - return; - QModelIndex idx = sourceModel()->index(start, 0, parent); - QString url = idx.data(HistoryModel::UrlStringRole).toString(); - if (m_historyHash.contains(url)) { - int sourceRow = sourceModel()->rowCount() - m_historyHash[url]; - int realRow = mapFromSource(sourceModel()->index(sourceRow, 0)).row(); - beginRemoveRows(QModelIndex(), realRow, realRow); - m_sourceRow.removeAt(realRow); - m_historyHash.remove(url); - endRemoveRows(); - } - beginInsertRows(QModelIndex(), 0, 0); - m_historyHash.insert(url, sourceModel()->rowCount() - start); - m_sourceRow.insert(0, sourceModel()->rowCount()); - endInsertRows(); -} - -void HistoryFilterModel::sourceRowsRemoved(const QModelIndex &, int start, int end) -{ - Q_UNUSED(start); - Q_UNUSED(end); - sourceReset(); -} - -/* - Removing a continuous block of rows will remove filtered rows too as this is - the users intention. -*/ -bool HistoryFilterModel::removeRows(int row, int count, const QModelIndex &parent) -{ - if (row < 0 || count <= 0 || row + count > rowCount(parent) || parent.isValid()) - return false; - int lastRow = row + count - 1; - disconnect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(sourceRowsRemoved(const QModelIndex &, int, int))); - beginRemoveRows(parent, row, lastRow); - int oldCount = rowCount(); - int start = sourceModel()->rowCount() - m_sourceRow.value(row); - int end = sourceModel()->rowCount() - m_sourceRow.value(lastRow); - sourceModel()->removeRows(start, end - start + 1); - endRemoveRows(); - connect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(sourceRowsRemoved(const QModelIndex &, int, int))); - m_loaded = false; - if (oldCount - count != rowCount()) - reset(); - return true; -} - -HistoryCompletionModel::HistoryCompletionModel(QObject *parent) - : QAbstractProxyModel(parent) -{ -} - -QVariant HistoryCompletionModel::data(const QModelIndex &index, int role) const -{ - if (sourceModel() - && (role == Qt::EditRole || role == Qt::DisplayRole) - && index.isValid()) { - QModelIndex idx = mapToSource(index); - idx = idx.sibling(idx.row(), 1); - QString urlString = idx.data(HistoryModel::UrlStringRole).toString(); - if (index.row() % 2) { - QUrl url = urlString; - QString s = url.toString(QUrl::RemoveScheme - | QUrl::RemoveUserInfo - | QUrl::StripTrailingSlash); - return s.mid(2); // strip // from the front - } - return urlString; - } - return QAbstractProxyModel::data(index, role); -} - -int HistoryCompletionModel::rowCount(const QModelIndex &parent) const -{ - return (parent.isValid() || !sourceModel()) ? 0 : sourceModel()->rowCount(parent) * 2; -} - -int HistoryCompletionModel::columnCount(const QModelIndex &parent) const -{ - return (parent.isValid()) ? 0 : 1; -} - -QModelIndex HistoryCompletionModel::mapFromSource(const QModelIndex &sourceIndex) const -{ - int row = sourceIndex.row() * 2; - return index(row, sourceIndex.column()); -} - -QModelIndex HistoryCompletionModel::mapToSource(const QModelIndex &proxyIndex) const -{ - if (!sourceModel()) - return QModelIndex(); - int row = proxyIndex.row() / 2; - return sourceModel()->index(row, proxyIndex.column()); -} - -QModelIndex HistoryCompletionModel::index(int row, int column, const QModelIndex &parent) const -{ - if (row < 0 || row >= rowCount(parent) - || column < 0 || column >= columnCount(parent)) - return QModelIndex(); - return createIndex(row, column, 0); -} - -QModelIndex HistoryCompletionModel::parent(const QModelIndex &) const -{ - return QModelIndex(); -} - -void HistoryCompletionModel::setSourceModel(QAbstractItemModel *newSourceModel) -{ - if (sourceModel()) { - disconnect(sourceModel(), SIGNAL(modelReset()), this, SLOT(sourceReset())); - disconnect(sourceModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), - this, SLOT(sourceReset())); - disconnect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(sourceReset())); - } - - QAbstractProxyModel::setSourceModel(newSourceModel); - - if (newSourceModel) { - connect(newSourceModel, SIGNAL(modelReset()), this, SLOT(sourceReset())); - connect(sourceModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), - this, SLOT(sourceReset())); - connect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(sourceReset())); - } - - reset(); -} - -void HistoryCompletionModel::sourceReset() -{ - reset(); -} - -HistoryTreeModel::HistoryTreeModel(QAbstractItemModel *sourceModel, QObject *parent) - : QAbstractProxyModel(parent) -{ - setSourceModel(sourceModel); -} - -QVariant HistoryTreeModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - return sourceModel()->headerData(section, orientation, role); -} - -QVariant HistoryTreeModel::data(const QModelIndex &index, int role) const -{ - if ((role == Qt::EditRole || role == Qt::DisplayRole)) { - int start = index.internalId(); - if (start == 0) { - int offset = sourceDateRow(index.row()); - if (index.column() == 0) { - QModelIndex idx = sourceModel()->index(offset, 0); - QDate date = idx.data(HistoryModel::DateRole).toDate(); - if (date == QDate::currentDate()) - return tr("Earlier Today"); - return date.toString(QLatin1String("dddd, MMMM d, yyyy")); - } - if (index.column() == 1) { - return tr("%1 items").arg(rowCount(index.sibling(index.row(), 0))); - } - } - } - if (role == Qt::DecorationRole && index.column() == 0 && !index.parent().isValid()) - return QIcon(QLatin1String(":history.png")); - if (role == HistoryModel::DateRole && index.column() == 0 && index.internalId() == 0) { - int offset = sourceDateRow(index.row()); - QModelIndex idx = sourceModel()->index(offset, 0); - return idx.data(HistoryModel::DateRole); - } - - return QAbstractProxyModel::data(index, role); -} - -int HistoryTreeModel::columnCount(const QModelIndex &parent) const -{ - return sourceModel()->columnCount(mapToSource(parent)); -} - -int HistoryTreeModel::rowCount(const QModelIndex &parent) const -{ - if ( parent.internalId() != 0 - || parent.column() > 0 - || !sourceModel()) - return 0; - - // row count OF dates - if (!parent.isValid()) { - if (!m_sourceRowCache.isEmpty()) - return m_sourceRowCache.count(); - QDate currentDate; - int rows = 0; - int totalRows = sourceModel()->rowCount(); - - for (int i = 0; i < totalRows; ++i) { - QDate rowDate = sourceModel()->index(i, 0).data(HistoryModel::DateRole).toDate(); - if (rowDate != currentDate) { - m_sourceRowCache.append(i); - currentDate = rowDate; - ++rows; - } - } - Q_ASSERT(m_sourceRowCache.count() == rows); - return rows; - } - - // row count FOR a date - int start = sourceDateRow(parent.row()); - int end = sourceDateRow(parent.row() + 1); - return (end - start); -} - -// Translate the top level date row into the offset where that date starts -int HistoryTreeModel::sourceDateRow(int row) const -{ - if (row <= 0) - return 0; - - if (m_sourceRowCache.isEmpty()) - rowCount(QModelIndex()); - - if (row >= m_sourceRowCache.count()) { - if (!sourceModel()) - return 0; - return sourceModel()->rowCount(); - } - return m_sourceRowCache.at(row); -} - -QModelIndex HistoryTreeModel::mapToSource(const QModelIndex &proxyIndex) const -{ - int offset = proxyIndex.internalId(); - if (offset == 0) - return QModelIndex(); - int startDateRow = sourceDateRow(offset - 1); - return sourceModel()->index(startDateRow + proxyIndex.row(), proxyIndex.column()); -} - -QModelIndex HistoryTreeModel::index(int row, int column, const QModelIndex &parent) const -{ - if (row < 0 - || column < 0 || column >= columnCount(parent) - || parent.column() > 0) - return QModelIndex(); - - if (!parent.isValid()) - return createIndex(row, column, 0); - return createIndex(row, column, parent.row() + 1); -} - -QModelIndex HistoryTreeModel::parent(const QModelIndex &index) const -{ - int offset = index.internalId(); - if (offset == 0 || !index.isValid()) - return QModelIndex(); - return createIndex(offset - 1, 0, 0); -} - -bool HistoryTreeModel::hasChildren(const QModelIndex &parent) const -{ - QModelIndex grandparent = parent.parent(); - if (!grandparent.isValid()) - return true; - return false; -} - -Qt::ItemFlags HistoryTreeModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - return Qt::NoItemFlags; - return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled; -} - -bool HistoryTreeModel::removeRows(int row, int count, const QModelIndex &parent) -{ - if (row < 0 || count <= 0 || row + count > rowCount(parent)) - return false; - - if (parent.isValid()) { - // removing pages - int offset = sourceDateRow(parent.row()); - return sourceModel()->removeRows(offset + row, count); - } else { - // removing whole dates - for (int i = row + count - 1; i >= row; --i) { - QModelIndex dateParent = index(i, 0); - int offset = sourceDateRow(dateParent.row()); - if (!sourceModel()->removeRows(offset, rowCount(dateParent))) - return false; - } - } - return true; -} - -void HistoryTreeModel::setSourceModel(QAbstractItemModel *newSourceModel) -{ - if (sourceModel()) { - disconnect(sourceModel(), SIGNAL(modelReset()), this, SLOT(sourceReset())); - disconnect(sourceModel(), SIGNAL(layoutChanged()), this, SLOT(sourceReset())); - disconnect(sourceModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), - this, SLOT(sourceRowsInserted(const QModelIndex &, int, int))); - disconnect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(sourceRowsRemoved(const QModelIndex &, int, int))); - } - - QAbstractProxyModel::setSourceModel(newSourceModel); - - if (newSourceModel) { - connect(sourceModel(), SIGNAL(modelReset()), this, SLOT(sourceReset())); - connect(sourceModel(), SIGNAL(layoutChanged()), this, SLOT(sourceReset())); - connect(sourceModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), - this, SLOT(sourceRowsInserted(const QModelIndex &, int, int))); - connect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(sourceRowsRemoved(const QModelIndex &, int, int))); - } - - reset(); -} - -void HistoryTreeModel::sourceReset() -{ - m_sourceRowCache.clear(); - reset(); -} - -void HistoryTreeModel::sourceRowsInserted(const QModelIndex &parent, int start, int end) -{ - Q_UNUSED(parent); // Avoid warnings when compiling release - Q_ASSERT(!parent.isValid()); - if (start != 0 || start != end) { - m_sourceRowCache.clear(); - reset(); - return; - } - - m_sourceRowCache.clear(); - QModelIndex treeIndex = mapFromSource(sourceModel()->index(start, 0)); - QModelIndex treeParent = treeIndex.parent(); - if (rowCount(treeParent) == 1) { - beginInsertRows(QModelIndex(), 0, 0); - endInsertRows(); - } else { - beginInsertRows(treeParent, treeIndex.row(), treeIndex.row()); - endInsertRows(); - } -} - -QModelIndex HistoryTreeModel::mapFromSource(const QModelIndex &sourceIndex) const -{ - if (!sourceIndex.isValid()) - return QModelIndex(); - - if (m_sourceRowCache.isEmpty()) - rowCount(QModelIndex()); - - QList::iterator it; - it = qLowerBound(m_sourceRowCache.begin(), m_sourceRowCache.end(), sourceIndex.row()); - if (*it != sourceIndex.row()) - --it; - int dateRow = qMax(0, it - m_sourceRowCache.begin()); - int row = sourceIndex.row() - m_sourceRowCache.at(dateRow); - return createIndex(row, sourceIndex.column(), dateRow + 1); -} - -void HistoryTreeModel::sourceRowsRemoved(const QModelIndex &parent, int start, int end) -{ - Q_UNUSED(parent); // Avoid warnings when compiling release - Q_ASSERT(!parent.isValid()); - if (m_sourceRowCache.isEmpty()) - return; - for (int i = end; i >= start;) { - QList::iterator it; - it = qLowerBound(m_sourceRowCache.begin(), m_sourceRowCache.end(), i); - // playing it safe - if (it == m_sourceRowCache.end()) { - m_sourceRowCache.clear(); - reset(); - return; - } - - if (*it != i) - --it; - int row = qMax(0, it - m_sourceRowCache.begin()); - int offset = m_sourceRowCache[row]; - QModelIndex dateParent = index(row, 0); - // If we can remove all the rows in the date do that and skip over them - int rc = rowCount(dateParent); - if (i - rc + 1 == offset && start <= i - rc + 1) { - beginRemoveRows(QModelIndex(), row, row); - m_sourceRowCache.removeAt(row); - i -= rc + 1; - } else { - beginRemoveRows(dateParent, i - offset, i - offset); - ++row; - --i; - } - for (int j = row; j < m_sourceRowCache.count(); ++j) - --m_sourceRowCache[j]; - endRemoveRows(); - } -} - diff --git a/examples/gestures/browser/history.h b/examples/gestures/browser/history.h deleted file mode 100644 index 626e2f3..0000000 --- a/examples/gestures/browser/history.h +++ /dev/null @@ -1,350 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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$ -** -****************************************************************************/ - -#ifndef HISTORY_H -#define HISTORY_H - -#include "modelmenu.h" - -#include -#include -#include -#include -#include - -#include - -#include - -class HistoryItem -{ -public: - HistoryItem() {} - HistoryItem(const QString &u, - const QDateTime &d = QDateTime(), const QString &t = QString()) - : title(t), url(u), dateTime(d) {} - - inline bool operator==(const HistoryItem &other) const - { return other.title == title - && other.url == url && other.dateTime == dateTime; } - - // history is sorted in reverse - inline bool operator <(const HistoryItem &other) const - { return dateTime > other.dateTime; } - - QString title; - QString url; - QDateTime dateTime; -}; - -class AutoSaver; -class HistoryModel; -class HistoryFilterModel; -class HistoryTreeModel; -class HistoryManager : public QWebHistoryInterface -{ - Q_OBJECT - Q_PROPERTY(int historyLimit READ historyLimit WRITE setHistoryLimit) - -signals: - void historyReset(); - void entryAdded(const HistoryItem &item); - void entryRemoved(const HistoryItem &item); - void entryUpdated(int offset); - -public: - HistoryManager(QObject *parent = 0); - ~HistoryManager(); - - bool historyContains(const QString &url) const; - void addHistoryEntry(const QString &url); - - void updateHistoryItem(const QUrl &url, const QString &title); - - int historyLimit() const; - void setHistoryLimit(int limit); - - QList history() const; - void setHistory(const QList &history, bool loadedAndSorted = false); - - // History manager keeps around these models for use by the completer and other classes - HistoryModel *historyModel() const; - HistoryFilterModel *historyFilterModel() const; - HistoryTreeModel *historyTreeModel() const; - -public slots: - void clear(); - void loadSettings(); - -private slots: - void save(); - void checkForExpired(); - -protected: - void addHistoryItem(const HistoryItem &item); - -private: - void load(); - - AutoSaver *m_saveTimer; - int m_historyLimit; - QTimer m_expiredTimer; - QList m_history; - QString m_lastSavedUrl; - - HistoryModel *m_historyModel; - HistoryFilterModel *m_historyFilterModel; - HistoryTreeModel *m_historyTreeModel; -}; - -class HistoryModel : public QAbstractTableModel -{ - Q_OBJECT - -public slots: - void historyReset(); - void entryAdded(); - void entryUpdated(int offset); - -public: - enum Roles { - DateRole = Qt::UserRole + 1, - DateTimeRole = Qt::UserRole + 2, - UrlRole = Qt::UserRole + 3, - UrlStringRole = Qt::UserRole + 4 - }; - - HistoryModel(HistoryManager *history, QObject *parent = 0); - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); - -private: - HistoryManager *m_history; -}; - -/*! - Proxy model that will remove any duplicate entries. - Both m_sourceRow and m_historyHash store their offsets not from - the front of the list, but as offsets from the back. - */ -class HistoryFilterModel : public QAbstractProxyModel -{ - Q_OBJECT - -public: - HistoryFilterModel(QAbstractItemModel *sourceModel, QObject *parent = 0); - - inline bool historyContains(const QString &url) const - { load(); return m_historyHash.contains(url); } - int historyLocation(const QString &url) const; - - QModelIndex mapFromSource(const QModelIndex &sourceIndex) const; - QModelIndex mapToSource(const QModelIndex &proxyIndex) const; - void setSourceModel(QAbstractItemModel *sourceModel); - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QModelIndex index(int, int, const QModelIndex& = QModelIndex()) const; - QModelIndex parent(const QModelIndex& index= QModelIndex()) const; - bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - -private slots: - void sourceReset(); - void sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); - void sourceRowsInserted(const QModelIndex &parent, int start, int end); - void sourceRowsRemoved(const QModelIndex &, int, int); - -private: - void load() const; - - mutable QList m_sourceRow; - mutable QHash m_historyHash; - mutable bool m_loaded; -}; - -/* - The history menu - - Removes the first twenty entries and puts them as children of the top level. - - If there are less then twenty entries then the first folder is also removed. - - The mapping is done by knowing that HistoryTreeModel is over a table - We store that row offset in our index's private data. -*/ -class HistoryMenuModel : public QAbstractProxyModel -{ - Q_OBJECT - -public: - HistoryMenuModel(HistoryTreeModel *sourceModel, QObject *parent = 0); - int columnCount(const QModelIndex &parent) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - QModelIndex mapFromSource(const QModelIndex & sourceIndex) const; - QModelIndex mapToSource(const QModelIndex & proxyIndex) const; - QModelIndex index(int, int, const QModelIndex &parent = QModelIndex()) const; - QModelIndex parent(const QModelIndex &index = QModelIndex()) const; - - int bumpedRows() const; - -private: - HistoryTreeModel *m_treeModel; -}; - -// Menu that is dynamically populated from the history -class HistoryMenu : public ModelMenu -{ - Q_OBJECT - -signals: - void openUrl(const QUrl &url); - -public: - HistoryMenu(QWidget *parent = 0); - void setInitialActions(QList actions); - -protected: - bool prePopulated(); - void postPopulated(); - -private slots: - void activated(const QModelIndex &index); - void showHistoryDialog(); - -private: - HistoryManager *m_history; - HistoryMenuModel *m_historyMenuModel; - QList m_initialActions; -}; - -// proxy model for the history model that -// exposes each url http://www.foo.com and it url starting at the host www.foo.com -class HistoryCompletionModel : public QAbstractProxyModel -{ - Q_OBJECT - -public: - HistoryCompletionModel(QObject *parent = 0); - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QModelIndex mapFromSource(const QModelIndex &sourceIndex) const; - QModelIndex mapToSource(const QModelIndex &proxyIndex) const; - QModelIndex index(int, int, const QModelIndex& = QModelIndex()) const; - QModelIndex parent(const QModelIndex& index= QModelIndex()) const; - void setSourceModel(QAbstractItemModel *sourceModel); - -private slots: - void sourceReset(); - -}; - -// proxy model for the history model that converts the list -// into a tree, one top level node per day. -// Used in the HistoryDialog. -class HistoryTreeModel : public QAbstractProxyModel -{ - Q_OBJECT - -public: - HistoryTreeModel(QAbstractItemModel *sourceModel, QObject *parent = 0); - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - int columnCount(const QModelIndex &parent) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - QModelIndex mapFromSource(const QModelIndex &sourceIndex) const; - QModelIndex mapToSource(const QModelIndex &proxyIndex) const; - QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; - QModelIndex parent(const QModelIndex &index= QModelIndex()) const; - bool hasChildren(const QModelIndex &parent = QModelIndex()) const; - Qt::ItemFlags flags(const QModelIndex &index) const; - bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - - void setSourceModel(QAbstractItemModel *sourceModel); - -private slots: - void sourceReset(); - void sourceRowsInserted(const QModelIndex &parent, int start, int end); - void sourceRowsRemoved(const QModelIndex &parent, int start, int end); - -private: - int sourceDateRow(int row) const; - mutable QList m_sourceRowCache; - -}; - -// A modified QSortFilterProxyModel that always accepts the root nodes in the tree -// so filtering is only done on the children. -// Used in the HistoryDialog -class TreeProxyModel : public QSortFilterProxyModel -{ - Q_OBJECT - -public: - TreeProxyModel(QObject *parent = 0); - -protected: - bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; -}; - -#include "ui_history.h" - -class HistoryDialog : public QDialog, public Ui_HistoryDialog -{ - Q_OBJECT - -signals: - void openUrl(const QUrl &url); - -public: - HistoryDialog(QWidget *parent = 0, HistoryManager *history = 0); - -private slots: - void customContextMenuRequested(const QPoint &pos); - void open(); - void copy(); - -}; - -#endif // HISTORY_H - diff --git a/examples/gestures/browser/history.ui b/examples/gestures/browser/history.ui deleted file mode 100644 index 0944940..0000000 --- a/examples/gestures/browser/history.ui +++ /dev/null @@ -1,106 +0,0 @@ - - HistoryDialog - - - - 0 - 0 - 758 - 450 - - - - History - - - - - - Qt::Horizontal - - - - 252 - 20 - - - - - - - - - - - - - - - - &Remove - - - - - - - Remove &All - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - QDialogButtonBox::Ok - - - - - - - - - - SearchLineEdit - QLineEdit -
searchlineedit.h
-
- - EditTreeView - QTreeView -
edittreeview.h
-
-
- - - - buttonBox - accepted() - HistoryDialog - accept() - - - 472 - 329 - - - 461 - 356 - - - - -
diff --git a/examples/gestures/browser/htmls/htmls.qrc b/examples/gestures/browser/htmls/htmls.qrc deleted file mode 100644 index 03b256c..0000000 --- a/examples/gestures/browser/htmls/htmls.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - notfound.html - - diff --git a/examples/gestures/browser/htmls/notfound.html b/examples/gestures/browser/htmls/notfound.html deleted file mode 100644 index b04a9f8..0000000 --- a/examples/gestures/browser/htmls/notfound.html +++ /dev/null @@ -1,63 +0,0 @@ - - -%1 - - - -
- -

%2

-

When connecting to: %3.

-
    -
  • Check the address for errors such as ww.trolltech.com - instead of www.trolltech.com
  • -
  • If the address is correct, try checking the network - connection.
  • -
  • If your computer or network is protected by a firewall or - proxy, make sure that the browser demo is permitted to access - the network.
  • -
-

-
- - diff --git a/examples/gestures/browser/main.cpp b/examples/gestures/browser/main.cpp deleted file mode 100644 index b9e2830..0000000 --- a/examples/gestures/browser/main.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 "browserapplication.h" - -int main(int argc, char **argv) -{ - Q_INIT_RESOURCE(data); - BrowserApplication application(argc, argv); - if (!application.isTheOnlyBrowser()) - return 0; - application.newMainWindow(); - return application.exec(); -} - diff --git a/examples/gestures/browser/modelmenu.cpp b/examples/gestures/browser/modelmenu.cpp deleted file mode 100644 index 2e81d0d..0000000 --- a/examples/gestures/browser/modelmenu.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 "modelmenu.h" - -#include -#include - -ModelMenu::ModelMenu(QWidget * parent) - : QMenu(parent) - , m_maxRows(7) - , m_firstSeparator(-1) - , m_maxWidth(-1) - , m_hoverRole(0) - , m_separatorRole(0) - , m_model(0) -{ - connect(this, SIGNAL(aboutToShow()), this, SLOT(aboutToShow())); -} - -bool ModelMenu::prePopulated() -{ - return false; -} - -void ModelMenu::postPopulated() -{ -} - -void ModelMenu::setModel(QAbstractItemModel *model) -{ - m_model = model; -} - -QAbstractItemModel *ModelMenu::model() const -{ - return m_model; -} - -void ModelMenu::setMaxRows(int max) -{ - m_maxRows = max; -} - -int ModelMenu::maxRows() const -{ - return m_maxRows; -} - -void ModelMenu::setFirstSeparator(int offset) -{ - m_firstSeparator = offset; -} - -int ModelMenu::firstSeparator() const -{ - return m_firstSeparator; -} - -void ModelMenu::setRootIndex(const QModelIndex &index) -{ - m_root = index; -} - -QModelIndex ModelMenu::rootIndex() const -{ - return m_root; -} - -void ModelMenu::setHoverRole(int role) -{ - m_hoverRole = role; -} - -int ModelMenu::hoverRole() const -{ - return m_hoverRole; -} - -void ModelMenu::setSeparatorRole(int role) -{ - m_separatorRole = role; -} - -int ModelMenu::separatorRole() const -{ - return m_separatorRole; -} - -Q_DECLARE_METATYPE(QModelIndex) -void ModelMenu::aboutToShow() -{ - if (QMenu *menu = qobject_cast(sender())) { - QVariant v = menu->menuAction()->data(); - if (v.canConvert()) { - QModelIndex idx = qvariant_cast(v); - createMenu(idx, -1, menu, menu); - disconnect(menu, SIGNAL(aboutToShow()), this, SLOT(aboutToShow())); - return; - } - } - - clear(); - if (prePopulated()) - addSeparator(); - int max = m_maxRows; - if (max != -1) - max += m_firstSeparator; - createMenu(m_root, max, this, this); - postPopulated(); -} - -void ModelMenu::createMenu(const QModelIndex &parent, int max, QMenu *parentMenu, QMenu *menu) -{ - if (!menu) { - QString title = parent.data().toString(); - menu = new QMenu(title, this); - QIcon icon = qvariant_cast(parent.data(Qt::DecorationRole)); - menu->setIcon(icon); - parentMenu->addMenu(menu); - QVariant v; - v.setValue(parent); - menu->menuAction()->setData(v); - connect(menu, SIGNAL(aboutToShow()), this, SLOT(aboutToShow())); - return; - } - - int end = m_model->rowCount(parent); - if (max != -1) - end = qMin(max, end); - - connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(triggered(QAction*))); - connect(menu, SIGNAL(hovered(QAction*)), this, SLOT(hovered(QAction*))); - - for (int i = 0; i < end; ++i) { - QModelIndex idx = m_model->index(i, 0, parent); - if (m_model->hasChildren(idx)) { - createMenu(idx, -1, menu); - } else { - if (m_separatorRole != 0 - && idx.data(m_separatorRole).toBool()) - addSeparator(); - else - menu->addAction(makeAction(idx)); - } - if (menu == this && i == m_firstSeparator - 1) - addSeparator(); - } -} - -QAction *ModelMenu::makeAction(const QModelIndex &index) -{ - QIcon icon = qvariant_cast(index.data(Qt::DecorationRole)); - QAction *action = makeAction(icon, index.data().toString(), this); - QVariant v; - v.setValue(index); - action->setData(v); - return action; -} - -QAction *ModelMenu::makeAction(const QIcon &icon, const QString &text, QObject *parent) -{ - QFontMetrics fm(font()); - if (-1 == m_maxWidth) - m_maxWidth = fm.width(QLatin1Char('m')) * 30; - QString smallText = fm.elidedText(text, Qt::ElideMiddle, m_maxWidth); - return new QAction(icon, smallText, parent); -} - -void ModelMenu::triggered(QAction *action) -{ - QVariant v = action->data(); - if (v.canConvert()) { - QModelIndex idx = qvariant_cast(v); - emit activated(idx); - } -} - -void ModelMenu::hovered(QAction *action) -{ - QVariant v = action->data(); - if (v.canConvert()) { - QModelIndex idx = qvariant_cast(v); - QString hoveredString = idx.data(m_hoverRole).toString(); - if (!hoveredString.isEmpty()) - emit hovered(hoveredString); - } -} - diff --git a/examples/gestures/browser/modelmenu.h b/examples/gestures/browser/modelmenu.h deleted file mode 100644 index b44daa8..0000000 --- a/examples/gestures/browser/modelmenu.h +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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$ -** -****************************************************************************/ - -#ifndef MODELMENU_H -#define MODELMENU_H - -#include -#include - -// A QMenu that is dynamically populated from a QAbstractItemModel -class ModelMenu : public QMenu -{ - Q_OBJECT - -signals: - void activated(const QModelIndex &index); - void hovered(const QString &text); - -public: - ModelMenu(QWidget *parent = 0); - - void setModel(QAbstractItemModel *model); - QAbstractItemModel *model() const; - - void setMaxRows(int max); - int maxRows() const; - - void setFirstSeparator(int offset); - int firstSeparator() const; - - void setRootIndex(const QModelIndex &index); - QModelIndex rootIndex() const; - - void setHoverRole(int role); - int hoverRole() const; - - void setSeparatorRole(int role); - int separatorRole() const; - - QAction *makeAction(const QIcon &icon, const QString &text, QObject *parent); - -protected: - // add any actions before the tree, return true if any actions are added. - virtual bool prePopulated(); - // add any actions after the tree - virtual void postPopulated(); - // put all of the children of parent into menu up to max - void createMenu(const QModelIndex &parent, int max, QMenu *parentMenu = 0, QMenu *menu = 0); - -private slots: - void aboutToShow(); - void triggered(QAction *action); - void hovered(QAction *action); - -private: - QAction *makeAction(const QModelIndex &index); - int m_maxRows; - int m_firstSeparator; - int m_maxWidth; - int m_hoverRole; - int m_separatorRole; - QAbstractItemModel *m_model; - QPersistentModelIndex m_root; -}; - -#endif // MODELMENU_H - diff --git a/examples/gestures/browser/networkaccessmanager.cpp b/examples/gestures/browser/networkaccessmanager.cpp deleted file mode 100644 index 3a4598c..0000000 --- a/examples/gestures/browser/networkaccessmanager.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 "networkaccessmanager.h" - -#include "browserapplication.h" -#include "browsermainwindow.h" -#include "ui_passworddialog.h" -#include "ui_proxy.h" - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -NetworkAccessManager::NetworkAccessManager(QObject *parent) - : QNetworkAccessManager(parent) -{ - connect(this, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)), - SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); - connect(this, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)), - SLOT(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*))); -#ifndef QT_NO_OPENSSL - connect(this, SIGNAL(sslErrors(QNetworkReply*, const QList&)), - SLOT(sslErrors(QNetworkReply*, const QList&))); -#endif - loadSettings(); - - QNetworkDiskCache *diskCache = new QNetworkDiskCache(this); - QString location = QDesktopServices::storageLocation(QDesktopServices::CacheLocation); - diskCache->setCacheDirectory(location); - setCache(diskCache); -} - -void NetworkAccessManager::loadSettings() -{ - QSettings settings; - settings.beginGroup(QLatin1String("proxy")); - QNetworkProxy proxy; - if (settings.value(QLatin1String("enabled"), false).toBool()) { - if (settings.value(QLatin1String("type"), 0).toInt() == 0) - proxy = QNetworkProxy::Socks5Proxy; - else - proxy = QNetworkProxy::HttpProxy; - proxy.setHostName(settings.value(QLatin1String("hostName")).toString()); - proxy.setPort(settings.value(QLatin1String("port"), 1080).toInt()); - proxy.setUser(settings.value(QLatin1String("userName")).toString()); - proxy.setPassword(settings.value(QLatin1String("password")).toString()); - } - setProxy(proxy); -} - -void NetworkAccessManager::authenticationRequired(QNetworkReply *reply, QAuthenticator *auth) -{ - BrowserMainWindow *mainWindow = BrowserApplication::instance()->mainWindow(); - - QDialog dialog(mainWindow); - dialog.setWindowFlags(Qt::Sheet); - - Ui::PasswordDialog passwordDialog; - passwordDialog.setupUi(&dialog); - - passwordDialog.iconLabel->setText(QString()); - passwordDialog.iconLabel->setPixmap(mainWindow->style()->standardIcon(QStyle::SP_MessageBoxQuestion, 0, mainWindow).pixmap(32, 32)); - - QString introMessage = tr("Enter username and password for \"%1\" at %2"); - introMessage = introMessage.arg(Qt::escape(reply->url().toString())).arg(Qt::escape(reply->url().toString())); - passwordDialog.introLabel->setText(introMessage); - passwordDialog.introLabel->setWordWrap(true); - - if (dialog.exec() == QDialog::Accepted) { - auth->setUser(passwordDialog.userNameLineEdit->text()); - auth->setPassword(passwordDialog.passwordLineEdit->text()); - } -} - -void NetworkAccessManager::proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth) -{ - BrowserMainWindow *mainWindow = BrowserApplication::instance()->mainWindow(); - - QDialog dialog(mainWindow); - dialog.setWindowFlags(Qt::Sheet); - - Ui::ProxyDialog proxyDialog; - proxyDialog.setupUi(&dialog); - - proxyDialog.iconLabel->setText(QString()); - proxyDialog.iconLabel->setPixmap(mainWindow->style()->standardIcon(QStyle::SP_MessageBoxQuestion, 0, mainWindow).pixmap(32, 32)); - - QString introMessage = tr("Connect to proxy \"%1\" using:"); - introMessage = introMessage.arg(Qt::escape(proxy.hostName())); - proxyDialog.introLabel->setText(introMessage); - proxyDialog.introLabel->setWordWrap(true); - - if (dialog.exec() == QDialog::Accepted) { - auth->setUser(proxyDialog.userNameLineEdit->text()); - auth->setPassword(proxyDialog.passwordLineEdit->text()); - } -} - -#ifndef QT_NO_OPENSSL -void NetworkAccessManager::sslErrors(QNetworkReply *reply, const QList &error) -{ - // check if SSL certificate has been trusted already - QString replyHost = reply->url().host() + ":" + reply->url().port(); - if(! sslTrustedHostList.contains(replyHost)) { - BrowserMainWindow *mainWindow = BrowserApplication::instance()->mainWindow(); - - QStringList errorStrings; - for (int i = 0; i < error.count(); ++i) - errorStrings += error.at(i).errorString(); - QString errors = errorStrings.join(QLatin1String("\n")); - int ret = QMessageBox::warning(mainWindow, QCoreApplication::applicationName(), - tr("SSL Errors:\n\n%1\n\n%2\n\n" - "Do you want to ignore these errors for this host?").arg(reply->url().toString()).arg(errors), - QMessageBox::Yes | QMessageBox::No, - QMessageBox::No); - if (ret == QMessageBox::Yes) { - reply->ignoreSslErrors(); - sslTrustedHostList.append(replyHost); - } - } -} -#endif diff --git a/examples/gestures/browser/networkaccessmanager.h b/examples/gestures/browser/networkaccessmanager.h deleted file mode 100644 index d90a4d4..0000000 --- a/examples/gestures/browser/networkaccessmanager.h +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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$ -** -****************************************************************************/ - -#ifndef NETWORKACCESSMANAGER_H -#define NETWORKACCESSMANAGER_H - -#include - -class NetworkAccessManager : public QNetworkAccessManager -{ - Q_OBJECT - -public: - NetworkAccessManager(QObject *parent = 0); - -private: - QList sslTrustedHostList; - -public slots: - void loadSettings(); - -private slots: - void authenticationRequired(QNetworkReply *reply, QAuthenticator *auth); - void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth); -#ifndef QT_NO_OPENSSL - void sslErrors(QNetworkReply *reply, const QList &error); -#endif -}; - -#endif // NETWORKACCESSMANAGER_H diff --git a/examples/gestures/browser/passworddialog.ui b/examples/gestures/browser/passworddialog.ui deleted file mode 100644 index 7c16658..0000000 --- a/examples/gestures/browser/passworddialog.ui +++ /dev/null @@ -1,111 +0,0 @@ - - PasswordDialog - - - - 0 - 0 - 399 - 148 - - - - Authentication Required - - - - - - - - DUMMY ICON - - - - - - - - 0 - 0 - - - - INTRO TEXT DUMMY - - - - - - - - - Username: - - - - - - - - - - Password: - - - - - - - QLineEdit::Password - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - PasswordDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - PasswordDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/examples/gestures/browser/proxy.ui b/examples/gestures/browser/proxy.ui deleted file mode 100644 index 62a8be6..0000000 --- a/examples/gestures/browser/proxy.ui +++ /dev/null @@ -1,104 +0,0 @@ - - ProxyDialog - - - - 0 - 0 - 369 - 144 - - - - Proxy Authentication - - - - - - ICON - - - - - - - Connect to proxy - - - true - - - - - - - Username: - - - - - - - - - - Password: - - - - - - - QLineEdit::Password - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - ProxyDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - ProxyDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/examples/gestures/browser/searchlineedit.cpp b/examples/gestures/browser/searchlineedit.cpp deleted file mode 100644 index e04010d..0000000 --- a/examples/gestures/browser/searchlineedit.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 "searchlineedit.h" - -#include -#include -#include -#include -#include - -ClearButton::ClearButton(QWidget *parent) - : QAbstractButton(parent) -{ - setCursor(Qt::ArrowCursor); - setToolTip(tr("Clear")); - setVisible(false); - setFocusPolicy(Qt::NoFocus); -} - -void ClearButton::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - QPainter painter(this); - int height = this->height(); - - painter.setRenderHint(QPainter::Antialiasing, true); - QColor color = palette().color(QPalette::Mid); - painter.setBrush(isDown() - ? palette().color(QPalette::Dark) - : palette().color(QPalette::Mid)); - painter.setPen(painter.brush().color()); - int size = width(); - int offset = size / 5; - int radius = size - offset * 2; - painter.drawEllipse(offset, offset, radius, radius); - - painter.setPen(palette().color(QPalette::Base)); - int border = offset * 2; - painter.drawLine(border, border, width() - border, height - border); - painter.drawLine(border, height - border, width() - border, border); -} - -void ClearButton::textChanged(const QString &text) -{ - setVisible(!text.isEmpty()); -} - -/* - Search icon on the left hand side of the search widget - When a menu is set a down arrow appears - */ -class SearchButton : public QAbstractButton { -public: - SearchButton(QWidget *parent = 0); - void paintEvent(QPaintEvent *event); - QMenu *m_menu; - -protected: - void mousePressEvent(QMouseEvent *event); -}; - -SearchButton::SearchButton(QWidget *parent) - : QAbstractButton(parent), - m_menu(0) -{ - setObjectName(QLatin1String("SearchButton")); - setCursor(Qt::ArrowCursor); - setFocusPolicy(Qt::NoFocus); -} - -void SearchButton::mousePressEvent(QMouseEvent *event) -{ - if (m_menu && event->button() == Qt::LeftButton) { - QWidget *p = parentWidget(); - if (p) { - QPoint r = p->mapToGlobal(QPoint(0, p->height())); - m_menu->exec(QPoint(r.x() + height() / 2, r.y())); - } - event->accept(); - } - QAbstractButton::mousePressEvent(event); -} - -void SearchButton::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - QPainterPath myPath; - - int radius = (height() / 5) * 2; - QRect circle(height() / 3 - 1, height() / 4, radius, radius); - myPath.addEllipse(circle); - - myPath.arcMoveTo(circle, 300); - QPointF c = myPath.currentPosition(); - int diff = height() / 7; - myPath.lineTo(qMin(width() - 2, (int)c.x() + diff), c.y() + diff); - - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing, true); - painter.setPen(QPen(Qt::darkGray, 2)); - painter.drawPath(myPath); - - if (m_menu) { - QPainterPath dropPath; - dropPath.arcMoveTo(circle, 320); - QPointF c = dropPath.currentPosition(); - c = QPointF(c.x() + 3.5, c.y() + 0.5); - dropPath.moveTo(c); - dropPath.lineTo(c.x() + 4, c.y()); - dropPath.lineTo(c.x() + 2, c.y() + 2); - dropPath.closeSubpath(); - painter.setPen(Qt::darkGray); - painter.setBrush(Qt::darkGray); - painter.setRenderHint(QPainter::Antialiasing, false); - painter.drawPath(dropPath); - } - painter.end(); -} - -/* - SearchLineEdit is an enhanced QLineEdit - - A Search icon on the left with optional menu - - When there is no text and doesn't have focus an "inactive text" is displayed - - When there is text a clear button is displayed on the right hand side - */ -SearchLineEdit::SearchLineEdit(QWidget *parent) : ExLineEdit(parent), - m_searchButton(new SearchButton(this)) -{ - connect(lineEdit(), SIGNAL(textChanged(const QString &)), - this, SIGNAL(textChanged(const QString &))); - setLeftWidget(m_searchButton); - m_inactiveText = tr("Search"); - - QSizePolicy policy = sizePolicy(); - setSizePolicy(QSizePolicy::Preferred, policy.verticalPolicy()); -} - -void SearchLineEdit::paintEvent(QPaintEvent *event) -{ - if (lineEdit()->text().isEmpty() && !hasFocus() && !m_inactiveText.isEmpty()) { - ExLineEdit::paintEvent(event); - QStyleOptionFrameV2 panel; - initStyleOption(&panel); - QRect r = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this); - QFontMetrics fm = fontMetrics(); - int horizontalMargin = lineEdit()->x(); - QRect lineRect(horizontalMargin + r.x(), r.y() + (r.height() - fm.height() + 1) / 2, - r.width() - 2 * horizontalMargin, fm.height()); - QPainter painter(this); - painter.setPen(palette().brush(QPalette::Disabled, QPalette::Text).color()); - painter.drawText(lineRect, Qt::AlignLeft|Qt::AlignVCenter, m_inactiveText); - } else { - ExLineEdit::paintEvent(event); - } -} - -void SearchLineEdit::resizeEvent(QResizeEvent *event) -{ - updateGeometries(); - ExLineEdit::resizeEvent(event); -} - -void SearchLineEdit::updateGeometries() -{ - int menuHeight = height(); - int menuWidth = menuHeight + 1; - if (!m_searchButton->m_menu) - menuWidth = (menuHeight / 5) * 4; - m_searchButton->resize(QSize(menuWidth, menuHeight)); -} - -QString SearchLineEdit::inactiveText() const -{ - return m_inactiveText; -} - -void SearchLineEdit::setInactiveText(const QString &text) -{ - m_inactiveText = text; -} - -void SearchLineEdit::setMenu(QMenu *menu) -{ - if (m_searchButton->m_menu) - m_searchButton->m_menu->deleteLater(); - m_searchButton->m_menu = menu; - updateGeometries(); -} - -QMenu *SearchLineEdit::menu() const -{ - if (!m_searchButton->m_menu) { - m_searchButton->m_menu = new QMenu(m_searchButton); - if (isVisible()) - (const_cast(this))->updateGeometries(); - } - return m_searchButton->m_menu; -} - diff --git a/examples/gestures/browser/searchlineedit.h b/examples/gestures/browser/searchlineedit.h deleted file mode 100644 index ad37dc7..0000000 --- a/examples/gestures/browser/searchlineedit.h +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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$ -** -****************************************************************************/ - -#ifndef SEARCHLINEEDIT_H -#define SEARCHLINEEDIT_H - -#include "urllineedit.h" - -#include -#include - -QT_BEGIN_NAMESPACE -class QMenu; -QT_END_NAMESPACE - -class SearchButton; - -/* - Clear button on the right hand side of the search widget. - Hidden by default - "A circle with an X in it" - */ -class ClearButton : public QAbstractButton -{ - Q_OBJECT - -public: - ClearButton(QWidget *parent = 0); - void paintEvent(QPaintEvent *event); - -public slots: - void textChanged(const QString &text); -}; - - -class SearchLineEdit : public ExLineEdit -{ - Q_OBJECT - Q_PROPERTY(QString inactiveText READ inactiveText WRITE setInactiveText) - -signals: - void textChanged(const QString &text); - -public: - SearchLineEdit(QWidget *parent = 0); - - QString inactiveText() const; - void setInactiveText(const QString &text); - - QMenu *menu() const; - void setMenu(QMenu *menu); - -protected: - void resizeEvent(QResizeEvent *event); - void paintEvent(QPaintEvent *event); - -private: - void updateGeometries(); - - SearchButton *m_searchButton; - QString m_inactiveText; -}; - -#endif // SEARCHLINEEDIT_H - diff --git a/examples/gestures/browser/settings.cpp b/examples/gestures/browser/settings.cpp deleted file mode 100644 index 2576449..0000000 --- a/examples/gestures/browser/settings.cpp +++ /dev/null @@ -1,324 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 "settings.h" - -#include "browserapplication.h" -#include "browsermainwindow.h" -#include "cookiejar.h" -#include "history.h" -#include "networkaccessmanager.h" -#include "webview.h" - -#include -#include -#include - -SettingsDialog::SettingsDialog(QWidget *parent) - : QDialog(parent) -{ - setupUi(this); - connect(exceptionsButton, SIGNAL(clicked()), this, SLOT(showExceptions())); - connect(setHomeToCurrentPageButton, SIGNAL(clicked()), this, SLOT(setHomeToCurrentPage())); - connect(cookiesButton, SIGNAL(clicked()), this, SLOT(showCookies())); - connect(standardFontButton, SIGNAL(clicked()), this, SLOT(chooseFont())); - connect(fixedFontButton, SIGNAL(clicked()), this, SLOT(chooseFixedFont())); - - loadDefaults(); - loadFromSettings(); -} - -void SettingsDialog::loadDefaults() -{ - QWebSettings *defaultSettings = QWebSettings::globalSettings(); - QString standardFontFamily = defaultSettings->fontFamily(QWebSettings::StandardFont); - int standardFontSize = defaultSettings->fontSize(QWebSettings::DefaultFontSize); - standardFont = QFont(standardFontFamily, standardFontSize); - standardLabel->setText(QString(QLatin1String("%1 %2")).arg(standardFont.family()).arg(standardFont.pointSize())); - - QString fixedFontFamily = defaultSettings->fontFamily(QWebSettings::FixedFont); - int fixedFontSize = defaultSettings->fontSize(QWebSettings::DefaultFixedFontSize); - fixedFont = QFont(fixedFontFamily, fixedFontSize); - fixedLabel->setText(QString(QLatin1String("%1 %2")).arg(fixedFont.family()).arg(fixedFont.pointSize())); - - downloadsLocation->setText(QDesktopServices::storageLocation(QDesktopServices::DesktopLocation)); - - enableJavascript->setChecked(defaultSettings->testAttribute(QWebSettings::JavascriptEnabled)); - enablePlugins->setChecked(defaultSettings->testAttribute(QWebSettings::PluginsEnabled)); -} - -void SettingsDialog::loadFromSettings() -{ - QSettings settings; - settings.beginGroup(QLatin1String("MainWindow")); - QString defaultHome = QLatin1String("http://qtsoftware.com"); - homeLineEdit->setText(settings.value(QLatin1String("home"), defaultHome).toString()); - settings.endGroup(); - - settings.beginGroup(QLatin1String("history")); - int historyExpire = settings.value(QLatin1String("historyExpire")).toInt(); - int idx = 0; - switch (historyExpire) { - case 1: idx = 0; break; - case 7: idx = 1; break; - case 14: idx = 2; break; - case 30: idx = 3; break; - case 365: idx = 4; break; - case -1: idx = 5; break; - default: - idx = 5; - } - expireHistory->setCurrentIndex(idx); - settings.endGroup(); - - settings.beginGroup(QLatin1String("downloadmanager")); - QString downloadDirectory = settings.value(QLatin1String("downloadDirectory"), downloadsLocation->text()).toString(); - downloadsLocation->setText(downloadDirectory); - settings.endGroup(); - - settings.beginGroup(QLatin1String("general")); - openLinksIn->setCurrentIndex(settings.value(QLatin1String("openLinksIn"), openLinksIn->currentIndex()).toInt()); - - settings.endGroup(); - - // Appearance - settings.beginGroup(QLatin1String("websettings")); - fixedFont = qVariantValue(settings.value(QLatin1String("fixedFont"), fixedFont)); - standardFont = qVariantValue(settings.value(QLatin1String("standardFont"), standardFont)); - - standardLabel->setText(QString(QLatin1String("%1 %2")).arg(standardFont.family()).arg(standardFont.pointSize())); - fixedLabel->setText(QString(QLatin1String("%1 %2")).arg(fixedFont.family()).arg(fixedFont.pointSize())); - - enableJavascript->setChecked(settings.value(QLatin1String("enableJavascript"), enableJavascript->isChecked()).toBool()); - enablePlugins->setChecked(settings.value(QLatin1String("enablePlugins"), enablePlugins->isChecked()).toBool()); - userStyleSheet->setText(settings.value(QLatin1String("userStyleSheet")).toUrl().toString()); - settings.endGroup(); - - // Privacy - settings.beginGroup(QLatin1String("cookies")); - - CookieJar *jar = BrowserApplication::cookieJar(); - QByteArray value = settings.value(QLatin1String("acceptCookies"), QLatin1String("AcceptOnlyFromSitesNavigatedTo")).toByteArray(); - QMetaEnum acceptPolicyEnum = jar->staticMetaObject.enumerator(jar->staticMetaObject.indexOfEnumerator("AcceptPolicy")); - CookieJar::AcceptPolicy acceptCookies = acceptPolicyEnum.keyToValue(value) == -1 ? - CookieJar::AcceptOnlyFromSitesNavigatedTo : - static_cast(acceptPolicyEnum.keyToValue(value)); - switch(acceptCookies) { - case CookieJar::AcceptAlways: - acceptCombo->setCurrentIndex(0); - break; - case CookieJar::AcceptNever: - acceptCombo->setCurrentIndex(1); - break; - case CookieJar::AcceptOnlyFromSitesNavigatedTo: - acceptCombo->setCurrentIndex(2); - break; - } - - value = settings.value(QLatin1String("keepCookiesUntil"), QLatin1String("Expire")).toByteArray(); - QMetaEnum keepPolicyEnum = jar->staticMetaObject.enumerator(jar->staticMetaObject.indexOfEnumerator("KeepPolicy")); - CookieJar::KeepPolicy keepCookies = keepPolicyEnum.keyToValue(value) == -1 ? - CookieJar::KeepUntilExpire : - static_cast(keepPolicyEnum.keyToValue(value)); - switch(keepCookies) { - case CookieJar::KeepUntilExpire: - keepUntilCombo->setCurrentIndex(0); - break; - case CookieJar::KeepUntilExit: - keepUntilCombo->setCurrentIndex(1); - break; - case CookieJar::KeepUntilTimeLimit: - keepUntilCombo->setCurrentIndex(2); - break; - } - settings.endGroup(); - - - // Proxy - settings.beginGroup(QLatin1String("proxy")); - proxySupport->setChecked(settings.value(QLatin1String("enabled"), false).toBool()); - proxyType->setCurrentIndex(settings.value(QLatin1String("type"), 0).toInt()); - proxyHostName->setText(settings.value(QLatin1String("hostName")).toString()); - proxyPort->setValue(settings.value(QLatin1String("port"), 1080).toInt()); - proxyUserName->setText(settings.value(QLatin1String("userName")).toString()); - proxyPassword->setText(settings.value(QLatin1String("password")).toString()); - settings.endGroup(); -} - -void SettingsDialog::saveToSettings() -{ - QSettings settings; - settings.beginGroup(QLatin1String("MainWindow")); - settings.setValue(QLatin1String("home"), homeLineEdit->text()); - settings.endGroup(); - - settings.beginGroup(QLatin1String("general")); - settings.setValue(QLatin1String("openLinksIn"), openLinksIn->currentIndex()); - settings.endGroup(); - - settings.beginGroup(QLatin1String("history")); - int historyExpire = expireHistory->currentIndex(); - int idx = -1; - switch (historyExpire) { - case 0: idx = 1; break; - case 1: idx = 7; break; - case 2: idx = 14; break; - case 3: idx = 30; break; - case 4: idx = 365; break; - case 5: idx = -1; break; - } - settings.setValue(QLatin1String("historyExpire"), idx); - settings.endGroup(); - - // Appearance - settings.beginGroup(QLatin1String("websettings")); - settings.setValue(QLatin1String("fixedFont"), fixedFont); - settings.setValue(QLatin1String("standardFont"), standardFont); - settings.setValue(QLatin1String("enableJavascript"), enableJavascript->isChecked()); - settings.setValue(QLatin1String("enablePlugins"), enablePlugins->isChecked()); - QString userStyleSheetString = userStyleSheet->text(); - if (QFile::exists(userStyleSheetString)) - settings.setValue(QLatin1String("userStyleSheet"), QUrl::fromLocalFile(userStyleSheetString)); - else - settings.setValue(QLatin1String("userStyleSheet"), QUrl(userStyleSheetString)); - settings.endGroup(); - - //Privacy - settings.beginGroup(QLatin1String("cookies")); - - CookieJar::KeepPolicy keepCookies; - switch(acceptCombo->currentIndex()) { - default: - case 0: - keepCookies = CookieJar::KeepUntilExpire; - break; - case 1: - keepCookies = CookieJar::KeepUntilExit; - break; - case 2: - keepCookies = CookieJar::KeepUntilTimeLimit; - break; - } - CookieJar *jar = BrowserApplication::cookieJar(); - QMetaEnum acceptPolicyEnum = jar->staticMetaObject.enumerator(jar->staticMetaObject.indexOfEnumerator("AcceptPolicy")); - settings.setValue(QLatin1String("acceptCookies"), QLatin1String(acceptPolicyEnum.valueToKey(keepCookies))); - - CookieJar::KeepPolicy keepPolicy; - switch(keepUntilCombo->currentIndex()) { - default: - case 0: - keepPolicy = CookieJar::KeepUntilExpire; - break; - case 1: - keepPolicy = CookieJar::KeepUntilExit; - break; - case 2: - keepPolicy = CookieJar::KeepUntilTimeLimit; - break; - } - - QMetaEnum keepPolicyEnum = jar->staticMetaObject.enumerator(jar->staticMetaObject.indexOfEnumerator("KeepPolicy")); - settings.setValue(QLatin1String("keepCookiesUntil"), QLatin1String(keepPolicyEnum.valueToKey(keepPolicy))); - - settings.endGroup(); - - // proxy - settings.beginGroup(QLatin1String("proxy")); - settings.setValue(QLatin1String("enabled"), proxySupport->isChecked()); - settings.setValue(QLatin1String("type"), proxyType->currentIndex()); - settings.setValue(QLatin1String("hostName"), proxyHostName->text()); - settings.setValue(QLatin1String("port"), proxyPort->text()); - settings.setValue(QLatin1String("userName"), proxyUserName->text()); - settings.setValue(QLatin1String("password"), proxyPassword->text()); - settings.endGroup(); - - BrowserApplication::instance()->loadSettings(); - BrowserApplication::networkAccessManager()->loadSettings(); - BrowserApplication::cookieJar()->loadSettings(); - BrowserApplication::historyManager()->loadSettings(); -} - -void SettingsDialog::accept() -{ - saveToSettings(); - QDialog::accept(); -} - -void SettingsDialog::showCookies() -{ - CookiesDialog *dialog = new CookiesDialog(BrowserApplication::cookieJar(), this); - dialog->exec(); -} - -void SettingsDialog::showExceptions() -{ - CookiesExceptionsDialog *dialog = new CookiesExceptionsDialog(BrowserApplication::cookieJar(), this); - dialog->exec(); -} - -void SettingsDialog::chooseFont() -{ - bool ok; - QFont font = QFontDialog::getFont(&ok, standardFont, this); - if ( ok ) { - standardFont = font; - standardLabel->setText(QString(QLatin1String("%1 %2")).arg(font.family()).arg(font.pointSize())); - } -} - -void SettingsDialog::chooseFixedFont() -{ - bool ok; - QFont font = QFontDialog::getFont(&ok, fixedFont, this); - if ( ok ) { - fixedFont = font; - fixedLabel->setText(QString(QLatin1String("%1 %2")).arg(font.family()).arg(font.pointSize())); - } -} - -void SettingsDialog::setHomeToCurrentPage() -{ - BrowserMainWindow *mw = static_cast(parent()); - WebView *webView = mw->currentTab(); - if (webView) - homeLineEdit->setText(webView->url().toString()); -} - diff --git a/examples/gestures/browser/settings.h b/examples/gestures/browser/settings.h deleted file mode 100644 index 900be7b..0000000 --- a/examples/gestures/browser/settings.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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$ -** -****************************************************************************/ - -#ifndef SETTINGS_H -#define SETTINGS_H - -#include -#include "ui_settings.h" - -class SettingsDialog : public QDialog, public Ui_Settings -{ - Q_OBJECT - -public: - SettingsDialog(QWidget *parent = 0); - void accept(); - -private slots: - void loadDefaults(); - void loadFromSettings(); - void saveToSettings(); - - void setHomeToCurrentPage(); - void showCookies(); - void showExceptions(); - - void chooseFont(); - void chooseFixedFont(); - -private: - QFont standardFont; - QFont fixedFont; -}; - -#endif // SETTINGS_H - diff --git a/examples/gestures/browser/settings.ui b/examples/gestures/browser/settings.ui deleted file mode 100644 index 3491ce0..0000000 --- a/examples/gestures/browser/settings.ui +++ /dev/null @@ -1,614 +0,0 @@ - - Settings - - - - 0 - 0 - 657 - 322 - - - - Settings - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - 0 - - - - - 0 - 0 - 627 - 243 - - - - General - - - - - - Home: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - Set to current page - - - - - - - Qt::Horizontal - - - - 280 - 18 - - - - - - - - Remove history items: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - After one day - - - - - After one week - - - - - After two weeks - - - - - After one month - - - - - After one year - - - - - Manually - - - - - - - - Save downloads to: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - Open links from applications: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - In a tab in the current window - - - - - In a new window - - - - - - - - Qt::Vertical - - - - 391 - 262 - - - - - - - - - - 0 - 0 - 627 - 243 - - - - Appearance - - - - - - Standard font: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - QFrame::StyledPanel - - - Times 16 - - - Qt::AlignCenter - - - - - - - Select... - - - - - - - Fixed-width font: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - QFrame::StyledPanel - - - Courier 13 - - - Qt::AlignCenter - - - - - - - Select... - - - - - - - Qt::Vertical - - - - 20 - 93 - - - - - - - - - - 0 - 0 - 627 - 243 - - - - Privacy - - - - - - Web Content - - - - - - Enable Plugins - - - true - - - - - - - Enable Javascript - - - true - - - - - - - - - - Cookies - - - - - - Accept Cookies: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - Always - - - - - Never - - - - - Only from sites you navigate to - - - - - - - - Exceptions... - - - - - - - Keep until: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - They expire - - - - - I exit the application - - - - - At most 90 days - - - - - - - - Cookies... - - - - - - - - - - Qt::Vertical - - - - 371 - 177 - - - - - - - - - - 0 - 0 - 627 - 243 - - - - Proxy - - - - - - Enable proxy - - - true - - - - - - Type: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - Socks5 - - - - - Http - - - - - - - - Host: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - Port: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - 10000 - - - 1080 - - - - - - - Qt::Horizontal - - - - 293 - 20 - - - - - - - - User Name: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - Password: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - QLineEdit::Password - - - - - - - Qt::Vertical - - - - 20 - 8 - - - - - - - - - - - - Advanced - - - - - - Style Sheet: - - - - - - - - - - Qt::Vertical - - - - 20 - 176 - - - - - - - - - - - - - - buttonBox - accepted() - Settings - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - Settings - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/examples/gestures/browser/squeezelabel.cpp b/examples/gestures/browser/squeezelabel.cpp deleted file mode 100644 index 3247330..0000000 --- a/examples/gestures/browser/squeezelabel.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 "squeezelabel.h" - -SqueezeLabel::SqueezeLabel(QWidget *parent) : QLabel(parent) -{ -} - -void SqueezeLabel::paintEvent(QPaintEvent *event) -{ - QFontMetrics fm = fontMetrics(); - if (fm.width(text()) > contentsRect().width()) { - QString elided = fm.elidedText(text(), Qt::ElideMiddle, width()); - QString oldText = text(); - setText(elided); - QLabel::paintEvent(event); - setText(oldText); - } else { - QLabel::paintEvent(event); - } -} - diff --git a/examples/gestures/browser/squeezelabel.h b/examples/gestures/browser/squeezelabel.h deleted file mode 100644 index 550a275..0000000 --- a/examples/gestures/browser/squeezelabel.h +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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$ -** -****************************************************************************/ - -#ifndef SQUEEZELABEL_H -#define SQUEEZELABEL_H - -#include - -class SqueezeLabel : public QLabel -{ - Q_OBJECT - -public: - SqueezeLabel(QWidget *parent = 0); - -protected: - void paintEvent(QPaintEvent *event); - -}; - -#endif // SQUEEZELABEL_H - diff --git a/examples/gestures/browser/tabwidget.cpp b/examples/gestures/browser/tabwidget.cpp deleted file mode 100644 index 67714e4..0000000 --- a/examples/gestures/browser/tabwidget.cpp +++ /dev/null @@ -1,830 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 "tabwidget.h" - -#include "browserapplication.h" -#include "browsermainwindow.h" -#include "history.h" -#include "urllineedit.h" -#include "webview.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -TabBar::TabBar(QWidget *parent) - : QTabBar(parent) -{ - setContextMenuPolicy(Qt::CustomContextMenu); - setAcceptDrops(true); - connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), - this, SLOT(contextMenuRequested(const QPoint &))); - - QString alt = QLatin1String("Alt+%1"); - for (int i = 1; i <= 10; ++i) { - int key = i; - if (key == 10) - key = 0; - QShortcut *shortCut = new QShortcut(alt.arg(key), this); - m_tabShortcuts.append(shortCut); - connect(shortCut, SIGNAL(activated()), this, SLOT(selectTabAction())); - } - setTabsClosable(true); - connect(this, SIGNAL(tabCloseRequested(int)), - this, SIGNAL(closeTab(int))); - setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab); - setMovable(true); -} - -void TabBar::selectTabAction() -{ - if (QShortcut *shortCut = qobject_cast(sender())) { - int index = m_tabShortcuts.indexOf(shortCut); - if (index == 0) - index = 10; - setCurrentIndex(index); - } -} - -void TabBar::contextMenuRequested(const QPoint &position) -{ - QMenu menu; - menu.addAction(tr("New &Tab"), this, SIGNAL(newTab()), QKeySequence::AddTab); - int index = tabAt(position); - if (-1 != index) { - QAction *action = menu.addAction(tr("Clone Tab"), - this, SLOT(cloneTab())); - action->setData(index); - - menu.addSeparator(); - - action = menu.addAction(tr("&Close Tab"), - this, SLOT(closeTab()), QKeySequence::Close); - action->setData(index); - - action = menu.addAction(tr("Close &Other Tabs"), - this, SLOT(closeOtherTabs())); - action->setData(index); - - menu.addSeparator(); - - action = menu.addAction(tr("Reload Tab"), - this, SLOT(reloadTab()), QKeySequence::Refresh); - action->setData(index); - } else { - menu.addSeparator(); - } - menu.addAction(tr("Reload All Tabs"), this, SIGNAL(reloadAllTabs())); - menu.exec(QCursor::pos()); -} - -void TabBar::cloneTab() -{ - if (QAction *action = qobject_cast(sender())) { - int index = action->data().toInt(); - emit cloneTab(index); - } -} - -void TabBar::closeTab() -{ - if (QAction *action = qobject_cast(sender())) { - int index = action->data().toInt(); - emit closeTab(index); - } -} - -void TabBar::closeOtherTabs() -{ - if (QAction *action = qobject_cast(sender())) { - int index = action->data().toInt(); - emit closeOtherTabs(index); - } -} - -void TabBar::mousePressEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton) - m_dragStartPos = event->pos(); - QTabBar::mousePressEvent(event); -} - -void TabBar::mouseMoveEvent(QMouseEvent *event) -{ - if (event->buttons() == Qt::LeftButton) { - int diffX = event->pos().x() - m_dragStartPos.x(); - int diffY = event->pos().y() - m_dragStartPos.y(); - if ((event->pos() - m_dragStartPos).manhattanLength() > QApplication::startDragDistance() - && diffX < 3 && diffX > -3 - && diffY < -10) { - QDrag *drag = new QDrag(this); - QMimeData *mimeData = new QMimeData; - QList urls; - int index = tabAt(event->pos()); - QUrl url = tabData(index).toUrl(); - urls.append(url); - mimeData->setUrls(urls); - mimeData->setText(tabText(index)); - mimeData->setData(QLatin1String("action"), "tab-reordering"); - drag->setMimeData(mimeData); - drag->exec(); - } - } - QTabBar::mouseMoveEvent(event); -} - -// When index is -1 index chooses the current tab -void TabWidget::reloadTab(int index) -{ - if (index < 0) - index = currentIndex(); - if (index < 0 || index >= count()) - return; - - QWidget *widget = this->widget(index); - if (WebView *tab = qobject_cast(widget)) - tab->reload(); -} - -void TabBar::reloadTab() -{ - if (QAction *action = qobject_cast(sender())) { - int index = action->data().toInt(); - emit reloadTab(index); - } -} - -TabWidget::TabWidget(QWidget *parent) - : QTabWidget(parent) - , m_recentlyClosedTabsAction(0) - , m_newTabAction(0) - , m_closeTabAction(0) - , m_nextTabAction(0) - , m_previousTabAction(0) - , m_recentlyClosedTabsMenu(0) - , m_lineEditCompleter(0) - , m_lineEdits(0) - , m_tabBar(new TabBar(this)) -{ - setElideMode(Qt::ElideRight); - - connect(m_tabBar, SIGNAL(newTab()), this, SLOT(newTab())); - connect(m_tabBar, SIGNAL(closeTab(int)), this, SLOT(closeTab(int))); - connect(m_tabBar, SIGNAL(cloneTab(int)), this, SLOT(cloneTab(int))); - connect(m_tabBar, SIGNAL(closeOtherTabs(int)), this, SLOT(closeOtherTabs(int))); - connect(m_tabBar, SIGNAL(reloadTab(int)), this, SLOT(reloadTab(int))); - connect(m_tabBar, SIGNAL(reloadAllTabs()), this, SLOT(reloadAllTabs())); - connect(m_tabBar, SIGNAL(tabMoved(int, int)), this, SLOT(moveTab(int, int))); - setTabBar(m_tabBar); - setDocumentMode(true); - - // Actions - m_newTabAction = new QAction(QIcon(QLatin1String(":addtab.png")), tr("New &Tab"), this); - m_newTabAction->setShortcuts(QKeySequence::AddTab); - m_newTabAction->setIconVisibleInMenu(false); - connect(m_newTabAction, SIGNAL(triggered()), this, SLOT(newTab())); - - m_closeTabAction = new QAction(QIcon(QLatin1String(":closetab.png")), tr("&Close Tab"), this); - m_closeTabAction->setShortcuts(QKeySequence::Close); - m_closeTabAction->setIconVisibleInMenu(false); - connect(m_closeTabAction, SIGNAL(triggered()), this, SLOT(closeTab())); - - m_nextTabAction = new QAction(tr("Show Next Tab"), this); - QList shortcuts; - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BraceRight)); - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_PageDown)); - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BracketRight)); - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Less)); - m_nextTabAction->setShortcuts(shortcuts); - connect(m_nextTabAction, SIGNAL(triggered()), this, SLOT(nextTab())); - - m_previousTabAction = new QAction(tr("Show Previous Tab"), this); - shortcuts.clear(); - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BraceLeft)); - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_PageUp)); - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BracketLeft)); - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Greater)); - m_previousTabAction->setShortcuts(shortcuts); - connect(m_previousTabAction, SIGNAL(triggered()), this, SLOT(previousTab())); - - m_recentlyClosedTabsMenu = new QMenu(this); - connect(m_recentlyClosedTabsMenu, SIGNAL(aboutToShow()), - this, SLOT(aboutToShowRecentTabsMenu())); - connect(m_recentlyClosedTabsMenu, SIGNAL(triggered(QAction *)), - this, SLOT(aboutToShowRecentTriggeredAction(QAction *))); - m_recentlyClosedTabsAction = new QAction(tr("Recently Closed Tabs"), this); - m_recentlyClosedTabsAction->setMenu(m_recentlyClosedTabsMenu); - m_recentlyClosedTabsAction->setEnabled(false); - - connect(this, SIGNAL(currentChanged(int)), - this, SLOT(currentChanged(int))); - - m_lineEdits = new QStackedWidget(this); -} - -void TabWidget::clear() -{ - // clear the recently closed tabs - m_recentlyClosedTabs.clear(); - // clear the line edit history - for (int i = 0; i < m_lineEdits->count(); ++i) { - QLineEdit *qLineEdit = lineEdit(i); - qLineEdit->setText(qLineEdit->text()); - } -} - -void TabWidget::moveTab(int fromIndex, int toIndex) -{ - QWidget *lineEdit = m_lineEdits->widget(fromIndex); - m_lineEdits->removeWidget(lineEdit); - m_lineEdits->insertWidget(toIndex, lineEdit); -} - -void TabWidget::addWebAction(QAction *action, QWebPage::WebAction webAction) -{ - if (!action) - return; - m_actions.append(new WebActionMapper(action, webAction, this)); -} - -void TabWidget::currentChanged(int index) -{ - WebView *webView = this->webView(index); - if (!webView) - return; - - Q_ASSERT(m_lineEdits->count() == count()); - - WebView *oldWebView = this->webView(m_lineEdits->currentIndex()); - if (oldWebView) { - disconnect(oldWebView, SIGNAL(statusBarMessage(const QString&)), - this, SIGNAL(showStatusBarMessage(const QString&))); - disconnect(oldWebView->page(), SIGNAL(linkHovered(const QString&, const QString&, const QString&)), - this, SIGNAL(linkHovered(const QString&))); - disconnect(oldWebView, SIGNAL(loadProgress(int)), - this, SIGNAL(loadProgress(int))); - } - - connect(webView, SIGNAL(statusBarMessage(const QString&)), - this, SIGNAL(showStatusBarMessage(const QString&))); - connect(webView->page(), SIGNAL(linkHovered(const QString&, const QString&, const QString&)), - this, SIGNAL(linkHovered(const QString&))); - connect(webView, SIGNAL(loadProgress(int)), - this, SIGNAL(loadProgress(int))); - - for (int i = 0; i < m_actions.count(); ++i) { - WebActionMapper *mapper = m_actions[i]; - mapper->updateCurrent(webView->page()); - } - emit setCurrentTitle(webView->title()); - m_lineEdits->setCurrentIndex(index); - emit loadProgress(webView->progress()); - emit showStatusBarMessage(webView->lastStatusBarText()); - if (webView->url().isEmpty()) - m_lineEdits->currentWidget()->setFocus(); - else - webView->setFocus(); -} - -QAction *TabWidget::newTabAction() const -{ - return m_newTabAction; -} - -QAction *TabWidget::closeTabAction() const -{ - return m_closeTabAction; -} - -QAction *TabWidget::recentlyClosedTabsAction() const -{ - return m_recentlyClosedTabsAction; -} - -QAction *TabWidget::nextTabAction() const -{ - return m_nextTabAction; -} - -QAction *TabWidget::previousTabAction() const -{ - return m_previousTabAction; -} - -QWidget *TabWidget::lineEditStack() const -{ - return m_lineEdits; -} - -QLineEdit *TabWidget::currentLineEdit() const -{ - return lineEdit(m_lineEdits->currentIndex()); -} - -WebView *TabWidget::currentWebView() const -{ - return webView(currentIndex()); -} - -QLineEdit *TabWidget::lineEdit(int index) const -{ - UrlLineEdit *urlLineEdit = qobject_cast(m_lineEdits->widget(index)); - if (urlLineEdit) - return urlLineEdit->lineEdit(); - return 0; -} - -WebView *TabWidget::webView(int index) const -{ - QWidget *widget = this->widget(index); - if (WebView *webView = qobject_cast(widget)) { - return webView; - } else { - // optimization to delay creating the first webview - if (count() == 1) { - TabWidget *that = const_cast(this); - that->setUpdatesEnabled(false); - that->newTab(); - that->closeTab(0); - that->setUpdatesEnabled(true); - return currentWebView(); - } - } - return 0; -} - -int TabWidget::webViewIndex(WebView *webView) const -{ - int index = indexOf(webView); - return index; -} - -WebView *TabWidget::newTab(bool makeCurrent) -{ - // line edit - UrlLineEdit *urlLineEdit = new UrlLineEdit; - QLineEdit *lineEdit = urlLineEdit->lineEdit(); - if (!m_lineEditCompleter && count() > 0) { - HistoryCompletionModel *completionModel = new HistoryCompletionModel(this); - completionModel->setSourceModel(BrowserApplication::historyManager()->historyFilterModel()); - m_lineEditCompleter = new QCompleter(completionModel, this); - // Should this be in Qt by default? - QAbstractItemView *popup = m_lineEditCompleter->popup(); - QListView *listView = qobject_cast(popup); - if (listView) - listView->setUniformItemSizes(true); - } - lineEdit->setCompleter(m_lineEditCompleter); - connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(lineEditReturnPressed())); - m_lineEdits->addWidget(urlLineEdit); - m_lineEdits->setSizePolicy(lineEdit->sizePolicy()); - - // optimization to delay creating the more expensive WebView, history, etc - if (count() == 0) { - QWidget *emptyWidget = new QWidget; - QPalette p = emptyWidget->palette(); - p.setColor(QPalette::Window, palette().color(QPalette::Base)); - emptyWidget->setPalette(p); - emptyWidget->setAutoFillBackground(true); - disconnect(this, SIGNAL(currentChanged(int)), - this, SLOT(currentChanged(int))); - addTab(emptyWidget, tr("(Untitled)")); - connect(this, SIGNAL(currentChanged(int)), - this, SLOT(currentChanged(int))); - return 0; - } - - // webview - WebView *webView = new WebView; - urlLineEdit->setWebView(webView); - connect(webView, SIGNAL(loadStarted()), - this, SLOT(webViewLoadStarted())); - connect(webView, SIGNAL(loadFinished(bool)), - this, SLOT(webViewIconChanged())); - connect(webView, SIGNAL(iconChanged()), - this, SLOT(webViewIconChanged())); - connect(webView, SIGNAL(titleChanged(const QString &)), - this, SLOT(webViewTitleChanged(const QString &))); - connect(webView, SIGNAL(urlChanged(const QUrl &)), - this, SLOT(webViewUrlChanged(const QUrl &))); - connect(webView->page(), SIGNAL(windowCloseRequested()), - this, SLOT(windowCloseRequested())); - connect(webView->page(), SIGNAL(geometryChangeRequested(const QRect &)), - this, SIGNAL(geometryChangeRequested(const QRect &))); - connect(webView->page(), SIGNAL(printRequested(QWebFrame *)), - this, SIGNAL(printRequested(QWebFrame *))); - connect(webView->page(), SIGNAL(menuBarVisibilityChangeRequested(bool)), - this, SIGNAL(menuBarVisibilityChangeRequested(bool))); - connect(webView->page(), SIGNAL(statusBarVisibilityChangeRequested(bool)), - this, SIGNAL(statusBarVisibilityChangeRequested(bool))); - connect(webView->page(), SIGNAL(toolBarVisibilityChangeRequested(bool)), - this, SIGNAL(toolBarVisibilityChangeRequested(bool))); - addTab(webView, tr("(Untitled)")); - if (makeCurrent) - setCurrentWidget(webView); - - // webview actions - for (int i = 0; i < m_actions.count(); ++i) { - WebActionMapper *mapper = m_actions[i]; - mapper->addChild(webView->page()->action(mapper->webAction())); - } - - if (count() == 1) - currentChanged(currentIndex()); - emit tabsChanged(); - return webView; -} - -void TabWidget::reloadAllTabs() -{ - for (int i = 0; i < count(); ++i) { - QWidget *tabWidget = widget(i); - if (WebView *tab = qobject_cast(tabWidget)) { - tab->reload(); - } - } -} - -void TabWidget::lineEditReturnPressed() -{ - if (QLineEdit *lineEdit = qobject_cast(sender())) { - emit loadPage(lineEdit->text()); - if (m_lineEdits->currentWidget() == lineEdit) - currentWebView()->setFocus(); - } -} - -void TabWidget::windowCloseRequested() -{ - WebPage *webPage = qobject_cast(sender()); - WebView *webView = qobject_cast(webPage->view()); - int index = webViewIndex(webView); - if (index >= 0) { - if (count() == 1) - webView->webPage()->mainWindow()->close(); - else - closeTab(index); - } -} - -void TabWidget::closeOtherTabs(int index) -{ - if (-1 == index) - return; - for (int i = count() - 1; i > index; --i) - closeTab(i); - for (int i = index - 1; i >= 0; --i) - closeTab(i); -} - -// When index is -1 index chooses the current tab -void TabWidget::cloneTab(int index) -{ - if (index < 0) - index = currentIndex(); - if (index < 0 || index >= count()) - return; - WebView *tab = newTab(false); - tab->setUrl(webView(index)->url()); -} - -// When index is -1 index chooses the current tab -void TabWidget::closeTab(int index) -{ - if (index < 0) - index = currentIndex(); - if (index < 0 || index >= count()) - return; - - bool hasFocus = false; - if (WebView *tab = webView(index)) { - if (tab->isModified()) { - QMessageBox closeConfirmation(tab); - closeConfirmation.setWindowFlags(Qt::Sheet); - closeConfirmation.setWindowTitle(tr("Do you really want to close this page?")); - closeConfirmation.setInformativeText(tr("You have modified this page and when closing it you would lose the modification.\n" - "Do you really want to close this page?\n")); - closeConfirmation.setIcon(QMessageBox::Question); - closeConfirmation.addButton(QMessageBox::Yes); - closeConfirmation.addButton(QMessageBox::No); - closeConfirmation.setEscapeButton(QMessageBox::No); - if (closeConfirmation.exec() == QMessageBox::No) - return; - } - hasFocus = tab->hasFocus(); - - m_recentlyClosedTabsAction->setEnabled(true); - m_recentlyClosedTabs.prepend(tab->url()); - if (m_recentlyClosedTabs.size() >= TabWidget::m_recentlyClosedTabsSize) - m_recentlyClosedTabs.removeLast(); - } - QWidget *lineEdit = m_lineEdits->widget(index); - m_lineEdits->removeWidget(lineEdit); - lineEdit->deleteLater(); - QWidget *webView = widget(index); - removeTab(index); - webView->deleteLater(); - emit tabsChanged(); - if (hasFocus && count() > 0) - currentWebView()->setFocus(); - if (count() == 0) - emit lastTabClosed(); -} - -void TabWidget::webViewLoadStarted() -{ - WebView *webView = qobject_cast(sender()); - int index = webViewIndex(webView); - if (-1 != index) { - QIcon icon(QLatin1String(":loading.gif")); - setTabIcon(index, icon); - } -} - -void TabWidget::webViewIconChanged() -{ - WebView *webView = qobject_cast(sender()); - int index = webViewIndex(webView); - if (-1 != index) { - QIcon icon = BrowserApplication::instance()->icon(webView->url()); - setTabIcon(index, icon); - } -} - -void TabWidget::webViewTitleChanged(const QString &title) -{ - WebView *webView = qobject_cast(sender()); - int index = webViewIndex(webView); - if (-1 != index) { - setTabText(index, title); - } - if (currentIndex() == index) - emit setCurrentTitle(title); - BrowserApplication::historyManager()->updateHistoryItem(webView->url(), title); -} - -void TabWidget::webViewUrlChanged(const QUrl &url) -{ - WebView *webView = qobject_cast(sender()); - int index = webViewIndex(webView); - if (-1 != index) { - m_tabBar->setTabData(index, url); - } - emit tabsChanged(); -} - -void TabWidget::aboutToShowRecentTabsMenu() -{ - m_recentlyClosedTabsMenu->clear(); - for (int i = 0; i < m_recentlyClosedTabs.count(); ++i) { - QAction *action = new QAction(m_recentlyClosedTabsMenu); - action->setData(m_recentlyClosedTabs.at(i)); - QIcon icon = BrowserApplication::instance()->icon(m_recentlyClosedTabs.at(i)); - action->setIcon(icon); - action->setText(m_recentlyClosedTabs.at(i).toString()); - m_recentlyClosedTabsMenu->addAction(action); - } -} - -void TabWidget::aboutToShowRecentTriggeredAction(QAction *action) -{ - QUrl url = action->data().toUrl(); - loadUrlInCurrentTab(url); -} - -void TabWidget::mouseDoubleClickEvent(QMouseEvent *event) -{ - if (!childAt(event->pos()) - // Remove the line below when QTabWidget does not have a one pixel frame - && event->pos().y() < (tabBar()->y() + tabBar()->height())) { - newTab(); - return; - } - QTabWidget::mouseDoubleClickEvent(event); -} - -void TabWidget::contextMenuEvent(QContextMenuEvent *event) -{ - if (!childAt(event->pos())) { - m_tabBar->contextMenuRequested(event->pos()); - return; - } - QTabWidget::contextMenuEvent(event); -} - -void TabWidget::mouseReleaseEvent(QMouseEvent *event) -{ - if (event->button() == Qt::MidButton && !childAt(event->pos()) - // Remove the line below when QTabWidget does not have a one pixel frame - && event->pos().y() < (tabBar()->y() + tabBar()->height())) { - QUrl url(QApplication::clipboard()->text(QClipboard::Selection)); - if (!url.isEmpty() && url.isValid() && !url.scheme().isEmpty()) { - WebView *webView = newTab(); - webView->setUrl(url); - } - } -} - -void TabWidget::loadUrlInCurrentTab(const QUrl &url) -{ - WebView *webView = currentWebView(); - if (webView) { - webView->loadUrl(url); - webView->setFocus(); - } -} - -void TabWidget::nextTab() -{ - int next = currentIndex() + 1; - if (next == count()) - next = 0; - setCurrentIndex(next); -} - -void TabWidget::previousTab() -{ - int next = currentIndex() - 1; - if (next < 0) - next = count() - 1; - setCurrentIndex(next); -} - -static const qint32 TabWidgetMagic = 0xaa; - -QByteArray TabWidget::saveState() const -{ - int version = 1; - QByteArray data; - QDataStream stream(&data, QIODevice::WriteOnly); - - stream << qint32(TabWidgetMagic); - stream << qint32(version); - - QStringList tabs; - for (int i = 0; i < count(); ++i) { - if (WebView *tab = qobject_cast(widget(i))) { - tabs.append(tab->url().toString()); - } else { - tabs.append(QString::null); - } - } - stream << tabs; - stream << currentIndex(); - return data; -} - -bool TabWidget::restoreState(const QByteArray &state) -{ - int version = 1; - QByteArray sd = state; - QDataStream stream(&sd, QIODevice::ReadOnly); - if (stream.atEnd()) - return false; - - qint32 marker; - qint32 v; - stream >> marker; - stream >> v; - if (marker != TabWidgetMagic || v != version) - return false; - - QStringList openTabs; - stream >> openTabs; - - for (int i = 0; i < openTabs.count(); ++i) { - if (i != 0) - newTab(); - loadPage(openTabs.at(i)); - } - - int currentTab; - stream >> currentTab; - setCurrentIndex(currentTab); - - return true; -} - -WebActionMapper::WebActionMapper(QAction *root, QWebPage::WebAction webAction, QObject *parent) - : QObject(parent) - , m_currentParent(0) - , m_root(root) - , m_webAction(webAction) -{ - if (!m_root) - return; - connect(m_root, SIGNAL(triggered()), this, SLOT(rootTriggered())); - connect(root, SIGNAL(destroyed(QObject *)), this, SLOT(rootDestroyed())); - root->setEnabled(false); -} - -void WebActionMapper::rootDestroyed() -{ - m_root = 0; -} - -void WebActionMapper::currentDestroyed() -{ - updateCurrent(0); -} - -void WebActionMapper::addChild(QAction *action) -{ - if (!action) - return; - connect(action, SIGNAL(changed()), this, SLOT(childChanged())); -} - -QWebPage::WebAction WebActionMapper::webAction() const -{ - return m_webAction; -} - -void WebActionMapper::rootTriggered() -{ - if (m_currentParent) { - QAction *gotoAction = m_currentParent->action(m_webAction); - gotoAction->trigger(); - } -} - -void WebActionMapper::childChanged() -{ - if (QAction *source = qobject_cast(sender())) { - if (m_root - && m_currentParent - && source->parent() == m_currentParent) { - m_root->setChecked(source->isChecked()); - m_root->setEnabled(source->isEnabled()); - } - } -} - -void WebActionMapper::updateCurrent(QWebPage *currentParent) -{ - if (m_currentParent) - disconnect(m_currentParent, SIGNAL(destroyed(QObject *)), - this, SLOT(currentDestroyed())); - - m_currentParent = currentParent; - if (!m_root) - return; - if (!m_currentParent) { - m_root->setEnabled(false); - m_root->setChecked(false); - return; - } - QAction *source = m_currentParent->action(m_webAction); - m_root->setChecked(source->isChecked()); - m_root->setEnabled(source->isEnabled()); - connect(m_currentParent, SIGNAL(destroyed(QObject *)), - this, SLOT(currentDestroyed())); -} - diff --git a/examples/gestures/browser/tabwidget.h b/examples/gestures/browser/tabwidget.h deleted file mode 100644 index ee7b226..0000000 --- a/examples/gestures/browser/tabwidget.h +++ /dev/null @@ -1,224 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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$ -** -****************************************************************************/ - -#ifndef TABWIDGET_H -#define TABWIDGET_H - -#include - -#include -/* - Tab bar with a few more features such as a context menu and shortcuts - */ -class TabBar : public QTabBar -{ - Q_OBJECT - -signals: - void newTab(); - void cloneTab(int index); - void closeTab(int index); - void closeOtherTabs(int index); - void reloadTab(int index); - void reloadAllTabs(); - void tabMoveRequested(int fromIndex, int toIndex); - -public: - TabBar(QWidget *parent = 0); - -protected: - void mousePressEvent(QMouseEvent* event); - void mouseMoveEvent(QMouseEvent* event); - -private slots: - void selectTabAction(); - void cloneTab(); - void closeTab(); - void closeOtherTabs(); - void reloadTab(); - void contextMenuRequested(const QPoint &position); - -private: - QList m_tabShortcuts; - friend class TabWidget; - - QPoint m_dragStartPos; - int m_dragCurrentIndex; -}; - -#include - -QT_BEGIN_NAMESPACE -class QAction; -QT_END_NAMESPACE -class WebView; -/*! - A proxy object that connects a single browser action - to one child webpage action at a time. - - Example usage: used to keep the main window stop action in sync with - the current tabs webview's stop action. - */ -class WebActionMapper : public QObject -{ - Q_OBJECT - -public: - WebActionMapper(QAction *root, QWebPage::WebAction webAction, QObject *parent); - QWebPage::WebAction webAction() const; - void addChild(QAction *action); - void updateCurrent(QWebPage *currentParent); - -private slots: - void rootTriggered(); - void childChanged(); - void rootDestroyed(); - void currentDestroyed(); - -private: - QWebPage *m_currentParent; - QAction *m_root; - QWebPage::WebAction m_webAction; -}; - -#include -#include -QT_BEGIN_NAMESPACE -class QCompleter; -class QLineEdit; -class QMenu; -class QStackedWidget; -QT_END_NAMESPACE -/*! - TabWidget that contains WebViews and a stack widget of associated line edits. - - Connects up the current tab's signals to this class's signal and uses WebActionMapper - to proxy the actions. - */ -class TabWidget : public QTabWidget -{ - Q_OBJECT - -signals: - // tab widget signals - void loadPage(const QString &url); - void tabsChanged(); - void lastTabClosed(); - - // current tab signals - void setCurrentTitle(const QString &url); - void showStatusBarMessage(const QString &message); - void linkHovered(const QString &link); - void loadProgress(int progress); - void geometryChangeRequested(const QRect &geometry); - void menuBarVisibilityChangeRequested(bool visible); - void statusBarVisibilityChangeRequested(bool visible); - void toolBarVisibilityChangeRequested(bool visible); - void printRequested(QWebFrame *frame); - -public: - TabWidget(QWidget *parent = 0); - void clear(); - void addWebAction(QAction *action, QWebPage::WebAction webAction); - - QAction *newTabAction() const; - QAction *closeTabAction() const; - QAction *recentlyClosedTabsAction() const; - QAction *nextTabAction() const; - QAction *previousTabAction() const; - - QWidget *lineEditStack() const; - QLineEdit *currentLineEdit() const; - WebView *currentWebView() const; - WebView *webView(int index) const; - QLineEdit *lineEdit(int index) const; - int webViewIndex(WebView *webView) const; - - QByteArray saveState() const; - bool restoreState(const QByteArray &state); - -protected: - void mouseDoubleClickEvent(QMouseEvent *event); - void contextMenuEvent(QContextMenuEvent *event); - void mouseReleaseEvent(QMouseEvent *event); - -public slots: - void loadUrlInCurrentTab(const QUrl &url); - WebView *newTab(bool makeCurrent = true); - void cloneTab(int index = -1); - void closeTab(int index = -1); - void closeOtherTabs(int index); - void reloadTab(int index = -1); - void reloadAllTabs(); - void nextTab(); - void previousTab(); - -private slots: - void currentChanged(int index); - void aboutToShowRecentTabsMenu(); - void aboutToShowRecentTriggeredAction(QAction *action); - void webViewLoadStarted(); - void webViewIconChanged(); - void webViewTitleChanged(const QString &title); - void webViewUrlChanged(const QUrl &url); - void lineEditReturnPressed(); - void windowCloseRequested(); - void moveTab(int fromIndex, int toIndex); - -private: - QAction *m_recentlyClosedTabsAction; - QAction *m_newTabAction; - QAction *m_closeTabAction; - QAction *m_nextTabAction; - QAction *m_previousTabAction; - - QMenu *m_recentlyClosedTabsMenu; - static const int m_recentlyClosedTabsSize = 10; - QList m_recentlyClosedTabs; - QList m_actions; - - QCompleter *m_lineEditCompleter; - QStackedWidget *m_lineEdits; - TabBar *m_tabBar; -}; - -#endif // TABWIDGET_H - diff --git a/examples/gestures/browser/toolbarsearch.cpp b/examples/gestures/browser/toolbarsearch.cpp deleted file mode 100644 index 0fb5322..0000000 --- a/examples/gestures/browser/toolbarsearch.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 "toolbarsearch.h" -#include "autosaver.h" - -#include -#include - -#include -#include -#include - -#include - -/* - ToolbarSearch is a very basic search widget that also contains a small history. - Searches are turned into urls that use Google to perform search - */ -ToolbarSearch::ToolbarSearch(QWidget *parent) - : SearchLineEdit(parent) - , m_autosaver(new AutoSaver(this)) - , m_maxSavedSearches(10) - , m_stringListModel(new QStringListModel(this)) -{ - QMenu *m = menu(); - connect(m, SIGNAL(aboutToShow()), this, SLOT(aboutToShowMenu())); - connect(m, SIGNAL(triggered(QAction*)), this, SLOT(triggeredMenuAction(QAction*))); - - QCompleter *completer = new QCompleter(m_stringListModel, this); - completer->setCompletionMode(QCompleter::InlineCompletion); - lineEdit()->setCompleter(completer); - - connect(lineEdit(), SIGNAL(returnPressed()), SLOT(searchNow())); - setInactiveText(tr("Google")); - load(); -} - -ToolbarSearch::~ToolbarSearch() -{ - m_autosaver->saveIfNeccessary(); -} - -void ToolbarSearch::save() -{ - QSettings settings; - settings.beginGroup(QLatin1String("toolbarsearch")); - settings.setValue(QLatin1String("recentSearches"), m_stringListModel->stringList()); - settings.setValue(QLatin1String("maximumSaved"), m_maxSavedSearches); - settings.endGroup(); -} - -void ToolbarSearch::load() -{ - QSettings settings; - settings.beginGroup(QLatin1String("toolbarsearch")); - QStringList list = settings.value(QLatin1String("recentSearches")).toStringList(); - m_maxSavedSearches = settings.value(QLatin1String("maximumSaved"), m_maxSavedSearches).toInt(); - m_stringListModel->setStringList(list); - settings.endGroup(); -} - -void ToolbarSearch::searchNow() -{ - QString searchText = lineEdit()->text(); - QStringList newList = m_stringListModel->stringList(); - if (newList.contains(searchText)) - newList.removeAt(newList.indexOf(searchText)); - newList.prepend(searchText); - if (newList.size() >= m_maxSavedSearches) - newList.removeLast(); - - QWebSettings *globalSettings = QWebSettings::globalSettings(); - if (!globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled)) { - m_stringListModel->setStringList(newList); - m_autosaver->changeOccurred(); - } - - QUrl url(QLatin1String("http://www.google.com/search")); - url.addQueryItem(QLatin1String("q"), searchText); - url.addQueryItem(QLatin1String("ie"), QLatin1String("UTF-8")); - url.addQueryItem(QLatin1String("oe"), QLatin1String("UTF-8")); - url.addQueryItem(QLatin1String("client"), QLatin1String("qtdemobrowser")); - emit search(url); -} - -void ToolbarSearch::aboutToShowMenu() -{ - lineEdit()->selectAll(); - QMenu *m = menu(); - m->clear(); - QStringList list = m_stringListModel->stringList(); - if (list.isEmpty()) { - m->addAction(tr("No Recent Searches")); - return; - } - - QAction *recent = m->addAction(tr("Recent Searches")); - recent->setEnabled(false); - for (int i = 0; i < list.count(); ++i) { - QString text = list.at(i); - m->addAction(text)->setData(text); - } - m->addSeparator(); - m->addAction(tr("Clear Recent Searches"), this, SLOT(clear())); -} - -void ToolbarSearch::triggeredMenuAction(QAction *action) -{ - QVariant v = action->data(); - if (v.canConvert()) { - QString text = v.toString(); - lineEdit()->setText(text); - searchNow(); - } -} - -void ToolbarSearch::clear() -{ - m_stringListModel->setStringList(QStringList()); - m_autosaver->changeOccurred();; -} - diff --git a/examples/gestures/browser/toolbarsearch.h b/examples/gestures/browser/toolbarsearch.h deleted file mode 100644 index 02c1871..0000000 --- a/examples/gestures/browser/toolbarsearch.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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$ -** -****************************************************************************/ - -#ifndef TOOLBARSEARCH_H -#define TOOLBARSEARCH_H - -#include "searchlineedit.h" - -QT_BEGIN_NAMESPACE -class QUrl; -class QAction; -class QStringListModel; -QT_END_NAMESPACE - -class AutoSaver; - -class ToolbarSearch : public SearchLineEdit -{ - Q_OBJECT - -signals: - void search(const QUrl &url); - -public: - ToolbarSearch(QWidget *parent = 0); - ~ToolbarSearch(); - -public slots: - void clear(); - void searchNow(); - -private slots: - void save(); - void aboutToShowMenu(); - void triggeredMenuAction(QAction *action); - -private: - void load(); - - AutoSaver *m_autosaver; - int m_maxSavedSearches; - QStringListModel *m_stringListModel; -}; - -#endif // TOOLBARSEARCH_H - diff --git a/examples/gestures/browser/urllineedit.cpp b/examples/gestures/browser/urllineedit.cpp deleted file mode 100644 index 70951d1..0000000 --- a/examples/gestures/browser/urllineedit.cpp +++ /dev/null @@ -1,340 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 "urllineedit.h" - -#include "browserapplication.h" -#include "searchlineedit.h" -#include "webview.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -ExLineEdit::ExLineEdit(QWidget *parent) - : QWidget(parent) - , m_leftWidget(0) - , m_lineEdit(new QLineEdit(this)) - , m_clearButton(0) -{ - setFocusPolicy(m_lineEdit->focusPolicy()); - setAttribute(Qt::WA_InputMethodEnabled); - setSizePolicy(m_lineEdit->sizePolicy()); - setBackgroundRole(m_lineEdit->backgroundRole()); - setMouseTracking(true); - setAcceptDrops(true); - setAttribute(Qt::WA_MacShowFocusRect, true); - QPalette p = m_lineEdit->palette(); - setPalette(p); - - // line edit - m_lineEdit->setFrame(false); - m_lineEdit->setFocusProxy(this); - m_lineEdit->setAttribute(Qt::WA_MacShowFocusRect, false); - QPalette clearPalette = m_lineEdit->palette(); - clearPalette.setBrush(QPalette::Base, QBrush(Qt::transparent)); - m_lineEdit->setPalette(clearPalette); - - // clearButton - m_clearButton = new ClearButton(this); - connect(m_clearButton, SIGNAL(clicked()), - m_lineEdit, SLOT(clear())); - connect(m_lineEdit, SIGNAL(textChanged(const QString&)), - m_clearButton, SLOT(textChanged(const QString&))); -} - -void ExLineEdit::setLeftWidget(QWidget *widget) -{ - m_leftWidget = widget; -} - -QWidget *ExLineEdit::leftWidget() const -{ - return m_leftWidget; -} - -void ExLineEdit::resizeEvent(QResizeEvent *event) -{ - Q_ASSERT(m_leftWidget); - updateGeometries(); - QWidget::resizeEvent(event); -} - -void ExLineEdit::updateGeometries() -{ - QStyleOptionFrameV2 panel; - initStyleOption(&panel); - QRect rect = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this); - - int height = rect.height(); - int width = rect.width(); - - int m_leftWidgetHeight = m_leftWidget->height(); - m_leftWidget->setGeometry(rect.x() + 2, rect.y() + (height - m_leftWidgetHeight)/2, - m_leftWidget->width(), m_leftWidget->height()); - - int clearButtonWidth = this->height(); - m_lineEdit->setGeometry(m_leftWidget->x() + m_leftWidget->width(), 0, - width - clearButtonWidth - m_leftWidget->width(), this->height()); - - m_clearButton->setGeometry(this->width() - clearButtonWidth, 0, - clearButtonWidth, this->height()); -} - -void ExLineEdit::initStyleOption(QStyleOptionFrameV2 *option) const -{ - option->initFrom(this); - option->rect = contentsRect(); - option->lineWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, option, this); - option->midLineWidth = 0; - option->state |= QStyle::State_Sunken; - if (m_lineEdit->isReadOnly()) - option->state |= QStyle::State_ReadOnly; -#ifdef QT_KEYPAD_NAVIGATION - if (hasEditFocus()) - option->state |= QStyle::State_HasEditFocus; -#endif - option->features = QStyleOptionFrameV2::None; -} - -QSize ExLineEdit::sizeHint() const -{ - m_lineEdit->setFrame(true); - QSize size = m_lineEdit->sizeHint(); - m_lineEdit->setFrame(false); - return size; -} - -void ExLineEdit::focusInEvent(QFocusEvent *event) -{ - m_lineEdit->event(event); - QWidget::focusInEvent(event); -} - -void ExLineEdit::focusOutEvent(QFocusEvent *event) -{ - m_lineEdit->event(event); - - if (m_lineEdit->completer()) { - connect(m_lineEdit->completer(), SIGNAL(activated(QString)), - m_lineEdit, SLOT(setText(QString))); - connect(m_lineEdit->completer(), SIGNAL(highlighted(QString)), - m_lineEdit, SLOT(_q_completionHighlighted(QString))); - } - QWidget::focusOutEvent(event); -} - -void ExLineEdit::keyPressEvent(QKeyEvent *event) -{ - m_lineEdit->event(event); -} - -bool ExLineEdit::event(QEvent *event) -{ - if (event->type() == QEvent::ShortcutOverride) - return m_lineEdit->event(event); - return QWidget::event(event); -} - -void ExLineEdit::paintEvent(QPaintEvent *) -{ - QPainter p(this); - QStyleOptionFrameV2 panel; - initStyleOption(&panel); - style()->drawPrimitive(QStyle::PE_PanelLineEdit, &panel, &p, this); -} - -QVariant ExLineEdit::inputMethodQuery(Qt::InputMethodQuery property) const -{ - return m_lineEdit->inputMethodQuery(property); -} - -void ExLineEdit::inputMethodEvent(QInputMethodEvent *e) -{ - m_lineEdit->event(e); -} - - -class UrlIconLabel : public QLabel -{ - -public: - UrlIconLabel(QWidget *parent); - - WebView *m_webView; - -protected: - void mousePressEvent(QMouseEvent *event); - void mouseMoveEvent(QMouseEvent *event); - -private: - QPoint m_dragStartPos; - -}; - -UrlIconLabel::UrlIconLabel(QWidget *parent) - : QLabel(parent) - , m_webView(0) -{ - setMinimumWidth(16); - setMinimumHeight(16); -} - -void UrlIconLabel::mousePressEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton) - m_dragStartPos = event->pos(); - QLabel::mousePressEvent(event); -} - -void UrlIconLabel::mouseMoveEvent(QMouseEvent *event) -{ - if (event->buttons() == Qt::LeftButton - && (event->pos() - m_dragStartPos).manhattanLength() > QApplication::startDragDistance() - && m_webView) { - QDrag *drag = new QDrag(this); - QMimeData *mimeData = new QMimeData; - mimeData->setText(QString::fromUtf8(m_webView->url().toEncoded())); - QList urls; - urls.append(m_webView->url()); - mimeData->setUrls(urls); - drag->setMimeData(mimeData); - drag->exec(); - } -} - -UrlLineEdit::UrlLineEdit(QWidget *parent) - : ExLineEdit(parent) - , m_webView(0) - , m_iconLabel(0) -{ - // icon - m_iconLabel = new UrlIconLabel(this); - m_iconLabel->resize(16, 16); - setLeftWidget(m_iconLabel); - m_defaultBaseColor = palette().color(QPalette::Base); - - webViewIconChanged(); -} - -void UrlLineEdit::setWebView(WebView *webView) -{ - Q_ASSERT(!m_webView); - m_webView = webView; - m_iconLabel->m_webView = webView; - connect(webView, SIGNAL(urlChanged(const QUrl &)), - this, SLOT(webViewUrlChanged(const QUrl &))); - connect(webView, SIGNAL(loadFinished(bool)), - this, SLOT(webViewIconChanged())); - connect(webView, SIGNAL(iconChanged()), - this, SLOT(webViewIconChanged())); - connect(webView, SIGNAL(loadProgress(int)), - this, SLOT(update())); -} - -void UrlLineEdit::webViewUrlChanged(const QUrl &url) -{ - m_lineEdit->setText(QString::fromUtf8(url.toEncoded())); - m_lineEdit->setCursorPosition(0); -} - -void UrlLineEdit::webViewIconChanged() -{ - QUrl url = (m_webView) ? m_webView->url() : QUrl(); - QIcon icon = BrowserApplication::instance()->icon(url); - QPixmap pixmap(icon.pixmap(16, 16)); - m_iconLabel->setPixmap(pixmap); -} - -QLinearGradient UrlLineEdit::generateGradient(const QColor &color) const -{ - QLinearGradient gradient(0, 0, 0, height()); - gradient.setColorAt(0, m_defaultBaseColor); - gradient.setColorAt(0.15, color.lighter(120)); - gradient.setColorAt(0.5, color); - gradient.setColorAt(0.85, color.lighter(120)); - gradient.setColorAt(1, m_defaultBaseColor); - return gradient; -} - -void UrlLineEdit::focusOutEvent(QFocusEvent *event) -{ - if (m_lineEdit->text().isEmpty() && m_webView) - m_lineEdit->setText(QString::fromUtf8(m_webView->url().toEncoded())); - ExLineEdit::focusOutEvent(event); -} - -void UrlLineEdit::paintEvent(QPaintEvent *event) -{ - QPalette p = palette(); - if (m_webView && m_webView->url().scheme() == QLatin1String("https")) { - QColor lightYellow(248, 248, 210); - p.setBrush(QPalette::Base, generateGradient(lightYellow)); - } else { - p.setBrush(QPalette::Base, m_defaultBaseColor); - } - setPalette(p); - ExLineEdit::paintEvent(event); - - QPainter painter(this); - QStyleOptionFrameV2 panel; - initStyleOption(&panel); - QRect backgroundRect = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this); - if (m_webView && !hasFocus()) { - int progress = m_webView->progress(); - QColor loadingColor = QColor(116, 192, 250); - painter.setBrush(generateGradient(loadingColor)); - painter.setPen(Qt::transparent); - int mid = backgroundRect.width() / 100 * progress; - QRect progressRect(backgroundRect.x(), backgroundRect.y(), mid, backgroundRect.height()); - painter.drawRect(progressRect); - } -} diff --git a/examples/gestures/browser/urllineedit.h b/examples/gestures/browser/urllineedit.h deleted file mode 100644 index 0727e6a..0000000 --- a/examples/gestures/browser/urllineedit.h +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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$ -** -****************************************************************************/ - -#ifndef URLLINEEDIT_H -#define URLLINEEDIT_H - -#include -#include -#include - -QT_BEGIN_NAMESPACE -class QLineEdit; -QT_END_NAMESPACE - -class ClearButton; -class ExLineEdit : public QWidget -{ - Q_OBJECT - -public: - ExLineEdit(QWidget *parent = 0); - - inline QLineEdit *lineEdit() const { return m_lineEdit; } - - void setLeftWidget(QWidget *widget); - QWidget *leftWidget() const; - - QSize sizeHint() const; - - QVariant inputMethodQuery(Qt::InputMethodQuery property) const; -protected: - void focusInEvent(QFocusEvent *event); - void focusOutEvent(QFocusEvent *event); - void keyPressEvent(QKeyEvent *event); - void paintEvent(QPaintEvent *event); - void resizeEvent(QResizeEvent *event); - void inputMethodEvent(QInputMethodEvent *e); - bool event(QEvent *event); - -protected: - void updateGeometries(); - void initStyleOption(QStyleOptionFrameV2 *option) const; - - QWidget *m_leftWidget; - QLineEdit *m_lineEdit; - ClearButton *m_clearButton; -}; - -class UrlIconLabel; -class WebView; -class UrlLineEdit : public ExLineEdit -{ - Q_OBJECT - -public: - UrlLineEdit(QWidget *parent = 0); - void setWebView(WebView *webView); - -protected: - void paintEvent(QPaintEvent *event); - void focusOutEvent(QFocusEvent *event); - -private slots: - void webViewUrlChanged(const QUrl &url); - void webViewIconChanged(); - -private: - QLinearGradient generateGradient(const QColor &color) const; - WebView *m_webView; - UrlIconLabel *m_iconLabel; - QColor m_defaultBaseColor; - -}; - - -#endif // URLLINEEDIT_H - diff --git a/examples/gestures/browser/webview.cpp b/examples/gestures/browser/webview.cpp deleted file mode 100644 index e50872f..0000000 --- a/examples/gestures/browser/webview.cpp +++ /dev/null @@ -1,363 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 "browserapplication.h" -#include "browsermainwindow.h" -#include "cookiejar.h" -#include "downloadmanager.h" -#include "networkaccessmanager.h" -#include "tabwidget.h" -#include "webview.h" - -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include - -WebPage::WebPage(QObject *parent) - : QWebPage(parent) - , m_keyboardModifiers(Qt::NoModifier) - , m_pressedButtons(Qt::NoButton) - , m_openInNewTab(false) -{ - setNetworkAccessManager(BrowserApplication::networkAccessManager()); - connect(this, SIGNAL(unsupportedContent(QNetworkReply *)), - this, SLOT(handleUnsupportedContent(QNetworkReply *))); -} - -BrowserMainWindow *WebPage::mainWindow() -{ - QObject *w = this->parent(); - while (w) { - if (BrowserMainWindow *mw = qobject_cast(w)) - return mw; - w = w->parent(); - } - return BrowserApplication::instance()->mainWindow(); -} - -bool WebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type) -{ - // ctrl open in new tab - // ctrl-shift open in new tab and select - // ctrl-alt open in new window - if (type == QWebPage::NavigationTypeLinkClicked - && (m_keyboardModifiers & Qt::ControlModifier - || m_pressedButtons == Qt::MidButton)) { - bool newWindow = (m_keyboardModifiers & Qt::AltModifier); - WebView *webView; - if (newWindow) { - BrowserApplication::instance()->newMainWindow(); - BrowserMainWindow *newMainWindow = BrowserApplication::instance()->mainWindow(); - webView = newMainWindow->currentTab(); - newMainWindow->raise(); - newMainWindow->activateWindow(); - webView->setFocus(); - } else { - bool selectNewTab = (m_keyboardModifiers & Qt::ShiftModifier); - webView = mainWindow()->tabWidget()->newTab(selectNewTab); - } - webView->load(request); - m_keyboardModifiers = Qt::NoModifier; - m_pressedButtons = Qt::NoButton; - return false; - } - if (frame == mainFrame()) { - m_loadingUrl = request.url(); - emit loadingUrl(m_loadingUrl); - } - return QWebPage::acceptNavigationRequest(frame, request, type); -} - -QWebPage *WebPage::createWindow(QWebPage::WebWindowType type) -{ - Q_UNUSED(type); - if (m_keyboardModifiers & Qt::ControlModifier || m_pressedButtons == Qt::MidButton) - m_openInNewTab = true; - if (m_openInNewTab) { - m_openInNewTab = false; - return mainWindow()->tabWidget()->newTab()->page(); - } - BrowserApplication::instance()->newMainWindow(); - BrowserMainWindow *mainWindow = BrowserApplication::instance()->mainWindow(); - return mainWindow->currentTab()->page(); -} - -#if !defined(QT_NO_UITOOLS) -QObject *WebPage::createPlugin(const QString &classId, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues) -{ - Q_UNUSED(url); - Q_UNUSED(paramNames); - Q_UNUSED(paramValues); - QUiLoader loader; - return loader.createWidget(classId, view()); -} -#endif // !defined(QT_NO_UITOOLS) - -void WebPage::handleUnsupportedContent(QNetworkReply *reply) -{ - if (reply->error() == QNetworkReply::NoError) { - BrowserApplication::downloadManager()->handleUnsupportedContent(reply); - return; - } - - QFile file(QLatin1String(":/notfound.html")); - bool isOpened = file.open(QIODevice::ReadOnly); - Q_ASSERT(isOpened); - QString title = tr("Error loading page: %1").arg(reply->url().toString()); - QString html = QString(QLatin1String(file.readAll())) - .arg(title) - .arg(reply->errorString()) - .arg(reply->url().toString()); - - QBuffer imageBuffer; - imageBuffer.open(QBuffer::ReadWrite); - QIcon icon = view()->style()->standardIcon(QStyle::SP_MessageBoxWarning, 0, view()); - QPixmap pixmap = icon.pixmap(QSize(32,32)); - if (pixmap.save(&imageBuffer, "PNG")) { - html.replace(QLatin1String("IMAGE_BINARY_DATA_HERE"), - QString(QLatin1String(imageBuffer.buffer().toBase64()))); - } - - QList frames; - frames.append(mainFrame()); - while (!frames.isEmpty()) { - QWebFrame *frame = frames.takeFirst(); - if (frame->url() == reply->url()) { - frame->setHtml(html, reply->url()); - return; - } - QList children = frame->childFrames(); - foreach(QWebFrame *frame, children) - frames.append(frame); - } - if (m_loadingUrl == reply->url()) { - mainFrame()->setHtml(html, reply->url()); - } -} - - -WebView::WebView(QWidget* parent) - : QWebView(parent) - , m_progress(0) - , m_page(new WebPage(this)) - , m_currentPanFrame(0) -{ - grabGesture(Qt::PanGesture); - setPage(m_page); - connect(page(), SIGNAL(statusBarMessage(const QString&)), - SLOT(setStatusBarText(const QString&))); - connect(this, SIGNAL(loadProgress(int)), - this, SLOT(setProgress(int))); - connect(this, SIGNAL(loadFinished(bool)), - this, SLOT(loadFinished())); - connect(page(), SIGNAL(loadingUrl(const QUrl&)), - this, SIGNAL(urlChanged(const QUrl &))); - connect(page(), SIGNAL(downloadRequested(const QNetworkRequest &)), - this, SLOT(downloadRequested(const QNetworkRequest &))); - page()->setForwardUnsupportedContent(true); - -} - -void WebView::contextMenuEvent(QContextMenuEvent *event) -{ - QWebHitTestResult r = page()->mainFrame()->hitTestContent(event->pos()); - if (!r.linkUrl().isEmpty()) { - QMenu menu(this); - menu.addAction(pageAction(QWebPage::OpenLinkInNewWindow)); - menu.addAction(tr("Open in New Tab"), this, SLOT(openLinkInNewTab())); - menu.addSeparator(); - menu.addAction(pageAction(QWebPage::DownloadLinkToDisk)); - // Add link to bookmarks... - menu.addSeparator(); - menu.addAction(pageAction(QWebPage::CopyLinkToClipboard)); - if (page()->settings()->testAttribute(QWebSettings::DeveloperExtrasEnabled)) - menu.addAction(pageAction(QWebPage::InspectElement)); - menu.exec(mapToGlobal(event->pos())); - return; - } - QWebView::contextMenuEvent(event); -} - -void WebView::wheelEvent(QWheelEvent *event) -{ - if (QApplication::keyboardModifiers() & Qt::ControlModifier) { - int numDegrees = event->delta() / 8; - int numSteps = numDegrees / 15; - setTextSizeMultiplier(textSizeMultiplier() + numSteps * 0.1); - event->accept(); - return; - } - QWebView::wheelEvent(event); -} - -void WebView::openLinkInNewTab() -{ - m_page->m_openInNewTab = true; - pageAction(QWebPage::OpenLinkInNewWindow)->trigger(); -} - -void WebView::setProgress(int progress) -{ - m_progress = progress; -} - -void WebView::loadFinished() -{ - if (100 != m_progress) { - qWarning() << "Recieved finished signal while progress is still:" << progress() - << "Url:" << url(); - } - m_progress = 0; -} - -void WebView::loadUrl(const QUrl &url) -{ - m_initialUrl = url; - load(url); -} - -QString WebView::lastStatusBarText() const -{ - return m_statusBarText; -} - -QUrl WebView::url() const -{ - QUrl url = QWebView::url(); - if (!url.isEmpty()) - return url; - - return m_initialUrl; -} - -void WebView::mousePressEvent(QMouseEvent *event) -{ - m_page->m_pressedButtons = event->buttons(); - m_page->m_keyboardModifiers = event->modifiers(); - QWebView::mousePressEvent(event); -} - -void WebView::mouseReleaseEvent(QMouseEvent *event) -{ - QWebView::mouseReleaseEvent(event); - if (!event->isAccepted() && (m_page->m_pressedButtons & Qt::MidButton)) { - QUrl url(QApplication::clipboard()->text(QClipboard::Selection)); - if (!url.isEmpty() && url.isValid() && !url.scheme().isEmpty()) { - setUrl(url); - } - } -} - -void WebView::setStatusBarText(const QString &string) -{ - m_statusBarText = string; -} - -void WebView::downloadRequested(const QNetworkRequest &request) -{ - BrowserApplication::downloadManager()->download(request); -} - -bool WebView::event(QEvent *event) -{ - if (event->type() == QEvent::Gesture) - { - gestureEvent(static_cast(event)); - return true; - } - return QWebView::event(event); -} - -void WebView::gestureEvent(QGestureEvent *event) -{ - if (const QGesture *g = event->gesture(Qt::PanGesture)) { - if (g->state() == Qt::GestureUpdated) { - if (m_currentPanFrame) { - m_panSpeed = g->pos() - g->lastPos(); - m_currentPanFrame->scroll(-m_panSpeed.x(), -m_panSpeed.y()); - } - } else if (g->state() == Qt::GestureStarted) { - startTimer(20); - m_currentPanFrame = 0; - if (QWebFrame *frame = page()->mainFrame()) { - QWebHitTestResult result = frame->hitTestContent(g->startPos()); - if (!result.isNull()) - m_currentPanFrame = result.frame(); - while (m_currentPanFrame && - m_currentPanFrame->scrollBarMinimum(Qt::Vertical) == 0 && - m_currentPanFrame->scrollBarMaximum(Qt::Vertical) == 0 && - m_currentPanFrame->scrollBarMinimum(Qt::Horizontal) == 0 && - m_currentPanFrame->scrollBarMaximum(Qt::Horizontal) == 0) { - m_currentPanFrame = m_currentPanFrame->parentFrame(); - } - } - } else { - } - event->accept(); - } -} - -static QPoint deaccelerate(const QPoint &speed, int a = 1, int max = 64) -{ - int x = qBound(-max, speed.x(), max); - int y = qBound(-max, speed.y(), max); - x = (x == 0) ? x : (x > 0) ? qMax(0, x - a) : qMin(0, x + a); - y = (y == 0) ? y : (y > 0) ? qMax(0, y - a) : qMin(0, y + a); - return QPoint(x, y); -} - -void WebView::timerEvent(QTimerEvent *event) -{ - m_panSpeed = deaccelerate(m_panSpeed); - if (m_panSpeed.isNull()) - killTimer(event->timerId()); - if (m_currentPanFrame) - m_currentPanFrame->scroll(-m_panSpeed.x(), -m_panSpeed.y()); -} diff --git a/examples/gestures/browser/webview.h b/examples/gestures/browser/webview.h deleted file mode 100644 index 71aca1a..0000000 --- a/examples/gestures/browser/webview.h +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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$ -** -****************************************************************************/ - -#ifndef WEBVIEW_H -#define WEBVIEW_H - -#include - -QT_BEGIN_NAMESPACE -class QAuthenticator; -class QMouseEvent; -class QNetworkProxy; -class QNetworkReply; -class QSslError; -QT_END_NAMESPACE - -class BrowserMainWindow; -class WebPage : public QWebPage { - Q_OBJECT - -signals: - void loadingUrl(const QUrl &url); - -public: - WebPage(QObject *parent = 0); - BrowserMainWindow *mainWindow(); - -protected: - bool acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type); - QWebPage *createWindow(QWebPage::WebWindowType type); -#if !defined(QT_NO_UITOOLS) - QObject *createPlugin(const QString &classId, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues); -#endif - -private slots: - void handleUnsupportedContent(QNetworkReply *reply); - -private: - friend class WebView; - - // set the webview mousepressedevent - Qt::KeyboardModifiers m_keyboardModifiers; - Qt::MouseButtons m_pressedButtons; - bool m_openInNewTab; - QUrl m_loadingUrl; -}; - -class WebView : public QWebView { - Q_OBJECT - -public: - WebView(QWidget *parent = 0); - WebPage *webPage() const { return m_page; } - - void loadUrl(const QUrl &url); - QUrl url() const; - - QString lastStatusBarText() const; - inline int progress() const { return m_progress; } - -protected: - bool event(QEvent *event); - void gestureEvent(QGestureEvent *event); - void timerEvent(QTimerEvent *event); - void mousePressEvent(QMouseEvent *event); - void mouseReleaseEvent(QMouseEvent *event); - void contextMenuEvent(QContextMenuEvent *event); - void wheelEvent(QWheelEvent *event); - -private slots: - void setProgress(int progress); - void loadFinished(); - void setStatusBarText(const QString &string); - void downloadRequested(const QNetworkRequest &request); - void openLinkInNewTab(); - -private: - QString m_statusBarText; - QUrl m_initialUrl; - int m_progress; - WebPage *m_page; - QPoint m_panSpeed; - QWebFrame *m_currentPanFrame; -}; - -#endif diff --git a/examples/gestures/browser/xbel.cpp b/examples/gestures/browser/xbel.cpp deleted file mode 100644 index 6145281..0000000 --- a/examples/gestures/browser/xbel.cpp +++ /dev/null @@ -1,320 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 "xbel.h" - -#include - -BookmarkNode::BookmarkNode(BookmarkNode::Type type, BookmarkNode *parent) : - expanded(false) - , m_parent(parent) - , m_type(type) -{ - if (parent) - parent->add(this); -} - -BookmarkNode::~BookmarkNode() -{ - if (m_parent) - m_parent->remove(this); - qDeleteAll(m_children); - m_parent = 0; - m_type = BookmarkNode::Root; -} - -bool BookmarkNode::operator==(const BookmarkNode &other) -{ - if (url != other.url - || title != other.title - || desc != other.desc - || expanded != other.expanded - || m_type != other.m_type - || m_children.count() != other.m_children.count()) - return false; - - for (int i = 0; i < m_children.count(); ++i) - if (!((*(m_children[i])) == (*(other.m_children[i])))) - return false; - return true; -} - -BookmarkNode::Type BookmarkNode::type() const -{ - return m_type; -} - -void BookmarkNode::setType(Type type) -{ - m_type = type; -} - -QList BookmarkNode::children() const -{ - return m_children; -} - -BookmarkNode *BookmarkNode::parent() const -{ - return m_parent; -} - -void BookmarkNode::add(BookmarkNode *child, int offset) -{ - Q_ASSERT(child->m_type != Root); - if (child->m_parent) - child->m_parent->remove(child); - child->m_parent = this; - if (-1 == offset) - offset = m_children.size(); - m_children.insert(offset, child); -} - -void BookmarkNode::remove(BookmarkNode *child) -{ - child->m_parent = 0; - m_children.removeAll(child); -} - - -XbelReader::XbelReader() -{ -} - -BookmarkNode *XbelReader::read(const QString &fileName) -{ - QFile file(fileName); - if (!file.exists()) { - return new BookmarkNode(BookmarkNode::Root); - } - file.open(QFile::ReadOnly); - return read(&file); -} - -BookmarkNode *XbelReader::read(QIODevice *device) -{ - BookmarkNode *root = new BookmarkNode(BookmarkNode::Root); - setDevice(device); - while (!atEnd()) { - readNext(); - if (isStartElement()) { - QString version = attributes().value(QLatin1String("version")).toString(); - if (name() == QLatin1String("xbel") - && (version.isEmpty() || version == QLatin1String("1.0"))) { - readXBEL(root); - } else { - raiseError(QObject::tr("The file is not an XBEL version 1.0 file.")); - } - } - } - return root; -} - -void XbelReader::readXBEL(BookmarkNode *parent) -{ - Q_ASSERT(isStartElement() && name() == QLatin1String("xbel")); - - while (!atEnd()) { - readNext(); - if (isEndElement()) - break; - - if (isStartElement()) { - if (name() == QLatin1String("folder")) - readFolder(parent); - else if (name() == QLatin1String("bookmark")) - readBookmarkNode(parent); - else if (name() == QLatin1String("separator")) - readSeparator(parent); - else - skipUnknownElement(); - } - } -} - -void XbelReader::readFolder(BookmarkNode *parent) -{ - Q_ASSERT(isStartElement() && name() == QLatin1String("folder")); - - BookmarkNode *folder = new BookmarkNode(BookmarkNode::Folder, parent); - folder->expanded = (attributes().value(QLatin1String("folded")) == QLatin1String("no")); - - while (!atEnd()) { - readNext(); - - if (isEndElement()) - break; - - if (isStartElement()) { - if (name() == QLatin1String("title")) - readTitle(folder); - else if (name() == QLatin1String("desc")) - readDescription(folder); - else if (name() == QLatin1String("folder")) - readFolder(folder); - else if (name() == QLatin1String("bookmark")) - readBookmarkNode(folder); - else if (name() == QLatin1String("separator")) - readSeparator(folder); - else - skipUnknownElement(); - } - } -} - -void XbelReader::readTitle(BookmarkNode *parent) -{ - Q_ASSERT(isStartElement() && name() == QLatin1String("title")); - parent->title = readElementText(); -} - -void XbelReader::readDescription(BookmarkNode *parent) -{ - Q_ASSERT(isStartElement() && name() == QLatin1String("desc")); - parent->desc = readElementText(); -} - -void XbelReader::readSeparator(BookmarkNode *parent) -{ - new BookmarkNode(BookmarkNode::Separator, parent); - // empty elements have a start and end element - readNext(); -} - -void XbelReader::readBookmarkNode(BookmarkNode *parent) -{ - Q_ASSERT(isStartElement() && name() == QLatin1String("bookmark")); - BookmarkNode *bookmark = new BookmarkNode(BookmarkNode::Bookmark, parent); - bookmark->url = attributes().value(QLatin1String("href")).toString(); - while (!atEnd()) { - readNext(); - if (isEndElement()) - break; - - if (isStartElement()) { - if (name() == QLatin1String("title")) - readTitle(bookmark); - else if (name() == QLatin1String("desc")) - readDescription(bookmark); - else - skipUnknownElement(); - } - } - if (bookmark->title.isEmpty()) - bookmark->title = QObject::tr("Unknown title"); -} - -void XbelReader::skipUnknownElement() -{ - Q_ASSERT(isStartElement()); - - while (!atEnd()) { - readNext(); - - if (isEndElement()) - break; - - if (isStartElement()) - skipUnknownElement(); - } -} - - -XbelWriter::XbelWriter() -{ - setAutoFormatting(true); -} - -bool XbelWriter::write(const QString &fileName, const BookmarkNode *root) -{ - QFile file(fileName); - if (!root || !file.open(QFile::WriteOnly)) - return false; - return write(&file, root); -} - -bool XbelWriter::write(QIODevice *device, const BookmarkNode *root) -{ - setDevice(device); - - writeStartDocument(); - writeDTD(QLatin1String("")); - writeStartElement(QLatin1String("xbel")); - writeAttribute(QLatin1String("version"), QLatin1String("1.0")); - if (root->type() == BookmarkNode::Root) { - for (int i = 0; i < root->children().count(); ++i) - writeItem(root->children().at(i)); - } else { - writeItem(root); - } - - writeEndDocument(); - return true; -} - -void XbelWriter::writeItem(const BookmarkNode *parent) -{ - switch (parent->type()) { - case BookmarkNode::Folder: - writeStartElement(QLatin1String("folder")); - writeAttribute(QLatin1String("folded"), parent->expanded ? QLatin1String("no") : QLatin1String("yes")); - writeTextElement(QLatin1String("title"), parent->title); - for (int i = 0; i < parent->children().count(); ++i) - writeItem(parent->children().at(i)); - writeEndElement(); - break; - case BookmarkNode::Bookmark: - writeStartElement(QLatin1String("bookmark")); - if (!parent->url.isEmpty()) - writeAttribute(QLatin1String("href"), parent->url); - writeTextElement(QLatin1String("title"), parent->title); - if (!parent->desc.isEmpty()) - writeAttribute(QLatin1String("desc"), parent->desc); - writeEndElement(); - break; - case BookmarkNode::Separator: - writeEmptyElement(QLatin1String("separator")); - break; - default: - break; - } -} - diff --git a/examples/gestures/browser/xbel.h b/examples/gestures/browser/xbel.h deleted file mode 100644 index 20cbda6..0000000 --- a/examples/gestures/browser/xbel.h +++ /dev/null @@ -1,113 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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$ -** -****************************************************************************/ - -#ifndef XBEL_H -#define XBEL_H - -#include -#include - -class BookmarkNode -{ -public: - enum Type { - Root, - Folder, - Bookmark, - Separator - }; - - BookmarkNode(Type type = Root, BookmarkNode *parent = 0); - ~BookmarkNode(); - bool operator==(const BookmarkNode &other); - - Type type() const; - void setType(Type type); - QList children() const; - BookmarkNode *parent() const; - - void add(BookmarkNode *child, int offset = -1); - void remove(BookmarkNode *child); - - QString url; - QString title; - QString desc; - bool expanded; - -private: - BookmarkNode *m_parent; - Type m_type; - QList m_children; - -}; - -class XbelReader : public QXmlStreamReader -{ -public: - XbelReader(); - BookmarkNode *read(const QString &fileName); - BookmarkNode *read(QIODevice *device); - -private: - void skipUnknownElement(); - void readXBEL(BookmarkNode *parent); - void readTitle(BookmarkNode *parent); - void readDescription(BookmarkNode *parent); - void readSeparator(BookmarkNode *parent); - void readFolder(BookmarkNode *parent); - void readBookmarkNode(BookmarkNode *parent); -}; - -#include - -class XbelWriter : public QXmlStreamWriter -{ -public: - XbelWriter(); - bool write(const QString &fileName, const BookmarkNode *root); - bool write(QIODevice *device, const BookmarkNode *root); - -private: - void writeItem(const BookmarkNode *parent); -}; - -#endif // XBEL_H - diff --git a/examples/gestures/collidingmice/collidingmice.pro b/examples/gestures/collidingmice/collidingmice.pro deleted file mode 100644 index 15164ce..0000000 --- a/examples/gestures/collidingmice/collidingmice.pro +++ /dev/null @@ -1,18 +0,0 @@ -HEADERS += \ - mouse.h \ - gesturerecognizerlinjazax.h \ - linjazaxgesture.h - -SOURCES += \ - main.cpp \ - mouse.cpp \ - gesturerecognizerlinjazax.cpp - -RESOURCES += \ - mice.qrc - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/gestures/collidingmice -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS collidingmice.pro images -sources.path = $$[QT_INSTALL_EXAMPLES]/gestures/collidingmice -INSTALLS += target sources diff --git a/examples/gestures/collidingmice/gesturerecognizerlinjazax.cpp b/examples/gestures/collidingmice/gesturerecognizerlinjazax.cpp deleted file mode 100644 index 2070f6f..0000000 --- a/examples/gestures/collidingmice/gesturerecognizerlinjazax.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 "gesturerecognizerlinjazax.h" - -#include -#include - -static const int SIZE = 20; - -DirectionSimpleRecognizer::DirectionSimpleRecognizer() -{ -} - -Direction DirectionSimpleRecognizer::addPosition(const QPoint &pos) -{ - if (!directions.isEmpty()) { - const QPoint tmp = pos - directions.back().point; - if (tmp.manhattanLength() < 5) - return Direction(); - } - if (lastPoint.isNull()) { - lastPoint = pos; - return Direction(); - } - int dx = pos.x() - lastPoint.x(); - int dy = pos.y() - lastPoint.y(); - QString direction; - if (dx < 0) { - if (-1*dx >= SIZE/2) - direction = "4"; - } else { - if (dx >= SIZE/2) - direction = "6"; - } - if (dy < 0) { - if (-1*dy >= SIZE/2) - direction = "8"; - } else { - if (dy >= SIZE/2) - direction = "2"; - } - if (direction.isEmpty()) - return Direction(); - - lastPoint = pos; - directions.push_back(Direction(direction, pos)); - return Direction(direction, pos); -} - - -DirectionList DirectionSimpleRecognizer::getDirections() const -{ - return directions; -} - -void DirectionSimpleRecognizer::reset() -{ - directions.clear(); - lastPoint = QPoint(); -} - -/////////////////////////////////////////////////////////////////////////// - -GestureRecognizerLinjaZax::GestureRecognizerLinjaZax() - : QGestureRecognizer(QLatin1String("LinjaZax")), mousePressed(false), gestureFinished(false), - zoomState(LinjaZaxGesture::NoZoom) -{ -} - -QGestureRecognizer::Result GestureRecognizerLinjaZax::filterEvent(const QEvent *event) -{ - if (zoomState != LinjaZaxGesture::NoZoom && !lastDirections.isEmpty()) { - lastDirections = lastDirections.right(1); - zoomState = LinjaZaxGesture::NoZoom; - } - - if (event->type() == QEvent::MouseButtonPress) { - if (!currentDirection.isEmpty()) { - reset(); - return QGestureRecognizer::NotGesture; - } - mousePressed = true; - const QMouseEvent *ev = static_cast(event); - pressedPos = lastPos = currentPos = ev->pos(); - return QGestureRecognizer::MaybeGesture; - } else if (event->type() == QEvent::MouseButtonRelease) { - const QMouseEvent *ev = static_cast(event); - if (mousePressed && !currentDirection.isEmpty()) { - gestureFinished = true; - currentPos = ev->pos(); - internalReset(); - return QGestureRecognizer::GestureFinished; - } - reset(); - return QGestureRecognizer::NotGesture; - } else if (event->type() == QEvent::MouseMove) { - if (!mousePressed) - return QGestureRecognizer::NotGesture; - lastPos = currentPos; - const QMouseEvent *ev = static_cast(event); - currentPos = ev->pos(); - QString direction = - simpleRecognizer.addPosition(ev->pos()).direction; - QGestureRecognizer::Result result = QGestureRecognizer::NotGesture; - if (currentDirection.isEmpty()) { - if (direction.isEmpty()) - result = QGestureRecognizer::MaybeGesture; - else - result = QGestureRecognizer::GestureStarted; - } else { - result = QGestureRecognizer::GestureStarted; - } - if (!direction.isEmpty()) { - lastDirections.append(direction); - currentDirection = direction; - if (lastDirections.length() > 5) - lastDirections.remove(0, 1); - if (lastDirections.contains("248") || lastDirections.contains("2448")) - zoomState = LinjaZaxGesture::ZoomingIn; - else if (lastDirections.contains("268") || lastDirections.contains("2668")) - zoomState = LinjaZaxGesture::ZoomingOut; - } - return result; - } - return QGestureRecognizer::NotGesture; -} - -static inline LinjaZaxGesture::DirectionType convertPanningDirection(const QString &direction) -{ - if (direction.length() == 1) { - if (direction == "4") - return LinjaZaxGesture::Left; - else if (direction == "6") - return LinjaZaxGesture::Right; - else if (direction == "8") - return LinjaZaxGesture::Up; - else if (direction == "2") - return LinjaZaxGesture::Down; - } - return LinjaZaxGesture::None; -} - -QGesture* GestureRecognizerLinjaZax::getGesture() -{ - LinjaZaxGesture::DirectionType dir = convertPanningDirection(currentDirection); - LinjaZaxGesture::DirectionType lastDir = convertPanningDirection(lastDirections.right(1)); - if (dir == LinjaZaxGesture::None) - return 0; - LinjaZaxGesture *g = - new LinjaZaxGesture(this, pressedPos, lastPos, currentPos, - QRect(), pressedPos, QDateTime(), 0, - gestureFinished ? Qt::GestureFinished : Qt::GestureStarted); - g->lastDirection_ = lastDir; - g->direction_ = dir; - g->zoomState_ = zoomState; - - return g; -} - -void GestureRecognizerLinjaZax::reset() -{ - mousePressed = false; - lastDirections.clear(); - currentDirection.clear(); - gestureFinished = false; - simpleRecognizer.reset(); - zoomState = LinjaZaxGesture::NoZoom; -} - -void GestureRecognizerLinjaZax::internalReset() -{ - mousePressed = false; - simpleRecognizer.reset(); -} diff --git a/examples/gestures/collidingmice/gesturerecognizerlinjazax.h b/examples/gestures/collidingmice/gesturerecognizerlinjazax.h deleted file mode 100644 index 79b2c2b..0000000 --- a/examples/gestures/collidingmice/gesturerecognizerlinjazax.h +++ /dev/null @@ -1,106 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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$ -** -****************************************************************************/ - -#ifndef GESTURERECOGNIZERLINJAZAX_H -#define GESTURERECOGNIZERLINJAZAX_H - -#include -#include -#include -#include -#include - -#include "linjazaxgesture.h" - -struct Direction -{ - QString direction; - QPoint point; - - Direction(QString dir, const QPoint &pt) - : direction(dir), point(pt) { } - Direction() - : direction() { } - - inline bool isEmpty() const { return direction.isEmpty(); } - inline bool isNull() const { return direction.isEmpty(); } -}; -typedef QList DirectionList; - -class DirectionSimpleRecognizer -{ -public: - DirectionSimpleRecognizer(); - Direction addPosition(const QPoint &pos); - DirectionList getDirections() const; - void reset(); - -private: - QPoint lastPoint; - DirectionList directions; -}; - -class GestureRecognizerLinjaZax : public QGestureRecognizer -{ - Q_OBJECT -public: - GestureRecognizerLinjaZax(); - - QGestureRecognizer::Result filterEvent(const QEvent *event); - QGesture* getGesture(); - - void reset(); - -private: - void internalReset(); - - QPoint pressedPos; - QPoint lastPos; - QPoint currentPos; - bool mousePressed; - bool gestureFinished; - QString lastDirections; - QString currentDirection; - DirectionSimpleRecognizer simpleRecognizer; - LinjaZaxGesture::ZoomState zoomState; -}; - -#endif diff --git a/examples/gestures/collidingmice/images/cheese.jpg b/examples/gestures/collidingmice/images/cheese.jpg deleted file mode 100644 index dea5795..0000000 Binary files a/examples/gestures/collidingmice/images/cheese.jpg and /dev/null differ diff --git a/examples/gestures/collidingmice/linjazaxgesture.h b/examples/gestures/collidingmice/linjazaxgesture.h deleted file mode 100644 index 53b907e..0000000 --- a/examples/gestures/collidingmice/linjazaxgesture.h +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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$ -** -****************************************************************************/ - -#ifndef LINJAZAXGESTURE_H -#define LINJAZAXGESTURE_H - -#include - -class LinjaZaxGesture : public QGesture -{ -public: - enum DirectionType - { - None = 0, - LeftDown = 1, - DownLeft = LeftDown, - Down = 2, - RightDown = 3, - DownRight = RightDown, - Left = 4, - Right = 6, - LeftUp = 7, - UpLeft = LeftUp, - Up = 8, - RightUp = 9, - UpRight = RightUp - }; - - enum ZoomState - { - NoZoom, - ZoomingIn, - ZoomingOut - }; - -public: - explicit LinjaZaxGesture(QObject *parent, - Qt::GestureState state = Qt::GestureStarted) - : QGesture(parent, QLatin1String("LinjaZax"), state), lastDirection_(None), - direction_(None), zoomState_(NoZoom) { } - LinjaZaxGesture(QObject *parent, const QPoint &startPos, - const QPoint &lastPos, const QPoint &pos, const QRect &rect, - const QPoint &hotSpot, const QDateTime &startTime, - uint duration, Qt::GestureState state) - : QGesture(parent, QLatin1String("LinjaZax"), startPos, lastPos, - pos, rect, hotSpot, startTime, duration, state) { } - ~LinjaZaxGesture() { } - - DirectionType lastDirection() const - { return lastDirection_; } - DirectionType direction() const - { return direction_; } - - ZoomState zoomState() const - { return zoomState_; } - -private: - DirectionType lastDirection_; - DirectionType direction_; - ZoomState zoomState_; - friend class GestureRecognizerLinjaZax; -}; - -#endif diff --git a/examples/gestures/collidingmice/main.cpp b/examples/gestures/collidingmice/main.cpp deleted file mode 100644 index 3638442..0000000 --- a/examples/gestures/collidingmice/main.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 "mouse.h" - -#include "gesturerecognizerlinjazax.h" -#include "linjazaxgesture.h" - -#include - -#include - -#define ZOOMING_ANIMATION -#ifdef ZOOMING_ANIMATION -static const int AnimationSteps = 10; -#endif - -static const int MouseCount = 7; - -class PannableGraphicsView : public QGraphicsView -{ - Q_OBJECT -public: - PannableGraphicsView(QGraphicsScene *scene, QWidget *parent = 0) - : QGraphicsView(scene, parent) - { - grabGesture(QLatin1String("LinjaZax")); -#ifdef ZOOMING_ANIMATION - timeline = new QTimeLine(700, this); - timeline->setFrameRange(0, AnimationSteps); - connect(timeline, SIGNAL(frameChanged(int)), this, SLOT(animationStep(int))); -#endif - } -protected: - bool event(QEvent *event) - { - if (event->type() == QEvent::Gesture) { - QGestureEvent *ge = static_cast(event); - const LinjaZaxGesture *g = static_cast(ge->gesture("LinjaZax")); - if (g) { - switch (g->zoomState()) { - case LinjaZaxGesture::ZoomingIn: -#ifdef ZOOMING_ANIMATION - scaleStep = 1. + 0.5/AnimationSteps; - timeline->stop(); - timeline->start(); -#else - scale(1.5, 1.5); -#endif - break; - case LinjaZaxGesture::ZoomingOut: -#ifdef ZOOMING_ANIMATION - scaleStep = 1. - 0.5/AnimationSteps; - timeline->stop(); - timeline->start(); -#else - scale(0.6, 0.6); -#endif - break; - default: - break; - }; - QPoint pt = g->pos() - g->lastPos(); - horizontalScrollBar()->setValue(horizontalScrollBar()->value() - pt.x()); - verticalScrollBar()->setValue(verticalScrollBar()->value() - pt.y()); - event->accept(); - return true; - } - } - return QGraphicsView::event(event); - } -private slots: -#ifdef ZOOMING_ANIMATION - void animationStep(int step) - { - scale(scaleStep, scaleStep); - } -private: - qreal scaleStep; - QTimeLine *timeline; -#endif -}; - -//! [0] -int main(int argc, char **argv) -{ - QApplication app(argc, argv); - app.addGestureRecognizer(new GestureRecognizerLinjaZax); - qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); -//! [0] - -//! [1] - QGraphicsScene scene; - scene.setSceneRect(-600, -600, 1200, 1200); -//! [1] //! [2] - scene.setItemIndexMethod(QGraphicsScene::NoIndex); -//! [2] - -//! [3] - for (int i = 0; i < MouseCount; ++i) { - Mouse *mouse = new Mouse; - mouse->setPos(::sin((i * 6.28) / MouseCount) * 200, - ::cos((i * 6.28) / MouseCount) * 200); - scene.addItem(mouse); - } -//! [3] - -//! [4] - PannableGraphicsView view(&scene); - view.setRenderHint(QPainter::Antialiasing); - view.setBackgroundBrush(QPixmap(":/images/cheese.jpg")); -//! [4] //! [5] - view.setCacheMode(QGraphicsView::CacheBackground); - view.setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); - //view.setDragMode(QGraphicsView::ScrollHandDrag); -//! [5] //! [6] - view.setWindowTitle(QT_TRANSLATE_NOOP(QGraphicsView, "Colliding Mice")); - view.resize(400, 300); - view.show(); - - return app.exec(); -} -//! [6] - -#include "main.moc" diff --git a/examples/gestures/collidingmice/mice.qrc b/examples/gestures/collidingmice/mice.qrc deleted file mode 100644 index accdb4d..0000000 --- a/examples/gestures/collidingmice/mice.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - images/cheese.jpg - - diff --git a/examples/gestures/collidingmice/mouse.cpp b/examples/gestures/collidingmice/mouse.cpp deleted file mode 100644 index 256811a..0000000 --- a/examples/gestures/collidingmice/mouse.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 "mouse.h" - -#include -#include -#include - -#include - -static const double Pi = 3.14159265358979323846264338327950288419717; -static double TwoPi = 2.0 * Pi; - -static qreal normalizeAngle(qreal angle) -{ - while (angle < 0) - angle += TwoPi; - while (angle > TwoPi) - angle -= TwoPi; - return angle; -} - -//! [0] -Mouse::Mouse() - : angle(0), speed(0), mouseEyeDirection(0), - color(qrand() % 256, qrand() % 256, qrand() % 256) -{ - rotate(qrand() % (360 * 16)); - startTimer(1000 / 33); -} -//! [0] - -//! [1] -QRectF Mouse::boundingRect() const -{ - qreal adjust = 0.5; - return QRectF(-18 - adjust, -22 - adjust, - 36 + adjust, 60 + adjust); -} -//! [1] - -//! [2] -QPainterPath Mouse::shape() const -{ - QPainterPath path; - path.addRect(-10, -20, 20, 40); - return path; -} -//! [2] - -//! [3] -void Mouse::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) -{ - // Body - painter->setBrush(color); - painter->drawEllipse(-10, -20, 20, 40); - - // Eyes - painter->setBrush(Qt::white); - painter->drawEllipse(-10, -17, 8, 8); - painter->drawEllipse(2, -17, 8, 8); - - // Nose - painter->setBrush(Qt::black); - painter->drawEllipse(QRectF(-2, -22, 4, 4)); - - // Pupils - painter->drawEllipse(QRectF(-8.0 + mouseEyeDirection, -17, 4, 4)); - painter->drawEllipse(QRectF(4.0 + mouseEyeDirection, -17, 4, 4)); - - // Ears - painter->setBrush(scene()->collidingItems(this).isEmpty() ? Qt::darkYellow : Qt::red); - painter->drawEllipse(-17, -12, 16, 16); - painter->drawEllipse(1, -12, 16, 16); - - // Tail - QPainterPath path(QPointF(0, 20)); - path.cubicTo(-5, 22, -5, 22, 0, 25); - path.cubicTo(5, 27, 5, 32, 0, 30); - path.cubicTo(-5, 32, -5, 42, 0, 35); - painter->setBrush(Qt::NoBrush); - painter->drawPath(path); -} -//! [3] - -//! [4] -void Mouse::timerEvent(QTimerEvent *) -{ -//! [4] - // Don't move too far away -//! [5] - QLineF lineToCenter(QPointF(0, 0), mapFromScene(0, 0)); - if (lineToCenter.length() > 150) { - qreal angleToCenter = ::acos(lineToCenter.dx() / lineToCenter.length()); - if (lineToCenter.dy() < 0) - angleToCenter = TwoPi - angleToCenter; - angleToCenter = normalizeAngle((Pi - angleToCenter) + Pi / 2); - - if (angleToCenter < Pi && angleToCenter > Pi / 4) { - // Rotate left - angle += (angle < -Pi / 2) ? 0.25 : -0.25; - } else if (angleToCenter >= Pi && angleToCenter < (Pi + Pi / 2 + Pi / 4)) { - // Rotate right - angle += (angle < Pi / 2) ? 0.25 : -0.25; - } - } else if (::sin(angle) < 0) { - angle += 0.25; - } else if (::sin(angle) > 0) { - angle -= 0.25; -//! [5] //! [6] - } -//! [6] - - // Try not to crash with any other mice -//! [7] - QList dangerMice = scene()->items(QPolygonF() - << mapToScene(0, 0) - << mapToScene(-30, -50) - << mapToScene(30, -50)); - foreach (QGraphicsItem *item, dangerMice) { - if (item == this) - continue; - - QLineF lineToMouse(QPointF(0, 0), mapFromItem(item, 0, 0)); - qreal angleToMouse = ::acos(lineToMouse.dx() / lineToMouse.length()); - if (lineToMouse.dy() < 0) - angleToMouse = TwoPi - angleToMouse; - angleToMouse = normalizeAngle((Pi - angleToMouse) + Pi / 2); - - if (angleToMouse >= 0 && angleToMouse < Pi / 2) { - // Rotate right - angle += 0.5; - } else if (angleToMouse <= TwoPi && angleToMouse > (TwoPi - Pi / 2)) { - // Rotate left - angle -= 0.5; -//! [7] //! [8] - } -//! [8] //! [9] - } -//! [9] - - // Add some random movement -//! [10] - if (dangerMice.size() > 1 && (qrand() % 10) == 0) { - if (qrand() % 1) - angle += (qrand() % 100) / 500.0; - else - angle -= (qrand() % 100) / 500.0; - } -//! [10] - -//! [11] - speed += (-50 + qrand() % 100) / 100.0; - - qreal dx = ::sin(angle) * 10; - mouseEyeDirection = (qAbs(dx / 5) < 1) ? 0 : dx / 5; - - rotate(dx); - setPos(mapToParent(0, -(3 + sin(speed) * 3))); -} -//! [11] diff --git a/examples/gestures/collidingmice/mouse.h b/examples/gestures/collidingmice/mouse.h deleted file mode 100644 index 6c8486f..0000000 --- a/examples/gestures/collidingmice/mouse.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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$ -** -****************************************************************************/ - -#ifndef MOUSE_H -#define MOUSE_H - -#include -#include - -//! [0] -class Mouse : public QObject, public QGraphicsItem -{ - Q_OBJECT - -public: - Mouse(); - - QRectF boundingRect() const; - QPainterPath shape() const; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, - QWidget *widget); - -protected: - void timerEvent(QTimerEvent *event); - -private: - qreal angle; - qreal speed; - qreal mouseEyeDirection; - QColor color; -}; -//! [0] - -#endif diff --git a/examples/gestures/gestures.pro b/examples/gestures/gestures.pro index d0735ae..09cd56a 100644 --- a/examples/gestures/gestures.pro +++ b/examples/gestures/gestures.pro @@ -1,14 +1,7 @@ TEMPLATE = \ subdirs SUBDIRS = \ - imageviewer \ - graphicsview \ - collidingmice - -contains(QT_CONFIG, webkit) { - SUBDIRS += pannablewebview - contains(QT_CONFIG, svg):SUBDIRS += browser -} + imageviewer # install target.path = $$[QT_INSTALL_EXAMPLES]/gestures diff --git a/examples/gestures/graphicsview/graphicsview.pro b/examples/gestures/graphicsview/graphicsview.pro deleted file mode 100644 index 9cef564..0000000 --- a/examples/gestures/graphicsview/graphicsview.pro +++ /dev/null @@ -1,2 +0,0 @@ -SOURCES = main.cpp - diff --git a/examples/gestures/graphicsview/main.cpp b/examples/gestures/graphicsview/main.cpp deleted file mode 100644 index 12f4e75..0000000 --- a/examples/gestures/graphicsview/main.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 - -class PannableGraphicsView : public QGraphicsView -{ -public: - PannableGraphicsView() - { - grabGesture(Qt::PanGesture); - } -protected: - bool event(QEvent *event) - { - if (event->type() == QEvent::Gesture) { - QGestureEvent *gestureEvent = static_cast(event); - if (const QGesture *g = gestureEvent->gesture(Qt::PanGesture)) { - QPoint pt = g->pos() - g->lastPos(); - horizontalScrollBar()->setValue(horizontalScrollBar()->value() - pt.x()); - verticalScrollBar()->setValue(verticalScrollBar()->value() - pt.y()); - event->accept(); - return true; - } - } - return QGraphicsView::event(event); - } -}; - -class ImageItem : public QGraphicsItem -{ -public: - ImageItem() - : colored(false) - { - grabGesture(Qt::DoubleTapGesture); - } - - QRectF boundingRect() const - { - return pixmap.isNull() ? QRectF(0, 0, 100, 100) - : QRectF(QPointF(0,0), QSizeF(pixmap.size())); - } - - void paint(QPainter *painter, const QStyleOptionGraphicsItem*, QWidget*) - { - if (pixmap.isNull()) { - painter->setBrush(QBrush( colored ? Qt::green : Qt::white)); - painter->drawRect(0, 0, 100, 100); - painter->drawLine(0, 0, 100, 100); - painter->drawLine(0, 100, 100, 0); - return; - } - painter->drawPixmap(0, 0, pixmap); - } - - bool sceneEvent(QEvent *event) - { - if (event->type() == QEvent::GraphicsSceneGesture) { - QGraphicsSceneGestureEvent *gestureEvent = static_cast(event); - if (gestureEvent->gesture(Qt::DoubleTapGesture)) { - event->accept(); - colored = !colored; - update(); - return true; - } else { - qWarning("Item received unknown gesture"); - } - } - return QGraphicsItem::sceneEvent(event); - } - -private: - QPixmap pixmap; - bool colored; -}; - -class MainWidget : public QWidget -{ - Q_OBJECT - -public: - MainWidget(QWidget *parent = 0) - : QWidget(parent) - { - QVBoxLayout *l = new QVBoxLayout(this); - view = new PannableGraphicsView; - l->addWidget(view); - scene = new QGraphicsScene(0, 0, 1024, 768, view); - view->setScene(scene); - - ImageItem *item = new ImageItem; - scene->addItem(item); - item->setPos(scene->width()/3, scene->height()/3); - } - -signals: -public slots: -private: - QGraphicsView *view; - QGraphicsScene *scene; -}; - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - MainWidget w; - w.show(); - return app.exec(); -} - -#include "main.moc" diff --git a/examples/gestures/imageviewer/imagewidget.cpp b/examples/gestures/imageviewer/imagewidget.cpp index a4f3c9a..717bb09 100644 --- a/examples/gestures/imageviewer/imagewidget.cpp +++ b/examples/gestures/imageviewer/imagewidget.cpp @@ -46,6 +46,7 @@ ImageWidget::ImageWidget(QWidget *parent) : QWidget(parent) { + setAttribute(Qt::WA_AcceptTouchEvents); setAttribute(Qt::WA_PaintOnScreen); setAttribute(Qt::WA_OpaquePaintEvent); setAttribute(Qt::WA_NoSystemBackground); @@ -61,9 +62,11 @@ ImageWidget::ImageWidget(QWidget *parent) horizontalOffset = 0; verticalOffset = 0; - grabGesture(Qt::DoubleTapGesture); - grabGesture(Qt::PanGesture); - grabGesture(Qt::TapAndHoldGesture); + panGesture = new QPanGesture(this); + connect(panGesture, SIGNAL(triggered()), this, SLOT(gestureTriggered())); + + tapAndHoldGesture = new QTapAndHoldGesture(this); + connect(tapAndHoldGesture, SIGNAL(triggered()), this, SLOT(gestureTriggered())); } void ImageWidget::paintEvent(QPaintEvent*) @@ -131,30 +134,33 @@ void ImageWidget::paintEvent(QPaintEvent*) p.restore(); } -bool ImageWidget::event(QEvent *event) +void ImageWidget::mousePressEvent(QMouseEvent *event) { - if (event->type() == QEvent::Gesture) { - gestureEvent(static_cast(event)); - return true; - } - return QWidget::event(event); + touchFeedback.tapped = true; + touchFeedback.position = event->pos(); +} + +void ImageWidget::mouseDoubleClickEvent(QMouseEvent *event) +{ + touchFeedback.doubleTapped = true; + const QPoint p = event->pos(); + touchFeedback.position = p; + horizontalOffset = p.x() - currentImage.width()*1.0*p.x()/width(); + verticalOffset = p.y() - currentImage.height()*1.0*p.y()/height(); + setZoomedIn(!zoomedIn); + zoomed = rotated = false; + updateImage(); + + feedbackFadeOutTimer.start(500, this); } -void ImageWidget::gestureEvent(QGestureEvent *event) +void ImageWidget::gestureTriggered() { + touchFeedback.tapped = false; touchFeedback.doubleTapped = false; - Q_ASSERT(event); - if (event->contains(Qt::TapGesture)) { - // - } else if (const QGesture *g = event->gesture(Qt::DoubleTapGesture)) { - touchFeedback.doubleTapped = true; - horizontalOffset = g->hotSpot().x() - currentImage.width()*1.0*g->hotSpot().x()/width(); - verticalOffset = g->hotSpot().y() - currentImage.height()*1.0*g->hotSpot().y()/height(); - setZoomedIn(!zoomedIn); - zoomed = rotated = false; - updateImage(); - } else if (const QGesture *g = event->gesture(Qt::PanGesture)) { + QGesture *g = qobject_cast(sender()); + if (sender() == panGesture) { if (zoomedIn) { // usual panning #ifndef QT_NO_CURSOR @@ -170,24 +176,22 @@ void ImageWidget::gestureEvent(QGestureEvent *event) update(); } else { // only slide gesture should be accepted - const QPanningGesture *pg = static_cast(g); - if (pg->direction() != pg->lastDirection()) { - // ###: event->cancel(); - } + const QPanGesture *pg = static_cast(g); if (g->state() == Qt::GestureFinished) { touchFeedback.sliding = false; zoomed = rotated = false; - if (pg->direction() == Qt::RightDirection) { + if (pg->totalOffset().width() > 0) { qDebug() << "slide right"; goNextImage(); - } else if (pg->direction() == Qt::LeftDirection) { + } else { qDebug() << "slide left"; goPrevImage(); } updateImage(); } } - } else if (const QGesture *g = event->gesture(Qt::TapAndHoldGesture)) { + feedbackFadeOutTimer.start(500, this); + } else if (sender() == tapAndHoldGesture) { if (g->state() == Qt::GestureFinished) { qDebug() << "tap and hold detected"; touchFeedback.reset(); @@ -197,13 +201,20 @@ void ImageWidget::gestureEvent(QGestureEvent *event) menu.addAction("Action 1"); menu.addAction("Action 2"); menu.addAction("Action 3"); - menu.exec(mapToGlobal(g->hotSpot())); + menu.exec(mapToGlobal(g->pos())); } - } else { - qDebug() << "unknown gesture"; + feedbackFadeOutTimer.start(500, this); } - feedbackFadeOutTimer.start(500, this); - event->accept(); +} + +void ImageWidget::gestureFinished() +{ + qDebug() << "gesture finished" << sender(); +} + +void ImageWidget::gestureCancelled() +{ + qDebug() << "gesture cancelled" << sender(); } void ImageWidget::resizeEvent(QResizeEvent*) @@ -345,3 +356,5 @@ void ImageWidget::timerEvent(QTimerEvent *event) } update(); } + +#include "moc_imagewidget.cpp" diff --git a/examples/gestures/imageviewer/imagewidget.h b/examples/gestures/imageviewer/imagewidget.h index 7ec73a7..e12634d 100644 --- a/examples/gestures/imageviewer/imagewidget.h +++ b/examples/gestures/imageviewer/imagewidget.h @@ -50,17 +50,24 @@ class ImageWidget : public QWidget { + Q_OBJECT + public: ImageWidget(QWidget *parent = 0); void openDirectory(const QString &path); protected: - bool event(QEvent *event); void paintEvent(QPaintEvent*); - void gestureEvent(QGestureEvent *event); void resizeEvent(QResizeEvent*); void timerEvent(QTimerEvent*); + void mousePressEvent(QMouseEvent*); + void mouseDoubleClickEvent(QMouseEvent*); + +private slots: + void gestureTriggered(); + void gestureFinished(); + void gestureCancelled(); private: void updateImage(); @@ -71,6 +78,9 @@ private: void goPrevImage(); void goToImage(int index); + QPanGesture *panGesture; + QTapAndHoldGesture *tapAndHoldGesture; + QString path; QStringList files; int position; diff --git a/examples/gestures/pannablewebview/main.cpp b/examples/gestures/pannablewebview/main.cpp deleted file mode 100644 index 89c1fce..0000000 --- a/examples/gestures/pannablewebview/main.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples 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 -#include - -class PannableWebView : public QWebView -{ -public: - PannableWebView(QWidget *parent = 0) - : QWebView(parent) - { -#if 0 - QPushButton *btn = new QPushButton("Some test button", this); - btn->resize(300, 200); - btn->move(40, 300); -#endif - grabGesture(Qt::PanGesture); - } -protected: - bool event(QEvent *event) - { - if (event->type() == QEvent::Gesture) - { - QGestureEvent *ev = static_cast(event); - if (const QGesture *g = ev->gesture(Qt::PanGesture)) { - if (QWebFrame *frame = page()->mainFrame()) { - QPoint offset = g->pos() - g->lastPos(); - frame->setScrollPosition(frame->scrollPosition() - offset); - } - event->accept(); - } - return true; - } - return QWebView::event(event); - } -}; - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - QGraphicsScene scene; - QGraphicsView w(&scene); - - QWebView *wv = new PannableWebView; - wv->resize(480, 800); - wv->setUrl(QUrl("http://www.trolltech.com")); - scene.addWidget(wv); - w.show(); - - return app.exec(); -} diff --git a/examples/gestures/pannablewebview/pannablewebview.pro b/examples/gestures/pannablewebview/pannablewebview.pro deleted file mode 100644 index 07d8f91..0000000 --- a/examples/gestures/pannablewebview/pannablewebview.pro +++ /dev/null @@ -1,4 +0,0 @@ -SOURCES += \ - main.cpp - -QT += webkit diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 0006026..e0584e5 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1562,18 +1562,6 @@ public: }; Q_DECLARE_FLAGS(TouchPointStates, TouchPointState) - enum GestureType - { - UnknownGesture, - TapGesture, - DoubleTapGesture, - TrippleTapGesture, - TapAndHoldGesture, - PanGesture, - PinchGesture - }; - - enum GestureState { NoGesture, @@ -1582,23 +1570,6 @@ public: GestureFinished = 3 }; - enum DirectionType - { - NoDirection = 0, - LeftDownDirection = 1, - DownLeftDirection = LeftDownDirection, - DownDirection = 2, - RightDownDirection = 3, - DownRightDirection = RightDownDirection, - LeftDirection = 4, - RightDirection = 6, - LeftUpDirection = 7, - UpLeftDirection = LeftUpDirection, - UpDirection = 8, - RightUpDirection = 9, - UpRightDirection = RightUpDirection - }; - } #ifdef Q_MOC_RUN ; diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index 504ae84..c636716 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -225,8 +225,6 @@ QT_BEGIN_NAMESPACE \value TouchBegin Beginning of a sequence of touch-screen and/or track-pad events (QTouchEvent) \value TouchUpdate Touch-screen event (QTouchEvent) \value TouchEnd End of touch-event sequence (QTouchEvent) - \value Gesture A gesture has occured. - \value GraphicsSceneGesture A gesture has occured on a graphics scene. User events should have values between \c User and \c{MaxUser}: @@ -271,6 +269,7 @@ QT_BEGIN_NAMESPACE \omitvalue CocoaRequestModal \omitvalue Wrapped \omitvalue Signal + \omitvalue WinGesture */ /*! diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h index 4929c51..1d86f47 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -276,8 +276,7 @@ public: TouchUpdate = 195, TouchEnd = 196, - Gesture = 197, - GraphicsSceneGesture = 198, + WinGesture = 197, // 512 reserved for Qt Jambi's MetaCall event // 513 reserved for Qt Jambi's DeleteOnMainThread event diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 2223f5d..c82c2e5 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -574,7 +574,6 @@ #include #include #include -#include #ifdef Q_WS_X11 #include @@ -615,8 +614,6 @@ public: }; Q_GLOBAL_STATIC(QGraphicsItemCustomDataStore, qt_dataStore) -QString qt_getStandardGestureTypeName(Qt::GestureType type); - /*! \internal @@ -1131,7 +1128,6 @@ QGraphicsItem::~QGraphicsItem() { d_ptr->inDestructor = 1; d_ptr->removeExtraItemCache(); - d_ptr->removeExtraGestures(); clearFocus(); if (!d_ptr->children.isEmpty()) { @@ -6251,104 +6247,6 @@ QVariant QGraphicsItem::inputMethodQuery(Qt::InputMethodQuery query) const } /*! - \since 4.6 - - Subscribes the graphics item to the specified \a gesture type. - - Returns the id of the gesture. - - \sa releaseGesture(), setGestureEnabled() -*/ -int QGraphicsItem::grabGesture(Qt::GestureType gesture) -{ - /// TODO: if we are QGraphicsProxyWidget we should subscribe the widget to gesture as well. - return grabGesture(qt_getStandardGestureTypeName(gesture)); -} - -/*! - \since 4.6 - - Subscribes the graphics item to the specified \a gesture type. - - Returns the id of the gesture. - - \sa releaseGesture(), setGestureEnabled() -*/ -int QGraphicsItem::grabGesture(const QString &gesture) -{ - int id = QGestureManager::instance()->makeGestureId(gesture); - d_ptr->grabGesture(id); - return id; -} - -void QGraphicsItemPrivate::grabGesture(int id) -{ - Q_Q(QGraphicsItem); - extraGestures()->gestures << id; - if (scene) - scene->d_func()->grabGesture(q, id); -} - -bool QGraphicsItemPrivate::releaseGesture(int id) -{ - Q_Q(QGraphicsItem); - QGestureExtraData *extra = maybeExtraGestures(); - if (extra && extra->gestures.contains(id)) { - if (scene) - scene->d_func()->releaseGesture(q, id); - extra->gestures.remove(id); - return true; - } - return false; -} - -/*! - \since 4.6 - - Unsubscribes the graphics item from a gesture, which is specified - by the \a gestureId. - - \sa grabGesture(), setGestureEnabled() -*/ -void QGraphicsItem::releaseGesture(int gestureId) -{ - /// TODO: if we are QGraphicsProxyWidget we should unsubscribe the widget from gesture as well. - if (d_ptr->releaseGesture(gestureId)) - QGestureManager::instance()->releaseGestureId(gestureId); -} - -/*! - \since 4.6 - - If \a enable is true, the gesture with the given \a gestureId is - enabled; otherwise the gesture is disabled. - - The id of the gesture is returned by the grabGesture(). - - \sa grabGesture(), releaseGesture() -*/ -void QGraphicsItem::setGestureEnabled(int gestureId, bool enable) -{ - Q_UNUSED(gestureId); - Q_UNUSED(enable); - //### -} - -bool QGraphicsItemPrivate::hasGesture(const QString &name) const -{ - if (QGestureExtraData *extra = maybeExtraGestures()) { - QGestureManager *gm = QGestureManager::instance(); - QSet::const_iterator it = extra->gestures.begin(), - e = extra->gestures.end(); - for (; it != e; ++it) { - if (gm->gestureNameFromId(*it) == name) - return true; - } - } - return false; -} - -/*! This virtual function is called by QGraphicsItem to notify custom items that some part of the item's state changes. By reimplementing this function, your can react to a change, and in some cases, (depending on \a @@ -6372,23 +6270,6 @@ bool QGraphicsItemPrivate::hasGesture(const QString &name) const QVariant QGraphicsItem::itemChange(GraphicsItemChange change, const QVariant &value) { Q_UNUSED(change); - if (change == QGraphicsItem::ItemSceneChange) { - QGestureExtraData *extra = d_ptr->maybeExtraGestures(); - if (!qVariantValue(value) && extra) { - // the item has been removed from a scene, unsubscribe gestures. - Q_ASSERT(d_ptr->scene); - foreach(int id, extra->gestures) - d_ptr->scene->d_func()->releaseGesture(this, id); - } - } else if (change == QGraphicsItem::ItemSceneHasChanged) { - QGraphicsScene *scene = qVariantValue(value); - QGestureExtraData *extra = d_ptr->maybeExtraGestures(); - if (scene && extra) { - // item has been added to the scene - foreach(int id, extra->gestures) - scene->d_func()->grabGesture(this, id); - } - } return value; } diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index 3a3d1a1..b0571c2 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -379,11 +379,6 @@ public: QVariant data(int key) const; void setData(int key, const QVariant &value); - int grabGesture(Qt::GestureType gesture); - int grabGesture(const QString &gesture); - void releaseGesture(int gestureId); - void setGestureEnabled(int gestureId, bool enable = true); - enum { Type = 1, UserType = 65536 diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index a0d061b..a977e1e 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -93,12 +93,6 @@ public: void purge(); }; -class QGestureExtraData -{ -public: - QSet gestures; -}; - class Q_AUTOTEST_EXPORT QGraphicsItemPrivate { Q_DECLARE_PUBLIC(QGraphicsItem) @@ -108,8 +102,7 @@ public: ExtraCursor, ExtraCacheData, ExtraMaxDeviceCoordCacheSize, - ExtraBoundingRegionGranularity, - ExtraGestures + ExtraBoundingRegionGranularity }; enum AncestorFlag { @@ -394,30 +387,6 @@ public: int index; int depth; - inline QGestureExtraData* extraGestures() const - { - QGestureExtraData *c = (QGestureExtraData *)qVariantValue(extra(ExtraGestures)); - if (!c) { - QGraphicsItemPrivate *that = const_cast(this); - c = new QGestureExtraData; - that->setExtra(ExtraGestures, qVariantFromValue(c)); - } - return c; - } - QGestureExtraData* maybeExtraGestures() const - { - return (QGestureExtraData *)qVariantValue(extra(ExtraGestures)); - } - inline void removeExtraGestures() - { - QGestureExtraData *c = (QGestureExtraData *)qVariantValue(extra(ExtraGestures)); - delete c; - unsetExtra(ExtraGestures); - } - bool hasGesture(const QString &gesture) const; - void grabGesture(int id); - bool releaseGesture(int id); - // Packed 32 bytes quint32 acceptedMouseButtons : 5; quint32 visible : 1; diff --git a/src/gui/graphicsview/qgraphicsproxywidget.cpp b/src/gui/graphicsview/qgraphicsproxywidget.cpp index f081222..0b421ad 100644 --- a/src/gui/graphicsview/qgraphicsproxywidget.cpp +++ b/src/gui/graphicsview/qgraphicsproxywidget.cpp @@ -48,7 +48,6 @@ #include "private/qgraphicsproxywidget_p.h" #include "private/qwidget_p.h" #include "private/qapplication_p.h" -#include "private/qgesturemanager_p.h" #include #include @@ -649,9 +648,6 @@ void QGraphicsProxyWidgetPrivate::setWidget_helper(QWidget *newWidget, bool auto q->setAttribute(Qt::WA_OpaquePaintEvent); widget = newWidget; - foreach(int gestureId, widget->d_func()->gestures) { - grabGesture(gestureId); - } // Changes only go from the widget to the proxy. enabledChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode; @@ -875,15 +871,6 @@ bool QGraphicsProxyWidget::event(QEvent *event) } break; } - case QEvent::GraphicsSceneGesture: { - qDebug() << "QGraphicsProxyWidget: graphicsscenegesture"; - if (d->widget && d->widget->isVisible()) { - //### TODO: widget->childAt(): decompose gesture event and find widget under hotspots. - //QGestureManager::instance()->sendGestureEvent(d->widget, ge->gestures().toSet(), ge->cancelledGestures()); - return true; - } - break; - } default: break; } diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index e50ee94..c3f72e6 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -247,8 +247,6 @@ #ifdef Q_WS_X11 #include #endif -#include -#include QT_BEGIN_NAMESPACE @@ -4018,47 +4016,6 @@ bool QGraphicsScene::event(QEvent *event) // geometries that do not have an explicit style set. update(); break; - case QEvent::GraphicsSceneGesture: { - QGraphicsSceneGestureEvent *ev = static_cast(event); - QGraphicsView *view = qobject_cast(ev->widget()); - if (!view) { - qWarning("QGraphicsScene::event: gesture event was received without a view"); - break; - } - - // get a list of gestures that just started. - QSet startedGestures; - QList gestures = ev->gestures(); - for(QList::const_iterator it = gestures.begin(), e = gestures.end(); - it != e; ++it) { - QGesture *g = *it; - QGesturePrivate *gd = g->d_func(); - if (g->state() == Qt::GestureStarted || gd->singleshot) { - startedGestures.insert(g); - } - } - if (!startedGestures.isEmpty()) { - // find a target for each started gesture. - for(QSet::const_iterator it = startedGestures.begin(), e = startedGestures.end(); - it != e; ++it) { - QGesture *g = *it; - QGesturePrivate *gd = g->d_func(); - gd->graphicsItem = 0; - QList itemsInGestureArea = items(g->hotSpot()); - const QString gestureName = g->type(); - foreach(QGraphicsItem *item, itemsInGestureArea) { - if (item->d_func()->hasGesture(gestureName)) { - Q_ASSERT(gd->graphicsItem == 0); - gd->graphicsItem = item; - d->itemsWithGestures[item].insert(g); - break; - } - } - } - } - d->sendGestureEvent(ev->gestures().toSet(), ev->cancelledGestures()); - } - break; case QEvent::TouchBegin: case QEvent::TouchUpdate: case QEvent::TouchEnd: @@ -4080,69 +4037,6 @@ bool QGraphicsScene::event(QEvent *event) return true; } -void QGraphicsScenePrivate::sendGestureEvent(const QSet &gestures, const QSet &cancelled) -{ - Q_Q(QGraphicsScene); - typedef QMap > ItemGesturesMap; - ItemGesturesMap itemGestures; - QSet startedGestures; - for(QSet::const_iterator it = gestures.begin(), e = gestures.end(); - it != e; ++it) { - QGesture *g = *it; - Q_ASSERT(g != 0); - QGesturePrivate *gd = g->d_func(); - if (gd->graphicsItem != 0) { - itemGestures[gd->graphicsItem].insert(g); - if (g->state() == Qt::GestureStarted || gd->singleshot) - startedGestures.insert(g); - } - } - - QSet ignoredGestures; - for(ItemGesturesMap::const_iterator it = itemGestures.begin(), e = itemGestures.end(); - it != e; ++it) { - QGraphicsItem *receiver = it.key(); - Q_ASSERT(receiver != 0); - QGraphicsSceneGestureEvent event; - event.setGestures(it.value()); - event.setCancelledGestures(cancelled); - bool processed = sendEvent(receiver, &event); - QSet started = startedGestures.intersect(it.value()); - if (event.isAccepted()) - foreach(QGesture *g, started) - g->accept(); - if (!started.isEmpty() && !(processed && event.isAccepted())) { - // there are started gestures event that weren't - // accepted, so propagating each gesture independently. - QSet::const_iterator it = started.begin(), - e = started.end(); - for(; it != e; ++it) { - QGesture *g = *it; - if (processed && g->isAccepted()) { - continue; - } - QGesturePrivate *gd = g->d_func(); - gd->graphicsItem = 0; - - //### THIS IS BS, DONT FORGET TO REWRITE THIS CODE - // need to make sure we try to deliver event just once to each widget - const QString gestureType = g->type(); - QList itemsUnderGesture = q->items(g->hotSpot()); - for (int i = 0; i < itemsUnderGesture.size(); ++i) { - QGraphicsItem *item = itemsUnderGesture.at(i); - if (item != receiver && item->d_func()->hasGesture(gestureType)) { - ignoredGestures.insert(g); - gd->graphicsItem = item; - break; - } - } - } - } - } - if (!ignoredGestures.isEmpty()) - sendGestureEvent(ignoredGestures, cancelled); -} - /*! \reimp @@ -6018,32 +5912,11 @@ bool QGraphicsScene::sendEvent(QGraphicsItem *item, QEvent *event) void QGraphicsScenePrivate::addView(QGraphicsView *view) { views << view; - foreach(int gestureId, grabbedGestures) - view->d_func()->grabGesture(gestureId); } void QGraphicsScenePrivate::removeView(QGraphicsView *view) { views.removeAll(view); - foreach(int gestureId, grabbedGestures) - view->releaseGesture(gestureId); -} - -void QGraphicsScenePrivate::grabGesture(QGraphicsItem *item, int gestureId) -{ - if (!grabbedGestures.contains(gestureId)) { - foreach(QGraphicsView *view, views) - view->d_func()->grabGesture(gestureId); - } - (void)itemsWithGestures[item]; - grabbedGestures << gestureId; -} - -void QGraphicsScenePrivate::releaseGesture(QGraphicsItem *item, int gestureId) -{ - Q_UNUSED(gestureId); - itemsWithGestures.remove(item); - //### } void QGraphicsScenePrivate::updateTouchPointsForItem(QGraphicsItem *item, QTouchEvent *touchEvent) diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h index c8b147f..6aaeb91 100644 --- a/src/gui/graphicsview/qgraphicsscene.h +++ b/src/gui/graphicsview/qgraphicsscene.h @@ -79,7 +79,6 @@ class QGraphicsSceneHelpEvent; class QGraphicsSceneHoverEvent; class QGraphicsSceneMouseEvent; class QGraphicsSceneWheelEvent; -class QGraphicsSceneGestureEvent; class QGraphicsSimpleTextItem; class QGraphicsTextItem; class QGraphicsView; diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 3c3a811..d2d603a 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -78,7 +78,6 @@ QT_BEGIN_NAMESPACE class QGraphicsView; class QGraphicsWidget; -class QGesture; class QGraphicsScenePrivate : public QObjectPrivate { @@ -309,13 +308,6 @@ public: QStyleOptionGraphicsItem styleOptionTmp; - // items with gestures -> list of started gestures. - QMap > itemsWithGestures; - QSet grabbedGestures; - void grabGesture(QGraphicsItem *item, int gestureId); - void releaseGesture(QGraphicsItem *item, int gestureId); - void sendGestureEvent(const QSet &gestures, const QSet &cancelled); - QMap sceneCurrentTouchPoints; QMap itemForTouchPointId; static void updateTouchPointsForItem(QGraphicsItem *item, QTouchEvent *touchEvent); diff --git a/src/gui/graphicsview/qgraphicssceneevent.cpp b/src/gui/graphicsview/qgraphicssceneevent.cpp index 27a2d7e..53019f2 100644 --- a/src/gui/graphicsview/qgraphicssceneevent.cpp +++ b/src/gui/graphicsview/qgraphicssceneevent.cpp @@ -275,8 +275,6 @@ QT_BEGIN_NAMESPACE -QString qt_getStandardGestureTypeName(Qt::GestureType type); - class QGraphicsSceneEventPrivate { public: @@ -1679,253 +1677,6 @@ void QGraphicsSceneMoveEvent::setNewPos(const QPointF &pos) d->newPos = pos; } -/*! - \class QGraphicsSceneGestureEvent - \brief The QGraphicsSceneGestureEvent class provides gesture events for - the graphics view framework. - \since 4.6 - \ingroup multimedia - \ingroup graphicsview-api - - QGraphicsSceneGestureEvent extends information provided by - QGestureEvent by adding some convenience functions like - \l{QGraphicsSceneEvent::}{widget()} to get a widget that received - original gesture event, and convenience functions mapToScene(), - mapToItem() for converting positions of the gesture into - QGraphicsScene and QGraphicsItem coordinate system respectively. - - The scene sends the event to the first QGraphicsItem under the - mouse cursor that accepts gestures; a graphics item is set to accept - gestures with \l{QGraphicsItem::}{grabGesture()}. - - \sa QGestureEvent -*/ - -/*! - Constructs a QGraphicsSceneGestureEvent. -*/ -QGraphicsSceneGestureEvent::QGraphicsSceneGestureEvent() - : QGraphicsSceneEvent(QEvent::GraphicsSceneGesture) -{ - setAccepted(false); -} - -/*! - Destroys a QGraphicsSceneGestureEvent. -*/ -QGraphicsSceneGestureEvent::~QGraphicsSceneGestureEvent() -{ -} - -/*! - Returns true if the gesture event contains gesture of specific \a - type; returns false otherwise. -*/ -bool QGraphicsSceneGestureEvent::contains(const QString &type) const -{ - return gesture(type) != 0; -} - -/*! - Returns true if the gesture event contains gesture of specific \a - type; returns false otherwise. -*/ -bool QGraphicsSceneGestureEvent::contains(Qt::GestureType type) const -{ - return contains(qt_getStandardGestureTypeName(type)); -} - -/*! - Returns a list of gesture names that this event contains. -*/ -QList QGraphicsSceneGestureEvent::gestureTypes() const -{ - return m_gestures.keys(); -} - -/*! - Returns extended information about a gesture of specific \a type. -*/ -const QGesture* QGraphicsSceneGestureEvent::gesture(const QString &type) const -{ - return m_gestures.value(type, 0); -} - -/*! - Returns extended information about a gesture of specific \a type. -*/ -const QGesture* QGraphicsSceneGestureEvent::gesture(Qt::GestureType type) const -{ - return gesture(qt_getStandardGestureTypeName(type)); -} - -/*! - Returns extended information about all gestures in the event. -*/ -QList QGraphicsSceneGestureEvent::gestures() const -{ - return m_gestures.values(); -} - -/*! - Returns a set of gesture names that used to be executed, but were - cancelled (i.e. they were not finished properly). -*/ -QSet QGraphicsSceneGestureEvent::cancelledGestures() const -{ - return m_cancelledGestures; -} - -/*! - Sets a list of gesture names \a cancelledGestures that used to be - executed, but were cancelled (i.e. they were not finished - properly). -*/ -void QGraphicsSceneGestureEvent::setCancelledGestures(const QSet &cancelledGestures) -{ - m_cancelledGestures = cancelledGestures; -} - -/*! - Maps the point \a point, which is in a view coordinate system, to - scene coordinate system, and returns the mapped coordinate. - - A \a point is in coordinate system of the widget that received - gesture event. - - \sa mapToItem(), {The Graphics View Coordinate System} -*/ -QPointF QGraphicsSceneGestureEvent::mapToScene(const QPoint &point) const -{ - if (QGraphicsView *view = qobject_cast(widget())) - return view->mapToScene(point); - return QPointF(); -} - -/*! - Maps the rectangular \a rect, which is in a view coordinate system, to - scene coordinate system, and returns the mapped coordinate. - - A \a rect is in coordinate system of the widget that received - gesture event. - - \sa mapToItem(), {The Graphics View Coordinate System} -*/ -QPolygonF QGraphicsSceneGestureEvent::mapToScene(const QRect &rect) const -{ - if (QGraphicsView *view = qobject_cast(widget())) - return view->mapToScene(rect); - return QPolygonF(); -} - -/*! - Maps the point \a point, which is in a view coordinate system, to - item's \a item coordinate system, and returns the mapped coordinate. - - If \a item is 0, this function returns the same as mapToScene(). - - \sa mapToScene(), {The Graphics View Coordinate System} -*/ -QPointF QGraphicsSceneGestureEvent::mapToItem(const QPoint &point, QGraphicsItem *item) const -{ - if (item) { - if (QGraphicsView *view = qobject_cast(widget())) - return item->mapFromScene(view->mapToScene(point)); - } else { - return mapToScene(point); - } - return QPointF(); -} - -/*! - Maps the rectangualar \a rect, which is in a view coordinate system, to - item's \a item coordinate system, and returns the mapped coordinate. - - If \a item is 0, this function returns the same as mapToScene(). - - \sa mapToScene(), {The Graphics View Coordinate System} -*/ -QPolygonF QGraphicsSceneGestureEvent::mapToItem(const QRect &rect, QGraphicsItem *item) const -{ - if (item) { - if (QGraphicsView *view = qobject_cast(widget())) - return item->mapFromScene(view->mapToScene(rect)); - } else { - return mapToScene(rect); - } - return QPolygonF(); -} - -/*! - Set a list of gesture objects containing extended information about \a gestures. -*/ -void QGraphicsSceneGestureEvent::setGestures(const QList &gestures) -{ - foreach(QGesture *g, gestures) - m_gestures.insert(g->type(), g); -} - -/*! - Set a list of gesture objects containing extended information about \a gestures. -*/ -void QGraphicsSceneGestureEvent::setGestures(const QSet &gestures) -{ - foreach(QGesture *g, gestures) - m_gestures.insert(g->type(), g); -} - -/*! - Sets the accept flag of the all gestures for the event object. - This is the equivalent of calling \l{QEvent::accept()} {accept()} - or \l{QEvent::setAccepted()}{setAccepted(true)}. - - Setting the accept flag indicates that the event receiver wants - the gesture. Unwanted gestures might be propagated to the parent - widget. -*/ -void QGraphicsSceneGestureEvent::acceptAll() -{ - QHash::iterator it = m_gestures.begin(), - e = m_gestures.end(); - for(; it != e; ++it) - it.value()->accept(); - setAccepted(true); -} - -/*! \fn void QGraphicsSceneGestureEvent::accept() - Calls QEvent::accept(). -*/ - -/*! - Sets the accept flag of the gesture specified by \a type. This is - equivalent to calling \l{QGestureEvent::gesture()} {gesture(type)}-> - \l{QGesture::accept()}{accept()} - - Setting the accept flag indicates that the event receiver - wants the gesture. Unwanted gestures might be propagated to the parent - widget. -*/ -void QGraphicsSceneGestureEvent::accept(Qt::GestureType type) -{ - if (QGesture *g = m_gestures.value(qt_getStandardGestureTypeName(type), 0)) - g->accept(); -} - -/*! - - Sets the accept flag of the gesture specified by \a type. This is - equivalent to calling \l{QGestureEvent::gesture()} {gesture(type)}-> - \l{QGesture::accept()}{accept()} - - Setting the accept flag indicates that the event receiver wants the - gesture. Unwanted gestures might be propagated to the parent widget. -*/ -void QGraphicsSceneGestureEvent::accept(const QString &type) -{ - if (QGesture *g = m_gestures.value(type, 0)) - g->accept(); -} - QT_END_NAMESPACE #endif // QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicssceneevent.h b/src/gui/graphicsview/qgraphicssceneevent.h index 8a30bb8..b38e757 100644 --- a/src/gui/graphicsview/qgraphicssceneevent.h +++ b/src/gui/graphicsview/qgraphicssceneevent.h @@ -306,49 +306,6 @@ public: void setNewPos(const QPointF &pos); }; -class QGesture; -class QGraphicsItem; -class QGraphicsSceneGestureEventPrivate; -class Q_GUI_EXPORT QGraphicsSceneGestureEvent : public QGraphicsSceneEvent -{ - Q_DECLARE_PRIVATE(QGraphicsSceneGestureEvent) -public: - QGraphicsSceneGestureEvent(); - ~QGraphicsSceneGestureEvent(); - - bool contains(const QString &type) const; - bool contains(Qt::GestureType type) const; - - QList gestureTypes() const; - - const QGesture* gesture(Qt::GestureType type) const; - const QGesture* gesture(const QString &type) const; - QList gestures() const; - void setGestures(const QList &gestures); - void setGestures(const QSet &gestures); - - QSet cancelledGestures() const; - void setCancelledGestures(const QSet &cancelledGestures); - - void acceptAll(); -#ifndef Q_NO_USING_KEYWORD - using QEvent::accept; -#else - inline void accept() { QEvent::accept(); } -#endif - void accept(Qt::GestureType type); - void accept(const QString &type); - - QPointF mapToScene(const QPoint &point) const; - QPolygonF mapToScene(const QRect &rect) const; - QPointF mapToItem(const QPoint &point, QGraphicsItem *item) const; - QPolygonF mapToItem(const QRect &rect, QGraphicsItem *item) const; - -protected: - QHash m_gestures; - QSet m_cancelledGestures; -}; - #endif // QT_NO_GRAPHICSVIEW QT_END_NAMESPACE diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index a2adf82..56a69f7 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -2658,9 +2658,6 @@ bool QGraphicsView::event(QEvent *event) } } break; - case QEvent::Gesture: - viewportEvent(event); - return true; default: break; } @@ -2742,17 +2739,6 @@ bool QGraphicsView::viewportEvent(QEvent *event) d->scene->d_func()->updateAll = false; } break; - case QEvent::Gesture: { - QGraphicsSceneGestureEvent gestureEvent; - gestureEvent.setWidget(this); - QGestureEvent *ev = static_cast(event); - gestureEvent.setGestures(ev->gestures()); - gestureEvent.setCancelledGestures(ev->cancelledGestures()); - QApplication::sendEvent(d->scene, &gestureEvent); - event->setAccepted(gestureEvent.isAccepted()); - return true; - } - break; case QEvent::TouchBegin: case QEvent::TouchUpdate: case QEvent::TouchEnd: diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index 2917592..e6eff6e 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -44,12 +44,8 @@ HEADERS += \ kernel/qkeymapper_p.h \ kernel/qgesture.h \ kernel/qgesture_p.h \ - kernel/qgesturemanager_p.h \ - kernel/qgesturerecognizer_p.h \ - kernel/qgesturerecognizer.h \ - kernel/qgesturestandardrecognizers_p.h \ - kernel/qdirectionrecognizer_p.h \ - kernel/qdirectionsimplificator_p.h + kernel/qstandardgestures.h \ + kernel/qstandardgestures_p.h SOURCES += \ kernel/qaction.cpp \ @@ -80,10 +76,7 @@ SOURCES += \ kernel/qwidgetaction.cpp \ kernel/qkeymapper.cpp \ kernel/qgesture.cpp \ - kernel/qgesturemanager.cpp \ - kernel/qgesturerecognizer.cpp \ - kernel/qgesturestandardrecognizers.cpp \ - kernel/qdirectionrecognizer.cpp + kernel/qstandardgestures.cpp win32 { DEFINES += QT_NO_DIRECTDRAW diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index a7b7a0a..0e8978f 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -90,8 +90,6 @@ #include "qapplication.h" -#include - #ifdef Q_WS_WINCE #include "qdatetime.h" #include "qguifunctions_wince.h" @@ -137,14 +135,6 @@ int QApplicationPrivate::autoMaximizeThreshold = -1; bool QApplicationPrivate::autoSipEnabled = false; #endif -QGestureManager* QGestureManager::instance() -{ - QApplicationPrivate *d = qApp->d_func(); - if (!d->gestureManager) - d->gestureManager = new QGestureManager(qApp); - return d->gestureManager; -} - QApplicationPrivate::QApplicationPrivate(int &argc, char **argv, QApplication::Type type) : QCoreApplicationPrivate(argc, argv) { @@ -168,8 +158,6 @@ QApplicationPrivate::QApplicationPrivate(int &argc, char **argv, QApplication::T directPainters = 0; #endif - gestureManager = 0; - if (!self) self = this; } @@ -3595,14 +3583,6 @@ bool QApplication::notify(QObject *receiver, QEvent *e) #endif // !QT_NO_WHEELEVENT || !QT_NO_TABLETEVENT } - if (!d->grabbedGestures.isEmpty() && e->spontaneous() && receiver->isWidgetType()) { - const QEvent::Type t = e->type(); - if (t != QEvent::Gesture && t != QEvent::GraphicsSceneGesture) { - if (QGestureManager::instance()->filterEvent(static_cast(receiver), e)) - return true; - } - } - // User input and window activation makes tooltips sleep switch (e->type()) { case QEvent::Wheel: @@ -4061,6 +4041,19 @@ bool QApplication::notify(QObject *receiver, QEvent *e) touchEvent->setAccepted(eventAccepted); break; } + case QEvent::WinGesture: + { + // only propagate the first gesture event (after the GID_BEGIN) + QWidget *w = static_cast(receiver); + while (w) { + e->ignore(); + res = d->notify_helper(w, e); + if ((res && e->isAccepted()) || w->isWindow()) + break; + w = w->parentWidget(); + } + break; + } default: res = d->notify_helper(receiver, e); break; @@ -5057,57 +5050,6 @@ bool QApplicationPrivate::shouldSetFocus(QWidget *w, Qt::FocusPolicy policy) return true; } -/*! - \since 4.6 - - Adds custom gesture \a recognizer object. - - Qt takes ownership of the provided \a recognizer. - - \sa QGestureEvent -*/ -void QApplication::addGestureRecognizer(QGestureRecognizer *recognizer) -{ - QGestureManager::instance()->addRecognizer(recognizer); -} - -/*! - \since 4.6 - - Removes custom gesture \a recognizer object. - - \sa QGestureEvent -*/ -void QApplication::removeGestureRecognizer(QGestureRecognizer *recognizer) -{ - Q_D(QApplication); - if (!d->gestureManager) - return; - d->gestureManager->removeRecognizer(recognizer); -} - -/*! - \property QApplication::eventDeliveryDelayForGestures - \since 4.6 - - Specifies the \a delay before input events are delivered to the - gesture enabled widgets. - - The delay allows to postpone widget's input event handling until - gestures framework can successfully recognize a gesture. - - \sa QWidget::grabGesture() -*/ -void QApplication::setEventDeliveryDelayForGestures(int delay) -{ - QGestureManager::instance()->setEventDeliveryDelay(delay); -} - -int QApplication::eventDeliveryDelayForGestures() -{ - return QGestureManager::instance()->eventDeliveryDelay(); -} - /*! \fn QDecoration &QApplication::qwsDecoration() Return the QWSDecoration used for decorating windows. diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h index 954f824..19ae085 100644 --- a/src/gui/kernel/qapplication.h +++ b/src/gui/kernel/qapplication.h @@ -71,7 +71,6 @@ class QStyle; class QEventLoop; class QIcon; class QInputContext; -class QGestureRecognizer; template class QList; class QLocale; #if defined(Q_WS_QWS) @@ -107,7 +106,6 @@ class Q_GUI_EXPORT QApplication : public QCoreApplication Q_PROPERTY(int autoMaximizeThreshold READ autoMaximizeThreshold WRITE setAutoMaximizeThreshold) Q_PROPERTY(bool autoSipEnabled READ autoSipEnabled WRITE setAutoSipEnabled) #endif - Q_PROPERTY(int eventDeliveryDelayForGestures READ eventDeliveryDelayForGestures WRITE setEventDeliveryDelayForGestures) public: enum Type { Tty, GuiClient, GuiServer }; @@ -268,12 +266,6 @@ public: static bool keypadNavigationEnabled(); #endif - void addGestureRecognizer(QGestureRecognizer *recognizer); - void removeGestureRecognizer(QGestureRecognizer *recognizer); - - void setEventDeliveryDelayForGestures(int delay); - int eventDeliveryDelayForGestures(); - Q_SIGNALS: void lastWindowClosed(); void focusChanged(QWidget *old, QWidget *now); @@ -382,7 +374,6 @@ private: friend class QDirectPainter; friend class QDirectPainterPrivate; #endif - friend class QGestureManager; #if defined(Q_WS_WIN) friend QApplicationPrivate* getQApplicationPrivateInternal(); diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index 4b2bf15..db77b07 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -193,7 +193,109 @@ extern "C" { typedef BOOL (WINAPI *qt_RegisterTouchWindowPtr)(HWND, ULONG); typedef BOOL (WINAPI *qt_GetTouchInputInfoPtr)(HANDLE, UINT, PVOID, int); typedef BOOL (WINAPI *qt_CloseTouchInputHandlePtr)(HANDLE); -#endif + +#ifndef WM_GESTURE + +#define WM_GESTURE 0x0119 +#define WM_GESTURE_NOTIFY 0x011A + +DECLARE_HANDLE(HGESTUREINFO); + +#define GF_BEGIN 0x00000001 +#define GF_INERTIA 0x00000002 +#define GF_END 0x00000004 + +/* + * Gesture IDs + */ +#define GID_BEGIN 1 +#define GID_END 2 +#define GID_ZOOM 3 +#define GID_PAN 4 +#define GID_ROTATE 5 +#define GID_TWOFINGERTAP 6 +#define GID_ROLLOVER 7 + +typedef struct tagGESTUREINFO { + UINT cbSize; // size, in bytes, of this structure (including variable length Args field) + DWORD dwFlags; // see GF_* flags + DWORD dwID; // gesture ID, see GID_* defines + HWND hwndTarget; // handle to window targeted by this gesture + POINTS ptsLocation; // current location of this gesture + DWORD dwInstanceID; // internally used + DWORD dwSequenceID; // internally used + ULONGLONG ullArguments; // arguments for gestures whose arguments fit in 8 BYTES + UINT cbExtraArgs; // size, in bytes, of extra arguments, if any, that accompany this gesture +} GESTUREINFO, *PGESTUREINFO; +typedef GESTUREINFO const * PCGESTUREINFO; + +typedef struct tagGESTURENOTIFYSTRUCT { + UINT cbSize; // size, in bytes, of this structure + DWORD dwFlags; // unused + HWND hwndTarget; // handle to window targeted by the gesture + POINTS ptsLocation; // starting location + DWORD dwInstanceID; // internally used +} GESTURENOTIFYSTRUCT, *PGESTURENOTIFYSTRUCT; + +/* + * Gesture argument helpers + * - Angle should be a double in the range of -2pi to +2pi + * - Argument should be an unsigned 16-bit value + */ +#define GID_ROTATE_ANGLE_TO_ARGUMENT(_arg_) ((USHORT)((((_arg_) + 2.0 * 3.14159265) / (4.0 * 3.14159265)) * 65535.0)) +#define GID_ROTATE_ANGLE_FROM_ARGUMENT(_arg_) ((((double)(_arg_) / 65535.0) * 4.0 * 3.14159265) - 2.0 * 3.14159265) + +typedef struct tagGESTURECONFIG { + DWORD dwID; // gesture ID + DWORD dwWant; // settings related to gesture ID that are to be turned on + DWORD dwBlock; // settings related to gesture ID that are to be turned off +} GESTURECONFIG, *PGESTURECONFIG; + +#define GC_ALLGESTURES 0x00000001 +#define GC_ZOOM 0x00000001 +#define GC_PAN 0x00000001 +#define GC_PAN_WITH_SINGLE_FINGER_VERTICALLY 0x00000002 +#define GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY 0x00000004 +#define GC_PAN_WITH_GUTTER 0x00000008 +#define GC_PAN_WITH_INERTIA 0x00000010 +#define GC_ROTATE 0x00000001 +#define GC_TWOFINGERTAP 0x00000001 +#define GC_ROLLOVER 0x00000001 +#define GESTURECONFIGMAXCOUNT 256 // Maximum number of gestures that can be included + // in a single call to SetGestureConfig / GetGestureConfig + + + +#define GCF_INCLUDE_ANCESTORS 0x00000001 // If specified, GetGestureConfig returns consolidated configuration + // for the specified window and it's parent window chain + +typedef BOOL (*PtrGetGestureInfo)(HGESTUREINFO hGestureInfo, PGESTUREINFO pGestureInfo); +typedef BOOL (*PtrGetGestureExtraArgs)(HGESTUREINFO hGestureInfo, UINT cbExtraArgs, PBYTE pExtraArgs); +typedef BOOL (*PtrCloseGestureInfoHandle)(HGESTUREINFO hGestureInfo); +typedef BOOL (*PtrSetGestureConfig)(HWND hwnd, DWORD dwReserved, UINT cIDs, + PGESTURECONFIG pGestureConfig, + UINT cbSize); +typedef BOOL (*PtrGetGestureConfig)(HWND hwnd, DWORD dwReserved, + DWORD dwFlags, PUINT pcIDs, + PGESTURECONFIG pGestureConfig, + UINT cbSize); + +typedef BOOL (*PtrBeginPanningFeedback)(HWND hwnd); +typedef BOOL (*PtrUpdatePanningFeedback)(HWND hwnd, LONG, LONG, BOOL); +typedef BOOL (*PtrEndPanningFeedback)(HWND hwnd, BOOL); + +#endif // WM_GESTURE +#endif // Q_WS_WIN + +class QPanGesture; +class QPinchGesture; +struct StandardGestures +{ + QPanGesture *pan; + QPinchGesture *pinch; + StandardGestures() : pan(0), pinch(0) { } +}; + class QScopedLoopLevelCounter { @@ -439,10 +541,6 @@ public: void sendSyntheticEnterLeave(QWidget *widget); #endif - QGestureManager *gestureManager; - // map number of widget subscribed to it> - QMap grabbedGestures; - QMap widgetForTouchPointId; QMap appCurrentTouchPoints; static void updateTouchPointsForWidget(QWidget *widget, QTouchEvent *touchEvent); @@ -465,6 +563,19 @@ public: QHash touchInputIDToTouchPointID; QList appAllTouchPoints; bool translateTouchEvent(const MSG &msg); + + typedef QMap WidgetStandardGesturesMap; + WidgetStandardGesturesMap widgetGestures; + ulong lastGestureId; + + PtrGetGestureInfo GetGestureInfo; + PtrGetGestureExtraArgs GetGestureExtraArgs; + PtrCloseGestureInfoHandle CloseGestureInfoHandle; + PtrSetGestureConfig SetGestureConfig; + PtrGetGestureConfig GetGestureConfig; + PtrBeginPanningFeedback BeginPanningFeedback; + PtrUpdatePanningFeedback UpdatePanningFeedback; + PtrEndPanningFeedback EndPanningFeedback; #endif #ifdef QT_RX71_MULTITOUCH diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index e1af0f7..13f19a3 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -89,6 +89,8 @@ extern void qt_wince_hide_taskbar(HWND hwnd); //defined in qguifunctions_wince.c #include #include #include "qevent_p.h" +#include "qstandardgestures.h" +#include "qstandardgestures_p.h" //#define ALIEN_DEBUG @@ -451,6 +453,7 @@ public: bool translateConfigEvent(const MSG &msg); bool translateCloseEvent(const MSG &msg); bool translateTabletEvent(const MSG &msg, PACKET *localPacketBuf, int numPackets); + bool translateGestureEvent(const MSG &msg); void repolishStyle(QStyle &style); inline void showChildren(bool spontaneous) { d_func()->showChildren(spontaneous); } inline void hideChildren(bool spontaneous) { d_func()->hideChildren(spontaneous); } @@ -809,6 +812,33 @@ void qt_init(QApplicationPrivate *priv, int) QLibrary::resolve(QLatin1String("user32"), "SetProcessDPIAware")) ptrSetProcessDPIAware(); #endif + + priv->lastGestureId = 0; + + priv->GetGestureInfo = + (PtrGetGestureInfo)QLibrary::resolve(QLatin1String("user32"), + "GetGestureInfo"); + priv->GetGestureExtraArgs = + (PtrGetGestureExtraArgs)QLibrary::resolve(QLatin1String("user32"), + "GetGestureExtraArgs"); + priv->CloseGestureInfoHandle = + (PtrCloseGestureInfoHandle)QLibrary::resolve(QLatin1String("user32"), + "CloseGestureInfoHandle"); + priv->SetGestureConfig = + (PtrSetGestureConfig)QLibrary::resolve(QLatin1String("user32"), + "SetGestureConfig"); + priv->GetGestureConfig = + (PtrGetGestureConfig)QLibrary::resolve(QLatin1String("user32"), + "GetGestureConfig"); + priv->BeginPanningFeedback = + (PtrBeginPanningFeedback)QLibrary::resolve(QLatin1String("uxtheme"), + "BeginPanningFeedback"); + priv->UpdatePanningFeedback = + (PtrUpdatePanningFeedback)QLibrary::resolve(QLatin1String("uxtheme"), + "UpdatePanningFeedback"); + priv->EndPanningFeedback = + (PtrEndPanningFeedback)QLibrary::resolve(QLatin1String("uxtheme"), + "EndPanningFeedback"); } /***************************************************************************** @@ -2469,6 +2499,10 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam } result = false; break; + case WM_GESTURE: + widget->translateGestureEvent(msg); + result = true; + break; default: result = false; // event was not processed break; @@ -3649,6 +3683,60 @@ bool QETWidget::translateCloseEvent(const MSG &) return d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent); } +bool QETWidget::translateGestureEvent(const MSG &msg) +{ + GESTUREINFO gi; + gi.cbSize = sizeof(GESTUREINFO); + gi.dwFlags = 0; + gi.ptsLocation.x = 0; + gi.ptsLocation.y = 0; + gi.dwID = 0; + gi.dwInstanceID = 0; + gi.dwSequenceID = 0; + + QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); + BOOL bResult = qAppPriv->GetGestureInfo((HGESTUREINFO)msg.lParam, &gi); + + const QPoint widgetPos = QPoint(gi.ptsLocation.x, gi.ptsLocation.y); + QWidget *alienWidget = !internalWinId() ? this : childAt(widgetPos); + if (alienWidget && alienWidget->internalWinId()) + alienWidget = 0; + QWidget *widget = alienWidget ? alienWidget : this; + + QWinGestureEvent event; + event.sequenceId = gi.dwSequenceID; + event.position = QPoint(gi.ptsLocation.x, gi.ptsLocation.y); + if (bResult) { + switch (gi.dwID) { + case GID_BEGIN: + // we are not interested in this type of event. + break; + case GID_END: + event.gestureType = QWinGestureEvent::GestureEnd; + break; + case GID_ZOOM: + event.gestureType = QWinGestureEvent::Pinch; + break; + case GID_PAN: + event.gestureType = QWinGestureEvent::Pan; + break; + case GID_ROTATE: + case GID_TWOFINGERTAP: + case GID_ROLLOVER: + default: + break; + } + if (event.gestureType != QWinGestureEvent::None) + qt_sendSpontaneousEvent(widget, &event); + } else { + DWORD dwErr = GetLastError(); + if (dwErr > 0) + qWarning() << "translateGestureEvent: error = " << dwErr; + } + qAppPriv->CloseGestureInfoHandle((HGESTUREINFO)msg.lParam); + return true; +} + void QApplication::setCursorFlashTime(int msecs) { @@ -3830,6 +3918,7 @@ void QSessionManager::cancel() #endif //QT_NO_SESSIONMANAGER + qt_RegisterTouchWindowPtr QApplicationPrivate::RegisterTouchWindow = 0; qt_GetTouchInputInfoPtr QApplicationPrivate::GetTouchInputInfo = 0; qt_CloseTouchInputHandlePtr QApplicationPrivate::CloseTouchInputHandle = 0; diff --git a/src/gui/kernel/qdirectionrecognizer.cpp b/src/gui/kernel/qdirectionrecognizer.cpp deleted file mode 100644 index a1bc5b1..0000000 --- a/src/gui/kernel/qdirectionrecognizer.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui 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 "qdirectionrecognizer_p.h" - -#include - -#ifndef M_PI -#define M_PI 3.141592653589793238462643 -#endif - -QT_BEGIN_NAMESPACE - -enum { - DistanceDelta = 20 -}; - -QDirectionSimpleRecognizer::QDirectionSimpleRecognizer() -{ -} - -Direction QDirectionSimpleRecognizer::addPosition(const QPoint &pos) -{ - if (!directions.isEmpty()) { - const QPoint tmp = pos - directions.back().point; - if (tmp.manhattanLength() < 5) - return Direction(); - } - if (lastPoint.isNull()) { - lastPoint = pos; - return Direction(); - } - int dx = pos.x() - lastPoint.x(); - int dy = pos.y() - lastPoint.y(); - Qt::DirectionType direction = Qt::NoDirection; - if (dx < 0) { - if (-1*dx >= DistanceDelta/2) - direction = Qt::LeftDirection; - } else { - if (dx >= DistanceDelta/2) - direction = Qt::RightDirection; - } - if (dy < 0) { - if (-1*dy >= DistanceDelta/2) - direction = Qt::UpDirection; - } else { - if (dy >= DistanceDelta/2) - direction = Qt::DownDirection; - } - if (direction == Qt::NoDirection) - return Direction(); - - lastPoint = pos; - directions.push_back(Direction(direction, pos)); - return Direction(direction, pos); -} - - -DirectionList QDirectionSimpleRecognizer::getDirections() const -{ - return directions; -} - -void QDirectionSimpleRecognizer::reset() -{ - directions.clear(); - lastPoint = QPoint(); -} - - -/// QDirectionDiagonalRecognizer - -QDirectionDiagonalRecognizer::QDirectionDiagonalRecognizer() -{ -} - -Direction QDirectionDiagonalRecognizer::addPosition(const QPoint &pos) -{ - if (!directions.isEmpty()) { - const QPoint tmp = pos - directions.back().point; - if (tmp.manhattanLength() < 5) - return Direction(); - } - if (lastPoint.isNull()) { - lastPoint = pos; - return Direction(); - } - int dx = pos.x() - lastPoint.x(); - int dy = pos.y() - lastPoint.y(); - int distance = sqrt(static_cast(dx*dx + dy*dy)); - if (distance < DistanceDelta/2) - return Direction(); - - Qt::DirectionType direction = Qt::NoDirection; - double angle = atan(1.0*qAbs(lastPoint.y() - pos.y())/qAbs(pos.x() - lastPoint.x())) * 180. / M_PI; - if (dx < 0 && dy <= 0) { - angle = 180 - angle; - } else if (dx <= 0 && dy > 0) { - angle += 180; - } else if (dx > 0 && dy > 0) { - angle = 360-angle; - } - if (angle < 0) - angle += 360; - if (angle <= 20) - direction = Qt::RightDirection; - else if (angle <= 65) - direction = Qt::RightUpDirection; - else if (angle <= 110) - direction = Qt::UpDirection; - else if (angle <= 155) - direction = Qt::LeftUpDirection; - else if (angle <= 200) - direction = Qt::LeftDirection; - else if (angle <= 245) - direction = Qt::LeftDownDirection; - else if (angle <= 290) - direction = Qt::DownDirection; - else if (angle <= 335) - direction = Qt::RightDownDirection; - else - direction = Qt::RightDirection; - - if (direction == Qt::NoDirection) - return Direction(); - - lastPoint = pos; - directions.push_back(Direction(direction, pos)); - return Direction(direction, pos); -} - - -DirectionList QDirectionDiagonalRecognizer::getDirections() const -{ - return directions; -} - -void QDirectionDiagonalRecognizer::reset() -{ - directions.clear(); - lastPoint = QPoint(); -} - -QT_END_NAMESPACE diff --git a/src/gui/kernel/qdirectionrecognizer_p.h b/src/gui/kernel/qdirectionrecognizer_p.h deleted file mode 100644 index 12307c6..0000000 --- a/src/gui/kernel/qdirectionrecognizer_p.h +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui 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$ -** -****************************************************************************/ - -#ifndef QDIRECTIONRECOGNIZER_P_H -#define QDIRECTIONRECOGNIZER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qpoint.h" -#include "qlist.h" - -QT_BEGIN_NAMESPACE - -struct Direction -{ - Qt::DirectionType direction; - QPoint point; - - Direction(Qt::DirectionType dir, const QPoint &pt) - : direction(dir), point(pt) { } - Direction() - : direction(Qt::NoDirection) { } - - inline bool isEmpty() const { return direction == Qt::NoDirection; } - inline bool isNull() const { return direction == Qt::NoDirection; } -}; - -typedef QList DirectionList; - -class QDirectionSimpleRecognizer -{ -public: - QDirectionSimpleRecognizer(); - Direction addPosition(const QPoint &pos); - DirectionList getDirections() const; - void reset(); - -private: - QPoint lastPoint; - DirectionList directions; -}; - -class QDirectionDiagonalRecognizer -{ -public: - QDirectionDiagonalRecognizer(); - Direction addPosition(const QPoint &pos); - DirectionList getDirections() const; - void reset(); - -private: - QPoint lastPoint; - DirectionList directions; -}; - -QT_END_NAMESPACE - -#endif // QDIRECTIONRECOGNIZER_P_H diff --git a/src/gui/kernel/qdirectionsimplificator_p.h b/src/gui/kernel/qdirectionsimplificator_p.h deleted file mode 100644 index d7491dc..0000000 --- a/src/gui/kernel/qdirectionsimplificator_p.h +++ /dev/null @@ -1,172 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui 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$ -** -****************************************************************************/ - -#ifndef QDIRECTIONSIMPLIFICATOR_P_H -#define QDIRECTIONSIMPLIFICATOR_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "private/qdirectionrecognizer_p.h" - -QT_BEGIN_NAMESPACE - -class QDirectionSimplificator -{ -public: - QDirectionSimplificator(const DirectionList &dir); - - bool simplify(DirectionList *result); - -private: - DirectionList directions; - DirectionList lastResult; - enum State { - None, - Trim, // remove first and last element - AccidentalMoves, // 66866 => 6666 - ComplexAccidentalMoves, // 778788 => 777888 (swapping elements without changing direction) - ShortMoves, // (moves of length 1) - } state; - - struct SimplifyTrim - { - SimplifyTrim() : state(0) { } - bool operator()(DirectionList &directions) - { - if (state == 0) { - directions.removeFirst(); - state = 1; - } else if (state == 1) { - directions.removeLast(); - state = 2; - } else if (state == 2 && directions.size() >= 2) { - directions.removeFirst(); - directions.removeLast(); - state = 3; - } else { - return false; - } - return true; - } - int state; - }; - struct SimplifyAccidentalMoves - { - SimplifyAccidentalMoves() : state(0) { } - bool operator()(DirectionList &directions) - { - return false; - } - int state; - }; - struct SimplifyComplexAccidentalMoves - { - SimplifyComplexAccidentalMoves() : state(0) { } - bool operator()(DirectionList &directions) - { - return false; - } - int state; - }; - - SimplifyTrim trim; - SimplifyAccidentalMoves accidentalMoves; - SimplifyComplexAccidentalMoves complexAccidentalMoves; - //SimplifyShortMoves shortMoves; -}; - -QDirectionSimplificator::QDirectionSimplificator(const DirectionList &dir) - : directions(dir), state(None) -{ -} - -bool QDirectionSimplificator::simplify(DirectionList *result) -{ - if (directions.isEmpty() || !result) - return false; - *result = directions; - switch(state) { - case None: - state = Trim; - trim = SimplifyTrim(); - case Trim: - if (trim(*result)) - break; - *result = lastResult; - state = AccidentalMoves; - accidentalMoves = SimplifyAccidentalMoves(); - case AccidentalMoves: - if (accidentalMoves(*result)) - break; - *result = lastResult; - state = ComplexAccidentalMoves; - complexAccidentalMoves = SimplifyComplexAccidentalMoves(); - case ComplexAccidentalMoves: - if (complexAccidentalMoves(*result)) - break; - *result = lastResult; - // state = ShortMoves; - // shortMoves = SimplifyShortMoves(); - // case ShortMoves: - // if (shortMoves(*result)) - // break; - // state = None; - default: - return false; - } - lastResult = *result; - if (lastResult.isEmpty()) - return false; - return true; -} - -QT_END_NAMESPACE - -#endif // QDIRECTIONSIMPLIFICATOR_P_H diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index a7a7f2d..bef7ee1 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -53,8 +53,6 @@ QT_BEGIN_NAMESPACE -QString qt_getStandardGestureTypeName(Qt::GestureType type); - /*! \class QInputEvent \ingroup events @@ -3332,9 +3330,6 @@ QDebug operator<<(QDebug dbg, const QEvent *e) { case QEvent::ChildRemoved: n = n ? n : "ChildRemoved"; dbg.nospace() << "QChildEvent(" << n << ", " << (static_cast(e))->child(); return dbg.space(); - case QEvent::Gesture: - n = "Gesture"; - break; default: dbg.nospace() << "QEvent(" << (const void *)e << ", type = " << e->type() << ')'; return dbg.space(); @@ -3531,157 +3526,6 @@ QMenubarUpdatedEvent::QMenubarUpdatedEvent(QMenuBar * const menuBar) #endif -/*! - \class QGestureEvent - \since 4.6 - \ingroup events - - \brief The QGestureEvent class provides the parameters used for - gesture recognition. - - The QGestureEvent class contains a list of gestures that are being - executed right now (\l{QGestureEvent::}{gestureTypes()}) and a - list of gestures that are cancelled (the gesture might be - cancelled because the window lost focus, or because of timeout, - etc). - - \sa QGesture -*/ - -/*! - Creates new QGestureEvent containing a list of \a gestures that - are being executed and a list of gesture that were cancelled (\a - cancelledGestures). -*/ -QGestureEvent::QGestureEvent(const QSet &gestures, - const QSet &cancelledGestures) - : QEvent(QEvent::Gesture), m_cancelledGestures(cancelledGestures) -{ - setAccepted(false); - foreach(QGesture *r, gestures) - m_gestures.insert(r->type(), r); -} - -/*! - Destroys the QGestureEvent object. -*/ -QGestureEvent::~QGestureEvent() -{ -} - -/*! - Returns true if the gesture event contains gesture of specific \a - type; returns false otherwise. -*/ -bool QGestureEvent::contains(Qt::GestureType type) const -{ - return contains(qt_getStandardGestureTypeName(type)); -} - -/*! - Returns true if the gesture event contains gesture of specific \a - type; returns false otherwise. -*/ -bool QGestureEvent::contains(const QString &type) const -{ - return gesture(type) != 0; -} - -/*! - Returns a list of gesture names that this event contains. -*/ -QList QGestureEvent::gestureTypes() const -{ - return m_gestures.keys(); -} - -/*! - Returns extended information about a gesture of specific \a type. -*/ -const QGesture* QGestureEvent::gesture(Qt::GestureType type) const -{ - return gesture(qt_getStandardGestureTypeName(type)); -} - -/*! - Returns extended information about a gesture of specific \a type. -*/ -const QGesture* QGestureEvent::gesture(const QString &type) const -{ - return m_gestures.value(type, 0); -} - -/*! - Returns extended information about all gestures in the event. -*/ -QList QGestureEvent::gestures() const -{ - return m_gestures.values(); -} - -/*! - Returns a set of gesture names that used to be executed, but were - cancelled (i.e. they were not finished properly). -*/ -QSet QGestureEvent::cancelledGestures() const -{ - return m_cancelledGestures; -} - -/*! \fn void QGestureEvent::accept() - Calls QEvent::accept(). -*/ - -/*! - Sets the accept flag of the all gestures inside the event object, - the equivalent of calling \l{QEvent::accept()}{accept()} or - \l{QEvent::setAccepted()}{setAccepted(true)}. - - Setting the accept parameter indicates that the event receiver - wants the gesture. Unwanted gestures might be propagated to the parent - widget. -*/ -void QGestureEvent::acceptAll() -{ - QHash::iterator it = m_gestures.begin(), - e = m_gestures.end(); - for(; it != e; ++it) - it.value()->accept(); - setAccepted(true); -} - -/*! - Sets the accept flag of the gesture specified by \a type. - This is equivalent to calling - \l{QGestureEvent::gesture()}{gesture(type)}-> - \l{QGesture::accept()}{accept()} - - Setting the accept flag indicates that the event receiver wants - the gesture. Unwanted gestures might be propagated to the parent - widget. -*/ -void QGestureEvent::accept(Qt::GestureType type) -{ - if (QGesture *g = m_gestures.value(qt_getStandardGestureTypeName(type), 0)) - g->accept(); -} - -/*! - Sets the accept flag of the gesture specified by \a type. - This is equivalent to calling - \l{QGestureEvent::gesture()}{gesture(type)}-> - \l{QGesture::accept()}{accept()} - - Setting the accept flag indicates that the event receiver wants - the gesture. Unwanted gestures might be propagated to the parent - widget. -*/ -void QGestureEvent::accept(const QString &type) -{ - if (QGesture *g = m_gestures.value(type, 0)) - g->accept(); -} - /*! \class QTouchEvent \brief The QTouchEvent class contains parameters that describe a touch event . diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index 136dd7f..11843cb 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -714,41 +714,6 @@ private: }; #endif -class Q_GUI_EXPORT QGestureEvent : public QEvent -{ -public: - QGestureEvent(const QSet &gestures, - const QSet &cancelledGestures = QSet()); - ~QGestureEvent(); - - bool contains(Qt::GestureType type) const; - bool contains(const QString &type) const; - - QList gestureTypes() const; - - const QGesture* gesture(Qt::GestureType type) const; - const QGesture* gesture(const QString &type) const; - QList gestures() const; - - QSet cancelledGestures() const; - - void acceptAll(); -#ifndef Q_NO_USING_KEYWORD - using QEvent::accept; -#else - inline void accept() { QEvent::accept(); } -#endif - void accept(Qt::GestureType type); - void accept(const QString &type); - -protected: - QHash m_gestures; - QSet m_cancelledGestures; - - friend class QApplication; - friend class QGestureManager; -}; - #ifndef QT_NO_DEBUG_STREAM Q_GUI_EXPORT QDebug operator<<(QDebug, const QEvent *); #endif diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h index 8a2bb05..67441ea 100644 --- a/src/gui/kernel/qevent_p.h +++ b/src/gui/kernel/qevent_p.h @@ -119,6 +119,22 @@ public: qreal pressure; }; +class QWinGestureEvent : public QEvent +{ +public: + enum Type { + None, + GestureEnd, + Pan, + Pinch + }; + + QWinGestureEvent() : QEvent(QEvent::WinGesture), gestureType(None), sequenceId(0) { } + Type gestureType; + QPoint position; + ulong sequenceId; +}; + QT_END_NAMESPACE #endif // QEVENT_P_H diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp index ff369e2..32a219c 100644 --- a/src/gui/kernel/qgesture.cpp +++ b/src/gui/kernel/qgesture.cpp @@ -41,190 +41,166 @@ #include "qgesture.h" #include +#include "qgraphicsitem.h" QT_BEGIN_NAMESPACE -QString qt_getStandardGestureTypeName(Qt::GestureType type); + +class QEventFilterProxyGraphicsItem : public QGraphicsItem +{ +public: + QEventFilterProxyGraphicsItem(QGesture *g) + : gesture(g) + { + } + bool sceneEventFilter(QGraphicsItem *, QEvent *event) + { + return gesture ? gesture->filterEvent(event) : false; + } + QRectF boundingRect() const { return QRectF(); } + void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) { } + +private: + QGesture *gesture; +}; /*! \class QGesture \since 4.6 - \brief The QGesture class represents a gesture, containing all - properties that describe a gesture. - - The widget receives a QGestureEvent with a list of QGesture - objects that represent gestures that are occuring on it. The class - has a list of properties that can be queried by the user to get - some gesture-specific arguments (i.e. position of the tap in the - DoubleTap gesture). - - When creating custom gesture recognizers, they might add new - properties to the gesture object, or custom gesture developers - might subclass the QGesture objects to provide some extended - information. However, if the gesture developer wants to add a new - property to the gesture object that describe coordinate (like a - QPoint or QRect), it is required to subclass the QGesture and - re-implement the \l{QGesture::}{translate()} function to make sure - the coordinates are translated properly when the gesture event is - propagated to parent widgets. - - \sa QGestureEvent, QGestureRecognizer -*/ + \brief The QGesture class is the base class for implementing custom + gestures. -/*! - Creates a new gesture object of type \a type in a \a state and - marks it as a child of \a parent. + This class represents both an object that recognizes a gesture out of a set + of input events (a gesture recognizer), and a gesture object itself that + can be used to get extended information about the triggered gesture. - Usually QGesture objects should only be contructed by the - QGestureRecognizer classes. -*/ -QGesture::QGesture(QObject *parent, const QString &type, Qt::GestureState state) - : QObject(*new QGesturePrivate, parent), m_accept(0) -{ - Q_D(QGesture); - d->type = type; - d->state = state; -} + The class has a list of properties that can be queried by the user to get + some gesture-specific parameters (for example, an offset of a Pan gesture). -/*! - Creates a new gesture object of type \a type in a \a state and - marks it as a child of \a parent. - - This constructor also fills some basic information about the - gesture like a \a startPos which describes the start point of the - gesture, \a lastPos - last point where the gesture happened, \a - pos - a current point, \a rect - a bounding rect of the gesture, - \a hotSpot - a center point of the gesture, \a startTime - a time - when the gesture has started, \a duration - how long the gesture - is going on. - - Usually QGesture objects should only be contructed by the - QGestureRecognizer classes. -*/ -QGesture::QGesture(QObject *parent, const QString &type, const QPoint &startPos, - const QPoint &lastPos, const QPoint &pos, const QRect &rect, - const QPoint &hotSpot, const QDateTime &startTime, - uint duration, Qt::GestureState state) - : QObject(*new QGesturePrivate, parent) -{ - Q_D(QGesture); - d->type = type; - d->state = state; - d->init(startPos, lastPos, pos, rect, hotSpot, startTime, duration); -} + Usually gesture recognizer implements a state machine, storing its state + internally in the recognizer object. The recognizer receives input events + through the \l{QGesture::}{filterEvent()} virtual function and decides + whether the event should change the state of the recognizer by emitting an + appropriate signal. -/*! \internal + Input events should be either fed to the recognizer one by one with a + filterEvent() function, or the gesture recognizer should be attached to an + object it filters events for by specifying it as a parent object. The + QGesture object installs itself as an event filter to the parent object + automatically, the unsetObject() function should be used to remove an event + filter from the parent object. To make a + gesture that operates on a QGraphicsItem, both the appropriate QGraphicsView + should be passed as a parent object and setGraphicsItem() functions should + be used to attach a gesture to a graphics item. + + This is a base class, to create a custom gesture type, you should subclass + it and implement its pure virtual functions. + + \sa QPanGesture, QTapAndHoldGesture */ -QGesture::QGesture(QGesturePrivate &dd, QObject *parent, const QString &type, - Qt::GestureState state) - : QObject(dd, parent) -{ - Q_D(QGesture); - d->type = type; - d->state = state; -} -/*! - Destroys the gesture object. +/*! \fn bool QGesture::filterEvent(QEvent *event) + + Parses input \a event and emits a signal when detects a gesture. + + In your reimplementation of this function, if you want to filter the \a + event out, i.e. stop it being handled further, return true; otherwise + return false; + + This is a pure virtual function that needs to be implemented in subclasses. */ -QGesture::~QGesture() -{ -} -/*! - \property QGesture::type +/*! \fn void QGesture::started() - \brief The type of the gesture. + The signal is emitted when the gesture is started. Extended information + about the gesture is contained in the signal sender object. + + In addition to started(), a triggered() signal should also be emitted. */ -QString QGesture::type() const -{ - return d_func()->type; -} +/*! \fn void QGesture::triggered() -/*! - \property QGesture::state + The signal is emitted when the gesture is detected. Extended information + about the gesture is contained in the signal sender object. +*/ - \brief The current state of the gesture. +/*! \fn void QGesture::finished() + + The signal is emitted when the gesture is finished. Extended information + about the gesture is contained in the signal sender object. */ -Qt::GestureState QGesture::state() const -{ - return d_func()->state; -} -/*! - Translates the internal gesture properties that represent - coordinates by \a offset. +/*! \fn void QGesture::cancelled() - Custom gesture recognizer developer have to re-implement this - function if they want to store custom properties that represent - coordinates. + The signal is emitted when the gesture is cancelled, for example the reset() + function is called while the gesture was in the process of emitting a + triggered() signal. Extended information about the gesture is contained in + the sender object. */ -void QGesture::translate(const QPoint &offset) -{ - Q_D(QGesture); - d->rect.translate(offset); - d->hotSpot += offset; - d->startPos += offset; - d->lastPos += offset; - d->pos += offset; -} + /*! - \property QGesture::rect + Creates a new gesture handler object and marks it as a child of \a parent. + + The \a parent object is also the default event source for the gesture, + meaning that the gesture installs itself as an event filter for the \a + parent. - \brief The bounding rect of a gesture. + \sa setGraphicsItem() */ -QRect QGesture::rect() const +QGesture::QGesture(QObject *parent) + : QObject(*new QGesturePrivate, parent) { - return d_func()->rect; + if (parent) + installEventFilter(parent); } -void QGesture::setRect(const QRect &rect) +/*! \internal + */ +QGesture::QGesture(QGesturePrivate &dd, QObject *parent) + : QObject(dd, parent) { - d_func()->rect = rect; + if (parent) + installEventFilter(parent); } /*! - \property QGesture::hotSpot - - \brief The center point of a gesture. + Destroys the gesture object. */ -QPoint QGesture::hotSpot() const +QGesture::~QGesture() { - return d_func()->hotSpot; } -void QGesture::setHotSpot(const QPoint &point) +/*! \internal + */ +bool QGesture::eventFilter(QObject *receiver, QEvent *event) { - d_func()->hotSpot = point; + Q_D(QGesture); + if (d->graphicsItem && receiver == parent()) + return false; + return filterEvent(event); } /*! - \property QGesture::startTime + \property QGesture::state - \brief The time when the gesture has started. + \brief The current state of the gesture. */ -QDateTime QGesture::startTime() const +Qt::GestureState QGesture::state() const { - return d_func()->startTime; + return d_func()->state; } -/*! - \property QGesture::duration - - \brief The duration time of a gesture. -*/ -uint QGesture::duration() const +void QGesture::setState(Qt::GestureState state) { - return d_func()->duration; + d_func()->state = state; } /*! \property QGesture::startPos - \brief The start position of the pointer. + \brief The start position of the gesture (if relevant). */ QPoint QGesture::startPos() const { @@ -239,7 +215,7 @@ void QGesture::setStartPos(const QPoint &point) /*! \property QGesture::lastPos - \brief The last recorded position of the pointer. + \brief The last recorded position of the gesture (if relevant). */ QPoint QGesture::lastPos() const { @@ -254,7 +230,7 @@ void QGesture::setLastPos(const QPoint &point) /*! \property QGesture::pos - \brief The current position of the pointer. + \brief The current position of the gesture (if relevant). */ QPoint QGesture::pos() const { @@ -266,66 +242,48 @@ void QGesture::setPos(const QPoint &point) d_func()->pos = point; } -/*! \fn void QGesture::setAccepted(bool accepted) - Marks the gesture with the value of \a accepted. - */ - -/*! \fn bool QGesture::isAccepted() const - Returns true if the gesture is marked accepted. - */ - -/*! \fn void QGesture::accept() - Marks the gesture accepted. -*/ - -/*! \fn void QGesture::ignore() - Marks the gesture ignored. -*/ - /*! - \class QPanningGesture - \since 4.6 + Sets the \a graphicsItem the gesture is filtering events for. - \brief The QPanningGesture class represents a Pan gesture, - providing additional information related to panning. + The gesture will install an event filter to the \a graphicsItem and + redirect them to the filterEvent() function. - This class is provided for convenience, panning direction - information is also contained in the QGesture object in it's - properties. + \sa graphicsItem() */ - -/*! \internal -*/ -QPanningGesture::QPanningGesture(QObject *parent) - : QGesture(*new QPanningGesturePrivate, parent, - qt_getStandardGestureTypeName(Qt::PanGesture)) -{ -} - -/*! \internal -*/ -QPanningGesture::~QPanningGesture() +void QGesture::setGraphicsItem(QGraphicsItem *graphicsItem) { + Q_D(QGesture); + if (d->graphicsItem && d->eventFilterProxyGraphicsItem) + d->graphicsItem->removeSceneEventFilter(d->eventFilterProxyGraphicsItem); + d->graphicsItem = graphicsItem; + if (!d->eventFilterProxyGraphicsItem) + d->eventFilterProxyGraphicsItem = new QEventFilterProxyGraphicsItem(this); + if (graphicsItem) + graphicsItem->installSceneEventFilter(d->eventFilterProxyGraphicsItem); } /*! - \property QPanningGesture::lastDirection + Returns the graphics item the gesture is filtering events for. - \brief The last recorded direction of panning. + \sa setGraphicsItem() */ -Qt::DirectionType QPanningGesture::lastDirection() const +QGraphicsItem* QGesture::graphicsItem() const { - return d_func()->lastDirection; + return d_func()->graphicsItem; } -/*! - \property QPanningGesture::direction +/*! \fn void QGesture::reset() - \brief The current direction of panning. + Resets the internal state of the gesture. This function might be called by + the filterEvent() implementation in a derived class, or by the user to + cancel a gesture. The base class implementation emits the cancelled() + signal if the state() of the gesture wasn't empty. */ -Qt::DirectionType QPanningGesture::direction() const +void QGesture::reset() { - return d_func()->direction; + if (state() != Qt::NoGesture) + emit cancelled(); + setState(Qt::NoGesture); } QT_END_NAMESPACE diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h index f3c95cc..b5abdd2 100644 --- a/src/gui/kernel/qgesture.h +++ b/src/gui/kernel/qgesture.h @@ -55,50 +55,32 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) +class QGraphicsItem; class QGesturePrivate; class Q_GUI_EXPORT QGesture : public QObject { Q_OBJECT Q_DECLARE_PRIVATE(QGesture) - Q_PROPERTY(QString type READ type) Q_PROPERTY(Qt::GestureState state READ state) - Q_PROPERTY(QDateTime startTime READ startTime) - Q_PROPERTY(uint duration READ duration) - - Q_PROPERTY(QRect rect READ rect WRITE setRect) - Q_PROPERTY(QPoint hotSpot READ hotSpot WRITE setHotSpot) Q_PROPERTY(QPoint startPos READ startPos WRITE setStartPos) Q_PROPERTY(QPoint lastPos READ lastPos WRITE setLastPos) Q_PROPERTY(QPoint pos READ pos WRITE setPos) public: - QGesture(QObject *parent, const QString &type, - Qt::GestureState state = Qt::GestureStarted); - QGesture(QObject *parent, - const QString &type, const QPoint &startPos, - const QPoint &lastPos, const QPoint &pos, const QRect &rect, - const QPoint &hotSpot, const QDateTime &startTime, - uint duration, Qt::GestureState state); - virtual ~QGesture(); - - inline void setAccepted(bool accepted) { m_accept = accepted; } - inline bool isAccepted() const { return m_accept; } - - inline void accept() { m_accept = true; } - inline void ignore() { m_accept = false; } - - QString type() const; - Qt::GestureState state() const; + explicit QGesture(QObject *parent = 0); + ~QGesture(); + + virtual bool filterEvent(QEvent *event) = 0; + + void setGraphicsItem(QGraphicsItem *); + QGraphicsItem *graphicsItem() const; - QDateTime startTime() const; - uint duration() const; + virtual void reset(); - QRect rect() const; - void setRect(const QRect &rect); - QPoint hotSpot() const; - void setHotSpot(const QPoint &point); + Qt::GestureState state() const; + void setState(Qt::GestureState state); QPoint startPos() const; void setStartPos(const QPoint &point); @@ -108,45 +90,19 @@ public: void setPos(const QPoint &point); protected: - QGesture(QGesturePrivate &dd, QObject *parent, const QString &type, - Qt::GestureState state = Qt::GestureStarted); - virtual void translate(const QPoint &offset); + QGesture(QGesturePrivate &dd, QObject *parent); + bool eventFilter(QObject*, QEvent*); -private: - ushort m_accept : 1; - - friend class QGestureManager; - friend class QApplication; - friend class QGraphicsScene; - friend class QGraphicsScenePrivate; - friend class QGestureRecognizerPan; - friend class QDoubleTapGestureRecognizer; - friend class QTapAndHoldGestureRecognizer; -}; - -class QPanningGesturePrivate; -class Q_GUI_EXPORT QPanningGesture : public QGesture -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QPanningGesture) - - Q_PROPERTY(Qt::DirectionType lastDirection READ lastDirection) - Q_PROPERTY(Qt::DirectionType direction READ direction) - -public: - Qt::DirectionType lastDirection() const; - Qt::DirectionType direction() const; +signals: + void started(); + void triggered(); + void finished(); + void cancelled(); private: - QPanningGesture(QObject *parent = 0); - ~QPanningGesture(); - - friend class QGestureRecognizerPan; + friend class QWidget; }; -Q_DECLARE_METATYPE(Qt::DirectionType) -Q_DECLARE_METATYPE(Qt::GestureState) - QT_END_NAMESPACE QT_END_HEADER diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h index caf851e..99f572f 100644 --- a/src/gui/kernel/qgesture_p.h +++ b/src/gui/kernel/qgesture_p.h @@ -56,10 +56,12 @@ #include "qrect.h" #include "qpoint.h" #include "qdatetime.h" +#include "qgesture.h" #include "private/qobject_p.h" QT_BEGIN_NAMESPACE +class QObject; class QGraphicsItem; class QGesturePrivate : public QObjectPrivate { @@ -67,47 +69,28 @@ class QGesturePrivate : public QObjectPrivate public: QGesturePrivate() - : state(Qt::NoGesture), graphicsItem(0), singleshot(0), duration(0) { } + : graphicsItem(0), eventFilterProxyGraphicsItem(0), state(Qt::NoGesture) + { + } void init(const QPoint &startPos, const QPoint &lastPos, - const QPoint &pos, const QRect &rect, - const QPoint &hotSpot, const QDateTime &startTime, - uint duration) + const QPoint &pos) { - this->rect = rect; - this->hotSpot = hotSpot; - this->startTime = startTime; - this->duration = duration; this->startPos = startPos; this->lastPos = lastPos; this->pos = pos; } - QString type; - Qt::GestureState state; - - QPointer widget; QGraphicsItem *graphicsItem; - uint singleshot:1; + QGraphicsItem *eventFilterProxyGraphicsItem; + + Qt::GestureState state; - QRect rect; - QPoint hotSpot; - QDateTime startTime; - uint duration; QPoint startPos; QPoint lastPos; QPoint pos; }; -class QPanningGesturePrivate : public QGesturePrivate -{ - Q_DECLARE_PUBLIC(QPanningGesture) - -public: - Qt::DirectionType lastDirection; - Qt::DirectionType direction; -}; - QT_END_NAMESPACE #endif // QGESTURE_P_H diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp deleted file mode 100644 index 20abda9..0000000 --- a/src/gui/kernel/qgesturemanager.cpp +++ /dev/null @@ -1,644 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui 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 "qgesturemanager_p.h" -#include "qgesture.h" -#include "qgesture_p.h" -#include "qevent.h" - -#include "qapplication.h" -#include "qapplication_p.h" -#include "qwidget.h" -#include "qwidget_p.h" - -#include "qgesturestandardrecognizers_p.h" - -#include "qdebug.h" - -// #define GESTURE_DEBUG -#ifndef GESTURE_DEBUG -# define DEBUG if (0) qDebug -#else -# define DEBUG qDebug -#endif - -QT_BEGIN_NAMESPACE - -bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); - -static const unsigned int MaximumGestureRecognitionTimeout = 2000; - -QGestureManager::QGestureManager(QObject *parent) - : QObject(parent), eventDeliveryDelayTimeout(300), - delayedPressTimer(0), lastMousePressReceiver(0), lastMousePressEvent(QEvent::None, QPoint(), Qt::NoButton, 0, 0), - lastGestureId(0), state(NotGesture) -{ - qRegisterMetaType(); - qRegisterMetaType(); - - recognizers << new QDoubleTapGestureRecognizer(this); - recognizers << new QTapAndHoldGestureRecognizer(this); - recognizers << new QGestureRecognizerPan(this); - - foreach(QGestureRecognizer *r, recognizers) - connect(r, SIGNAL(stateChanged(QGestureRecognizer::Result)), - this, SLOT(recognizerStateChanged(QGestureRecognizer::Result))); -} - -void QGestureManager::addRecognizer(QGestureRecognizer *recognizer) -{ - recognizer->setParent(this); - recognizers << recognizer; -} - -void QGestureManager::removeRecognizer(QGestureRecognizer *recognizer) -{ - recognizers.remove(recognizer); -} - -bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event) -{ - QPoint currentPos; - switch (event->type()) { - case QEvent::MouseButtonPress: - case QEvent::MouseButtonRelease: - case QEvent::MouseButtonDblClick: - case QEvent::MouseMove: - currentPos = static_cast(event)->pos(); break; - default: break; - } - - const QMap &grabbedGestures = qApp->d_func()->grabbedGestures; - - bool ret = false; - QSet startedGestures; - QSet finishedGestures; - QSet newMaybeGestures; - QSet cancelledGestures; - QSet notGestures; - if (state == NotGesture || state == MaybeGesture) { - DEBUG() << "QGestureManager: current event processing state: " - << (state == NotGesture ? "NotGesture" : "MaybeGesture"); - - QSet stillMaybeGestures; - // try other recognizers. - foreach(QGestureRecognizer *r, recognizers) { - if (grabbedGestures.value(r->gestureType(), 0) <= 0) - continue; - QGestureRecognizer::Result result = r->filterEvent(event); - if (result == QGestureRecognizer::GestureStarted) { - DEBUG() << "QGestureManager: gesture started: " << r; - startedGestures << r; - } else if (result == QGestureRecognizer::GestureFinished) { - DEBUG() << "QGestureManager: gesture finished: " << r; - finishedGestures << r; - } else if (result == QGestureRecognizer::MaybeGesture) { - DEBUG() << "QGestureManager: maybe gesture: " << r; - newMaybeGestures << r; - } else if (result == QGestureRecognizer::NotGesture) { - // if it was maybe gesture, but isn't a gesture anymore. - DEBUG() << "QGestureManager: not gesture: " << r; - notGestures << r; - } - } - Q_ASSERT(activeGestures.isEmpty()); - activeGestures += startedGestures; - for(QMap::iterator it = maybeGestures.begin(); - it != maybeGestures.end();) { - QGestureRecognizer *r = it.key(); - if (startedGestures.contains(r) || finishedGestures.contains(r) || - notGestures.contains(r)) { - killTimer(it.value()); - it = maybeGestures.erase(it); - } else { - ++it; - } - } - foreach(QGestureRecognizer *r, newMaybeGestures) { - if (!maybeGestures.contains(r)) { - int timerId = startTimer(MaximumGestureRecognitionTimeout); - if (!timerId) - qWarning("QGestureManager: couldn't start timer!"); - maybeGestures.insert(r, timerId); - } - } - if (!finishedGestures.isEmpty() || !startedGestures.isEmpty()) { - // gesture found! - ret = true; - QSet started; - foreach(QGestureRecognizer *r, finishedGestures) { - if (QGesture *gesture = r->getGesture()) { - started << gesture; - gesture->d_func()->singleshot = true; - } - } - foreach(QGestureRecognizer *r, startedGestures) { - if (QGesture *gesture = r->getGesture()) { - started << gesture; - gesture->d_func()->singleshot = false; - } - } - - if (!activeGestures.isEmpty()) { - DEBUG() << "QGestureManager: new state = Gesture"; - state = Gesture; - } else if (!maybeGestures.isEmpty()) { - DEBUG() << "QGestureManager: new state = Maybe"; - state = MaybeGesture; - } else { - DEBUG() << "QGestureManager: new state = NotGesture"; - state = NotGesture; - } - - Q_ASSERT(!started.isEmpty()); - ret = sendGestureEvent(receiver, started, QSet()); - } else if (!maybeGestures.isEmpty()) { - if (state != MaybeGesture) { - // We got a new set of events that look like a start - // of some gesture, so we switch to state MaybeGesture - // and wait for more events. - DEBUG() << "QGestureManager: new state = Maybe. Waiting for events"; - state = MaybeGesture; - // start gesture timer - } else { - // we still not sure if it is a gesture or not. - } - } else if (state == MaybeGesture) { - // last time we thought it looks like gesture, but now we - // know for sure that it isn't. - DEBUG() << "QGestureManager: new state = NotGesture"; - state = NotGesture; - } - foreach(QGestureRecognizer *r, finishedGestures) - r->reset(); - foreach(QGestureRecognizer *r, cancelledGestures) - r->reset(); - foreach(QGestureRecognizer *r, notGestures) - r->reset(); - } else if (state == Gesture) { - DEBUG() << "QGestureManager: current event processing state: Gesture"; - Q_ASSERT(!activeGestures.isEmpty()); - - foreach(QGestureRecognizer *r, recognizers) { - if (grabbedGestures.value(r->gestureType(), 0) <= 0) - continue; - QGestureRecognizer::Result result = r->filterEvent(event); - if (result == QGestureRecognizer::GestureStarted) { - DEBUG() << "QGestureManager: gesture started: " << r; - startedGestures << r; - } else if (result == QGestureRecognizer::GestureFinished) { - DEBUG() << "QGestureManager: gesture finished: " << r; - finishedGestures << r; - } else if (result == QGestureRecognizer::MaybeGesture) { - DEBUG() << "QGestureManager: maybe gesture: " << r; - newMaybeGestures << r; - } else if (result == QGestureRecognizer::NotGesture) { - // if it was an active gesture, but isn't a gesture anymore. - if (activeGestures.contains(r)) { - DEBUG() << "QGestureManager: cancelled gesture: " << r; - cancelledGestures << r; - } else { - DEBUG() << "QGestureManager: not gesture: " << r; - notGestures << r; - } - } - } - - for(QMap::iterator it = maybeGestures.begin(); - it != maybeGestures.end();) { - QGestureRecognizer *r = it.key(); - if (startedGestures.contains(r) || finishedGestures.contains(r) || - notGestures.contains(r)) { - killTimer(it.value()); - it = maybeGestures.erase(it); - } else { - ++it; - } - } - foreach(QGestureRecognizer *r, newMaybeGestures) { - if (!maybeGestures.contains(r)) { - int timerId = startTimer(MaximumGestureRecognitionTimeout); - if (!timerId) - qWarning("QGestureManager: couldn't start timer!"); - maybeGestures.insert(r, timerId); - } - } - QSet started, updated; - if (!finishedGestures.isEmpty() || !startedGestures.isEmpty()) { - // another gesture found! - ret = true; - foreach(QGestureRecognizer *r, finishedGestures) { - if (QGesture *gesture = r->getGesture()) { - gesture->d_func()->singleshot = !activeGestures.contains(r); - if (gesture->d_func()->singleshot) - started << gesture; - else - updated << gesture; - } - } - foreach(QGestureRecognizer *r, startedGestures) { - if (QGesture *gesture = r->getGesture()) { - gesture->d_func()->singleshot = !activeGestures.contains(r); - if (gesture->d_func()->singleshot) - started << gesture; - else - updated << gesture; - } - } - } - activeGestures -= newMaybeGestures; - activeGestures -= cancelledGestures; - activeGestures += startedGestures; - activeGestures -= finishedGestures; - QSet cancelledGestureNames; - foreach(QGestureRecognizer *r, cancelledGestures) - cancelledGestureNames << r->gestureType(); - ret = sendGestureEvent(receiver, started, updated, cancelledGestureNames); - - foreach(QGestureRecognizer *r, finishedGestures) - r->reset(); - foreach(QGestureRecognizer *r, cancelledGestures) - r->reset(); - foreach(QGestureRecognizer *r, notGestures) - r->reset(); - if (!activeGestures.isEmpty()) { - // nothing changed, we are still handling a gesture - } else if (!maybeGestures.isEmpty()) { - DEBUG() << "QGestureManager: new state = Maybe. Waiting for events: " << maybeGestures; - state = MaybeGesture; - } else { - DEBUG() << "QGestureManager: new state = NotGesture"; - state = NotGesture; - } - } - - if (delayedPressTimer && state == Gesture) { - DEBUG() << "QGestureManager: gesture started. Forgetting about postponed mouse press event"; - killTimer(delayedPressTimer); - delayedPressTimer = 0; - lastMousePressReceiver = 0; - } else if (delayedPressTimer && (state == NotGesture || - event->type() == QEvent::MouseButtonRelease)) { - // not a gesture or released button too fast, so replay press - // event back. - DEBUG() << "QGestureManager: replaying mouse press event"; - QMap::const_iterator it = maybeGestures.begin(), - e = maybeGestures.end();; - for (; it != e; ++it) { - it.key()->reset(); - killTimer(it.value()); - } - maybeGestures.clear(); - state = NotGesture; - - if (lastMousePressReceiver) { - QApplication::sendEvent(lastMousePressReceiver, &lastMousePressEvent); - if (event->type() == QEvent::MouseButtonRelease) { - QMouseEvent *me = static_cast(event); - QMouseEvent move(QEvent::MouseMove, me->pos(), me->globalPos(), me->button(), - me->buttons(), me->modifiers()); - QApplication::sendEvent(lastMousePressReceiver, &move); - ret = false; - } - lastMousePressReceiver = 0; - } - lastMousePressReceiver = 0; - killTimer(delayedPressTimer); - delayedPressTimer = 0; - } else if (state == MaybeGesture && event->type() == QEvent::MouseButtonPress - && eventDeliveryDelayTimeout) { - // postpone the press event delivery until we know for - // sure whether it is a gesture. - DEBUG() << "QGestureManager: postponing mouse press event"; - QMouseEvent *me = static_cast(event); - lastMousePressReceiver = receiver; - lastMousePressEvent = QMouseEvent(QEvent::MouseButtonPress, me->pos(), - me->globalPos(), me->button(), - me->buttons(), me->modifiers()); - Q_ASSERT(delayedPressTimer == 0); - delayedPressTimer = startTimer(eventDeliveryDelayTimeout); - if (!delayedPressTimer) - qWarning("QGestureManager: couldn't start delayed press timer!"); - ret = true; - } - if (delayedPressTimer && event->type() == QEvent::MouseMove) { - // if we have postponed a mouse press event, postpone all - // subsequent mouse move events as well. - ret = true; - } - - lastPos = currentPos; - return ret; -} - -void QGestureManager::timerEvent(QTimerEvent *event) -{ - if (event->timerId() == delayedPressTimer) { - DEBUG() << "QGestureManager: replaying mouse press event due to timeout"; - // sanity checks - Q_ASSERT(state != Gesture); - - QMap::const_iterator it = maybeGestures.begin(), - e = maybeGestures.end();; - for (; it != e; ++it) { - it.key()->reset(); - killTimer(it.value()); - } - maybeGestures.clear(); - state = NotGesture; - - if (lastMousePressReceiver) { - // we neither received a mouse release event nor gesture - // started, so we replay stored mouse press event. - QApplication::sendEvent(lastMousePressReceiver, &lastMousePressEvent); - lastMousePressReceiver = 0; - } - - lastMousePressReceiver = 0; - killTimer(delayedPressTimer); - delayedPressTimer = 0; - } else { - // sanity checks, remove later - Q_ASSERT((state == Gesture && !activeGestures.isEmpty()) || (state != Gesture && activeGestures.isEmpty())); - - typedef QMap MaybeGestureMap; - for (MaybeGestureMap::iterator it = maybeGestures.begin(), e = maybeGestures.end(); - it != e; ++it) { - if (it.value() == event->timerId()) { - DEBUG() << "QGestureManager: gesture timeout."; - QGestureRecognizer *r = it.key(); - r->reset(); - maybeGestures.erase(it); - killTimer(event->timerId()); - break; - } - } - - if (state == MaybeGesture && maybeGestures.isEmpty()) { - DEBUG() << "QGestureManager: new state = NotGesture because of timeout"; - state = NotGesture; - } - } -} - -bool QGestureManager::inGestureMode() -{ - return state == Gesture; -} - -void QGestureManager::recognizerStateChanged(QGestureRecognizer::Result result) -{ - QGestureRecognizer *recognizer = qobject_cast(sender()); - if (!recognizer) - return; - if (qApp->d_func()->grabbedGestures.value(recognizer->gestureType(), 0) <= 0) { - recognizer->reset(); - return; - } - - switch (result) { - case QGestureRecognizer::GestureStarted: - case QGestureRecognizer::GestureFinished: { - if (result == QGestureRecognizer::GestureStarted) { - DEBUG() << "QGestureManager: gesture started: " << recognizer; - activeGestures << recognizer; - DEBUG() << "QGestureManager: new state = Gesture"; - state = Gesture; - } else { - DEBUG() << "QGestureManager: gesture finished: " << recognizer; - } - if (maybeGestures.contains(recognizer)) { - killTimer(maybeGestures.value(recognizer)); - maybeGestures.remove(recognizer); - } - QSet gestures; - if (QGesture *gesture = recognizer->getGesture()) - gestures << gesture; - if(!gestures.isEmpty()) { - //FIXME: sendGestureEvent(targetWidget, gestures); - } - if (result == QGestureRecognizer::GestureFinished) - recognizer->reset(); - } - break; - case QGestureRecognizer::MaybeGesture: { - DEBUG() << "QGestureManager: maybe gesture: " << recognizer; - if (activeGestures.contains(recognizer)) { - //FIXME: sendGestureEvent(targetWidget, QSet(), QSet() << recognizer->gestureType()); - } - if (!maybeGestures.contains(recognizer)) { - int timerId = startTimer(MaximumGestureRecognitionTimeout); - if (!timerId) - qWarning("QGestureManager: couldn't start timer!"); - maybeGestures.insert(recognizer, timerId); - } - } - break; - case QGestureRecognizer::NotGesture: - DEBUG() << "QGestureManager: not gesture: " << recognizer; - if (maybeGestures.contains(recognizer)) { - killTimer(maybeGestures.value(recognizer)); - maybeGestures.remove(recognizer); - } - recognizer->reset(); - break; - default: - Q_ASSERT(false); - } - - if (delayedPressTimer && state == Gesture) { - killTimer(delayedPressTimer); - delayedPressTimer = 0; - } -} - -bool QGestureManager::sendGestureEvent(QWidget *receiver, - const QSet &startedGestures, - const QSet &updatedGestures, - const QSet &cancelled) -{ - DEBUG() << "QGestureManager::sendGestureEvent: sending to" << receiver - << "gestures:" << startedGestures << "," << updatedGestures - << "cancelled:" << cancelled; - // grouping gesture objects by receiver widgets. - typedef QMap > WidgetGesturesMap; - WidgetGesturesMap widgetGestures; - for(QSet::const_iterator it = startedGestures.begin(), e = startedGestures.end(); - it != e; ++it) { - QGesture *g = *it; - QGesturePrivate *gd = g->d_func(); - if (receiver) { - // find the target widget - gd->widget = 0; - gd->graphicsItem = 0; - QWidget *w = receiver; - QPoint offset; - const QString gestureType = g->type(); - while (w) { - if (w->d_func()->hasGesture(gestureType)) - break; - if (w->isWindow()) { - w = 0; - break; - } - offset += w->pos(); - w = w->parentWidget(); - } - if (w && w != gd->widget) { - DEBUG() << "QGestureManager::sendGestureEvent:" << g << "propagating to widget" << w << "offset" << offset; - g->translate(offset); - } - gd->widget = w; - } - if (!gd->widget) { - DEBUG() << "QGestureManager: didn't find a widget to send gesture event (" - << g->type() << ") for tree:" << receiver; - // TODO: maybe we should reset gesture recognizers when nobody interested in its gestures. - continue; - } - widgetGestures[gd->widget].insert(g); - } - - QSet ignoredGestures; - bool ret = false; - for(WidgetGesturesMap::const_iterator it = widgetGestures.begin(), e = widgetGestures.end(); - it != e; ++it) { - QWidget *receiver = it.key(); - Q_ASSERT(receiver != 0 /*should be taken care above*/); - QSet gestures = it.value(); - // mark all gestures as ignored by default - for(QSet::iterator it = gestures.begin(), e = gestures.end(); it != e; ++it) - (*it)->ignore(); - // TODO: send cancelled gesture event to the widget that received the original gesture! - QGestureEvent event(gestures, cancelled); - DEBUG() << "QGestureManager::sendGestureEvent: sending now to" << receiver - << "gestures" << gestures; - bool processed = qt_sendSpontaneousEvent(receiver, &event); - QSet started = startedGestures & gestures; - DEBUG() << "QGestureManager::sendGestureEvent:" << - (event.isAccepted() ? "" : "not") << "all gestures were accepted"; - if (!started.isEmpty() && !(processed && event.isAccepted())) { - // there are started gestures events that weren't - // accepted, so propagating each gesture independently. - if (event.isAccepted()) { - foreach(QGesture *g, started) - g->accept(); - } - QSet::const_iterator it = started.begin(), - e = started.end(); - for(; it != e; ++it) { - QGesture *g = *it; - if (processed && g->isAccepted()) { - ret = true; - continue; - } - // if it wasn't accepted, find the first parent widget - // that is subscribed to the gesture. - QGesturePrivate *gd = g->d_func(); - QWidget *w = gd->widget; - gd->widget = 0; - - if (w && !w->isWindow()) { - g->translate(w->pos()); - w = w->parentWidget(); - QPoint offset; - const QString gestureType = g->type(); - while (w) { - if (w->d_func()->hasGesture(gestureType)) { - DEBUG() << "QGestureManager::sendGestureEvent:" << receiver - << "didn't accept gesture" << g << "propagating to" << w; - ignoredGestures.insert(g); - gd->widget = w; - break; - } - if (w->isWindow()) { - w = 0; - break; - } - offset += w->pos(); - w = w->parentWidget(); - } - if (w) { - g->translate(offset); - } else { - DEBUG() << "QGestureManager::sendGestureEvent:" << receiver - << "didn't accept gesture" << g << "and nobody wants it"; - } - } - } - } - } - if (ignoredGestures.isEmpty()) - return ret; - // try to send all gestures that were ignored to the next parent - return sendGestureEvent(0, ignoredGestures, QSet(), cancelled) || ret; -} - -int QGestureManager::eventDeliveryDelay() const -{ - return eventDeliveryDelayTimeout; -} - -void QGestureManager::setEventDeliveryDelay(int ms) -{ - eventDeliveryDelayTimeout = ms; -} - -int QGestureManager::makeGestureId(const QString &name) -{ - gestureIdMap[++lastGestureId] = name; - return lastGestureId; -} - -void QGestureManager::releaseGestureId(int gestureId) -{ - gestureIdMap.remove(gestureId); -} - -QString QGestureManager::gestureNameFromId(int gestureId) const -{ - return gestureIdMap.value(gestureId); -} - -QT_END_NAMESPACE - -#include "moc_qgesturemanager_p.cpp" - diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/gui/kernel/qgesturemanager_p.h deleted file mode 100644 index 8656590..0000000 --- a/src/gui/kernel/qgesturemanager_p.h +++ /dev/null @@ -1,126 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui 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$ -** -****************************************************************************/ - -#ifndef QGESTUREMANAGER_P_H -#define QGESTUREMANAGER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qlist.h" -#include "qset.h" -#include "qevent.h" -#include "qbasictimer.h" -#include "qpointer.h" - -#include "qgesturerecognizer.h" - -QT_BEGIN_NAMESPACE - -class QWidget; -class Q_AUTOTEST_EXPORT QGestureManager : public QObject -{ - Q_OBJECT -public: - QGestureManager(QObject *parent); - - int eventDeliveryDelay() const; - void setEventDeliveryDelay(int ms); - - void addRecognizer(QGestureRecognizer *recognizer); - void removeRecognizer(QGestureRecognizer *recognizer); - - bool filterEvent(QWidget *receiver, QEvent *event); - bool inGestureMode(); - - int makeGestureId(const QString &name); - void releaseGestureId(int gestureId); - QString gestureNameFromId(int gestureId) const; - - // declared in qapplication.cpp - static QGestureManager* instance(); - - bool sendGestureEvent(QWidget *receiver, - const QSet &startedGestures, - const QSet &updatedGestures, - const QSet &cancelled = QSet()); - -protected: - void timerEvent(QTimerEvent *event); - -private slots: - void recognizerStateChanged(QGestureRecognizer::Result); - -private: - QSet activeGestures; - QMap maybeGestures; - QSet recognizers; - - QPoint lastPos; - - int eventDeliveryDelayTimeout; - int delayedPressTimer; - QPointer lastMousePressReceiver; - QMouseEvent lastMousePressEvent; - - QMap gestureIdMap; - int lastGestureId; - - enum State { - Gesture, - NotGesture, - MaybeGesture // that mean timers are up and waiting for some - // more events, and input events are handled by - // gesture recognizer explicitely - } state; -}; - -QT_END_NAMESPACE - -#endif // QGESTUREMANAGER_P_H diff --git a/src/gui/kernel/qgesturerecognizer.cpp b/src/gui/kernel/qgesturerecognizer.cpp deleted file mode 100644 index 30889d7..0000000 --- a/src/gui/kernel/qgesturerecognizer.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui 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 "qgesturerecognizer.h" -#include "qgesture.h" - -#include -#include - -QT_BEGIN_NAMESPACE - -QString qt_getStandardGestureTypeName(Qt::GestureType gestureType); - -/*! - \class QGestureRecognizer - \since 4.6 - - \brief The QGestureRecognizer class is the base class for - implementing custom gestures. - - This is a base class, to create a custom gesture type, you should - subclass it and implement its pure virtual functions. - - Usually gesture recognizer implements state machine, storing its - state internally in the recognizer object. The recognizer receives - input events through the \l{QGestureRecognizer::}{filterEvent()} - virtual function and decides whether the parsed event should - change the state of the recognizer - i.e. if the event starts or - ends a gesture or if it isn't related to gesture at all. -*/ - -/*! - \enum QGestureRecognizer::Result - \since 4.6 - - This enum type defines the state of the gesture recognizer. - - \value Ignore Gesture recognizer ignores the event. - - \value NotGesture Not a gesture. - - \value GestureStarted The continuous gesture has started. When the - recognizer is in this state, a \l{QGestureEvent}{gesture event} - containing QGesture objects returned by the - \l{QGestureRecognizer::}{getGesture()} will be sent to a widget. - - \value GestureFinished The gesture has ended. A - \l{QGestureEvent}{gesture event} will be sent to a widget. - - \value MaybeGesture Gesture recognizer hasn't decided yet if a - gesture has started, but it might start soon after the following - events are received by the recognizer. This means that gesture - manager shouldn't reset() the internal state of the gesture - recognizer. -*/ - -/*! \fn QGestureRecognizer::Result QGestureRecognizer::filterEvent(const QEvent *event) - - This is a pure virtual function that needs to be implemented in - subclasses. - - Parses input \a event and returns the result, which specifies - whether the event sequence is a gesture or not. -*/ - -/*! \fn QGesture* QGestureRecognizer::getGesture() - - Returns a gesture object that will be send to the widget. This - function is called when the gesture recognizer changed its state - to QGestureRecognizer::GestureStarted or - QGestureRecognizer::GestureFinished. - - The returned QGesture object must point to the same object in a - single gesture sequence. - - The gesture object is owned by the recognizer itself. -*/ - -/*! \fn void QGestureRecognizer::reset() - - Resets the internal state of the gesture recognizer. -*/ - -/*! \fn void QGestureRecognizer::stateChanged(QGestureRecognizer::Result result) - - The gesture recognizer might emit the stateChanged() signal when - the gesture state changes asynchronously, i.e. without any event - being filtered through filterEvent(). \a result specifies whether - the event sequence is a gesture or not. -*/ - -QGestureRecognizerPrivate::QGestureRecognizerPrivate() - : gestureType(Qt::UnknownGesture) -{ -} - -/*! - Creates a new gesture recognizer object that handles gestures of - the specific \a gestureType as a child of \a parent. - - \sa QApplication::addGestureRecognizer(), - QApplication::removeGestureRecognizer(), -*/ -QGestureRecognizer::QGestureRecognizer(const QString &gestureType, QObject *parent) - : QObject(*new QGestureRecognizerPrivate, parent) -{ - Q_D(QGestureRecognizer); - d->customGestureType = gestureType; -} - -/*! - Returns the name of the gesture that is handled by the recognizer. -*/ -QString QGestureRecognizer::gestureType() const -{ - Q_D(const QGestureRecognizer); - if (d->gestureType == Qt::UnknownGesture) - return d->customGestureType; - return qt_getStandardGestureTypeName(d->gestureType); -} - -QT_END_NAMESPACE diff --git a/src/gui/kernel/qgesturerecognizer.h b/src/gui/kernel/qgesturerecognizer.h deleted file mode 100644 index 2c1c61b..0000000 --- a/src/gui/kernel/qgesturerecognizer.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui 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$ -** -****************************************************************************/ - -#ifndef QGESTURERECOGNIZER_H -#define QGESTURERECOGNIZER_H - -#include "qevent.h" -#include "qlist.h" -#include "qset.h" - -QT_BEGIN_NAMESPACE - -class QGesture; -class QGestureRecognizerPrivate; -class Q_GUI_EXPORT QGestureRecognizer : public QObject -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QGestureRecognizer) - -public: - enum Result - { - Ignore, - NotGesture, - GestureStarted, //TODO: rename to just Gesture? - GestureFinished, - MaybeGesture - }; - - explicit QGestureRecognizer(const QString &gestureType, QObject *parent = 0); - - QString gestureType() const; - - virtual QGestureRecognizer::Result filterEvent(const QEvent* event) = 0; - virtual QGesture* getGesture() = 0; - virtual void reset() = 0; - -signals: - void stateChanged(QGestureRecognizer::Result result); - -private: - friend class QDoubleTapGestureRecognizer; - friend class QTapAndHoldGestureRecognizer; - friend class QGestureRecognizerPan; -}; - -QT_END_NAMESPACE - -#endif // QGESTURERECOGNIZER_P_H diff --git a/src/gui/kernel/qgesturerecognizer_p.h b/src/gui/kernel/qgesturerecognizer_p.h deleted file mode 100644 index e250201..0000000 --- a/src/gui/kernel/qgesturerecognizer_p.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui 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$ -** -****************************************************************************/ - -#ifndef QGESTURERECOGNIZER_P_H -#define QGESTURERECOGNIZER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include - -QT_BEGIN_NAMESPACE - -class QGestureRecognizerPrivate : public QObjectPrivate -{ -public: - QGestureRecognizerPrivate(); - -public: - Qt::GestureType gestureType; - QString customGestureType; -}; - -QT_END_NAMESPACE - -#endif // QGESTURERECOGNIZER_P_H diff --git a/src/gui/kernel/qgesturestandardrecognizers.cpp b/src/gui/kernel/qgesturestandardrecognizers.cpp deleted file mode 100644 index b108994..0000000 --- a/src/gui/kernel/qgesturestandardrecognizers.cpp +++ /dev/null @@ -1,306 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui 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 "qgesturestandardrecognizers_p.h" -#include "qgesture_p.h" -#include "qgesturerecognizer_p.h" - -// #define GESTURE_RECOGNIZER_DEBUG -#ifndef GESTURE_RECOGNIZER_DEBUG -# define DEBUG if (0) qDebug -#else -# define DEBUG qDebug -#endif - -QT_BEGIN_NAMESPACE - -QString qt_getStandardGestureTypeName(Qt::GestureType gestureType) -{ - switch (gestureType) { - case Qt::TapGesture: - return QLatin1String("__QTapGesture"); - case Qt::DoubleTapGesture: - return QLatin1String("__QDoubleTapGesture"); - case Qt::TrippleTapGesture: - return QLatin1String("__QTrippleTapGesture"); - case Qt::TapAndHoldGesture: - return QLatin1String("__QTapAndHoldGesture"); - case Qt::PanGesture: - return QLatin1String("__QPanGesture"); - case Qt::PinchGesture: - return QLatin1String("__QPinchGesture"); - case Qt::UnknownGesture: - break; - } - qFatal("QGestureRecognizer::gestureType: got an unhandled gesture type."); - return QLatin1String("__unknown_gesture"); -} - -// -// QGestureRecognizerPan -// - -QGestureRecognizerPan::QGestureRecognizerPan(QObject *parent) - : QGestureRecognizer(QString(), parent), - mousePressed(false), gestureState(Qt::NoGesture), - lastDirection(Qt::NoDirection), currentDirection(Qt::NoDirection) -{ - Q_D(QGestureRecognizer); - d->gestureType = Qt::PanGesture; -} - -QGestureRecognizer::Result QGestureRecognizerPan::filterEvent(const QEvent *event) -{ - if (event->type() == QEvent::MouseButtonPress) { - const QMouseEvent *ev = static_cast(event); - if (currentDirection != Qt::NoDirection) { - DEBUG() << "Pan: MouseButtonPress: fail. another press during pan"; - reset(); - return QGestureRecognizer::NotGesture; - } - if (ev->button() != Qt::LeftButton) { - return QGestureRecognizer::NotGesture; - } - DEBUG() << "Pan: MouseButtonPress: maybe gesture started"; - mousePressed = true; - pressedPos = lastPos = currentPos = ev->pos(); - return QGestureRecognizer::MaybeGesture; - } else if (event->type() == QEvent::MouseButtonRelease) { - const QMouseEvent *ev = static_cast(event); - if (mousePressed && currentDirection != Qt::NoDirection - && ev->button() == Qt::LeftButton) { - DEBUG() << "Pan: MouseButtonRelease: pan detected"; - gestureState = Qt::GestureFinished; - currentPos = ev->pos(); - internalReset(); - return QGestureRecognizer::GestureFinished; - } - DEBUG() << "Pan: MouseButtonRelease: some weird release detected, ignoring"; - reset(); - return QGestureRecognizer::NotGesture; - } else if (event->type() == QEvent::MouseMove) { - if (!mousePressed) - return QGestureRecognizer::NotGesture; - const QMouseEvent *ev = static_cast(event); - lastPos = currentPos; - currentPos = ev->pos(); - Qt::DirectionType newDirection = - simpleRecognizer.addPosition(ev->pos()).direction; - DEBUG() << "Pan: MouseMove: simplerecognizer result = " << newDirection; - QGestureRecognizer::Result result = QGestureRecognizer::NotGesture; - if (currentDirection == Qt::NoDirection) { - if (newDirection == Qt::NoDirection) { - result = QGestureRecognizer::MaybeGesture; - } else { - result = QGestureRecognizer::GestureStarted; - gestureState = Qt::GestureStarted; - } - } else { - result = QGestureRecognizer::GestureStarted; - gestureState = Qt::GestureUpdated; - } - if (newDirection != Qt::NoDirection) { - if (currentDirection != newDirection) - lastDirection = currentDirection; - currentDirection = newDirection; - } - return result; - } - return QGestureRecognizer::Ignore; -} - -QGesture* QGestureRecognizerPan::getGesture() -{ - if (currentDirection == Qt::NoDirection) - return 0; - QPanningGesturePrivate *d = gesture.d_func(); - d->startPos = pressedPos; - d->lastPos = lastPos; - d->pos = currentPos; - d->hotSpot = pressedPos; - d->state = gestureState; - d->lastDirection = lastDirection; - d->direction = currentDirection; - - return &gesture; -} - -void QGestureRecognizerPan::reset() -{ - mousePressed = false; - lastDirection = Qt::NoDirection; - currentDirection = Qt::NoDirection; - gestureState = Qt::NoGesture; - diagonalRecognizer.reset(); - simpleRecognizer.reset(); -} - -void QGestureRecognizerPan::internalReset() -{ - mousePressed = false; - diagonalRecognizer.reset(); - simpleRecognizer.reset(); -} - - -// -// QDoubleTapGestureRecognizer -// -QDoubleTapGestureRecognizer::QDoubleTapGestureRecognizer(QObject *parent) - : QGestureRecognizer(QString(), parent), - gesture(0, qt_getStandardGestureTypeName(Qt::DoubleTapGesture)) -{ - Q_D(QGestureRecognizer); - d->gestureType = Qt::DoubleTapGesture; -} - -QGestureRecognizer::Result QDoubleTapGestureRecognizer::filterEvent(const QEvent *event) -{ - if (event->type() == QEvent::MouseButtonPress) { - const QMouseEvent *ev = static_cast(event); - if (pressedPosition.isNull()) { - pressedPosition = ev->pos(); - return QGestureRecognizer::MaybeGesture; - } else if ((pressedPosition - ev->pos()).manhattanLength() < 10) { - return QGestureRecognizer::GestureFinished; - } - return QGestureRecognizer::NotGesture; - } else if (event->type() == QEvent::MouseButtonRelease) { - const QMouseEvent *ev = static_cast(event); - if (!pressedPosition.isNull() && (pressedPosition - ev->pos()).manhattanLength() < 10) - return QGestureRecognizer::MaybeGesture; - return QGestureRecognizer::NotGesture; - } else if (event->type() == QEvent::MouseButtonDblClick) { - const QMouseEvent *ev = static_cast(event); - pressedPosition = ev->pos(); - return QGestureRecognizer::GestureFinished; - } - return QGestureRecognizer::NotGesture; -} - -QGesture* QDoubleTapGestureRecognizer::getGesture() -{ - QGesturePrivate *d = gesture.d_func(); - d->startPos = pressedPosition; - d->lastPos = pressedPosition; - d->pos = pressedPosition; - d->hotSpot = pressedPosition; - d->state = Qt::GestureFinished; - return &gesture; -} - -void QDoubleTapGestureRecognizer::reset() -{ - pressedPosition = QPoint(); -} - -// -// QTapAndHoldGestureRecognizer -// -const int QTapAndHoldGestureRecognizer::iterationCount = 40; -const int QTapAndHoldGestureRecognizer::iterationTimeout = 50; - -QTapAndHoldGestureRecognizer::QTapAndHoldGestureRecognizer(QObject *parent) - : QGestureRecognizer(QString(), parent), - gesture(0, qt_getStandardGestureTypeName(Qt::TapAndHoldGesture)), - iteration(0) -{ - Q_D(QGestureRecognizer); - d->gestureType = Qt::TapAndHoldGesture; -} - -QGestureRecognizer::Result QTapAndHoldGestureRecognizer::filterEvent(const QEvent *event) -{ - if (event->type() == QEvent::MouseButtonPress) { - const QMouseEvent *ev = static_cast(event); - if (timer.isActive()) - timer.stop(); - timer.start(QTapAndHoldGestureRecognizer::iterationTimeout, this); - pressedPosition = ev->pos(); - return QGestureRecognizer::MaybeGesture; - } else if (event->type() == QEvent::MouseMove) { - const QMouseEvent *ev = static_cast(event); - if ((pressedPosition - ev->pos()).manhattanLength() < 15) - return QGestureRecognizer::GestureStarted; - else - return QGestureRecognizer::NotGesture; - } else if (event->type() == QEvent::MouseButtonRelease) { - timer.stop(); - return QGestureRecognizer::NotGesture; - } - return QGestureRecognizer::Ignore; -} - -void QTapAndHoldGestureRecognizer::timerEvent(QTimerEvent *event) -{ - if (event->timerId() != timer.timerId()) - return; - if (iteration == QTapAndHoldGestureRecognizer::iterationCount) { - timer.stop(); - emit stateChanged(QGestureRecognizer::GestureFinished); - } else { - emit stateChanged(QGestureRecognizer::GestureStarted); - } - ++iteration; -} - -QGesture* QTapAndHoldGestureRecognizer::getGesture() -{ - QGesturePrivate *d = gesture.d_func(); - d->startPos = pressedPosition; - d->lastPos = pressedPosition; - d->pos = pressedPosition; - d->hotSpot = pressedPosition; - if (iteration >= QTapAndHoldGestureRecognizer::iterationCount) - d->state = Qt::GestureFinished; - else - d->state = iteration == 0 ? Qt::GestureStarted : Qt::GestureUpdated; - return &gesture; -} - -void QTapAndHoldGestureRecognizer::reset() -{ - pressedPosition = QPoint(); - timer.stop(); - iteration = 0; -} - -QT_END_NAMESPACE diff --git a/src/gui/kernel/qgesturestandardrecognizers_p.h b/src/gui/kernel/qgesturestandardrecognizers_p.h deleted file mode 100644 index 8abc1fb..0000000 --- a/src/gui/kernel/qgesturestandardrecognizers_p.h +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui 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$ -** -****************************************************************************/ - -#ifndef QGESTURESTANDARDRECOGNIZERS_P_H -#define QGESTURESTANDARDRECOGNIZERS_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qevent.h" -#include "qbasictimer.h" -#include "qdebug.h" - -#include "qgesture.h" -#include "qgesturerecognizer.h" -#include "private/qdirectionrecognizer_p.h" - -QT_BEGIN_NAMESPACE - -class QGestureRecognizerPan : public QGestureRecognizer -{ - Q_OBJECT -public: - QGestureRecognizerPan(QObject *parent); - - QGestureRecognizer::Result filterEvent(const QEvent *event); - QGesture* getGesture(); - void reset(); - -private: - void internalReset(); - - QPanningGesture gesture; - - QPoint pressedPos; - QPoint lastPos; - QPoint currentPos; - bool mousePressed; - Qt::GestureState gestureState; - Qt::DirectionType lastDirection; - Qt::DirectionType currentDirection; - QDirectionDiagonalRecognizer diagonalRecognizer; - QDirectionSimpleRecognizer simpleRecognizer; -}; - -class QDoubleTapGestureRecognizer : public QGestureRecognizer -{ - Q_OBJECT -public: - QDoubleTapGestureRecognizer(QObject *parent); - - QGestureRecognizer::Result filterEvent(const QEvent *event); - QGesture* getGesture(); - void reset(); - -private: - QGesture gesture; - QPoint pressedPosition; -}; - -class QTapAndHoldGestureRecognizer : public QGestureRecognizer -{ - Q_OBJECT -public: - QTapAndHoldGestureRecognizer(QObject *parent); - - QGestureRecognizer::Result filterEvent(const QEvent *event); - QGesture* getGesture(); - void reset(); - -protected: - void timerEvent(QTimerEvent *event); - -private: - QGesture gesture; - QPoint pressedPosition; - QBasicTimer timer; - int iteration; - static const int iterationCount; - static const int iterationTimeout; -}; - -QT_END_NAMESPACE - -#endif // QGESTURESTANDARDRECOGNIZERS_P_H diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp new file mode 100644 index 0000000..c8b11c5 --- /dev/null +++ b/src/gui/kernel/qstandardgestures.cpp @@ -0,0 +1,254 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui 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 "qstandardgestures.h" +#include "qstandardgestures_p.h" + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \class QPanGesture + \since 4.6 + + \brief The QPanGesture class represents a Pan gesture, + providing additional information related to panning. +*/ + +/*! + Creates a new Pan gesture handler object and marks it as a child of \a + parent. + + On some platform like Windows it's necessary to provide a non-null widget + as \a parent to get native gesture support. +*/ +QPanGesture::QPanGesture(QWidget *parent) + : QGesture(*new QPanGesturePrivate, parent) +{ +#ifdef Q_WS_WIN + if (parent) { + QApplicationPrivate* getQApplicationPrivateInternal(); + QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); + qAppPriv->widgetGestures[parent].pan = this; + } +#endif +} + +/*! \internal */ +bool QPanGesture::event(QEvent *event) +{ +#ifdef Q_WS_WIN + QApplicationPrivate* getQApplicationPrivateInternal(); + switch (event->type()) { + case QEvent::ParentAboutToChange: + if (QWidget *w = qobject_cast(parent())) + getQApplicationPrivateInternal()->widgetGestures[w].pan = 0; + break; + case QEvent::ParentChange: + if (QWidget *w = qobject_cast(parent())) + getQApplicationPrivateInternal()->widgetGestures[w].pan = this; + break; + default: + break; + } +#endif + return QObject::event(event); +} + +/*! \internal */ +bool QPanGesture::filterEvent(QEvent *event) +{ + Q_D(QPanGesture); + if (!event->spontaneous()) + return false; + const QTouchEvent *ev = static_cast(event); + if (event->type() == QEvent::TouchBegin) { + d->touchPoints = ev->touchPoints(); + const QPoint p = ev->touchPoints().at(0).pos().toPoint(); + setStartPos(p); + setLastPos(p); + setPos(p); + return false; + } else if (event->type() == QEvent::TouchEnd) { + if (state() != Qt::NoGesture) { + setState(Qt::GestureFinished); + setLastPos(pos()); + setPos(ev->touchPoints().at(0).pos().toPoint()); + emit triggered(); + emit finished(); + } + setState(Qt::NoGesture); + reset(); + } else if (event->type() == QEvent::TouchUpdate) { + d->touchPoints = ev->touchPoints(); + QPointF pt = d->touchPoints.at(0).pos() - d->touchPoints.at(0).startPos(); + setLastPos(pos()); + setPos(ev->touchPoints().at(0).pos().toPoint()); + if (pt.x() > 10 || pt.y() > 10 || pt.x() < -10 || pt.y() < -10) { + if (state() == Qt::NoGesture) + setState(Qt::GestureStarted); + else + setState(Qt::GestureUpdated); + emit triggered(); + } + } + return false; +} + +/*! \internal */ +void QPanGesture::reset() +{ + Q_D(QPanGesture); + d->touchPoints.clear(); +} + +/*! + \property QPanGesture::totalOffset + + Specifies a total pan offset since the start of the gesture. +*/ +QSize QPanGesture::totalOffset() const +{ + QPoint pt = pos() - startPos(); + return QSize(pt.x(), pt.y()); +} + +/*! + \property QPanGesture::lastOffset + + Specifies a pan offset since the last time the gesture was + triggered. +*/ +QSize QPanGesture::lastOffset() const +{ + QPoint pt = pos() - lastPos(); + return QSize(pt.x(), pt.y()); +} + +/*! + \class QTapAndHoldGesture + \since 4.6 + + \brief The QTapAndHoldGesture class represents a Tap-and-Hold gesture, + providing additional information. +*/ + +const int QTapAndHoldGesturePrivate::iterationCount = 40; +const int QTapAndHoldGesturePrivate::iterationTimeout = 50; + +/*! + Creates a new Tap and Hold gesture handler object and marks it as a child + of \a parent. + + On some platforms like Windows there is a system-wide tap and hold gesture + that cannot be overriden, hence the gesture might never trigger and default + context menu will be shown instead. +*/ +QTapAndHoldGesture::QTapAndHoldGesture(QWidget *parent) + : QGesture(*new QTapAndHoldGesturePrivate, parent) +{ +} + +/*! \internal */ +bool QTapAndHoldGesture::filterEvent(QEvent *event) +{ + Q_D(QTapAndHoldGesture); + if (!event->spontaneous()) + return false; + const QTouchEvent *ev = static_cast(event); + switch (event->type()) { + case QEvent::TouchBegin: { + if (d->timer.isActive()) + d->timer.stop(); + d->timer.start(QTapAndHoldGesturePrivate::iterationTimeout, this); + const QPoint p = ev->touchPoints().at(0).pos().toPoint(); + setStartPos(p); + setLastPos(p); + setPos(p); + break; + } + case QEvent::TouchUpdate: + if (ev->touchPoints().size() != 1) + reset(); + else if ((startPos() - ev->touchPoints().at(0).pos().toPoint()).manhattanLength() > 15) + reset(); + break; + case QEvent::TouchEnd: + reset(); + break; + default: + break; + } + return false; +} + +/*! \internal */ +void QTapAndHoldGesture::timerEvent(QTimerEvent *event) +{ + Q_D(QTapAndHoldGesture); + if (event->timerId() != d->timer.timerId()) + return; + if (d->iteration == QTapAndHoldGesturePrivate::iterationCount) { + d->timer.stop(); + setState(Qt::GestureFinished); + emit triggered(); + } else { + setState(Qt::GestureStarted); + emit triggered(); + } + ++d->iteration; +} + +/*! \internal */ +void QTapAndHoldGesture::reset() +{ + Q_D(QTapAndHoldGesture); + if (state() != Qt::NoGesture) + emit cancelled(); + setState(Qt::NoGesture); + d->timer.stop(); + d->iteration = 0; +} + +QT_END_NAMESPACE diff --git a/src/gui/kernel/qstandardgestures.h b/src/gui/kernel/qstandardgestures.h new file mode 100644 index 0000000..db96ef6 --- /dev/null +++ b/src/gui/kernel/qstandardgestures.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui 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$ +** +****************************************************************************/ + +#ifndef QSTANDARDGESTURES_H +#define QSTANDARDGESTURES_H + +#include "qevent.h" +#include "qbasictimer.h" +#include "qdebug.h" + +#include "qgesture.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class QPanGesturePrivate; +class Q_GUI_EXPORT QPanGesture : public QGesture +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QPanGesture) + + Q_PROPERTY(QSize totalOffset READ totalOffset) + Q_PROPERTY(QSize lastOffset READ lastOffset) + +public: + QPanGesture(QWidget *parent); + + bool filterEvent(QEvent *event); + void reset(); + + QSize totalOffset() const; + QSize lastOffset() const; + +protected: + bool event(QEvent *event); + +private: + friend class QWidget; +}; + +class QTapAndHoldGesturePrivate; +class Q_GUI_EXPORT QTapAndHoldGesture : public QGesture +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QTapAndHoldGesture) + +public: + QTapAndHoldGesture(QWidget *parent); + + bool filterEvent(QEvent *event); + void reset(); + +protected: + void timerEvent(QTimerEvent *event); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QSTANDARDGESTURES_H diff --git a/src/gui/kernel/qstandardgestures_p.h b/src/gui/kernel/qstandardgestures_p.h new file mode 100644 index 0000000..bb11c9f --- /dev/null +++ b/src/gui/kernel/qstandardgestures_p.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui 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$ +** +****************************************************************************/ + +#ifndef QSTANDARDGESTURES_P_H +#define QSTANDARDGESTURES_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qevent.h" +#include "qbasictimer.h" +#include "qdebug.h" + +#include "qgesture.h" +#include "qgesture_p.h" + +QT_BEGIN_NAMESPACE + +class QPanGesturePrivate : public QGesturePrivate +{ + Q_DECLARE_PUBLIC(QPanGesture) + +public: + QPanGesturePrivate() { } + + QList touchPoints; +}; + +class QTapAndHoldGesturePrivate : public QGesturePrivate +{ + Q_DECLARE_PUBLIC(QTapAndHoldGesture) + +public: + QTapAndHoldGesturePrivate() + : iteration(0) { } + + QBasicTimer timer; + int iteration; + static const int iterationCount; + static const int iterationTimeout; +}; + +QT_END_NAMESPACE + +#endif // QSTANDARDGESTURES_P_H diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 9a834aa..611cb44 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -82,6 +82,8 @@ #include "private/qstyle_p.h" #include "private/qinputcontext_p.h" #include "qfileinfo.h" +#include "qstandardgestures.h" +#include "qstandardgestures_p.h" #if defined (Q_WS_WIN) # include @@ -107,9 +109,9 @@ #include "private/qgraphicsproxywidget_p.h" #include "QtGui/qabstractscrollarea.h" #include "private/qabstractscrollarea_p.h" +#include "private/qevent_p.h" #include "private/qgraphicssystem_p.h" -#include "private/qgesturemanager_p.h" // widget/widget data creation count //#define QWIDGET_EXTRA_DEBUG @@ -128,8 +130,6 @@ Q_GUI_EXPORT void qt_x11_set_global_double_buffer(bool enable) } #endif -QString qt_getStandardGestureTypeName(Qt::GestureType); - static inline bool qRectIntersects(const QRect &r1, const QRect &r2) { return (qMax(r1.left(), r2.left()) <= qMin(r1.right(), r2.right()) && @@ -7484,8 +7484,6 @@ bool QWidget::event(QEvent *event) #ifndef QT_NO_WHEELEVENT case QEvent::Wheel: #endif - case QEvent::Gesture: - return false; default: break; } @@ -7880,9 +7878,6 @@ bool QWidget::event(QEvent *event) d->needWindowChange = false; break; #endif - case QEvent::Gesture: - event->ignore(); - break; case QEvent::TouchBegin: case QEvent::TouchUpdate: case QEvent::TouchEnd: @@ -7920,6 +7915,59 @@ bool QWidget::event(QEvent *event) (void) QApplication::sendEvent(this, &mouseEvent); break; } +#ifdef Q_WS_WIN + case QEvent::WinGesture: { + QWinGestureEvent *ev = static_cast(event); + QApplicationPrivate *qAppPriv = qApp->d_func(); + QApplicationPrivate::WidgetStandardGesturesMap::iterator it; + it = qAppPriv->widgetGestures.find(this); + if (it != qAppPriv->widgetGestures.end()) { + Qt::GestureState state = Qt::GestureUpdated; + if (qAppPriv->lastGestureId == 0) + state = Qt::GestureStarted; + QWinGestureEvent::Type type = ev->gestureType; + if (ev->gestureType == QWinGestureEvent::GestureEnd) { + type = (QWinGestureEvent::Type)qAppPriv->lastGestureId; + state = Qt::GestureFinished; + } + + QGesture *gesture = 0; + switch (type) { + case QWinGestureEvent::Pan: { + QPanGesture *pan = it.value().pan; + gesture = pan; + if (state == Qt::GestureStarted) { + gesture->setStartPos(ev->position); + gesture->setLastPos(ev->position); + } else { + gesture->setLastPos(gesture->pos()); + } + gesture->setPos(ev->position); + break; + } + case QWinGestureEvent::Pinch: + break; + default: + break; + } + if (gesture) { + gesture->setState(state); + if (state == Qt::GestureStarted) + emit gesture->started(); + emit gesture->triggered(); + if (state == Qt::GestureFinished) + emit gesture->finished(); + event->accept(); + } + if (ev->gestureType == QWinGestureEvent::GestureEnd) { + qAppPriv->lastGestureId = 0; + } else { + qAppPriv->lastGestureId = type; + } + } + break; + } +#endif #ifndef QT_NO_PROPERTIES case QEvent::DynamicPropertyChange: { const QByteArray &propName = static_cast(event)->propertyName(); @@ -11016,105 +11064,6 @@ QWindowSurface *QWidget::windowSurface() const return bs ? bs->windowSurface : 0; } -/*! - \since 4.6 - - Subscribes the widget to the specified \a gesture type. - - Returns the id of the gesture. - - \sa releaseGesture(), setGestureEnabled() -*/ -int QWidget::grabGesture(const QString &gesture) -{ - Q_D(QWidget); - int id = d->grabGesture(QGestureManager::instance()->makeGestureId(gesture)); - if (d->extra && d->extra->proxyWidget) - d->extra->proxyWidget->QGraphicsItem::d_ptr->grabGesture(id); - return id; -} - -int QWidgetPrivate::grabGesture(int gestureId) -{ - gestures << gestureId; - ++qApp->d_func()->grabbedGestures[QGestureManager::instance()->gestureNameFromId(gestureId)]; - return gestureId; -} - -bool QWidgetPrivate::releaseGesture(int gestureId) -{ - QApplicationPrivate *qAppPriv = qApp->d_func(); - if (gestures.contains(gestureId)) { - QString name = QGestureManager::instance()->gestureNameFromId(gestureId); - Q_ASSERT(qAppPriv->grabbedGestures[name] > 0); - --qAppPriv->grabbedGestures[name]; - gestures.remove(gestureId); - return true; - } - return false; -} - -bool QWidgetPrivate::hasGesture(const QString &name) const -{ - QGestureManager *gm = QGestureManager::instance(); - QSet::const_iterator it = gestures.begin(), - e = gestures.end(); - for (; it != e; ++it) { - if (gm->gestureNameFromId(*it) == name) - return true; - } - return false; -} - -/*! - \since 4.6 - - Subscribes the widget to the specified \a gesture type. - - Returns the id of the gesture. - - \sa releaseGesture(), setGestureEnabled() -*/ -int QWidget::grabGesture(Qt::GestureType gesture) -{ - return grabGesture(qt_getStandardGestureTypeName(gesture)); -} - -/*! - \since 4.6 - - Unsubscribes the widget from a gesture, which is specified by the - \a gestureId. - - \sa grabGesture(), setGestureEnabled() -*/ -void QWidget::releaseGesture(int gestureId) -{ - Q_D(QWidget); - if (d->releaseGesture(gestureId)) { - if (d->extra && d->extra->proxyWidget) - d->extra->proxyWidget->QGraphicsItem::d_ptr->releaseGesture(gestureId); - QGestureManager::instance()->releaseGestureId(gestureId); - } -} - -/*! - \since 4.6 - - If \a enable is true, the gesture with the given \a gestureId is - enabled; otherwise the gesture is disabled. - - The id of the gesture is returned by the grabGesture(). - - \sa grabGesture(), releaseGesture() -*/ -void QWidget::setGestureEnabled(int gestureId, bool enable) -{ - Q_UNUSED(gestureId); - Q_UNUSED(enable); - //### -} - void QWidgetPrivate::getLayoutItemMargins(int *left, int *top, int *right, int *bottom) const { if (left) diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h index 1667275..bc9952c 100644 --- a/src/gui/kernel/qwidget.h +++ b/src/gui/kernel/qwidget.h @@ -90,7 +90,6 @@ class QDragLeaveEvent; class QDropEvent; class QShowEvent; class QHideEvent; -class QGestureEvent; class QInputContext; class QIcon; class QWindowSurface; @@ -612,11 +611,6 @@ public: void setWindowSurface(QWindowSurface *surface); QWindowSurface *windowSurface() const; - int grabGesture(const QString &gesture); - int grabGesture(Qt::GestureType gesture); - void releaseGesture(int gestureId); - void setGestureEnabled(int gestureId, bool enable = true); - Q_SIGNALS: void customContextMenuRequested(const QPoint &pos); @@ -752,7 +746,6 @@ private: friend bool isWidgetOpaque(const QWidget *); friend class QGLWidgetPrivate; #endif - friend class QGestureManager; #ifdef Q_WS_X11 friend void qt_net_update_user_time(QWidget *tlw, unsigned long timestamp); friend void qt_net_remove_user_time(QWidget *tlw); diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 7385e83..626950e 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -523,11 +523,6 @@ public: QList actions; #endif - QSet gestures; - int grabGesture(int gestureId); - bool releaseGesture(int gestureId); - bool hasGesture(const QString &type) const; - // Bit fields. uint high_attributes[3]; // the low ones are in QWidget::widget_attributes QPalette::ColorRole fg_role : 8; diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp index e1beb98..66572b8 100644 --- a/src/gui/widgets/qabstractscrollarea.cpp +++ b/src/gui/widgets/qabstractscrollarea.cpp @@ -51,10 +51,13 @@ #include "qdebug.h" #include "qboxlayout.h" #include "qpainter.h" +#include "qstandardgestures.h" #include "qabstractscrollarea_p.h" #include +#include + #ifdef Q_WS_MAC #include #include @@ -157,6 +160,9 @@ QAbstractScrollAreaPrivate::QAbstractScrollAreaPrivate() :hbar(0), vbar(0), vbarpolicy(Qt::ScrollBarAsNeeded), hbarpolicy(Qt::ScrollBarAsNeeded), viewport(0), cornerWidget(0), left(0), top(0), right(0), bottom(0), xoffset(0), yoffset(0), viewportFilter(0) +#ifdef Q_WS_WIN + , singleFingerPanEnabled(false) +#endif { } @@ -290,6 +296,31 @@ void QAbstractScrollAreaPrivate::init() layoutChildren(); } +void QAbstractScrollAreaPrivate::setupGestures() +{ +#ifdef Q_OS_WIN + if (!viewport) + return; + QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); + bool needh = (hbarpolicy == Qt::ScrollBarAlwaysOn + || (hbarpolicy == Qt::ScrollBarAsNeeded && hbar->minimum() < hbar->maximum())); + + bool needv = (vbarpolicy == Qt::ScrollBarAlwaysOn + || (vbarpolicy == Qt::ScrollBarAsNeeded && vbar->minimum() < vbar->maximum())); + if (qAppPriv->SetGestureConfig && (needh || needv)) { + GESTURECONFIG gc[1]; + gc[0].dwID = GID_PAN; + gc[0].dwWant = GC_PAN; + gc[0].dwBlock = 0; + if (needv && singleFingerPanEnabled) + gc[0].dwWant |= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY; + if (needh && singleFingerPanEnabled) + gc[0].dwWant |= GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY; + qAppPriv->SetGestureConfig(viewport->winId(), 0, 1, gc, sizeof(gc)); + } +#endif // Q_OS_WIN +} + void QAbstractScrollAreaPrivate::layoutChildren() { Q_Q(QAbstractScrollArea); @@ -909,8 +940,6 @@ bool QAbstractScrollArea::event(QEvent *e) case QEvent::DragMove: case QEvent::DragLeave: #endif - case QEvent::Gesture: - return false; case QEvent::StyleChange: case QEvent::LayoutDirectionChange: case QEvent::ApplicationLayoutDirectionChange: @@ -1239,6 +1268,7 @@ void QAbstractScrollAreaPrivate::_q_vslide(int y) void QAbstractScrollAreaPrivate::_q_showOrHideScrollBars() { layoutChildren(); + setupGestures(); } QPoint QAbstractScrollAreaPrivate::contentsOffset() const diff --git a/src/gui/widgets/qabstractscrollarea_p.h b/src/gui/widgets/qabstractscrollarea_p.h index 71a83cc..5d3494b 100644 --- a/src/gui/widgets/qabstractscrollarea_p.h +++ b/src/gui/widgets/qabstractscrollarea_p.h @@ -99,6 +99,11 @@ public: inline bool viewportEvent(QEvent *event) { return q_func()->viewportEvent(event); } QObject *viewportFilter; + +#ifdef Q_WS_WIN + bool singleFingerPanEnabled; +#endif + void setupGestures(); }; class QAbstractScrollAreaFilter : public QObject diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index bab6b89..c9d1d6e 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -66,6 +66,8 @@ #include #include +#include + #include #ifndef QT_NO_TEXTEDIT @@ -726,6 +728,9 @@ QPlainTextEditPrivate::QPlainTextEditPrivate() backgroundVisible = false; centerOnScroll = false; inDrag = false; +#ifdef Q_WS_WIN + singleFingerPanEnabled = true; +#endif } @@ -781,6 +786,9 @@ void QPlainTextEditPrivate::init(const QString &txt) #ifndef QT_NO_CURSOR viewport->setCursor(Qt::IBeamCursor); #endif + originalOffsetY = 0; + panGesture = new QPanGesture(q); + QObject::connect(panGesture, SIGNAL(triggered()), q, SLOT(_q_gestureTriggered())); } void QPlainTextEditPrivate::_q_repaintContents(const QRectF &contentsRect) @@ -2899,6 +2907,30 @@ QAbstractTextDocumentLayout::PaintContext QPlainTextEdit::getPaintContext() cons (\a available is true) or unavailable (\a available is false). */ +void QPlainTextEditPrivate::_q_gestureTriggered() +{ + Q_Q(QPlainTextEdit); + QPanGesture *g = qobject_cast(q->sender()); + if (!g) + return; + QScrollBar *hBar = q->horizontalScrollBar(); + QScrollBar *vBar = q->verticalScrollBar(); + if (g->state() == Qt::GestureStarted) + originalOffsetY = vBar->value(); + QSize totalOffset = g->totalOffset(); + if (!totalOffset.isNull()) { + if (QApplication::isRightToLeft()) + totalOffset.rwidth() *= -1; + // QPlainTextEdit scrolls by lines only in vertical direction + QFontMetrics fm(q->document()->defaultFont()); + int lineHeight = fm.height(); + int newX = hBar->value() - g->lastOffset().width(); + int newY = originalOffsetY - totalOffset.height()/lineHeight; + hbar->setValue(newX); + vbar->setValue(newY); + } +} + QT_END_NAMESPACE #include "moc_qplaintextedit.cpp" diff --git a/src/gui/widgets/qplaintextedit.h b/src/gui/widgets/qplaintextedit.h index dc0851b..35bbc37 100644 --- a/src/gui/widgets/qplaintextedit.h +++ b/src/gui/widgets/qplaintextedit.h @@ -269,6 +269,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_adjustScrollbars()) Q_PRIVATE_SLOT(d_func(), void _q_verticalScrollbarActionTriggered(int)) Q_PRIVATE_SLOT(d_func(), void _q_cursorPositionChanged()) + Q_PRIVATE_SLOT(d_func(), void _q_gestureTriggered()) friend class QPlainTextEditControl; }; diff --git a/src/gui/widgets/qplaintextedit_p.h b/src/gui/widgets/qplaintextedit_p.h index 5075fc4..ae584e0 100644 --- a/src/gui/widgets/qplaintextedit_p.h +++ b/src/gui/widgets/qplaintextedit_p.h @@ -72,6 +72,7 @@ class QMimeData; class QPlainTextEdit; class ExtraArea; +class QPanGesture; class QPlainTextEditControl : public QTextControl { @@ -173,6 +174,10 @@ public: void _q_cursorPositionChanged(); void _q_modificationChanged(bool); + + void _q_gestureTriggered(); + int originalOffsetY; + QPanGesture *panGesture; }; QT_END_NAMESPACE diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp index c8d8d04..e80df92 100644 --- a/src/gui/widgets/qtextedit.cpp +++ b/src/gui/widgets/qtextedit.cpp @@ -67,6 +67,8 @@ #include #include +#include + #include #endif @@ -111,6 +113,9 @@ QTextEditPrivate::QTextEditPrivate() preferRichText = false; showCursorOnInitialShow = true; inDrag = false; +#ifdef Q_WS_WIN + singleFingerPanEnabled = true; +#endif } void QTextEditPrivate::createAutoBulletList() @@ -178,6 +183,8 @@ void QTextEditPrivate::init(const QString &html) #ifndef QT_NO_CURSOR viewport->setCursor(Qt::IBeamCursor); #endif + panGesture = new QPanGesture(q); + QObject::connect(panGesture, SIGNAL(triggered()), q, SLOT(_q_gestureTriggered())); } void QTextEditPrivate::_q_repaintContents(const QRectF &contentsRect) @@ -2610,6 +2617,25 @@ void QTextEdit::ensureCursorVisible() d->control->ensureCursorVisible(); } +void QTextEditPrivate::_q_gestureTriggered() +{ + Q_Q(QTextEdit); + QPanGesture *g = qobject_cast(q->sender()); + if (!g) + return; + QScrollBar *hBar = q->horizontalScrollBar(); + QScrollBar *vBar = q->verticalScrollBar(); + QPoint delta = g->pos() - (g->lastPos().isNull() ? g->pos() : g->lastPos()); + if (!delta.isNull()) { + if (QApplication::isRightToLeft()) + delta.rx() *= -1; + int newX = hBar->value() - delta.x(); + int newY = vBar->value() - delta.y(); + hbar->setValue(newX); + vbar->setValue(newY); + } +} + /*! \enum QTextEdit::KeyboardAction diff --git a/src/gui/widgets/qtextedit.h b/src/gui/widgets/qtextedit.h index 617822a..9e10e07 100644 --- a/src/gui/widgets/qtextedit.h +++ b/src/gui/widgets/qtextedit.h @@ -414,6 +414,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_currentCharFormatChanged(const QTextCharFormat &)) Q_PRIVATE_SLOT(d_func(), void _q_adjustScrollbars()) Q_PRIVATE_SLOT(d_func(), void _q_ensureVisible(const QRectF &)) + Q_PRIVATE_SLOT(d_func(), void _q_gestureTriggered()) friend class QTextEditControl; friend class QTextDocument; friend class QTextControl; diff --git a/src/gui/widgets/qtextedit_p.h b/src/gui/widgets/qtextedit_p.h index e7609d6..249331e 100644 --- a/src/gui/widgets/qtextedit_p.h +++ b/src/gui/widgets/qtextedit_p.h @@ -70,7 +70,7 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_TEXTEDIT class QMimeData; - +class QPanGesture; class QTextEditPrivate : public QAbstractScrollAreaPrivate { Q_DECLARE_PUBLIC(QTextEdit) @@ -129,6 +129,9 @@ public: QString anchorToScrollToWhenVisible; + void _q_gestureTriggered(); + QPanGesture *panGesture; + #ifdef QT_KEYPAD_NAVIGATION QBasicTimer deleteAllTimer; #endif diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp index 6d3bc0a..d2ef64a 100644 --- a/tests/auto/gestures/tst_gestures.cpp +++ b/tests/auto/gestures/tst_gestures.cpp @@ -140,6 +140,13 @@ struct GestureState last.secondfinger.lastPoint = TouchPoint(); last.secondfinger.point = TouchPoint(); last.secondfinger.offset = QPoint(); + last.pan.delivered = false; + last.pan.startPoints[0] = TouchPoint(); + last.pan.startPoints[1] = TouchPoint(); + last.pan.lastPoints[0] = TouchPoint(); + last.pan.lastPoints[1] = TouchPoint(); + last.pan.points[0] = TouchPoint(); + last.pan.points[1] = TouchPoint(); last.cancelled.clear(); } }; @@ -760,7 +767,8 @@ void tst_Gestures::simpleGraphicsItem() scene.addItem(item); QApplication::processEvents(); - SingleshotEvent event(50, 80); + QPoint pt = view.mapFromScene(item->mapToScene(30, 30)); + SingleshotEvent event(pt.x(), pt.y()); sendSpontaneousEvent(&view, &event); QVERIFY(item->gesture.seenGestureEvent); QVERIFY(scene.gesture.seenGestureEvent); @@ -771,7 +779,9 @@ void tst_Gestures::simpleGraphicsItem() mainWidget->reset(); item->shouldAcceptSingleshotGesture = false; - SingleshotEvent event2(20, 40); + // outside of the graphicsitem + pt = view.mapFromScene(item->mapToScene(-10, -10)); + SingleshotEvent event2(pt.x(), pt.y()); sendSpontaneousEvent(&view, &event2); QVERIFY(!item->gesture.seenGestureEvent); QVERIFY(scene.gesture.seenGestureEvent); @@ -790,9 +800,11 @@ void tst_Gestures::overlappingGraphicsItems() scene.addItem(item); GraphicsItem *subitem1 = new GraphicsItem(50, 70); subitem1->setPos(70, 70); + subitem1->setZValue(1); scene.addItem(subitem1); GraphicsItem *subitem2 = new GraphicsItem(50, 70); subitem2->setPos(250, 70); + subitem2->setZValue(1); scene.addItem(subitem2); QApplication::processEvents(); @@ -802,13 +814,14 @@ void tst_Gestures::overlappingGraphicsItems() subitem1->grabSingleshotGesture(); subitem2->grabSecondFingerGesture(); - SingleshotEvent event(100, 100); + QPoint pt = view.mapFromScene(subitem1->mapToScene(20, 20)); + SingleshotEvent event(pt.x(), pt.y()); sendSpontaneousEvent(&view, &event); - QVERIFY(subitem1->gesture.seenGestureEvent); + QVERIFY(scene.gesture.seenGestureEvent); QVERIFY(!subitem2->gesture.seenGestureEvent); QVERIFY(!item->gesture.seenGestureEvent); - QVERIFY(scene.gesture.seenGestureEvent); QVERIFY(!mainWidget->gesture.seenGestureEvent); + QVERIFY(subitem1->gesture.seenGestureEvent); QVERIFY(subitem1->gesture.last.singleshot.delivered); item->reset(); @@ -818,12 +831,12 @@ void tst_Gestures::overlappingGraphicsItems() mainWidget->reset(); subitem1->shouldAcceptSingleshotGesture = false; - SingleshotEvent event2(100, 100); + SingleshotEvent event2(pt.x(), pt.y()); sendSpontaneousEvent(&view, &event2); - QVERIFY(subitem1->gesture.seenGestureEvent); + QVERIFY(scene.gesture.seenGestureEvent); QVERIFY(!subitem2->gesture.seenGestureEvent); + QVERIFY(subitem1->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); -- cgit v0.12 From 69b4be80a445985bdb8632dab4104236fe9b054d Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Tue, 30 Jun 2009 11:42:02 +0200 Subject: Benchmark test for quaternion multiplication. Reviewed-by: Rhys Weatherley --- tests/benchmarks/qquaternion/qquaternion.pro | 6 ++ tests/benchmarks/qquaternion/tst_qquaternion.cpp | 124 +++++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 tests/benchmarks/qquaternion/qquaternion.pro create mode 100644 tests/benchmarks/qquaternion/tst_qquaternion.cpp diff --git a/tests/benchmarks/qquaternion/qquaternion.pro b/tests/benchmarks/qquaternion/qquaternion.pro new file mode 100644 index 0000000..cd68423 --- /dev/null +++ b/tests/benchmarks/qquaternion/qquaternion.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_qquaternion + +SOURCES += tst_qquaternion.cpp + diff --git a/tests/benchmarks/qquaternion/tst_qquaternion.cpp b/tests/benchmarks/qquaternion/tst_qquaternion.cpp new file mode 100644 index 0000000..eaacf74 --- /dev/null +++ b/tests/benchmarks/qquaternion/tst_qquaternion.cpp @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** 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 +#include + +//TESTED_FILES= + +class tst_QQuaternion : public QObject +{ + Q_OBJECT + +public: + tst_QQuaternion(); + virtual ~tst_QQuaternion(); + +public slots: + void init(); + void cleanup(); + +private slots: + void multiply_data(); + void multiply(); +}; + +tst_QQuaternion::tst_QQuaternion() +{ +} + +tst_QQuaternion::~tst_QQuaternion() +{ +} + +void tst_QQuaternion::init() +{ +} + +void tst_QQuaternion::cleanup() +{ +} + +void tst_QQuaternion::multiply_data() +{ + QTest::addColumn("x1"); + QTest::addColumn("y1"); + QTest::addColumn("z1"); + QTest::addColumn("w1"); + QTest::addColumn("x2"); + QTest::addColumn("y2"); + QTest::addColumn("z2"); + QTest::addColumn("w2"); + + QTest::newRow("null") + << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f + << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f << (qreal)0.0f; + + QTest::newRow("unitvec") + << (qreal)1.0f << (qreal)0.0f << (qreal)0.0f << (qreal)1.0f + << (qreal)0.0f << (qreal)1.0f << (qreal)0.0f << (qreal)1.0f; + + QTest::newRow("complex") + << (qreal)1.0f << (qreal)2.0f << (qreal)3.0f << (qreal)7.0f + << (qreal)4.0f << (qreal)5.0f << (qreal)6.0f << (qreal)8.0f; +} + +void tst_QQuaternion::multiply() +{ + QFETCH(qreal, x1); + QFETCH(qreal, y1); + QFETCH(qreal, z1); + QFETCH(qreal, w1); + QFETCH(qreal, x2); + QFETCH(qreal, y2); + QFETCH(qreal, z2); + QFETCH(qreal, w2); + + QQuaternion q1(w1, x1, y1, z1); + QQuaternion q2(w2, x2, y2, z2); + + QBENCHMARK { + QQuaternion q3 = q1 * q2; + } +} + +QTEST_MAIN(tst_QQuaternion) +#include "tst_qquaternion.moc" -- cgit v0.12 From 1d651e82459c0480cb3e803a9d9452092ac9d502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Thu, 2 Jul 2009 18:01:33 +0200 Subject: More re-factoring of QGraphicsSceneIndex. New method: QGraphicsSceneIndex::estimateTopLevelItems. QGraphicsSceneIndex::estimateItems returns *all* items within the rect, but we are only interested in the top-levels (those that are within the rect themselves or have descendants within the rect) when doing recursive drawing/item-lookup. All auto-tests pass. Demos/examples/manualtests run fine. --- src/gui/graphicsview/qgraphicsscene.cpp | 46 +++++--------- src/gui/graphicsview/qgraphicsscene_bsp.cpp | 8 ++- src/gui/graphicsview/qgraphicsscene_bsp_p.h | 4 +- src/gui/graphicsview/qgraphicsscene_p.h | 17 +---- .../graphicsview/qgraphicsscenebsptreeindex.cpp | 72 ++++++++++++++-------- .../graphicsview/qgraphicsscenebsptreeindex_p.h | 8 ++- src/gui/graphicsview/qgraphicssceneindex.cpp | 21 +++++-- src/gui/graphicsview/qgraphicssceneindex_p.h | 10 +-- src/gui/graphicsview/qgraphicsscenelinearindex.cpp | 5 +- src/gui/graphicsview/qgraphicsscenelinearindex_p.h | 3 +- 10 files changed, 98 insertions(+), 96 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 3b1c8ad..85d05e9 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1085,36 +1085,6 @@ QGraphicsWidget *QGraphicsScenePrivate::windowForItem(const QGraphicsItem *item) return 0; } -QList QGraphicsScenePrivate::topLevelItemsInStackingOrder(const QTransform *const viewTransform, - const QRectF &sceneRect) -{ - if (indexMethod == QGraphicsScene::NoIndex || sceneRect.isNull()) { - ensureSortedTopLevelItems(); - return topLevelItems; - } - - const QList tmp = index->estimateItems(sceneRect, Qt::SortOrder(-1), - viewTransform ? *viewTransform : QTransform()); - // estimateItems returns a list of *all* items, but we are only interested - // in the top-levels (those that are within the rect themselves and those that - // have descendants within the rect). - // ### Look into how we can add this feature to the BSP. - QList tli; - for (int i = 0; i < tmp.size(); ++i) { - QGraphicsItem *topLevelItem = tmp.at(i)->topLevelItem(); - if (!topLevelItem->d_ptr->itemDiscovered) { - tli << topLevelItem; - topLevelItem->d_ptr->itemDiscovered = 1; - } - } - // Reset discovered bit. - for (int i = 0; i < tli.size(); ++i) - tli.at(i)->d_ptr->itemDiscovered = 0; - - qSort(tli.begin(), tli.end(), qt_notclosestLeaf); - return tli; -} - /*! \internal @@ -1759,7 +1729,7 @@ QList QGraphicsScene::collidingItems(const QGraphicsItem *item, // Does not support ItemIgnoresTransformations. QList tmp; - foreach (QGraphicsItem *itemInVicinity, d->index->estimateItems(item->sceneBoundingRect(), Qt::AscendingOrder, QTransform())) { + foreach (QGraphicsItem *itemInVicinity, d->index->estimateItems(item->sceneBoundingRect(), Qt::AscendingOrder)) { if (item != itemInVicinity && item->collidesWithItem(itemInVicinity, mode)) tmp << itemInVicinity; } @@ -4209,6 +4179,20 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte } } +void QGraphicsScenePrivate::drawItems(QPainter *painter, const QTransform *const viewTransform, + QRegion *exposedRegion, QWidget *widget) +{ + QRectF exposedSceneRect; + if (exposedRegion && indexMethod != QGraphicsScene::NoIndex) { + exposedSceneRect = exposedRegion->boundingRect().adjusted(-1, -1, 1, 1); + if (viewTransform) + exposedSceneRect = viewTransform->inverted().mapRect(exposedSceneRect); + } + const QList tli = index->estimateTopLevelItems(exposedSceneRect, Qt::DescendingOrder); + for (int i = 0; i < tli.size(); ++i) + drawSubtreeRecursive(tli.at(i), painter, viewTransform, exposedRegion, widget); +} + void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *painter, const QTransform *const viewTransform, QRegion *exposedRegion, QWidget *widget, diff --git a/src/gui/graphicsview/qgraphicsscene_bsp.cpp b/src/gui/graphicsview/qgraphicsscene_bsp.cpp index 7d30749..fb4b9a4 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp.cpp +++ b/src/gui/graphicsview/qgraphicsscene_bsp.cpp @@ -70,12 +70,15 @@ class QGraphicsSceneFindItemBspTreeVisitor : public QGraphicsSceneBspTreeVisitor { public: QList *foundItems; + bool onlyTopLevelItems; void visit(QList *items) { for (int i = 0; i < items->size(); ++i) { QGraphicsItem *item = items->at(i); - if (!item->d_func()->itemDiscovered && item->isVisible()) { + if (onlyTopLevelItems && item->d_ptr->parent) + item = item->topLevelItem(); + if (!item->d_func()->itemDiscovered && item->d_ptr->visible) { item->d_func()->itemDiscovered = 1; foundItems->prepend(item); } @@ -143,10 +146,11 @@ void QGraphicsSceneBspTree::removeItems(const QSet &items) } } -QList QGraphicsSceneBspTree::items(const QRectF &rect) const +QList QGraphicsSceneBspTree::items(const QRectF &rect, bool onlyTopLevelItems) const { QList tmp; findVisitor->foundItems = &tmp; + findVisitor->onlyTopLevelItems = onlyTopLevelItems; climbTree(findVisitor, rect); // Reset discovery bits. for (int i = 0; i < tmp.size(); ++i) diff --git a/src/gui/graphicsview/qgraphicsscene_bsp_p.h b/src/gui/graphicsview/qgraphicsscene_bsp_p.h index 24b926c..4cac64a 100644 --- a/src/gui/graphicsview/qgraphicsscene_bsp_p.h +++ b/src/gui/graphicsview/qgraphicsscene_bsp_p.h @@ -92,7 +92,7 @@ public: void removeItem(QGraphicsItem *item, const QRectF &rect); void removeItems(const QSet &items); - QList items(const QRectF &rect) const; + QList items(const QRectF &rect, bool onlyTopLevelItems = false) const; int leafCount() const; inline int firstChildIndex(int index) const @@ -106,8 +106,6 @@ public: private: void initialize(const QRectF &rect, int depth, int index); void climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QRectF &rect, int index = 0) const; - - void findItems(QList *foundItems, const QRectF &rect, int index); QRectF rectForIndex(int index) const; QVector nodes; diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 23b0dd5..245380f 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -191,26 +191,13 @@ public: QGraphicsWidget *windowForItem(const QGraphicsItem *item) const; bool sortCacheEnabled; // for compatibility - QList topLevelItemsInStackingOrder(const QTransform *const, const QRectF&); void drawItemHelper(QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget, bool painterStateProtection); - inline void drawItems(QPainter *painter, const QTransform *const viewTransform, - QRegion *exposedRegion, QWidget *widget) - { - QRectF exposedSceneRect; - if (exposedRegion && indexMethod != QGraphicsScene::NoIndex) { - exposedSceneRect = exposedRegion->boundingRect().adjusted(-1, -1, 1, 1); - if (viewTransform) - exposedSceneRect = viewTransform->inverted().mapRect(exposedSceneRect); - } - const QList tli = topLevelItemsInStackingOrder(viewTransform, exposedSceneRect); - for (int i = 0; i < tli.size(); ++i) - drawSubtreeRecursive(tli.at(i), painter, viewTransform, exposedRegion, widget); - return; - } + void drawItems(QPainter *painter, const QTransform *const viewTransform, + QRegion *exposedRegion, QWidget *widget); void drawSubtreeRecursive(QGraphicsItem *item, QPainter *painter, const QTransform *const, QRegion *exposedRegion, QWidget *widget, qreal parentOpacity = qreal(1.0)); diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 0688cb1..a7b4828 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -372,6 +372,32 @@ void QGraphicsSceneBspTreeIndexPrivate::removeItem(QGraphicsItem *item, bool rec } } +QList QGraphicsSceneBspTreeIndexPrivate::estimateItems(const QRectF &rect, Qt::SortOrder order, + bool onlyTopLevelItems) +{ + Q_Q(QGraphicsSceneBspTreeIndex); + if (onlyTopLevelItems && rect.isNull()) + return q->QGraphicsSceneIndex::estimateTopLevelItems(rect, order); + + purgeRemovedItems(); + _q_updateSortCache(); + Q_ASSERT(unindexedItems.isEmpty()); + + QList rectItems = bsp.items(rect, onlyTopLevelItems); + if (onlyTopLevelItems) { + for (int i = 0; i < untransformableItems.size(); ++i) { + QGraphicsItem *item = untransformableItems.at(i); + if (!item->d_ptr->parent) + rectItems << item; + } + } else { + rectItems += untransformableItems; + } + + sortItems(&rectItems, order, sortCacheEnabled, onlyTopLevelItems); + return rectItems; +} + /*! Returns true if \a item1 is on top of \a item2. @@ -442,8 +468,19 @@ bool QGraphicsSceneBspTreeIndexPrivate::closestItemLast_withoutCache(const QGrap \internal */ void QGraphicsSceneBspTreeIndexPrivate::sortItems(QList *itemList, Qt::SortOrder order, - bool sortCacheEnabled) + bool sortCacheEnabled, bool onlyTopLevelItems) { + if (order == Qt::SortOrder(-1)) + return; + + if (onlyTopLevelItems) { + if (order == Qt::AscendingOrder) + qSort(itemList->begin(), itemList->end(), qt_closestLeaf); + else if (order == Qt::DescendingOrder) + qSort(itemList->begin(), itemList->end(), qt_notclosestLeaf); + return; + } + if (sortCacheEnabled) { if (order == Qt::AscendingOrder) { qSort(itemList->begin(), itemList->end(), closestItemFirst_withCache); @@ -548,36 +585,17 @@ void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem * \a deviceTransform is the transformation apply to the view. */ -QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &rect, Qt::SortOrder order, - const QTransform &deviceTransform) const +QList QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &rect, Qt::SortOrder order) const { Q_D(const QGraphicsSceneBspTreeIndex); - const_cast(d)->purgeRemovedItems(); - const_cast(d)->_q_updateSortCache(); - - // ### Handle items that ignore transformations - Q_UNUSED(deviceTransform); - - QList rectItems = d->bsp.items(rect); - - // Fill in with any unindexed items - for (int i = 0; i < d->unindexedItems.size(); ++i) { - if (QGraphicsItem *item = d->unindexedItems.at(i)) { - if (item->d_ptr->visible - && !(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { - QRectF boundingRect = item->sceneBoundingRect(); - if (QRectF_intersects(boundingRect, rect)) - rectItems << item; - } - } - } - - rectItems += d->untransformableItems; - d->sortItems(&rectItems, order, d->sortCacheEnabled); - - return rectItems; + return const_cast(d)->estimateItems(rect, order); } +QList QGraphicsSceneBspTreeIndex::estimateTopLevelItems(const QRectF &rect, Qt::SortOrder order) const +{ + Q_D(const QGraphicsSceneBspTreeIndex); + return const_cast(d)->estimateItems(rect, order, /*onlyTopLevels=*/true); +} /*! \fn QList QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order = Qt::AscendingOrder) const; diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 437b17d..3ac922b 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -82,8 +82,8 @@ public: QGraphicsSceneBspTreeIndex(QGraphicsScene *scene = 0); ~QGraphicsSceneBspTreeIndex(); - QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const; - + QList estimateItems(const QRectF &rect, Qt::SortOrder order) const; + QList estimateTopLevelItems(const QRectF &rect, Qt::SortOrder order) const; QList items(Qt::SortOrder order = Qt::AscendingOrder) const; int bspTreeDepth(); @@ -145,6 +145,7 @@ public: void invalidateSortCache(); void addItem(QGraphicsItem *item, bool recursive = false); void removeItem(QGraphicsItem *item, bool recursive = false, bool moveToUnindexedItems = false); + QList estimateItems(const QRectF &, Qt::SortOrder, bool b = false); static void climbTree(QGraphicsItem *item, int *stackingOrder); static bool closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2); @@ -159,7 +160,8 @@ public: return item1->d_ptr->globalStackingOrder >= item2->d_ptr->globalStackingOrder; } - static void sortItems(QList *itemList, Qt::SortOrder order, bool cached); + static void sortItems(QList *itemList, Qt::SortOrder order, + bool cached, bool onlyTopLevelItems = false); }; diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index d6281e2..5626051 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -482,12 +482,25 @@ QList QGraphicsSceneIndex::items(const QPainterPath &path, Qt:: /*! This virtual function return an estimation of items at position \a point. This method return a list sorted using \a order. - \a deviceTransform is the transformation apply to the view. */ -QList QGraphicsSceneIndex::estimateItems(const QPointF &point, Qt::SortOrder order, - const QTransform &deviceTransform) const +QList QGraphicsSceneIndex::estimateItems(const QPointF &point, Qt::SortOrder order) const +{ + return estimateItems(QRectF(point, QSize(1, 1)), order); +} + +QList QGraphicsSceneIndex::estimateTopLevelItems(const QRectF &rect, Qt::SortOrder order) const { - return estimateItems(QRectF(point, QSize(1,1)), order, deviceTransform); + Q_D(const QGraphicsSceneIndex); + Q_UNUSED(rect); + QGraphicsScenePrivate *scened = d->scene->d_func(); + scened->ensureSortedTopLevelItems(); + if (order == Qt::AscendingOrder) { + QList sorted; + for (int i = scened->topLevelItems.size() - 1; i >= 0; --i) + sorted << scened->topLevelItems.at(i); + return sorted; + } + return scened->topLevelItems; } /*! diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index aabfa79..6521765 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -97,10 +97,9 @@ public: Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; virtual QList items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const; - virtual QList estimateItems(const QPointF &point, - Qt::SortOrder order, const QTransform &deviceTransform) const; - virtual QList estimateItems(const QRectF &rect, - Qt::SortOrder order, const QTransform &deviceTransform) const = 0; + virtual QList estimateItems(const QPointF &point, Qt::SortOrder order) const; + virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order) const = 0; + virtual QList estimateTopLevelItems(const QRectF &, Qt::SortOrder order) const; protected Q_SLOTS: virtual void updateSceneRect(const QRectF &rect); @@ -154,7 +153,8 @@ inline void QGraphicsSceneIndexPrivate::items_helper(const QRectF &rect, QGraphi QList *items, const QTransform &viewTransform, Qt::ItemSelectionMode mode, Qt::SortOrder order) const { - const QList tli = scene->d_func()->topLevelItemsInStackingOrder(&viewTransform, rect); + Q_Q(const QGraphicsSceneIndex); + const QList tli = q->estimateTopLevelItems(rect, Qt::DescendingOrder); const QTransform identity; for (int i = 0; i < tli.size(); ++i) recursive_items_helper(tli.at(i), rect, intersector, items, identity, viewTransform, mode, order); diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex.cpp b/src/gui/graphicsview/qgraphicsscenelinearindex.cpp index bc401f2..5e6ac30 100644 --- a/src/gui/graphicsview/qgraphicsscenelinearindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenelinearindex.cpp @@ -30,13 +30,10 @@ /*! - \fn virtual QList QGraphicsSceneLinearIndex::estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const; + \fn virtual QList QGraphicsSceneLinearIndex::estimateItems(const QRectF &rect, Qt::SortOrder order) const; Returns an estimation visible items that are either inside or intersect with the specified \a rect and return a list sorted using \a order. - - \a deviceTransform is the transformation apply to the view. - */ /*! diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h index 9463487..56dde3a 100644 --- a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h @@ -79,11 +79,10 @@ public: QList items(Qt::SortOrder order = Qt::AscendingOrder) const { Q_UNUSED(order); return m_items; } - virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order, const QTransform &deviceTransform) const + virtual QList estimateItems(const QRectF &rect, Qt::SortOrder order) const { Q_UNUSED(rect); Q_UNUSED(order); - Q_UNUSED(deviceTransform); return m_items; } -- cgit v0.12 From 8f7ed011e38021f19f50b22d8a5c00d8ccd366ed Mon Sep 17 00:00:00 2001 From: mae Date: Thu, 2 Jul 2009 15:55:19 +0200 Subject: QPlainTextEdit pixel dust redrawing problem on clear() With document margins, the mapping from content-coordinates to visual coordinates went wrong. --- src/gui/widgets/qplaintextedit.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index c9d1d6e..82026d4 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -252,7 +252,7 @@ QPlainTextDocumentLayoutPrivate *QPlainTextDocumentLayout::priv() const */ void QPlainTextDocumentLayout::requestUpdate() { - emit update(QRectF(0., -4., 1000000000., 1000000000.)); + emit update(QRectF(0., -document()->documentMargin(), 1000000000., 1000000000.)); } @@ -347,8 +347,7 @@ void QPlainTextDocumentLayout::documentChanged(int from, int /*charsRemoved*/, i } if (!d->blockUpdate) - emit update(); // optimization potential - + emit update(QRectF(0., -doc->documentMargin(), 1000000000., 1000000000.)); // optimization potential } -- cgit v0.12 From 1866485e46039d51ea78a6d672b678aa02f68eef Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Fri, 3 Jul 2009 11:51:49 +1000 Subject: Fixed compile of QtCore with some exotic GNU toolchains. Fixes: corelib/kernel/qcore_unix_p.h:127: error: `O_CLOEXEC' undeclared Some toolchains claim to provide glibc >= 2.4 but do not define O_CLOEXEC. An alternative fix might be to define O_CLOEXEC ourselves as we do with some of the system call numbers. --- src/corelib/kernel/qcore_unix_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index 1f3fe39..61d8401 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -71,7 +71,7 @@ struct sockaddr; QT_BEGIN_NAMESPACE -#if defined(Q_OS_LINUX) && defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0204 +#if defined(Q_OS_LINUX) && defined(O_CLOEXEC) && defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0204 // Linux supports thread-safe FD_CLOEXEC # define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 1 -- cgit v0.12 From 1752e03a97cc16dd653d68d5a4bcf24024c59980 Mon Sep 17 00:00:00 2001 From: Keith Isdale Date: Fri, 3 Jul 2009 16:46:54 +1000 Subject: Do not specify the output file when generating Visual Studio Project Files files with qmake. The correct file extension for generated file is best left to qmake to decide. --- doc/src/snippets/code/doc_src_qmake-manual.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/snippets/code/doc_src_qmake-manual.qdoc b/doc/src/snippets/code/doc_src_qmake-manual.qdoc index edb66bc..82c710d 100644 --- a/doc/src/snippets/code/doc_src_qmake-manual.qdoc +++ b/doc/src/snippets/code/doc_src_qmake-manual.qdoc @@ -689,7 +689,7 @@ qmake -o Makefile hello.pro //! [115] -qmake -tp vc -o hello.dsp hello.pro +qmake -tp vc hello.pro //! [115] -- cgit v0.12 From 17f814ce07a4d82563012a15a46dfe6acb2edcc5 Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Fri, 3 Jul 2009 09:41:00 +0200 Subject: Add a specialization for QByteArray It tries to keep the semantics of QString::append(QByteArray) as much as possible. --- src/corelib/tools/qstringbuilder.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h index 4d6b64b..127c183 100644 --- a/src/corelib/tools/qstringbuilder.h +++ b/src/corelib/tools/qstringbuilder.h @@ -202,6 +202,18 @@ template <> struct QConcatenable *out++ = QLatin1Char(*a++); } }; + +template <> struct QConcatenable +{ + typedef QByteArray type; + static int size(const QByteArray &ba) { qstrnlen(ba.constData(), ba.size()); } + static inline void appendTo(const QByteArray &ba, QChar *&out) + { + const char *data = ba.constData(); + while (*data) + *out++ = *data++; + } +}; #endif template -- cgit v0.12 From 95e4c95d28be9bc9d94685f7a13e36cbf57bf74e Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Fri, 3 Jul 2009 10:08:25 +0200 Subject: doc: Corrected several qdoc warnings. --- doc/src/qmake-manual.qdoc | 5 +++-- src/corelib/tools/qsharedpointer.cpp | 6 +++--- src/dbus/qdbuserror.cpp | 10 +++++++++- src/gui/kernel/qgesture.cpp | 7 +++++++ 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/doc/src/qmake-manual.qdoc b/doc/src/qmake-manual.qdoc index 42921db..5b261ab 100644 --- a/doc/src/qmake-manual.qdoc +++ b/doc/src/qmake-manual.qdoc @@ -1037,8 +1037,9 @@ (see \l{LibDepend}{Library Dependencies} for more info). \endtable - Please note that \c create_prl is required when \i {building} a static library, - while \c link_prl is required when \i {using} a static library. + Please note that \c create_prl is required when \e {building} a + static library, while \c link_prl is required when \e {using} a + static library. On Windows (or if Qt is configured with \c{-debug_and_release}, adding the \c build_all option to the \c CONFIG variable makes this rule the default diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index 71bf318..fe3d9e0 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -342,7 +342,7 @@ /*! \fn QSharedPointer QSharedPointer::objectCast() const - Performs a \ref qobject_cast from this pointer's type to \tt X and + Performs a \l qobject_cast() from this pointer's type to \tt X and returns a QSharedPointer that shares the reference. If this function is used to up-cast, then QSharedPointer will perform a \tt qobject_cast, which means that if the object being pointed by this @@ -739,7 +739,7 @@ \relates QSharedPointer Returns a shared pointer to the pointer held by \a other, using a - \ref qobject_cast to type \tt X to obtain an internal pointer of the + \l qobject_cast() to type \tt X to obtain an internal pointer of the appropriate type. If the \tt qobject_cast fails, the object returned will be null. @@ -756,7 +756,7 @@ \relates QWeakPointer Returns a shared pointer to the pointer held by \a other, using a - \ref qobject_cast to type \tt X to obtain an internal pointer of the + \l qobject_cast() to type \tt X to obtain an internal pointer of the appropriate type. If the \tt qobject_cast fails, the object returned will be null. diff --git a/src/dbus/qdbuserror.cpp b/src/dbus/qdbuserror.cpp index b2d21ec..caa2437 100644 --- a/src/dbus/qdbuserror.cpp +++ b/src/dbus/qdbuserror.cpp @@ -225,8 +225,16 @@ static inline QDBusError::ErrorType get(const char *name) \value UnknownInterface The interface is not known \value InternalError An internal error occurred (\c com.trolltech.QtDBus.Error.InternalError) - \value UnknownObject The remote object could not be found. + \value InvalidObjectPath The object path provided is invalid. + + \value InvalidService The service requested is invalid. + + \value InvalidMember The member is invalid. + + \value InvalidInterface The interface is invalid. + + \value UnknownObject The remote object could not be found. */ /*! diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp index 32a219c..d53b419 100644 --- a/src/gui/kernel/qgesture.cpp +++ b/src/gui/kernel/qgesture.cpp @@ -187,11 +187,18 @@ bool QGesture::eventFilter(QObject *receiver, QEvent *event) \brief The current state of the gesture. */ + +/*! + Returns the gesture recognition state. + */ Qt::GestureState QGesture::state() const { return d_func()->state; } +/*! + Sets this gesture's recognition state to \a state. + */ void QGesture::setState(Qt::GestureState state) { d_func()->state = state; -- cgit v0.12 From 8a0b05f71d2a9481a21143d1b87e2b18d427d1d5 Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Fri, 3 Jul 2009 10:08:52 +0200 Subject: fix the test _and_ the class :) --- src/corelib/tools/qstringbuilder.h | 2 +- tests/auto/qstringbuilder/tst_qstringbuilder.cpp | 17 ++++++----------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h index 127c183..97f13ee 100644 --- a/src/corelib/tools/qstringbuilder.h +++ b/src/corelib/tools/qstringbuilder.h @@ -206,7 +206,7 @@ template <> struct QConcatenable template <> struct QConcatenable { typedef QByteArray type; - static int size(const QByteArray &ba) { qstrnlen(ba.constData(), ba.size()); } + static int size(const QByteArray &ba) { return qstrnlen(ba.constData(), ba.size()); } static inline void appendTo(const QByteArray &ba, QChar *&out) { const char *data = ba.constData(); diff --git a/tests/auto/qstringbuilder/tst_qstringbuilder.cpp b/tests/auto/qstringbuilder/tst_qstringbuilder.cpp index fdbaf21..72889bc 100644 --- a/tests/auto/qstringbuilder/tst_qstringbuilder.cpp +++ b/tests/auto/qstringbuilder/tst_qstringbuilder.cpp @@ -85,28 +85,18 @@ #undef QT_NO_CAST_TO_ASCII #endif - #include //TESTED_CLASS=QStringBuilder //TESTED_FILES=qstringbuilder.cpp -#include - #define LITERAL "some literal" class tst_QStringBuilder : public QObject { Q_OBJECT -public: - tst_QStringBuilder() {} - ~tst_QStringBuilder() {} - -public slots: - void init() {} - void cleanup() {} - +private slots: void scenario(); }; @@ -119,6 +109,7 @@ void tst_QStringBuilder::scenario() QLatin1Char achar('c'); QString r2(QLatin1String(LITERAL LITERAL)); QString r; + QByteArray ba(LITERAL); r = l1literal P l1literal; QCOMPARE(r, r2); @@ -139,6 +130,10 @@ void tst_QStringBuilder::scenario() QCOMPARE(r, r2); r = LITERAL P string; QCOMPARE(r, r2); + r = ba P string; + QCOMPARE(r, r2); + r = string P ba; + QCOMPARE(r, r2); #endif } -- cgit v0.12 From d64d961c7242d22a4d71b376e9dcbbb3a7061a9e Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 3 Jul 2009 11:21:58 +0200 Subject: QToolBar: avoid repaints when entering/leaving a toolbar HoverEnter/Leave now do nothing. Task-number: 256103 --- src/gui/widgets/qtoolbar.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/widgets/qtoolbar.cpp b/src/gui/widgets/qtoolbar.cpp index 3414b4f..b249915 100644 --- a/src/gui/widgets/qtoolbar.cpp +++ b/src/gui/widgets/qtoolbar.cpp @@ -1145,6 +1145,10 @@ bool QToolBar::event(QEvent *event) if (d->mouseReleaseEvent(static_cast(event))) return true; break; + case QEvent::HoverEnter: + case QEvent::HoverLeave: + // there's nothing special to do here and we don't want to update the whole widget + return true; case QEvent::HoverMove: { #ifndef QT_NO_CURSOR QHoverEvent *e = static_cast(event); -- cgit v0.12 From 88a0857ac76c803d4f88204fe74448e140bbf300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Riku=20Palom=C3=A4ki?= Date: Fri, 3 Jul 2009 11:28:07 +0200 Subject: Fix QX11Embed* with x86_64 by reading prop_return as long. Even though the _XEMBED_INFO property uses 32 bit values, prop_return has 64-bit padded values in 64-bit applications, see man XChangeProperty. Without this fix the XEMBED client will read XEMBED_MAPPED wrong and unmap (hide) itself. Merge-request: 797 Reviewed-by: Denis Dzyubenko --- src/gui/kernel/qx11embed_x11.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qx11embed_x11.cpp b/src/gui/kernel/qx11embed_x11.cpp index 3ddde1b..659331f 100644 --- a/src/gui/kernel/qx11embed_x11.cpp +++ b/src/gui/kernel/qx11embed_x11.cpp @@ -826,7 +826,7 @@ bool QX11EmbedWidget::x11Event(XEvent *event) &actual_format_return, &nitems_return, &bytes_after_return, &prop_return) == Success) { if (nitems_return > 1) { - if (((int * )prop_return)[1] & XEMBED_MAPPED) { + if (((long * )prop_return)[1] & XEMBED_MAPPED) { XMapWindow(x11Info().display(), internalWinId()); } else { XUnmapWindow(x11Info().display(), internalWinId()); @@ -1670,9 +1670,9 @@ void QX11EmbedContainerPrivate::acceptClient(WId window) // Clients with the _XEMBED_INFO property are XEMBED clients. clientIsXEmbed = true; - unsigned int *p = (unsigned int *)prop_return; + long *p = (long *)prop_return; if (nitems_return >= 2) - clientversion = p[0]; + clientversion = (unsigned int)p[0]; } XFree(prop_return); -- cgit v0.12 From 9b4234d567804e8f503951e8d0c96e95f5dbec48 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Fri, 3 Jul 2009 13:45:49 +0200 Subject: Enabled double buffering of window surfaces on Windows. Without this, QWindowSurface::flush() doesn't work. Reviewed-by: Samuel --- src/opengl/qwindowsurface_gl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index 3a7a07e..eec725e 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -171,7 +171,7 @@ QGLGraphicsSystem::QGLGraphicsSystem() } } #elif defined(Q_WS_WIN) - QGLWindowSurface::surfaceFormat.setDoubleBuffer(false); + QGLWindowSurface::surfaceFormat.setDoubleBuffer(true); qt_win_owndc_required = true; #endif -- cgit v0.12 From 460e204c5b96cb67244bd9463ca0dfa56ad02564 Mon Sep 17 00:00:00 2001 From: Trond Kjernaasen Date: Fri, 3 Jul 2009 13:29:43 +0200 Subject: Replace usage of the old, obsolete PrintDlg with PrintDlgEx. Since we don't support Windows versions < Win 2000, we can just go ahead and replace usage of the old compat dialog. Task-number: 222417 Reviewed-by: Prasanth --- src/gui/dialogs/qprintdialog_win.cpp | 79 +++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/src/gui/dialogs/qprintdialog_win.cpp b/src/gui/dialogs/qprintdialog_win.cpp index 6022a66..115cd8d 100644 --- a/src/gui/dialogs/qprintdialog_win.cpp +++ b/src/gui/dialogs/qprintdialog_win.cpp @@ -77,14 +77,10 @@ public: QWin32PrintEnginePrivate *ep; }; -static PRINTDLG* qt_win_make_PRINTDLG(QWidget *parent, - QPrintDialog *pdlg, - QPrintDialogPrivate *d, HGLOBAL *tempDevNames) +static void qt_win_setup_PRINTDLGEX(PRINTDLGEX *pd, QWidget *parent, + QPrintDialog *pdlg, + QPrintDialogPrivate *d, HGLOBAL *tempDevNames) { - PRINTDLG *pd = new PRINTDLG; - memset(pd, 0, sizeof(PRINTDLG)); - pd->lStructSize = sizeof(PRINTDLG); - DEVMODE *devMode = d->ep->devMode; if (devMode) { @@ -125,31 +121,31 @@ static PRINTDLG* qt_win_make_PRINTDLG(QWidget *parent, if (pd->nMinPage==0 && pd->nMaxPage==0) pd->Flags |= PD_NOPAGENUMS; + // we don't have a 'current page' notion in the QPrinter API yet. + // Neither do we support more than one page range, so limit those + // options + pd->Flags |= PD_NOCURRENTPAGE; + pd->nStartPage = START_PAGE_GENERAL; + pd->nPageRanges = 1; + pd->nMaxPageRanges = 1; + if (d->ep->printToFile) pd->Flags |= PD_PRINTTOFILE; Q_ASSERT(!parent ||parent->testAttribute(Qt::WA_WState_Created)); pd->hwndOwner = parent ? parent->winId() : 0; - pd->nFromPage = qMax(pdlg->fromPage(), pdlg->minPage()); - pd->nToPage = (pdlg->toPage() > 0) ? qMin(pdlg->toPage(), pdlg->maxPage()) : 1; + pd->lpPageRanges[0].nFromPage = qMax(pdlg->fromPage(), pdlg->minPage()); + pd->lpPageRanges[0].nToPage = (pdlg->toPage() > 0) ? qMin(pdlg->toPage(), pdlg->maxPage()) : 1; pd->nCopies = d->ep->num_copies; - - return pd; -} - -static void qt_win_clean_up_PRINTDLG(PRINTDLG **pd) -{ - delete *pd; - *pd = 0; } -static void qt_win_read_back_PRINTDLG(PRINTDLG *pd, QPrintDialog *pdlg, QPrintDialogPrivate *d) +static void qt_win_read_back_PRINTDLGEX(PRINTDLGEX *pd, QPrintDialog *pdlg, QPrintDialogPrivate *d) { if (pd->Flags & PD_SELECTION) { pdlg->setPrintRange(QPrintDialog::Selection); pdlg->setFromTo(0, 0); } else if (pd->Flags & PD_PAGENUMS) { pdlg->setPrintRange(QPrintDialog::PageRange); - pdlg->setFromTo(pd->nFromPage, pd->nToPage); + pdlg->setFromTo(pd->lpPageRanges[0].nFromPage, pd->lpPageRanges[0].nToPage); } else { pdlg->setPrintRange(QPrintDialog::AllPages); pdlg->setFromTo(0, 0); @@ -223,19 +219,35 @@ int QPrintDialogPrivate::openWindowsPrintDialogModally() HGLOBAL *tempDevNames = ep->createDevNames(); - bool result; bool done; - PRINTDLG *pd = qt_win_make_PRINTDLG(parent, q, this, tempDevNames); + bool result; + bool doPrinting; + + PRINTPAGERANGE pageRange; + PRINTDLGEX pd; + memset(&pd, 0, sizeof(PRINTDLGEX)); + pd.lStructSize = sizeof(PRINTDLGEX); + pd.lpPageRanges = &pageRange; + qt_win_setup_PRINTDLGEX(&pd, parent, q, this, tempDevNames); do { done = true; - result = PrintDlg(pd); - if ((pd->Flags & PD_PAGENUMS) && (pd->nFromPage > pd->nToPage)) - done = false; - if (result && pd->hDC == 0) - result = false; - else if (!result) - done = true; + doPrinting = false; + result = (PrintDlgEx(&pd) == S_OK); + if (result && (pd.dwResultAction == PD_RESULT_PRINT + || pd.dwResultAction == PD_RESULT_APPLY)) + { + doPrinting = (pd.dwResultAction == PD_RESULT_PRINT); + if ((pd.Flags & PD_PAGENUMS) + && (pd.lpPageRanges[0].nFromPage > pd.lpPageRanges[0].nToPage)) + { + pd.lpPageRanges[0].nFromPage = 1; + pd.lpPageRanges[0].nToPage = 1; + done = false; + } + if (pd.hDC == 0) + result = false; + } if (!done) { QMessageBox::warning(0, QPrintDialog::tr("Print"), @@ -249,9 +261,10 @@ int QPrintDialogPrivate::openWindowsPrintDialogModally() qt_win_eatMouseMove(); // write values back... - if (result) { - qt_win_read_back_PRINTDLG(pd, q, this); - qt_win_clean_up_PRINTDLG(&pd); + if (result && (pd.dwResultAction == PD_RESULT_PRINT + || pd.dwResultAction == PD_RESULT_APPLY)) + { + qt_win_read_back_PRINTDLGEX(&pd, q, this); // update printer validity printer->d_func()->validPrinter = !ep->name.isEmpty(); } @@ -259,9 +272,9 @@ int QPrintDialogPrivate::openWindowsPrintDialogModally() // Cleanup... GlobalFree(tempDevNames); - q->done(result); + q->done(result && doPrinting); - return result; + return result && doPrinting; } void QPrintDialog::setVisible(bool visible) -- cgit v0.12 From b43cbebc5353b7e6b2a3812046a23f327a12c4dc Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Fri, 3 Jul 2009 13:46:22 +0200 Subject: Drag leave event is delivered, after re-entering the widget. This happens only for widgets with focus frames. Since the mouse location at the time of this event will be outside of the focus frame, we cannot use it to identify the widget. Instead, use the QDragManager's currentTarget() to deliver the drag leave event. Task-number: 252088 Reviewed-by: Norwegian Rock Cat --- src/gui/kernel/qdnd_mac.mm | 4 ++-- src/gui/kernel/qwidget_mac.mm | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qdnd_mac.mm b/src/gui/kernel/qdnd_mac.mm index b244d84..99399da 100644 --- a/src/gui/kernel/qdnd_mac.mm +++ b/src/gui/kernel/qdnd_mac.mm @@ -405,12 +405,12 @@ bool QWidgetPrivate::qt_mac_dnd_event(uint kind, DragRef dragRef) SetDragDropAction(dragRef, qt_mac_dnd_map_qt_actions(qDEEvent.dropAction())); if (!qDEEvent.isAccepted()) - // The widget is simply not interrested in this + // The widget is simply not interested in this // drag. So tell carbon this by returning 'false'. We will then // not receive any further move, drop or leave events for this widget. return false; else { - // Documentation states that a drag move event is sendt immidiatly after + // Documentation states that a drag move event is sent immediately after // a drag enter event. So we do that. This will honor widgets overriding // 'dragMoveEvent' only, and not 'dragEnterEvent' QDragMoveEvent qDMEvent(q->mapFromGlobal(QPoint(mouse.h, mouse.v)), qtAllowed, dropdata, diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 250cc35..d1e4230 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -1369,6 +1369,14 @@ OSStatus QWidgetPrivate::qt_widget_event(EventHandlerCallRef er, EventRef event, // Set dropWidget to zero, so qt_mac_dnd_event // doesn't get called a second time below: dropWidget = 0; + } else if (ekind == kEventControlDragLeave) { + dropWidget = QDragManager::self()->currentTarget(); + if (dropWidget) { + dropWidget->d_func()->qt_mac_dnd_event(kEventControlDragLeave, drag); + } + // Set dropWidget to zero, so qt_mac_dnd_event + // doesn't get called a second time below: + dropWidget = 0; } } } -- cgit v0.12 From 468bbd8fd5c40e29b50e6c38b3f2c3450aad2e67 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Fri, 3 Jul 2009 15:18:16 +0200 Subject: signals -> Q_SIGNALS --- src/gui/kernel/qgesture.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h index b5abdd2..cc46916 100644 --- a/src/gui/kernel/qgesture.h +++ b/src/gui/kernel/qgesture.h @@ -93,7 +93,7 @@ protected: QGesture(QGesturePrivate &dd, QObject *parent); bool eventFilter(QObject*, QEvent*); -signals: +Q_SIGNALS: void started(); void triggered(); void finished(); -- cgit v0.12 From 7bc98d7bd7aabc6086e5cd27a167769d7aa71d83 Mon Sep 17 00:00:00 2001 From: jasplin Date: Fri, 3 Jul 2009 15:40:20 +0200 Subject: Improved the support for input methods in Graphics View. This patch improves the graphics view support for input methods in several ways: * A new ItemAcceptsInputMethod flag is introduced to serve the same purpose for graphics items as WA_InputMethodEnabled does for widgets: Input method support can be controlled individually for each item. * The input method sensitivity of a view (i.e. the value of the WA_InputMethodEnabled flag) is updated dynamically whenever the input method support of the current focus item may change. * Input contexts are reset whenever an item that supports input methods loses focus. Reviewed-by: janarve Task-number: 254492 --- src/gui/graphicsview/qgraphicsitem.cpp | 13 +++ src/gui/graphicsview/qgraphicsitem.h | 3 +- src/gui/graphicsview/qgraphicsitem_p.h | 4 +- src/gui/graphicsview/qgraphicsproxywidget.cpp | 22 +++- src/gui/graphicsview/qgraphicsproxywidget_p.h | 2 + src/gui/graphicsview/qgraphicsscene.cpp | 33 +++++- src/gui/graphicsview/qgraphicsscene_p.h | 2 + src/gui/graphicsview/qgraphicsview.cpp | 20 ++++ src/gui/graphicsview/qgraphicsview_p.h | 1 + .../tst_qgraphicsproxywidget.cpp | 46 +++++++- tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp | 58 ++++++++++ tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 118 +++++++++++++++++++++ 12 files changed, 310 insertions(+), 12 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index c82c2e5..a5ee7e6 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -323,6 +323,10 @@ performance reasons, these notifications are disabled by default. You must enable this flag to receive notifications for position and transform changes. This flag was introduced in Qt 4.6. + + \value ItemAcceptsInputMethod The item supports input methods typically + used for Asian languages. + This flag was introduced in Qt 4.6. */ /*! @@ -1486,6 +1490,12 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) d_ptr->scene->d_func()->needSortTopLevelItems = 1; } + if ((flags & ItemAcceptsInputMethod) != (oldFlags & ItemAcceptsInputMethod)) { + // Update input method sensitivity in any views. + if (d_ptr->scene) + d_ptr->scene->d_func()->updateInputMethodSensitivityInViews(); + } + if (d_ptr->scene) { d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true, @@ -9840,6 +9850,9 @@ QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlag flag) case QGraphicsItem::ItemSendsGeometryChanges: str = "ItemSendsGeometryChanges"; break; + case QGraphicsItem::ItemAcceptsInputMethod: + str = "ItemAcceptsInputMethod"; + break; } debug << str; return debug; diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index b0571c2..d26110a 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -98,7 +98,8 @@ public: ItemStacksBehindParent = 0x100, ItemUsesExtendedStyleOption = 0x200, ItemHasNoContents = 0x400, - ItemSendsGeometryChanges = 0x800 + ItemSendsGeometryChanges = 0x800, + ItemAcceptsInputMethod = 0x1000 // NB! Don't forget to increase the d_ptr->flags bit field by 1 when adding a new flag. }; Q_DECLARE_FLAGS(GraphicsItemFlags, GraphicsItemFlag) diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index a977e1e..46ec6fe 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -415,7 +415,7 @@ public: quint32 fullUpdatePending : 1; // New 32 bits - quint32 flags : 12; + quint32 flags : 13; quint32 dirtyChildrenBoundingRect : 1; quint32 paintedViewBoundingRectsNeedRepaint : 1; quint32 dirtySceneTransform : 1; @@ -426,7 +426,7 @@ public: quint32 ignoreOpacity : 1; quint32 acceptTouchEvents : 1; quint32 acceptedTouchBeginEvent : 1; - quint32 unused : 10; // feel free to use + quint32 unused : 9; // feel free to use // Optional stacking order int globalStackingOrder; diff --git a/src/gui/graphicsview/qgraphicsproxywidget.cpp b/src/gui/graphicsview/qgraphicsproxywidget.cpp index 0b421ad..5fac6cf 100644 --- a/src/gui/graphicsview/qgraphicsproxywidget.cpp +++ b/src/gui/graphicsview/qgraphicsproxywidget.cpp @@ -451,6 +451,22 @@ void QGraphicsProxyWidgetPrivate::updateProxyGeometryFromWidget() /*! \internal +*/ +void QGraphicsProxyWidgetPrivate::updateProxyInputMethodAcceptanceFromWidget() +{ + Q_Q(QGraphicsProxyWidget); + if (!widget) + return; + + QWidget *focusWidget = widget->focusWidget(); + if (!focusWidget) + focusWidget = widget; + q->setFlag(QGraphicsItem::ItemAcceptsInputMethod, + focusWidget->testAttribute(Qt::WA_InputMethodEnabled)); +} + +/*! + \internal Embeds \a subWin as a subwindow of this proxy widget. \a subWin must be a top-level widget and a descendant of the widget managed by this proxy. A separate subproxy @@ -690,6 +706,8 @@ void QGraphicsProxyWidgetPrivate::setWidget_helper(QWidget *newWidget, bool auto updateProxyGeometryFromWidget(); + updateProxyInputMethodAcceptanceFromWidget(); + // Hook up the event filter to keep the state up to date. newWidget->installEventFilter(q); QObject::connect(newWidget, SIGNAL(destroyed()), q, SLOT(_q_removeWidgetSlot())); @@ -1303,8 +1321,8 @@ void QGraphicsProxyWidget::focusInEvent(QFocusEvent *event) if (d->widget && d->widget->focusWidget()) { d->widget->focusWidget()->setFocus(event->reason()); return; - } - break; + } + break; } } diff --git a/src/gui/graphicsview/qgraphicsproxywidget_p.h b/src/gui/graphicsview/qgraphicsproxywidget_p.h index ec5400a..fbc9f6c 100644 --- a/src/gui/graphicsview/qgraphicsproxywidget_p.h +++ b/src/gui/graphicsview/qgraphicsproxywidget_p.h @@ -102,6 +102,8 @@ public: void updateWidgetGeometryFromProxy(); void updateProxyGeometryFromWidget(); + void updateProxyInputMethodAcceptanceFromWidget(); + QPointF mapToReceiver(const QPointF &pos, const QWidget *receiver) const; enum ChangeMode { diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index c3f72e6..0c3abd4 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -242,6 +242,7 @@ #include #include #include +#include #include #include #ifdef Q_WS_X11 @@ -3175,6 +3176,8 @@ void QGraphicsScene::addItem(QGraphicsItem *item) // Deliver post-change notification item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant); + + d->updateInputMethodSensitivityInViews(); } /*! @@ -3450,6 +3453,8 @@ void QGraphicsScene::removeItem(QGraphicsItem *item) // Deliver post-change notification item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant); + + d->updateInputMethodSensitivityInViews(); } /*! @@ -3504,6 +3509,17 @@ void QGraphicsScene::setFocusItem(QGraphicsItem *item, Qt::FocusReason focusReas d->lastFocusItem = d->focusItem; d->focusItem = 0; d->sendEvent(d->lastFocusItem, &event); + + if (d->lastFocusItem + && (d->lastFocusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod)) { + // Reset any visible preedit text + QInputMethodEvent imEvent; + d->sendEvent(d->lastFocusItem, &imEvent); + + // Close any external input method panel + for (int i = 0; i < d->views.size(); ++i) + d->views.at(i)->inputContext()->reset(); + } } if (item) { @@ -3516,6 +3532,8 @@ void QGraphicsScene::setFocusItem(QGraphicsItem *item, Qt::FocusReason focusReas QFocusEvent event(QEvent::FocusIn, focusReason); d->sendEvent(item, &event); } + + d->updateInputMethodSensitivityInViews(); } /*! @@ -3699,7 +3717,7 @@ void QGraphicsScene::setForegroundBrush(const QBrush &brush) QVariant QGraphicsScene::inputMethodQuery(Qt::InputMethodQuery query) const { Q_D(const QGraphicsScene); - if (!d->focusItem) + if (!d->focusItem || !(d->focusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod)) return QVariant(); const QTransform matrix = d->focusItem->sceneTransform(); QVariant value = d->focusItem->inputMethodQuery(query); @@ -4662,16 +4680,16 @@ void QGraphicsScene::wheelEvent(QGraphicsSceneWheelEvent *wheelEvent) subclass to receive input method events for the scene. The default implementation forwards the event to the focusItem(). - If no item currently has focus, this function does nothing. + If no item currently has focus or the current focus item does not + accept input methods, this function does nothing. \sa QGraphicsItem::inputMethodEvent() */ void QGraphicsScene::inputMethodEvent(QInputMethodEvent *event) { Q_D(QGraphicsScene); - if (!d->focusItem) - return; - d->sendEvent(d->focusItem, event); + if (d->focusItem && (d->focusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod)) + d->sendEvent(d->focusItem, event); } /*! @@ -6128,6 +6146,11 @@ void QGraphicsScenePrivate::enableTouchEventsOnViews() view->viewport()->setAttribute(Qt::WA_AcceptTouchEvents, true); } +void QGraphicsScenePrivate::updateInputMethodSensitivityInViews() +{ + for (int i = 0; i < views.size(); ++i) + views.at(i)->d_func()->updateInputMethodSensitivity(); +} QT_END_NAMESPACE diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index d2d603a..dc720a7 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -316,6 +316,8 @@ public: bool sendTouchBeginEvent(QGraphicsItem *item, QTouchEvent *touchEvent); bool allItemsIgnoreTouchEvents; void enableTouchEventsOnViews(); + + void updateInputMethodSensitivityInViews(); }; QT_END_NAMESPACE diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 56a69f7..3b29552 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -280,6 +280,7 @@ static const int QGRAPHICSVIEW_PREALLOC_STYLE_OPTIONS = 503; // largest prime < #include #include #include +#include #ifdef Q_WS_X11 #include #endif @@ -1017,6 +1018,22 @@ QList QGraphicsViewPrivate::findItems(const QRegion &exposedReg } /*! + \internal + + Enables input methods for the view if and only if the current focus item of + the scene accepts input methods. Call function whenever that condition has + potentially changed. +*/ +void QGraphicsViewPrivate::updateInputMethodSensitivity() +{ + Q_Q(QGraphicsView); + q->setAttribute( + Qt::WA_InputMethodEnabled, + scene && scene->focusItem() + && scene->focusItem()->flags() & QGraphicsItem::ItemAcceptsInputMethod); +} + +/*! Constructs a QGraphicsView. \a parent is passed to QWidget's constructor. */ QGraphicsView::QGraphicsView(QWidget *parent) @@ -1538,6 +1555,8 @@ void QGraphicsView::setScene(QGraphicsScene *scene) } else { d->recalculateContentSize(); } + + d->updateInputMethodSensitivity(); } /*! @@ -2929,6 +2948,7 @@ void QGraphicsView::dragMoveEvent(QDragMoveEvent *event) void QGraphicsView::focusInEvent(QFocusEvent *event) { Q_D(QGraphicsView); + d->updateInputMethodSensitivity(); QAbstractScrollArea::focusInEvent(event); if (d->scene) QApplication::sendEvent(d->scene, event); diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h index 8c62f73..09d842d 100644 --- a/src/gui/graphicsview/qgraphicsview_p.h +++ b/src/gui/graphicsview/qgraphicsview_p.h @@ -181,6 +181,7 @@ public: QPointF mapToScene(const QPointF &point) const; QRectF mapToScene(const QRectF &rect) const; static void translateTouchEvent(QGraphicsViewPrivate *d, QTouchEvent *touchEvent); + void updateInputMethodSensitivity(); }; QT_END_NAMESPACE diff --git a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp index 0b1d5cf..dbc4339 100644 --- a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp +++ b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp @@ -178,6 +178,7 @@ private slots: void windowFlags_data(); void windowFlags(); void comboboxWindowFlags(); + void inputMethod(); }; // Subclass that exposes the protected functions. @@ -1572,7 +1573,7 @@ void tst_QGraphicsProxyWidget::resize_simple() QGraphicsProxyWidget proxy; QWidget *widget = new QWidget; - widget->setGeometry(0, 0, size.width(), size.height()); + widget->setGeometry(0, 0, (int)size.width(), (int)size.height()); proxy.setWidget(widget); widget->show(); QCOMPARE(widget->pos(), QPoint()); @@ -3217,10 +3218,51 @@ void tst_QGraphicsProxyWidget::comboboxWindowFlags() QVERIFY((static_cast(popupProxy)->windowFlags() & Qt::Popup) == Qt::Popup); } +class InputMethod_LineEdit : public QLineEdit +{ + bool event(QEvent *e) + { + if (e->type() == QEvent::InputMethod) + ++inputMethodEvents; + return QLineEdit::event(e); + } +public: + int inputMethodEvents; +}; + +void tst_QGraphicsProxyWidget::inputMethod() +{ + QGraphicsScene scene; + + // check that the proxy is initialized with the correct input method sensitivity + for (int i = 0; i < 2; ++i) + { + QLineEdit *lineEdit = new QLineEdit; + lineEdit->setAttribute(Qt::WA_InputMethodEnabled, !!i); + QGraphicsProxyWidget *proxy = scene.addWidget(lineEdit); + QCOMPARE(!!(proxy->flags() & QGraphicsItem::ItemAcceptsInputMethod), !!i); + } + + // check that input method events are only forwarded to widgets with focus + for (int i = 0; i < 2; ++i) + { + InputMethod_LineEdit *lineEdit = new InputMethod_LineEdit; + lineEdit->setAttribute(Qt::WA_InputMethodEnabled, true); + QGraphicsProxyWidget *proxy = scene.addWidget(lineEdit); + + if (i) + lineEdit->setFocus(); + + lineEdit->inputMethodEvents = 0; + QInputMethodEvent event; + qApp->sendEvent(proxy, &event); + QCOMPARE(lineEdit->inputMethodEvents, i); + } +} + QTEST_MAIN(tst_QGraphicsProxyWidget) #include "tst_qgraphicsproxywidget.moc" #else // QT_NO_STYLE_CLEANLOOKS QTEST_NOOP_MAIN #endif - diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index 4247cca..d325f0f 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -252,6 +252,8 @@ private slots: void stickyFocus_data(); void stickyFocus(); void sendEvent(); + void inputMethod_data(); + void inputMethod(); // task specific tests below me void task139710_bspTreeCrash(); @@ -3614,5 +3616,61 @@ void tst_QGraphicsScene::sendEvent() QCOMPARE(spy->count(), 1); } +void tst_QGraphicsScene::inputMethod_data() +{ + QTest::addColumn("flags"); + QTest::addColumn("callFocusItem"); + QTest::newRow("0") << 0 << false; + QTest::newRow("1") << (int)QGraphicsItem::ItemAcceptsInputMethod << false; + QTest::newRow("2") << (int)QGraphicsItem::ItemIsFocusable << false; + QTest::newRow("3") << + (int)(QGraphicsItem::ItemAcceptsInputMethod|QGraphicsItem::ItemIsFocusable) << true; +} + +class InputMethodTester : public QGraphicsRectItem +{ + void inputMethodEvent(QInputMethodEvent *) { ++eventCalls; } + QVariant inputMethodQuery(Qt::InputMethodQuery) const { ++queryCalls; return QVariant(); } +public: + int eventCalls; + mutable int queryCalls; +}; + +void tst_QGraphicsScene::inputMethod() +{ + QFETCH(int, flags); + QFETCH(bool, callFocusItem); + + InputMethodTester *item = new InputMethodTester; + item->setFlags((QGraphicsItem::GraphicsItemFlags)flags); + + QGraphicsScene scene; + scene.addItem(item); + QInputMethodEvent event; + + scene.setFocusItem(item); + QCOMPARE(!!(item->flags() & QGraphicsItem::ItemIsFocusable), scene.focusItem() == item); + + item->eventCalls = 0; + qApp->sendEvent(&scene, &event); + QCOMPARE(item->eventCalls, callFocusItem ? 1 : 0); + + item->queryCalls = 0; + scene.inputMethodQuery((Qt::InputMethodQuery)0); + QCOMPARE(item->queryCalls, callFocusItem ? 1 : 0); + + scene.setFocusItem(0); + QCOMPARE(item->eventCalls, callFocusItem ? 2 : 0); // verify correct delivery of "reset" event + QCOMPARE(item->queryCalls, callFocusItem ? 1 : 0); // verify that value is unaffected + + item->eventCalls = 0; + qApp->sendEvent(&scene, &event); + QCOMPARE(item->eventCalls, 0); + + item->queryCalls = 0; + scene.inputMethodQuery((Qt::InputMethodQuery)0); + QCOMPARE(item->queryCalls, 0); +} + QTEST_MAIN(tst_QGraphicsScene) #include "tst_qgraphicsscene.moc" diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index d24e437..8b4ca4c 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -63,6 +63,7 @@ #include #include #include +#include //TESTED_CLASS= //TESTED_FILES= @@ -195,6 +196,8 @@ private slots: void mouseTracking2(); void render(); void exposeRegion(); + void inputMethodSensitivity(); + void inputContextReset(); // task specific tests below me void task172231_untransformableItems(); @@ -3357,6 +3360,121 @@ void tst_QGraphicsView::exposeRegion() QCOMPARE(item->paints, 0); } +void tst_QGraphicsView::inputMethodSensitivity() +{ + QGraphicsScene scene; + QGraphicsView view(&scene); + + QGraphicsRectItem *item = new QGraphicsRectItem; + + view.setAttribute(Qt::WA_InputMethodEnabled, true); + + scene.addItem(item); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + + scene.removeItem(item); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + + item->setFlag(QGraphicsItem::ItemAcceptsInputMethod); + scene.addItem(item); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + + scene.removeItem(item); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + + scene.addItem(item); + scene.setFocusItem(item); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + + scene.removeItem(item); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + + item->setFlag(QGraphicsItem::ItemIsFocusable); + scene.addItem(item); + scene.setFocusItem(item); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true); + + item->setFlag(QGraphicsItem::ItemAcceptsInputMethod, false); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + + item->setFlag(QGraphicsItem::ItemAcceptsInputMethod, true); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true); + + // introduce another item that is focusable but does not accept input methods + QGraphicsRectItem *item2 = new QGraphicsRectItem; + item2->setFlag(QGraphicsItem::ItemIsFocusable); + scene.addItem(item2); + scene.setFocusItem(item2); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + + scene.setFocusItem(item); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true); + + view.setScene(0); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + + view.setScene(&scene); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true); + + scene.setFocusItem(item2); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + + view.setScene(0); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + + scene.setFocusItem(item); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + + view.setScene(&scene); + QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true); +} + +class InputContextTester : public QInputContext +{ + QString identifierName() { return QString(); } + bool isComposing() const { return false; } + QString language() { return QString(); } + void reset() { ++resets; } +public: + int resets; +}; + +void tst_QGraphicsView::inputContextReset() +{ + QGraphicsScene scene; + QGraphicsView view(&scene); + + InputContextTester inputContext; + view.setInputContext(&inputContext); + + QGraphicsItem *item1 = new QGraphicsRectItem; + item1->setFlags(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemAcceptsInputMethod); + + inputContext.resets = 0; + scene.addItem(item1); + QCOMPARE(inputContext.resets, 0); + + inputContext.resets = 0; + scene.setFocusItem(item1); + QCOMPARE(inputContext.resets, 0); + + inputContext.resets = 0; + scene.setFocusItem(0); + QCOMPARE(inputContext.resets, 1); + + // introduce another item that is focusable but does not accept input methods + QGraphicsItem *item2 = new QGraphicsRectItem; + item1->setFlags(QGraphicsItem::ItemIsFocusable); + + inputContext.resets = 0; + scene.setFocusItem(item2); + QCOMPARE(inputContext.resets, 0); + + inputContext.resets = 0; + scene.setFocusItem(item1); + QCOMPARE(inputContext.resets, 0); +} + void tst_QGraphicsView::task253415_reconnectUpdateSceneOnSceneChanged() { QGraphicsView view; -- cgit v0.12 From 208bba0abd8a417cf8fdfd61295682738df3bc67 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 3 Jul 2009 16:40:32 +0200 Subject: QHeaderView: fixed the sizeHint with hidden sections We used to check the 100 first sections and 100 last sections Now we make sure we check 100 visible sections Task-number: 255574 --- src/gui/itemviews/qheaderview.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp index aea288b..a73f85a 100644 --- a/src/gui/itemviews/qheaderview.cpp +++ b/src/gui/itemviews/qheaderview.cpp @@ -528,20 +528,24 @@ QSize QHeaderView::sizeHint() const return d->cachedSizeHint; int width = 0; int height = 0; + d->executePostedLayout(); + // get size hint for the first n sections - int c = qMin(count(), 100); - for (int i = 0; i < c; ++i) { + int i = 0; + for (int checked = 0; checked < 100 && i < d->sectionCount; ++i) { if (isSectionHidden(i)) continue; + checked++; QSize hint = sectionSizeFromContents(i); width = qMax(hint.width(), width); height = qMax(hint.height(), height); } // get size hint for the last n sections - c = qMax(count() - 100, c); - for (int j = count() - 1; j >= c; --j) { + i = qMax(i, d->sectionCount - 100 ); + for (int j = d->sectionCount - 1, checked = 0; j > i && checked < 100; --j) { if (isSectionHidden(j)) continue; + checked++; QSize hint = sectionSizeFromContents(j); width = qMax(hint.width(), width); height = qMax(hint.height(), height); -- cgit v0.12 From 108f549a446e13a3be7ee6753be9eb74260547d7 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 3 Jul 2009 16:44:51 +0200 Subject: QHeaderView: code cleanup in sizehint calculation --- src/gui/itemviews/qheaderview.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp index a73f85a..57e44c7 100644 --- a/src/gui/itemviews/qheaderview.cpp +++ b/src/gui/itemviews/qheaderview.cpp @@ -522,12 +522,9 @@ int QHeaderView::length() const QSize QHeaderView::sizeHint() const { Q_D(const QHeaderView); - if (count() < 1) - return QSize(0, 0); if (d->cachedSizeHint.isValid()) return d->cachedSizeHint; - int width = 0; - int height = 0; + d->cachedSizeHint = QSize(0, 0); d->executePostedLayout(); // get size hint for the first n sections @@ -537,8 +534,7 @@ QSize QHeaderView::sizeHint() const continue; checked++; QSize hint = sectionSizeFromContents(i); - width = qMax(hint.width(), width); - height = qMax(hint.height(), height); + d->cachedSizeHint = d->cachedSizeHint.expandedTo(hint); } // get size hint for the last n sections i = qMax(i, d->sectionCount - 100 ); @@ -547,10 +543,8 @@ QSize QHeaderView::sizeHint() const continue; checked++; QSize hint = sectionSizeFromContents(j); - width = qMax(hint.width(), width); - height = qMax(hint.height(), height); + d->cachedSizeHint = d->cachedSizeHint.expandedTo(hint); } - d->cachedSizeHint = QSize(width, height); return d->cachedSizeHint; } -- cgit v0.12 From 84bbac2a4d7b663e57b74094cbebf8fca16e0ed8 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Fri, 3 Jul 2009 17:25:40 +0200 Subject: Moved uniform enum to QGLEngineShaderManager. Simplified caching of uniform locations. Reviewed-by: Samuel --- .../gl2paintengineex/qglengineshadermanager.cpp | 40 ++++++++------ .../gl2paintengineex/qglengineshadermanager_p.h | 26 +++++++-- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 61 ++++++++-------------- .../gl2paintengineex/qpaintengineex_opengl2_p.h | 25 +-------- 4 files changed, 69 insertions(+), 83 deletions(-) diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 4b73ca9..27636f4 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -190,27 +190,33 @@ QGLEngineShaderManager::~QGLEngineShaderManager() //### } - -uint QGLEngineShaderManager::getUniformIdentifier(const char *uniformName) -{ - uniformIdentifiers << uniformName; - return uniformIdentifiers.size() - 1; -} - -uint QGLEngineShaderManager::getUniformLocation(uint id) +uint QGLEngineShaderManager::getUniformLocation(Uniform id) { QVector &uniformLocations = currentShaderProg->uniformLocations; - uint oldSize = uniformLocations.size(); - if (oldSize <= id) { - uint newSize = id + 1; - uniformLocations.resize(newSize); - - for (uint i = oldSize; i < newSize; ++i) - uniformLocations[i] = GLuint(-1); - } + if (uniformLocations.isEmpty()) + uniformLocations.fill(GLuint(-1), NumUniforms); + + static const char *uniformNames[] = { + "imageTexture", + "patternColor", + "globalOpacity", + "depth", + "pmvMatrix", + "maskTexture", + "fragmentColor", + "linearData", + "angle", + "halfViewportSize", + "fmp", + "fmp2_m_radius2", + "inverse_2_fmp2_m_radius2", + "invertedTextureSize", + "brushTransform", + "brushTexture" + }; if (uniformLocations.at(id) == GLuint(-1)) - uniformLocations[id] = currentShaderProg->program->uniformLocation(uniformIdentifiers.at(id)); + uniformLocations[id] = currentShaderProg->program->uniformLocation(uniformNames[id]); return uniformLocations.at(id); } diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h index 34f0768..442edfe 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h @@ -274,6 +274,26 @@ public: TextureSrcWithPattern = Qt::TexturePattern+4 }; + enum Uniform { + ImageTexture, + PatternColor, + GlobalOpacity, + Depth, + PmvMatrix, + MaskTexture, + FragmentColor, + LinearData, + Angle, + HalfViewportSize, + Fmp, + Fmp2MRadius2, + Inverse2Fmp2MRadius2, + InvertedTextureSize, + BrushTransform, + BrushTexture, + NumUniforms + }; + // There are optimisations we can do, depending on the brush transform: // 1) May not have to apply perspective-correction // 2) Can use lower precision for matrix @@ -285,8 +305,7 @@ public: void setMaskType(MaskType); void setCompositionMode(QPainter::CompositionMode); - uint getUniformIdentifier(const char *uniformName); - uint getUniformLocation(uint id); + uint getUniformLocation(Uniform id); void setDirty(); // someone has manually changed the current shader program bool useCorrectShaderProg(); // returns true if the shader program needed to be changed @@ -352,6 +371,7 @@ public: TotalShaderCount, InvalidShaderName }; + /* // These allow the ShaderName enum to be used as a cache key const int mainVertexOffset = 0; @@ -391,8 +411,6 @@ private: void compileNamedShader(QGLEngineShaderManager::ShaderName name, QGLShader::ShaderType type); static const char* qglEngineShaderSourceCode[TotalShaderCount]; - - QVector uniformIdentifiers; }; QT_END_NAMESPACE diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index f261ca2..bcff29b 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -393,7 +393,7 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() if (style == Qt::SolidPattern) { QColor col = premultiplyColor(currentBrush->color(), (GLfloat)q->state()->opacity); - shaderManager->currentProgram()->setUniformValue(location(FragmentColor), col); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::FragmentColor), col); } else { // All other brushes have a transform and thus need the translation point: @@ -404,10 +404,10 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() QColor col = premultiplyColor(currentBrush->color(), (GLfloat)q->state()->opacity); - shaderManager->currentProgram()->setUniformValue(location(PatternColor), col); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::PatternColor), col); QVector2D halfViewportSize(width*0.5, height*0.5); - shaderManager->currentProgram()->setUniformValue(location(HalfViewportSize), halfViewportSize); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize); } else if (style == Qt::LinearGradientPattern) { const QLinearGradient *g = static_cast(currentBrush->gradient()); @@ -424,10 +424,10 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() 1.0f / (l.x() * l.x() + l.y() * l.y()) ); - shaderManager->currentProgram()->setUniformValue(location(LinearData), linearData); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::LinearData), linearData); QVector2D halfViewportSize(width*0.5, height*0.5); - shaderManager->currentProgram()->setUniformValue(location(HalfViewportSize), halfViewportSize); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize); } else if (style == Qt::ConicalGradientPattern) { const QConicalGradient *g = static_cast(currentBrush->gradient()); @@ -435,10 +435,10 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() GLfloat angle = -(g->angle() * 2 * Q_PI) / 360.0; - shaderManager->currentProgram()->setUniformValue(location(Angle), angle); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Angle), angle); QVector2D halfViewportSize(width*0.5, height*0.5); - shaderManager->currentProgram()->setUniformValue(location(HalfViewportSize), halfViewportSize); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize); } else if (style == Qt::RadialGradientPattern) { const QRadialGradient *g = static_cast(currentBrush->gradient()); @@ -448,15 +448,15 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() translationPoint = realFocal; QPointF fmp = realCenter - realFocal; - shaderManager->currentProgram()->setUniformValue(location(Fmp), fmp); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Fmp), fmp); GLfloat fmp2_m_radius2 = -fmp.x() * fmp.x() - fmp.y() * fmp.y() + realRadius*realRadius; - shaderManager->currentProgram()->setUniformValue(location(Fmp2MRadius2), fmp2_m_radius2); - shaderManager->currentProgram()->setUniformValue(location(Inverse2Fmp2MRadius2), + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Fmp2MRadius2), fmp2_m_radius2); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Inverse2Fmp2MRadius2), GLfloat(1.0 / (2.0*fmp2_m_radius2))); QVector2D halfViewportSize(width*0.5, height*0.5); - shaderManager->currentProgram()->setUniformValue(location(HalfViewportSize), halfViewportSize); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize); } else if (style == Qt::TexturePattern) { translationPoint = q->state()->brushOrigin; @@ -465,14 +465,14 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() if (qHasPixmapTexture(*currentBrush) && currentBrush->texture().isQBitmap()) { QColor col = premultiplyColor(currentBrush->color(), (GLfloat)q->state()->opacity); - shaderManager->currentProgram()->setUniformValue(location(PatternColor), col); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::PatternColor), col); } QSizeF invertedTextureSize( 1.0 / texPixmap.width(), 1.0 / texPixmap.height() ); - shaderManager->currentProgram()->setUniformValue(location(InvertedTextureSize), invertedTextureSize); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::InvertedTextureSize), invertedTextureSize); QVector2D halfViewportSize(width*0.5, height*0.5); - shaderManager->currentProgram()->setUniformValue(location(HalfViewportSize), halfViewportSize); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize); } else qWarning("QGL2PaintEngineEx: Unimplemented fill style"); @@ -481,8 +481,8 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() QTransform gl_to_qt(1, 0, 0, -1, 0, height); QTransform inv_matrix = gl_to_qt * (brushQTransform * q->state()->matrix).inverted() * translate; - shaderManager->currentProgram()->setUniformValue(location(BrushTransform), inv_matrix); - shaderManager->currentProgram()->setUniformValue(location(BrushTexture), QT_BRUSH_TEXTURE_UNIT); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::BrushTransform), inv_matrix); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::BrushTexture), QT_BRUSH_TEXTURE_UNIT); } brushUniformsDirty = false; } @@ -620,11 +620,11 @@ void QGL2PaintEngineExPrivate::drawTexture(const QGLRect& dest, const QGLRect& s shaderManager->setSrcPixelType(pattern ? QGLEngineShaderManager::PatternSrc : QGLEngineShaderManager::ImageSrc); shaderManager->setTextureCoordsEnabled(true); if (prepareForDraw(opaque)) - shaderManager->currentProgram()->setUniformValue(location(ImageTexture), QT_IMAGE_TEXTURE_UNIT); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::ImageTexture), QT_IMAGE_TEXTURE_UNIT); if (pattern) { QColor col = premultiplyColor(q->state()->pen.color(), (GLfloat)q->state()->opacity); - shaderManager->currentProgram()->setUniformValue(location(PatternColor), col); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::PatternColor), col); } GLfloat dx = 1.0 / textureSize.width(); @@ -873,17 +873,17 @@ bool QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque) updateBrushUniforms(); if (shaderMatrixUniformDirty) { - shaderManager->currentProgram()->setUniformValue(location(PmvMatrix), pmvMatrix); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::PmvMatrix), pmvMatrix); shaderMatrixUniformDirty = false; } if (depthUniformDirty) { - shaderManager->currentProgram()->setUniformValue(location(Depth), (GLfloat)q->state()->currentDepth); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Depth), (GLfloat)q->state()->currentDepth); depthUniformDirty = false; } if (useGlobalOpacityUniform && opacityUniformDirty) { - shaderManager->currentProgram()->setUniformValue(location(GlobalOpacity), (GLfloat)q->state()->opacity); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::GlobalOpacity), (GLfloat)q->state()->opacity); opacityUniformDirty = false; } @@ -1166,7 +1166,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte prepareForDraw(false); // Text always causes src pixels to be transparent - shaderManager->currentProgram()->setUniformValue(location(MaskTexture), QT_MASK_TEXTURE_UNIT); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::MaskTexture), QT_MASK_TEXTURE_UNIT); if (vertexCoordinateArray.data() != oldVertexCoordinateDataPtr) glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray.data()); @@ -1210,23 +1210,6 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) d->shaderManager->setDirty(); } else { d->shaderManager = new QGLEngineShaderManager(d->ctx); - - d->uniformIdentifiers[QGL2PaintEngineExPrivate::ImageTexture] = d->shaderManager->getUniformIdentifier("imageTexture"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::PatternColor] = d->shaderManager->getUniformIdentifier("patternColor"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::GlobalOpacity] = d->shaderManager->getUniformIdentifier("globalOpacity"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::Depth] = d->shaderManager->getUniformIdentifier("depth"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::PmvMatrix] = d->shaderManager->getUniformIdentifier("pmvMatrix"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::MaskTexture] = d->shaderManager->getUniformIdentifier("maskTexture"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::FragmentColor] = d->shaderManager->getUniformIdentifier("fragmentColor"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::LinearData] = d->shaderManager->getUniformIdentifier("linearData"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::Angle] = d->shaderManager->getUniformIdentifier("angle"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::HalfViewportSize] = d->shaderManager->getUniformIdentifier("halfViewportSize"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::Fmp] = d->shaderManager->getUniformIdentifier("fmp"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::Fmp2MRadius2] = d->shaderManager->getUniformIdentifier("fmp2_m_radius2"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::Inverse2Fmp2MRadius2] = d->shaderManager->getUniformIdentifier("inverse_2_fmp2_m_radius2"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::InvertedTextureSize] = d->shaderManager->getUniformIdentifier("invertedTextureSize"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::BrushTransform] = d->shaderManager->getUniformIdentifier("brushTransform"); - d->uniformIdentifiers[QGL2PaintEngineExPrivate::BrushTexture] = d->shaderManager->getUniformIdentifier("brushTexture"); } glViewport(0, 0, d->width, d->height); diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 0d28a49..ec447a3 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -221,32 +221,11 @@ public: void systemStateChanged(); uint use_system_clip : 1; - enum Uniform { - ImageTexture, - PatternColor, - GlobalOpacity, - Depth, - PmvMatrix, - MaskTexture, - FragmentColor, - LinearData, - Angle, - HalfViewportSize, - Fmp, - Fmp2MRadius2, - Inverse2Fmp2MRadius2, - InvertedTextureSize, - BrushTransform, - BrushTexture, - NumUniforms - }; - - uint location(Uniform uniform) + uint location(QGLEngineShaderManager::Uniform uniform) { - return shaderManager->getUniformLocation(uniformIdentifiers[uniform]); + return shaderManager->getUniformLocation(uniform); } - uint uniformIdentifiers[NumUniforms]; GLuint lastTexture; bool needsSync; -- cgit v0.12 From d228015c67614051df8ae0b2f0483572fd667b83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Fri, 3 Jul 2009 17:38:38 +0200 Subject: Simplify QGraphicsScenePrivate::processDirtyItemsRecursive. This version is easier to read and is slightly faster than the old one. All auto-tests pass. --- src/gui/graphicsview/qgraphicsscene.cpp | 135 +++++++++++++++++--------------- src/gui/graphicsview/qgraphicsscene_p.h | 8 +- 2 files changed, 81 insertions(+), 62 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 85d05e9..bae1afd 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -414,9 +414,22 @@ void QGraphicsScenePrivate::_q_processDirtyItems() { processDirtyItemsEmitted = false; + if (updateAll) { + Q_ASSERT(calledEmitUpdated); + // No need for further processing (except resetting the dirty states). + // The growingItemsBoundingRect is updated in _q_emitUpdated. + for (int i = 0; i < topLevelItems.size(); ++i) + resetDirtyItem(topLevelItems.at(i), /*recursive=*/true); + return; + } + const bool wasPendingSceneUpdate = calledEmitUpdated; const QRectF oldGrowingItemsBoundingRect = growingItemsBoundingRect; - processDirtyItemsRecursive(0); + + // Process items recursively. + for (int i = 0; i < topLevelItems.size(); ++i) + processDirtyItemsRecursive(topLevelItems.at(i)); + dirtyGrowingItemsBoundingRect = false; if (!hasSceneRect && oldGrowingItemsBoundingRect != growingItemsBoundingRect) emit q_func()->sceneRectChanged(growingItemsBoundingRect); @@ -4416,48 +4429,67 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool qreal parentOpacity) { Q_Q(QGraphicsScene); + Q_ASSERT(item); + Q_ASSERT(!updateAll); - bool wasDirtyParentViewBoundingRects = false; - bool wasDirtyParentSceneTransform = false; - qreal opacity = parentOpacity; + if (!item->d_ptr->dirty && !item->d_ptr->dirtyChildren) { + resetDirtyItem(item); + return; + } - if (item) { - wasDirtyParentViewBoundingRects = item->d_ptr->paintedViewBoundingRectsNeedRepaint; - opacity = item->d_ptr->combineOpacityFromParent(parentOpacity); - const bool itemIsHidden = !item->d_ptr->ignoreVisible && !item->d_ptr->visible; - const bool itemIsFullyTransparent = !item->d_ptr->ignoreOpacity && opacity == 0.0; - - if (item->d_ptr->dirtySceneTransform && !itemIsHidden && !item->d_ptr->itemIsUntransformable() - && !(itemIsFullyTransparent && item->d_ptr->childrenCombineOpacity())) { - // Calculate the full scene transform for this item. - item->d_ptr->sceneTransform = item->d_ptr->parent ? item->d_ptr->parent->d_ptr->sceneTransform - : QTransform(); - item->d_ptr->combineTransformFromParent(&item->d_ptr->sceneTransform); - item->d_ptr->dirtySceneTransform = 0; - wasDirtyParentSceneTransform = true; - } + const bool itemIsHidden = !item->d_ptr->ignoreVisible && !item->d_ptr->visible; + if (itemIsHidden) { + resetDirtyItem(item, /*recursive=*/true); + return; + } - if (itemIsHidden || itemIsFullyTransparent || (item->d_ptr->flags & QGraphicsItem::ItemHasNoContents)) { - // Make sure we don't process invisible items or items with no content. - item->d_ptr->dirty = 0; + const bool itemHasContents = !(item->d_ptr->flags & QGraphicsItem::ItemHasNoContents); + const bool itemHasChildren = !item->d_ptr->children.isEmpty(); + if (!itemHasContents && !itemHasChildren) { + resetDirtyItem(item); + return; // Item has neither contents nor children!(?) + } + + const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity); + const bool itemIsFullyTransparent = !item->d_ptr->ignoreOpacity && opacity < 0.0001; + if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity())) { + resetDirtyItem(item, /*recursive=*/itemHasChildren); + return; + } + + bool wasDirtyParentSceneTransform = item->d_ptr->dirtySceneTransform; + const bool itemIsUntransformable = item->d_ptr->itemIsUntransformable(); + if (wasDirtyParentSceneTransform && !itemIsUntransformable) { + // Calculate the full scene transform for this item. + item->d_ptr->sceneTransform = item->d_ptr->parent ? item->d_ptr->parent->d_ptr->sceneTransform + : QTransform(); + item->d_ptr->combineTransformFromParent(&item->d_ptr->sceneTransform); + item->d_ptr->dirtySceneTransform = 0; + } + + const bool wasDirtyParentViewBoundingRects = item->d_ptr->paintedViewBoundingRectsNeedRepaint; + if (itemIsFullyTransparent || !itemHasContents || dirtyAncestorContainsChildren) { + // Make sure we don't process invisible items or items with no content. + item->d_ptr->dirty = 0; + item->d_ptr->fullUpdatePending = 0; + // Might have a dirty view bounding rect otherwise. + if (itemIsFullyTransparent || !itemHasContents) item->d_ptr->paintedViewBoundingRectsNeedRepaint = 0; - } + } - if (item->d_ptr->geometryChanged) { - // Update growingItemsBoundingRect. - if (!hasSceneRect && !itemIsHidden) - growingItemsBoundingRect |= item->d_ptr->sceneTransform.mapRect(item->boundingRect()); - item->d_ptr->geometryChanged = 0; - } + if (item->d_ptr->geometryChanged) { + // Update growingItemsBoundingRect. + if (!hasSceneRect) + growingItemsBoundingRect |= item->d_ptr->sceneTransform.mapRect(item->boundingRect()); + item->d_ptr->geometryChanged = 0; } // Process item. - if (item && (item->d_ptr->dirty || item->d_ptr->paintedViewBoundingRectsNeedRepaint)) { + if (item->d_ptr->dirty || item->d_ptr->paintedViewBoundingRectsNeedRepaint) { const bool useCompatUpdate = views.isEmpty() || (connectedSignals & changedSignalMask); - const bool untransformableItem = item->d_ptr->itemIsUntransformable(); const QRectF itemBoundingRect = adjustedItemBoundingRect(item); - if (useCompatUpdate && !untransformableItem && qFuzzyIsNull(item->boundingRegionGranularity())) { + if (useCompatUpdate && !itemIsUntransformable && qFuzzyIsNull(item->boundingRegionGranularity())) { // This block of code is kept for compatibility. Since 4.5, by default // QGraphicsView does not connect the signal and we use the below // method of delivering updates. @@ -4484,7 +4516,6 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool QRect &paintedViewBoundingRect = item->d_ptr->paintedViewBoundingRects[viewPrivate->viewport]; if (item->d_ptr->paintedViewBoundingRectsNeedRepaint) { - wasDirtyParentViewBoundingRects = true; paintedViewBoundingRect.translate(viewPrivate->dirtyScrollOffset); if (!viewPrivate->updateRect(paintedViewBoundingRect)) paintedViewBoundingRect = QRect(); @@ -4506,7 +4537,7 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool continue; // Discard updates outside the bounding rect. bool valid = false; - if (untransformableItem) { + if (itemIsUntransformable) { valid = updateHelper(viewPrivate, item->d_ptr, dirtyRect, item->deviceTransform(view->viewportTransform())); } else if (!view->isTransformed()) { @@ -4522,18 +4553,17 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool } } - // Process root items / children. - if (!item || item->d_ptr->dirtyChildren) { - QList *children = item ? &item->d_ptr->children : &topLevelItems; - const bool allChildrenDirty = item && item->d_ptr->allChildrenDirty; + // Process children. + if (itemHasChildren && item->d_ptr->dirtyChildren) { if (!dirtyAncestorContainsChildren) { - dirtyAncestorContainsChildren = item && item->d_ptr->fullUpdatePending + dirtyAncestorContainsChildren = item->d_ptr->fullUpdatePending && (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape); } - const bool parentIgnoresVisible = item && item->d_ptr->ignoreVisible; - const bool parentIgnoresOpacity = item && item->d_ptr->ignoreOpacity; - for (int i = 0; i < children->size(); ++i) { - QGraphicsItem *child = children->at(i); + const bool allChildrenDirty = item->d_ptr->allChildrenDirty; + const bool parentIgnoresVisible = item->d_ptr->ignoreVisible; + const bool parentIgnoresOpacity = item->d_ptr->ignoreOpacity; + for (int i = 0; i < item->d_ptr->children.size(); ++i) { + QGraphicsItem *child = item->d_ptr->children.at(i); if (wasDirtyParentSceneTransform) child->d_ptr->dirtySceneTransform = 1; if (wasDirtyParentViewBoundingRects) @@ -4542,36 +4572,19 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool child->d_ptr->ignoreVisible = 1; if (parentIgnoresOpacity) child->d_ptr->ignoreOpacity = 1; - if (allChildrenDirty) { child->d_ptr->dirty = 1; child->d_ptr->fullUpdatePending = 1; child->d_ptr->dirtyChildren = 1; child->d_ptr->allChildrenDirty = 1; - } else if (!child->d_ptr->dirty && !child->d_ptr->dirtyChildren) { - resetDirtyItem(child); - continue; } - - if (dirtyAncestorContainsChildren || updateAll) { - // No need to process this child's dirty rect, hence reset the dirty state. - // However, we have to continue the recursion because it might have a dirty - // view bounding rect that needs repaint. We also have to reset the dirty - // state of its descendants. - child->d_ptr->dirty = 0; - child->d_ptr->fullUpdatePending = 0; - if (updateAll) - child->d_ptr->paintedViewBoundingRectsNeedRepaint = 0; - } - processDirtyItemsRecursive(child, dirtyAncestorContainsChildren, opacity); } } else if (wasDirtyParentSceneTransform) { item->d_ptr->invalidateChildrenSceneTransform(); } - if (item) - resetDirtyItem(item); + resetDirtyItem(item); } /*! diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 245380f..bd72a71 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -207,18 +207,24 @@ public: void processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren = false, qreal parentOpacity = qreal(1.0)); - inline void resetDirtyItem(QGraphicsItem *item) + inline void resetDirtyItem(QGraphicsItem *item, bool recursive = false) { Q_ASSERT(item); item->d_ptr->dirty = 0; item->d_ptr->paintedViewBoundingRectsNeedRepaint = 0; item->d_ptr->geometryChanged = 0; + if (!item->d_ptr->dirtyChildren) + recursive = false; item->d_ptr->dirtyChildren = 0; item->d_ptr->needsRepaint = QRectF(); item->d_ptr->allChildrenDirty = 0; item->d_ptr->fullUpdatePending = 0; item->d_ptr->ignoreVisible = 0; item->d_ptr->ignoreOpacity = 0; + if (recursive) { + for (int i = 0; i < item->d_ptr->children.size(); ++i) + resetDirtyItem(item->d_ptr->children.at(i), recursive); + } } inline void ensureSortedTopLevelItems() -- cgit v0.12 From d3de6acd72b42ebe99bba104c83cfbfda538cc33 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 6 Jul 2009 09:15:15 +0200 Subject: qdoc: Added missing CR to help message. --- tools/qdoc3/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/qdoc3/main.cpp b/tools/qdoc3/main.cpp index 5a98275..6425765 100644 --- a/tools/qdoc3/main.cpp +++ b/tools/qdoc3/main.cpp @@ -128,7 +128,7 @@ static void printHelp() " -D " "Define as a macro while parsing sources\n" " -slow " - "Turn on features that slow down qdoc" + "Turn on features that slow down qdoc\n" " -showinternal " "Include stuff marked internal") ); } -- cgit v0.12 From cb78e8165bd9e210b336a59065f710d24cae5dd2 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 6 Jul 2009 10:34:16 +0200 Subject: doc: Added note about qmake not building to two targets simultaneously Task-number: 256486 --- doc/src/qmake-manual.qdoc | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/doc/src/qmake-manual.qdoc b/doc/src/qmake-manual.qdoc index 5b261ab..049f30c 100644 --- a/doc/src/qmake-manual.qdoc +++ b/doc/src/qmake-manual.qdoc @@ -829,6 +829,29 @@ Note that, if a project is later moved on the disk, \c qmake must be run again to process the project file and create a new Xcode project file. + \section2 On supporting two build targets simultaneously + + Implementing this is currently not feasible, because the XCode + concept of Active Build Configurations is conceptually different + from the qmake idea of build targets. + + The XCode Active Build Configurations settings are for modifying + xcode configurations, compiler flags and similar build + options. Unlike Visual Studio, XCode does not allow for the + selection of specific library files based on whether debug or + release build configurations are selected. The qmake debug and + release settings control which library files are linked to the + executable. + + It is currently not possible to set files in XCode configuration + settings from the qmake generated xcode project file. The way the + libraries are linked in the "Frameworks & Libraries" phase in the + XCode build system. + + Furthermore, The selected "Active Build Configuration" is stored + in a .pbxuser file, which is generated by xcode on first load, not + created by qmake. + \section1 Windows Features specific to this platform include support for creating Visual -- cgit v0.12 From 1737e24412ba3becd9b4a86bff3656281767564c Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 6 Jul 2009 10:48:04 +0200 Subject: doc: Removed specific reference to Mac OS X. Task-number: 256452 --- src/gui/dialogs/qfiledialog.cpp | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp index f6a8602..849f4b3 100644 --- a/src/gui/dialogs/qfiledialog.cpp +++ b/src/gui/dialogs/qfiledialog.cpp @@ -209,25 +209,30 @@ Q_GUI_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook /*! \enum QFileDialog::Option - \value ShowDirsOnly Only show directories in the file dialog. By default both files and - directories are shown. (Valid only in the \l Directory file mode.) - \value DontResolveSymlinks Don't resolve symlinks in the file dialog. By default symlinks - are resolved. - \value DontConfirmOverwrite Don't ask for confirmation if an existing file is selected. - By default confirmation is requested. - \value DontUseNativeDialog Don't use the native file dialog. By default on Mac OS X, - the native file dialog is used unless you use a subclass of QFileDialog that contains the - Q_OBJECT macro. + \value ShowDirsOnly Only show directories in the file dialog. By + default both files and directories are shown. (Valid only in the + \l Directory file mode.) + + \value DontResolveSymlinks Don't resolve symlinks in the file + dialog. By default symlinks are resolved. + + \value DontConfirmOverwrite Don't ask for confirmation if an + existing file is selected. By default confirmation is requested. + + \value DontUseNativeDialog Don't use the native file dialog. By + default, the native file dialog is used unless you use a subclass + of QFileDialog that contains the Q_OBJECT macro. + \value ReadOnly Indicates that the model is readonly. - \value HideNameFilterDetails Indicates if the is hidden or not. + \value HideNameFilterDetails Indicates if the is hidden or not. This value is obsolete and does nothing since Qt 4.5: - \value DontUseSheet In previous versions of Qt, the static functions would - create a sheet by default if the static function was given a parent. This - is no longer supported in Qt 4.5, The static functions will always be an - application modal dialog. If you want to use sheets, use - QFileDialog::open() instead. + \value DontUseSheet In previous versions of Qt, the static + functions would create a sheet by default if the static function + was given a parent. This is no longer supported in Qt 4.5, The + static functions will always be an application modal dialog. If + you want to use sheets, use QFileDialog::open() instead. */ -- cgit v0.12 From 423d40c56f090f3619c8df5667dcfcb0c0a0dc32 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 6 Jul 2009 11:24:21 +0200 Subject: doc: Added not about Mac OS X. On Mac OS X, QMenuBar::clear() does not remove menu items that have been merged into the system menu bar. Task-number: 255222 --- src/gui/widgets/qmenubar.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp index e1d41de..caacc58 100644 --- a/src/gui/widgets/qmenubar.cpp +++ b/src/gui/widgets/qmenubar.cpp @@ -956,6 +956,13 @@ void QMenuBar::setActiveAction(QAction *act) /*! Removes all the actions from the menu bar. + \note On Mac OS X, menu items that have been merged to the system + menu bar are not removed by this function. One way to handle this + would be to remove the extra actions yourself. You can set the + \l{QAction::MenuRole}{menu role} on the different menus, so that + you know ahead of time which menu items get merged and which do + not. Then decide what to recreate or remove yourself. + \sa removeAction() */ void QMenuBar::clear() -- cgit v0.12 From c4b7fab9e8296915fff700704db26161bac8df0c Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Mon, 6 Jul 2009 10:19:01 +0200 Subject: Fix to paint big widgets in a scroll area If a big widget is inside a scroll area, and this widget is in the limits of XCOORD_MAX, its child might not be inside the limits. The child is then limited to wrect, but wrect might not be on the screen because the parent is scrolled. To avoid this problem, the widgets position should not influence whether wrect is used or not. Task-number: 144779 Reviewed-by: nrc --- src/gui/kernel/qwidget_mac.mm | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index d1e4230..b0531ec 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -3823,7 +3823,6 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect) Qt coordinate system for parent X coordinate system for parent (relative to parent's wrect). */ - QRect validRange(-XCOORD_MAX,-XCOORD_MAX, 2*XCOORD_MAX, 2*XCOORD_MAX); QRect wrectRange(-WRECT_MAX,-WRECT_MAX, 2*WRECT_MAX, 2*WRECT_MAX); QRect wrect; //xrect is the X geometry of my X widget. (starts out in parent's Qt coord sys, and ends up in parent's X coord sys) @@ -3901,7 +3900,7 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect) } } - if (!validRange.contains(xrect)) { + if (xrect.height() > XCOORD_MAX || xrect.width() > XCOORD_MAX) { // we are too big, and must clip xrect &=wrectRange; wrect = xrect; @@ -3949,10 +3948,9 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect) qt_mac_update_widget_posisiton(q, oldRect, xrect); - if (jump) { - updateSystemBackground(); + if (jump) q->update(); - } + if (mapWindow && !dontShow) { q->setAttribute(Qt::WA_Mapped); #ifndef QT_MAC_USE_COCOA -- cgit v0.12 From f0cd15365d683ad1998a32aab305cbcf69c3140e Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 6 Jul 2009 13:11:42 +0200 Subject: doc: Corrected comment about effect of deleting a QObject from a thread. Task-number: 151180 --- doc/src/threads.qdoc | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/doc/src/threads.qdoc b/doc/src/threads.qdoc index c9d0904..9f7f857 100644 --- a/doc/src/threads.qdoc +++ b/doc/src/threads.qdoc @@ -428,20 +428,22 @@ an object and its children (the object cannot be moved if it has a parent). - Calling \c delete on a QObject from another thread than the - thread where it is created (or accessing the object in other - ways) is unsafe unless you can guarantee that the object isn't - processing events at the same moment. Use QObject::deleteLater() - instead; it will post a - \l{QEvent::DeferredDelete}{DeferredDelete} event, which the - event loop of the object's thread will eventually pick up. + Calling \c delete on a QObject from a thread other than the one + that \e owns the object (or accessing the object in other ways) is + unsafe, unless you guarantee that the object isn't processing + events at that moment. Use QObject::deleteLater() instead, and a + \l{QEvent::DeferredDelete}{DeferredDelete} event will be posted, + which the event loop of the object's thread will eventually pick + up. By default, the thread that \e owns a QObject is the thread + that \e creates the QObject, but not after QObject::moveToThread() + has been called. If no event loop is running, events won't be delivered to the - object. For example, if you create a QTimer object in a thread - but never call \l{QThread::exec()}{exec()}, the QTimer will never emit its - \l{QTimer::timeout()}{timeout()} signal. Calling - \l{QObject::deleteLater()}{deleteLater()} won't work either. (These - restrictions apply to the main thread as well.) + object. For example, if you create a QTimer object in a thread but + never call \l{QThread::exec()}{exec()}, the QTimer will never emit + its \l{QTimer::timeout()}{timeout()} signal. Calling + \l{QObject::deleteLater()}{deleteLater()} won't work + either. (These restrictions apply to the main thread as well.) You can manually post events to any object in any thread at any time using the thread-safe function -- cgit v0.12 From e446729d99bebaf7fac0110fcf22fc867d7229cb Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 3 Jul 2009 11:55:06 +0200 Subject: remove arbitrary string length limits --- tools/linguist/lupdate/cpp.cpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index b1d2d01..35b41d4 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -58,10 +58,6 @@ QT_BEGIN_NAMESPACE static const char MagicComment[] = "TRANSLATOR "; -static const int yyIdentMaxLen = 128; -static const int yyCommentMaxLen = 65536; -static const int yyStringMaxLen = 65536; - #define STRINGIFY_INTERNAL(x) #x #define STRINGIFY(x) STRINGIFY_INTERNAL(x) #define STRING(s) static QString str##s(QLatin1String(STRINGIFY(s))) @@ -668,14 +664,9 @@ uint CppParser::getToken() yyCh = getChar(); if (yyCh == EOF || yyCh == '\n') break; - if (yyString.size() < yyStringMaxLen) { - yyString.append(QLatin1Char('\\')); - yyString.append(yyCh); - } - } else { - if (yyString.size() < yyStringMaxLen) - yyString.append(yyCh); + yyString.append(QLatin1Char('\\')); } + yyString.append(yyCh); yyCh = getChar(); } -- cgit v0.12 From 20d73ef1bf23569b09ca862f6c5e5971098613d6 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 3 Jul 2009 13:28:16 +0200 Subject: support for id-based translations unlike in an earlier attempt, ids are textual this time. the developer is able to provide a template for the string. when lupdate and lrelease are integrated into the build process, this makes it possible to avoid a round-trip to a dedicated string designer during the early development stage. Requirement-id: QT-435 --- .../snippets/code/src_corelib_global_qglobal.cpp | 24 ++++++++ src/corelib/global/qglobal.cpp | 56 +++++++++++++++++ src/corelib/global/qglobal.h | 12 ++++ src/corelib/kernel/qcoreapplication.cpp | 6 ++ tests/auto/linguist/lrelease/tst_lrelease.cpp | 13 ++++ .../lupdate/testdata/good/parsecpp/main.cpp | 12 ++++ .../testdata/good/parsecpp/project.ts.result | 18 ++++++ tools/linguist/lrelease/main.cpp | 19 ++++-- tools/linguist/lupdate/cpp.cpp | 70 +++++++++++++++++++++- tools/linguist/shared/qm.cpp | 52 ++++++++++++---- tools/linguist/shared/translator.h | 2 + 11 files changed, 267 insertions(+), 17 deletions(-) diff --git a/doc/src/snippets/code/src_corelib_global_qglobal.cpp b/doc/src/snippets/code/src_corelib_global_qglobal.cpp index 287181a..50052c3 100644 --- a/doc/src/snippets/code/src_corelib_global_qglobal.cpp +++ b/doc/src/snippets/code/src_corelib_global_qglobal.cpp @@ -358,6 +358,30 @@ QString global_greeting(int type) //! [36] +//! [qttrid] + //% "%n fooish bar(s) found.\n" + //% "Do you want to continue?" + QString text = qtTrId("qtn_foo_bar", n); +//! [qttrid] + + +//! [qttrid_noop] +static const char * const ids[] = { + //% "This is the first text." + QT_TRID_NOOP("qtn_1st_text"), + //% "This is the second text." + QT_TRID_NOOP("qtn_2nd_text"), + 0 +}; + +void TheClass::addLabels() +{ + for (int i = 0; ids[i]; ++i) + new QLabel(qtTrId(ids[i]), this); +} +//! [qttrid_noop] + + //! [37] qWarning("%s: %s", qPrintable(key), qPrintable(value)); //! [37] diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index f7a97e1..ad4868d 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -2459,6 +2459,62 @@ int qrand() */ /*! + \fn QString qtTrId(const char *id, int n = -1) + \relates + \reentrant + \since 4.6 + + Returns a translated string identified by \a id. + If no matching string is found, the id itself is returned. This + should not happen under normal conditions. + + If \a n >= 0, all occurrences of \c %n in the resulting string + are replaced with a decimal representation of \a n. In addition, + depending on \a n's value, the translation text may vary. + + Meta data and comments can be passed as documented for QObject::tr(). + In addition, it is possible to supply a source string template like that: + + \tt{//% } + + or + + \tt{\begincomment% \endcomment} + + Example: + + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp qttrid + + Creating QM files suitable for use with this function requires passing + the \c -idbased option to the \c lrelease tool. + + \warning This method is reentrant only if all translators are + installed \e before calling this method. Installing or removing + translators while performing translations is not supported. Doing + so will probably result in crashes or other undesirable behavior. + + \sa QObject::tr(), QCoreApplication::translate(), {Internationalization with Qt} +*/ + +/*! + \macro QT_TRID_NOOP(id) + \relates + \since 4.6 + + Marks \a id for dynamic translation. + The only purpose of this macro is to provide an anchor for attaching + meta data like to qtTrId(). + + The macro expands to \a id. + + Example: + + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp qttrid_noop + + \sa qtTrId(), {Internationalization with Qt} +*/ + +/*! \macro QT_POINTER_SIZE \relates diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index a522bcf..a139a55 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -2198,6 +2198,18 @@ inline const QForeachContainer *qForeachContainer(const QForeachContainerBase #define QT_TRANSLATE_NOOP_UTF8(scope, x) (x) #define QT_TRANSLATE_NOOP3(scope, x, comment) {x, comment} #define QT_TRANSLATE_NOOP3_UTF8(scope, x, comment) {x, comment} + +#ifndef QT_NO_TRANSLATION // ### This should enclose the NOOPs above + +// Defined in qcoreapplication.cpp +// The better name qTrId() is reserved for an upcoming function which would +// return a much more powerful QStringFormatter instead of a QString. +Q_CORE_EXPORT QString qtTrId(const char *id, int n = -1); + +#define QT_TRID_NOOP(id) id + +#endif // QT_NO_TRANSLATION + #define QDOC_PROPERTY(text) /* diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index e2708c3..054be70 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -1675,6 +1675,12 @@ QString QCoreApplication::translate(const char *context, const char *sourceText, return result; } +// Declared in qglobal.h +QString qtTrId(const char *id, int n) +{ + return QCoreApplication::translate(0, id, 0, QCoreApplication::UnicodeUTF8, n); +} + bool QCoreApplicationPrivate::isTranslatorInstalled(QTranslator *translator) { return QCoreApplication::self diff --git a/tests/auto/linguist/lrelease/tst_lrelease.cpp b/tests/auto/linguist/lrelease/tst_lrelease.cpp index 512987d..ff90b3c 100644 --- a/tests/auto/linguist/lrelease/tst_lrelease.cpp +++ b/tests/auto/linguist/lrelease/tst_lrelease.cpp @@ -55,6 +55,7 @@ private slots: void translate(); void mixedcodecs(); void compressed(); + void idbased(); void dupes(); private: @@ -191,6 +192,18 @@ void tst_lrelease::compressed() } +void tst_lrelease::idbased() +{ + QVERIFY(!QProcess::execute("lrelease -idbased testdata/idbased.ts")); + + QTranslator translator; + QVERIFY(translator.load("testdata/idbased.qm")); + qApp->installTranslator(&translator); + + QCOMPARE(qtTrId("test_id"), QString::fromAscii("This is a test string.")); + QCOMPARE(qtTrId("untranslated_id"), QString::fromAscii("This has no translation.")); +} + void tst_lrelease::dupes() { QProcess proc; diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp index 9fb43fe..735e4cd 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp +++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp @@ -175,3 +175,15 @@ class TestingTake17 : QObject { tr("even more cool"); } }; + + + + +//: again an extra comment, this time for id-based NOOP +//% "This is supposed\tto be quoted \" newline\n" +//% "backslashed \\ stuff." +QT_TRID_NOOP("this_a_id") + +//~ some thing +//% "This needs to be here. Really." +QString test = qtTrId("this_another_id", n); diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result index 5bd7525..97d3bce 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result +++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result @@ -2,6 +2,24 @@ + + + + This is supposed to be quoted " newline +backslashed \ stuff. + again an extra comment, this time for id-based NOOP + + + + + This needs to be here. Really. + + + + thing + + + Dialog2 diff --git a/tools/linguist/lrelease/main.cpp b/tools/linguist/lrelease/main.cpp index 86b7866..5fbecac 100644 --- a/tools/linguist/lrelease/main.cpp +++ b/tools/linguist/lrelease/main.cpp @@ -70,6 +70,8 @@ static void printUsage() "format into the 'compiled' .qm format used by QTranslator objects.\n\n" "Options:\n" " -help Display this information and exit\n" + " -idbased\n" + " Use IDs instead of source strings for message keying\n" " -compress\n" " Compress the .qm files\n" " -nounfinished\n" @@ -99,7 +101,7 @@ static bool loadTsFile(Translator &tor, const QString &tsFileName, bool /* verbo static bool releaseTranslator(Translator &tor, const QString &qmFileName, bool verbose, bool ignoreUnfinished, - bool removeIdentical, TranslatorSaveMode mode) + bool removeIdentical, bool idBased, TranslatorSaveMode mode) { Translator::reportDuplicates(tor.resolveDuplicates(), qmFileName, verbose); @@ -121,6 +123,7 @@ static bool releaseTranslator(Translator &tor, const QString &qmFileName, ConversionData cd; cd.m_verbose = verbose; cd.m_ignoreUnfinished = ignoreUnfinished; + cd.m_idBased = idBased; cd.m_saveMode = mode; bool ok = tor.release(&file, cd); file.close(); @@ -136,7 +139,7 @@ static bool releaseTranslator(Translator &tor, const QString &qmFileName, } static bool releaseTsFile(const QString& tsFileName, bool verbose, - bool ignoreUnfinished, bool removeIdentical, TranslatorSaveMode mode) + bool ignoreUnfinished, bool removeIdentical, bool idBased, TranslatorSaveMode mode) { Translator tor; if (!loadTsFile(tor, tsFileName, verbose)) @@ -151,7 +154,7 @@ static bool releaseTsFile(const QString& tsFileName, bool verbose, } qmFileName += QLatin1String(".qm"); - return releaseTranslator(tor, qmFileName, verbose, ignoreUnfinished, removeIdentical, mode); + return releaseTranslator(tor, qmFileName, verbose, ignoreUnfinished, removeIdentical, idBased, mode); } int main(int argc, char **argv) @@ -164,6 +167,7 @@ int main(int argc, char **argv) bool verbose = true; // the default is true starting with Qt 4.2 bool ignoreUnfinished = false; + bool idBased = false; // the default mode is SaveEverything starting with Qt 4.2 TranslatorSaveMode mode = SaveEverything; bool removeIdentical = false; @@ -175,6 +179,9 @@ int main(int argc, char **argv) if (args[i] == QLatin1String("-compress")) { mode = SaveStripped; continue; + } else if (args[i] == QLatin1String("-idbased")) { + idBased = true; + continue; } else if (args[i] == QLatin1String("-nocompress")) { mode = SaveEverything; continue; @@ -232,7 +239,7 @@ int main(int argc, char **argv) qPrintable(args[i])); } else { foreach (const QString &trans, translations) - if (!releaseTsFile(trans, verbose, ignoreUnfinished, removeIdentical, mode)) + if (!releaseTsFile(trans, verbose, ignoreUnfinished, removeIdentical, idBased, mode)) return 1; } } else { @@ -243,7 +250,7 @@ int main(int argc, char **argv) } } else { if (outputFile.isEmpty()) { - if (!releaseTsFile(args[i], verbose, ignoreUnfinished, removeIdentical, mode)) + if (!releaseTsFile(args[i], verbose, ignoreUnfinished, removeIdentical, idBased, mode)) return 1; } else { if (!loadTsFile(tor, args[i], verbose)) @@ -254,7 +261,7 @@ int main(int argc, char **argv) if (!outputFile.isEmpty()) return releaseTranslator(tor, outputFile, verbose, ignoreUnfinished, - removeIdentical, mode) ? 0 : 1; + removeIdentical, idBased, mode) ? 0 : 1; return 0; } diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index 35b41d4..58e094b 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -199,7 +199,7 @@ private: enum { Tok_Eof, Tok_class, Tok_friend, Tok_namespace, Tok_using, Tok_return, - Tok_tr = 10, Tok_trUtf8, Tok_translate, Tok_translateUtf8, + Tok_tr = 10, Tok_trUtf8, Tok_translate, Tok_translateUtf8, Tok_trid, Tok_Q_OBJECT = 20, Tok_Q_DECLARE_TR_FUNCTIONS, Tok_Ident, Tok_Comment, Tok_String, Tok_Arrow, Tok_Colon, Tok_ColonColon, Tok_Equals, @@ -553,6 +553,8 @@ uint CppParser::getToken() return Tok_Q_DECLARE_TR_FUNCTIONS; if (yyIdent == QLatin1String("QT_TR_NOOP")) return Tok_tr; + if (yyIdent == QLatin1String("QT_TRID_NOOP")) + return Tok_trid; if (yyIdent == QLatin1String("QT_TRANSLATE_NOOP")) return Tok_translate; if (yyIdent == QLatin1String("QT_TRANSLATE_NOOP3")) @@ -588,6 +590,10 @@ uint CppParser::getToken() if (yyIdent == QLatin1String("namespace")) return Tok_namespace; break; + case 'q': + if (yyIdent == QLatin1String("qtTrId")) + return Tok_trid; + break; case 'r': if (yyIdent == QLatin1String("return")) return Tok_return; @@ -1328,6 +1334,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) QString comment; QString extracomment; QString msgid; + QString sourcetext; TranslatorMessage::ExtraData extra; QString prefix; #ifdef DIAGNOSE_RETRANSLATABILITY @@ -1514,6 +1521,9 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) case Tok_trUtf8: if (!results->tor) goto case_default; + if (!sourcetext.isEmpty()) + qWarning("%s:%d: //%% cannot be used with tr() / QT_TR_NOOP(). Ignoring\n", + qPrintable(yyFileName), yyLineNo); utf8 = (yyTok == Tok_trUtf8); line = yyLineNo; yyTok = getToken(); @@ -1611,6 +1621,9 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) case Tok_translate: if (!results->tor) goto case_default; + if (!sourcetext.isEmpty()) + qWarning("%s:%d: //%% cannot be used with translate() / QT_TRANSLATE_NOOP(). Ignoring\n", + qPrintable(yyFileName), yyLineNo); utf8 = (yyTok == Tok_translateUtf8); line = yyLineNo; yyTok = getToken(); @@ -1660,6 +1673,27 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) msgid.clear(); extra.clear(); break; + case Tok_trid: + if (!results->tor) + goto case_default; + if (!sourcetext.isEmpty()) { + if (!msgid.isEmpty()) + qWarning("%s:%d: //= cannot be used with qtTrId() / QT_TRID_NOOP(). Ignoring\n", + qPrintable(yyFileName), yyLineNo); + //utf8 = false; // Maybe use //%% or something like that + line = yyLineNo; + yyTok = getToken(); + if (match(Tok_LeftParen) && matchString(&msgid) && !msgid.isEmpty()) { + bool plural = match(Tok_Comma); + recordMessage(line, QString(), sourcetext, QString(), extracomment, + msgid, extra, false, plural); + } + sourcetext.clear(); + } + extracomment.clear(); + msgid.clear(); + extra.clear(); + break; case Tok_Q_DECLARE_TR_FUNCTIONS: case Tok_Q_OBJECT: namespaces.last()->hasTrFunctions = true; @@ -1689,6 +1723,40 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) int k = yyComment.indexOf(QLatin1Char(' ')); if (k > -1) extra.insert(yyComment.left(k), yyComment.mid(k + 1).trimmed()); + } else if (yyComment.startsWith(QLatin1Char('%'))) { + int p = 1, c; + forever { + if (p >= yyComment.length()) + break; + c = yyComment.unicode()[p++].unicode(); + if (isspace(c)) + continue; + if (c != '"') { + qWarning("%s:%d: Unexpected character in meta string\n", + qPrintable(yyFileName), yyLineNo); + break; + } + forever { + if (p >= yyComment.length()) { + whoops: + qWarning("%s:%d: Unterminated meta string\n", + qPrintable(yyFileName), yyLineNo); + break; + } + c = yyComment.unicode()[p++].unicode(); + if (c == '"') + break; + if (c == '\\') { + if (p >= yyComment.length()) + goto whoops; + c = yyComment.unicode()[p++].unicode(); + if (c == '\n') + goto whoops; + sourcetext.append(QLatin1Char('\\')); + } + sourcetext.append(c); + } + } } else { comment = yyComment.simplified(); if (comment.startsWith(QLatin1String(MagicComment))) { diff --git a/tools/linguist/shared/qm.cpp b/tools/linguist/shared/qm.cpp index ec61cb6..05d8e12 100644 --- a/tools/linguist/shared/qm.cpp +++ b/tools/linguist/shared/qm.cpp @@ -173,6 +173,7 @@ public: bool save(QIODevice *iod); void insert(const TranslatorMessage &msg, bool forceComment); + void insertIdBased(const TranslatorMessage &message); void squeeze(TranslatorSaveMode mode); @@ -436,6 +437,16 @@ void Releaser::insert(const TranslatorMessage &message, bool forceComment) insertInternal(message, forceComment, false); } +void Releaser::insertIdBased(const TranslatorMessage &message) +{ + QStringList tlns = message.translations(); + for (int i = 0; i < tlns.size(); ++i) + if (tlns.at(i).isEmpty()) + tlns[i] = message.sourceText(); + ByteTranslatorMessage bmsg("", originalBytes(message.id(), false), "", tlns); + m_messages.insert(bmsg, 0); +} + void Releaser::setNumerusRules(const QByteArray &rules) { m_numerusRules = rules; @@ -689,11 +700,17 @@ static bool saveQM(const Translator &translator, QIODevice &dev, ConversionData int finished = 0; int unfinished = 0; int untranslated = 0; + int missingIds = 0; + int droppedData = 0; for (int i = 0; i != translator.messageCount(); ++i) { const TranslatorMessage &msg = translator.message(i); TranslatorMessage::Type typ = msg.type(); if (typ != TranslatorMessage::Obsolete) { + if (cd.m_idBased && msg.id().isEmpty()) { + ++missingIds; + continue; + } if (typ == TranslatorMessage::Unfinished) { if (msg.translation().isEmpty()) { ++untranslated; @@ -706,19 +723,34 @@ static bool saveQM(const Translator &translator, QIODevice &dev, ConversionData } else { ++finished; } - // Drop the comment in (context, sourceText, comment), - // unless the context is empty, - // unless (context, sourceText, "") already exists or - // unless we already dropped the comment of (context, - // sourceText, comment0). - bool forceComment = - msg.comment().isEmpty() - || msg.context().isEmpty() - || translator.contains(msg.context(), msg.sourceText(), QString()); - releaser.insert(msg, forceComment); + if (cd.m_idBased) { + if (!msg.context().isEmpty() || !msg.comment().isEmpty()) + ++droppedData; + releaser.insertIdBased(msg); + } else { + // Drop the comment in (context, sourceText, comment), + // unless the context is empty, + // unless (context, sourceText, "") already exists or + // unless we already dropped the comment of (context, + // sourceText, comment0). + bool forceComment = + msg.comment().isEmpty() + || msg.context().isEmpty() + || translator.contains(msg.context(), msg.sourceText(), QString()); + releaser.insert(msg, forceComment); + } } } + if (missingIds) + cd.appendError(QCoreApplication::translate("LRelease", + "Dropped %n message(s) which had no ID.", 0, + QCoreApplication::CodecForTr, missingIds)); + if (droppedData) + cd.appendError(QCoreApplication::translate("LRelease", + "Excess context/disambiguation dropped from %n message(s).", 0, + QCoreApplication::CodecForTr, droppedData)); + releaser.squeeze(cd.m_saveMode); bool saved = releaser.save(&dev); if (saved && cd.isVerbose()) { diff --git a/tools/linguist/shared/translator.h b/tools/linguist/shared/translator.h index ac824f3..fb17fd1 100644 --- a/tools/linguist/shared/translator.h +++ b/tools/linguist/shared/translator.h @@ -65,6 +65,7 @@ public: m_ignoreUnfinished(false), m_sortContexts(false), m_noUiLines(false), + m_idBased(false), m_saveMode(SaveEverything) {} @@ -97,6 +98,7 @@ public: bool m_ignoreUnfinished; bool m_sortContexts; bool m_noUiLines; + bool m_idBased; TranslatorSaveMode m_saveMode; }; -- cgit v0.12 From a59fbee567571827c3a1505b125b9dfb3788c79e Mon Sep 17 00:00:00 2001 From: Frederik Schwarzer Date: Mon, 6 Jul 2009 13:45:28 +0200 Subject: update German translation - unification - typos Merge-request: 823 Reviewed-by: Oswald Buddenhagen --- translations/assistant_de.ts | 100 +++++++++++----------- translations/linguist_de.ts | 194 +++++++++++++++++++++---------------------- 2 files changed, 150 insertions(+), 144 deletions(-) diff --git a/translations/assistant_de.ts b/translations/assistant_de.ts index 72b24b6..f702465 100644 --- a/translations/assistant_de.ts +++ b/translations/assistant_de.ts @@ -14,7 +14,7 @@ Warning - Warnung + Achtung @@ -68,12 +68,12 @@ Delete Folder - Verzeichnis löschen + Ordner löschen Rename Folder - Verzeichnis umbenennen + Ordner umbenennen @@ -91,7 +91,7 @@ You are going to delete a Folder, this will also<br>remove it's content. Are you sure to continue? - Wenn Sie dieses Verzeichnis löschen, wird auch<br>dessen kompletter Inhalt gelöscht! Fortfahren? + Wenn Sie diesen Ordner löschen, wird auch<br>dessen kompletter Inhalt gelöscht. Möchten Sie wirklich fortfahren? @@ -123,12 +123,12 @@ Delete Folder - Verzeichnis löschen + Ordner löschen Rename Folder - Verzeichnis umbenennen + Ordner umbenennen @@ -201,7 +201,7 @@ Add Bookmark for this Page... - Lesezeichen für diese Seite hinzufügen... + Lesezeichen für diese Seite hinzufügen ... @@ -236,7 +236,7 @@ Filter Name: - Filter Name: + Filtername: @@ -244,22 +244,22 @@ Previous - Vorherige + Zurück Next - Nächste + Weiter Case Sensitive - Gross/ Kleinschreibung beachten + Groß-/Kleinschreibung beachten Whole words - Gesamte Worte + Ganze Wörter @@ -316,12 +316,12 @@ <title>Error 404...</title><div align="center"><br><br><h1>The page could not be found</h1><br><h3>'%1'</h3></div> - <title>Fehler 404...</title><div align="center"><br><br><h1>Die Seite konnte nicht gefunden werden!</h1><br><h3>'%1'</h3></div> + <title>Fehler 404 ...</title><div align="center"><br><br><h1>Die Seite kann nicht gefunden werden.</h1><br><h3>'%1'</h3></div> Copy &Link Location - &Link Adresse kopieren + &Link-Adresse kopieren @@ -346,7 +346,7 @@ &Look for: - Suche &nach: + Suchen &nach: @@ -370,7 +370,7 @@ Downloading documentation info... - Dokumentationsinformation herunterladen... + Dokumentationsinformation herunterladen ... @@ -387,12 +387,12 @@ The file %1 already exists. Do you want to overwrite it? - Die Datei %1 existiert bereits. Überschreiben? + Die Datei %1 existiert bereits. Möchten Sie sie überschreiben? Unable to save the file %1: %2. - Die Datei %1 konnte nicht gespeichert werden! Ursache: %2 + Die Datei %1 kann nicht gespeichert werden: %2. @@ -404,7 +404,7 @@ Download failed: %1. - Herunterladen fehlgeschlagen: %1 + Herunterladen fehlgeschlagen: %1. @@ -431,7 +431,7 @@ Available Documentation: - Verfügbare Dokumentationen: + Verfügbare Dokumentation: @@ -451,7 +451,7 @@ Installation Path: - Installationsverzeichnis: + Installationsordner: @@ -504,17 +504,17 @@ Page Set&up... - S&eite einrichten... + S&eite einrichten ... Print Preview... - Druckvorschau... + Druckvorschau ... &Print... - &Drucken... + &Drucken ... CTRL+P @@ -523,7 +523,7 @@ New &Tab - Neue &Seite + Neuer &Tab CTRL+T @@ -532,7 +532,7 @@ &Close Tab - &Seite schließen + Tab &schließen CTRL+W @@ -555,7 +555,7 @@ &Copy selected Text - &Kopieren + Ausgewählten Text &kopieren Ctrl+C @@ -564,7 +564,7 @@ &Find in Text... - &Textsuche... + &Textsuche ... Ctrl+F @@ -591,7 +591,7 @@ Preferences... - Einstellungen... + Einstellungen ... View @@ -656,7 +656,7 @@ Ctrl+Home - Strg+Pos1 + Ctrl+Home @@ -671,7 +671,7 @@ Sync with Table of Contents - Seite mit Inhalt Tab syncronisieren + Seite mit Inhalt-Tab abgleichen @@ -696,7 +696,7 @@ Add Bookmark... - Lesezeichen hinzufügen... + Lesezeichen hinzufügen ... CTRL+B @@ -709,7 +709,7 @@ About... - Über... + Über ... @@ -775,7 +775,7 @@ Looking for Qt Documentation... - Suche nach Qt-Dokumentation... + Suche nach Qt-Dokumentation ... @@ -790,7 +790,7 @@ Ctrl+M - CTRL+M + Ctrl+M @@ -823,7 +823,7 @@ &Go - &Gehe + &Gehe zu @@ -869,12 +869,12 @@ Qt Compressed Help Files (*.qch) - Komprimierte Hilfe-Dateien (*.qch) + Komprimierte Hilfedateien (*.qch) The specified file is not a valid Qt Help File! - Die angegebene Datei ist keine Qt-Hilfe-Datei. + Die angegebene Datei ist keine Qt-Hilfedatei. @@ -889,7 +889,7 @@ Some documents currently opened in Assistant reference the documentation you are attempting to remove. Removing the documentation will close those documents. - Einige der gegenwärtig geöffneten Dokumente stammen aus der Dokumentation, die Sie gerade zu löschen versuchen. Sie werden beim Löschen geschlossen. + Einige der derzeit geöffneten Dokumente stammen aus der Dokumentation, die Sie gerade zu löschen versuchen. Sie werden beim Löschen geschlossen. @@ -904,7 +904,7 @@ Use custom settings - Benutze erweiterte Einstellungen + Benutzerdefinierte Einstellungen verwenden @@ -972,12 +972,12 @@ Registered Documentation: - Registrierte Dokumentationen: + Registrierte Dokumentation: Add... - Hinzufügen... + Hinzufügen ... Network @@ -1008,7 +1008,7 @@ Restore to default - Vorgabe wiederherstellen + Voreinstellung wiederherstellen @@ -1035,7 +1035,7 @@ Invalid URL! - Unbekannte URL. + Ungültige URL. @@ -1091,7 +1091,10 @@ Reason: %2 - Could not register documentation file%1Reason:%2 + Dokumentationsdatei %1 kann nicht registriert werden + +Grund: +%2 @@ -1105,7 +1108,10 @@ Reason: Reason: %2 - Could not unregister documentation file%1Reason:%2 + Registrierung der Dokumentationsdatei %1 kann nicht aufgehoben werden + +Grund: +%2 @@ -1152,7 +1158,7 @@ Reason: Copy &Link Location - &Link Adresse kopieren + &Link-Adresse kopieren diff --git a/translations/linguist_de.ts b/translations/linguist_de.ts index 5e9712c..48f1f2e 100644 --- a/translations/linguist_de.ts +++ b/translations/linguist_de.ts @@ -34,7 +34,7 @@ Searching, please wait... - Suche, bitte warten... + Suche, bitte warten ... @@ -67,7 +67,7 @@ Set translated entries to finished - Markiere Übersetzung als erledigt + Übersetzung als erledigt markieren @@ -77,7 +77,7 @@ Note that the modified entries will be reset to unfinished if 'Set translated entries to finished' above is unchecked. - Beachten Sie, dass die geänderten Einträge in den Status 'unerledigt' zurückgesetzt werden, wenn 'Markiere Übersetzung als erledigt' deaktiviert ist. + Beachten Sie, dass die geänderten Einträge in den Status 'unerledigt' zurückgesetzt werden, wenn 'Übersetzung als erledigt markieren' deaktiviert ist. @@ -215,17 +215,17 @@ Es wird mit einer einfachen Universalform gearbeitet. Accelerator possibly superfluous in translation. - Zusätzliche Kurztaste im Übersetzungstext. + Möglicherweise überflüssiger Kurzbefehl im Übersetzungstext. Accelerator possibly missing in translation. - Kurztaste fehlt im Übersetzungstext. + Kurzbefehl fehlt im Übersetzungstext. Translation does not end with the same punctuation as the source text. - Interpunktion am Ende des Übersetzungstextes unterscheidet sich von Interpunktion im Quelltext. + Interpunktion am Ende des Übersetzungstextes unterscheidet sich von Interpunktion des Ursprungstextes. @@ -235,7 +235,7 @@ Es wird mit einer einfachen Universalform gearbeitet. Translation does not refer to the same place markers as in the source text. - Platzhalter im Übersetzungstext und Quelltext unterscheiden sich. + Platzhalter im Übersetzungstext und Ursprungstext unterscheiden sich. @@ -276,7 +276,7 @@ Es wird mit einer einfachen Universalform gearbeitet. Source texts are searched when checked. - Wenn aktiviert, wird in dem Ursprungstexten gesucht. + Wenn aktiviert, wird in den Ursprungstexten gesucht. Source texts @@ -322,7 +322,7 @@ Es wird mit einer einfachen Universalform gearbeitet. &Source texts - &Quelltexte + &Ursprungstexte @@ -347,7 +347,7 @@ Es wird mit einer einfachen Universalform gearbeitet. Click here to find the next occurrence of the text you typed in. - Hier klicken für das nächste Vorkommen des Suchtextes. + Klicken Sie hier, um zum nächsten Vorkommen des Suchtextes zu springen. @@ -357,7 +357,7 @@ Es wird mit einer einfachen Universalform gearbeitet. Click here to close this window. - Klicken Sie hier um das Fenster zu schließen. + Klicken Sie hier, um das Fenster zu schließen. @@ -510,12 +510,12 @@ p, li { white-space: pre-wrap; } &Edit Phrase Book - Wörterbuch &Editieren + Wörterbuch &bearbeiten &Print Phrase Book - Wörterbuch &Drucken + Wörterbuch &drucken @@ -572,7 +572,7 @@ p, li { white-space: pre-wrap; } &Open... - Ö&ffnen... + Ö&ffnen ... @@ -613,7 +613,7 @@ p, li { white-space: pre-wrap; } Previous unfinished item. - Vorherige Unerledigte + Vorheriger unerledigter Eintrag. @@ -623,7 +623,7 @@ p, li { white-space: pre-wrap; } Next unfinished item. - Nächste Unerledigte + Nächster unerledigter Eintrag. @@ -663,7 +663,7 @@ p, li { white-space: pre-wrap; } Copy from source text - &Ursprungstext übernehmen + Ursprungstext übernehmen @@ -698,17 +698,17 @@ p, li { white-space: pre-wrap; } Toggle the validity check of place markers, i.e. whether %1, %2, ... are used consistently in the source text and translation text. If the check fails, a message is shown in the warnings window. - Die Prüfung der Platzhalter, das heißt, ob %1, %2 usw. in Quelltext und Übersetzung übereinstimmend verwendet werden, ein- bzw. ausschalten. Bei Fehlschlag wird eine Warnung im Hinweis-Fenster angezeigt. + Die Prüfung der Platzhalter, das heißt, ob %1, %2 usw. in Ursprungstext und Übersetzung übereinstimmend verwendet werden, ein- bzw. ausschalten. Bei Fehlschlag wird eine Warnung im Hinweis-Fenster angezeigt. Open Read-O&nly... - Schr&eibgeschützt öffnen... + Schr&eibgeschützt öffnen ... &Save All - &Alles speichern + &Alle speichern @@ -725,7 +725,7 @@ p, li { white-space: pre-wrap; } Save As... - Speichern unter... + Speichern unter ... @@ -745,7 +745,7 @@ p, li { white-space: pre-wrap; } &Print... - &Drucken... + &Drucken ... Print a list of all the phrases in the current Qt translation source file. @@ -853,7 +853,7 @@ p, li { white-space: pre-wrap; } Select &All - Alle &markieren + Alles &markieren @@ -868,12 +868,12 @@ p, li { white-space: pre-wrap; } &Find... - &Suchen... + &Suchen ... Search for some text in the translation source file. - Suche einen Text in der Übersetzungsdatei. + In der Übersetzungsdatei nach Text suchen. @@ -888,7 +888,7 @@ p, li { white-space: pre-wrap; } Continue the search where it was left. - Setze die Suche fort. + Die Suche fortsetzen. @@ -898,7 +898,7 @@ p, li { white-space: pre-wrap; } &Prev Unfinished - &Vorherige Unerledigte + &Vorheriger Unerledigter @@ -913,7 +913,7 @@ p, li { white-space: pre-wrap; } Ctrl+W - + Ctrl+W Moves to the previous unfinished item. @@ -927,7 +927,7 @@ p, li { white-space: pre-wrap; } &Next Unfinished - &Nächste Unerledigte + &Nächster Unerledigter Moves to the next unfinished item. @@ -940,7 +940,7 @@ p, li { white-space: pre-wrap; } P&rev - V&orherige + V&orheriger Moves to the previous item. @@ -954,7 +954,7 @@ p, li { white-space: pre-wrap; } Ne&xt - Nä&chste + Nä&chster Moves to the next item. @@ -967,7 +967,7 @@ p, li { white-space: pre-wrap; } &Done and Next - &Fertig und Nächste + &Fertig und Nächster Marks this item as done and moves to the next unfinished item. @@ -980,7 +980,7 @@ p, li { white-space: pre-wrap; } Copies the source text into the translation field. - Kopiere den Ursprungstext in das Übersetzungsfeld. + Kopiert den Ursprungstext in das Übersetzungsfeld. @@ -990,7 +990,7 @@ p, li { white-space: pre-wrap; } &Accelerators - &Kurztasten + &Kurzbefehle Toggle validity checks of accelerators. @@ -1013,7 +1013,7 @@ p, li { white-space: pre-wrap; } Toggle checking that phrase suggestions are used. - Aktiviere/Deaktiviere Überprüfung, ob Wörterbucheinträge benutzt wurden. + Überprüfung, ob Wörterbucheinträge benutzt werden, aktivieren/deaktivieren. @@ -1027,12 +1027,12 @@ p, li { white-space: pre-wrap; } &New Phrase Book... - &Neues Wörterbuch... + &Neues Wörterbuch ... Create a new phrase book. - Erzeuge ein neues Wörterbuch. + Ein neues Wörterbuch erzeugen. @@ -1042,12 +1042,12 @@ p, li { white-space: pre-wrap; } &Open Phrase Book... - &Wörterbuch Öffnen... + &Wörterbuch öffnen ... Open a phrase book to assist translation. - Öffne ein Wörterbuch als Unterstützung bei der Übersetzung. + Ein Wörterbuch zur Unterstützung bei der Übersetzung öffnen. @@ -1062,17 +1062,17 @@ p, li { white-space: pre-wrap; } Sort the items back in the same order as in the message file. - Sortiere die Einträge in der gleichen Reihenfolge wie in der ursprünglichen Übersetzungsdatei. + Die Einträge in der gleichen Reihenfolge wie in der ursprünglichen Übersetzungsdatei sortieren. &Display guesses - &Vorschläge + &Vorschläge anzeigen Set whether or not to display translation guesses. - Aktiviere/Deaktivere Darstellung von Übersetzungsvorschlägen. + Darstellung von Übersetzungsvorschlägen aktivieren/deaktivieren. @@ -1107,7 +1107,7 @@ p, li { white-space: pre-wrap; } Display information about the Qt toolkit by Trolltech. - Informationen über das Qt-Toolkit von Trolltech an. + Informationen über das Qt-Toolkit von Trolltech anzeigen. @@ -1132,18 +1132,18 @@ p, li { white-space: pre-wrap; } &Search And Translate... - Suchen und &Übersetzen... + Suchen und &übersetzen ... Replace the translation on all entries that matches the search source text. - Ersetze die Übersetzung von allen Einträgen, die dem Suchtext entsprechen. + Die Übersetzung aller Einträge ersetzen, die dem Suchtext entsprechen. &Batch Translation... - &Automatische Übersetzung... + &Automatische Übersetzung ... @@ -1160,7 +1160,7 @@ p, li { white-space: pre-wrap; } Create a Qt message file suitable for released applications from the current message file. The filename will automatically be determined from the name of the .ts file. - Eine Qt-Nachrichtendatei aus der aktuellen Übersetzungsdatei erzeugen. Der Dateiname wird automatisch aus dem Namen der .ts-Datei abgeleitet. + Eine Qt-Nachrichtendatei aus der aktuellen Übersetzungsdatei erzeugen. Der Dateiname wird automatisch aus dem Namen der TS-Datei abgeleitet. @@ -1224,7 +1224,7 @@ p, li { white-space: pre-wrap; } Loading... - Lade... + Lade ... @@ -1298,7 +1298,7 @@ Alle Dateien (*) Printing... - Drucke... + Drucke ... @@ -1324,7 +1324,7 @@ Alle Dateien (*) Printing... (page %1) - Drucke... (Seite %1) + Drucke ... (Seite %1) @@ -1355,7 +1355,7 @@ Alle Dateien (*) Qt Linguist - + Qt Linguist @@ -1393,7 +1393,7 @@ Alle Dateien (*) No more occurrences of '%1'. Start over? - Keine weiteren Fundstellen von '%1'. Von vorne beginnen? + Keine weiteren Vorkommen von '%1'. Von vorne beginnen? @@ -1440,7 +1440,7 @@ Alle Dateien (*) No appropriate phrasebook found. - Es wurde kein geeignetes Wörterbuch gefunden. + Es kann kein geeignetes Wörterbuch gefunden werden. @@ -1484,12 +1484,12 @@ Alle Dateien (*) Qt Linguist[*] - + Qt Linguist[*] %1[*] - Qt Linguist - + %1[*] - Qt Linguist @@ -1510,27 +1510,27 @@ Alle Dateien (*) Ctrl+M - + Ctrl+M Display the manual for %1. - Zeige Handbuch für %1 an. + Handbuch zu %1 anzeigen. Display information about %1. - Zeige Informationen über %1 an. + Informationen über %1 anzeigen. &Save '%1' - '%1' &Speichern + '%1' &speichern Save '%1' &As... - Speichere '%1' &unter... + '%1' speichern &unter ... @@ -1540,12 +1540,12 @@ Alle Dateien (*) Release '%1' As... - Gebe '%1'frei unter ... + '%1' freigeben unter ... &Close '%1' - '%1' &Schließen + '%1' &schließen @@ -1572,22 +1572,22 @@ Alle Dateien (*) Translation File &Settings for '%1'... - Einstellungen der Übersetzungs&datei für '%1'... + Einstellungen der Übersetzungs&datei für '%1' ... &Batch Translation of '%1'... - &Automatische Übersetzung von '%1'... + &Automatische Übersetzung von '%1' ... Search And &Translate in '%1'... - Suchen und &Übersetzen in '%1'... + Suchen und &übersetzen in '%1' ... Search And &Translate... - Suchen und &Übersetzen... + Suchen und &übersetzen ... @@ -1622,27 +1622,27 @@ Alle Dateien (*) Cannot read from phrase book '%1'. - Kann Wörterbuch '%1' nicht lesen. + Wörterbuch '%1' kann nicht gelesen werden. Close this phrase book. - Schließe dieses Wörterbuch. + Dieses Wörterbuch schließen. Enables you to add, modify, or delete entries in this phrase book. - Erlaubt das Hinzufügen, Ändern und Entfernen von Einträgen aus dem Wörterbuch. + Erlaubt das Hinzufügen, Ändern und Entfernen von Wörterbuch-Einträgen. Print the entries in this phrase book. - Drucke die Einträge des Wörterbuchs. + Die Einträge des Wörterbuchs drucken. Cannot create phrase book '%1'. - Kann Wörterbuch '%1' nicht erzeugen. + Wörterbuch '%1' kann nicht erzeugt werden. @@ -1657,7 +1657,7 @@ Alle Dateien (*) Open/Refresh Form &Preview - Öffne/Aktualisiere die &Vorschau + Die &Vorschau öffnen/&aktualisieren @@ -1673,7 +1673,7 @@ Alle Dateien (*) Translation File &Settings... - E&instellungen... + E&instellungen ... Other &Languages... @@ -1686,7 +1686,7 @@ Alle Dateien (*) &Add to Phrase Book - &Füge zum Wörterbuch hinzu + Zum Wörterbuch &hinzufügen @@ -1696,12 +1696,12 @@ Alle Dateien (*) Ctrl+J - + Ctrl+J Ctrl+Shift+J - + Ctrl+Shift+J @@ -1893,7 +1893,7 @@ Zeile: %2 %1[*] - Qt Linguist - + %1[*] - Qt Linguist @@ -1903,12 +1903,12 @@ Zeile: %2 Cannot save phrase book '%1'. - Kann Wörterbuch '%1' nicht speichern. + Wörterbuch '%1' kann nicht gespeichert werden. Edit Phrase Book - Ändere Wörterbuch + Wörterbuch bearbeiten This window allows you to add, modify, or delete phrases in a phrase book. @@ -1917,7 +1917,7 @@ Zeile: %2 This window allows you to add, modify, or delete entries in a phrase book. - Dieses Fenster erlaubt das Hinzufügen, Ändern und Entfernen von Einträgen aus dem Wörterbuch. + Dieses Fenster erlaubt das Hinzufügen, Ändern und Entfernen von Wörterbuch-Einträgen. @@ -1927,7 +1927,7 @@ Zeile: %2 This is the phrase in the target language corresponding to the source phrase. - Dies ist der Text, die in der Zielsprache dem Ursprungstext entspricht. + Dies ist der Text, der in der Zielsprache dem Ursprungstext entspricht. @@ -1952,7 +1952,7 @@ Zeile: %2 Click here to add the phrase to the phrase book. - Füge eine neuen Eintrag ins Wörterbuch hinzu. + Einen neuen Eintrag ins Wörterbuch einfügen. @@ -1962,17 +1962,17 @@ Zeile: %2 Click here to remove the entry from the phrase book. - Entferne den Eintrag aus dem Wörterbuch. + Den Eintrag aus dem Wörterbuch entfernen. &Remove Entry - &Entferne Eintrag + &Eintrag entfernen Settin&gs... - &Einstellungen... + &Einstellungen ... &New Phrase @@ -1989,7 +1989,7 @@ Zeile: %2 Click here to save the changes made. - Speichere Änderungen. + Änderungen speichern. @@ -1999,7 +1999,7 @@ Zeile: %2 Click here to close this window. - Klicken Sie hier um das Fenster zu schließen. + Klicken Sie hier, um das Fenster zu schließen. @@ -2053,7 +2053,7 @@ Zeile: %2 Compiled Qt translations - + Kompilierte Qt-Übersetzungen @@ -2079,7 +2079,7 @@ Zeile: %2 C++ source files - C++-Quelltextdateien' + C++-Quelltextdateien @@ -2089,7 +2089,7 @@ Zeile: %2 GNU Gettext localization files - GNU-Gettext Übersetzungsdateien + GNU-Gettext-Übersetzungsdateien @@ -2109,7 +2109,7 @@ Zeile: %2 Qt translation sources (latest format) - Qt Übersetzungsdateien (aktuelles Format) + Qt-Übersetzungsdateien (aktuelles Format) @@ -2213,7 +2213,7 @@ Zeile: %2 Words: - Worte: + Wörter: @@ -2654,7 +2654,7 @@ Alle Dateien (*) Search options - Suchoptionen + Sucheinstellungen @@ -2669,12 +2669,12 @@ Alle Dateien (*) Mark new translation as &finished - Markiere neue Übersetzung als &erledigt + Neue Übersetzung als &erledigt markieren Click here to find the next occurrence of the text you typed in. - Hier klicken für das nächste Vorkommen des Suchtextes. + Klicken Sie hier, um zum nächsten Vorkommen des Suchtextes zu springen. @@ -2689,12 +2689,12 @@ Alle Dateien (*) Translate All - Alle Übersetzen + Alle übersetzen Click here to close this window. - Klicken Sie hier um das Fenster zu schließen. + Klicken Sie hier, um das Fenster zu schließen. -- cgit v0.12 From 33604fb02fa463f36fa78e515bb42a34a746f0f2 Mon Sep 17 00:00:00 2001 From: Frederik Schwarzer Date: Mon, 6 Jul 2009 13:47:01 +0200 Subject: general wording change for some file type names - .ts file -> TS file - .qm file -> QM file - .ui file -> UI file + a handfull of typos I stumbled over Merge-request: 802 Reviewed-by: Oswald Buddenhagen --- doc/src/designer-manual.qdoc | 40 +++++++-------- doc/src/dnd.qdoc | 2 +- doc/src/examples/arrowpad.qdoc | 8 +-- doc/src/examples/calculatorform.qdoc | 6 +-- doc/src/examples/helloscript.qdoc | 12 ++--- doc/src/examples/hellotr.qdoc | 26 +++++----- doc/src/examples/multipleinheritance.qdoc | 2 +- doc/src/examples/qtscripttetrix.qdoc | 2 +- doc/src/examples/svggenerator.qdoc | 4 +- doc/src/examples/textfinder.qdoc | 4 +- doc/src/examples/worldtimeclockbuilder.qdoc | 2 +- doc/src/i18n.qdoc | 18 +++---- doc/src/linguist-manual.qdoc | 59 +++++++++++----------- doc/src/porting4-canvas.qdoc | 2 +- doc/src/porting4-designer.qdoc | 40 +++++++-------- doc/src/porting4-overview.qdoc | 4 +- doc/src/porting4.qdoc | 12 ++--- doc/src/qmake-manual.qdoc | 18 +++---- doc/src/qmsdev.qdoc | 2 +- doc/src/qt3to4.qdoc | 2 +- doc/src/qt4-intro.qdoc | 2 +- doc/src/qtdesigner.qdoc | 8 +-- doc/src/qthelp.qdoc | 2 +- doc/src/qtscript.qdoc | 24 ++++----- doc/src/qtuiloader.qdoc | 2 +- doc/src/signalsandslots.qdoc | 2 +- doc/src/snippets/code/doc_src_linguist-manual.qdoc | 6 +-- doc/src/templates.qdoc | 2 +- examples/uitools/textfinder/forms/input.txt | 2 +- mkspecs/features/uic.prf | 2 +- src/corelib/kernel/qobject.cpp | 2 +- src/corelib/kernel/qtranslator.cpp | 2 +- src/tools/uic/uic.cpp | 4 +- src/tools/uic3/main.cpp | 6 +-- src/tools/uic3/uic.cpp | 4 +- src/xmlpatterns/data/qresourceloader_p.h | 2 +- .../testdata/good/mergeui/project.ts.before | 2 +- .../good/mergeui_obsolete/project.ts.result | 2 +- .../testdata/good/mergeui_obsolete/project.ui | 2 +- .../testdata/good/textsimilarity/project.ts.result | 2 +- .../testdata/good/textsimilarity/project.ui | 2 +- tools/designer/data/generate_shared.xsl | 4 +- .../components/formeditor/qdesigner_resource.cpp | 6 +-- tools/designer/src/designer/mainwindow.cpp | 2 +- .../designer/src/designer/qdesigner_workbench.cpp | 2 +- tools/designer/src/lib/sdk/abstractformwindow.cpp | 14 ++--- tools/designer/src/lib/sdk/script.cpp | 6 +-- .../designer/src/lib/uilib/abstractformbuilder.cpp | 14 ++--- tools/designer/src/lib/uilib/formbuilder.cpp | 4 +- tools/designer/src/uitools/quiloader.cpp | 8 +-- tools/linguist/lconvert/main.cpp | 8 +-- tools/linguist/linguist/mainwindow.ui | 2 +- tools/linguist/lrelease/lrelease.1 | 12 ++--- tools/linguist/lrelease/main.cpp | 10 ++-- tools/linguist/lupdate/lupdate.1 | 14 ++--- tools/linguist/lupdate/main.cpp | 6 +-- tools/linguist/shared/qm.cpp | 2 +- tools/linguist/shared/ts.dtd | 8 +-- tools/qtconfig/paletteeditoradvanced.cpp | 2 +- 59 files changed, 235 insertions(+), 236 deletions(-) diff --git a/doc/src/designer-manual.qdoc b/doc/src/designer-manual.qdoc index 67114b9..25e7455 100644 --- a/doc/src/designer-manual.qdoc +++ b/doc/src/designer-manual.qdoc @@ -86,7 +86,7 @@ \o \l{Creating Main Windows in Qt Designer} \o \l{Editing Resources with Qt Designer} \o \l{Using Stylesheets with Qt Designer} - \o \l{Using a Designer .ui File in Your Application} + \o \l{Using a Designer UI File in Your Application} \endlist For advanced usage of \QD, you can refer to these links: @@ -158,7 +158,7 @@ has been introduced to aid translators in the case of two source texts being the same but used for different purposes. For example, a dialog could have two \gui{Add} buttons for two different - reasons. \note To maintain compatibility, comments in \c{.ui} files + reasons. \note To maintain compatibility, comments in UI files created prior to Qt 4.5 will be listed in the \gui{Disambiguation} field. \endlist @@ -620,7 +620,7 @@ \key{Ctrl+O}. At any point, you can save your form by selecting the \gui{Save From As...} - option from the \gui File menu. The \c{.ui} files saved by \QD contain + option from the \gui File menu. The UI files saved by \QD contain information about the objects used, and any details of signal and slot connections between them. @@ -953,7 +953,7 @@ \image designer-form-layout.png - The \c{.ui} file above results in the previews shown below. + The UI file above results in the previews shown below. \table \header @@ -1226,7 +1226,7 @@ The whole connection can be selected by clicking on any of its path segments. Once selected, a connection can be deleted with the - \key Delete key, ensuring that it will not be set up in the \c{.ui} + \key Delete key, ensuring that it will not be set up in the UI file. \endtable */ @@ -1795,7 +1795,7 @@ pixmap property in the property editor. \page designer-stylesheet.html \contentspage {Qt Designer Manual}{Contents} \previouspage Editing Resources with Qt Designer - \nextpage Using a Designer .ui File in Your Application + \nextpage Using a Designer UI File in Your Application \title Using Stylesheets with Qt Designer @@ -1824,7 +1824,7 @@ pixmap property in the property editor. \contentspage {Qt Designer Manual}{Contents} \nextpage Using Custom Widgets with Qt Designer - \title Using a Designer .ui File in Your Application + \title Using a Designer UI File in Your Application With Qt's integrated build tools, \l{qmake Manual}{qmake} and \l uic, the code for user interface components created with \QD is automatically @@ -1855,11 +1855,11 @@ pixmap property in the property editor. \section2 The Direct Approach - To demonstrate how to use user interface (\c{.ui}) files straight from + To demonstrate how to use user interface (UI) files straight from \QD, we create a simple Calculator Form application. This is based on the original \l{Calculator Form Example}{Calculator Form} example. - The application consists of one source file, \c main.cpp and a \c{.ui} + The application consists of one source file, \c main.cpp and a UI file. The \c{calculatorform.ui} file designed with \QD is shown below: @@ -1882,7 +1882,7 @@ pixmap property in the property editor. \snippet doc/src/snippets/uitools/calculatorform/main.cpp 0 This include is an additional check to ensure that we do not generate code - for \c .ui files that are not used. + for UI files that are not used. The \c main function creates the calculator widget by constructing a standard QWidget that we use to host the user interface described by the @@ -2003,7 +2003,7 @@ pixmap property in the property editor. \section2 The UiTools Approach - A resource file containing a \c{.ui} file is required to process forms at + A resource file containing a UI file is required to process forms at run time. Also, the application needs to be configured to use the QtUiTools module. This is done by including the following declaration in a \c qmake project file, ensuring that the application is compiled and linked @@ -2034,7 +2034,7 @@ pixmap property in the property editor. \snippet examples/uitools/textfinder/textfinder.cpp 1 Processing forms at run-time gives the developer the freedom to change a - program's user interface, just by changing the \c{.ui} file. This is useful + program's user interface, just by changing the UI file. This is useful when customizing programs to suit various user needs, such as extra large icons or a different colour scheme for accessibility support. @@ -2130,12 +2130,12 @@ pixmap property in the property editor. \image designer-form-settings.png - When saving a form in \QD, it is stored as an \c .ui file. Several form + When saving a form in \QD, it is stored as a UI file. Several form settings, for example the grid settings or the margin and spacing for the default layout, are stored along with the form's components. These settings are used when the \l uic generates the form's C++ code. For more information on how to use forms in your application, see the - \l{Using a Designer .ui File in Your Application} section. + \l{Using a Designer UI File in Your Application} section. \section1 Modifying the Form Settings @@ -2168,7 +2168,7 @@ pixmap property in the property editor. You can also specify the form's \gui{Include Hints}; i.e., provide a list of the header files which will then be included in the form window's - associated \c .ui file. Header files may be local, i.e., relative to the + associated UI file. Header files may be local, i.e., relative to the project's directory, \c "mywidget.h", or global, i.e. part of Qt or the compilers standard libraries: \c . @@ -2331,7 +2331,7 @@ pixmap property in the property editor. \row \o \c includeFile() \o The header file that must be included in applications that use - this widget. This information is stored in .ui files and will + this widget. This information is stored in UI files and will be used by \c uic to create a suitable \c{#includes} statement in the code it generates for the form containing the custom widget. @@ -2379,12 +2379,12 @@ pixmap property in the property editor. \section2 Notes on the \c{domXml()} Function - The \c{domXml()} function returns a \c{.ui} file snippet that is used by + The \c{domXml()} function returns a UI file snippet that is used by \QD's widget factory to create a custom widget and its applicable properties. - Since Qt 4.4, \QD's widget box allows for a complete \c{.ui} file to - describe \bold one custom widget. The \c{.ui} file can be loaded using the + Since Qt 4.4, \QD's widget box allows for a complete UI file to + describe \bold one custom widget. The UI file can be loaded using the \c{} tag. Specifying the tag allows for adding the element that contains additional information for custom widgets. The \c{} tag is sufficient if no additional information is required @@ -2800,7 +2800,7 @@ pixmap property in the property editor. \title Qt Designer's UI File Format - The \c .ui file format used by \QD is described by the + The \c UI file format used by \QD is described by the \l{http://www.w3.org/XML/Schema}{XML schema} presented below, which we include for your convenience. Be aware that the format may change in future Qt releases. diff --git a/doc/src/dnd.qdoc b/doc/src/dnd.qdoc index 8d3d79d..b5039f6 100644 --- a/doc/src/dnd.qdoc +++ b/doc/src/dnd.qdoc @@ -435,7 +435,7 @@ \title Porting to Qt 4 - Drag and Drop \contentspage {Porting Guides}{Contents} \previouspage Porting to Qt 4 - Virtual Functions - \nextpage Porting .ui Files to Qt 4 + \nextpage Porting UI Files to Qt 4 \ingroup porting \brief An overview of the porting process for applications that use drag and drop. diff --git a/doc/src/examples/arrowpad.qdoc b/doc/src/examples/arrowpad.qdoc index 9e9268c..fa19fbb 100644 --- a/doc/src/examples/arrowpad.qdoc +++ b/doc/src/examples/arrowpad.qdoc @@ -140,10 +140,10 @@ QLocale::system() can be influenced by setting the \c LANG environment variable, for example. Notice that the use of a naming convention that incorporates the locale for \c .qm message files, - (and \c .ts files), makes it easy to implement choosing the + (and TS files), makes it easy to implement choosing the translation file according to locale. - If there is no \c .qm message file for the locale chosen the original + If there is no QM message file for the locale chosen the original source text will be used and no error raised. \section1 Translating to French and Dutch @@ -194,9 +194,9 @@ \endlist We have to convert the \c tt1_fr.ts and \c tt1_nl.ts translation source - files into \c .qm files. We could use \e {Qt Linguist} as we've done + files into QM files. We could use \e {Qt Linguist} as we've done before; however using the command line tool \c lrelease ensures that - \e all the \c .qm files for the application are created without us + \e all the QM files for the application are created without us having to remember to load and \gui File|Release each one individually from \e {Qt Linguist}. diff --git a/doc/src/examples/calculatorform.qdoc b/doc/src/examples/calculatorform.qdoc index 7cbf2ac..90eef3b 100644 --- a/doc/src/examples/calculatorform.qdoc +++ b/doc/src/examples/calculatorform.qdoc @@ -45,8 +45,8 @@ The Calculator Form Example shows how to use a form created with \QD in an application by using the user interface information from - a QWidget subclass. We use \l{Using a Designer .ui File in Your Application} - {uic's auto-connection} feature to automatically connect signals + a QWidget subclass. We use \l{Using a Designer UI File in Your Application} + {uic's auto-connection} feature to automatically connect signals from widgets on the form to slots in our code. \image calculatorform-example.png Screenshot of the Calculator Form example @@ -59,7 +59,7 @@ \section1 Preparation The user interface for this example is designed completely using \QD. The - result is a .ui file describing the form, the widgets used, any signal-slot + result is a UI file describing the form, the widgets used, any signal-slot connections between them, and other standard user interface properties. To ensure that the example can use this file, we need to include a \c FORMS diff --git a/doc/src/examples/helloscript.qdoc b/doc/src/examples/helloscript.qdoc index a18e4ad..1b0f43c 100644 --- a/doc/src/examples/helloscript.qdoc +++ b/doc/src/examples/helloscript.qdoc @@ -121,7 +121,7 @@ window). Don't forget the exclamation mark! Click the \gui Done checkbox and choose \gui File|Save from the - menu bar. The \c .ts file will no longer contain + menu bar. The TS file will no longer contain \snippet doc/src/snippets/code/doc_src_examples_hellotr.qdoc 3 @@ -129,11 +129,11 @@ \snippet doc/src/snippets/code/doc_src_examples_hellotr.qdoc 4 - To see the application running in Latin, we have to generate a \c .qm - file from the \c .ts file. Generating a \c .qm file can be achieved - either from within \e {Qt Linguist} (for a single \c .ts file), or - by using the command line program \c lrelease which will produce one \c - .qm file for each of the \c .ts files listed in the project file. + To see the application running in Latin, we have to generate a QM + file from the TS file. Generating a QM file can be achieved + either from within \e {Qt Linguist} (for a single TS file), or + by using the command line program \c lrelease which will produce one + QM file for each of the TS files listed in the project file. Generate \c hellotr_la.qm from \c hellotr_la.ts by choosing \gui File|Release from \e {Qt Linguist}'s menu bar and pressing \gui Save in the file save dialog that pops up. Now run the \c helloscript diff --git a/doc/src/examples/hellotr.qdoc b/doc/src/examples/hellotr.qdoc index bb38737..18e0715 100644 --- a/doc/src/examples/hellotr.qdoc +++ b/doc/src/examples/hellotr.qdoc @@ -108,12 +108,12 @@ Note that the file extension is \c .ts, not \c .qm. The \c .ts translation source format is designed for use during the application's development. Programmers or release managers run - the \c lupdate program to generate and update \c .ts files with + the \c lupdate program to generate and update TS files with the source text that is extracted from the source code. - Translators read and update the \c .ts files using \e {Qt + Translators read and update the TS files using \e {Qt Linguist} adding and editing their translations. - The \c .ts format is human-readable XML that can be emailed directly + The TS format is human-readable XML that can be emailed directly and is easy to put under version control. If you edit this file manually, be aware that the default encoding for XML is UTF-8, not Latin1 (ISO 8859-1). One way to type in a Latin1 character such as @@ -121,8 +121,8 @@ "\ø". This will work for any Unicode 4.0 character. Once the translations are complete the \c lrelease program is used to - convert the \c .ts files into the \c .qm Qt message file format. The - \c .qm format is a compact binary format designed to deliver very + convert the TS files into the QM Qt message file format. The + QM format is a compact binary format designed to deliver very fast lookup performance. Both \c lupdate and \c lrelease read all the project's source and header files (as specified in the HEADERS and SOURCES lines of the project file) and extract the strings that @@ -131,7 +131,7 @@ \c lupdate is used to create and update the message files (\c hellotr_la.ts in this case) to keep them in sync with the source code. It is safe to run \c lupdate at any time, as \c lupdate does not remove any - information. For example, you can put it in the makefile, so the \c .ts + information. For example, you can put it in the makefile, so the TS files are updated whenever the source changes. Try running \c lupdate right now, like this: @@ -151,7 +151,7 @@ We will use \e {Qt Linguist} to provide the translation, although you can use any XML or plain text editor to enter a translation into a - \c .ts file. + TS file. To start \e {Qt Linguist}, type @@ -163,7 +163,7 @@ window). Don't forget the exclamation mark! Click the \gui Done checkbox and choose \gui File|Save from the - menu bar. The \c .ts file will no longer contain + menu bar. The TS file will no longer contain \snippet doc/src/snippets/code/doc_src_examples_hellotr.qdoc 3 @@ -173,11 +173,11 @@ \section1 Running the Application in Latin - To see the application running in Latin, we have to generate a \c .qm - file from the \c .ts file. Generating a \c .qm file can be achieved - either from within \e {Qt Linguist} (for a single \c .ts file), or - by using the command line program \c lrelease which will produce one \c - .qm file for each of the \c .ts files listed in the project file. + To see the application running in Latin, we have to generate a QM + file from the TS file. Generating a QM file can be achieved + either from within \e {Qt Linguist} (for a single TS file), or + by using the command line program \c lrelease which will produce one + QM file for each of the TS files listed in the project file. Generate \c hellotr_la.qm from \c hellotr_la.ts by choosing \gui File|Release from \e {Qt Linguist}'s menu bar and pressing \gui Save in the file save dialog that pops up. Now run the \c hellotr diff --git a/doc/src/examples/multipleinheritance.qdoc b/doc/src/examples/multipleinheritance.qdoc index 5a77275..1622fb0 100644 --- a/doc/src/examples/multipleinheritance.qdoc +++ b/doc/src/examples/multipleinheritance.qdoc @@ -103,6 +103,6 @@ There are various approaches to include forms into applications. The Multiple Inheritance approach is just one of them. See - \l{Using a Designer .ui File in Your Application} for more information on + \l{Using a Designer UI File in Your Application} for more information on the other approaches available. */ diff --git a/doc/src/examples/qtscripttetrix.qdoc b/doc/src/examples/qtscripttetrix.qdoc index c94697a..fb2d537 100644 --- a/doc/src/examples/qtscripttetrix.qdoc +++ b/doc/src/examples/qtscripttetrix.qdoc @@ -57,7 +57,7 @@ \section1 Setting up the GUI - The graphical user interface is defined in a \c{.ui} file, creating + The graphical user interface is defined in a UI file, created using Qt Designer, and is set up in the example's C++ \c{main.cpp} file. \snippet examples/script/qstetrix/main.cpp 0 diff --git a/doc/src/examples/svggenerator.qdoc b/doc/src/examples/svggenerator.qdoc index 09fe6e1..dd7459a 100644 --- a/doc/src/examples/svggenerator.qdoc +++ b/doc/src/examples/svggenerator.qdoc @@ -55,8 +55,8 @@ The example consists of two classes: \c Window and \c DisplayWidget. The \c Window class contains the application logic and constructs the user - interface from a Qt Designer \c{.ui} file as described in the - \l{Using a Designer .ui File in Your Application#The Multiple Inheritance Approach}{Qt Designer manual}. + interface from a Qt Designer UI file as described in the + \l{Using a Designer UI File in Your Application#The Multiple Inheritance Approach}{Qt Designer manual}. It also contains the code to write an SVG file. The \c DisplayWidget class performs all the work of painting a picture on diff --git a/doc/src/examples/textfinder.qdoc b/doc/src/examples/textfinder.qdoc index adbbd0d..acfbd0f 100644 --- a/doc/src/examples/textfinder.qdoc +++ b/doc/src/examples/textfinder.qdoc @@ -45,7 +45,7 @@ The Text Finder example demonstrates how to dynamically process forms using the QtUiTools module. Dynamic form processing enables a form to - be processed at run-time only by changing the .ui file for the project. + be processed at run-time only by changing the UI file for the project. The program allows the user to look up a particular word within the contents of a text file. This text file is included in the project's resource and is loaded into the display at startup. @@ -95,7 +95,7 @@ \snippet examples/uitools/textfinder/textfinder.h 0 The slot \c{on_find_Button_clicked()} is a slot named according to the - \l{Using a Designer .ui File in Your Application#Automatic Connections} + \l{Using a Designer UI File in Your Application#Automatic Connections} {Automatic Connection} naming convention required by \c uic. diff --git a/doc/src/examples/worldtimeclockbuilder.qdoc b/doc/src/examples/worldtimeclockbuilder.qdoc index 55246e9..f38062a 100644 --- a/doc/src/examples/worldtimeclockbuilder.qdoc +++ b/doc/src/examples/worldtimeclockbuilder.qdoc @@ -66,7 +66,7 @@ generate a dependency on the \c libQtUiTools library containing the QtUiTools classes. - Note that we do not inform \c qmake about any .ui files, and so none will + Note that we do not inform \c qmake about any UI files, and so none will be processed and built into the application. The resource file contains an entry for the particular form that we wish to use: diff --git a/doc/src/i18n.qdoc b/doc/src/i18n.qdoc index 4109b62..5964926 100644 --- a/doc/src/i18n.qdoc +++ b/doc/src/i18n.qdoc @@ -266,19 +266,19 @@ \o Run \c lupdate to extract translatable text from the C++ source code of the Qt application, resulting in a message file - for translators (a \c .ts file). The utility recognizes the tr() + for translators (a TS file). The utility recognizes the tr() construct and the \c{QT_TR*_NOOP()} macros described above and - produces \c .ts files (usually one per language). + produces TS files (usually one per language). - \o Provide translations for the source texts in the \c .ts file, using - \e{Qt Linguist}. Since \c .ts files are in XML format, you can also + \o Provide translations for the source texts in the TS file, using + \e{Qt Linguist}. Since TS files are in XML format, you can also edit them by hand. - \o Run \c lrelease to obtain a light-weight message file (a \c .qm - file) from the \c .ts file, suitable only for end use. Think of the \c - .ts files as "source files", and \c .qm files as "object files". The - translator edits the \c .ts files, but the users of your application - only need the \c .qm files. Both kinds of files are platform and + \o Run \c lrelease to obtain a light-weight message file (a QM + file) from the TS file, suitable only for end use. Think of the TS + files as "source files", and QM files as "object files". The + translator edits the TS files, but the users of your application + only need the QM files. Both kinds of files are platform and locale independent. \endlist diff --git a/doc/src/linguist-manual.qdoc b/doc/src/linguist-manual.qdoc index ee59fdc..fd062bb 100644 --- a/doc/src/linguist-manual.qdoc +++ b/doc/src/linguist-manual.qdoc @@ -247,10 +247,10 @@ subsequent \l lupdate runs would probably take place during the final beta phase. - The \c .ts file format is a simple human-readable XML format that + The TS file format is a simple human-readable XML format that can be used with version control systems if required. \c lupdate can also process Localization Interchange File Format (XLIFF) - format files; file in this format typically have file names that + format files; files in this format typically have file names that end with the \c .xlf suffix. Pass the \c -help option to \c lupdate to obtain the list of @@ -266,19 +266,19 @@ Usage: \c {lrelease myproject.pro} - \l lrelease is a command line tool that produces \c .qm files out - of \c .ts files. The \c .qm file format is a compact binary format + \l lrelease is a command line tool that produces QM files out + of TS files. The QM file format is a compact binary format that is used by the localized application. It provides extremely - fast lookups for translations. The \c .ts files \l lrelease + fast lookups for translations. The TS files \l lrelease processes can be specified at the command line, or given indirectly by a Qt \c .pro project file. This tool is run whenever a release of the application is to be made, from initial test version through to final release - version. If the \c .qm files are not created, e.g. because an + version. If the QM files are not created, e.g. because an alpha release is required before any translation has been undertaken, the application will run perfectly well using the text - the programmers placed in the source files. Once the \c .qm files + the programmers placed in the source files. Once the QM files are available the application will detect them and use them automatically. @@ -293,7 +293,7 @@ \section1 Missing Translations - Both \l lupdate and \l lrelease may be used with \c .ts + Both \l lupdate and \l lrelease may be used with TS translation source files which are incomplete. Missing translations will be replaced with the native language phrases at runtime. @@ -317,8 +317,8 @@ from the taskbar menu, or by double clicking the desktop icon, or by entering the command \c {linguist} at the command line. Once \QL has started, choose \menu{File|Open} from the \l{menubar} - {menu bar} and select a translation source (\c{.ts} file) to - load. If you don't have a \c{.ts} file, see the \l {Qt Linguist + {menu bar} and select a translation source (TS file) to + load. If you do not have a TS file, see the \l {Qt Linguist Manual: Release Manager} {release manager manual} to learn how to generate one. @@ -928,12 +928,12 @@ \image linguist-previewtool.png - Forms created by \e{Qt Designer} are stored in special \c .ui files. - \QL can make use of these \c .ui files to show the translations - done so far on the form itself. This of course requires access to the \c .ui + Forms created by \e{Qt Designer} are stored in special UI files. + \QL can make use of these UI files to show the translations + done so far on the form itself. This of course requires access to the UI files during the translation process. Activate \menu{Tools|Open/Refresh Form Preview} to open the window shown above. - The list of \c .ui files \QL has detected are displayed in the Forms + The list of UI files \QL has detected are displayed in the Forms List on the left hand. If the path to the files has changed, you can load the files manually via \menu{File|Open Form...}. Double-click on an entry in the Forms List to display the Form File. Select \e{} from @@ -947,15 +947,15 @@ \QL makes use of four kinds of files: \list - \o \c .ts \e {translation source files} \BR are human-readable XML + \o TS \e {translation source files} \BR are human-readable XML files containing source phrases and their translations. These files are usually created and updated by \l lupdate and are specific to an application. \o \c .xlf \e {XLIFF files} \BR are human-readable XML files that adhere to the international XML Localization Interchange File Format. \QL can be used to edit XLIFF files generated by other programs. For standard - Qt projects, however, only the \c .ts file format is used. - \o \c .qm \e {Qt message files} \BR are binary files that contain + Qt projects, however, only the TS file format is used. + \o QM \e {Qt message files} \BR are binary files that contain translations used by an application at runtime. These files are generated by \l lrelease, but can also be generated by \QL. \o \c .qph \e {Qt phrase book files} \BR are human-readable XML @@ -974,18 +974,18 @@ \list \o \gui {Open... Ctrl+O} \BR pops up an open file dialog from which a translation source \c .ts or \c .xlf file can be chosen. - \o \gui {Recently opened files} \BR shows the \c .ts files that + \o \gui {Recently opened files} \BR shows the TS files that have been opened recently, click one to open it. \o \gui {Save Ctrl+S} \BR saves the current translation source file. \o \gui {Save As...} \BR pops up a save as file dialog so that the current translation source file may be saved with a different name, format and/or put in a different location. - \o \gui {Release} \BR create a Qt message \c .qm file with the same base + \o \gui {Release} \BR create a Qt message QM file with the same base name as the current translation source file. The release manager's command line tool \l lrelease performs the same function on \e all of an application's translation source files. \o \gui {Release As...} \BR pops up a save as file dialog. The - filename entered will be a Qt message \c .qm file of the translation + filename entered will be a Qt message QM file of the translation based on the current translation source file. The release manager's command line tool \l lrelease performs the same function on \e all of an application's translation source files. @@ -1136,16 +1136,15 @@ \list \o \inlineimage linguist-fileopen.png \BR - Pops up the open file dialog to open a new translation source \c .ts - file. + Pops up the open file dialog to open a new translation source TS file. \o \inlineimage linguist-filesave.png \BR - Saves the current translation source \c .ts file. + Saves the current translation source TS file. \o \inlineimage linguist-fileprint.png \BR - Prints the current translation source \c .ts file. + Prints the current translation source TS file. \o \inlineimage linguist-phrasebookopen.png \BR @@ -1263,10 +1262,10 @@ Translation files are created as follows: \list 1 - \o Run \l lupdate initially to generate the first set of \c .ts + \o Run \l lupdate initially to generate the first set of TS translation source files with all the user-visible text but no translations. - \o The \c .ts files are given to the translator who adds translations + \o The TS files are given to the translator who adds translations using \QL. \QL takes care of any changed or deleted source text. \o Run \l lupdate to incorporate any new text added to the @@ -1274,7 +1273,7 @@ application with the translations; it does not destroy any data. \o Steps 2 and 3 are repeated as often as necessary. \o When a release of the application is needed \l lrelease is run to - read the \c .ts files and produce the \c .qm files used by the + read the TS files and produce the QM files used by the application at runtime. \endlist @@ -1319,7 +1318,7 @@ In production applications a more flexible approach, for example, loading translations according to locale, might be more appropriate. If - the \c .ts files are all named according to a convention such as + the TS files are all named according to a convention such as \e appname_locale, e.g. \c tt2_fr, \c tt2_de etc, then the code above will load the current locale's translation at runtime. @@ -1413,7 +1412,7 @@ To handle plural forms in the native language, you need to load a translation file for this language, too. \l lupdate has the \c -pluralonly command line option, which allows the creation of - \c .ts files containing only entries with plural forms. + TS files containing only entries with plural forms. See the \l{http://doc.trolltech.com/qq/}{Qt Quarterly} Article \l{http://doc.trolltech.com/qq/qq19-plurals.html}{Plural Forms in Translations} @@ -1503,7 +1502,7 @@ \contentspage {Qt Linguist Manual}{Contents} \previouspage Qt Linguist Manual: Programmers - The \c .ts file format used by \QL is described by the + The TS file format used by \QL is described by the \l{http://www.w3.org/TR/1998/REC-xml-19980210}{DTD} presented below, which we include for your convenience. Be aware that the format may change in future Qt releases. diff --git a/doc/src/porting4-canvas.qdoc b/doc/src/porting4-canvas.qdoc index fa0bc6b..d1221cf 100644 --- a/doc/src/porting4-canvas.qdoc +++ b/doc/src/porting4-canvas.qdoc @@ -43,7 +43,7 @@ \page graphicsview-porting.html \title Porting to Graphics View \contentspage {Porting Guides}{Contents} - \previouspage Porting .ui Files to Qt 4 + \previouspage Porting UI Files to Qt 4 \nextpage qt3to4 - The Qt 3 to 4 Porting Tool \ingroup porting \ingroup multimedia diff --git a/doc/src/porting4-designer.qdoc b/doc/src/porting4-designer.qdoc index 916894b..7de1d43 100644 --- a/doc/src/porting4-designer.qdoc +++ b/doc/src/porting4-designer.qdoc @@ -41,12 +41,12 @@ /*! \page porting4-designer.html - \title Porting .ui Files to Qt 4 + \title Porting UI Files to Qt 4 \contentspage {Porting Guides}{Contents} \previouspage Porting to Qt 4 - Drag and Drop \nextpage Porting to Graphics View \ingroup porting - \brief Information about changes to the .ui file format in Qt 4. + \brief Information about changes to the UI file format in Qt 4. Qt Designer has changed significantly in the Qt 4 release. We have moved away from viewing Qt Designer as an IDE and @@ -57,20 +57,20 @@ IDEs. The most important changes in Qt Designer 4 which affect porting - for \c .ui files are summarized below: + for UI files are summarized below: \list \o \bold{Removed project manager.} - Qt Designer now only reads and edits \c .ui - files. It has no notion of a project (\c .pro file). + Qt Designer now only reads and edits UI + files. It has no notion of a project file (\c .pro). \o \bold{Removed code editor.} Qt Designer can no longer be used to edit source files. - \o \bold{Changed format of \c .ui files.} + \o \bold{Changed format of UI files.} Qt Designer 4 cannot read files created by Qt Designer 3 and vice versa. However, we provide the tool \c uic3 to generate Qt - 4 code out of Qt 3 \c .ui files, and to convert old \c .ui files + 4 code out of Qt 3 UI files, and to convert old UI files into a format readable by Qt Designer 4. \o \bold{Changed structure of the code generated by \c uic.} @@ -80,7 +80,7 @@ \c Ui::MyForm. \o \bold{New resource file system.} Icon data is no longer - stored in the \c .ui file. Instead, icons are put into resource + stored in the UI file. Instead, icons are put into resource files (\c .qrc). \endlist @@ -146,9 +146,9 @@ therefore has an interface identical to that of a class generated by \c uic in Qt 3. - Creating POD classes from \c .ui files is more flexible and + Creating POD classes from UI files is more flexible and generic than the old approach of creating widgets. Qt Designer - doesn't need to know anything about the main container apart from + does not need to know anything about the main container apart from the base widget class it inherits. Indeed, \c Ui::HelloWorld can be used to populate any container that inherits QWidget. Conversely, all non-GUI aspects of the main container may be @@ -163,10 +163,10 @@ \list 1 \o To generate headers and source code for a widget to implement any custom signals and slots added using Qt Designer 3. - \o To generate a new \c .ui file that can be used with Qt Designer 4. + \o To generate a new UI file that can be used with Qt Designer 4. \endlist - You can use both these methods in combination to obtain \c{.ui}, header + You can use both these methods in combination to obtain UI, header and source files that you can use as a starting point when porting your user interface to Qt 4. @@ -179,7 +179,7 @@ The resulting files \c myform.h and \c myform.cpp implement the form in Qt 4 using a QWidget that will include custom signals, - slots and connections specified in the \c .ui file. However, + slots and connections specified in the UI file. However, see below for the \l{#Limitations of uic3}{limitations} of this method. @@ -190,7 +190,7 @@ The resulting file \c myform4.ui can be edited in Qt Designer 4. The header file for the form is generated by Qt 4's \c uic. See the - \l{Using a Designer .ui File in Your Application} chapter of the + \l{Using a Designer UI File in Your Application} chapter of the \l{Qt Designer Manual} for information about the preferred ways to use forms created with Qt Designer 4. @@ -218,7 +218,7 @@ \section1 Limitations of uic3 - Converting Qt 3 \c .ui files to Qt 4 has some limitations. The + Converting Qt 3 UI files to Qt 4 has some limitations. The most noticeable limitation is the fact that since \c uic no longer generates a QObject, it's not possible to define custom signals or slots for the form. Instead, the programmer must @@ -231,9 +231,9 @@ A quick and dirty way to port forms containing custom signals and slots is to generate the code using \c uic3, rather than \c uic. Since \c uic3 does generate a QWidget, it will populate it with custom - signals, slots and connections specified in the \c .ui file. - However, \c uic3 can only generate code from Qt 3 \c .ui files, which - implies that the \c .ui files never get translated and need to be + signals, slots and connections specified in the UI file. + However, \c uic3 can only generate code from Qt 3 UI files, which + implies that the UI files never get translated and need to be edited using Qt Designer 3. Note also that it is possible to create implicit connections @@ -256,7 +256,7 @@ \section1 Icons In Qt 3, the binary data for the icons used by a form was stored - in the \c .ui file. In Qt 4 icons and any other external files + in the UI file. In Qt 4 icons and any other external files can be compiled into the application by listing them in a \l{The Qt Resource System}{resource file} (\c .qrc). This file is translated into a C++ source file using Qt's resource compiler @@ -306,7 +306,7 @@ the following steps: \list 1 - \o Use \c{uic3 -convert} to obtain a \c .ui file understood by + \o Use \c{uic3 -convert} to obtain a UI file understood by Qt Designer 4. \o Create a \c .qrc file with a list of all the icon files. diff --git a/doc/src/porting4-overview.qdoc b/doc/src/porting4-overview.qdoc index d91729d..3494c6d 100644 --- a/doc/src/porting4-overview.qdoc +++ b/doc/src/porting4-overview.qdoc @@ -115,13 +115,13 @@ support these project-level features. We recommend using one of the - \l{Using a Designer .ui File in Your Application}{form subclassing approaches} + \l{Using a Designer UI File in Your Application}{form subclassing approaches} with forms created using Qt Designer. This avoids the need to use \c{.ui.h} files and special purpose code editors. Existing Qt 3 forms created using Qt Designer can be gradually ported to Qt 4 by following the advice in the - \l{Porting .ui Files to Qt 4} guide. However, some extra effort + \l{Porting UI Files to Qt 4} guide. However, some extra effort will be required to move application logic from \c{.ui.h} files into the main body of a Qt 4 application. diff --git a/doc/src/porting4.qdoc b/doc/src/porting4.qdoc index 7ce2969..2414c4d 100644 --- a/doc/src/porting4.qdoc +++ b/doc/src/porting4.qdoc @@ -97,7 +97,7 @@ to developers porting from Qt 3 to Qt 4. \o \l{Porting to Qt 4 - Drag and Drop} \mdash covers differences in the way drag and drop is handled between Qt 3 and Qt 4. - \o \l{Porting .ui Files to Qt 4} \mdash describes the new format used to + \o \l{Porting UI Files to Qt 4} \mdash describes the new format used to describe forms created with \QD. \o \l{Porting to Graphics View} \mdash provides a class-by-class overview of the differences between Qt 3's canvas API and Qt 4's Graphics @@ -135,7 +135,7 @@ \o Run the \l qt3to4 porting tool. The tool will go through your source code and adapt it to Qt 4. - \o Follow the instructions in the \l{Porting .ui Files to Qt 4} + \o Follow the instructions in the \l{Porting UI Files to Qt 4} page to port Qt Designer files. \o Recompile with Qt 4. For each error, search below for related @@ -347,7 +347,7 @@ macro, removing the need for a \c Q_OVERRIDE() macro. The table below lists the Qt properties that have been renamed in - Qt 4. Occurrences of these in \e{Qt Designer} \c .ui files are + Qt 4. Occurrences of these in \e{Qt Designer} UI files are automatically converted to the new name by \c uic. \table @@ -406,11 +406,11 @@ Some properties have been removed from Qt 4, but the associated access functions are provided if \c QT3_SUPPORT is defined to help - porting to Qt 4. When converting Qt 3 \c .ui files to Qt 4, \c uic + porting to Qt 4. When converting Qt 3 UI files to Qt 4, \c uic generates calls to the Qt 3 compatibility functions. Note that this only applies to the properties of the Qt3Support library, i.e. \c QT3_SUPPORT properties of the other libraries must be - ported manually when converting Qt 3 .ui files to Qt 4. + ported manually when converting Qt 3 UI files to Qt 4. The table below lists these properties with the read and write functions that you can use instead. The documentation for the @@ -518,7 +518,7 @@ (Notice the \c & in the parameter declaration.) \omit - \section1 Qt Designer .ui Files + \section1 Qt Designer UI Files ### \endomit diff --git a/doc/src/qmake-manual.qdoc b/doc/src/qmake-manual.qdoc index 049f30c..0921ae7 100644 --- a/doc/src/qmake-manual.qdoc +++ b/doc/src/qmake-manual.qdoc @@ -235,7 +235,7 @@ \row \o CONFIG \o General project configuration options. \row \o DESTDIR \o The directory in which the executable or binary file will be placed. - \row \o FORMS \o A list of .ui files to be processed by \c uic. + \row \o FORMS \o A list of UI files to be processed by \c uic. \row \o HEADERS \o A list of filenames of header (.h) files used when building the project. \row \o QT \o Qt-specific configuration options. @@ -701,8 +701,8 @@ If a directory is specified, it will be included in the \c DEPENDPATH variable, and relevant code from there will be included in the generated project file. If a file is given, it will be appended to the correct - variable, depending on its extension; for example, .ui files are added - to \c FORMS, and .cpp files are added to \c SOURCES. + variable, depending on its extension; for example, UI files are added + to \c FORMS, and C++ files are added to \c SOURCES. You may also pass assignments on the command line in this mode. When doing so, these assignments will be placed last in the generated project file. @@ -1304,10 +1304,10 @@ \target FORMS \section1 FORMS - This variable specifies the .ui files (see \link + This variable specifies the UI files (see \link designer-manual.html Qt Designer \endlink) to be processed through \c uic before compiling. All dependencies, headers and source files required - to build these .ui files will automatically be added to the project. + to build these UI files will automatically be added to the project. For example: @@ -1320,10 +1320,10 @@ \target FORMS3 \section1 FORMS3 - This variable specifies the old style .ui files to be processed + This variable specifies the old style UI files to be processed through \c uic3 before compiling, when \c CONFIG contains uic3. All dependencies, headers and source files required to build these - .ui files will automatically be added to the project. + UI files will automatically be added to the project. For example: @@ -4151,7 +4151,7 @@ \list \o HEADERS - A list of all the header files for the application. \o SOURCES - A list of all the source files for the application. - \o FORMS - A list of all the .ui files (created using \c{Qt Designer}) + \o FORMS - A list of all the UI files (created using \c{Qt Designer}) for the application. \o LEXSOURCES - A list of all the lex source files for the application. \o YACCSOURCES - A list of all the yacc source files for the application. @@ -4169,7 +4169,7 @@ \endlist You only need to use the system variables that you have values for, - for instance, if you don't have any extra INCLUDEPATHs then you don't + for instance, if you do not have any extra INCLUDEPATHs then you do not need to specify any, \c qmake will add in the default ones needed. For instance, an example project file might look like this: diff --git a/doc/src/qmsdev.qdoc b/doc/src/qmsdev.qdoc index b8d8f85..127b514 100644 --- a/doc/src/qmsdev.qdoc +++ b/doc/src/qmsdev.qdoc @@ -87,7 +87,7 @@ the existing project. If you want to add an existing dialog to your project, then just select the - relevant \c .ui file. This will then add it to your existing project and add + relevant UI file. This will then add it to your existing project and add the relevant steps to create the generated code. \section2 Using the 'Qt Designer' button diff --git a/doc/src/qt3to4.qdoc b/doc/src/qt3to4.qdoc index 9ffd52e..47e85b4 100644 --- a/doc/src/qt3to4.qdoc +++ b/doc/src/qt3to4.qdoc @@ -50,7 +50,7 @@ to Qt 4. It is designed to automate the most tedious part of the porting effort. - See \l{Porting to Qt 4} and \l{Porting .ui Files to Qt 4} for + See \l{Porting to Qt 4} and \l{Porting UI Files to Qt 4} for more information about porting Qt 3 applications to Qt 4. \section1 Usage diff --git a/doc/src/qt4-intro.qdoc b/doc/src/qt4-intro.qdoc index 2fda7cf..6f59cae 100644 --- a/doc/src/qt4-intro.qdoc +++ b/doc/src/qt4-intro.qdoc @@ -235,7 +235,7 @@ for your project (using "DEFINES +=") on to moc, which has its own built-in C++ preprocessor. - To compile code that uses .ui files, you will also need this line in + To compile code that uses UI files, you will also need this line in the .pro file: \snippet doc/src/snippets/code/doc_src_qt4-intro.qdoc 2 diff --git a/doc/src/qtdesigner.qdoc b/doc/src/qtdesigner.qdoc index 2117b27..d913b32 100644 --- a/doc/src/qtdesigner.qdoc +++ b/doc/src/qtdesigner.qdoc @@ -52,7 +52,7 @@ that enable you to access Qt Designer's components. In addition, the QFormBuilder class provides the possibility of - constructing user interfaces from \c .ui files at run-time. + constructing user interfaces from UI files at run-time. To include the definitions of the module's classes, use the following directive: @@ -155,7 +155,7 @@ The \c QtDesigner module contains the QFormBuilder class that provides a mechanism for dynamically creating user interfaces at - run-time, based on \c .ui files created with \QD. This class is + run-time, based on UI files created with \QD. This class is typically used by custom components and applications that embed \QD. Standalone applications that need to dynamically generate user interfaces at run-time use the QUiLoader class, found in @@ -1427,7 +1427,7 @@ \fn bool QDesignerPropertySheetExtension::isAttribute(int index) const Returns true if the property at the given \a index is an attribute, - which will be \e excluded from the .ui file, otherwise false. + which will be \e excluded from the UI file, otherwise false. \sa indexOf(), setAttribute() */ @@ -1436,7 +1436,7 @@ \fn void QDesignerPropertySheetExtension::setAttribute(int index, bool attribute) If \a attribute is true, the property at the given \a index is - made an attribute which will be \e excluded from the .ui file; + made an attribute which will be \e excluded from the UI file; otherwise it will be included. \sa indexOf(), isAttribute() diff --git a/doc/src/qthelp.qdoc b/doc/src/qthelp.qdoc index 7260b6e..b5395c9 100644 --- a/doc/src/qthelp.qdoc +++ b/doc/src/qthelp.qdoc @@ -279,7 +279,7 @@ \section1 Qt Help Project File Format - The file format is XML based. For a better understanding of + The file format is XML-based. For a better understanding of the format we'll discuss the following example: \snippet doc/src/snippets/code/doc_src_qthelp.qdoc 7 diff --git a/doc/src/qtscript.qdoc b/doc/src/qtscript.qdoc index f2ac6c9..6b8f639 100644 --- a/doc/src/qtscript.qdoc +++ b/doc/src/qtscript.qdoc @@ -1782,20 +1782,20 @@ \list 1 \o Run \c lupdate to extract translatable text from the script source code - of the Qt application, resulting in a message file for translators (a \c - .ts file). The utility recognizes qsTr(), qsTranslate() and the - \c{QT_TR*_NOOP()} functions described above and produces \c .ts files + of the Qt application, resulting in a message file for translators (a TS + file). The utility recognizes qsTr(), qsTranslate() and the + \c{QT_TR*_NOOP()} functions described above and produces TS files (usually one per language). - \o Provide translations for the source texts in the \c .ts file, using - \e{Qt Linguist}. Since \c .ts files are in XML format, you can also + \o Provide translations for the source texts in the TS file, using + \e{Qt Linguist}. Since TS files are in XML format, you can also edit them by hand. - \o Run \c lrelease to obtain a light-weight message file (a \c .qm - file) from the \c .ts file, suitable only for end use. Think of the \c - .ts files as "source files", and \c .qm files as "object files". The - translator edits the \c .ts files, but the users of your application - only need the \c .qm files. Both kinds of files are platform and + \o Run \c lrelease to obtain a light-weight message file (a QM + file) from the TS file, suitable only for end use. Think of the TS + files as "source files", and QM files as "object files". The + translator edits the TS files, but the users of your application + only need the QM files. Both kinds of files are platform and locale independent. \endlist @@ -1805,7 +1805,7 @@ translations from previous releases. When running \c lupdate, you must specify the location of the script(s), - and the name of the \c{.ts} file to produce. Examples: + and the name of the TS file to produce. Examples: \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 87 @@ -1823,7 +1823,7 @@ \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 89 - When running \c lrelease, you must specify the name of the \c{.ts} input + When running \c lrelease, you must specify the name of the TS input file; or, if you are using a qmake project file to manage script translations, you specify the name of that file. \c lrelease will create \c myscript_la.qm, the binary representation of the translation. diff --git a/doc/src/qtuiloader.qdoc b/doc/src/qtuiloader.qdoc index 137cfeb..0a23366 100644 --- a/doc/src/qtuiloader.qdoc +++ b/doc/src/qtuiloader.qdoc @@ -53,7 +53,7 @@ These forms are processed at run-time to produce dynamically-generated user interfaces. In order to generate a form at run-time, a resource - file containing a \c{.ui} file is needed. Applications that use the + file containing a UI file is needed. Applications that use the form handling classes need to be configured to be built against the QtUiTools module. This is done by including the following declaration in a \c qmake project file to ensure that the application is compiled diff --git a/doc/src/signalsandslots.qdoc b/doc/src/signalsandslots.qdoc index 356db33..09eb0a6 100644 --- a/doc/src/signalsandslots.qdoc +++ b/doc/src/signalsandslots.qdoc @@ -190,7 +190,7 @@ know any information about each other. To enable this, the objects only need to be connected together, and this can be achieved with some simple QObject::connect() function calls, or with \c{uic}'s - \l{Using a Designer .ui File in Your Application#Automatic Connections} + \l{Using a Designer UI File in Your Application#Automatic Connections} {automatic connections} feature. \section1 Building the Example diff --git a/doc/src/snippets/code/doc_src_linguist-manual.qdoc b/doc/src/snippets/code/doc_src_linguist-manual.qdoc index ce3b997..5697300 100644 --- a/doc/src/snippets/code/doc_src_linguist-manual.qdoc +++ b/doc/src/snippets/code/doc_src_linguist-manual.qdoc @@ -42,7 +42,7 @@ Options: -pluralonly Only include plural form messages. -silent - Don't explain what is being done. + Do not explain what is being done. -version Display the version of lupdate and exit. //! [4] @@ -55,14 +55,14 @@ Usage: Options: -help Display this information and exit -compress - Compress the .qm files + Compress the QM files -nounfinished Do not include unfinished translations -removeidentical If the translated text is the same as the source text, do not include the message -silent - Don't explain what is being done + Do not explain what is being done -version Display the version of lrelease and exit //! [5] diff --git a/doc/src/templates.qdoc b/doc/src/templates.qdoc index 5a8acf7..8cfb851 100644 --- a/doc/src/templates.qdoc +++ b/doc/src/templates.qdoc @@ -162,7 +162,7 @@ without having to know the exact types of the objects we are connecting. This is impossible with a template based solution. This kind of runtime introspection opens up new possibilities, for example GUIs that are - generated and connected from Qt Designer's XML \c{ui} files. + generated and connected from Qt Designer's XML UI files. \section1 Calling Performance is Not Everything diff --git a/examples/uitools/textfinder/forms/input.txt b/examples/uitools/textfinder/forms/input.txt index fae542f..29dfe5d 100644 --- a/examples/uitools/textfinder/forms/input.txt +++ b/examples/uitools/textfinder/forms/input.txt @@ -1,5 +1,5 @@ These forms are processed at run-time to produce dynamically-generated user interfaces. -In order to generate a form at run-time, a resource file containing a .ui file is needed. +In order to generate a form at run-time, a resource file containing a UI file is needed. Applications that use the form handling classes need to be configured to be built against the QtUiTools module. This is done by including the following declaration in a qmake project file to ensure that the application is compiled and linked appropriately. A form loader object, diff --git a/mkspecs/features/uic.prf b/mkspecs/features/uic.prf index d2985f9..e768d0f 100644 --- a/mkspecs/features/uic.prf +++ b/mkspecs/features/uic.prf @@ -51,7 +51,7 @@ equals(UI_DIR, .) { uic3 { isEmpty(FORMS3) { UIC3_FORMS = FORMS - !build_pass:message("Project contains CONFIG+=uic3, but no files in FORMS3; .ui files in FORMS treated as UIC3 form files.") + !build_pass:message("Project contains CONFIG+=uic3, but no files in FORMS3; UI files in FORMS treated as UIC3 form files.") } else { UIC3_FORMS = FORMS3 } diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 9e87b3b..eb1bd0b 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -565,7 +565,7 @@ int QMetaCallEvent::placeMetaCall(QObject *object) \l uic generates code that invokes this function to enable auto-connection to be performed between widgets on forms created with \QD. More information about using auto-connection with \QD is - given in the \l{Using a Designer .ui File in Your Application} section of + given in the \l{Using a Designer UI File in Your Application} section of the \QD manual. \section2 Dynamic Properties diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index 4aed2b2..dc1b530 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -503,7 +503,7 @@ bool QTranslator::load(const QString & filename, const QString & directory, \overload load() \fn bool QTranslator::load(const uchar *data, int len) - Loads the .qm file data \a data of length \a len into the + Loads the QM file data \a data of length \a len into the translator. The data is not copied. The caller must be able to guarantee that \a data diff --git a/src/tools/uic/uic.cpp b/src/tools/uic/uic.cpp index 1c6e3a5..bbb3af7 100644 --- a/src/tools/uic/uic.cpp +++ b/src/tools/uic/uic.cpp @@ -137,12 +137,12 @@ void Uic::writeCopyrightHeader(DomUI *ui) out << "/*\n" << comment << "\n*/\n\n"; out << "/********************************************************************************\n"; - out << "** Form generated from reading ui file '" << QFileInfo(opt.inputFile).fileName() << "'\n"; + out << "** Form generated from reading UI file '" << QFileInfo(opt.inputFile).fileName() << "'\n"; out << "**\n"; out << "** Created: " << QDateTime::currentDateTime().toString() << "\n"; out << "** " << QString::fromLatin1("by: Qt User Interface Compiler version %1\n").arg(QLatin1String(QT_VERSION_STR)); out << "**\n"; - out << "** WARNING! All changes made in this file will be lost when recompiling ui file!\n"; + out << "** WARNING! All changes made in this file will be lost when recompiling UI file!\n"; out << "********************************************************************************/\n\n"; } diff --git a/src/tools/uic3/main.cpp b/src/tools/uic3/main.cpp index 38afc60..f4a9cba 100644 --- a/src/tools/uic3/main.cpp +++ b/src/tools/uic3/main.cpp @@ -114,7 +114,7 @@ int runUic3(int argc, char * argv[]) wrap = true; if (opt == "wrap" || opt[1] == '\0') { if (!(n < argc-1)) { - error = "Missing name of converted ui file"; + error = "Missing name of converted UI file"; break; } convertedUiFile = argv[++n]; @@ -230,7 +230,7 @@ int runUic3(int argc, char * argv[]) " %s [options] -decl \n" "\t name of the data file\n" " %s [options] -wrap \n" - "\t name of the converted ui file\n" + "\t name of the converted UI file\n" "Generate implementation:\n" " %s [options] -impl \n" "\t name of the declaration file\n" @@ -254,7 +254,7 @@ int runUic3(int argc, char * argv[]) "\t-pch file Add #include \"file\" as the first statement in implementation\n" "\t-nofwd Omit forward declarations of custom classes\n" "\t-no-implicit-includes Do not generate #include-directives for custom classes\n" - "\t-nounload Don't unload plugins after processing\n" + "\t-nounload Do not unload plugins after processing\n" "\t-tr func Use func() instead of tr() for i18n\n" "\t-L path Additional plugin search path\n" "\t-version Display version of uic\n" diff --git a/src/tools/uic3/uic.cpp b/src/tools/uic3/uic.cpp index e911844..16b2754 100644 --- a/src/tools/uic3/uic.cpp +++ b/src/tools/uic3/uic.cpp @@ -144,12 +144,12 @@ void Uic::writeCopyrightHeader(DomUI *ui) out << "/*\n" << comment << "\n*/\n\n"; out << "/********************************************************************************\n"; - out << "** Form generated from reading ui file '" << QFileInfo(opt.inputFile).fileName() << "'\n"; + out << "** Form generated from reading UI file '" << QFileInfo(opt.inputFile).fileName() << "'\n"; out << "**\n"; out << "** Created: " << QDateTime::currentDateTime().toString() << "\n"; out << "** " << QString::fromLatin1("by: Qt User Interface Compiler version %1\n").arg(QLatin1String(QT_VERSION_STR)); out << "**\n"; - out << "** WARNING! All changes made in this file will be lost when recompiling ui file!\n"; + out << "** WARNING! All changes made in this file will be lost when recompiling UI file!\n"; out << "********************************************************************************/\n\n"; } diff --git a/src/xmlpatterns/data/qresourceloader_p.h b/src/xmlpatterns/data/qresourceloader_p.h index 8cb174d..0ebc885 100644 --- a/src/xmlpatterns/data/qresourceloader_p.h +++ b/src/xmlpatterns/data/qresourceloader_p.h @@ -114,7 +114,7 @@ namespace QPatternist * * Typically this hint is given when the URI is available at * compile-time, but it is used inside a conditional statement - * whose branching can't be determined at compile time. + * whose branching cannot be determined at compile time. */ MayUse, diff --git a/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ts.before index e297784..076520a 100644 --- a/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ts.before +++ b/tests/auto/linguist/lupdate/testdata/good/mergeui/project.ts.before @@ -5,7 +5,7 @@ Qt Assistant - Find text - + Qt Assistant - Finn tekst 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 index d65110a..6bc565c 100644 --- a/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ts.result +++ b/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ts.result @@ -9,7 +9,7 @@ - This should not be considered to be more or less equal to the corresponding one in the ts file. + This should not be considered to be more or less equal to the corresponding one in the TS file. diff --git a/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ui b/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ui index 0d0defd..a5f8e9f 100644 --- a/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ui +++ b/tests/auto/linguist/lupdate/testdata/good/mergeui_obsolete/project.ui @@ -17,7 +17,7 @@ - This should not be considered to be more or less equal to the corresponding one in the ts file. + This should not be considered to be more or less equal to the corresponding one in the TS file. Here, similarity should kick in! diff --git a/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ts.result index d65110a..6bc565c 100644 --- a/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ts.result +++ b/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ts.result @@ -9,7 +9,7 @@ - This should not be considered to be more or less equal to the corresponding one in the ts file. + This should not be considered to be more or less equal to the corresponding one in the TS file. diff --git a/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ui b/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ui index 0d0defd..a5f8e9f 100644 --- a/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ui +++ b/tests/auto/linguist/lupdate/testdata/good/textsimilarity/project.ui @@ -17,7 +17,7 @@ - This should not be considered to be more or less equal to the corresponding one in the ts file. + This should not be considered to be more or less equal to the corresponding one in the TS file. Here, similarity should kick in! diff --git a/tools/designer/data/generate_shared.xsl b/tools/designer/data/generate_shared.xsl index f7859cd..ec95fe2 100644 --- a/tools/designer/data/generate_shared.xsl +++ b/tools/designer/data/generate_shared.xsl @@ -6,8 +6,8 @@ xmlns:xs="http://www.w3.org/2001/XMLSchema"> diff --git a/tools/designer/src/components/formeditor/qdesigner_resource.cpp b/tools/designer/src/components/formeditor/qdesigner_resource.cpp index de4b57b..ac03909 100644 --- a/tools/designer/src/components/formeditor/qdesigner_resource.cpp +++ b/tools/designer/src/components/formeditor/qdesigner_resource.cpp @@ -631,13 +631,13 @@ static bool readUiAttributes(QIODevice *dev, QString *errorMessage, *language = attributes.value(languageAttribute).toString(); return true; } else { - *errorMessage = QCoreApplication::translate("Designer", "Invalid ui file: The root element is missing."); + *errorMessage = QCoreApplication::translate("Designer", "Invalid UI file: The root element is missing."); return false; } } } - *errorMessage = QCoreApplication::translate("Designer", "An error has occurred while reading the ui file at line %1, column %2: %3") + *errorMessage = QCoreApplication::translate("Designer", "An error has occurred while reading the UI file at line %1, column %2: %3") .arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString()); return false; } @@ -756,7 +756,7 @@ void QDesignerResource::setSaveRelative(bool relative) QWidget *QDesignerResource::create(DomUI *ui, QWidget *parentWidget) { // Load extra info extension. This is used by Jambi for preventing - // C++ ui files from being loaded + // C++ UI files from being loaded if (QDesignerExtraInfoExtension *extra = qt_extension(core()->extensionManager(), core())) { if (!extra->loadUiExtraInfo(ui)) { const QString errorMessage = QApplication::translate("Designer", "This file cannot be read because the extra info extension failed to load."); diff --git a/tools/designer/src/designer/mainwindow.cpp b/tools/designer/src/designer/mainwindow.cpp index b72a790..a3ca234 100644 --- a/tools/designer/src/designer/mainwindow.cpp +++ b/tools/designer/src/designer/mainwindow.cpp @@ -155,7 +155,7 @@ DockedMdiArea::DockedMdiArea(const QString &extension, QWidget *parent) : QStringList DockedMdiArea::uiFiles(const QMimeData *d) const { - // Extract dropped ui files from Mime data. + // Extract dropped UI files from Mime data. QStringList rc; if (!d->hasFormat(QLatin1String(uriListMimeFormatC))) return rc; diff --git a/tools/designer/src/designer/qdesigner_workbench.cpp b/tools/designer/src/designer/qdesigner_workbench.cpp index 923687a2..f21da8c 100644 --- a/tools/designer/src/designer/qdesigner_workbench.cpp +++ b/tools/designer/src/designer/qdesigner_workbench.cpp @@ -960,7 +960,7 @@ QDesignerFormWindow * QDesignerWorkbench::loadForm(const QString &fileName, removeFormWindow(formWindow); formWindowManager->removeFormWindow(editor); m_core->metaDataBase()->remove(editor); - *errorMessage = tr("The file %1 is not a valid Designer ui file.").arg(file.fileName()); + *errorMessage = tr("The file %1 is not a valid Designer UI file.").arg(file.fileName()); return 0; } *uic3Converted = editor->fileName().isEmpty(); diff --git a/tools/designer/src/lib/sdk/abstractformwindow.cpp b/tools/designer/src/lib/sdk/abstractformwindow.cpp index 89c1015..313b324 100644 --- a/tools/designer/src/lib/sdk/abstractformwindow.cpp +++ b/tools/designer/src/lib/sdk/abstractformwindow.cpp @@ -247,7 +247,7 @@ QDesignerFormWindowInterface *QDesignerFormWindowInterface::findFormWindow(QObje /*! \fn virtual QString QDesignerFormWindowInterface::fileName() const - Returns the file name of the .ui file that describes the form + Returns the file name of the UI file that describes the form currently being shown. \sa setFileName() @@ -399,11 +399,11 @@ QDesignerFormWindowInterface *QDesignerFormWindowInterface::findFormWindow(QObje \fn virtual QStringList QDesignerFormWindowInterface::includeHints() const Returns a list of the header files that will be included in the - form window's associated \c .ui file. + form window's associated UI file. Header files may be local, i.e. relative to the project's - directory,\c "mywidget.h", or global, i.e. part of Qt or the - compilers standard libraries:\c . + directory, \c "mywidget.h", or global, i.e. part of Qt or the + compilers standard libraries: \c . \sa setIncludeHints() */ @@ -412,11 +412,11 @@ QDesignerFormWindowInterface *QDesignerFormWindowInterface::findFormWindow(QObje \fn virtual void QDesignerFormWindowInterface::setIncludeHints(const QStringList &includeHints) Sets the header files that will be included in the form window's - associated \c .ui file to the specified \a includeHints. + associated UI file to the specified \a includeHints. Header files may be local, i.e. relative to the project's - directory,\c "mywidget.h", or global, i.e. part of Qt or the - compilers standard libraries:\c . + directory, \c "mywidget.h", or global, i.e. part of Qt or the + compilers standard libraries: \c . \sa includeHints() */ diff --git a/tools/designer/src/lib/sdk/script.cpp b/tools/designer/src/lib/sdk/script.cpp index 90b4c73..2eda3d1 100644 --- a/tools/designer/src/lib/sdk/script.cpp +++ b/tools/designer/src/lib/sdk/script.cpp @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE \since 4.3 On saving the form, the extension is queried for a script snippet - to be associated with the widget while saving the \c .ui file. + to be associated with the widget while saving the UI file. This script is then run after creating the widget by \l uic or QUiLoader. @@ -66,7 +66,7 @@ QT_BEGIN_NAMESPACE for which an editor is provided by the QDesignerTaskMenuExtension. While saving the form, the state is serialized as a QVariantMap of - \QD-supported properties, which is stored in the \c .ui file. This is + \QD-supported properties, which is stored in the UI file. This is handled by data() and setData(). For item view contents, there might be for example a key that determines @@ -97,7 +97,7 @@ QDesignerScriptExtension::~QDesignerScriptExtension() \fn virtual QVariantMap QDesignerScriptExtension::data() const Returns a map of variants describing the internal state to be - stored in the \c .ui file. + stored in the UI file. */ /*! diff --git a/tools/designer/src/lib/uilib/abstractformbuilder.cpp b/tools/designer/src/lib/uilib/abstractformbuilder.cpp index 65ea375..05e05c1 100644 --- a/tools/designer/src/lib/uilib/abstractformbuilder.cpp +++ b/tools/designer/src/lib/uilib/abstractformbuilder.cpp @@ -135,7 +135,7 @@ public: QAbstractFormBuilder provides a standard interface and a default implementation for constructing forms from user interface files. It is not intended to be instantiated directly. Use the - QFormBuilder class to create user interfaces from \c{.ui} files at + QFormBuilder class to create user interfaces from UI files at run-time. For example: \snippet doc/src/snippets/code/tools_designer_src_lib_uilib_abstractformbuilder.cpp 0 @@ -145,10 +145,10 @@ public: functions: \list - \o load() handles reading of \c{.ui} format files from arbitrary + \o load() handles reading of UI format files from arbitrary QIODevices, and construction of widgets from the XML data that they contain. - \o save() handles saving of widget details in \c{.ui} format to + \o save() handles saving of widget details in UI format to arbitrary QIODevices. \o workingDirectory() and setWorkingDirectory() control the directory in which forms are held. The form builder looks for @@ -208,13 +208,13 @@ QWidget *QAbstractFormBuilder::load(QIODevice *dev, QWidget *parentWidget) } } if (reader.hasError()) { - uiLibWarning(QCoreApplication::translate("QAbstractFormBuilder", "An error has occurred while reading the ui file at line %1, column %2: %3") + uiLibWarning(QCoreApplication::translate("QAbstractFormBuilder", "An error has occurred while reading the UI file at line %1, column %2: %3") .arg(reader.lineNumber()).arg(reader.columnNumber()) .arg(reader.errorString())); return 0; } if (!initialized) { - uiLibWarning(QCoreApplication::translate("QAbstractFormBuilder", "Invalid ui file: The root element is missing.")); + uiLibWarning(QCoreApplication::translate("QAbstractFormBuilder", "Invalid UI file: The root element is missing.")); return 0; } @@ -657,7 +657,7 @@ void QAbstractFormBuilder::layoutInfo(DomLayout *ui_layout, QObject *parent, int spac = p->elementNumber(); #ifdef Q_OS_MAC - // here we recognize ui file < 4.3 (no we don't store margin property) + // here we recognize UI file < 4.3 (no we don't store margin property) if (mar != INT_MIN) { const int defaultMargin = parent->inherits("QLayoutWidget") ? 0 : 9; if (mar == defaultMargin) @@ -1202,7 +1202,7 @@ QActionGroup *QAbstractFormBuilder::createActionGroup(QObject *parent, const QSt \fn void QAbstractFormBuilder::save(QIODevice *device, QWidget *widget) Saves an XML representation of the given \a widget to the - specified \a device in the standard \c{.ui} file format. + specified \a device in the standard UI file format. \sa load()*/ void QAbstractFormBuilder::save(QIODevice *dev, QWidget *widget) diff --git a/tools/designer/src/lib/uilib/formbuilder.cpp b/tools/designer/src/lib/uilib/formbuilder.cpp index 043991e..f737311 100644 --- a/tools/designer/src/lib/uilib/formbuilder.cpp +++ b/tools/designer/src/lib/uilib/formbuilder.cpp @@ -57,12 +57,12 @@ namespace QFormInternal { \class QFormBuilder \brief The QFormBuilder class is used to dynamically construct - user interfaces from .ui files at run-time. + user interfaces from UI files at run-time. \inmodule QtDesigner The QFormBuilder class provides a mechanism for dynamically - creating user interfaces at run-time, based on \c{.ui} files + creating user interfaces at run-time, based on UI files created with \QD. For example: \snippet doc/src/snippets/code/tools_designer_src_lib_uilib_formbuilder.cpp 0 diff --git a/tools/designer/src/uitools/quiloader.cpp b/tools/designer/src/uitools/quiloader.cpp index 5387c2d..1c7d1cc 100644 --- a/tools/designer/src/uitools/quiloader.cpp +++ b/tools/designer/src/uitools/quiloader.cpp @@ -574,20 +574,20 @@ void QUiLoaderPrivate::setupWidgetMap() const \brief The QUiLoader class enables standalone applications to dynamically create user interfaces at run-time using the - information stored in .ui files or specified in plugin paths. + information stored in UI files or specified in plugin paths. In addition, you can customize or create your own user interface by deriving your own loader class. If you have a custom component or an application that embeds \QD, you can also use the QFormBuilder class provided by the QtDesigner module to create - user interfaces from \c{.ui} files. + user interfaces from UI files. The QUiLoader class provides a collection of functions allowing you to - create widgets based on the information stored in \c .ui files (created + create widgets based on the information stored in UI files (created with \QD) or available in the specified plugin paths. The specified plugin paths can be retrieved using the pluginPaths() function. Similarly, the - contents of a \c{.ui} file can be retrieved using the load() function. For + contents of a UI file can be retrieved using the load() function. For example: \snippet doc/src/snippets/quiloader/mywidget.cpp 0 diff --git a/tools/linguist/lconvert/main.cpp b/tools/linguist/lconvert/main.cpp index 534bc11..4bed02f 100644 --- a/tools/linguist/lconvert/main.cpp +++ b/tools/linguist/lconvert/main.cpp @@ -81,10 +81,10 @@ static int usage(const QStringList &args) " --output-format \n" " Specify output format. See -if.\n\n" " --input-codec \n" - " Specify encoding for .qm input files. Default is 'Latin1'.\n" + " Specify encoding for QM input files. Default is 'Latin1'.\n" " UTF-8 is always tried as well, corresponding to the trUtf8() function.\n\n" " --drop-tags \n" - " Drop named extra tags when writing 'ts' or 'xlf' files.\n" + " Drop named extra tags when writing TS or XLIFF files.\n" " May be specified repeatedly.\n\n" " --drop-translations\n" " Drop existing translations and reset the status to 'unfinished'.\n" @@ -101,10 +101,10 @@ static int usage(const QStringList &args) " --no-finished\n" " Drop finished messages.\n\n" " --locations {absolute|relative|none}\n" - " Override how source code references are saved in ts files.\n" + " Override how source code references are saved in TS files.\n" " Default is absolute.\n\n" " --no-ui-lines\n" - " Drop line numbers from references to .ui files.\n\n" + " Drop line numbers from references to UI files.\n\n" " --verbose\n" " be a bit more verbose\n\n" "Long options can be specified with only one leading dash, too.\n\n" diff --git a/tools/linguist/linguist/mainwindow.ui b/tools/linguist/linguist/mainwindow.ui index 4f66f31..613241b 100644 --- a/tools/linguist/linguist/mainwindow.ui +++ b/tools/linguist/linguist/mainwindow.ui @@ -747,7 +747,7 @@ Release As... - Create a Qt message file suitable for released applications from the current message file. The filename will automatically be determined from the name of the .ts file. + Create a Qt message file suitable for released applications from the current message file. The filename will automatically be determined from the name of the TS file. diff --git a/tools/linguist/lrelease/lrelease.1 b/tools/linguist/lrelease/lrelease.1 index 9e77504..8dd14b2 100644 --- a/tools/linguist/lrelease/lrelease.1 +++ b/tools/linguist/lrelease/lrelease.1 @@ -51,10 +51,10 @@ This page documents the tool for the Qt GUI toolkit. .B Lrelease reads a qmake/tmake project file (.pro file) and converts the -translation files (.ts files) specified in it into Qt message files -(.qm files) used by the application to translate. +translation files (TS files) specified in it into Qt message files +(QM files) used by the application to translate. .PP -The .qm file format is a compact binary format that provides +The QM file format is a compact binary format that provides extremely fast lookups for translations and that is used by Qt. .SH OPTIONS .TP @@ -62,7 +62,7 @@ extremely fast lookups for translations and that is used by Qt. Display the usage and exit. .TP .I "-compress" -Compress the .qm files. +Compress the QM files. .TP .I "-nounfinished" Do not include unfinished translations. @@ -72,7 +72,7 @@ If the translated text is the same as the source text, do not include the message. .TP .I "-silent" -Don't explain what is being done. +Do not explain what is being done. .TP .I "-version" Display the version of @@ -105,7 +105,7 @@ generated from gnomovision_dk.ts, gnomovision_fi.ts, gnomovision_no.ts and gnomovision_se.ts, respectively. .PP .B Lrelease -can also be invoked with a list of .ts files to convert: +can also be invoked with a list of TS files to convert: .PP .in +4 .nf diff --git a/tools/linguist/lrelease/main.cpp b/tools/linguist/lrelease/main.cpp index 5fbecac..aeed1f2 100644 --- a/tools/linguist/lrelease/main.cpp +++ b/tools/linguist/lrelease/main.cpp @@ -66,21 +66,21 @@ static void printUsage() " lrelease [options] project-file\n" " lrelease [options] ts-files [-qm qm-file]\n\n" "lrelease is part of Qt's Linguist tool chain. It can be used as a\n" - "stand-alone tool to convert XML based translations files in the .ts\n" - "format into the 'compiled' .qm format used by QTranslator objects.\n\n" + "stand-alone tool to convert XML-based translations files in the TS\n" + "format into the 'compiled' QM format used by QTranslator objects.\n\n" "Options:\n" " -help Display this information and exit\n" " -idbased\n" " Use IDs instead of source strings for message keying\n" " -compress\n" - " Compress the .qm files\n" + " Compress the QM files\n" " -nounfinished\n" " Do not include unfinished translations\n" " -removeidentical\n" " If the translated text is the same as\n" " the source text, do not include the message\n" " -silent\n" - " Don't explain what is being done\n" + " Do not explain what is being done\n" " -version\n" " Display the version of lrelease and exit\n" )); @@ -244,7 +244,7 @@ int main(int argc, char **argv) } } else { qWarning("error: lrelease encountered project file functionality that is currently not supported.\n" - "You might want to consider using .ts files as input instead of a project file.\n" + "You might want to consider using TS files as input instead of a project file.\n" "Try the following syntax:\n" " lrelease [options] ts-files [-qm qm-file]\n"); } diff --git a/tools/linguist/lupdate/lupdate.1 b/tools/linguist/lupdate/lupdate.1 index 68958b9..b37e7b3 100644 --- a/tools/linguist/lupdate/lupdate.1 +++ b/tools/linguist/lupdate/lupdate.1 @@ -52,12 +52,12 @@ tool for the Qt GUI toolkit. .B Lupdate reads a qmake/tmake project file (.pro file), finds the translatable strings in the specified source, header and interface files, and -updates the translation files (.ts files) specified in it. The +updates the translation files (TS files) specified in it. The translation files are given to the translator who uses .B Qt Linguist to read the files and insert the translations. .PP -The .ts file format is a simple human-readable XML format that can be +The TS file format is a simple human-readable XML format that can be used with version control systems if required. .PP .SH OPTIONS @@ -74,7 +74,7 @@ Default: 'ui,c,c++,cc,cpp,cxx,ch,h,h++,hh,hpp,hxx'. Display the usage and exit. .TP .I "-locations {absolute|relative|none}" -Specify/override how source code references are saved in ts files. +Specify/override how source code references are saved in TS files. Default is absolute. .TP .I "-no-obsolete" @@ -84,7 +84,7 @@ Drop all obsolete strings. Do not recursively scan the following directories. .TP .I "-no-sort" -Do not sort contexts in .ts files. +Do not sort contexts in TS files. .TP .I "-pluralonly" Only include plural form messages. @@ -97,7 +97,7 @@ file syntax but different file suffix Recursively scan the following directories. .TP .I "-silent" -Don't explain what is being done. +Do not explain what is being done. .TP .I "-source-language [_]" Specify/override the language of the source strings. Defaults to @@ -139,8 +139,8 @@ translations will be reused as far as possible, and translated strings that have vanished from the source files are marked obsolete. .PP .B lupdate -can also be invoked with a list of C++ source files, .ui files -and .ts files: +can also be invoked with a list of C++ source files, UI files +and TS files: .PP .in +4 .nf diff --git a/tools/linguist/lupdate/main.cpp b/tools/linguist/lupdate/main.cpp index 18c8932..c9250c6 100644 --- a/tools/linguist/lupdate/main.cpp +++ b/tools/linguist/lupdate/main.cpp @@ -103,7 +103,7 @@ static void printUsage() " -silent\n" " Do not explain what is being done.\n" " -no-sort\n" - " Do not sort contexts in .ts files.\n" + " Do not sort contexts in TS files.\n" " -no-recursive\n" " Do not recursively scan the following directories.\n" " -recursive\n" @@ -112,10 +112,10 @@ static void printUsage() " Additional location to look for include files.\n" " May be specified multiple times.\n" " -locations {absolute|relative|none}\n" - " Specify/override how source code references are saved in ts files.\n" + " Specify/override how source code references are saved in TS files.\n" " Default is absolute.\n" " -no-ui-lines\n" - " Do not record line numbers in references to .ui files.\n" + " Do not record line numbers in references to UI files.\n" " -disable-heuristic {sametext|similartext|number}\n" " Disable the named merge heuristic. Can be specified multiple times.\n" " -pro \n" diff --git a/tools/linguist/shared/qm.cpp b/tools/linguist/shared/qm.cpp index 05d8e12..9523fde 100644 --- a/tools/linguist/shared/qm.cpp +++ b/tools/linguist/shared/qm.cpp @@ -245,7 +245,7 @@ void Releaser::writeMessage(const ByteTranslatorMessage &msg, QDataStream &strea if (mode == SaveEverything) prefix = HashContextSourceTextComment; - // lrelease produces "wrong" .qm files for QByteArrays that are .isNull(). + // lrelease produces "wrong" QM files for QByteArrays that are .isNull(). switch (prefix) { default: case HashContextSourceTextComment: diff --git a/tools/linguist/shared/ts.dtd b/tools/linguist/shared/ts.dtd index ab77f64..4d2cdeb 100644 --- a/tools/linguist/shared/ts.dtd +++ b/tools/linguist/shared/ts.dtd @@ -34,7 +34,7 @@ version CDATA #IMPLIED sourcelanguage CDATA #IMPLIED language CDATA #IMPLIED> - + diff --git a/tools/qtconfig/paletteeditoradvanced.cpp b/tools/qtconfig/paletteeditoradvanced.cpp index 45f6a45..36cbd89 100644 --- a/tools/qtconfig/paletteeditoradvanced.cpp +++ b/tools/qtconfig/paletteeditoradvanced.cpp @@ -55,7 +55,7 @@ PaletteEditorAdvanced::PaletteEditorAdvanced( QWidget * parent, const char * name, bool modal, Qt::WindowFlags f ) : PaletteEditorAdvancedBase( parent, name, modal, f ), selectedPalette(0) { - // work around buggy ui file + // work around buggy UI file comboEffect->setEnabled(false); buttonEffect->setEnabled(false); onToggleBuildEffects(true); -- cgit v0.12 From 039c800f728054a56ae1584d269ee1ddadd1312f Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 6 Jul 2009 11:04:27 +0200 Subject: QHeaderView::sizeHint: small bug fix and refactor --- src/gui/itemviews/qheaderview.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp index 57e44c7..2419c18 100644 --- a/src/gui/itemviews/qheaderview.cpp +++ b/src/gui/itemviews/qheaderview.cpp @@ -524,12 +524,12 @@ QSize QHeaderView::sizeHint() const Q_D(const QHeaderView); if (d->cachedSizeHint.isValid()) return d->cachedSizeHint; - d->cachedSizeHint = QSize(0, 0); - d->executePostedLayout(); + d->cachedSizeHint = QSize(0, 0); //reinitialize the cached size hint + const int sectionCount = count(); // get size hint for the first n sections int i = 0; - for (int checked = 0; checked < 100 && i < d->sectionCount; ++i) { + for (int checked = 0; checked < 100 && i < sectionCount; ++i) { if (isSectionHidden(i)) continue; checked++; @@ -537,8 +537,8 @@ QSize QHeaderView::sizeHint() const d->cachedSizeHint = d->cachedSizeHint.expandedTo(hint); } // get size hint for the last n sections - i = qMax(i, d->sectionCount - 100 ); - for (int j = d->sectionCount - 1, checked = 0; j > i && checked < 100; --j) { + i = qMax(i, sectionCount - 100 ); + for (int j = sectionCount - 1, checked = 0; j >= i && checked < 100; --j) { if (isSectionHidden(j)) continue; checked++; -- cgit v0.12 From 14ed83f4e65b26cea12b128043c1c67c5489832d Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 6 Jul 2009 12:21:00 +0200 Subject: Phonon: Some work done on binary size removing foreach seems to help on Windows --- src/3rdparty/phonon/ds9/iodevicereader.cpp | 10 +---- src/3rdparty/phonon/ds9/videorenderer_soft.cpp | 32 ++++++---------- src/3rdparty/phonon/ds9/volumeeffect.cpp | 12 +----- src/3rdparty/phonon/phonon/audiooutput.cpp | 14 ++++--- src/3rdparty/phonon/phonon/backendcapabilities.cpp | 14 +++---- src/3rdparty/phonon/phonon/effect.cpp | 6 ++- src/3rdparty/phonon/phonon/effectwidget.cpp | 10 +++-- src/3rdparty/phonon/phonon/factory.cpp | 43 +++++++++++----------- src/3rdparty/phonon/phonon/medianode.cpp | 4 +- src/3rdparty/phonon/phonon/mediaobject.cpp | 12 +++--- .../phonon/phonon/objectdescriptionmodel.cpp | 4 +- .../phonon/phonon/objectdescriptionmodel.h | 8 ++-- src/3rdparty/phonon/phonon/path.cpp | 24 +++++++----- 13 files changed, 88 insertions(+), 105 deletions(-) diff --git a/src/3rdparty/phonon/ds9/iodevicereader.cpp b/src/3rdparty/phonon/ds9/iodevicereader.cpp index ec10278..2dff1fe 100644 --- a/src/3rdparty/phonon/ds9/iodevicereader.cpp +++ b/src/3rdparty/phonon/ds9/iodevicereader.cpp @@ -36,15 +36,7 @@ namespace Phonon //these mediatypes define a stream, its type will be autodetected by DirectShow static QVector getMediaTypes() { - AM_MEDIA_TYPE mt; - mt.majortype = MEDIATYPE_Stream; - mt.bFixedSizeSamples = TRUE; - mt.bTemporalCompression = FALSE; - mt.lSampleSize = 1; - mt.formattype = GUID_NULL; - mt.pUnk = 0; - mt.cbFormat = 0; - mt.pbFormat = 0; + AM_MEDIA_TYPE mt = { MEDIATYPE_Stream, MEDIASUBTYPE_NULL, TRUE, FALSE, 1, GUID_NULL, 0, 0, 0}; QVector ret; //normal auto-detect stream diff --git a/src/3rdparty/phonon/ds9/videorenderer_soft.cpp b/src/3rdparty/phonon/ds9/videorenderer_soft.cpp index dd6e076..2112267 100644 --- a/src/3rdparty/phonon/ds9/videorenderer_soft.cpp +++ b/src/3rdparty/phonon/ds9/videorenderer_soft.cpp @@ -63,9 +63,9 @@ along with this library. If not, see . static const char yv12ToRgb[] = "!!ARBfp1.0" "PARAM c[5] = { program.local[0..1]," -" { 1.164, 0, 1.596, 0.5 }," -" { 0.0625, 1.164, -0.391, -0.81300002 }," -" { 1.164, 2.0179999, 0 } };" +"{ 1.164, 0, 1.596, 0.5 }," +"{ 0.0625, 1.164, -0.391, -0.81300002 }," +"{ 1.164, 2.0179999, 0 } };" "TEMP R0;" "TEX R0.x, fragment.texcoord[0], texture[1], 2D;" "ADD R0.y, R0.x, -c[2].w;" @@ -89,11 +89,11 @@ static const char yv12ToRgb[] = "END"; static const char yuy2ToRgb[] = - "!!ARBfp1.0" +"!!ARBfp1.0" "PARAM c[5] = { program.local[0..1]," -" { 0.5, 2, 1, 0.0625 }," -" { 1.164, 0, 1.596, 2.0179999 }," -" { 1.164, -0.391, -0.81300002 } };" +"{ 0.5, 2, 1, 0.0625 }," +"{ 1.164, 0, 1.596, 2.0179999 }," +"{ 1.164, -0.391, -0.81300002 } };" "TEMP R0;" "TEMP R1;" "TEMP R2;" @@ -149,24 +149,16 @@ namespace Phonon { static const QVector videoMediaTypes() { - AM_MEDIA_TYPE mt; - qMemSet(&mt, 0, sizeof(AM_MEDIA_TYPE)); - mt.majortype = MEDIATYPE_Video; - - //we accept any video format - mt.formattype = GUID_NULL; - mt.cbFormat = 0; - mt.pbFormat = 0; + AM_MEDIA_TYPE mt = { MEDIATYPE_Video, MEDIASUBTYPE_YV12, 0, 0, 0, GUID_NULL, 0, 0, 0 }; QVector ret; - //we support YUV (YV12 and YUY2) and RGB32 - mt.subtype = MEDIASUBTYPE_YV12; - ret << mt; + //we add all the subtypes we support + ret << mt; //YV12 mt.subtype = MEDIASUBTYPE_YUY2; - ret << mt; + ret << mt; //YUY2 mt.subtype = MEDIASUBTYPE_RGB32; - ret << mt; + ret << mt; //RGB32 return ret; } diff --git a/src/3rdparty/phonon/ds9/volumeeffect.cpp b/src/3rdparty/phonon/ds9/volumeeffect.cpp index 2fd1afc..b9a5fce 100644 --- a/src/3rdparty/phonon/ds9/volumeeffect.cpp +++ b/src/3rdparty/phonon/ds9/volumeeffect.cpp @@ -68,17 +68,7 @@ namespace Phonon static const QVector audioMediaType() { QVector ret; - - AM_MEDIA_TYPE mt; - mt.majortype = MEDIATYPE_Audio; - mt.subtype = MEDIASUBTYPE_PCM; - mt.bFixedSizeSamples = 1; - mt.bTemporalCompression = 0; - mt.pUnk = 0; - mt.lSampleSize = 1; - mt.cbFormat = 0; - mt.pbFormat = 0; - mt.formattype = GUID_NULL; + AM_MEDIA_TYPE mt = { MEDIATYPE_Audio, MEDIASUBTYPE_PCM, 1, 0, 1, GUID_NULL, 0, 0, 0}; ret << mt; return ret; } diff --git a/src/3rdparty/phonon/phonon/audiooutput.cpp b/src/3rdparty/phonon/phonon/audiooutput.cpp index 752580a..00b2ebd 100644 --- a/src/3rdparty/phonon/phonon/audiooutput.cpp +++ b/src/3rdparty/phonon/phonon/audiooutput.cpp @@ -264,8 +264,8 @@ void AudioOutputPrivate::setupBackendObject() if (deviceList.isEmpty()) { return; } - foreach (int devIndex, deviceList) { - const AudioOutputDevice &dev = AudioOutputDevice::fromIndex(devIndex); + for (int i = 0; i < deviceList.count(); ++i) { + const AudioOutputDevice &dev = AudioOutputDevice::fromIndex(deviceList.at(i)); if (callSetOutputDevice(this, dev)) { handleAutomaticDeviceChange(dev, AudioOutputPrivate::FallbackChange); return; // found one that works @@ -305,8 +305,9 @@ void AudioOutputPrivate::_k_audioDeviceFailed() pDebug() << Q_FUNC_INFO; // outputDeviceIndex identifies a failing device // fall back in the preference list of output devices - QList deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices); - foreach (int devIndex, deviceList) { + const QList deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices); + for (int i = 0; i < deviceList.count(); ++i) { + const int devIndex = deviceList.at(i); // if it's the same device as the one that failed, ignore it if (device.index() != devIndex) { const AudioOutputDevice &info = AudioOutputDevice::fromIndex(devIndex); @@ -326,9 +327,10 @@ void AudioOutputPrivate::_k_deviceListChanged() { pDebug() << Q_FUNC_INFO; // let's see if there's a usable device higher in the preference list - QList deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings); + const QList deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings); DeviceChangeType changeType = HigherPreferenceChange; - foreach (int devIndex, deviceList) { + for (int i = 0; i < deviceList.count(); ++i) { + const int devIndex = deviceList.at(i); const AudioOutputDevice &info = AudioOutputDevice::fromIndex(devIndex); if (!info.property("available").toBool()) { if (device.index() == devIndex) { diff --git a/src/3rdparty/phonon/phonon/backendcapabilities.cpp b/src/3rdparty/phonon/phonon/backendcapabilities.cpp index 5dee6a0..62c9cc9 100644 --- a/src/3rdparty/phonon/phonon/backendcapabilities.cpp +++ b/src/3rdparty/phonon/phonon/backendcapabilities.cpp @@ -76,8 +76,8 @@ QList BackendCapabilities::availableAudioOutputDevices() { QList ret; const QList deviceIndexes = GlobalConfig().audioOutputDeviceListFor(Phonon::NoCategory); - foreach (int i, deviceIndexes) { - ret.append(AudioOutputDevice::fromIndex(i)); + for (int i = 0; i < deviceIndexes.count(); ++i) { + ret.append(AudioOutputDevice::fromIndex(deviceIndexes.at(i))); } return ret; } @@ -88,8 +88,8 @@ QList BackendCapabilities::availableAudioCaptureDevices() { QList ret; const QList deviceIndexes = GlobalConfig().audioCaptureDeviceListFor(Phonon::NoCategory); - foreach (int i, deviceIndexes) { - ret.append(AudioCaptureDevice::fromIndex(i)); + for (int i = 0; i < deviceIndexes.count(); ++i) { + ret.append(AudioCaptureDevice::fromIndex(deviceIndexes.at(i))); } return ret; } @@ -101,9 +101,9 @@ QList BackendCapabilities::availableAudioEffects() BackendInterface *backendIface = qobject_cast(Factory::backend()); QList ret; if (backendIface) { - QList deviceIndexes = backendIface->objectDescriptionIndexes(Phonon::EffectType); - foreach (int i, deviceIndexes) { - ret.append(EffectDescription::fromIndex(i)); + const QList deviceIndexes = backendIface->objectDescriptionIndexes(Phonon::EffectType); + for (int i = 0; i < deviceIndexes.count(); ++i) { + ret.append(EffectDescription::fromIndex(deviceIndexes.at(i))); } } return ret; diff --git a/src/3rdparty/phonon/phonon/effect.cpp b/src/3rdparty/phonon/phonon/effect.cpp index c125232..98662a5 100644 --- a/src/3rdparty/phonon/phonon/effect.cpp +++ b/src/3rdparty/phonon/phonon/effect.cpp @@ -107,7 +107,8 @@ bool EffectPrivate::aboutToDeleteBackendObject() { if (m_backendObject) { const QList parameters = pINTERFACE_CALL(parameters()); - foreach (const EffectParameter &p, parameters) { + for (int i = 0; i < parameters.count(); ++i) { + const EffectParameter &p = parameters.at(i); parameterValues[p] = pINTERFACE_CALL(parameterValue(p)); } } @@ -120,7 +121,8 @@ void EffectPrivate::setupBackendObject() // set up attributes const QList parameters = pINTERFACE_CALL(parameters()); - foreach (const EffectParameter &p, parameters) { + for (int i = 0; i < parameters.count(); ++i) { + const EffectParameter &p = parameters.at(i); pINTERFACE_CALL(setParameterValue(p, parameterValues[p])); } } diff --git a/src/3rdparty/phonon/phonon/effectwidget.cpp b/src/3rdparty/phonon/phonon/effectwidget.cpp index d5c6c81..99478f7 100644 --- a/src/3rdparty/phonon/phonon/effectwidget.cpp +++ b/src/3rdparty/phonon/phonon/effectwidget.cpp @@ -97,7 +97,8 @@ void EffectWidgetPrivate::autogenerateUi() Q_Q(EffectWidget); QVBoxLayout *mainLayout = new QVBoxLayout(q); mainLayout->setMargin(0); - foreach (const EffectParameter ¶, effect->parameters()) { + for (int i = 0; i < effect->parameters().count(); ++i) { + const EffectParameter ¶ = effect->parameters().at(i); QVariant value = effect->parameterValue(para); QHBoxLayout *pLayout = new QHBoxLayout; mainLayout->addLayout(pLayout); @@ -117,13 +118,14 @@ void EffectWidgetPrivate::autogenerateUi() control = cb; if (value.type() == QVariant::Int) { //value just defines the item index - foreach (const QVariant &item, para.possibleValues()) { - cb->addItem(item.toString()); + for (int i = 0; i < para.possibleValues().count(); ++i) { + cb->addItem(para.possibleValues().at(i).toString()); } cb->setCurrentIndex(value.toInt()); QObject::connect(cb, SIGNAL(currentIndexChanged(int)), q, SLOT(_k_setIntParameter(int))); } else { - foreach (const QVariant &item, para.possibleValues()) { + for (int i = 0; i < para.possibleValues().count(); ++i) { + const QVariant &item = para.possibleValues().at(i); cb->addItem(item.toString()); if (item == value) { cb->setCurrentIndex(cb->count() - 1); diff --git a/src/3rdparty/phonon/phonon/factory.cpp b/src/3rdparty/phonon/phonon/factory.cpp index 43c45ee..fef88f0 100644 --- a/src/3rdparty/phonon/phonon/factory.cpp +++ b/src/3rdparty/phonon/phonon/factory.cpp @@ -124,15 +124,18 @@ bool FactoryPrivate::createBackend() // could not load a backend through the platform plugin. Falling back to the default // (finding the first loadable backend). const QLatin1String suffix("/phonon_backend/"); - foreach (QString libPath, QCoreApplication::libraryPaths()) { - libPath += suffix; + const QStringList paths = QCoreApplication::libraryPaths(); + for (int i = 0; i < paths.count(); ++i) { + const QString libPath = paths.at(i) + suffix; const QDir dir(libPath); if (!dir.exists()) { pDebug() << Q_FUNC_INFO << dir.absolutePath() << "does not exist"; continue; } - foreach (const QString &pluginName, dir.entryList(QDir::Files)) { - QPluginLoader pluginLoader(libPath + pluginName); + + const QStringList files = dir.entryList(QDir::Files); + for (int i = 0; i < files.count(); ++i) { + QPluginLoader pluginLoader(libPath + files.at(i)); if (!pluginLoader.load()) { pDebug() << Q_FUNC_INFO << " load failed:" << pluginLoader.errorString(); @@ -183,14 +186,8 @@ FactoryPrivate::FactoryPrivate() FactoryPrivate::~FactoryPrivate() { - foreach (QObject *o, objects) { - MediaObject *m = qobject_cast(o); - if (m) { - m->stop(); - } - } - foreach (MediaNodePrivate *bp, mediaNodePrivateList) { - bp->deleteBackendObject(); + for (int i = 0; i < mediaNodePrivateList.count(); ++i) { + mediaNodePrivateList.at(i)->deleteBackendObject(); } if (objects.size() > 0) { pError() << "The backend objects are not deleted as was requested."; @@ -258,8 +255,8 @@ void Factory::deregisterFrontendObject(MediaNodePrivate *bp) void FactoryPrivate::phononBackendChanged() { if (m_backendObject) { - foreach (MediaNodePrivate *bp, mediaNodePrivateList) { - bp->deleteBackendObject(); + for (int i = 0; i < mediaNodePrivateList.count(); ++i) { + mediaNodePrivateList.at(i)->deleteBackendObject(); } if (objects.size() > 0) { pDebug() << "WARNING: we were asked to change the backend but the application did\n" @@ -268,8 +265,8 @@ void FactoryPrivate::phononBackendChanged() "backendswitching possible."; // in case there were objects deleted give 'em a chance to recreate // them now - foreach (MediaNodePrivate *bp, mediaNodePrivateList) { - bp->createBackendObject(); + for (int i = 0; i < mediaNodePrivateList.count(); ++i) { + mediaNodePrivateList.at(i)->createBackendObject(); } return; } @@ -277,8 +274,8 @@ void FactoryPrivate::phononBackendChanged() m_backendObject = 0; } createBackend(); - foreach (MediaNodePrivate *bp, mediaNodePrivateList) { - bp->createBackendObject(); + for (int i = 0; i < mediaNodePrivateList.count(); ++i) { + mediaNodePrivateList.at(i)->createBackendObject(); } emit backendChanged(); } @@ -362,15 +359,17 @@ PlatformPlugin *FactoryPrivate::platformPlugin() QStringList()) ); dir.setFilter(QDir::Files); + const QStringList libPaths = QCoreApplication::libraryPaths(); forever { - foreach (QString libPath, QCoreApplication::libraryPaths()) { - libPath += suffix; + for (int i = 0; i < libPaths.count(); ++i) { + const QString libPath = libPaths.at(i) + suffix; dir.setPath(libPath); if (!dir.exists()) { continue; } - foreach (const QString &pluginName, dir.entryList()) { - QPluginLoader pluginLoader(libPath + pluginName); + const QStringList files = dir.entryList(QDir::Files); + for (int i = 0; i < files.count(); ++i) { + QPluginLoader pluginLoader(libPath + files.at(i)); if (!pluginLoader.load()) { pDebug() << Q_FUNC_INFO << " platform plugin load failed:" << pluginLoader.errorString(); diff --git a/src/3rdparty/phonon/phonon/medianode.cpp b/src/3rdparty/phonon/phonon/medianode.cpp index 4693cb8..63fa2e3 100644 --- a/src/3rdparty/phonon/phonon/medianode.cpp +++ b/src/3rdparty/phonon/phonon/medianode.cpp @@ -67,8 +67,8 @@ bool MediaNode::isValid() const MediaNodePrivate::~MediaNodePrivate() { - foreach (MediaNodeDestructionHandler *handler, handlers) { - handler->phononObjectDestroyed(this); + for (int i = 0 ; i < handlers.count(); ++i) { + handlers.at(i)->phononObjectDestroyed(this); } Factory::deregisterFrontendObject(this); delete m_backendObject; diff --git a/src/3rdparty/phonon/phonon/mediaobject.cpp b/src/3rdparty/phonon/phonon/mediaobject.cpp index de5fbc8..10fefbd 100644 --- a/src/3rdparty/phonon/phonon/mediaobject.cpp +++ b/src/3rdparty/phonon/phonon/mediaobject.cpp @@ -300,15 +300,15 @@ void MediaObject::enqueue(const MediaSource &source) void MediaObject::enqueue(const QList &sources) { - foreach (const MediaSource &m, sources) { - enqueue(m); + for (int i = 0; i < sources.count(); ++i) { + enqueue(sources.at(i)); } } void MediaObject::enqueue(const QList &urls) { - foreach (const QUrl &url, urls) { - enqueue(url); + for (int i = 0; i < urls.count(); ++i) { + enqueue(urls.at(i)); } } @@ -502,8 +502,8 @@ void MediaObjectPrivate::setupBackendObject() } #ifndef QT_NO_PHONON_MEDIACONTROLLER - foreach (FrontendInterfacePrivate *f, interfaceList) { - f->_backendObjectChanged(); + for (int i = 0 ; i < interfaceList.count(); ++i) { + interfaceList.at(i)->_backendObjectChanged(); } #endif //QT_NO_PHONON_MEDIACONTROLLER diff --git a/src/3rdparty/phonon/phonon/objectdescriptionmodel.cpp b/src/3rdparty/phonon/phonon/objectdescriptionmodel.cpp index e989d0c..b67344f 100644 --- a/src/3rdparty/phonon/phonon/objectdescriptionmodel.cpp +++ b/src/3rdparty/phonon/phonon/objectdescriptionmodel.cpp @@ -321,8 +321,8 @@ bool ObjectDescriptionModelData::dropMimeData(ObjectDescriptionType type, const } } d->model->beginInsertRows(QModelIndex(), row, row + toInsert.size() - 1); - foreach (const QExplicitlySharedDataPointer &obj, toInsert) { - d->data.insert(row, obj); + for (int i = 0 ; i < toInsert.count(); ++i) { + d->data.insert(row, toInsert.at(i)); } d->model->endInsertRows(); return true; diff --git a/src/3rdparty/phonon/phonon/objectdescriptionmodel.h b/src/3rdparty/phonon/phonon/objectdescriptionmodel.h index 84dc0bb..ba3cb42 100644 --- a/src/3rdparty/phonon/phonon/objectdescriptionmodel.h +++ b/src/3rdparty/phonon/phonon/objectdescriptionmodel.h @@ -292,8 +292,8 @@ namespace Phonon */ inline void setModelData(const QList > &data) { //krazy:exclude=inline QList > list; - Q_FOREACH (const ObjectDescription &desc, data) { - list << desc.d; + for (int i = 0; i < data.count(); ++i) { + list += data.at(i).d; } d->setModelData(list); } @@ -307,8 +307,8 @@ namespace Phonon inline QList > modelData() const { //krazy:exclude=inline QList > ret; QList > list = d->modelData(); - Q_FOREACH (const QExplicitlySharedDataPointer &data, list) { - ret << ObjectDescription(data); + for (int i = 0; i < list.count(); ++i) { + ret << ObjectDescription(list.at(i)); } return ret; } diff --git a/src/3rdparty/phonon/phonon/path.cpp b/src/3rdparty/phonon/phonon/path.cpp index b46d30a..aec8d05 100644 --- a/src/3rdparty/phonon/phonon/path.cpp +++ b/src/3rdparty/phonon/phonon/path.cpp @@ -58,8 +58,8 @@ class ConnectionTransaction PathPrivate::~PathPrivate() { #ifndef QT_NO_PHONON_EFFECT - foreach (Effect *e, effects) { - e->k_ptr->removeDestructionHandler(this); + for (int i = 0; i < effects.count(); ++i) { + effects.at(i)->k_ptr->removeDestructionHandler(this); } delete effectsParent; #endif @@ -233,8 +233,8 @@ bool Path::disconnect() if (d->sourceNode) list << d->sourceNode->k_ptr->backendObject(); #ifndef QT_NO_PHONON_EFFECT - foreach(Effect *e, d->effects) { - list << e->k_ptr->backendObject(); + for (int i = 0; i < d->effects.count(); ++i) { + list << d->effects.at(i)->k_ptr->backendObject(); } #endif if (d->sinkNode) { @@ -260,8 +260,8 @@ bool Path::disconnect() d->sourceNode = 0; #ifndef QT_NO_PHONON_EFFECT - foreach(Effect *e, d->effects) { - e->k_ptr->removeDestructionHandler(d.data()); + for (int i = 0; i < d->effects.count(); ++i) { + d->effects.at(i)->k_ptr->removeDestructionHandler(d.data()); } d->effects.clear(); #endif @@ -292,11 +292,13 @@ MediaNode *Path::sink() const bool PathPrivate::executeTransaction( const QList &disconnections, const QList &connections) { QSet nodesForTransaction; - foreach(const QObjectPair &pair, disconnections) { + for (int i = 0; i < disconnections.count(); ++i) { + const QObjectPair &pair = disconnections.at(i); nodesForTransaction << pair.first; nodesForTransaction << pair.second; } - foreach(const QObjectPair &pair, connections) { + for (int i = 0; i < connections.count(); ++i) { + const QObjectPair &pair = connections.at(i); nodesForTransaction << pair.first; nodesForTransaction << pair.second; } @@ -338,7 +340,8 @@ bool PathPrivate::executeTransaction( const QList &disconnections, } //and now let's reconnect the nodes that were disconnected: rollback - foreach(const QObjectPair &pair, disconnections) { + for (int i = 0; i < disconnections.count(); ++i) { + const QObjectPair &pair = disconnections.at(i); bool success = backend->connectNodes(pair.first, pair.second); Q_ASSERT(success); //a failure here means it is impossible to reestablish the connection Q_UNUSED(success); @@ -417,7 +420,8 @@ void PathPrivate::phononObjectDestroyed(MediaNodePrivate *mediaNodePrivate) sinkNode = 0; } else { #ifndef QT_NO_PHONON_EFFECT - foreach (Effect *e, effects) { + for (int i = 0; i < effects.count(); ++i) { + Effect *e = effects.at(i); if (e->k_ptr == mediaNodePrivate) { removeEffect(e); } -- cgit v0.12 From bf51ca62d4d5c5df5aa8d3c09007eb1c44d7d710 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 6 Jul 2009 14:17:04 +0200 Subject: Phonon: take advantage of more modern compiler to initialize struct This was not supported before by MSVC6 and MSVC2002 --- src/3rdparty/phonon/ds9/fakesource.cpp | 34 ++++----------------- src/3rdparty/phonon/ds9/iodevicereader.cpp | 1 - src/3rdparty/phonon/ds9/qaudiocdreader.cpp | 49 ++++++++++-------------------- src/3rdparty/phonon/ds9/qpin.cpp | 23 +++----------- 4 files changed, 27 insertions(+), 80 deletions(-) diff --git a/src/3rdparty/phonon/ds9/fakesource.cpp b/src/3rdparty/phonon/ds9/fakesource.cpp index 9a61a2e..a4d4640 100644 --- a/src/3rdparty/phonon/ds9/fakesource.cpp +++ b/src/3rdparty/phonon/ds9/fakesource.cpp @@ -29,8 +29,10 @@ namespace Phonon namespace DS9 { static WAVEFORMATEX g_defaultWaveFormat = {WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0}; - static BITMAPINFOHEADER g_defautBitmapHeader = { sizeof(BITMAPINFOHEADER), 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}; - static VIDEOINFOHEADER2 g_defaultVideoInfo = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + static VIDEOINFOHEADER2 g_defaultVideoInfo = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0, 0, 0, 0, {sizeof(BITMAPINFOHEADER), 1, 1, 1, 0, 0, 0, 0, 0, 0, 0} }; + + static const AM_MEDIA_TYPE g_fakeAudioType = {MEDIATYPE_Audio, MEDIASUBTYPE_PCM, 0, 0, 2, FORMAT_WaveFormatEx, 0, sizeof(WAVEFORMATEX), reinterpret_cast(&g_defaultWaveFormat)}; + static const AM_MEDIA_TYPE g_fakeVideoType = {MEDIATYPE_Video, MEDIASUBTYPE_RGB32, TRUE, FALSE, 0, FORMAT_VideoInfo2, 0, sizeof(VIDEOINFOHEADER2), reinterpret_cast(&g_defaultVideoInfo)}; class FakePin : public QPin { @@ -128,36 +130,12 @@ namespace Phonon void FakeSource::createFakeAudioPin() { - AM_MEDIA_TYPE mt; - qMemSet(&mt, 0, sizeof(AM_MEDIA_TYPE)); - mt.majortype = MEDIATYPE_Audio; - mt.subtype = MEDIASUBTYPE_PCM; - mt.formattype = FORMAT_WaveFormatEx; - mt.lSampleSize = 2; - - //fake the format (stereo 44.1 khz stereo 16 bits) - mt.cbFormat = sizeof(WAVEFORMATEX); - mt.pbFormat = reinterpret_cast(&g_defaultWaveFormat); - - new FakePin(this, mt); + new FakePin(this, g_fakeAudioType); } void FakeSource::createFakeVideoPin() { - AM_MEDIA_TYPE mt; - qMemSet(&mt, 0, sizeof(AM_MEDIA_TYPE)); - mt.majortype = MEDIATYPE_Video; - mt.subtype = MEDIASUBTYPE_RGB32; - mt.formattype = FORMAT_VideoInfo2; - mt.bFixedSizeSamples = 1; - - g_defaultVideoInfo.bmiHeader = g_defautBitmapHeader; - - //fake the format - mt.cbFormat = sizeof(VIDEOINFOHEADER2); - mt.pbFormat = reinterpret_cast(&g_defaultVideoInfo); - - new FakePin(this, mt); + new FakePin(this, g_fakeVideoType); } } diff --git a/src/3rdparty/phonon/ds9/iodevicereader.cpp b/src/3rdparty/phonon/ds9/iodevicereader.cpp index 2dff1fe..38c983b 100644 --- a/src/3rdparty/phonon/ds9/iodevicereader.cpp +++ b/src/3rdparty/phonon/ds9/iodevicereader.cpp @@ -40,7 +40,6 @@ namespace Phonon QVector ret; //normal auto-detect stream - mt.subtype = MEDIASUBTYPE_NULL; ret << mt; //AVI stream mt.subtype = MEDIASUBTYPE_Avi; diff --git a/src/3rdparty/phonon/ds9/qaudiocdreader.cpp b/src/3rdparty/phonon/ds9/qaudiocdreader.cpp index d5bdce2..6d0f335 100644 --- a/src/3rdparty/phonon/ds9/qaudiocdreader.cpp +++ b/src/3rdparty/phonon/ds9/qaudiocdreader.cpp @@ -103,8 +103,8 @@ namespace Phonon private: HANDLE m_cddrive; - CDROM_TOC *m_toc; - WaveStructure *m_waveHeader; + CDROM_TOC m_toc; + WaveStructure m_waveHeader; qint64 m_trackAddress; }; @@ -112,19 +112,8 @@ namespace Phonon #define SECTOR_SIZE 2352 #define NB_SECTORS_READ 20 - static AM_MEDIA_TYPE getAudioCDMediaType() - { - AM_MEDIA_TYPE mt; - qMemSet(&mt, 0, sizeof(AM_MEDIA_TYPE)); - mt.majortype = MEDIATYPE_Stream; - mt.subtype = MEDIASUBTYPE_WAVE; - mt.bFixedSizeSamples = TRUE; - mt.bTemporalCompression = FALSE; - mt.lSampleSize = 1; - mt.formattype = GUID_NULL; - return mt; - } - + static const AM_MEDIA_TYPE audioCDMediaType = { MEDIATYPE_Stream, MEDIASUBTYPE_WAVE, TRUE, FALSE, 1, GUID_NULL, 0, 0, 0}; + int addressToSectors(UCHAR address[4]) { return ((address[0] * 60 + address[1]) * 60 + address[2]) * 75 + address[3] - 150; @@ -141,11 +130,8 @@ namespace Phonon } - QAudioCDReader::QAudioCDReader(QBaseFilter *parent, QChar drive) : QAsyncReader(parent, QVector() << getAudioCDMediaType()) + QAudioCDReader::QAudioCDReader(QBaseFilter *parent, QChar drive) : QAsyncReader(parent, QVector() << audioCDMediaType) { - m_toc = new CDROM_TOC; - m_waveHeader = new WaveStructure; - //now open the cd-drive QString path; if (drive.isNull()) { @@ -156,31 +142,28 @@ namespace Phonon m_cddrive = ::CreateFile((const wchar_t *)path.utf16(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - qMemSet(m_toc, 0, sizeof(CDROM_TOC)); + qMemSet(&m_toc, 0, sizeof(CDROM_TOC)); //read the TOC DWORD bytesRead = 0; - bool tocRead = ::DeviceIoControl(m_cddrive, IOCTL_CDROM_READ_TOC, 0, 0, m_toc, sizeof(CDROM_TOC), &bytesRead, 0); + bool tocRead = ::DeviceIoControl(m_cddrive, IOCTL_CDROM_READ_TOC, 0, 0, &m_toc, sizeof(CDROM_TOC), &bytesRead, 0); if (!tocRead) { qWarning("unable to load the TOC from the CD"); return; } - m_trackAddress = addressToSectors(m_toc->TrackData[0].Address); - const qint32 nbSectorsToRead = (addressToSectors(m_toc->TrackData[m_toc->LastTrack + 1 - m_toc->FirstTrack].Address) + m_trackAddress = addressToSectors(m_toc.TrackData[0].Address); + const qint32 nbSectorsToRead = (addressToSectors(m_toc.TrackData[m_toc.LastTrack + 1 - m_toc.FirstTrack].Address) - m_trackAddress); const qint32 dataLength = nbSectorsToRead * SECTOR_SIZE; - m_waveHeader->chunksize = 4 + (8 + m_waveHeader->chunksize2) + (8 + dataLength); - m_waveHeader->dataLength = dataLength; + m_waveHeader.chunksize = 4 + (8 + m_waveHeader.chunksize2) + (8 + dataLength); + m_waveHeader.dataLength = dataLength; } QAudioCDReader::~QAudioCDReader() { ::CloseHandle(m_cddrive); - delete m_toc; - delete m_waveHeader; - } STDMETHODIMP_(ULONG) QAudioCDReader::AddRef() @@ -196,7 +179,7 @@ namespace Phonon STDMETHODIMP QAudioCDReader::Length(LONGLONG *total,LONGLONG *available) { - const LONGLONG length = sizeof(WaveStructure) + m_waveHeader->dataLength; + const LONGLONG length = sizeof(WaveStructure) + m_waveHeader.dataLength; if (total) { *total = length; } @@ -235,11 +218,11 @@ namespace Phonon if (pos < sizeof(WaveStructure)) { //we first copy the content of the structure nbRead = qMin(LONG(sizeof(WaveStructure) - pos), length); - qMemCopy(buffer, reinterpret_cast(m_waveHeader) + pos, nbRead); + qMemCopy(buffer, reinterpret_cast(&m_waveHeader) + pos, nbRead); } const LONGLONG posInTrack = pos - sizeof(WaveStructure) + nbRead; - const int bytesLeft = qMin(m_waveHeader->dataLength - posInTrack, LONGLONG(length - nbRead)); + const int bytesLeft = qMin(m_waveHeader.dataLength - posInTrack, LONGLONG(length - nbRead)); if (bytesLeft > 0) { @@ -294,8 +277,8 @@ namespace Phonon { QList ret; ret << 0; - for(int i = m_toc->FirstTrack; i <= m_toc->LastTrack ; ++i) { - const uchar *address = m_toc->TrackData[i].Address; + for(int i = m_toc.FirstTrack; i <= m_toc.LastTrack ; ++i) { + const uchar *address = m_toc.TrackData[i].Address; ret << ((address[0] * 60 + address[1]) * 60 + address[2]) * 1000 + address[3]*1000/75 - 2000; } diff --git a/src/3rdparty/phonon/ds9/qpin.cpp b/src/3rdparty/phonon/ds9/qpin.cpp index 37fe48d..5f335ac 100644 --- a/src/3rdparty/phonon/ds9/qpin.cpp +++ b/src/3rdparty/phonon/ds9/qpin.cpp @@ -28,20 +28,7 @@ namespace Phonon namespace DS9 { - static const AM_MEDIA_TYPE defaultMediaType() - { - AM_MEDIA_TYPE ret; - ret.majortype = MEDIATYPE_NULL; - ret.subtype = MEDIASUBTYPE_NULL; - ret.bFixedSizeSamples = TRUE; - ret.bTemporalCompression = FALSE; - ret.lSampleSize = 1; - ret.formattype = GUID_NULL; - ret.pUnk = 0; - ret.cbFormat = 0; - ret.pbFormat = 0; - return ret; - } + static const AM_MEDIA_TYPE defaultMediaType = { MEDIATYPE_NULL, MEDIASUBTYPE_NULL, TRUE, FALSE, 1, GUID_NULL, 0, 0, 0}; class QEnumMediaTypes : public IEnumMediaTypes { @@ -159,7 +146,7 @@ namespace Phonon QPin::QPin(QBaseFilter *parent, PIN_DIRECTION dir, const QVector &mt) : m_memAlloc(0), m_parent(parent), m_refCount(1), m_connected(0), - m_direction(dir), m_mediaTypes(mt), m_connectedType(defaultMediaType()), + m_direction(dir), m_mediaTypes(mt), m_connectedType(defaultMediaType), m_flushing(false) { Q_ASSERT(m_parent); @@ -273,7 +260,7 @@ namespace Phonon if (FAILED(hr)) { setConnected(0); - setConnectedType(defaultMediaType()); + setConnectedType(defaultMediaType); } else { ComPointer input(pin, IID_IMemInputPin); if (input) { @@ -315,7 +302,7 @@ namespace Phonon } setConnected(0); - setConnectedType(defaultMediaType()); + setConnectedType(defaultMediaType); if (m_direction == PINDIR_INPUT) { setMemoryAllocator(0); } @@ -470,7 +457,7 @@ namespace Phonon freeMediaType(type); return S_OK; } else { - setConnectedType(defaultMediaType()); + setConnectedType(defaultMediaType); freeMediaType(type); } } -- cgit v0.12 From 8a72074b0ab146942512b37439ffc8618e3f7d06 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 6 Jul 2009 15:13:07 +0200 Subject: doc: Included note about the effect of WA_NoMousePropagation. Task-number: 162945 --- src/gui/kernel/qevent.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index bef7ee1..4fc3643 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -114,6 +114,10 @@ QInputEvent::~QInputEvent() propagated up the parent widget chain until a widget accepts it with accept(), or an event filter consumes it. + \note If a mouse event is propagated to a \l{QWidget}{widget} for + which Qt::WA_NoMousePropagation has been set, that mouse event + will not be propagated further up the parent widget chain. + The state of the keyboard modifier keys can be found by calling the \l{QInputEvent::modifiers()}{modifiers()} function, inhertied from QInputEvent. -- cgit v0.12 From ba25bdcb9122d45ccdd06f281a5f49999eaff089 Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Mon, 6 Jul 2009 15:33:10 +0200 Subject: Doc - beautified some of the existing sentences in Part 6 Reviewed-By: TrustMe --- doc/src/tutorials/addressbook.qdoc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/src/tutorials/addressbook.qdoc b/doc/src/tutorials/addressbook.qdoc index 33832da..95394eb 100644 --- a/doc/src/tutorials/addressbook.qdoc +++ b/doc/src/tutorials/addressbook.qdoc @@ -876,7 +876,7 @@ \image addressbook-tutorial-part6-save.png - If \c fileName is not empty, we create a QFile object, \c file with + If \c fileName is not empty, we create a QFile object, \c file, with \c fileName. QFile works with QDataStream as QFile is a QIODevice. Next, we attempt to open the file in \l{QIODevice::}{WriteOnly} mode. @@ -906,18 +906,18 @@ \image addressbook-tutorial-part6-load.png If \c fileName is not empty, again, we use a QFile object, \c file, and - attempt to open it in \l{QIODevice::}{ReadOnly} mode. In a similar way - to our implementation of \c saveToFile(), if this attempt is unsuccessful, - we display a QMessageBox to inform the user. + attempt to open it in \l{QIODevice::}{ReadOnly} mode. Similar to our + implementation of \c saveToFile(), if this attempt is unsuccessful, we + display a QMessageBox to inform the user. \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part2 Otherwise, we instantiate a QDataStream object, \c in, set its version as above and read the serialized data into the \c contacts data structure. - Note that we empty \c contacts before reading data into it to simplify the - file reading process. A more advanced method would be to read the contacts - into temporary QMap object, and copy only the contacts that do not already - exist in \c contacts. + The \c contacts object is emptied before data is read into it to simplify + the file reading process. A more advanced method would be to read the + contacts into a temporary QMap object, and copy over non-duplicate contacts + into \c contacts. \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part3 -- cgit v0.12 From d000c29f9039dab6cd46bb3a12df828d5f9354a7 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 6 Jul 2009 16:12:36 +0200 Subject: QMenu: scrolling in menus was broken --- src/gui/widgets/qmenu.cpp | 34 +++++++++++++++++++++------------- src/gui/widgets/qmenu_p.h | 6 +++--- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index d3f5bc5..ef892d7 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -257,7 +257,6 @@ void QMenuPrivate::updateActionRects() const //let the style modify the above size.. QStyleOptionMenuItem opt; q->initStyleOption(&opt, action); - opt.rect = q->rect(); const QFontMetrics &fm = opt.fontMetrics; QSize sz; @@ -757,9 +756,19 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc } //actually update flags - scroll->scrollOffset = newOffset; - if (scroll->scrollOffset > 0) - scroll->scrollOffset = 0; + const int delta = qMin(0, newOffset) - scroll->scrollOffset; //make sure the new offset is always negative + if (!itemsDirty && delta) { + //we've scrolled so we need to update the action rects + for (int i = 0; i < actionRects.count(); ++i) { + QRect ¤t = actionRects[i]; + current.moveTop(current.top() + delta); + + //we need to update the widgets geometry + if (QWidget *w = widgetItems.at(i)) + w->setGeometry(current); + } + } + scroll->scrollOffset += delta; scroll->scrollFlags = newScrollFlags; if (active) setCurrentAction(action); @@ -875,12 +884,10 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e) } } if (isScroll) { - if (!scroll->scrollTimer) - scroll->scrollTimer = new QBasicTimer; - scroll->scrollTimer->start(50, q); + scroll->scrollTimer.start(50, q); return true; - } else if (scroll->scrollTimer && scroll->scrollTimer->isActive()) { - scroll->scrollTimer->stop(); + } else { + scroll->scrollTimer.stop(); } } @@ -2054,6 +2061,8 @@ void QMenu::hideEvent(QHideEvent *) d->hasHadMouse = false; d->causedPopup.widget = 0; d->causedPopup.action = 0; + if (d->scroll) + d->scroll->scrollTimer.stop(); //make sure the timer stops } /*! @@ -2499,8 +2508,7 @@ void QMenu::keyPressEvent(QKeyEvent *e) } if (nextAction) { if (d->scroll && scroll_loc != QMenuPrivate::QMenuScroller::ScrollStay) { - if (d->scroll->scrollTimer) - d->scroll->scrollTimer->stop(); + d->scroll->scrollTimer.stop(); d->scrollMenu(nextAction, scroll_loc); } d->setCurrentAction(nextAction, /*popup*/-1, QMenuPrivate::SelectedFromKeyboard); @@ -2761,10 +2769,10 @@ void QMenu::timerEvent(QTimerEvent *e) { Q_D(QMenu); - if (d->scroll && d->scroll->scrollTimer && d->scroll->scrollTimer->timerId() == e->timerId()) { + if (d->scroll && d->scroll->scrollTimer.timerId() == e->timerId()) { d->scrollMenu((QMenuPrivate::QMenuScroller::ScrollDirection)d->scroll->scrollDirection); if (d->scroll->scrollFlags == QMenuPrivate::QMenuScroller::ScrollNone) - d->scroll->scrollTimer->stop(); + d->scroll->scrollTimer.stop(); } else if(QMenuPrivate::menuDelayTimer.timerId() == e->timerId()) { QMenuPrivate::menuDelayTimer.stop(); internalDelayedPopup(); diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h index 50a9f2f..461d435 100644 --- a/src/gui/widgets/qmenu_p.h +++ b/src/gui/widgets/qmenu_p.h @@ -189,10 +189,10 @@ public: enum ScrollDirection { ScrollNone=0, ScrollUp=0x01, ScrollDown=0x02 }; uint scrollFlags : 2, scrollDirection : 2; int scrollOffset; - QBasicTimer *scrollTimer; + QBasicTimer scrollTimer; - QMenuScroller() : scrollFlags(ScrollNone), scrollDirection(ScrollNone), scrollOffset(0), scrollTimer(0) { } - ~QMenuScroller() { delete scrollTimer; } + QMenuScroller() : scrollFlags(ScrollNone), scrollDirection(ScrollNone), scrollOffset(0) { } + ~QMenuScroller() { } } *scroll; void scrollMenu(QMenuScroller::ScrollLocation location, bool active=false); void scrollMenu(QMenuScroller::ScrollDirection direction, bool page=false, bool active=false); -- cgit v0.12 From 134dad4c6a996045397098498eaf0afca889b6f9 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 6 Jul 2009 16:48:15 +0200 Subject: QMenu: the scroller now takes the qapp's global strut into account Task-number: 257118 --- src/gui/widgets/qmenu.cpp | 48 +++++++++++++++++++++++------------------------ src/gui/widgets/qmenu_p.h | 2 ++ 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index ef892d7..af9ddf5 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -163,6 +163,12 @@ void QMenuPrivate::init() } } +int QMenuPrivate::scrollerHeight() const +{ + Q_Q(const QMenu); + return qMax(QApplication::globalStrut().height(), q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q)); +} + //Windows and KDE allows menus to cover the taskbar, while GNOME and Mac don't QRect QMenuPrivate::popupGeometry(int screen) const { @@ -483,14 +489,13 @@ void QMenuPrivate::setFirstActionActive() { Q_Q(QMenu); updateActionRects(); - const int scrollerHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q); for(int i = 0, saccum = 0; i < actions.count(); i++) { const QRect &rect = actionRects.at(i); if (rect.isNull()) continue; if (scroll && scroll->scrollFlags & QMenuScroller::ScrollUp) { saccum -= rect.height(); - if (saccum > scroll->scrollOffset-scrollerHeight) + if (saccum > scroll->scrollOffset - scrollerHeight()) continue; } QAction *act = actions.at(i); @@ -668,16 +673,14 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc return; updateActionRects(); int newOffset = 0; - const int scrollHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q); - const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollHeight : 0; - const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollHeight : 0; + const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollerHeight() : 0; + const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollerHeight() : 0; const int vmargin = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q); const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q); if (location == QMenuScroller::ScrollTop) { for(int i = 0, saccum = 0; i < actions.count(); i++) { - QAction *act = actions.at(i); - if (act == action) { + if (actions.at(i) == action) { newOffset = topScroll - saccum; break; } @@ -685,9 +688,8 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc } } else { for(int i = 0, saccum = 0; i < actions.count(); i++) { - QAction *act = actions.at(i); saccum += actionRects.at(i).height(); - if (act == action) { + if (actions.at(i) == action) { if (location == QMenuScroller::ScrollCenter) newOffset = ((q->height() / 2) - botScroll) - (saccum - topScroll); else @@ -820,9 +822,8 @@ void QMenuPrivate::scrollMenu(QMenuScroller::ScrollDirection direction, bool pag if (!scroll || !(scroll->scrollFlags & direction)) //not really possible... return; updateActionRects(); - const int scrollHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q); - const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollHeight : 0; - const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollHeight : 0; + const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollerHeight() : 0; + const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollerHeight() : 0; const int vmargin = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q); const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q); const int offset = topScroll ? topScroll-vmargin : 0; @@ -869,13 +870,12 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e) if (scroll && !activeMenu) { //let the scroller "steal" the event bool isScroll = false; if (pos.x() >= 0 && pos.x() < q->width()) { - const int scrollerHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q); for(int dir = QMenuScroller::ScrollUp; dir <= QMenuScroller::ScrollDown; dir = dir << 1) { if (scroll->scrollFlags & dir) { if (dir == QMenuScroller::ScrollUp) - isScroll = (pos.y() <= scrollerHeight); + isScroll = (pos.y() <= scrollerHeight()); else if (dir == QMenuScroller::ScrollDown) - isScroll = (pos.y() >= q->height()-scrollerHeight); + isScroll = (pos.y() >= q->height() - scrollerHeight()); if (isScroll) { scroll->scrollDirection = dir; break; @@ -894,7 +894,7 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e) if (tearoff) { //let the tear off thingie "steal" the event.. QRect tearRect(0, 0, q->width(), q->style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, q)); if (scroll && scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp) - tearRect.translate(0, q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q)); + tearRect.translate(0, scrollerHeight()); q->update(tearRect); if (tearRect.contains(pos) && hasMouseMoved(e->globalPos())) { setCurrentAction(0); @@ -2104,18 +2104,17 @@ void QMenu::paintEvent(QPaintEvent *e) const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, this); //draw the scroller regions.. if (d->scroll) { - const int scrollerHeight = style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this); menuOpt.menuItemType = QStyleOptionMenuItem::Scroller; menuOpt.state |= QStyle::State_Enabled; if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp) { - menuOpt.rect.setRect(fw, fw, width() - (fw * 2), scrollerHeight); + menuOpt.rect.setRect(fw, fw, width() - (fw * 2), d->scrollerHeight()); emptyArea -= QRegion(menuOpt.rect); p.setClipRect(menuOpt.rect); style()->drawControl(QStyle::CE_MenuScroller, &menuOpt, &p, this); } if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown) { - menuOpt.rect.setRect(fw, height() - scrollerHeight - fw, width() - (fw * 2), - scrollerHeight); + menuOpt.rect.setRect(fw, height() - d->scrollerHeight() - fw, width() - (fw * 2), + d->scrollerHeight()); emptyArea -= QRegion(menuOpt.rect); menuOpt.state |= QStyle::State_DownArrow; p.setClipRect(menuOpt.rect); @@ -2128,7 +2127,7 @@ void QMenu::paintEvent(QPaintEvent *e) menuOpt.rect.setRect(fw, fw, width() - (fw * 2), style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this)); if (d->scroll && d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp) - menuOpt.rect.translate(0, style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this)); + menuOpt.rect.translate(0, d->scrollerHeight()); emptyArea -= QRegion(menuOpt.rect); p.setClipRect(menuOpt.rect); menuOpt.state = QStyle::State_None; @@ -2458,7 +2457,7 @@ void QMenu::keyPressEvent(QKeyEvent *e) continue; nextAction = next; if (d->scroll && (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)) { - int topVisible = style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this); + int topVisible = d->scrollerHeight(); if (d->tearoff) topVisible += style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this); if (((y + d->scroll->scrollOffset) - topVisible) <= d->actionRects.at(next_i).height()) @@ -2489,10 +2488,9 @@ void QMenu::keyPressEvent(QKeyEvent *e) continue; nextAction = next; if (d->scroll && (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown)) { - const int scrollerHeight = style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, this); - int bottomVisible = height()-scrollerHeight; + int bottomVisible = height() - d->scrollerHeight(); if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp) - bottomVisible -= scrollerHeight; + bottomVisible -= d->scrollerHeight(); if (d->tearoff) bottomVisible -= style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this); if ((y + d->scroll->scrollOffset + d->actionRects.at(next_i).height()) > bottomVisible) diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h index 461d435..4e428fe 100644 --- a/src/gui/widgets/qmenu_p.h +++ b/src/gui/widgets/qmenu_p.h @@ -151,6 +151,8 @@ public: } void init(); + int scrollerHeight() const; + //item calculations mutable uint itemsDirty : 1; mutable uint maxIconWidth, tabWidth; -- cgit v0.12 From 4e31ccad1cfb9df0d624d5c39d7906a75b4fc2d0 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 7 Jul 2009 10:01:21 +0200 Subject: QFontComboBox: used to emit currentFontChanged twice when setting it. Setting the current font would change the current font and then it would try to select the right model index and get the font only from the text of the combobox. This was resetting the point size of the font, resulting in emitting the signal a second time. In the case of the user, it was also causing signals to be called in a loop. Task-number: 229731 --- src/gui/widgets/qfontcombobox.cpp | 2 +- tests/auto/qfontcombobox/tst_qfontcombobox.cpp | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/gui/widgets/qfontcombobox.cpp b/src/gui/widgets/qfontcombobox.cpp index 9660399..f87ccd3 100644 --- a/src/gui/widgets/qfontcombobox.cpp +++ b/src/gui/widgets/qfontcombobox.cpp @@ -263,7 +263,7 @@ void QFontComboBoxPrivate::_q_currentChanged(const QString &text) { Q_Q(QFontComboBox); QFont newFont(text); - if (currentFont != newFont) { + if (currentFont.family() != newFont.family()) { currentFont = newFont; emit q->currentFontChanged(currentFont); } diff --git a/tests/auto/qfontcombobox/tst_qfontcombobox.cpp b/tests/auto/qfontcombobox/tst_qfontcombobox.cpp index 62bfdf7..e2515ae 100644 --- a/tests/auto/qfontcombobox/tst_qfontcombobox.cpp +++ b/tests/auto/qfontcombobox/tst_qfontcombobox.cpp @@ -122,7 +122,10 @@ void tst_QFontComboBox::currentFont_data() { QTest::addColumn("currentFont"); // Normalize the names - QTest::newRow("default") << QFont(QFontInfo(QFont()).family()); + QFont defaultFont; + QTest::newRow("default") << defaultFont; + defaultFont.setPointSize(defaultFont.pointSize() + 10); + QTest::newRow("default") << defaultFont; QFontDatabase db; QStringList list = db.families(); for (int i = 0; i < list.count(); ++i) { @@ -141,6 +144,7 @@ void tst_QFontComboBox::currentFont() QFont oldCurrentFont = box.currentFont(); box.setCurrentFont(currentFont); + QCOMPARE(box.currentFont(), currentFont); QString boxFontFamily = QFontInfo(box.currentFont()).family(); QRegExp foundry(" \\[.*\\]"); if (!currentFont.family().contains(foundry)) -- cgit v0.12 From 07ba75cb8031b844484901bef903fb055cc0b182 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 7 Jul 2009 11:12:39 +0200 Subject: QToolBar: better management of positions when hiding/unhiding The toolbar that one would unhide could be packed at the right of the screen. This was because the last toolbar always has a size that fills the space. So if you unhide a toolbar situated after this one, it got "compressed". --- src/gui/widgets/qtoolbararealayout.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/gui/widgets/qtoolbararealayout.cpp b/src/gui/widgets/qtoolbararealayout.cpp index 0c11700..b4a0ef0 100644 --- a/src/gui/widgets/qtoolbararealayout.cpp +++ b/src/gui/widgets/qtoolbararealayout.cpp @@ -156,21 +156,15 @@ void QToolBarAreaLayoutLine::fitLayout() if (item.skip()) continue; - QToolBarLayout *tblayout = qobject_cast(item.widgetItem->widget()->layout()); - if (tblayout) + if (QToolBarLayout *tblayout = qobject_cast(item.widgetItem->widget()->layout())) tblayout->checkUsePopupMenu(); - int itemMin = pick(o, item.minimumSize()); - int itemHint = pick(o, item.sizeHint()); - //we ensure the extraspace is not too low - item.size = qMax(item.size, itemHint); - if (item.preferredSize > 0) { - //preferredSize would be the default size - item.size = item.preferredSize; - } + const int itemMin = pick(o, item.minimumSize()); + //preferredSize is the default if it is set, otherwise, we take the sizehint + item.size = item.preferredSize > 0 ? item.preferredSize : pick(o, item.sizeHint()); //the extraspace is the space above the item minimum sizehint - int extraSpace = qMin(item.size - itemMin, extra); + const int extraSpace = qMin(item.size - itemMin, extra); item.size = itemMin + extraSpace; //that is the real size extra -= extraSpace; -- cgit v0.12 From a28dc778305cf67830f15119b29c5a77754a8c18 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 7 Jul 2009 11:14:26 +0200 Subject: QMenu: with tearoff handle, it would reserve the space for it twice sizeHint is now fixed --- src/gui/widgets/qmenu.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index af9ddf5..35b68b4 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -1355,8 +1355,7 @@ QMenu::~QMenu() if (d->eventLoop) d->eventLoop->exit(); - if (d->tornPopup) - d->tornPopup->close(); + hideTearOffMenu(); } /*! @@ -1567,8 +1566,8 @@ void QMenu::setTearOffEnabled(bool b) Q_D(QMenu); if (d->tearoff == b) return; - if (!b && d->tornPopup) - d->tornPopup->close(); + if (!b) + hideTearOffMenu(); d->tearoff = b; d->itemsDirty = true; @@ -1603,8 +1602,8 @@ bool QMenu::isTearOffMenuVisible() const */ void QMenu::hideTearOffMenu() { - if (d_func()->tornPopup) - d_func()->tornPopup->close(); + if (QWidget *w = d_func()->tornPopup) + w->close(); } @@ -1719,8 +1718,6 @@ QSize QMenu::sizeHint() const if (rect.right() >= s.width()) s.setWidth(rect.x() + rect.width()); } - if (d->tearoff) - s.rheight() += style()->pixelMetric(QStyle::PM_MenuTearoffHeight, &opt, this); // Note that the action rects calculated above already include // the top and left margins, so we only need to add margins for // the bottom and right. -- cgit v0.12 From ac6fad8a677eb113839ff4ca79c8185e0aa8237b Mon Sep 17 00:00:00 2001 From: ck Date: Tue, 7 Jul 2009 11:23:45 +0200 Subject: Added wildcard support for file lists in help projects. The qhelpgenerator auto test was also updated to test the new feature. Reviewed-by: kh --- tests/auto/qhelpgenerator/data/test.qhp | 7 +++---- tools/assistant/lib/qhelpprojectdata.cpp | 22 +++++++++++++++++++--- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/tests/auto/qhelpgenerator/data/test.qhp b/tests/auto/qhelpgenerator/data/test.qhp index e9ac7f2..a97c00d 100644 --- a/tests/auto/qhelpgenerator/data/test.qhp +++ b/tests/auto/qhelpgenerator/data/test.qhp @@ -38,9 +38,8 @@ classic.css - test.html - people.html - ./sub/about.html + [pt]*.html + ./sub/abou?.html @@ -69,4 +68,4 @@ cars.html - \ No newline at end of file + diff --git a/tools/assistant/lib/qhelpprojectdata.cpp b/tools/assistant/lib/qhelpprojectdata.cpp index 8947a36..55b4ea7 100644 --- a/tools/assistant/lib/qhelpprojectdata.cpp +++ b/tools/assistant/lib/qhelpprojectdata.cpp @@ -41,6 +41,7 @@ #include "qhelpprojectdata_p.h" +#include #include #include #include @@ -73,6 +74,7 @@ private: void readKeywords(); void readFiles(); void raiseUnknownTokenError(); + void addMatchingFiles(const QString &pattern); }; void QHelpProjectDataPrivate::raiseUnknownTokenError() @@ -161,7 +163,7 @@ void QHelpProjectDataPrivate::readFilterSection() readNext(); if (isStartElement()) { if (name() == QLatin1String("filterAttribute")) - filterSectionList.last().addFilterAttribute(readElementText()); + filterSectionList.last().addFilterAttribute(readElementText()); else if (name() == QLatin1String("toc")) readTOC(); else if (name() == QLatin1String("keywords")) @@ -244,7 +246,7 @@ void QHelpProjectDataPrivate::readFiles() readNext(); if (isStartElement()) { if (name() == QLatin1String("file")) - filterSectionList.last().addFile(readElementText()); + addMatchingFiles(readElementText()); else raiseUnknownTokenError(); } else if (isEndElement()) { @@ -258,7 +260,21 @@ void QHelpProjectDataPrivate::readFiles() } } - +// Expand file pattern and add matches into list. If the pattern does not match +// any files, insert the pattern itself so the QHelpGenerator will emit a +// meaningful warning later. +void QHelpProjectDataPrivate::addMatchingFiles(const QString &pattern) +{ + QFileInfo fileInfo(rootPath + '/' + pattern); + const QStringList &matches = + fileInfo.dir().entryList(QStringList(fileInfo.fileName())); + for (QStringList::ConstIterator it = matches.constBegin(); + it != matches.constEnd(); + ++it) + filterSectionList.last().addFile(QFileInfo(pattern).dir().path() + '/' + *it); + if (matches.empty()) + filterSectionList.last().addFile(pattern); +} /*! \internal -- cgit v0.12 From 53b116be1bbadd416449d9a0104f514139f495c8 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 7 Jul 2009 11:49:59 +0200 Subject: ItemViews: it would go into DraggingState even without clicking an item We now just make sure that we start the drag if there was a pressed index. Task-number: 252643 --- src/gui/itemviews/qabstractitemview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index b64bc71..cefe8a5 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -1602,7 +1602,7 @@ void QAbstractItemView::mouseMoveEvent(QMouseEvent *event) d->checkMouseMove(index); #ifndef QT_NO_DRAGANDDROP - if (index.isValid() + if (d->pressedIndex.isValid() && d->dragEnabled && (state() != DragSelectingState) && (event->buttons() != Qt::NoButton) -- cgit v0.12 From f70f321c8b5769476796e2bae540a57b3b62c684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Tue, 7 Jul 2009 11:39:43 +0200 Subject: Make sure we send a ValueChanged event if the spinbox value has changed Unfortunately the codepath for keyPressEvent does not call updateState, so we have to add the same line in two places. Note that updateState() is only called from mousePressEvent() and mouseMoveEvent(). Task-number: 254053 --- src/gui/widgets/qabstractspinbox.cpp | 9 +++++++++ tests/auto/qaccessibility/tst_qaccessibility.cpp | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/src/gui/widgets/qabstractspinbox.cpp b/src/gui/widgets/qabstractspinbox.cpp index 25acd6e..da18d13 100644 --- a/src/gui/widgets/qabstractspinbox.cpp +++ b/src/gui/widgets/qabstractspinbox.cpp @@ -57,6 +57,9 @@ #include #include #include +#ifndef QT_NO_ACCESSIBILITY +# include +#endif #if defined(Q_WS_X11) #include @@ -951,6 +954,9 @@ void QAbstractSpinBox::keyPressEvent(QKeyEvent *event) d->buttonState = (Keyboard | (up ? Up : Down)); } stepBy(steps); +#ifndef QT_NO_ACCESSIBILITY + QAccessible::updateAccessibility(this, 0, QAccessible::ValueChanged); +#endif return; } #ifdef QT_KEYPAD_NAVIGATION @@ -1548,6 +1554,9 @@ void QAbstractSpinBoxPrivate::updateState(bool up) spinClickThresholdTimerId = q->startTimer(spinClickThresholdTimerInterval); buttonState = (up ? (Mouse | Up) : (Mouse | Down)); q->stepBy(up ? 1 : -1); +#ifndef QT_NO_ACCESSIBILITY + QAccessible::updateAccessibility(q, 0, QAccessible::ValueChanged); +#endif } } diff --git a/tests/auto/qaccessibility/tst_qaccessibility.cpp b/tests/auto/qaccessibility/tst_qaccessibility.cpp index 8a88b59..b8aec50 100644 --- a/tests/auto/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/qaccessibility/tst_qaccessibility.cpp @@ -2623,6 +2623,13 @@ void tst_QAccessibility::spinBoxTest() QVERIFY(childRect.isNull() == false); } + spinBox->setFocus(); + QTestAccessibility::clearEvents(); + QTest::keyPress(spinBox, Qt::Key_Up); + QTest::qWait(200); + EventList events = QTestAccessibility::events(); + QTestAccessibilityEvent expectedEvent(spinBox, 0, (int)QAccessible::ValueChanged); + QVERIFY(events.contains(expectedEvent)); delete spinBox; QTestAccessibility::clearEvents(); #else -- cgit v0.12 From 1e9d76013ef0121bcfc6efbe4328ded58c1eebd3 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 7 Jul 2009 13:25:42 +0200 Subject: QMainWindow: layout private API cleanup using const references to pass parameter --- src/gui/widgets/qmainwindowlayout.cpp | 56 +++++++++++++++++------------------ src/gui/widgets/qmainwindowlayout_p.h | 14 ++++----- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp index 0318f53..1057f5f 100644 --- a/src/gui/widgets/qmainwindowlayout.cpp +++ b/src/gui/widgets/qmainwindowlayout.cpp @@ -426,42 +426,42 @@ QList QMainWindowLayoutState::gapIndex(QWidget *widget, return result; } -bool QMainWindowLayoutState::insertGap(QList path, QLayoutItem *item) +bool QMainWindowLayoutState::insertGap(const QList &path, QLayoutItem *item) { if (path.isEmpty()) return false; - int i = path.takeFirst(); + int i = path.first(); #ifndef QT_NO_TOOLBAR if (i == 0) { Q_ASSERT(qobject_cast(item->widget()) != 0); - return toolBarAreaLayout.insertGap(path, item); + return toolBarAreaLayout.insertGap(path.mid(1), item); } #endif #ifndef QT_NO_DOCKWIDGET if (i == 1) { Q_ASSERT(qobject_cast(item->widget()) != 0); - return dockAreaLayout.insertGap(path, item); + return dockAreaLayout.insertGap(path.mid(1), item); } #endif //QT_NO_DOCKWIDGET return false; } -void QMainWindowLayoutState::remove(QList path) +void QMainWindowLayoutState::remove(const QList &path) { - int i = path.takeFirst(); + int i = path.first(); #ifndef QT_NO_TOOLBAR if (i == 0) - toolBarAreaLayout.remove(path); + toolBarAreaLayout.remove(path.mid(1)); #endif #ifndef QT_NO_DOCKWIDGET if (i == 1) - dockAreaLayout.remove(path); + dockAreaLayout.remove(path.mid(1)); #endif //QT_NO_DOCKWIDGET } @@ -501,88 +501,88 @@ bool QMainWindowLayoutState::isValid() const return rect.isValid(); } -QLayoutItem *QMainWindowLayoutState::item(QList path) +QLayoutItem *QMainWindowLayoutState::item(const QList &path) { - int i = path.takeFirst(); + int i = path.first(); #ifndef QT_NO_TOOLBAR if (i == 0) - return toolBarAreaLayout.item(path).widgetItem; + return toolBarAreaLayout.item(path.mid(1)).widgetItem; #endif #ifndef QT_NO_DOCKWIDGET if (i == 1) - return dockAreaLayout.item(path).widgetItem; + return dockAreaLayout.item(path.mid(1)).widgetItem; #endif //QT_NO_DOCKWIDGET return 0; } -QRect QMainWindowLayoutState::itemRect(QList path) const +QRect QMainWindowLayoutState::itemRect(const QList &path) const { - int i = path.takeFirst(); + int i = path.first(); #ifndef QT_NO_TOOLBAR if (i == 0) - return toolBarAreaLayout.itemRect(path); + return toolBarAreaLayout.itemRect(path.mid(1)); #endif #ifndef QT_NO_DOCKWIDGET if (i == 1) - return dockAreaLayout.itemRect(path); + return dockAreaLayout.itemRect(path.mid(1)); #endif //QT_NO_DOCKWIDGET return QRect(); } -QRect QMainWindowLayoutState::gapRect(QList path) const +QRect QMainWindowLayoutState::gapRect(const QList &path) const { - int i = path.takeFirst(); + int i = path.first(); #ifndef QT_NO_TOOLBAR if (i == 0) - return toolBarAreaLayout.itemRect(path); + return toolBarAreaLayout.itemRect(path.mid(1)); #endif #ifndef QT_NO_DOCKWIDGET if (i == 1) - return dockAreaLayout.gapRect(path); + return dockAreaLayout.gapRect(path.mid(1)); #endif //QT_NO_DOCKWIDGET return QRect(); } -QLayoutItem *QMainWindowLayoutState::plug(QList path) +QLayoutItem *QMainWindowLayoutState::plug(const QList &path) { - int i = path.takeFirst(); + int i = path.first(); #ifndef QT_NO_TOOLBAR if (i == 0) - return toolBarAreaLayout.plug(path); + return toolBarAreaLayout.plug(path.mid(1)); #endif #ifndef QT_NO_DOCKWIDGET if (i == 1) - return dockAreaLayout.plug(path); + return dockAreaLayout.plug(path.mid(1)); #endif //QT_NO_DOCKWIDGET return 0; } -QLayoutItem *QMainWindowLayoutState::unplug(QList path, QMainWindowLayoutState *other) +QLayoutItem *QMainWindowLayoutState::unplug(const QList &path, QMainWindowLayoutState *other) { - int i = path.takeFirst(); + int i = path.first(); #ifdef QT_NO_TOOLBAR Q_UNUSED(other); #else if (i == 0) - return toolBarAreaLayout.unplug(path, other ? &other->toolBarAreaLayout : 0); + return toolBarAreaLayout.unplug(path.mid(1), other ? &other->toolBarAreaLayout : 0); #endif #ifndef QT_NO_DOCKWIDGET if (i == 1) - return dockAreaLayout.unplug(path); + return dockAreaLayout.unplug(path.mid(1)); #endif //QT_NO_DOCKWIDGET return 0; diff --git a/src/gui/widgets/qmainwindowlayout_p.h b/src/gui/widgets/qmainwindowlayout_p.h index 5c5965a..759461b 100644 --- a/src/gui/widgets/qmainwindowlayout_p.h +++ b/src/gui/widgets/qmainwindowlayout_p.h @@ -129,9 +129,9 @@ public: QLayoutItem *itemAt(int index, int *x) const; QLayoutItem *takeAt(int index, int *x); QList indexOf(QWidget *widget) const; - QLayoutItem *item(QList path); - QRect itemRect(QList path) const; - QRect gapRect(QList path) const; // ### get rid of this, use itemRect() instead + QLayoutItem *item(const QList &path); + QRect itemRect(const QList &path) const; + QRect gapRect(const QList &path) const; // ### get rid of this, use itemRect() instead bool contains(QWidget *widget) const; @@ -139,14 +139,14 @@ public: QWidget *centralWidget() const; QList gapIndex(QWidget *widget, const QPoint &pos) const; - bool insertGap(QList path, QLayoutItem *item); - void remove(QList path); + bool insertGap(const QList &path, QLayoutItem *item); + void remove(const QList &path); void remove(QLayoutItem *item); void clear(); bool isValid() const; - QLayoutItem *plug(QList path); - QLayoutItem *unplug(QList path, QMainWindowLayoutState *savedState = 0); + QLayoutItem *plug(const QList &path); + QLayoutItem *unplug(const QList &path, QMainWindowLayoutState *savedState = 0); void saveState(QDataStream &stream) const; bool checkFormat(QDataStream &stream, bool pre43); -- cgit v0.12 From 5c756b368f5a76eeeff9e8e762a89368ba0b8149 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Tue, 7 Jul 2009 13:41:09 +0200 Subject: doc: Explained that you can't add new Q3DockAreas to a Widget. They won't be shown. Task-number: 166508 --- src/qt3support/widgets/q3dockarea.cpp | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/qt3support/widgets/q3dockarea.cpp b/src/qt3support/widgets/q3dockarea.cpp index a00bc81..a823caa 100644 --- a/src/qt3support/widgets/q3dockarea.cpp +++ b/src/qt3support/widgets/q3dockarea.cpp @@ -473,24 +473,25 @@ int Q3DockAreaLayout::widthForHeight(int h) const contain Q3ToolBars since Q3ToolBar is a Q3DockWindow subclass. QMainWindow contains four Q3DockAreas which you can use for your - Q3ToolBars and Q3DockWindows, so in most situations you do not need - to use the Q3DockArea class directly. Although QMainWindow contains - support for its own dock areas it isn't convenient for adding new - Q3DockAreas. If you need to create your own dock areas we suggest - that you create a subclass of QWidget and add your Q3DockAreas to - your subclass. + Q3ToolBars and Q3DockWindows, so in most situations you do not + need to use the Q3DockArea class directly. Although QMainWindow + contains support for its own dock areas, you can't add new ones. + You also can't add a Q3DockArea to your own subclass of QWidget. + It won't be shown. \img qmainwindow-qdockareas.png QMainWindow's Q3DockAreas \target lines - \e Lines. Q3DockArea uses the concept of lines. A line is a - horizontal region which may contain dock windows side-by-side. A - dock area may have room for more than one line. When dock windows - are docked into a dock area they are usually added at the right - hand side of the top-most line that has room (unless manually - placed by the user). When users move dock windows they may leave - empty lines or gaps in non-empty lines. Qt::Dock windows can be lined - up to minimize wasted space using the lineUp() function. + \section2 Lines. + + Q3DockArea uses the concept of lines. A line is a horizontal + region which may contain dock windows side-by-side. A dock area + may have room for more than one line. When dock windows are docked + into a dock area they are usually added at the right hand side of + the top-most line that has room (unless manually placed by the + user). When users move dock windows they may leave empty lines or + gaps in non-empty lines. Qt::Dock windows can be lined up to + minimize wasted space using the lineUp() function. The Q3DockArea class maintains a position list of all its child dock windows. Qt::Dock windows are added to a dock area from position -- cgit v0.12 From 20b2c6bd8e6f6a7ef384f4b478623768c11e01ae Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Tue, 7 Jul 2009 13:45:15 +0200 Subject: Document limitation in Cocoa cursor handling. It seems there is a bug in AppKit which will automatically reset a cursor even when it is grabbed, but won't reset it when it's brought back into the window. The upshot of this is that doing a setCursor() inside of mouse handling behaves slightly different than on the other platforms (including Carbon). However, we are at the mercy of Cocoa here and I would rather have all the other things AppKit does right and live with this bug which they may fix some day. --- src/gui/kernel/qwidget.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index e6a5ae0..9d40b00 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -4590,6 +4590,11 @@ void QWidget::unsetLayoutDirection() By default, this property contains a cursor with the Qt::ArrowCursor shape. + Some underlying window implementations will reset the cursor if it + leaves a widget even if the mouse is grabbed. If you want to have + a cursor set for all widgets, even when outside the window, consider + QApplication::setOverrideCursor(). + \sa QApplication::setOverrideCursor() */ -- cgit v0.12 From da1dee6894f96b416bb123578cc6e61c6444ddd8 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Tue, 7 Jul 2009 13:49:20 +0200 Subject: improve the QScriptEngine::importExtension() autotest Error messages and __postInit__. --- tests/auto/qscriptengine/script/com/__init__.js | 4 ++++ tests/auto/qscriptengine/script/com/trolltech/__init__.js | 4 ++++ tests/auto/qscriptengine/tst_qscriptengine.cpp | 7 +++++++ 3 files changed, 15 insertions(+) diff --git a/tests/auto/qscriptengine/script/com/__init__.js b/tests/auto/qscriptengine/script/com/__init__.js index 381816a..7db3ee4 100644 --- a/tests/auto/qscriptengine/script/com/__init__.js +++ b/tests/auto/qscriptengine/script/com/__init__.js @@ -3,3 +3,7 @@ __setupPackage__("com"); com.wasDefinedAlready = wasDefinedAlready; com.name = __extension__; com.level = 1; + +com.postInitCallCount = 0; +com.originalPostInit = __postInit__; +__postInit__ = function() { ++com.postInitCallCount; }; diff --git a/tests/auto/qscriptengine/script/com/trolltech/__init__.js b/tests/auto/qscriptengine/script/com/trolltech/__init__.js index f12b17d..a55b132 100644 --- a/tests/auto/qscriptengine/script/com/trolltech/__init__.js +++ b/tests/auto/qscriptengine/script/com/trolltech/__init__.js @@ -3,3 +3,7 @@ __setupPackage__("com.trolltech"); com.trolltech.wasDefinedAlready = wasDefinedAlready; com.trolltech.name = __extension__; com.trolltech.level = com.level + 1; + +com.trolltech.postInitCallCount = 0; +com.trolltech.originalPostInit = __postInit__; +__postInit__ = function() { ++com.trolltech.postInitCallCount; }; diff --git a/tests/auto/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp index c17454d..57c5167 100644 --- a/tests/auto/qscriptengine/tst_qscriptengine.cpp +++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp @@ -1583,6 +1583,7 @@ void tst_QScriptEngine::importExtension() QScriptValue ret = eng.importExtension("this.extension.does.not.exist"); QCOMPARE(eng.hasUncaughtException(), true); QCOMPARE(ret.isError(), true); + QCOMPARE(ret.toString(), QString::fromLatin1("Error: Unable to import this.extension.does.not.exist: no such extension")); } { @@ -1601,6 +1602,8 @@ void tst_QScriptEngine::importExtension() .strictlyEquals(QScriptValue(&eng, "com")), true); QCOMPARE(com.property("level") .strictlyEquals(QScriptValue(&eng, 1)), true); + QVERIFY(com.property("originalPostInit").isUndefined()); + QVERIFY(com.property("postInitCallCount").strictlyEquals(1)); QScriptValue trolltech = com.property("trolltech"); QCOMPARE(trolltech.isObject(), true); @@ -1610,6 +1613,8 @@ void tst_QScriptEngine::importExtension() .strictlyEquals(QScriptValue(&eng, "com.trolltech")), true); QCOMPARE(trolltech.property("level") .strictlyEquals(QScriptValue(&eng, 2)), true); + QVERIFY(trolltech.property("originalPostInit").isUndefined()); + QVERIFY(trolltech.property("postInitCallCount").strictlyEquals(1)); } QStringList imp = eng.importedExtensions(); QCOMPARE(imp.size(), 2); @@ -1625,6 +1630,8 @@ void tst_QScriptEngine::importExtension() eng.globalObject().setProperty("__import__", eng.newFunction(__import__)); QScriptValue ret = eng.importExtension("com.trolltech.recursive"); QCOMPARE(eng.hasUncaughtException(), true); + QVERIFY(ret.isError()); + QCOMPARE(ret.toString(), QString::fromLatin1("Error: recursive import of com.trolltech.recursive")); QStringList imp = eng.importedExtensions(); QCOMPARE(imp.size(), 2); QCOMPARE(imp.at(0), QString::fromLatin1("com")); -- cgit v0.12 From 9e2573bac15e39dc4f3545351ad87e221b4785e7 Mon Sep 17 00:00:00 2001 From: ck Date: Tue, 7 Jul 2009 13:54:39 +0200 Subject: Updated docs to mention pattern matching in help project file lists. Reviewed-by: kh --- doc/src/examples/simpletextviewer.qdoc | 7 +------ doc/src/qthelp.qdoc | 14 ++++++++------ doc/src/snippets/code/doc_src_qthelp.qdoc | 6 ++---- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/doc/src/examples/simpletextviewer.qdoc b/doc/src/examples/simpletextviewer.qdoc index 87eae57..2531a86 100644 --- a/doc/src/examples/simpletextviewer.qdoc +++ b/doc/src/examples/simpletextviewer.qdoc @@ -198,12 +198,7 @@ openfile.html wildcardmatching.html images/browse.png - images/fadedfilemenu.png - images/filedialog.png - images/handbook.png - images/mainwindow.png - images/open.png - images/wildcard.png + images/*.png diff --git a/doc/src/qthelp.qdoc b/doc/src/qthelp.qdoc index b5395c9..92c9609 100644 --- a/doc/src/qthelp.qdoc +++ b/doc/src/qthelp.qdoc @@ -398,11 +398,13 @@ Finally, the actual documentation files have to be listed. Make sure that all files neccessary to display the help are mentioned, i.e. - stylesheets or similar files need to be there as well. The file, like all + stylesheets or similar files need to be there as well. The files, like all file references in a Qt help project, are relative to the help project file - itself. All listed files will be compressed and written to the Qt compressed - help file. So, in the end, one single Qt help file contains all - documentation files along with the contents and indices. \note The - referenced files must be inside the same directory (or within a subdirectory) - as the help project file. An absolute file path is not supported either. + itself. As the example shows, files (but not directories) can also be + specified as patterns using wildcards. All listed files will be compressed + and written to the Qt compressed help file. So, in the end, one single Qt + help file contains all documentation files along with the contents and + indices. \note The referenced files must be inside the same directory + (or within a subdirectory) as the help project file. An absolute file path + is not supported either. */ diff --git a/doc/src/snippets/code/doc_src_qthelp.qdoc b/doc/src/snippets/code/doc_src_qthelp.qdoc index 11d231f..949e2a5 100644 --- a/doc/src/snippets/code/doc_src_qthelp.qdoc +++ b/doc/src/snippets/code/doc_src_qthelp.qdoc @@ -92,8 +92,7 @@ if (links.count()) { classic.css - index.html - doc.html + *.html @@ -154,8 +153,7 @@ if (links.count()) { ... classic.css - index.html - doc.html + *.html ... //! [13] -- cgit v0.12 From 0044b3c968f5023f502e3574c96d4e4df0de865d Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 7 Jul 2009 14:18:12 +0200 Subject: Doc: Mentioned the use of the meta-type declaration macro and the function for registering types. Additional clean-up. Task-number: 221375 Reviewed-by: Trust Me --- src/network/socket/qlocalsocket.cpp | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/network/socket/qlocalsocket.cpp b/src/network/socket/qlocalsocket.cpp index acacdf2..7809226 100644 --- a/src/network/socket/qlocalsocket.cpp +++ b/src/network/socket/qlocalsocket.cpp @@ -63,7 +63,8 @@ QT_BEGIN_NAMESPACE waitForReadyRead(), waitForBytesWritten(), and waitForDisconnected() which blocks until the operation is complete or the timeout expires. - Note that this feature is not supported on Window 9x. + Note that this feature is not supported on versions of Windows earlier than + Windows XP. \sa QLocalServer */ @@ -102,7 +103,7 @@ QT_BEGIN_NAMESPACE opened in the mode specified by \a openMode, and enters the socket state specified by \a socketState. - Note: It is not possible to initialize two local sockets with the same + \note It is not possible to initialize two local sockets with the same native socket descriptor. \sa socketDescriptor(), state(), openMode() @@ -207,10 +208,10 @@ QT_BEGIN_NAMESPACE Returns true if the socket is valid and ready for use; otherwise returns false. - Note: The socket's state must be ConnectedState before reading + \note The socket's state must be ConnectedState before reading and writing can occur. - \sa state() + \sa state(), connectToServer() */ /*! @@ -243,9 +244,9 @@ QT_BEGIN_NAMESPACE */ /*! - \fn bool QLocalSocket::waitForConnected(int msec) + \fn bool QLocalSocket::waitForConnected(int msecs) - Waits until the socket is connected, up to \a msec milliseconds. If the + Waits until the socket is connected, up to \a msecs milliseconds. If the connection has been established, this function returns true; otherwise it returns false. In the case where it returns false, you can call error() to determine the cause of the error. @@ -255,7 +256,7 @@ QT_BEGIN_NAMESPACE \snippet doc/src/snippets/code/src_network_socket_qlocalsocket_unix.cpp 0 - If msecs is -1, this function will not time out. + If \a msecs is -1, this function will not time out. \sa connectToServer(), connected() */ @@ -274,7 +275,7 @@ QT_BEGIN_NAMESPACE \snippet doc/src/snippets/code/src_network_socket_qlocalsocket_unix.cpp 1 - If msecs is -1, this function will not time out. + If \a msecs is -1, this function will not time out. \sa disconnectFromServer(), close() */ @@ -309,9 +310,10 @@ QT_BEGIN_NAMESPACE parameter describes the type of error that occurred. QLocalSocket::LocalSocketError is not a registered metatype, so for queued - connections, you will have to register it with Q_DECLARE_METATYPE. + connections, you will have to register it with Q_DECLARE_METATYPE() and + qRegisterMetaType(). - \sa error(), errorString() + \sa error(), errorString(), {Creating Custom Qt Types} */ /*! @@ -321,9 +323,10 @@ QT_BEGIN_NAMESPACE The \a socketState parameter is the new state. QLocalSocket::SocketState is not a registered metatype, so for queued - connections, you will have to register it with Q_DECLARE_METATYPE. + connections, you will have to register it with Q_DECLARE_METATYPE() and + qRegisterMetaType(). - \sa state() + \sa state(), {Creating Custom Qt Types} */ /*! @@ -365,7 +368,7 @@ QString QLocalSocket::serverName() const /*! Returns the server path that the socket is connected to. - Note: This is platform specific + \note The return value of this function is platform specific. \sa connectToServer(), serverName() */ -- cgit v0.12 From 2a834d39a69430058df3916392afab064ca941ee Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 7 Jul 2009 13:48:03 +0200 Subject: try to fix the accept4 not being found in some older kernels --- src/corelib/kernel/qcore_unix.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp index 2549f77..b04abae 100644 --- a/src/corelib/kernel/qcore_unix.cpp +++ b/src/corelib/kernel/qcore_unix.cpp @@ -138,22 +138,32 @@ static inline int syscall(...) { errno = ENOSYS; return -1;} # define __NR_dup3 330 # define __NR_pipe2 331 # elif defined(__x86_64__) -# define __NR_accept4 288 # define __NR_dup3 292 # define __NR_pipe2 293 # elif defined(__ia64__) -# define __NR_accept4 -1 # define __NR_dup3 1316 # define __NR_pipe2 1317 # else // set the syscalls to absurd numbers so that they'll cause ENOSYS errors -# warning "Please port the pipe2/dup3/accept4 code to this platform" -# define __NR_accept4 -1 +# warning "Please port the pipe2/dup3 code to this platform" # define __NR_dup3 -1 # define __NR_pipe2 -1 # endif # endif +# if !defined(__NR_socketcall) && !defined(__NR_accept4) +# if defined(__x86_64__) +# define __NR_accept4 288 +# elif defined(__ia64__) +// not assigned yet to IA-64 +# define __NR_accept4 -1 +# else +// set the syscalls to absurd numbers so that they'll cause ENOSYS errors +# warning "Please port the accept4 code to this platform" +# define __NR_accept4 -1 +# endif +# endif + QT_BEGIN_NAMESPACE namespace QtLibcSupplement { int pipe2(int pipes[], int flags) -- cgit v0.12 From e5e2f9fd5c1554337a576374ec6744f953d2404d Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 7 Jul 2009 15:13:44 +0200 Subject: QColumnView: didn't react to addition of rows/cols in the current view Task-number: 246999 --- src/gui/itemviews/qabstractitemview_p.h | 13 +++++---- src/gui/itemviews/qcolumnview.cpp | 45 +++++++++++++++++++++++++++++- src/gui/itemviews/qcolumnview.h | 8 ++---- src/gui/itemviews/qcolumnview_p.h | 3 ++ src/gui/itemviews/qheaderview.h | 1 - src/gui/itemviews/qtreeview.h | 7 ++--- src/gui/widgets/qabstractscrollarea.cpp | 3 -- src/gui/widgets/qabstractscrollarea_p.h | 2 +- tests/auto/qcolumnview/tst_qcolumnview.cpp | 42 +++++++++++++++++++++++----- 9 files changed, 96 insertions(+), 28 deletions(-) diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index c2c1f32..026912a 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -109,12 +109,13 @@ public: void init(); - void _q_rowsRemoved(const QModelIndex &parent, int start, int end); - void _q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end); - void _q_columnsRemoved(const QModelIndex &parent, int start, int end); - void _q_columnsInserted(const QModelIndex &parent, int start, int end); - void _q_modelDestroyed(); - void _q_layoutChanged(); + virtual void _q_rowsRemoved(const QModelIndex &parent, int start, int end); + virtual void _q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end); + virtual void _q_columnsRemoved(const QModelIndex &parent, int start, int end); + virtual void _q_columnsInserted(const QModelIndex &parent, int start, int end); + virtual void _q_modelDestroyed(); + virtual void _q_layoutChanged(); + void _q_fetchMore(); bool shouldEdit(QAbstractItemView::EditTrigger trigger, const QModelIndex &index) const; diff --git a/src/gui/itemviews/qcolumnview.cpp b/src/gui/itemviews/qcolumnview.cpp index 1662fa8..ff20163 100644 --- a/src/gui/itemviews/qcolumnview.cpp +++ b/src/gui/itemviews/qcolumnview.cpp @@ -52,7 +52,6 @@ #include #include #include -#include QT_BEGIN_NAMESPACE @@ -896,6 +895,15 @@ QList QColumnView::columnWidths() const /*! \reimp */ +void QColumnView::rowsInserted(const QModelIndex &parent, int start, int end) +{ + QAbstractItemView::rowsInserted(parent, start, end); + d_func()->checkColumnCreation(parent); +} + +/*! + \reimp +*/ void QColumnView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) { Q_D(QColumnView); @@ -1048,6 +1056,41 @@ QColumnViewPrivate::~QColumnViewPrivate() /*! \internal + + */ +void QColumnViewPrivate::_q_columnsInserted(const QModelIndex &parent, int start, int end) +{ + QAbstractItemViewPrivate::_q_columnsInserted(parent, start, end); + checkColumnCreation(parent); +} + +/*! + \internal + + Makes sure we create a corresponding column as a result of changing the model. + + */ +void QColumnViewPrivate::checkColumnCreation(const QModelIndex &parent) +{ + if (parent == q_func()->currentIndex() && model->hasChildren(parent)) { + //the parent has children and is the current + //let's try to find out if there is already a mapping that is good + for (int i = 0; i < columns.count(); ++i) { + QAbstractItemView *view = columns.at(i); + if (view->rootIndex() == parent) { + if (view == previewColumn) { + //let's recreate the parent + closeColumns(parent, false); + createColumn(parent, true /*show*/); + } + break; + } + } + } +} + +/*! + \internal Place all of the columns where they belong inside of the viewport, resize as necessary. */ void QColumnViewPrivate::doLayout() diff --git a/src/gui/itemviews/qcolumnview.h b/src/gui/itemviews/qcolumnview.h index 880870a..f8697e9 100644 --- a/src/gui/itemviews/qcolumnview.h +++ b/src/gui/itemviews/qcolumnview.h @@ -97,16 +97,14 @@ protected: QRegion visualRegionForSelection(const QItemSelection &selection) const; int horizontalOffset() const; int verticalOffset() const; - void scrollContentsBy(int dx, int dy); + void rowsInserted(const QModelIndex &parent, int start, int end); + void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); // QColumnView functions + void scrollContentsBy(int dx, int dy); virtual QAbstractItemView* createColumn(const QModelIndex &rootIndex); void initializeColumn(QAbstractItemView *column) const; -protected Q_SLOTS: - // QAbstractItemView overloads - void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); - private: Q_DECLARE_PRIVATE(QColumnView) Q_DISABLE_COPY(QColumnView) diff --git a/src/gui/itemviews/qcolumnview_p.h b/src/gui/itemviews/qcolumnview_p.h index 92a4d2a..233dc3c 100644 --- a/src/gui/itemviews/qcolumnview_p.h +++ b/src/gui/itemviews/qcolumnview_p.h @@ -148,10 +148,13 @@ public: void closeColumns(const QModelIndex &parent = QModelIndex(), bool build = false); void doLayout(); void setPreviewWidget(QWidget *widget); + void checkColumnCreation(const QModelIndex &parent); + void _q_gripMoved(int offset); void _q_changeCurrentColumn(); void _q_clicked(const QModelIndex &index); + void _q_columnsInserted(const QModelIndex &parent, int start, int end); QList columns; QVector columnSizes; // used during init and corner moving diff --git a/src/gui/itemviews/qheaderview.h b/src/gui/itemviews/qheaderview.h index bf92667..3a66c9a 100644 --- a/src/gui/itemviews/qheaderview.h +++ b/src/gui/itemviews/qheaderview.h @@ -228,7 +228,6 @@ protected: private: Q_PRIVATE_SLOT(d_func(), void _q_sectionsRemoved(const QModelIndex &parent, int logicalFirst, int logicalLast)) Q_PRIVATE_SLOT(d_func(), void _q_layoutAboutToBeChanged()) - Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged()) Q_DECLARE_PRIVATE(QHeaderView) Q_DISABLE_COPY(QHeaderView) }; diff --git a/src/gui/itemviews/qtreeview.h b/src/gui/itemviews/qtreeview.h index 35a205c..0347645 100644 --- a/src/gui/itemviews/qtreeview.h +++ b/src/gui/itemviews/qtreeview.h @@ -144,19 +144,20 @@ public: void sortByColumn(int column, Qt::SortOrder order); + void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); + void selectAll(); + Q_SIGNALS: void expanded(const QModelIndex &index); void collapsed(const QModelIndex &index); public Q_SLOTS: - void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); void hideColumn(int column); void showColumn(int column); void expand(const QModelIndex &index); void collapse(const QModelIndex &index); void resizeColumnToContents(int column); void sortByColumn(int column); - void selectAll(); void expandAll(); void collapseAll(); void expandToDepth(int depth); @@ -225,8 +226,6 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_endAnimatedOperation()) Q_PRIVATE_SLOT(d_func(), void _q_animate()) Q_PRIVATE_SLOT(d_func(), void _q_currentChanged(const QModelIndex&, const QModelIndex &)) - Q_PRIVATE_SLOT(d_func(), void _q_columnsAboutToBeRemoved(const QModelIndex &, int, int)) - Q_PRIVATE_SLOT(d_func(), void _q_columnsRemoved(const QModelIndex &, int, int)) Q_PRIVATE_SLOT(d_func(), void _q_modelAboutToBeReset()) Q_PRIVATE_SLOT(d_func(), void _q_sortIndicatorChanged(int column, Qt::SortOrder order)) Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed()) diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp index 66572b8..d952ab0 100644 --- a/src/gui/widgets/qabstractscrollarea.cpp +++ b/src/gui/widgets/qabstractscrollarea.cpp @@ -490,9 +490,6 @@ void QAbstractScrollAreaPrivate::layoutChildren() viewport->setGeometry(QStyle::visualRect(opt.direction, opt.rect, viewportRect)); // resize the viewport last } -// ### Fix for 4.4, talk to Bjoern E or Girish. -void QAbstractScrollAreaPrivate::scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {} - /*! \internal diff --git a/src/gui/widgets/qabstractscrollarea_p.h b/src/gui/widgets/qabstractscrollarea_p.h index 5d3494b..7e0f444 100644 --- a/src/gui/widgets/qabstractscrollarea_p.h +++ b/src/gui/widgets/qabstractscrollarea_p.h @@ -88,7 +88,7 @@ public: void init(); void layoutChildren(); // ### Fix for 4.4, talk to Bjoern E or Girish. - virtual void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy); + virtual void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {} void _q_hslide(int); void _q_vslide(int); diff --git a/tests/auto/qcolumnview/tst_qcolumnview.cpp b/tests/auto/qcolumnview/tst_qcolumnview.cpp index 0216e0f..0b3ba7a 100644 --- a/tests/auto/qcolumnview/tst_qcolumnview.cpp +++ b/tests/auto/qcolumnview/tst_qcolumnview.cpp @@ -42,6 +42,7 @@ #include #include +#include #include #include "../../../src/gui/itemviews/qcolumnviewgrip_p.h" #include "../../../src/gui/dialogs/qfilesystemmodel_p.h" @@ -87,6 +88,8 @@ private slots: void setSelectionModel(); void visualRegionForSelection(); + void dynamicModelChanges(); + // grip void moveGrip_basic(); void moveGrip_data(); @@ -133,16 +136,10 @@ public: inline QModelIndex thirdLevel() { return index(0, 0, secondLevel()); } }; -class ColumnViewPrivate : public QColumnViewPrivate -{ -public: - ColumnViewPrivate() : QColumnViewPrivate() {} -}; - class ColumnView : public QColumnView { public: - ColumnView(QWidget *parent = 0) : QColumnView(*new ColumnViewPrivate, parent){} + ColumnView(QWidget *parent = 0) : QColumnView(parent){} QList > createdColumns; void ScrollContentsBy(int x, int y) {scrollContentsBy(x,y); } @@ -1002,6 +999,37 @@ void tst_QColumnView::pullRug() // don't crash } +void tst_QColumnView::dynamicModelChanges() +{ + struct MyItemDelegate : public QItemDelegate + { + void paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const + { + paintedIndexes += index; + QItemDelegate::paint(painter, option, index); + } + + mutable QSet paintedIndexes; + + } delegate;; + QStandardItemModel model; + ColumnView view; + view.setModel(&model); + view.setItemDelegate(&delegate); + view.show(); + + QStandardItem *item = new QStandardItem(QLatin1String("item")); + model.appendRow(item); + + QTest::qWait(200); //let the time for painting to occur + QCOMPARE(delegate.paintedIndexes.count(), 1); + QCOMPARE(*delegate.paintedIndexes.begin(), model.index(0,0)); + + +} + QTEST_MAIN(tst_QColumnView) #include "tst_qcolumnview.moc" -- cgit v0.12 From 1a112561126c7f2148d91e40a6c3f52ccf506fd5 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 7 Jul 2009 15:29:05 +0200 Subject: Getting rid of compiler warnings on windows --- src/gui/kernel/qapplication.cpp | 6 ++---- src/gui/kernel/qapplication_win.cpp | 4 +--- src/gui/util/qsystemtrayicon_win.cpp | 4 ++-- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 0e8978f..839e465 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -5233,8 +5233,6 @@ void QApplicationPrivate::translateRawTouchEvent(QWidget *window, const QList &touchPoints) { QApplicationPrivate *d = self; - QApplication *q = self->q_func(); - typedef QPair > StatesAndTouchPoints; QHash widgetsNeedingEvents; @@ -5256,7 +5254,7 @@ void QApplicationPrivate::translateRawTouchEvent(QWidget *window, if (!widget) { // determine which widget this event will go to if (!window) - window = q->topLevelAt(touchPoint.screenPos().toPoint()); + window = QApplication::topLevelAt(touchPoint.screenPos().toPoint()); if (!window) continue; widget = window->childAt(window->mapFromGlobal(touchPoint.screenPos().toPoint())); @@ -5356,7 +5354,7 @@ void QApplicationPrivate::translateRawTouchEvent(QWidget *window, QTouchEvent touchEvent(eventType, deviceType, - q->keyboardModifiers(), + QApplication::keyboardModifiers(), it.value().first, it.value().second); updateTouchPointsForWidget(widget, &touchEvent); diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 13f19a3..e0eda82 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -3940,13 +3940,11 @@ void QApplicationPrivate::cleanupMultitouch_sys() bool QApplicationPrivate::translateTouchEvent(const MSG &msg) { - Q_Q(QApplication); - QWidget *widgetForHwnd = QWidget::find(msg.hwnd); if (!widgetForHwnd) return false; - QRect screenGeometry = q->desktop()->screenGeometry(widgetForHwnd); + QRect screenGeometry = QApplication::desktop()->screenGeometry(widgetForHwnd); QList touchPoints; diff --git a/src/gui/util/qsystemtrayicon_win.cpp b/src/gui/util/qsystemtrayicon_win.cpp index c1b7e7f..dea9264 100644 --- a/src/gui/util/qsystemtrayicon_win.cpp +++ b/src/gui/util/qsystemtrayicon_win.cpp @@ -163,7 +163,7 @@ void QSystemTrayIconSys::setIconContents(NOTIFYICONDATA &tnd) } } -int iconFlag( QSystemTrayIcon::MessageIcon icon ) +static int iconFlag( QSystemTrayIcon::MessageIcon icon ) { #if NOTIFYICON_VERSION >= 3 switch (icon) { @@ -176,7 +176,7 @@ int iconFlag( QSystemTrayIcon::MessageIcon icon ) case QSystemTrayIcon::NoIcon: return NIIF_NONE; default: - Q_ASSERT("Invalid QSystemTrayIcon::MessageIcon value", false); + Q_ASSERT_X(false, "QSystemTrayIconSys::showMessage", "Invalid QSystemTrayIcon::MessageIcon value"); return NIIF_NONE; } #else -- cgit v0.12 From e348e7b633ff3a0279d4d1759e35f0920afcc3e0 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 7 Jul 2009 15:56:07 +0200 Subject: QColumnView: new uses QPropertyAnimation over QTimeLine --- src/gui/itemviews/qcolumnview.cpp | 27 +++++++-------------------- src/gui/itemviews/qcolumnview_p.h | 4 ++-- 2 files changed, 9 insertions(+), 22 deletions(-) diff --git a/src/gui/itemviews/qcolumnview.cpp b/src/gui/itemviews/qcolumnview.cpp index ff20163..fc89967 100644 --- a/src/gui/itemviews/qcolumnview.cpp +++ b/src/gui/itemviews/qcolumnview.cpp @@ -107,9 +107,10 @@ void QColumnViewPrivate::initialize() { Q_Q(QColumnView); q->setTextElideMode(Qt::ElideMiddle); - QObject::connect(¤tAnimation, SIGNAL(frameChanged(int)), - hbar, SLOT(setValue(int))); QObject::connect(¤tAnimation, SIGNAL(finished()), q, SLOT(_q_changeCurrentColumn())); + currentAnimation.setDuration(ANIMATION_DURATION_MSEC); + currentAnimation.setTargetObject(hbar); + currentAnimation.setEasingCurve(QEasingCurve::InOutQuad); delete itemDelegate; q->setItemDelegate(new QColumnViewDelegate(q)); } @@ -259,7 +260,7 @@ void QColumnView::scrollTo(const QModelIndex &index, ScrollHint hint) if (!index.isValid() || d->columns.isEmpty()) return; - if (d->currentAnimation.state() == QTimeLine::Running) + if (d->currentAnimation.state() == QPropertyAnimation::Running) return; d->currentAnimation.stop(); @@ -325,21 +326,7 @@ void QColumnView::scrollTo(const QModelIndex &index, ScrollHint hint) } } - //horizontalScrollBar()->setValue(newScrollbarValue); - //d->_q_changeCurrentColumn(); - //return; - // or do the following currentAnimation - - int oldValue = horizontalScrollBar()->value(); - - if (oldValue < newScrollbarValue) { - d->currentAnimation.setFrameRange(oldValue, newScrollbarValue); - d->currentAnimation.setDirection(QTimeLine::Forward); - d->currentAnimation.setCurrentTime(0); - } else { - d->currentAnimation.setFrameRange(newScrollbarValue, oldValue); - d->currentAnimation.setDirection(QTimeLine::Backward); - } + d->currentAnimation.setEndValue(newScrollbarValue); d->currentAnimation.start(); } @@ -409,7 +396,7 @@ void QColumnView::resizeEvent(QResizeEvent *event) void QColumnViewPrivate::updateScrollbars() { Q_Q(QColumnView); - if (currentAnimation.state() == QTimeLine::Running) + if (currentAnimation.state() == QPropertyAnimation::Running) return; // find the total horizontal length of the laid out columns @@ -1044,7 +1031,7 @@ QColumnViewPrivate::QColumnViewPrivate() : QAbstractItemViewPrivate() ,showResizeGrips(true) ,offset(0) -,currentAnimation(ANIMATION_DURATION_MSEC) +,currentAnimation(0, "value") // will set the target later ,previewWidget(0) ,previewColumn(0) { diff --git a/src/gui/itemviews/qcolumnview_p.h b/src/gui/itemviews/qcolumnview_p.h index 233dc3c..1a8be70 100644 --- a/src/gui/itemviews/qcolumnview_p.h +++ b/src/gui/itemviews/qcolumnview_p.h @@ -60,7 +60,7 @@ #include #include -#include +#include #include #include #include @@ -160,7 +160,7 @@ public: QVector columnSizes; // used during init and corner moving bool showResizeGrips; int offset; - QTimeLine currentAnimation; + QPropertyAnimation currentAnimation; QWidget *previewWidget; QAbstractItemView *previewColumn; }; -- cgit v0.12 From 5f48e2a16b0b64536a205320fbf7a22f7461d80d Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Tue, 7 Jul 2009 15:43:53 +0200 Subject: Fixes a crash when scrolling a scrollarea with a mouse wheel. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a crashed introduced in 60e965fd35037f4a27816d2aeccafdff0d6ae9d6 - those lines were removed by accident. Reviewed-by: João Abecasis Author: João Abecasis --- src/gui/kernel/qwidget.cpp | 1 + src/gui/widgets/qabstractscrollarea.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 611cb44..d1ab45a 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -7484,6 +7484,7 @@ bool QWidget::event(QEvent *event) #ifndef QT_NO_WHEELEVENT case QEvent::Wheel: #endif + return false; default: break; } diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp index d952ab0..e78f5a7 100644 --- a/src/gui/widgets/qabstractscrollarea.cpp +++ b/src/gui/widgets/qabstractscrollarea.cpp @@ -937,6 +937,7 @@ bool QAbstractScrollArea::event(QEvent *e) case QEvent::DragMove: case QEvent::DragLeave: #endif + return false; case QEvent::StyleChange: case QEvent::LayoutDirectionChange: case QEvent::ApplicationLayoutDirectionChange: -- cgit v0.12 From 424e2e68f9a3f556ad2d06e2fbceac0d48c060be Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 7 Jul 2009 16:42:20 +0200 Subject: ItemViews: _q_fetchMore now uses a timer instead of invokeMethod --- src/gui/itemviews/qabstractitemview.cpp | 11 +++++++---- src/gui/itemviews/qabstractitemview.h | 1 - src/gui/itemviews/qabstractitemview_p.h | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index cefe8a5..dd84304 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -2200,6 +2200,8 @@ void QAbstractItemView::resizeEvent(QResizeEvent *event) void QAbstractItemView::timerEvent(QTimerEvent *event) { Q_D(QAbstractItemView); + if (event->timerId() == d->fetchMoreTimer.timerId()) + d->fetchMore(); if (event->timerId() == d->autoScrollTimer.timerId()) doAutoScroll(); else if (event->timerId() == d->updateTimer.timerId()) @@ -2415,7 +2417,7 @@ void QAbstractItemView::updateEditorGeometries() void QAbstractItemView::updateGeometries() { updateEditorGeometries(); - QMetaObject::invokeMethod(this, "_q_fetchMore", Qt::QueuedConnection); + d_func()->fetchMoreTimer.start(0, this); //fetch more later } /*! @@ -2960,7 +2962,7 @@ void QAbstractItemView::dataChanged(const QModelIndex &topLeft, const QModelInde void QAbstractItemView::rowsInserted(const QModelIndex &, int, int) { if (!isVisible()) - QMetaObject::invokeMethod(this, "_q_fetchMore", Qt::QueuedConnection); + d_func()->fetchMoreTimer.start(0, this); //fetch more later else updateEditorGeometries(); } @@ -3183,7 +3185,7 @@ void QAbstractItemView::currentChanged(const QModelIndex ¤t, const QModelI update(current); edit(current, CurrentChanged, 0); if (current.row() == (d->model->rowCount(d->root) - 1)) - d->_q_fetchMore(); + d->fetchMore(); } else { d->shouldScrollToCurrentOnShow = d->autoScroll; } @@ -3604,8 +3606,9 @@ QAbstractItemViewPrivate::contiguousSelectionCommand(const QModelIndex &index, } } -void QAbstractItemViewPrivate::_q_fetchMore() +void QAbstractItemViewPrivate::fetchMore() { + fetchMoreTimer.stop(); if (!model->canFetchMore(root)) return; int last = model->rowCount(root) - 1; diff --git a/src/gui/itemviews/qabstractitemview.h b/src/gui/itemviews/qabstractitemview.h index f98dd16..da6f0ea 100644 --- a/src/gui/itemviews/qabstractitemview.h +++ b/src/gui/itemviews/qabstractitemview.h @@ -353,7 +353,6 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_rowsRemoved(const QModelIndex&, int, int)) Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed()) Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged()) - Q_PRIVATE_SLOT(d_func(), void _q_fetchMore()) friend class QTreeViewPrivate; // needed to compile with MSVC friend class QAccessibleItemRow; diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index 026912a..2950bcd 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -116,7 +116,7 @@ public: virtual void _q_modelDestroyed(); virtual void _q_layoutChanged(); - void _q_fetchMore(); + void fetchMore(); bool shouldEdit(QAbstractItemView::EditTrigger trigger, const QModelIndex &index) const; bool shouldForwardEvent(QAbstractItemView::EditTrigger trigger, const QEvent *event) const; @@ -388,6 +388,7 @@ public: private: mutable QBasicTimer delayedLayout; + mutable QBasicTimer fetchMoreTimer; }; QT_BEGIN_INCLUDE_NAMESPACE -- cgit v0.12 From f37bd111f7622a34b3a7bd63f5a82f6042dc0f0d Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Tue, 7 Jul 2009 16:46:30 +0200 Subject: Stop showing then hiding windows on starting designer in top-level mode. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We've had this since 4.5 and it's very annoying to see the window show and quickly hide itself. I was hoping it wasn't a bug in Qt, and it turns it isn't and it was happening on all platforms. Reviewed-by: Friedemann Kleint Shout outs: João for testing. --- tools/designer/src/designer/qdesigner_workbench.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/designer/src/designer/qdesigner_workbench.cpp b/tools/designer/src/designer/qdesigner_workbench.cpp index 923687a2..ce8dde6 100644 --- a/tools/designer/src/designer/qdesigner_workbench.cpp +++ b/tools/designer/src/designer/qdesigner_workbench.cpp @@ -462,8 +462,7 @@ void QDesignerWorkbench::switchToTopLevelMode() // make sure that the widgetbox is visible if it is different from neutral. QDesignerToolWindow *widgetBoxWrapper = widgetBoxToolWindow(); Q_ASSERT(widgetBoxWrapper); - if (!widgetBoxWrapper->action()->isChecked()) - widgetBoxWrapper->action()->trigger(); + const bool needWidgetBoxWrapperVisible = widgetBoxWrapper->action()->isChecked(); switchToNeutralMode(); const QPoint desktopOffset = desktopGeometry().topLeft(); @@ -502,7 +501,7 @@ void QDesignerWorkbench::switchToTopLevelMode() found_visible_window |= tw->isVisible(); } - if (!widgetBoxWrapper->action()->isChecked()) + if (needWidgetBoxWrapperVisible) widgetBoxWrapper->action()->trigger(); if (!m_toolWindows.isEmpty() && !found_visible_window) -- cgit v0.12 From fbc384f1bc1dd57e4af8e008b9db000b6ff82a37 Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Tue, 7 Jul 2009 16:24:49 +0200 Subject: On Mac OS X, translate the wrect to the coordinates on screen In the following configuration, wrect was off-screen and the widget was not painted: -scroll area "A" -contains another scrollarea "B" with 2*WRECT_MAX < size < XCOORD_MAX -the widget contained in B has size > XCOORD_MAX -A is scrolled to the the bottom To fix the issue, wrect is moved to the area where the top level window is in the widget coordinate. Task-number: 144779 Reviewed-by: nrc --- src/gui/kernel/qwidget_mac.mm | 23 ++++++++++++++++------- tests/auto/qwidget/tst_qwidget.cpp | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index b0531ec..48e174b 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -3823,7 +3823,6 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect) Qt coordinate system for parent X coordinate system for parent (relative to parent's wrect). */ - QRect wrectRange(-WRECT_MAX,-WRECT_MAX, 2*WRECT_MAX, 2*WRECT_MAX); QRect wrect; //xrect is the X geometry of my X widget. (starts out in parent's Qt coord sys, and ends up in parent's X coord sys) QRect xrect = data.crect; @@ -3845,6 +3844,7 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect) parentWRect = QRect(tmpRect.origin.x, tmpRect.origin.y, tmpRect.size.width, tmpRect.size.height); } else { + const QRect wrectRange(-WRECT_MAX,-WRECT_MAX, 2*WRECT_MAX, 2*WRECT_MAX); parentWRect = wrectRange; } } else { @@ -3900,15 +3900,24 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect) } } - if (xrect.height() > XCOORD_MAX || xrect.width() > XCOORD_MAX) { + const QRect validRange(-XCOORD_MAX,-XCOORD_MAX, 2*XCOORD_MAX, 2*XCOORD_MAX); + if (!validRange.contains(xrect)) { // we are too big, and must clip - xrect &=wrectRange; + QPoint screenOffset(0, 0); // offset of the part being on screen + const QWidget *parentWidget = q->parentWidget(); + while (parentWidget) { + screenOffset -= parentWidget->data->crect.topLeft(); + parentWidget = parentWidget->parentWidget(); + } + QRect cropRect(screenOffset.x() - WRECT_MAX, + screenOffset.y() - WRECT_MAX, + 2*WRECT_MAX, + 2*WRECT_MAX); + + xrect &=cropRect; wrect = xrect; - wrect.translate(-data.crect.topLeft()); - //parent's X coord system is equal to parent's Qt coord - //sys, so we don't need to map xrect. + wrect.translate(-data.crect.topLeft()); // translate wrect in my Qt coordinates } - } // unmap if we are outside the valid window system coord system diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 04ec77d..fa36496 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -353,6 +353,7 @@ private slots: void toplevelLineEditFocus(); void focusWidget_task254563(); + void rectOutsideCoordinatesLimit_task144779(); private: bool ensureScreenSize(int width, int height); @@ -9117,5 +9118,39 @@ void tst_QWidget::focusWidget_task254563() QVERIFY(top.focusWidget() != widget); //dangling pointer } +void tst_QWidget::rectOutsideCoordinatesLimit_task144779() +{ + QWidget main; + QPalette palette; + palette.setColor(QPalette::Window, Qt::red); + main.setPalette(palette); + main.resize(400, 400); + + QWidget *offsetWidget = new QWidget(&main); + offsetWidget->setGeometry(0, -14600, 400, 15000); + + // big widget is too big for the coordinates, it must be limited by wrect + // if wrect is not at the right position because of offsetWidget, bigwidget + // is not painted correctly + QWidget *bigWidget = new QWidget(offsetWidget); + bigWidget->setGeometry(0, 0, 400, 50000); + palette.setColor(QPalette::Window, Qt::green); + bigWidget->setPalette(palette); + bigWidget->setAutoFillBackground(true); + + main.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&main); +#endif + QTest::qWait(100); + QPixmap pixmap = QPixmap::grabWindow(main.winId()); + + QPixmap correct(main.size()); + correct.fill(Qt::green); + + QRect center(100, 100, 200, 200); // to avoid the decorations + QCOMPARE(pixmap.toImage().copy(center), correct.toImage().copy(center)); +} + QTEST_MAIN(tst_QWidget) #include "tst_qwidget.moc" -- cgit v0.12 From e5049ecc4590896a75dedcb098da9e991e1764ee Mon Sep 17 00:00:00 2001 From: Derick Hawcroft Date: Wed, 8 Jul 2009 09:20:31 +1000 Subject: Handle special number cases (nan,{+-}infinity) in PostgreSQL When contructing the EXECUTE statement, there is a special case that we need to handle whereby we explicitly put quotes around the special float values before submutting the statement for execution Task-number:233829 Reviewed-by: Bill King --- src/sql/drivers/psql/qsql_psql.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index 69697da..64b2a23 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -54,6 +54,8 @@ #include #include +#include + #include #include @@ -1144,6 +1146,21 @@ QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const qPQfreemem(data); break; } + case QVariant::Double: { + double val = field.value().toDouble(); + if (isnan(val)) + r = QLatin1String("'NaN'"); + else { + int res = isinf(val); + if (res == 1) + r = QLatin1String("'Infinity'"); + else if (res == -1) + r = QLatin1String("'-Infinity'"); + else + r = QSqlDriver::formatValue(field, trimStrings); + } + break; + } default: r = QSqlDriver::formatValue(field, trimStrings); break; -- cgit v0.12 From c2198e1c7884b835807e45ff53c3c54e86900211 Mon Sep 17 00:00:00 2001 From: Derick Hawcroft Date: Wed, 8 Jul 2009 09:29:33 +1000 Subject: Auto test for task 233829 - postgreSQL specific autotest. Task-number:233829 --- tests/auto/qsqlquery/tst_qsqlquery.cpp | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp index ed19e91..4b41eaf 100644 --- a/tests/auto/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp @@ -188,6 +188,9 @@ private slots: void task_205701_data() { generic_data("QMYSQL"); } void task_205701(); + void task_233829_data() { generic_data(); } + void task_233829(); + private: // returns all database connections @@ -301,7 +304,7 @@ void tst_QSqlQuery::dropTestTables( QSqlDatabase db ) tablenames << qTableName( "qtest_lockedtable" ); tablenames << qTableName( "Planet" ); - + tablenames << qTableName( "task_250026" ); tst_Databases::safeDropTables( db, tablenames ); @@ -2814,5 +2817,30 @@ void tst_QSqlQuery::task_234422() #endif +void tst_QSqlQuery::task_233829() +{ + QFETCH( QString, dbName ); + QSqlDatabase db = QSqlDatabase::database( dbName ); + CHECK_DATABASE( db ); + + if (!db.driverName().startsWith( "QPSQL" )) { + QSKIP( "This is a PostgreSQL specific test", SkipSingle ); + } + + QSqlQuery q( db ); + QString tableName = qTableName("task_233829"); + q.exec("DROP TABLE " + tableName); + QVERIFY_SQL(q,exec("CREATE TABLE " + tableName + " (dbl1 double precision,dbl2 double precision) without oids;")); + + QString queryString("INSERT INTO " + tableName +"(dbl1, dbl2) VALUES(?,?)"); + + double k = 0.0; + QVERIFY_SQL(q,prepare(queryString)); + q.bindValue(0,0.0 / k); // nan + q.bindValue(1,0.0 / k); // nan + QVERIFY_SQL(q,exec()); + q.exec("DROP TABLE " + tableName); +} + QTEST_MAIN( tst_QSqlQuery ) #include "tst_qsqlquery.moc" -- cgit v0.12 From 529df6f1dbcf8992417d03ef2c9c3ec3f2d7bc4b Mon Sep 17 00:00:00 2001 From: Derick Hawcroft Date: Wed, 8 Jul 2009 09:39:53 +1000 Subject: remove debug --- src/sql/drivers/psql/qsql_psql.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index 64b2a23..8de79a3 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -54,7 +54,6 @@ #include #include -#include #include #include -- cgit v0.12 From 355d058a0c7eba3ae3b2a54dda566d94a4134941 Mon Sep 17 00:00:00 2001 From: Derick Hawcroft Date: Wed, 8 Jul 2009 10:50:09 +1000 Subject: safely drop tables. --- tests/auto/qsqlquery/tst_qsqlquery.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp index 4b41eaf..30b85e8 100644 --- a/tests/auto/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp @@ -295,6 +295,9 @@ void tst_QSqlQuery::dropTestTables( QSqlDatabase db ) << qTableName( "blobstest" ) << qTableName( "oraRowId" ); + if ( db.driverName().startsWith("QPSQL") ) + tablenames <<"task_233829"; + if ( db.driverName().startsWith("QSQLITE") ) tablenames << qTableName( "record_sqlite" ); @@ -2839,7 +2842,6 @@ void tst_QSqlQuery::task_233829() q.bindValue(0,0.0 / k); // nan q.bindValue(1,0.0 / k); // nan QVERIFY_SQL(q,exec()); - q.exec("DROP TABLE " + tableName); } QTEST_MAIN( tst_QSqlQuery ) -- cgit v0.12 From 5ff22b1ed4da11dc16a236825c939b5ae38d27cc Mon Sep 17 00:00:00 2001 From: Bill King Date: Wed, 8 Jul 2009 11:09:42 +1000 Subject: Fixes Dericks inf/nan patch for msvc --- src/sql/drivers/psql/qsql_psql.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index 8de79a3..33f2e2b 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -59,7 +59,20 @@ #include #include +#if defined(_MSC_VER) +#include +#define isnan(x) _isnan(x) +int isinf(double x) +{ + if(_fpclass(x) == _FPCLASS_NINF) + return -1; + else if(_fpclass(x) == _FPCLASS_PINF) + return 1; + else return 0; +} +#else #include +#endif // workaround for postgres defining their OIDs in a private header file #define QBOOLOID 16 -- cgit v0.12 From b2e62931f1b2968a69aa013b27a50d2e6beb4e27 Mon Sep 17 00:00:00 2001 From: Bill King Date: Wed, 8 Jul 2009 11:17:40 +1000 Subject: Cleanup more SQL autotest failures. --- tests/auto/qsqldatabase/tst_databases.h | 13 +++++++++++++ tests/auto/qsqldatabase/tst_qsqldatabase.cpp | 7 ++++++- tests/auto/qsqlquery/tst_qsqlquery.cpp | 20 +++++++++----------- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/tests/auto/qsqldatabase/tst_databases.h b/tests/auto/qsqldatabase/tst_databases.h index bd51b97..8ee74df 100644 --- a/tests/auto/qsqldatabase/tst_databases.h +++ b/tests/auto/qsqldatabase/tst_databases.h @@ -249,12 +249,15 @@ public: // addDb( "QODBC3", "DRIVER={SQL Native Client};SERVER=silence.nokia.troll.no\\SQLEXPRESS", "troll", "trond", "" ); // addDb( "QODBC", "DRIVER={MySQL ODBC 3.51 Driver};SERVER=mysql5-nokia.trolltech.com.au;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" ); +// addDb( "QODBC", "DRIVER={MySQL ODBC 5.1 Driver};SERVER=mysql4-nokia.trolltech.com.au;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" ); // addDb( "QODBC", "DRIVER={FreeTDS};SERVER=horsehead.nokia.troll.no;DATABASE=testdb;PORT=4101;UID=troll;PWD=trondk", "troll", "trondk", "" ); // addDb( "QODBC", "DRIVER={FreeTDS};SERVER=silence.nokia.troll.no;DATABASE=testdb;PORT=2392;UID=troll;PWD=trond", "troll", "trond", "" ); // addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2003-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "", "", "" ); // addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2008-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "", "", "" ); // 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() @@ -438,6 +441,16 @@ public: return db.databaseName().contains( "Access Driver", Qt::CaseInsensitive ); } + static bool isPostgreSQL( QSqlDatabase db ) + { + return db.driverName().startsWith("QPSQL") || (db.driverName().startsWith("QODBC") && db.databaseName().contains("PostgreSQL") ); + } + + static bool isMySQL( QSqlDatabase db ) + { + return db.driverName().startsWith("QMYSQL") || (db.driverName().startsWith("QODBC") && db.databaseName().contains("MySQL") ); + } + // -1 on fail, else Oracle version static int getOraVersion( QSqlDatabase db ) { diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index 21064c3..025e895 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -256,6 +256,8 @@ static int createFieldTable(const FieldDef fieldDefs[], QSqlDatabase db) QString autoName = tst_Databases::autoFieldName(db); if (tst_Databases::isMSAccess(db)) qs.append(" (id int not null"); + else if (tst_Databases::isPostgreSQL(db)) + qs.append(" (id serial not null"); else qs.append(QString("(id integer not null %1 primary key").arg(autoName)); @@ -1350,6 +1352,8 @@ void tst_QSqlDatabase::transaction() } QVERIFY_SQL(q, exec("select * from " + qTableName("qtest") + " where id = 41")); + if(db.driverName().startsWith("QODBC") && dbName.contains("MySQL")) + QEXPECT_FAIL("", "Some odbc drivers don't actually roll back despite telling us they do, especially the mysql driver", Continue); QVERIFY(!q.next()); populateTestTables(db); @@ -1427,7 +1431,8 @@ void tst_QSqlDatabase::caseSensivity() bool cs = false; if (db.driverName().startsWith("QMYSQL") || db.driverName().startsWith("QSQLITE") - || db.driverName().startsWith("QTDS")) + || db.driverName().startsWith("QTDS") + || db.driverName().startsWith("QODBC")) cs = true; QSqlRecord rec = db.record(qTableName("qtest")); diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp index 30b85e8..5e782ca 100644 --- a/tests/auto/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp @@ -188,7 +188,7 @@ private slots: void task_205701_data() { generic_data("QMYSQL"); } void task_205701(); - void task_233829_data() { generic_data(); } + void task_233829_data() { generic_data("QPSQL"); } void task_233829(); @@ -322,7 +322,10 @@ void tst_QSqlQuery::createTestTables( QSqlDatabase db ) // in the MySQL server startup script q.exec( "set table_type=innodb" ); - QVERIFY_SQL( q, exec( "create table " + qTableName( "qtest" ) + " (id int "+tst_Databases::autoFieldName(db) +" NOT NULL, t_varchar varchar(20), t_char char(20), primary key(id))" ) ); + if(tst_Databases::isPostgreSQL(db)) + QVERIFY_SQL( q, exec( "create table " + qTableName( "qtest" ) + " (id serial NOT NULL, t_varchar varchar(20), t_char char(20), primary key(id)) WITH OIDS" ) ); + else + QVERIFY_SQL( q, exec( "create table " + qTableName( "qtest" ) + " (id int "+tst_Databases::autoFieldName(db) +" NOT NULL, t_varchar varchar(20), t_char char(20), primary key(id))" ) ); if ( tst_Databases::isSqlServer( db ) || db.driverName().startsWith( "QTDS" ) ) QVERIFY_SQL( q, exec( "create table " + qTableName( "qtest_null" ) + " (id int null, t_varchar varchar(20) null)" ) ); @@ -1874,7 +1877,7 @@ void tst_QSqlQuery::invalidQuery() QVERIFY( !q.next() ); QVERIFY( !q.isActive() ); - if ( !db.driverName().startsWith( "QOCI" ) && !db.driverName().startsWith( "QDB2" ) ) { + if ( !db.driverName().startsWith( "QOCI" ) && !db.driverName().startsWith( "QDB2" ) && !db.driverName().startsWith( "QODBC" ) ) { // oracle and db2 just prepares everything without complaining if ( db.driver()->hasFeature( QSqlDriver::PreparedQueries ) ) QVERIFY( !q.prepare( "blahfasel" ) ); @@ -2034,7 +2037,7 @@ void tst_QSqlQuery::oraArrayBind() q.bindValue( 0, list, QSql::In ); - QVERIFY_SQL( q, execBatch( QSqlQuery::ValuesAsRows ) ); + QVERIFY_SQL( q, execBatch( QSqlQuery::ValuesAsColumns ) ); QVERIFY_SQL( q, prepare( "BEGIN " "ora_array_test.get_table(?); " @@ -2046,7 +2049,7 @@ void tst_QSqlQuery::oraArrayBind() q.bindValue( 0, list, QSql::Out ); - QVERIFY_SQL( q, execBatch( QSqlQuery::ValuesAsRows ) ); + QVERIFY_SQL( q, execBatch( QSqlQuery::ValuesAsColumns ) ); QVariantList out_list = q.boundValue( 0 ).toList(); @@ -2593,7 +2596,7 @@ void tst_QSqlQuery::blobsPreparedQuery() if ( db.driverName().startsWith( "QPSQL" ) ) typeName = "BYTEA"; - else if ( db.driverName().startsWith( "QODBC" ) ) + else if ( db.driverName().startsWith( "QODBC" ) && tst_Databases::isSqlServer( db )) typeName = "IMAGE"; QVERIFY_SQL( q, exec( QString( "CREATE TABLE %1(id INTEGER, data %2)" ).arg( tableName ).arg( typeName ) ) ); @@ -2826,13 +2829,8 @@ void tst_QSqlQuery::task_233829() QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); - if (!db.driverName().startsWith( "QPSQL" )) { - QSKIP( "This is a PostgreSQL specific test", SkipSingle ); - } - QSqlQuery q( db ); QString tableName = qTableName("task_233829"); - q.exec("DROP TABLE " + tableName); QVERIFY_SQL(q,exec("CREATE TABLE " + tableName + " (dbl1 double precision,dbl2 double precision) without oids;")); QString queryString("INSERT INTO " + tableName +"(dbl1, dbl2) VALUES(?,?)"); -- cgit v0.12 From 291279cc24aa543454953b93b1db026caf0d7eb6 Mon Sep 17 00:00:00 2001 From: Bill King Date: Wed, 8 Jul 2009 11:52:38 +1000 Subject: Make the table actually delete before the autotest --- tests/auto/qsqlquery/tst_qsqlquery.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp index 5e782ca..c94b693 100644 --- a/tests/auto/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp @@ -296,7 +296,7 @@ void tst_QSqlQuery::dropTestTables( QSqlDatabase db ) << qTableName( "oraRowId" ); if ( db.driverName().startsWith("QPSQL") ) - tablenames <<"task_233829"; + tablenames << qTableName("task_233829"); if ( db.driverName().startsWith("QSQLITE") ) tablenames << qTableName( "record_sqlite" ); -- cgit v0.12 From 9e2b47da3b88c63acb1b3a8cb7566f2a1e0e18ff Mon Sep 17 00:00:00 2001 From: Derick Hawcroft Date: Wed, 8 Jul 2009 14:47:21 +1000 Subject: make test behave like others --- tests/auto/qsqlquery/tst_qsqlquery.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp index c94b693..0e30873 100644 --- a/tests/auto/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp @@ -2831,7 +2831,7 @@ void tst_QSqlQuery::task_233829() QSqlQuery q( db ); QString tableName = qTableName("task_233829"); - QVERIFY_SQL(q,exec("CREATE TABLE " + tableName + " (dbl1 double precision,dbl2 double precision) without oids;")); + QVERIFY_SQL(q,exec("CREATE TABLE " + tableName + "(dbl1 double precision,dbl2 double precision) without oids;")); QString queryString("INSERT INTO " + tableName +"(dbl1, dbl2) VALUES(?,?)"); -- cgit v0.12 From e33704cdd6f935410dbbdbfedca6ddd648e70f4e Mon Sep 17 00:00:00 2001 From: Bill King Date: Wed, 8 Jul 2009 15:24:36 +1000 Subject: Tables aren't deleting properly. Send the correct name . --- .../qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp index e2dace8..d934b35 100644 --- a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp +++ b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp @@ -167,10 +167,10 @@ void tst_QSqlRelationalTableModel::dropTestTables( QSqlDatabase db ) << qTableName( "reltest3" ) << qTableName( "reltest4" ) << qTableName( "reltest5" ) - << qTableName( "rel test6", db.driver() ) - << qTableName( "rel test7", db.driver() ) - << qTableName("CASETEST1", db.driver() ) - << qTableName("casetest1", db.driver() ); + << qTableName( "rel test6" ) + << qTableName( "rel test7" ) + << qTableName("CASETEST1" ) + << qTableName("casetest1" ); tst_Databases::safeDropTables( db, tableNames ); } -- cgit v0.12 From 4d2f47da2e4869b0419cf13856ddca8a3e34e88a Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Wed, 8 Jul 2009 10:11:03 +0200 Subject: The offset of cropRect should not depend on the position of the window The rect cropRect should be positioned with the offset to the top-level window, not the screen position. --- src/gui/kernel/qwidget_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 48e174b..ad16485 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -3905,7 +3905,7 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect) // we are too big, and must clip QPoint screenOffset(0, 0); // offset of the part being on screen const QWidget *parentWidget = q->parentWidget(); - while (parentWidget) { + while (parentWidget && !parentWidget->isWindow()) { screenOffset -= parentWidget->data->crect.topLeft(); parentWidget = parentWidget->parentWidget(); } -- cgit v0.12 From 7486389a0d742a7c9e70c6110692186f70dbf1e5 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 8 Jul 2009 10:25:04 +0200 Subject: QMainWindow: made use of QPropertyAnimation for animations This required some refactoring as well. Now code is leaner and cleaner --- src/gui/widgets/qmainwindowlayout.cpp | 75 ++++++++++-------------- src/gui/widgets/qmainwindowlayout_p.h | 3 +- src/gui/widgets/qwidgetanimator.cpp | 107 +++++++--------------------------- src/gui/widgets/qwidgetanimator_p.h | 23 ++------ 4 files changed, 59 insertions(+), 149 deletions(-) diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp index 1057f5f..a02dca3 100644 --- a/src/gui/widgets/qmainwindowlayout.cpp +++ b/src/gui/widgets/qmainwindowlayout.cpp @@ -1550,37 +1550,10 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem) return true; } -void QMainWindowLayout::allAnimationsFinished() -{ -#ifndef QT_NO_DOCKWIDGET - parentWidget()->update(layoutState.dockAreaLayout.separatorRegion()); - -#ifndef QT_NO_TABBAR - foreach (QTabBar *tab_bar, usedTabBars) - tab_bar->show(); -#endif // QT_NO_TABBAR -#endif // QT_NO_DOCKWIDGET - - updateGapIndicator(); -} - void QMainWindowLayout::animationFinished(QWidget *widget) { - - /* This signal is delivered from QWidgetAnimator over a qeued connection. The problem is that - the widget can be deleted. This is handled as follows: - - The animator only ever animates widgets that have been added to this layout. If a widget - is deleted during animation, the widget's destructor removes the widget form this layout. - This in turn aborts the animation (see takeAt()) and this signal will never be delivered. - - If the widget is deleted after the animation is finished but before this qeued signal - is delivered, the widget is no longer in the layout and we catch it here. The key is that - QMainWindowLayoutState::contains() never dereferences the pointer. */ - - if (!layoutState.contains(widget)) - return; - + //this function is called from within the Widget Animator whenever an animation is finished + //on a certain widget #ifndef QT_NO_TOOLBAR if (QToolBar *tb = qobject_cast(widget)) { QToolBarLayout *tbl = qobject_cast(tb->layout()); @@ -1593,32 +1566,44 @@ void QMainWindowLayout::animationFinished(QWidget *widget) } #endif - if (widget != pluggingWidget) - return; + if (widget == pluggingWidget) { #ifndef QT_NO_DOCKWIDGET - if (QDockWidget *dw = qobject_cast(widget)) - dw->d_func()->plug(currentGapRect); + if (QDockWidget *dw = qobject_cast(widget)) + dw->d_func()->plug(currentGapRect); #endif #ifndef QT_NO_TOOLBAR - if (QToolBar *tb = qobject_cast(widget)) - tb->d_func()->plug(currentGapRect); + if (QToolBar *tb = qobject_cast(widget)) + tb->d_func()->plug(currentGapRect); #endif - applyState(layoutState, false); + applyState(layoutState, false); #ifndef QT_NO_DOCKWIDGET #ifndef QT_NO_TABBAR - if (qobject_cast(widget) != 0) { - // info() might return null if the widget is destroyed while - // animating but before the animationFinished signal is received. - if (QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(widget)) - info->setCurrentTab(widget); - } + if (qobject_cast(widget) != 0) { + // info() might return null if the widget is destroyed while + // animating but before the animationFinished signal is received. + if (QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(widget)) + info->setCurrentTab(widget); + } #endif #endif - savedState.clear(); - currentGapPos.clear(); - pluggingWidget = 0; + savedState.clear(); + currentGapPos.clear(); + pluggingWidget = 0; + } + + if (!widgetAnimator.animating()) { + //all animations are finished +#ifndef QT_NO_DOCKWIDGET + parentWidget()->update(layoutState.dockAreaLayout.separatorRegion()); +#ifndef QT_NO_TABBAR + foreach (QTabBar *tab_bar, usedTabBars) + tab_bar->show(); +#endif // QT_NO_TABBAR +#endif // QT_NO_DOCKWIDGET + } + updateGapIndicator(); } diff --git a/src/gui/widgets/qmainwindowlayout_p.h b/src/gui/widgets/qmainwindowlayout_p.h index 759461b..a7f70b4 100644 --- a/src/gui/widgets/qmainwindowlayout_p.h +++ b/src/gui/widgets/qmainwindowlayout_p.h @@ -297,9 +297,8 @@ public: void restore(bool keepSavedState = false); void updateHIToolBarStatus(); void animationFinished(QWidget *widget); - void allAnimationsFinished(); -private slots: +private Q_SLOTS: #ifndef QT_NO_DOCKWIDGET #ifndef QT_NO_TABBAR void tabChanged(); diff --git a/src/gui/widgets/qwidgetanimator.cpp b/src/gui/widgets/qwidgetanimator.cpp index 56b3f43..d820b59 100644 --- a/src/gui/widgets/qwidgetanimator.cpp +++ b/src/gui/widgets/qwidgetanimator.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include #include #include @@ -46,47 +47,25 @@ QT_BEGIN_NAMESPACE -static const int g_animation_steps = 12; -static const int g_animation_interval = 16; - -// 1000 * (x/(1 + x*x) + 0.5) on interval [-1, 1] -static const int g_animate_function[] = -{ - 0, 1, 5, 12, 23, 38, 58, 84, 116, 155, 199, 251, 307, 368, - 433, 500, 566, 631, 692, 748, 799, 844, 883, 915, 941, 961, - 976, 987, 994, 998, 1000 -}; -static const int g_animate_function_points = sizeof(g_animate_function)/sizeof(int); - -static inline int animateHelper(int start, int stop, int step, int steps) -{ - if (start == stop) - return start; - if (step == 0) - return start; - if (step == steps) - return stop; - - int x = g_animate_function_points*step/(steps + 1); - return start + g_animate_function[x]*(stop - start)/1000; -} - QWidgetAnimator::QWidgetAnimator(QMainWindowLayout *layout) : m_mainWindowLayout(layout) { } -QWidgetAnimator::~QWidgetAnimator() +void QWidgetAnimator::abort(QWidget *w) { + AnimationMap::iterator it = m_animation_map.find(w); + if (it == m_animation_map.end()) + return; + QPropertyAnimation *anim = *it; + m_animation_map.erase(it); + anim->stop(); + m_mainWindowLayout->animationFinished(w); } -void QWidgetAnimator::abort(QWidget *w) +void QWidgetAnimator::animationFinished() { - if (m_animation_map.remove(w) == 0) - return; - if (m_animation_map.isEmpty()) { - m_timer.stop(); - m_mainWindowLayout->allAnimationsFinished(); - } + QPropertyAnimation *anim = qobject_cast(sender()); + abort(static_cast(anim->targetObject())); } void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, bool animate) @@ -101,16 +80,17 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo animate = false; AnimationMap::const_iterator it = m_animation_map.constFind(widget); - if (it != m_animation_map.constEnd() && (*it).r2 == final_geometry) + if (it != m_animation_map.constEnd() && (*it)->endValue().toRect() == final_geometry) return; if (animate) { - AnimationItem item(widget, r, final_geometry); - m_animation_map[widget] = item; - if (!m_timer.isActive()) { - m_timer.start(g_animation_interval, this); - m_time.start(); - } + QPropertyAnimation *anim = new QPropertyAnimation(widget, "geometry"); + anim->setDuration(200); + anim->setEasingCurve(QEasingCurve::InOutQuad); + anim->setEndValue(final_geometry); + m_animation_map[widget] = anim; + connect(anim, SIGNAL(finished()), SLOT(animationFinished())); + anim->start(QPropertyAnimation::DeleteWhenStopped); } else { if (!final_geometry.isValid() && !widget->isWindow()) { // Make the wigdet go away by sending it to negative space @@ -118,58 +98,15 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo final_geometry = QRect(-500 - s.width(), -500 - s.height(), s.width(), s.height()); } widget->setGeometry(final_geometry); - - if (m_animation_map.remove(widget)) { - m_mainWindowLayout->animationFinished(widget); - if (m_animation_map.isEmpty()) { - m_timer.stop(); - m_mainWindowLayout->allAnimationsFinished(); - } - } - } -} - -void QWidgetAnimator::timerEvent(QTimerEvent *) -{ - int steps = (1 + m_time.restart())/g_animation_interval; - AnimationMap::iterator it = m_animation_map.begin(); - while (it != m_animation_map.end()) { - AnimationItem &item = *it; - - item.step = qMin(item.step + steps, g_animation_steps); - - int x = animateHelper(item.r1.left(), item.r2.left(), - item.step, g_animation_steps); - int y = animateHelper(item.r1.top(), item.r2.top(), - item.step, g_animation_steps); - int w = animateHelper(item.r1.width(), item.r2.width(), - item.step, g_animation_steps); - int h = animateHelper(item.r1.height(), item.r2.height(), - item.step, g_animation_steps); - - item.widget->setGeometry(x, y, w, h); - - if (item.step == g_animation_steps) { - QWidget *widget = item.widget; - it = m_animation_map.erase(it); - m_mainWindowLayout->animationFinished(widget); - } else { - ++it; - } - } - - if (m_animation_map.isEmpty()) { - m_timer.stop(); - m_mainWindowLayout->allAnimationsFinished(); } } bool QWidgetAnimator::animating() const { - return m_timer.isActive(); + return !m_animation_map.isEmpty(); } -bool QWidgetAnimator::animating(QWidget *widget) +bool QWidgetAnimator::animating(QWidget *widget) const { return m_animation_map.contains(widget); } diff --git a/src/gui/widgets/qwidgetanimator_p.h b/src/gui/widgets/qwidgetanimator_p.h index 0c68e00..edd8e7c 100644 --- a/src/gui/widgets/qwidgetanimator_p.h +++ b/src/gui/widgets/qwidgetanimator_p.h @@ -56,41 +56,30 @@ #include #include #include -#include -#include QT_BEGIN_NAMESPACE class QWidget; class QMainWindowLayout; +class QPropertyAnimation; class QWidgetAnimator : public QObject { + Q_OBJECT public: QWidgetAnimator(QMainWindowLayout *layout); - ~QWidgetAnimator(); void animate(QWidget *widget, const QRect &final_geometry, bool animate); bool animating() const; - bool animating(QWidget *widget); + bool animating(QWidget *widget) const; void abort(QWidget *widget); -protected: - void timerEvent(QTimerEvent *e); +private Q_SLOTS: + void animationFinished(); private: - struct AnimationItem { - AnimationItem(QWidget *_widget = 0, const QRect &_r1 = QRect(), - const QRect &_r2 = QRect()) - : widget(_widget), r1(_r1), r2(_r2), step(0) {} - QWidget *widget; - QRect r1, r2; - int step; - }; - typedef QMap AnimationMap; + typedef QMap AnimationMap; AnimationMap m_animation_map; - QBasicTimer m_timer; - QTime m_time; QMainWindowLayout *m_mainWindowLayout; }; -- cgit v0.12 From ed4c85c33683ce541590639f19adcef8dcd001a8 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 8 Jul 2009 12:09:08 +0200 Subject: don't drop all location tags after the first file without any Task-number: 256647 --- tools/linguist/lupdate/main.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/linguist/lupdate/main.cpp b/tools/linguist/lupdate/main.cpp index c28bf8b..52a57fb 100644 --- a/tools/linguist/lupdate/main.cpp +++ b/tools/linguist/lupdate/main.cpp @@ -178,9 +178,10 @@ static void updateTsFiles(const Translator &fetchedTor, const QStringList &tsFil if (options & Verbose) printOut(QObject::tr("Updating '%1'...\n").arg(fn)); + UpdateOptions theseOptions = options; if (tor.locationsType() == Translator::NoLocations) // Could be set from file - options |= NoLocations; - Translator out = merge(tor, fetchedTor, options, err); + theseOptions |= NoLocations; + Translator out = merge(tor, fetchedTor, theseOptions, err); if (!codecForTr.isEmpty()) out.setCodecName(codecForTr); -- cgit v0.12 From 191c621cbaa318e60111ae88c7b1e57286b1368b Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 8 Jul 2009 13:18:24 +0200 Subject: QMainWindow: fixed a crash in some cases when deleting the widget This happened because the rubberband used as a gapindicator was not allocated on the heap and might have been deleted by the QMainWindow destructor. Task-number: 257626 --- src/gui/widgets/qmainwindowlayout.cpp | 16 +++++----------- src/gui/widgets/qmainwindowlayout_p.h | 3 +-- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp index a02dca3..ad608d3 100644 --- a/src/gui/widgets/qmainwindowlayout.cpp +++ b/src/gui/widgets/qmainwindowlayout.cpp @@ -1639,7 +1639,7 @@ QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow) , widgetAnimator(this) , pluggingWidget(0) #ifndef QT_NO_RUBBERBAND - , gapIndicator(QRubberBand::Rectangle, mainwindow) + , gapIndicator(new QRubberBand(QRubberBand::Rectangle, mainwindow)) #endif //QT_NO_RUBBERBAND { #ifndef QT_NO_DOCKWIDGET @@ -1655,8 +1655,8 @@ QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow) #ifndef QT_NO_RUBBERBAND // For accessibility to identify this special widget. - gapIndicator.setObjectName(QLatin1String("qt_rubberband")); - gapIndicator.hide(); + gapIndicator->setObjectName(QLatin1String("qt_rubberband")); + gapIndicator->hide(); #endif pluggingWidget = 0; @@ -1762,14 +1762,8 @@ QLayoutItem *QMainWindowLayout::unplug(QWidget *widget) void QMainWindowLayout::updateGapIndicator() { #ifndef QT_NO_RUBBERBAND - if (widgetAnimator.animating() || currentGapPos.isEmpty()) { - gapIndicator.hide(); - } else { - if (gapIndicator.geometry() != currentGapRect) - gapIndicator.setGeometry(currentGapRect); - if (!gapIndicator.isVisible()) - gapIndicator.show(); - } + gapIndicator->setVisible(!widgetAnimator.animating() && !currentGapPos.isEmpty()); + gapIndicator->setGeometry(currentGapRect); #endif } diff --git a/src/gui/widgets/qmainwindowlayout_p.h b/src/gui/widgets/qmainwindowlayout_p.h index a7f70b4..45f62cd 100644 --- a/src/gui/widgets/qmainwindowlayout_p.h +++ b/src/gui/widgets/qmainwindowlayout_p.h @@ -59,7 +59,6 @@ #include "QtGui/qlayout.h" #include "QtGui/qtabbar.h" -#include "QtGui/qrubberband.h" #include "QtCore/qvector.h" #include "QtCore/qset.h" #include "QtCore/qbasictimer.h" @@ -284,7 +283,7 @@ public: QRect currentGapRect; QWidget *pluggingWidget; #ifndef QT_NO_RUBBERBAND - QRubberBand gapIndicator; + QRubberBand *gapIndicator; #endif QList hover(QLayoutItem *widgetItem, const QPoint &mousePos); -- cgit v0.12 From 12dc33d0e7191dbabb03db989b0f56372de731e3 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 8 Jul 2009 14:19:00 +0200 Subject: QMainWindow: compile fix when defining QT_NO_DOCKWIDGET --- src/gui/widgets/qmainwindowlayout.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp index ad608d3..8fb7c4f 100644 --- a/src/gui/widgets/qmainwindowlayout.cpp +++ b/src/gui/widgets/qmainwindowlayout.cpp @@ -237,7 +237,7 @@ void QMainWindowLayoutState::apply(bool animated) if (centralWidgetItem != 0) { QMainWindowLayout *layout = qobject_cast(mainWindow->layout()); Q_ASSERT(layout != 0); - layout->widgetAnimator->animate(centralWidgetItem->widget(), centralWidgetRect, animated); + layout->widgetAnimator.animate(centralWidgetItem->widget(), centralWidgetRect, animated); } #endif } @@ -946,7 +946,6 @@ void QMainWindowLayout::toggleToolBarsVisible() r = layoutState.toolBarAreaLayout.rectHint(r); r.moveTo(topLeft); parentWidget()->setGeometry(r); -// widgetAnimator->animate(parentWidget(), r, true); } else{ update(); } -- cgit v0.12 From 19a824cfe36458732f12e6374848df37cd92eed8 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 8 Jul 2009 15:12:08 +0200 Subject: Animations: fix compilation with QT_NO_ANIMATION --- src/corelib/animation/qabstractanimation_p.h | 7 ++++++- src/corelib/animation/qanimationgroup_p.h | 4 ++++ src/corelib/animation/qparallelanimationgroup_p.h | 4 ++++ src/corelib/animation/qpropertyanimation_p.h | 6 +++++- .../animation/qsequentialanimationgroup_p.h | 3 +++ src/corelib/animation/qvariantanimation_p.h | 4 ++++ src/gui/itemviews/qcolumnview.cpp | 12 +++++++++++- src/gui/itemviews/qcolumnview_p.h | 2 ++ src/gui/widgets/qwidgetanimator.cpp | 22 +++++++++++++++++++++- src/gui/widgets/qwidgetanimator_p.h | 3 +++ 10 files changed, 63 insertions(+), 4 deletions(-) diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h index 00def55..0d8402e 100644 --- a/src/corelib/animation/qabstractanimation_p.h +++ b/src/corelib/animation/qabstractanimation_p.h @@ -58,6 +58,8 @@ #include #include +#ifndef QT_NO_ANIMATION + QT_BEGIN_NAMESPACE class QAnimationGroup; @@ -147,4 +149,7 @@ private: }; QT_END_NAMESPACE -#endif + +#endif //QT_NO_ANIMATION + +#endif //QABSTRACTANIMATION_P_H diff --git a/src/corelib/animation/qanimationgroup_p.h b/src/corelib/animation/qanimationgroup_p.h index 8e668f0..01252c5 100644 --- a/src/corelib/animation/qanimationgroup_p.h +++ b/src/corelib/animation/qanimationgroup_p.h @@ -59,6 +59,8 @@ #include "private/qabstractanimation_p.h" +#ifndef QT_NO_ANIMATION + QT_BEGIN_NAMESPACE class QAnimationGroupPrivate : public QAbstractAnimationPrivate @@ -76,4 +78,6 @@ public: QT_END_NAMESPACE +#endif //QT_NO_ANIMATION + #endif //QANIMATIONGROUP_P_H diff --git a/src/corelib/animation/qparallelanimationgroup_p.h b/src/corelib/animation/qparallelanimationgroup_p.h index 201eb16..949a9b2 100644 --- a/src/corelib/animation/qparallelanimationgroup_p.h +++ b/src/corelib/animation/qparallelanimationgroup_p.h @@ -57,6 +57,8 @@ #include "private/qanimationgroup_p.h" #include +#ifndef QT_NO_ANIMATION + QT_BEGIN_NAMESPACE class QParallelAnimationGroupPrivate : public QAnimationGroupPrivate @@ -82,4 +84,6 @@ public: QT_END_NAMESPACE +#endif //QT_NO_ANIMATION + #endif //QPARALLELANIMATIONGROUP_P_H diff --git a/src/corelib/animation/qpropertyanimation_p.h b/src/corelib/animation/qpropertyanimation_p.h index 68b2519..a2ae5ec 100644 --- a/src/corelib/animation/qpropertyanimation_p.h +++ b/src/corelib/animation/qpropertyanimation_p.h @@ -58,6 +58,8 @@ #include "private/qvariantanimation_p.h" +#ifndef QT_NO_ANIMATION + QT_BEGIN_NAMESPACE class QPropertyAnimationPrivate : public QVariantAnimationPrivate @@ -86,4 +88,6 @@ public: QT_END_NAMESPACE -#endif +#endif //QT_NO_ANIMATION + +#endif //QPROPERTYANIMATION_P_H diff --git a/src/corelib/animation/qsequentialanimationgroup_p.h b/src/corelib/animation/qsequentialanimationgroup_p.h index 555b696..8db79a0 100644 --- a/src/corelib/animation/qsequentialanimationgroup_p.h +++ b/src/corelib/animation/qsequentialanimationgroup_p.h @@ -56,6 +56,7 @@ #include "qsequentialanimationgroup.h" #include "private/qanimationgroup_p.h" +#ifndef QT_NO_ANIMATION QT_BEGIN_NAMESPACE @@ -108,4 +109,6 @@ public: QT_END_NAMESPACE +#endif //QT_NO_ANIMATION + #endif //QSEQUENTIALANIMATIONGROUP_P_H diff --git a/src/corelib/animation/qvariantanimation_p.h b/src/corelib/animation/qvariantanimation_p.h index b848e12..69e23dc 100644 --- a/src/corelib/animation/qvariantanimation_p.h +++ b/src/corelib/animation/qvariantanimation_p.h @@ -60,6 +60,8 @@ #include "private/qabstractanimation_p.h" +#ifndef QT_NO_ANIMATION + QT_BEGIN_NAMESPACE class QVariantAnimationPrivate : public QAbstractAnimationPrivate @@ -120,4 +122,6 @@ template inline QVariant _q_interpolateVariant(const T &from, const QT_END_NAMESPACE +#endif //QT_NO_ANIMATION + #endif //QANIMATION_P_H diff --git a/src/gui/itemviews/qcolumnview.cpp b/src/gui/itemviews/qcolumnview.cpp index fc89967..c544394 100644 --- a/src/gui/itemviews/qcolumnview.cpp +++ b/src/gui/itemviews/qcolumnview.cpp @@ -107,10 +107,13 @@ void QColumnViewPrivate::initialize() { Q_Q(QColumnView); q->setTextElideMode(Qt::ElideMiddle); +#ifndef QT_NO_ANIMATION QObject::connect(¤tAnimation, SIGNAL(finished()), q, SLOT(_q_changeCurrentColumn())); currentAnimation.setDuration(ANIMATION_DURATION_MSEC); currentAnimation.setTargetObject(hbar); + currentAnimation.setPropertyName("value"); currentAnimation.setEasingCurve(QEasingCurve::InOutQuad); +#endif //QT_NO_ANIMATION delete itemDelegate; q->setItemDelegate(new QColumnViewDelegate(q)); } @@ -260,10 +263,12 @@ void QColumnView::scrollTo(const QModelIndex &index, ScrollHint hint) if (!index.isValid() || d->columns.isEmpty()) return; +#ifndef QT_NO_ANIMATION if (d->currentAnimation.state() == QPropertyAnimation::Running) return; d->currentAnimation.stop(); +#endif //QT_NO_ANIMATION // Fill up what is needed to get to index d->closeColumns(index, true); @@ -326,8 +331,12 @@ void QColumnView::scrollTo(const QModelIndex &index, ScrollHint hint) } } +#ifndef QT_NO_ANIMATION d->currentAnimation.setEndValue(newScrollbarValue); d->currentAnimation.start(); +#else + horizontalScrollBar()->setValue(newScrollbarValue); +#endif //QT_NO_ANIMATION } /*! @@ -396,8 +405,10 @@ void QColumnView::resizeEvent(QResizeEvent *event) void QColumnViewPrivate::updateScrollbars() { Q_Q(QColumnView); +#ifndef QT_NO_ANIMATION if (currentAnimation.state() == QPropertyAnimation::Running) return; +#endif //QT_NO_ANIMATION // find the total horizontal length of the laid out columns int horizontalLength = 0; @@ -1031,7 +1042,6 @@ QColumnViewPrivate::QColumnViewPrivate() : QAbstractItemViewPrivate() ,showResizeGrips(true) ,offset(0) -,currentAnimation(0, "value") // will set the target later ,previewWidget(0) ,previewColumn(0) { diff --git a/src/gui/itemviews/qcolumnview_p.h b/src/gui/itemviews/qcolumnview_p.h index 1a8be70..3f99220 100644 --- a/src/gui/itemviews/qcolumnview_p.h +++ b/src/gui/itemviews/qcolumnview_p.h @@ -160,7 +160,9 @@ public: QVector columnSizes; // used during init and corner moving bool showResizeGrips; int offset; +#ifndef QT_NO_ANIMATION QPropertyAnimation currentAnimation; +#endif QWidget *previewWidget; QAbstractItemView *previewColumn; }; diff --git a/src/gui/widgets/qwidgetanimator.cpp b/src/gui/widgets/qwidgetanimator.cpp index d820b59..7a3a464 100644 --- a/src/gui/widgets/qwidgetanimator.cpp +++ b/src/gui/widgets/qwidgetanimator.cpp @@ -53,6 +53,7 @@ QWidgetAnimator::QWidgetAnimator(QMainWindowLayout *layout) : m_mainWindowLayout void QWidgetAnimator::abort(QWidget *w) { +#ifndef QT_NO_ANIMATION AnimationMap::iterator it = m_animation_map.find(w); if (it == m_animation_map.end()) return; @@ -60,13 +61,18 @@ void QWidgetAnimator::abort(QWidget *w) m_animation_map.erase(it); anim->stop(); m_mainWindowLayout->animationFinished(w); +#else + Q_UNUSED(w); //there is no animation to abort +#endif //QT_NO_ANIMATION } +#ifndef QT_NO_ANIMATION void QWidgetAnimator::animationFinished() { QPropertyAnimation *anim = qobject_cast(sender()); abort(static_cast(anim->targetObject())); } +#endif //QT_NO_ANIMATION void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, bool animate) { @@ -76,6 +82,9 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo if (r.right() < 0 || r.bottom() < 0) r = QRect(); +#ifdef QT_NO_ANIMATION + Q_UNUSED(animate); +#else if (r.isNull() || final_geometry.isNull() || r == final_geometry) animate = false; @@ -91,7 +100,9 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo m_animation_map[widget] = anim; connect(anim, SIGNAL(finished()), SLOT(animationFinished())); anim->start(QPropertyAnimation::DeleteWhenStopped); - } else { + } else +#endif //QT_NO_ANIMATION + { if (!final_geometry.isValid() && !widget->isWindow()) { // Make the wigdet go away by sending it to negative space QSize s = widget->size(); @@ -103,12 +114,21 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo bool QWidgetAnimator::animating() const { +#ifdef QT_NO_ANIMATION + return false; +#else return !m_animation_map.isEmpty(); +#endif //QT_NO_ANIMATION } bool QWidgetAnimator::animating(QWidget *widget) const { +#ifdef QT_NO_ANIMATION + Q_UNUSED(widget); + return false; +#else return m_animation_map.contains(widget); +#endif //QT_NO_ANIMATION } QT_END_NAMESPACE diff --git a/src/gui/widgets/qwidgetanimator_p.h b/src/gui/widgets/qwidgetanimator_p.h index edd8e7c..4047395 100644 --- a/src/gui/widgets/qwidgetanimator_p.h +++ b/src/gui/widgets/qwidgetanimator_p.h @@ -74,12 +74,15 @@ public: void abort(QWidget *widget); +#ifndef QT_NO_ANIMATION private Q_SLOTS: void animationFinished(); private: typedef QMap AnimationMap; AnimationMap m_animation_map; +#endif +private: QMainWindowLayout *m_mainWindowLayout; }; -- cgit v0.12 From a92a6ede9c6a13833d1a6c83b863a5e492b2ba9e Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 8 Jul 2009 13:40:29 +0200 Subject: Cocoa: Plain text from clipboard use '\r' as newline instead of '\n' The 'public.utf16-plain-text' clipboard type maps newlines to '\r' instead of '\n'. The NSStringPboardType from NSPasteboard does this correctly, so first try to get data through this type. Task-number: 257661 Reviewed-by: Norwegian Rock Cat --- src/gui/kernel/qclipboard_mac.cpp | 14 ++++++++++++-- src/gui/kernel/qt_cocoa_helpers_mac.mm | 12 ++++++++++++ src/gui/kernel/qt_cocoa_helpers_mac_p.h | 1 + 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qclipboard_mac.cpp b/src/gui/kernel/qclipboard_mac.cpp index b7b57b8..45050b2 100644 --- a/src/gui/kernel/qclipboard_mac.cpp +++ b/src/gui/kernel/qclipboard_mac.cpp @@ -50,6 +50,7 @@ #include "qurl.h" #include #include +#include "qt_cocoa_helpers_mac_p.h" QT_BEGIN_NAMESPACE @@ -525,8 +526,17 @@ QMacPasteboard::retrieveData(const QString &format, QVariant::Type) const QString c_flavor = c->flavorFor(format); if(!c_flavor.isEmpty()) { // Handle text/plain a little differently. Try handling Unicode first. - if((c_flavor == QLatin1String("com.apple.traditional-mac-plain-text") || c_flavor == QLatin1String("public.utf8-plain-text")) && - hasFlavor(QLatin1String("public.utf16-plain-text"))) + bool checkForUtf16 = (c_flavor == QLatin1String("com.apple.traditional-mac-plain-text") + || c_flavor == QLatin1String("public.utf8-plain-text")); + if (checkForUtf16 || c_flavor == QLatin1String("public.utf16-plain-text")) { + // Try to get the NSStringPboardType from NSPasteboard, newlines are mapped + // correctly (as '\n') in this data. The 'public.utf16-plain-text' type + // usually maps newlines to '\r' instead. + QString str = qt_mac_get_pasteboardString(); + if (!str.isEmpty()) + return str; + } + if (checkForUtf16 && hasFlavor(QLatin1String("public.utf16-plain-text"))) c_flavor = QLatin1String("public.utf16-plain-text"); QVariant ret; diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index 073a00e..13b0e50 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -1131,4 +1131,16 @@ CGFloat qt_mac_get_scalefactor() #endif } +QString qt_mac_get_pasteboardString() +{ + QMacCocoaAutoReleasePool pool; + NSPasteboard *pb = [NSPasteboard generalPasteboard]; + NSString *text = [pb stringForType:NSStringPboardType]; + if (text) { + return qt_mac_NSStringToQString(text); + } else { + return QString(); + } +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qt_cocoa_helpers_mac_p.h b/src/gui/kernel/qt_cocoa_helpers_mac_p.h index 7b975f5..3881ccd 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac_p.h +++ b/src/gui/kernel/qt_cocoa_helpers_mac_p.h @@ -162,6 +162,7 @@ void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list); void qt_syncCocoaTitleBarButtons(OSWindowRef window, QWidget *widgetForWindow); CGFloat qt_mac_get_scalefactor(); +QString qt_mac_get_pasteboardString(); #ifdef __OBJC__ inline NSMutableArray *qt_mac_QStringListToNSMutableArray(const QStringList &qstrlist) -- cgit v0.12 From 94c44ba8d6d1220d00a844d95f9dfb15165ea983 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 8 Jul 2009 14:26:57 +0200 Subject: Phonon: Fixed a possible race condition Task-number: 257495 --- src/3rdparty/phonon/ds9/mediaobject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty/phonon/ds9/mediaobject.cpp b/src/3rdparty/phonon/ds9/mediaobject.cpp index 1d0b69d..26ba8eb 100644 --- a/src/3rdparty/phonon/ds9/mediaobject.cpp +++ b/src/3rdparty/phonon/ds9/mediaobject.cpp @@ -207,10 +207,10 @@ namespace Phonon HRESULT hr = S_OK; + QMutexLocker locker(&m_mutex); m_currentRender = w.graph; m_currentRenderId = w.id; if (w.task == ReplaceGraph) { - QMutexLocker locker(&m_mutex); HANDLE h; int index = -1; -- cgit v0.12 From e21e83b9b81801257337902102ea1b267227de4a Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 2 Jul 2009 14:53:13 +0200 Subject: added auto test tst_QLocalSocket::readBufferOverflow This test handles the case when one limits the size of the socket's read buffer and more data than the buffer size is available. Reviewed-by: ossi --- tests/auto/qlocalsocket/tst_qlocalsocket.cpp | 33 ++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp index 4f1eb1d..0f636a4 100644 --- a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp @@ -80,6 +80,8 @@ private slots: void sendData_data(); void sendData(); + void readBufferOverflow(); + void fullPath(); void hitMaximumConnections_data(); @@ -531,6 +533,37 @@ void tst_QLocalSocket::sendData() QCOMPARE(spy.count(), (canListen ? 1 : 0)); } +void tst_QLocalSocket::readBufferOverflow() +{ + const int readBufferSize = 128; + const int dataBufferSize = readBufferSize * 2; + const QString serverName = QLatin1String("myPreciousTestServer"); + LocalServer server; + server.listen(serverName); + QVERIFY(server.isListening()); + + LocalSocket client; + client.setReadBufferSize(readBufferSize); + client.connectToServer(serverName); + + bool timedOut = true; + QVERIFY(server.waitForNewConnection(3000, &timedOut)); + QVERIFY(!timedOut); + + QCOMPARE(client.state(), QLocalSocket::ConnectedState); + QVERIFY(server.hasPendingConnections()); + + QLocalSocket* serverSocket = server.nextPendingConnection(); + char* buffer = (char*)qMalloc(dataBufferSize); + memset(buffer, 0, dataBufferSize); + serverSocket->write(buffer, dataBufferSize); + serverSocket->flush(); + qFree(buffer); + + QVERIFY(client.waitForReadyRead()); + QCOMPARE(client.readAll().size(), dataBufferSize); +} + // QLocalSocket/Server can take a name or path, check that it works as expected void tst_QLocalSocket::fullPath() { -- cgit v0.12 From 16d23fdced8577e9ad015fd9283373761b8464ef Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 1 Jul 2009 11:06:13 +0200 Subject: fast Windows version of QLocalSocket This commit removes the 100 ms polling timer from QLocalSocket and replaces it with proper overlapped IO handling. Reviewed-by: ossi --- src/network/socket/qlocalsocket.h | 1 + src/network/socket/qlocalsocket_p.h | 16 ++- src/network/socket/qlocalsocket_win.cpp | 241 +++++++++++++++++--------------- 3 files changed, 138 insertions(+), 120 deletions(-) diff --git a/src/network/socket/qlocalsocket.h b/src/network/socket/qlocalsocket.h index 417671a..4bff62e 100644 --- a/src/network/socket/qlocalsocket.h +++ b/src/network/socket/qlocalsocket.h @@ -134,6 +134,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_notified()) Q_PRIVATE_SLOT(d_func(), void _q_canWrite()) Q_PRIVATE_SLOT(d_func(), void _q_pipeClosed()) + Q_PRIVATE_SLOT(d_func(), void _q_emitReadyRead()) #else Q_PRIVATE_SLOT(d_func(), void _q_stateChanged(QAbstractSocket::SocketState)) Q_PRIVATE_SLOT(d_func(), void _q_error(QAbstractSocket::SocketError)) diff --git a/src/network/socket/qlocalsocket_p.h b/src/network/socket/qlocalsocket_p.h index bdbba42..2dae7d9 100644 --- a/src/network/socket/qlocalsocket_p.h +++ b/src/network/socket/qlocalsocket_p.h @@ -65,6 +65,7 @@ #elif defined(Q_OS_WIN) # include "private/qwindowspipewriter_p.h" # include "private/qringbuffer_p.h" +# include #else # include "private/qnativesocketengine_p.h" # include @@ -135,18 +136,23 @@ public: void _q_notified(); void _q_canWrite(); void _q_pipeClosed(); - qint64 readData(char *data, qint64 maxSize); - qint64 bytesAvailable(); - bool readFromSocket(); + void _q_emitReadyRead(); + DWORD bytesAvailable(); + void startAsyncRead(); + void completeAsyncRead(); + void checkReadyRead(); HANDLE handle; OVERLAPPED overlapped; QWindowsPipeWriter *pipeWriter; qint64 readBufferMaxSize; QRingBuffer readBuffer; - QTimer dataNotifier; + int actualReadBufferSize; + QWinEventNotifier *dataReadNotifier; QLocalSocket::LocalSocketError error; - bool readyReadEmitted; + bool readSequenceStarted; + bool pendingReadyRead; bool pipeClosed; + static const qint64 initialReadBufferSize = 4096; #else QLocalUnixSocket unixSocket; QString generateErrorString(QLocalSocket::LocalSocketError, const QString &function) const; diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index b1b69fc..1a971f0 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -48,13 +48,13 @@ QT_BEGIN_NAMESPACE -#define NOTIFYTIMEOUT 100 - void QLocalSocketPrivate::init() { Q_Q(QLocalSocket); - QObject::connect(&dataNotifier, SIGNAL(timeout()), q, SLOT(_q_notified())); + memset(&overlapped, 0, sizeof(overlapped)); overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + dataReadNotifier = new QWinEventNotifier(overlapped.hEvent, q); + q->connect(dataReadNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_notified())); } void QLocalSocketPrivate::setErrorString(const QString &function) @@ -101,8 +101,10 @@ QLocalSocketPrivate::QLocalSocketPrivate() : QIODevicePrivate(), handle(INVALID_HANDLE_VALUE), pipeWriter(0), readBufferMaxSize(0), + actualReadBufferSize(0), error(QLocalSocket::UnknownSocketError), - readyReadEmitted(false), + readSequenceStarted(false), + pendingReadyRead(false), pipeClosed(false), state(QLocalSocket::UnconnectedState) { @@ -176,82 +178,103 @@ void QLocalSocket::connectToServer(const QString &name, OpenMode openMode) qint64 QLocalSocket::readData(char *data, qint64 maxSize) { Q_D(QLocalSocket); - if (d->readBuffer.isEmpty()) { - if (!d->readFromSocket()) { - if (d->pipeClosed) - return -1; - return 0; - } - } - - if (!d->dataNotifier.isActive() && d->threadData->eventDispatcher) - d->dataNotifier.start(NOTIFYTIMEOUT); - - if (d->readBuffer.isEmpty()) - return qint64(0); - // If readFromSocket() read data, copy it to its destination. - if (maxSize == 1) { + qint64 readSoFar; + // If startAsyncRead() read data, copy it to its destination. + if (maxSize == 1 && d->actualReadBufferSize > 0) { *data = d->readBuffer.getChar(); - return 1; + d->actualReadBufferSize--; + readSoFar = 1; + } else { + qint64 bytesToRead = qMin(qint64(d->actualReadBufferSize), maxSize); + readSoFar = 0; + while (readSoFar < bytesToRead) { + const char *ptr = d->readBuffer.readPointer(); + int bytesToReadFromThisBlock = qMin(bytesToRead - readSoFar, + qint64(d->readBuffer.nextDataBlockSize())); + memcpy(data + readSoFar, ptr, bytesToReadFromThisBlock); + readSoFar += bytesToReadFromThisBlock; + d->readBuffer.free(bytesToReadFromThisBlock); + d->actualReadBufferSize -= bytesToReadFromThisBlock; + } } - qint64 bytesToRead = qMin(qint64(d->readBuffer.size()), maxSize); - qint64 readSoFar = 0; - while (readSoFar < bytesToRead) { - const char *ptr = d->readBuffer.readPointer(); - int bytesToReadFromThisBlock = qMin(int(bytesToRead - readSoFar), - d->readBuffer.nextDataBlockSize()); - memcpy(data + readSoFar, ptr, bytesToReadFromThisBlock); - readSoFar += bytesToReadFromThisBlock; - d->readBuffer.free(bytesToReadFromThisBlock); - } + if (!d->readSequenceStarted) + d->startAsyncRead(); + d->checkReadyRead(); + return readSoFar; } /*! \internal - read from the socket + Schedules or cancels a readyRead() emission depending on actual data availability */ -qint64 QLocalSocketPrivate::readData(char *data, qint64 maxSize) +void QLocalSocketPrivate::checkReadyRead() { - DWORD bytesRead = 0; - overlapped.Offset = 0; - overlapped.OffsetHigh = 0; - bool success = ReadFile(handle, data, maxSize, &bytesRead, &overlapped); - if (!success && GetLastError() == ERROR_IO_PENDING) - if (GetOverlappedResult(handle, &overlapped, &bytesRead, TRUE)) - success = true; - if (!success) { - setErrorString(QLatin1String("QLocalSocket::readData")); - return 0; + if (actualReadBufferSize > 0) { + if (!pendingReadyRead) { + Q_Q(QLocalSocket); + QTimer::singleShot(0, q, SLOT(_q_emitReadyRead())); + pendingReadyRead = true; + } + } else { + pendingReadyRead = false; } - return bytesRead; } /*! \internal Reads data from the socket into the readbuffer */ -bool QLocalSocketPrivate::readFromSocket() +void QLocalSocketPrivate::startAsyncRead() { - qint64 bytesToRead = bytesAvailable(); - if (bytesToRead == 0) - return false; + do { + DWORD bytesToRead = bytesAvailable(); + if (bytesToRead == 0) { + // There are no bytes in the pipe but we need to + // start the overlapped read with some buffer size. + bytesToRead = initialReadBufferSize; + } - if (readBufferMaxSize && bytesToRead - > (readBufferMaxSize - readBuffer.size())) - bytesToRead = readBufferMaxSize - readBuffer.size(); + if (readBufferMaxSize && bytesToRead > (readBufferMaxSize - readBuffer.size())) { + bytesToRead = readBufferMaxSize - readBuffer.size(); + if (bytesToRead == 0) { + // Buffer is full. User must read data from the buffer + // before we can read more from the pipe. + return; + } + } - char *ptr = readBuffer.reserve(bytesToRead); - qint64 readBytes = readData(ptr, bytesToRead); - if (readBytes == 0) { - readBuffer.chop(bytesToRead); - return false; + char *ptr = readBuffer.reserve(bytesToRead); + + readSequenceStarted = true; + if (ReadFile(handle, ptr, bytesToRead, NULL, &overlapped)) { + completeAsyncRead(); + } else if (GetLastError() != ERROR_IO_PENDING) { + setErrorString(QLatin1String("QLocalSocketPrivate::startAsyncRead")); + return; + } + } while (!readSequenceStarted); +} + +/*! + \internal + Sets the correct size of the read buffer after a read operation. + */ +void QLocalSocketPrivate::completeAsyncRead() +{ + ResetEvent(overlapped.hEvent); + readSequenceStarted = false; + + DWORD bytesRead; + if (!GetOverlappedResult(handle, &overlapped, &bytesRead, TRUE)) { + setErrorString(QLatin1String("QLocalSocketPrivate::completeAsyncRead")); + return; } - readyReadEmitted = false; - readBuffer.chop(int(bytesToRead - (readBytes < 0 ? qint64(0) : readBytes))); - return true; + + actualReadBufferSize += bytesRead; + readBuffer.truncate(actualReadBufferSize); } qint64 QLocalSocket::writeData(const char *data, qint64 maxSize) @@ -273,7 +296,7 @@ void QLocalSocket::abort() /*! The number of bytes available from the pipe */ -qint64 QLocalSocketPrivate::bytesAvailable() +DWORD QLocalSocketPrivate::bytesAvailable() { Q_Q(QLocalSocket); if (q->state() != QLocalSocket::ConnectedState) @@ -300,7 +323,7 @@ qint64 QLocalSocket::bytesAvailable() const { Q_D(const QLocalSocket); qint64 available = QIODevice::bytesAvailable(); - available += (qint64) d->readBuffer.size(); + available += (qint64) d->actualReadBufferSize; return available; } @@ -327,7 +350,6 @@ void QLocalSocket::close() QIODevice::close(); d->state = ClosingState; emit stateChanged(d->state); - d->readyReadEmitted = false; emit readChannelFinished(); d->serverName = QString(); d->fullServerName = QString(); @@ -336,10 +358,13 @@ void QLocalSocket::close() disconnectFromServer(); return; } + d->readSequenceStarted = false; + d->pendingReadyRead = false; d->pipeClosed = false; DisconnectNamedPipe(d->handle); CloseHandle(d->handle); d->handle = INVALID_HANDLE_VALUE; + ResetEvent(d->overlapped.hEvent); d->state = UnconnectedState; emit stateChanged(d->state); emit disconnected(); @@ -347,7 +372,6 @@ void QLocalSocket::close() delete d->pipeWriter; d->pipeWriter = 0; } - d->dataNotifier.stop(); } bool QLocalSocket::flush() @@ -381,12 +405,15 @@ bool QLocalSocket::setSocketDescriptor(quintptr socketDescriptor, { Q_D(QLocalSocket); d->readBuffer.clear(); + d->actualReadBufferSize = 0; QIODevice::open(openMode); d->handle = (int*)socketDescriptor; d->state = socketState; emit stateChanged(d->state); - if (d->threadData->eventDispatcher) - d->dataNotifier.start(NOTIFYTIMEOUT); + if (d->state == ConnectedState) { + d->startAsyncRead(); + d->checkReadyRead(); + } return true; } @@ -400,20 +427,18 @@ void QLocalSocketPrivate::_q_canWrite() void QLocalSocketPrivate::_q_notified() { Q_Q(QLocalSocket); - if (0 != bytesAvailable()) { - if (readBufferMaxSize == 0 || readBuffer.size() < readBufferMaxSize) { - if (!readFromSocket()) { - return; - } - // wait until buffer is cleared before starting again - if (readBufferMaxSize && readBuffer.size() == readBufferMaxSize) { - dataNotifier.stop(); - } - } - if (!readyReadEmitted) { - readyReadEmitted = true; - q->emit readyRead(); - } + completeAsyncRead(); + startAsyncRead(); + pendingReadyRead = false; + emit q->readyRead(); +} + +void QLocalSocketPrivate::_q_emitReadyRead() +{ + if (pendingReadyRead) { + Q_Q(QLocalSocket); + pendingReadyRead = false; + emit q->readyRead(); } } @@ -448,9 +473,9 @@ bool QLocalSocket::waitForDisconnected(int msecs) return false; QIncrementalSleepTimer timer(msecs); forever { - d->_q_notified(); - if (d->pipeClosed) - close(); + d->bytesAvailable(); // to check if PeekNamedPipe fails + if (d->pipeClosed) + close(); if (state() == UnconnectedState) return true; Sleep(timer.nextSleepTime()); @@ -470,22 +495,24 @@ bool QLocalSocket::isValid() const bool QLocalSocket::waitForReadyRead(int msecs) { Q_D(QLocalSocket); - QIncrementalSleepTimer timer(msecs); - forever { - d->_q_notified(); - if (bytesAvailable() > 0) { - if (!d->readyReadEmitted) { - d->readyReadEmitted = true; - emit readyRead(); - } - return true; - } - Sleep(timer.nextSleepTime()); - if (timer.hasTimedOut()) - break; + if (bytesAvailable() > 0) + return true; + + if (d->state != QLocalSocket::ConnectedState) + return false; + + Q_ASSERT(d->readSequenceStarted); + DWORD result = WaitForSingleObject(d->overlapped.hEvent, msecs == -1 ? INFINITE : msecs); + switch (result) { + case WAIT_OBJECT_0: + d->_q_notified(); + return true; + case WAIT_TIMEOUT: + return false; } + qWarning("QLocalSocket::waitForReadyRead WaitForSingleObject failed with error code %d.", GetLastError()); return false; } @@ -495,27 +522,11 @@ bool QLocalSocket::waitForBytesWritten(int msecs) if (!d->pipeWriter) return false; - QIncrementalSleepTimer timer(msecs); - forever { - if (d->pipeWriter->hadWritten()) - return true; - - if (d->pipeWriter->bytesToWrite() == 0) - return false; - - // Wait for the pipe writer to acknowledge that it has - // written. This will succeed if either the pipe writer has - // already written the data, or if it manages to write data - // within the given timeout. - if (d->pipeWriter->waitForWrite(0)) - return true; - - Sleep(timer.nextSleepTime()); - if (timer.hasTimedOut()) - break; - } - - return false; + // Wait for the pipe writer to acknowledge that it has + // written. This will succeed if either the pipe writer has + // already written the data, or if it manages to write data + // within the given timeout. + return d->pipeWriter->waitForWrite(msecs); } QT_END_NAMESPACE -- cgit v0.12 From 1dd1cb8c70a8986c1acc911a663d99d7043d15c7 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 8 Jul 2009 14:26:57 +0200 Subject: Phonon: Fixed a possible race condition Task-number: 257495 --- src/3rdparty/phonon/ds9/mediaobject.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/3rdparty/phonon/ds9/mediaobject.cpp b/src/3rdparty/phonon/ds9/mediaobject.cpp index 26ba8eb..f77bdc1 100644 --- a/src/3rdparty/phonon/ds9/mediaobject.cpp +++ b/src/3rdparty/phonon/ds9/mediaobject.cpp @@ -207,12 +207,14 @@ namespace Phonon HRESULT hr = S_OK; - QMutexLocker locker(&m_mutex); - m_currentRender = w.graph; - m_currentRenderId = w.id; - if (w.task == ReplaceGraph) { - HANDLE h; + { + QMutexLocker locker(&m_mutex); + m_currentRender = w.graph; + m_currentRenderId = w.id; + } + if (w.task == ReplaceGraph) { + QMutexLocker locker(&m_mutex); int index = -1; for(int i = 0; i < FILTER_COUNT; ++i) { if (m_graphHandle[i].graph == w.oldGraph) { @@ -228,6 +230,7 @@ namespace Phonon Q_ASSERT(index != -1); //add the new graph + HANDLE h; if (SUCCEEDED(ComPointer(w.graph, IID_IMediaEvent) ->GetEventHandle(reinterpret_cast(&h)))) { m_graphHandle[index].graph = w.graph; @@ -324,8 +327,11 @@ namespace Phonon } } - m_currentRender = Graph(); - m_currentRenderId = 0; + { + QMutexLocker locker(&m_mutex); + m_currentRender = Graph(); + m_currentRenderId = 0; + } } -- cgit v0.12 From 0ed214105547980803336337096fd9429ce9f1a1 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 8 Jul 2009 14:46:59 +0200 Subject: Use current license header. --- src/corelib/kernel/qcore_unix_p.h | 4 ++-- src/network/socket/qnet_unix_p.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index 61d8401..1bf2425 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -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 QtCore module 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$ ** ****************************************************************************/ diff --git a/src/network/socket/qnet_unix_p.h b/src/network/socket/qnet_unix_p.h index ffd5b39..392c1e2 100644 --- a/src/network/socket/qnet_unix_p.h +++ b/src/network/socket/qnet_unix_p.h @@ -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 QtNetwork module 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$ ** ****************************************************************************/ -- cgit v0.12 From 0f34ed602bcb00b19b0e550d790ae6521de37aa6 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 8 Jul 2009 14:48:52 +0200 Subject: QMenuBar: the extension could be visible when it shouldn't If you had invisible actions in the menubar, it would always show the extension button --- src/gui/widgets/qmenubar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp index caacc58..be6ed67 100644 --- a/src/gui/widgets/qmenubar.cpp +++ b/src/gui/widgets/qmenubar.cpp @@ -218,7 +218,7 @@ void QMenuBarPrivate::updateGeometries() bool hasHiddenActions = false; for (int i = 0; i < actions.count(); ++i) { const QRect &rect = actionRects.at(i); - if (!menuRect.contains(rect)) { + if (rect.isValid() && !menuRect.contains(rect)) { hasHiddenActions = true; break; } @@ -229,7 +229,7 @@ void QMenuBarPrivate::updateGeometries() menuRect = this->menuRect(true); for (int i = 0; i < actions.count(); ++i) { const QRect &rect = actionRects.at(i); - if (!menuRect.contains(rect)) { + if (rect.isValid() && !menuRect.contains(rect)) { hiddenActions.append(actions.at(i)); } } -- cgit v0.12 From d85d31c50620a215647ab2c3d27636006c04a01d Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Wed, 8 Jul 2009 14:54:59 +0200 Subject: doc: Output a clearer "All functions in this class are..." statement. Task-number: 189232 --- tools/qdoc3/generator.cpp | 168 +++++++++++++++++++++++++++++++++++----------- tools/qdoc3/generator.h | 4 ++ tools/qdoc3/separator.cpp | 36 ++++++---- tools/qdoc3/separator.h | 1 + 4 files changed, 156 insertions(+), 53 deletions(-) diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp index 00831d1..e97b7f2 100644 --- a/tools/qdoc3/generator.cpp +++ b/tools/qdoc3/generator.cpp @@ -68,10 +68,12 @@ QStringList Generator::imageDirs; QString Generator::outDir; QString Generator::project; -static Text stockLink(const QString &target) +static void singularPlural(Text& text, const NodeList& nodes) { - return Text() << Atom(Atom::Link, target) << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) - << target << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); + if (nodes.count() == 1) + text << " is"; + else + text << " are"; } Generator::Generator() @@ -775,64 +777,138 @@ void Generator::generateThreadSafeness(const Node *node, CodeMarker *marker) { Text text; Text theStockLink; - Node::ThreadSafeness parent = node->parent()->inheritedThreadSafeness(); + Node::ThreadSafeness threadSafeness = node->threadSafeness(); + + Text rlink; + rlink << Atom(Atom::Link,"reentrant") + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) + << "reentrant" + << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); - switch (node->threadSafeness()) { + Text tlink; + tlink << Atom(Atom::Link,"thread-safe") + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) + << "thread-safe" + << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); + + switch (threadSafeness) { case Node::UnspecifiedSafeness: break; case Node::NonReentrant: - text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD) << "Warning:" - << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) << " This " - << typeString(node) << " is not " << stockLink("reentrant") << "." << Atom::ParaRight; + text << Atom::ParaLeft + << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD) + << "Warning:" + << Atom(Atom::FormattingRight,ATOM_FORMATTING_BOLD) + << " This " + << typeString(node) + << " is not " + << rlink + << "." + << Atom::ParaRight; break; case Node::Reentrant: case Node::ThreadSafe: - text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD); - if (parent == Node::ThreadSafe) { - text << "Warning:"; - } else { - text << "Note:"; - } - text << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) << " "; - - if (node->threadSafeness() == Node::ThreadSafe) - theStockLink = stockLink("thread-safe"); - else - theStockLink = stockLink("reentrant"); + text << Atom::ParaLeft + << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD) + << "Note:" + << Atom(Atom::FormattingRight,ATOM_FORMATTING_BOLD) + << " "; if (node->isInnerNode()) { - const InnerNode *innerNode = static_cast(node); - text << "All the functions in this " << typeString(node) << " are " - << theStockLink; - - NodeList except; + const InnerNode* innerNode = static_cast(node); + text << "All functions in this " + << typeString(node) + << " are "; + if (threadSafeness == Node::ThreadSafe) + text << tlink; + else + text << rlink; + + bool exceptions = false; + NodeList reentrant; + NodeList threadsafe; + NodeList nonreentrant; NodeList::ConstIterator c = innerNode->childNodes().begin(); while (c != innerNode->childNodes().end()) { - if ((*c)->threadSafeness() != Node::UnspecifiedSafeness) - except.append(*c); + switch ((*c)->threadSafeness()) { + case Node::Reentrant: + reentrant.append(*c); + if (threadSafeness == Node::ThreadSafe) + exceptions = true; + break; + case Node::ThreadSafe: + threadsafe.append(*c); + if (threadSafeness == Node::Reentrant) + exceptions = true; + break; + case Node::NonReentrant: + nonreentrant.append(*c); + exceptions = true; + break; + default: + break; + } ++c; } - if (except.isEmpty()) { + if (!exceptions) text << "."; + else if (threadSafeness == Node::Reentrant) { + if (nonreentrant.isEmpty()) { + if (!threadsafe.isEmpty()) { + text << ", but "; + appendFullNames(text,threadsafe,innerNode,marker); + singularPlural(text,threadsafe); + text << " also " << tlink << "."; + } + else + text << "."; + } + else { + text << ", except for "; + appendFullNames(text,nonreentrant,innerNode,marker); + text << ", which"; + singularPlural(text,nonreentrant); + text << " nonreentrant."; + if (!threadsafe.isEmpty()) { + text << " "; + appendFullNames(text,threadsafe,innerNode,marker); + singularPlural(text,threadsafe); + text << " " << tlink << "."; + } + } } - else { - text << ", except "; - - NodeList::ConstIterator e = except.begin(); - int index = 0; - while (e != except.end()) { - appendFullName(text, *e, innerNode, marker); - text << separator(index++, except.count()); - ++e; + else { // thread-safe + if (!nonreentrant.isEmpty() || !reentrant.isEmpty()) { + text << ", except for "; + if (!reentrant.isEmpty()) { + appendFullNames(text,reentrant,innerNode,marker); + text << ", which"; + singularPlural(text,reentrant); + text << " only " << rlink; + if (!nonreentrant.isEmpty()) + text << ", and "; + } + if (!nonreentrant.isEmpty()) { + appendFullNames(text,nonreentrant,innerNode,marker); + text << ", which"; + singularPlural(text,nonreentrant); + text << " nonreentrant."; + } + text << "."; } } } else { - text << "This " << typeString(node) << " is " << theStockLink << "."; + text << "This " << typeString(node) << " is "; + if (threadSafeness == Node::ThreadSafe) + text << tlink; + else + text << rlink; + text << "."; } text << Atom::ParaRight; } - generateText(text, node, marker); + generateText(text,node,marker); } void Generator::generateSince(const Node *node, CodeMarker *marker) @@ -966,6 +1042,20 @@ void Generator::appendFullName(Text& text, << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); } +void Generator::appendFullNames(Text& text, + const NodeList& nodes, + const Node* relative, + CodeMarker* marker) +{ + NodeList::ConstIterator n = nodes.begin(); + int index = 0; + while (n != nodes.end()) { + appendFullName(text,*n,relative,marker); + text << comma(index++,nodes.count()); + ++n; + } +} + void Generator::appendSortedNames(Text& text, const ClassNode *classe, const QList &classes, diff --git a/tools/qdoc3/generator.h b/tools/qdoc3/generator.h index 08b857b..cdc4c29 100644 --- a/tools/qdoc3/generator.h +++ b/tools/qdoc3/generator.h @@ -154,6 +154,10 @@ class Generator const Node *apparentNode, const QString& fullName, const Node *actualNode); + void appendFullNames(Text& text, + const NodeList& nodes, + const Node* relative, + CodeMarker* marker); void appendSortedNames(Text& text, const ClassNode *classe, const QList &classes, diff --git a/tools/qdoc3/separator.cpp b/tools/qdoc3/separator.cpp index 8f27f90..60674be 100644 --- a/tools/qdoc3/separator.cpp +++ b/tools/qdoc3/separator.cpp @@ -48,22 +48,30 @@ QT_BEGIN_NAMESPACE -QString separator( int index, int count ) +QString separator(int index, int count) { - if ( index == count - 1 ) - return tr( ".", "terminator" ); + if (index == count - 1) + return tr(".", "terminator"); + if (count == 2) + return tr(" and ", "separator when N = 2"); + if (index == 0) + return tr(", ", "first separator when N > 2"); + if (index < count - 2) + return tr(", ", "general separator when N > 2"); + return tr(", and ", "last separator when N > 2"); +} - if ( count == 2 ) { - return tr( " and ", "separator when N = 2" ); - } else { - if ( index == 0 ) { - return tr( ", ", "first separator when N > 2" ); - } else if ( index < count - 2 ) { - return tr( ", ", "general separator when N > 2" ); - } else { - return tr( ", and ", "last separator when N > 2" ); - } - } +QString comma(int index, int count) +{ + if (index == count - 1) + return QString(""); + if (count == 2) + return tr(" and ", "separator when N = 2"); + if (index == 0) + return tr(", ", "first separator when N > 2"); + if (index < count - 2) + return tr(", ", "general separator when N > 2"); + return tr(", and ", "last separator when N > 2"); } QT_END_NAMESPACE diff --git a/tools/qdoc3/separator.h b/tools/qdoc3/separator.h index 70ba624..2336d94 100644 --- a/tools/qdoc3/separator.h +++ b/tools/qdoc3/separator.h @@ -51,6 +51,7 @@ QT_BEGIN_NAMESPACE QString separator( int index, int count ); +QString comma( int index, int count ); QT_END_NAMESPACE -- cgit v0.12 From 48f049d6fbddd60d99fb6ebc15fd5b52a3b515ec Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Wed, 8 Jul 2009 16:23:21 +0200 Subject: Update QGroupBox on focus We cannot assume the position of the decorations when a QGroupBox get the focus. Task-number: 257660 Reviewed-by: Thierry --- src/gui/widgets/qgroupbox.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/gui/widgets/qgroupbox.cpp b/src/gui/widgets/qgroupbox.cpp index fe882a6..022c377 100644 --- a/src/gui/widgets/qgroupbox.cpp +++ b/src/gui/widgets/qgroupbox.cpp @@ -479,11 +479,7 @@ void QGroupBox::focusInEvent(QFocusEvent *fe) if (focusPolicy() == Qt::NoFocus) { d->_q_fixFocus(fe->reason()); } else { - QStyleOptionGroupBox box; - initStyleOption(&box); - QRect rect = style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxCheckBox, this) - | style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxLabel, this); - update(rect); + QWidget::focusInEvent(fe); } } -- cgit v0.12 From e95f4fb1c11795625be8b3b4adc62ed3c520a467 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 8 Jul 2009 16:36:30 +0200 Subject: autotest compile fix for MacOSX --- tests/auto/qfontdialog/tst_qfontdialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qfontdialog/tst_qfontdialog.cpp b/tests/auto/qfontdialog/tst_qfontdialog.cpp index 1444ee0..5f1797b 100644 --- a/tests/auto/qfontdialog/tst_qfontdialog.cpp +++ b/tests/auto/qfontdialog/tst_qfontdialog.cpp @@ -156,7 +156,7 @@ void tst_QFontDialog::setFont() class FriendlyFontDialog : public QFontDialog { - friend tst_QFontDialog; + friend class tst_QFontDialog; Q_DECLARE_PRIVATE(QFontDialog); }; -- cgit v0.12 From c02a9925f10fbf1a4883983f35c735666862a3f6 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 8 Jul 2009 15:48:57 +0200 Subject: Compile fix for the qapplication autotest. Reviewed-by: TrustMe --- tests/auto/qapplication/tst_qapplication.cpp | 68 ++++++++++++++++++---------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/tests/auto/qapplication/tst_qapplication.cpp b/tests/auto/qapplication/tst_qapplication.cpp index 85494af..8532723 100644 --- a/tests/auto/qapplication/tst_qapplication.cpp +++ b/tests/auto/qapplication/tst_qapplication.cpp @@ -1820,27 +1820,38 @@ void tst_QApplication::touchEventPropagation() { int argc = 1; QApplication app(argc, &argv0, QApplication::GuiServer); - QTouchEvent::TouchPoint touchPoint(0); - QTouchEvent touchEvent(QEvent::TouchBegin, Qt::NoModifier, QList() << (&touchPoint)); + + QList pressedTouchPoints; + QTouchEvent::TouchPoint press(0); + press.setState(Qt::TouchPointPressed); + pressedTouchPoints << press; + + QList releasedTouchPoints; + QTouchEvent::TouchPoint release(0); + release.setState(Qt::TouchPointReleased); + releasedTouchPoints << release; { // touch event behavior on a window TouchEventPropagationTestWidget window; window.setObjectName("1. window"); - QApplicationPrivate::sendTouchEvent(&window, &touchEvent); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); QVERIFY(!window.seenTouchEvent); - QVERIFY(window.seenMouseEvent); + QVERIFY(!window.seenMouseEvent); window.reset(); - window.setAttribute(Qt::WA_AcceptsTouchEvents); - QApplicationPrivate::sendTouchEvent(&window, &touchEvent); + window.setAttribute(Qt::WA_AcceptTouchEvents); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); QVERIFY(window.seenTouchEvent); - QVERIFY(window.seenMouseEvent); + QVERIFY(!window.seenMouseEvent); window.reset(); window.acceptTouchEvent = true; - QApplicationPrivate::sendTouchEvent(&window, &touchEvent); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); QVERIFY(window.seenTouchEvent); QVERIFY(!window.seenMouseEvent); } @@ -1852,34 +1863,38 @@ void tst_QApplication::touchEventPropagation() TouchEventPropagationTestWidget widget(&window); widget.setObjectName("2. widget"); - QApplicationPrivate::sendTouchEvent(&widget, &touchEvent); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); QVERIFY(!widget.seenTouchEvent); - QVERIFY(widget.seenMouseEvent); + QVERIFY(!widget.seenMouseEvent); QVERIFY(!window.seenTouchEvent); - QVERIFY(window.seenMouseEvent); + QVERIFY(!window.seenMouseEvent); window.reset(); widget.reset(); - widget.setAttribute(Qt::WA_AcceptsTouchEvents); - QApplicationPrivate::sendTouchEvent(&widget, &touchEvent); + widget.setAttribute(Qt::WA_AcceptTouchEvents); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); QVERIFY(widget.seenTouchEvent); - QVERIFY(widget.seenMouseEvent); + QVERIFY(!widget.seenMouseEvent); QVERIFY(!window.seenTouchEvent); - QVERIFY(window.seenMouseEvent); + QVERIFY(!window.seenMouseEvent); window.reset(); widget.reset(); widget.acceptMouseEvent = true; - QApplicationPrivate::sendTouchEvent(&widget, &touchEvent); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); QVERIFY(widget.seenTouchEvent); - QVERIFY(widget.seenMouseEvent); + QVERIFY(!widget.seenMouseEvent); QVERIFY(!window.seenTouchEvent); QVERIFY(!window.seenMouseEvent); window.reset(); widget.reset(); widget.acceptTouchEvent = true; - QApplicationPrivate::sendTouchEvent(&widget, &touchEvent); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); QVERIFY(widget.seenTouchEvent); QVERIFY(!widget.seenMouseEvent); QVERIFY(!window.seenTouchEvent); @@ -1887,18 +1902,20 @@ void tst_QApplication::touchEventPropagation() window.reset(); widget.reset(); - widget.setAttribute(Qt::WA_AcceptsTouchEvents, false); - window.setAttribute(Qt::WA_AcceptsTouchEvents); - QApplicationPrivate::sendTouchEvent(&widget, &touchEvent); + widget.setAttribute(Qt::WA_AcceptTouchEvents, false); + window.setAttribute(Qt::WA_AcceptTouchEvents); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); QVERIFY(!widget.seenTouchEvent); - QVERIFY(widget.seenMouseEvent); + QVERIFY(!widget.seenMouseEvent); QVERIFY(window.seenTouchEvent); - QVERIFY(window.seenMouseEvent); + QVERIFY(!window.seenMouseEvent); window.reset(); widget.reset(); window.acceptTouchEvent = true; - QApplicationPrivate::sendTouchEvent(&widget, &touchEvent); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); QVERIFY(!widget.seenTouchEvent); QVERIFY(!widget.seenMouseEvent); QVERIFY(window.seenTouchEvent); @@ -1908,7 +1925,8 @@ void tst_QApplication::touchEventPropagation() widget.reset(); widget.acceptMouseEvent = true; // doesn't matter, touch events are propagated first window.acceptTouchEvent = true; - QApplicationPrivate::sendTouchEvent(&widget, &touchEvent); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); + qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); QVERIFY(!widget.seenTouchEvent); QVERIFY(!widget.seenMouseEvent); QVERIFY(window.seenTouchEvent); -- cgit v0.12 From c2f2b6509fcd91617ae3eb860d6d3f947c5ea443 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 8 Jul 2009 16:34:55 +0200 Subject: QMainWindow: fix the use of animation and improve code quality --- src/gui/widgets/qmainwindowlayout.cpp | 33 +++++++++++----------- src/gui/widgets/qwidgetanimator.cpp | 53 +++++++++++++---------------------- src/gui/widgets/qwidgetanimator_p.h | 4 +-- 3 files changed, 38 insertions(+), 52 deletions(-) diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp index 8fb7c4f..aba9120 100644 --- a/src/gui/widgets/qmainwindowlayout.cpp +++ b/src/gui/widgets/qmainwindowlayout.cpp @@ -1527,24 +1527,20 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem) layoutState.remove(previousPath); pluggingWidget = widget; - if (dockOptions & QMainWindow::AnimatedDocks) { - QRect globalRect = currentGapRect; - globalRect.moveTopLeft(parentWidget()->mapToGlobal(globalRect.topLeft())); + QRect globalRect = currentGapRect; + globalRect.moveTopLeft(parentWidget()->mapToGlobal(globalRect.topLeft())); #ifndef QT_NO_DOCKWIDGET - if (qobject_cast(widget) != 0) { - QDockWidgetLayout *layout = qobject_cast(widget->layout()); - if (layout->nativeWindowDeco()) { - globalRect.adjust(0, layout->titleHeight(), 0, 0); - } else { - int fw = widget->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, widget); - globalRect.adjust(-fw, -fw, fw, fw); - } + if (qobject_cast(widget) != 0) { + QDockWidgetLayout *layout = qobject_cast(widget->layout()); + if (layout->nativeWindowDeco()) { + globalRect.adjust(0, layout->titleHeight(), 0, 0); + } else { + int fw = widget->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, widget); + globalRect.adjust(-fw, -fw, fw, fw); } -#endif - widgetAnimator.animate(widget, globalRect, true); - } else { - animationFinished(widget); } +#endif + widgetAnimator.animate(widget, globalRect, dockOptions & QMainWindow::AnimatedDocks); return true; } @@ -1576,9 +1572,11 @@ void QMainWindowLayout::animationFinished(QWidget *widget) tb->d_func()->plug(currentGapRect); #endif - applyState(layoutState, false); #ifndef QT_NO_DOCKWIDGET #ifndef QT_NO_TABBAR + //it is important to set the current tab before applying the layout + //so that applyState will not try to counter the result of the animation + //by putting the item in negative space if (qobject_cast(widget) != 0) { // info() might return null if the widget is destroyed while // animating but before the animationFinished signal is received. @@ -1587,6 +1585,9 @@ void QMainWindowLayout::animationFinished(QWidget *widget) } #endif #endif + + applyState(layoutState, false); + savedState.clear(); currentGapPos.clear(); pluggingWidget = 0; diff --git a/src/gui/widgets/qwidgetanimator.cpp b/src/gui/widgets/qwidgetanimator.cpp index 7a3a464..26cf905 100644 --- a/src/gui/widgets/qwidgetanimator.cpp +++ b/src/gui/widgets/qwidgetanimator.cpp @@ -76,59 +76,46 @@ void QWidgetAnimator::animationFinished() void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, bool animate) { - QRect final_geometry = _final_geometry; - QRect r = widget->geometry(); if (r.right() < 0 || r.bottom() < 0) r = QRect(); -#ifdef QT_NO_ANIMATION - Q_UNUSED(animate); -#else - if (r.isNull() || final_geometry.isNull() || r == final_geometry) - animate = false; + animate = animate && !r.isNull() && !_final_geometry.isNull(); + + // might make the wigdet go away by sending it to negative space + const QRect final_geometry = _final_geometry.isValid() || widget->isWindow() ? _final_geometry : + QRect(QPoint(-500 - widget->width(), -500 - widget->height()), widget->size()); + if (r == final_geometry) + return; //the widget is already where it should be +#ifndef QT_NO_ANIMATION AnimationMap::const_iterator it = m_animation_map.constFind(widget); if (it != m_animation_map.constEnd() && (*it)->endValue().toRect() == final_geometry) return; - if (animate) { - QPropertyAnimation *anim = new QPropertyAnimation(widget, "geometry"); - anim->setDuration(200); - anim->setEasingCurve(QEasingCurve::InOutQuad); - anim->setEndValue(final_geometry); - m_animation_map[widget] = anim; - connect(anim, SIGNAL(finished()), SLOT(animationFinished())); - anim->start(QPropertyAnimation::DeleteWhenStopped); - } else + QPropertyAnimation *anim = new QPropertyAnimation(widget, "geometry"); + anim->setDuration(animate ? 200 : 0); + anim->setEasingCurve(QEasingCurve::InOutQuad); + anim->setEndValue(final_geometry); + m_animation_map[widget] = anim; + connect(anim, SIGNAL(finished()), SLOT(animationFinished())); + anim->start(QPropertyAnimation::DeleteWhenStopped); + Q_ASSERT(animate || widget->geometry() == final_geometry); +#else + //we do it in one shot + widget->setGeometry(final_geometry); + m_mainWindowLayout->animationFinished(widget); #endif //QT_NO_ANIMATION - { - if (!final_geometry.isValid() && !widget->isWindow()) { - // Make the wigdet go away by sending it to negative space - QSize s = widget->size(); - final_geometry = QRect(-500 - s.width(), -500 - s.height(), s.width(), s.height()); - } - widget->setGeometry(final_geometry); - } } bool QWidgetAnimator::animating() const { -#ifdef QT_NO_ANIMATION - return false; -#else return !m_animation_map.isEmpty(); -#endif //QT_NO_ANIMATION } bool QWidgetAnimator::animating(QWidget *widget) const { -#ifdef QT_NO_ANIMATION - Q_UNUSED(widget); - return false; -#else return m_animation_map.contains(widget); -#endif //QT_NO_ANIMATION } QT_END_NAMESPACE diff --git a/src/gui/widgets/qwidgetanimator_p.h b/src/gui/widgets/qwidgetanimator_p.h index 4047395..64697a9 100644 --- a/src/gui/widgets/qwidgetanimator_p.h +++ b/src/gui/widgets/qwidgetanimator_p.h @@ -54,7 +54,6 @@ // #include -#include #include QT_BEGIN_NAMESPACE @@ -77,12 +76,11 @@ public: #ifndef QT_NO_ANIMATION private Q_SLOTS: void animationFinished(); +#endif private: typedef QMap AnimationMap; AnimationMap m_animation_map; -#endif -private: QMainWindowLayout *m_mainWindowLayout; }; -- cgit v0.12 From cf7ca87e057ef3810c5db36ff975a98f532a8dc0 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 8 Jul 2009 17:00:43 +0200 Subject: Make test pass when executed from debug/release directory. --- tests/auto/qchar/tst_qchar.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/auto/qchar/tst_qchar.cpp b/tests/auto/qchar/tst_qchar.cpp index 01ba534..512c180 100644 --- a/tests/auto/qchar/tst_qchar.cpp +++ b/tests/auto/qchar/tst_qchar.cpp @@ -500,6 +500,9 @@ void tst_QChar::normalization() } QFile f("NormalizationTest.txt"); + // Windows - current directory is the debug/release subdirectory where the executable is located + if (!f.exists()) + f.setFileName("../NormalizationTest.txt");; if (!f.exists()) { QFAIL("Couldn't find NormalizationTest.txt"); return; -- cgit v0.12 From b358143b7eb5dc3d76a09e501914fa00d0c3876c Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 8 Jul 2009 17:02:23 +0200 Subject: Define M_PI in qmath.h if not defined by math.h (as is the case on Windows), and remove duplicate defines elsewhere. --- src/corelib/kernel/qmath.h | 4 ++++ src/gui/math3d/qmatrix4x4.cpp | 4 ---- src/gui/math3d/qquaternion.cpp | 4 ---- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/corelib/kernel/qmath.h b/src/corelib/kernel/qmath.h index 348957f..7a77d56 100644 --- a/src/corelib/kernel/qmath.h +++ b/src/corelib/kernel/qmath.h @@ -132,6 +132,10 @@ inline qreal qPow(qreal x, qreal y) return pow(x, y); } +#ifndef M_PI +#define M_PI (3.14159265358979323846) +#endif + QT_END_NAMESPACE QT_END_HEADER diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp index 9fe487b..b998353 100644 --- a/src/gui/math3d/qmatrix4x4.cpp +++ b/src/gui/math3d/qmatrix4x4.cpp @@ -1004,10 +1004,6 @@ QMatrix4x4& QMatrix4x4::rotate(qreal angle, const QVector3D& vector) #endif -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - /*! \overload diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp index 17c4373..9988e2b 100644 --- a/src/gui/math3d/qquaternion.cpp +++ b/src/gui/math3d/qquaternion.cpp @@ -339,10 +339,6 @@ QVector3D QQuaternion::rotateVector(const QVector3D& vector) const \sa operator*=() */ -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - #ifndef QT_NO_VECTOR3D /*! -- cgit v0.12 From 1336f8268512a4ad29732acf75f2e6c4d41683ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Tue, 7 Jul 2009 10:31:52 +0200 Subject: Reduce QTransform operations in Graphics View. Use the item's cached scene transform directly instead of always making a copy of it. Moreover, we don't have to use the transform at all if the scene transform is a "translate only" transform :-). QTransform already use the same cut-offs, but it must update the type() before it can find out. We don't have to check the type() because that is already stored (and we usually don't call type() when we store the value either). All auto-tests pass. --- src/gui/graphicsview/qgraphicsitem.cpp | 140 +++++++++++++++++++++++++------- src/gui/graphicsview/qgraphicsitem_p.h | 16 +++- src/gui/graphicsview/qgraphicsscene.cpp | 86 +++++++++++++------- src/gui/graphicsview/qgraphicsview.cpp | 7 +- 4 files changed, 188 insertions(+), 61 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 9a27ef5..85d76d4 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -821,6 +821,42 @@ void QGraphicsItemPrivate::combineTransformFromParent(QTransform *x, const QTran } } +void QGraphicsItemPrivate::updateSceneTransformFromParent() +{ + if (parent) { + Q_ASSERT(!parent->d_ptr->dirtySceneTransform); + if (parent->d_ptr->sceneTransformTranslateOnly) { + sceneTransform = QTransform::fromTranslate(parent->d_ptr->sceneTransform.dx() + pos.x(), + parent->d_ptr->sceneTransform.dy() + pos.y()); + } else { + sceneTransform = parent->d_ptr->sceneTransform; + sceneTransform.translate(pos.x(), pos.y()); + } + if (transformData) { + sceneTransform = transformData->computedFullTransform(&sceneTransform); + sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate); + } else { + sceneTransformTranslateOnly = parent->d_ptr->sceneTransformTranslateOnly; + } + } else if (!transformData) { + sceneTransform = QTransform::fromTranslate(pos.x(), pos.y()); + sceneTransformTranslateOnly = 1; + } else if (transformData->onlyTransform) { + sceneTransform = transformData->transform; + if (!pos.isNull()) + sceneTransform *= QTransform::fromTranslate(pos.x(), pos.y()); + sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate); + } else if (pos.isNull()) { + sceneTransform = transformData->computedFullTransform(); + sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate); + } else { + sceneTransform = QTransform::fromTranslate(pos.x(), pos.y()); + sceneTransform = transformData->computedFullTransform(&sceneTransform); + sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate); + } + dirtySceneTransform = 0; +} + /*! \internal @@ -3145,7 +3181,8 @@ void QGraphicsItem::setTransformOrigin(const QPointF &origin) */ QMatrix QGraphicsItem::sceneMatrix() const { - return sceneTransform().toAffine(); + d_ptr->ensureSceneTransform(); + return d_ptr->sceneTransform.toAffine(); } @@ -3168,16 +3205,7 @@ QMatrix QGraphicsItem::sceneMatrix() const */ QTransform QGraphicsItem::sceneTransform() const { - if (d_ptr->dirtySceneTransform) { - // This item and all its descendants have dirty scene transforms. - // We're about to validate this item's scene transform, so we have to - // invalidate all the children; otherwise there's no way for the descendants - // to detect that the ancestor has changed. - d_ptr->invalidateChildrenSceneTransform(); - } - - QGraphicsItem *that = const_cast(this); - d_ptr->ensureSceneTransformRecursive(&that); + d_ptr->ensureSceneTransform(); return d_ptr->sceneTransform; } @@ -3207,8 +3235,10 @@ QTransform QGraphicsItem::sceneTransform() const QTransform QGraphicsItem::deviceTransform(const QTransform &viewportTransform) const { // Ensure we return the standard transform if we're not untransformable. - if (!d_ptr->itemIsUntransformable()) - return sceneTransform() * viewportTransform; + if (!d_ptr->itemIsUntransformable()) { + d_ptr->ensureSceneTransform(); + return d_ptr->sceneTransform * viewportTransform; + } // Find the topmost item that ignores view transformations. const QGraphicsItem *untransformedAncestor = this; @@ -3227,7 +3257,8 @@ QTransform QGraphicsItem::deviceTransform(const QTransform &viewportTransform) c } // First translate the base untransformable item. - QPointF mappedPoint = (untransformedAncestor->sceneTransform() * viewportTransform).map(QPointF(0, 0)); + untransformedAncestor->d_ptr->ensureSceneTransform(); + QPointF mappedPoint = (untransformedAncestor->d_ptr->sceneTransform * viewportTransform).map(QPointF(0, 0)); // COMBINE QTransform matrix = QTransform::fromTranslate(mappedPoint.x(), mappedPoint.y()); @@ -3320,8 +3351,11 @@ QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) co // Find the closest common ancestor. If the two items don't share an // ancestor, then the only way is to combine their scene transforms. const QGraphicsItem *commonAncestor = commonAncestorItem(other); - if (!commonAncestor) - return sceneTransform() * other->sceneTransform().inverted(ok); + if (!commonAncestor) { + d_ptr->ensureSceneTransform(); + other->d_ptr->ensureSceneTransform(); + return d_ptr->sceneTransform * other->d_ptr->sceneTransform.inverted(ok); + } // If the two items are cousins (in sibling branches), map both to the // common ancestor, and combine the two transforms. @@ -3716,7 +3750,13 @@ QRectF QGraphicsItem::sceneBoundingRect() const QRectF br = boundingRect(); br.translate(offset); - return !parentItem ? br : parentItem->sceneTransform().mapRect(br); + if (!parentItem) + return br; + if (parentItem->d_ptr->hasTranslateOnlySceneTransform()) { + br.translate(parentItem->d_ptr->sceneTransform.dx(), parentItem->d_ptr->sceneTransform.dy()); + return br; + } + return parentItem->d_ptr->sceneTransform.mapRect(br); } /*! @@ -4484,9 +4524,22 @@ void QGraphicsItemPrivate::ensureSceneTransformRecursive(QGraphicsItem **topMost } // COMBINE my transform with the parent's scene transform. - sceneTransform = parent ? parent->d_ptr->sceneTransform : QTransform(); - combineTransformFromParent(&sceneTransform); - dirtySceneTransform = 0; + updateSceneTransformFromParent(); + Q_ASSERT(!dirtySceneTransform); +} + +void QGraphicsItemPrivate::ensureSceneTransform() +{ + if (dirtySceneTransform) { + // This item and all its descendants have dirty scene transforms. + // We're about to validate this item's scene transform, so we have to + // invalidate all the children; otherwise there's no way for the descendants + // to detect that the ancestor has changed. + invalidateChildrenSceneTransform(); + } + + QGraphicsItem *that = q_func(); + ensureSceneTransformRecursive(&that); } /*! @@ -4827,7 +4880,9 @@ QPointF QGraphicsItem::mapToParent(const QPointF &point) const */ QPointF QGraphicsItem::mapToScene(const QPointF &point) const { - return sceneTransform().map(point); + if (d_ptr->hasTranslateOnlySceneTransform()) + return QPointF(point.x() + d_ptr->sceneTransform.dx(), point.y() + d_ptr->sceneTransform.dy()); + return d_ptr->sceneTransform.map(point); } /*! @@ -4894,7 +4949,9 @@ QPolygonF QGraphicsItem::mapToParent(const QRectF &rect) const */ QPolygonF QGraphicsItem::mapToScene(const QRectF &rect) const { - return sceneTransform().map(rect); + if (d_ptr->hasTranslateOnlySceneTransform()) + return rect.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy()); + return d_ptr->sceneTransform.map(rect); } /*! @@ -4967,7 +5024,9 @@ QRectF QGraphicsItem::mapRectToParent(const QRectF &rect) const */ QRectF QGraphicsItem::mapRectToScene(const QRectF &rect) const { - return sceneTransform().mapRect(rect); + if (d_ptr->hasTranslateOnlySceneTransform()) + return rect.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy()); + return d_ptr->sceneTransform.mapRect(rect); } /*! @@ -5041,7 +5100,9 @@ QRectF QGraphicsItem::mapRectFromParent(const QRectF &rect) const */ QRectF QGraphicsItem::mapRectFromScene(const QRectF &rect) const { - return sceneTransform().inverted().mapRect(rect); + if (d_ptr->hasTranslateOnlySceneTransform()) + return rect.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy()); + return d_ptr->sceneTransform.inverted().mapRect(rect); } /*! @@ -5093,7 +5154,9 @@ QPolygonF QGraphicsItem::mapToParent(const QPolygonF &polygon) const */ QPolygonF QGraphicsItem::mapToScene(const QPolygonF &polygon) const { - return sceneTransform().map(polygon); + if (d_ptr->hasTranslateOnlySceneTransform()) + return polygon.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy()); + return d_ptr->sceneTransform.map(polygon); } /*! @@ -5138,7 +5201,9 @@ QPainterPath QGraphicsItem::mapToParent(const QPainterPath &path) const */ QPainterPath QGraphicsItem::mapToScene(const QPainterPath &path) const { - return sceneTransform().map(path); + if (d_ptr->hasTranslateOnlySceneTransform()) + return path.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy()); + return d_ptr->sceneTransform.map(path); } /*! @@ -5199,7 +5264,9 @@ QPointF QGraphicsItem::mapFromParent(const QPointF &point) const */ QPointF QGraphicsItem::mapFromScene(const QPointF &point) const { - return sceneTransform().inverted().map(point); + if (d_ptr->hasTranslateOnlySceneTransform()) + return QPointF(point.x() - d_ptr->sceneTransform.dx(), point.y() - d_ptr->sceneTransform.dy()); + return d_ptr->sceneTransform.inverted().map(point); } /*! @@ -5267,7 +5334,9 @@ QPolygonF QGraphicsItem::mapFromParent(const QRectF &rect) const */ QPolygonF QGraphicsItem::mapFromScene(const QRectF &rect) const { - return sceneTransform().inverted().map(rect); + if (d_ptr->hasTranslateOnlySceneTransform()) + return rect.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy()); + return d_ptr->sceneTransform.inverted().map(rect); } /*! @@ -5317,7 +5386,9 @@ QPolygonF QGraphicsItem::mapFromParent(const QPolygonF &polygon) const */ QPolygonF QGraphicsItem::mapFromScene(const QPolygonF &polygon) const { - return sceneTransform().inverted().map(polygon); + if (d_ptr->hasTranslateOnlySceneTransform()) + return polygon.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy()); + return d_ptr->sceneTransform.inverted().map(polygon); } /*! @@ -5360,7 +5431,9 @@ QPainterPath QGraphicsItem::mapFromParent(const QPainterPath &path) const */ QPainterPath QGraphicsItem::mapFromScene(const QPainterPath &path) const { - return sceneTransform().inverted().map(path); + if (d_ptr->hasTranslateOnlySceneTransform()) + return path.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy()); + return d_ptr->sceneTransform.inverted().map(path); } /*! @@ -6492,7 +6565,12 @@ void QGraphicsItem::prepareGeometryChange() // _q_processDirtyItems is called before _q_emitUpdated. if ((scenePrivate->connectedSignals & scenePrivate->changedSignalMask) || scenePrivate->views.isEmpty()) { - d_ptr->scene->update(sceneTransform().mapRect(boundingRect())); + if (d_ptr->hasTranslateOnlySceneTransform()) { + d_ptr->scene->update(boundingRect().translated(d_ptr->sceneTransform.dx(), + d_ptr->sceneTransform.dy())); + } else { + d_ptr->scene->update(d_ptr->sceneTransform.mapRect(boundingRect())); + } } } diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 99865b0..3ba77b7 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -164,6 +164,7 @@ public: ignoreOpacity(0), acceptTouchEvents(0), acceptedTouchBeginEvent(0), + sceneTransformTranslateOnly(0), globalStackingOrder(-1), q_ptr(0) { @@ -194,6 +195,7 @@ public: void combineTransformToParent(QTransform *x, const QTransform *viewTransform = 0) const; void combineTransformFromParent(QTransform *x, const QTransform *viewTransform = 0) const; + void updateSceneTransformFromParent(); // ### Qt 5: Remove. Workaround for reimplementation added after Qt 4.4. virtual QVariant inputMethodQueryHelper(Qt::InputMethodQuery query) const; @@ -303,6 +305,13 @@ public: void invalidateCachedClipPathRecursively(bool childrenOnly = false, const QRectF &emptyIfOutsideThisRect = QRectF()); void updateCachedClipPathFromSetPosHelper(const QPointF &newPos); void ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem); + void ensureSceneTransform(); + + inline bool hasTranslateOnlySceneTransform() + { + ensureSceneTransform(); + return sceneTransformTranslateOnly; + } inline void invalidateChildrenSceneTransform() { @@ -469,7 +478,8 @@ public: quint32 ignoreOpacity : 1; quint32 acceptTouchEvents : 1; quint32 acceptedTouchBeginEvent : 1; - quint32 unused : 10; // feel free to use + quint32 sceneTransformTranslateOnly : 1; + quint32 unused : 9; // feel free to use // Optional stacking order int globalStackingOrder; @@ -500,6 +510,10 @@ struct QGraphicsItemPrivate::TransformData { if (onlyTransform) { if (!postmultiplyTransform) return transform; + if (postmultiplyTransform->isIdentity()) + return transform; + if (transform.isIdentity()) + return *postmultiplyTransform; QTransform x(transform); x *= *postmultiplyTransform; return x; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index bae1afd..ae6c53c 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4228,6 +4228,7 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter * QTransform transform(Qt::Uninitialized); QTransform *transformPtr = 0; + bool translateOnlyTransform = false; #define ENSURE_TRANSFORM_PTR \ if (!transformPtr) { \ Q_ASSERT(!itemIsUntransformable); \ @@ -4237,6 +4238,7 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter * transformPtr = &transform; \ } else { \ transformPtr = &item->d_ptr->sceneTransform; \ + translateOnlyTransform = item->d_ptr->sceneTransformTranslateOnly; \ } \ } @@ -4248,10 +4250,8 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter * transform = item->deviceTransform(viewTransform ? *viewTransform : QTransform()); transformPtr = &transform; } else if (item->d_ptr->dirtySceneTransform) { - item->d_ptr->sceneTransform = item->d_ptr->parent ? item->d_ptr->parent->d_ptr->sceneTransform - : QTransform(); - item->d_ptr->combineTransformFromParent(&item->d_ptr->sceneTransform); - item->d_ptr->dirtySceneTransform = 0; + item->d_ptr->updateSceneTransformFromParent(); + Q_ASSERT(!item->d_ptr->dirtySceneTransform); wasDirtyParentSceneTransform = true; } @@ -4260,7 +4260,8 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter * if (drawItem) { const QRectF brect = adjustedItemBoundingRect(item); ENSURE_TRANSFORM_PTR - QRect viewBoundingRect = transformPtr->mapRect(brect).toRect(); + QRect viewBoundingRect = translateOnlyTransform ? brect.translated(transformPtr->dx(), transformPtr->dy()).toRect() + : transformPtr->mapRect(brect).toRect(); item->d_ptr->paintedViewBoundingRects.insert(widget, viewBoundingRect); viewBoundingRect.adjust(-1, -1, 1, 1); drawItem = exposedRegion ? exposedRegion->intersects(viewBoundingRect) : !viewBoundingRect.isEmpty(); @@ -4416,13 +4417,45 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b } static inline bool updateHelper(QGraphicsViewPrivate *view, QGraphicsItemPrivate *item, - const QRectF &rect, const QTransform &xform) + const QRectF &rect, bool itemIsUntransformable) { Q_ASSERT(view); Q_ASSERT(item); - if (item->hasBoundingRegionGranularity) + + QGraphicsItem *itemq = static_cast(item->q_ptr); + QGraphicsView *viewq = static_cast(view->q_ptr); + + if (itemIsUntransformable) { + const QTransform xform = itemq->deviceTransform(viewq->viewportTransform()); + if (!item->hasBoundingRegionGranularity) + return view->updateRect(xform.mapRect(rect).toRect()); return view->updateRegion(xform.map(QRegion(rect.toRect()))); - return view->updateRect(xform.mapRect(rect).toRect()); + } + + if (item->sceneTransformTranslateOnly && view->identityMatrix) { + const qreal dx = item->sceneTransform.dx(); + const qreal dy = item->sceneTransform.dy(); + if (!item->hasBoundingRegionGranularity) { + QRectF r(rect); + r.translate(dx - view->horizontalScroll(), dy - view->verticalScroll()); + return view->updateRect(r.toRect()); + } + QRegion r(rect.toRect()); + r.translate(qRound(dx) - view->horizontalScroll(), qRound(dy) - view->verticalScroll()); + return view->updateRegion(r); + } + + if (!viewq->isTransformed()) { + if (!item->hasBoundingRegionGranularity) + return view->updateRect(item->sceneTransform.mapRect(rect).toRect()); + return view->updateRegion(item->sceneTransform.map(QRegion(rect.toRect()))); + } + + QTransform xform = item->sceneTransform; + xform *= viewq->viewportTransform(); + if (!item->hasBoundingRegionGranularity) + return view->updateRect(xform.mapRect(rect).toRect()); + return view->updateRegion(xform.map(QRegion(rect.toRect()))); } void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren, @@ -4460,11 +4493,8 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool bool wasDirtyParentSceneTransform = item->d_ptr->dirtySceneTransform; const bool itemIsUntransformable = item->d_ptr->itemIsUntransformable(); if (wasDirtyParentSceneTransform && !itemIsUntransformable) { - // Calculate the full scene transform for this item. - item->d_ptr->sceneTransform = item->d_ptr->parent ? item->d_ptr->parent->d_ptr->sceneTransform - : QTransform(); - item->d_ptr->combineTransformFromParent(&item->d_ptr->sceneTransform); - item->d_ptr->dirtySceneTransform = 0; + item->d_ptr->updateSceneTransformFromParent(); + Q_ASSERT(!item->d_ptr->dirtySceneTransform); } const bool wasDirtyParentViewBoundingRects = item->d_ptr->paintedViewBoundingRectsNeedRepaint; @@ -4479,8 +4509,14 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool if (item->d_ptr->geometryChanged) { // Update growingItemsBoundingRect. - if (!hasSceneRect) - growingItemsBoundingRect |= item->d_ptr->sceneTransform.mapRect(item->boundingRect()); + if (!hasSceneRect) { + if (item->d_ptr->sceneTransformTranslateOnly) { + growingItemsBoundingRect |= item->boundingRect().translated(item->d_ptr->sceneTransform.dx(), + item->d_ptr->sceneTransform.dy()); + } else { + growingItemsBoundingRect |= item->d_ptr->sceneTransform.mapRect(item->boundingRect()); + } + } item->d_ptr->geometryChanged = 0; } @@ -4493,7 +4529,12 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool // This block of code is kept for compatibility. Since 4.5, by default // QGraphicsView does not connect the signal and we use the below // method of delivering updates. - q->update(item->d_ptr->sceneTransform.mapRect(itemBoundingRect)); + if (item->d_ptr->sceneTransformTranslateOnly) { + q->update(itemBoundingRect.translated(item->d_ptr->sceneTransform.dx(), + item->d_ptr->sceneTransform.dy())); + } else { + q->update(item->d_ptr->sceneTransform.mapRect(itemBoundingRect)); + } } else { QRectF dirtyRect; bool uninitializedDirtyRect = true; @@ -4536,18 +4577,7 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool if (dirtyRect.isEmpty()) continue; // Discard updates outside the bounding rect. - bool valid = false; - if (itemIsUntransformable) { - valid = updateHelper(viewPrivate, item->d_ptr, dirtyRect, - item->deviceTransform(view->viewportTransform())); - } else if (!view->isTransformed()) { - valid = updateHelper(viewPrivate, item->d_ptr, dirtyRect, item->d_ptr->sceneTransform); - } else { - QTransform deviceTransform = item->d_ptr->sceneTransform; - deviceTransform *= view->viewportTransform(); - valid = updateHelper(viewPrivate, item->d_ptr, dirtyRect, deviceTransform); - } - if (!valid) + if (!updateHelper(viewPrivate, item->d_ptr, dirtyRect, itemIsUntransformable)) paintedViewBoundingRect = QRect(); } } diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 995f3f3..1e34320 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -1864,7 +1864,12 @@ void QGraphicsView::fitInView(const QRectF &rect, Qt::AspectRatioMode aspectRati void QGraphicsView::fitInView(const QGraphicsItem *item, Qt::AspectRatioMode aspectRatioMode) { QPainterPath path = item->isClipped() ? item->clipPath() : item->shape(); - fitInView(item->sceneTransform().map(path).boundingRect(), aspectRatioMode); + if (item->d_ptr->hasTranslateOnlySceneTransform()) { + path.translate(item->d_ptr->sceneTransform.dx(), item->d_ptr->sceneTransform.dy()); + fitInView(path.boundingRect(), aspectRatioMode); + } else { + fitInView(item->d_ptr->sceneTransform.map(path).boundingRect(), aspectRatioMode); + } } /*! -- cgit v0.12 From 8ca44447283deb333591c6354f16f01f30d74e21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Tue, 7 Jul 2009 18:05:51 +0200 Subject: Reduce QTransform operations in QGraphicsSceneIndex. Update the scene transform and use it directly in the same fashion as we do in processDirtyItemsRecursive/drawSubtreeRecursive. All auto-tests pass --- src/gui/graphicsview/qgraphicssceneindex.cpp | 97 +++++++++++++++++++++------- src/gui/graphicsview/qgraphicssceneindex_p.h | 7 +- 2 files changed, 76 insertions(+), 28 deletions(-) diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 5626051..01efde4 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -72,7 +72,7 @@ class QGraphicsSceneIndexRectIntersector : public QGraphicsSceneIndexIntersector { public: bool intersect(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode, - const QTransform &transform, const QTransform &deviceTransform) const + const QTransform &deviceTransform) const { QRectF brect = item->boundingRect(); _q_adjustRect(&brect); @@ -81,8 +81,10 @@ public: Q_UNUSED(exposeRect); bool keep = true; - if (QGraphicsItemPrivate::get(item)->itemIsUntransformable()) { + const QGraphicsItemPrivate *itemd = QGraphicsItemPrivate::get(item); + if (itemd->itemIsUntransformable()) { // Untransformable items; map the scene rect to item coordinates. + const QTransform transform = item->deviceTransform(deviceTransform); QRectF itemRect = (deviceTransform * transform.inverted()).mapRect(sceneRect); if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) keep = itemRect.contains(brect) && itemRect != brect; @@ -94,14 +96,23 @@ public: keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, itemPath, mode); } } else { + Q_ASSERT(!itemd->dirtySceneTransform); + const QRectF itemSceneBoundingRect = itemd->sceneTransformTranslateOnly + ? brect.translated(itemd->sceneTransform.dx(), + itemd->sceneTransform.dy()) + : itemd->sceneTransform.mapRect(brect); if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) - keep = sceneRect.contains(transform.mapRect(brect)) && sceneRect != brect; + keep = sceneRect != brect && sceneRect.contains(itemSceneBoundingRect); else - keep = sceneRect.intersects(transform.mapRect(brect)); + keep = sceneRect.intersects(itemSceneBoundingRect); if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { QPainterPath rectPath; rectPath.addRect(sceneRect); - keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, transform.inverted().map(rectPath), mode); + if (itemd->sceneTransformTranslateOnly) + rectPath.translate(-itemd->sceneTransform.dx(), -itemd->sceneTransform.dy()); + else + rectPath = itemd->sceneTransform.inverted().map(rectPath); + keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, rectPath, mode); } } return keep; @@ -114,7 +125,7 @@ class QGraphicsSceneIndexPointIntersector : public QGraphicsSceneIndexIntersecto { public: bool intersect(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode, - const QTransform &transform, const QTransform &deviceTransform) const + const QTransform &deviceTransform) const { QRectF brect = item->boundingRect(); _q_adjustRect(&brect); @@ -123,8 +134,10 @@ public: Q_UNUSED(exposeRect); bool keep = false; - if (QGraphicsItemPrivate::get(item)->itemIsUntransformable()) { + const QGraphicsItemPrivate *itemd = QGraphicsItemPrivate::get(item); + if (itemd->itemIsUntransformable()) { // Untransformable items; map the scene point to item coordinates. + const QTransform transform = item->deviceTransform(deviceTransform); QPointF itemPoint = (deviceTransform * transform.inverted()).map(scenePoint); keep = brect.contains(itemPoint); if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { @@ -133,8 +146,19 @@ public: keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, pointPath, mode); } } else { - QRectF sceneBoundingRect = transform.mapRect(brect); - keep = sceneBoundingRect.intersects(QRectF(scenePoint, QSizeF(1, 1))) && item->contains(transform.inverted().map(scenePoint)); + Q_ASSERT(!itemd->dirtySceneTransform); + QRectF sceneBoundingRect = itemd->sceneTransformTranslateOnly + ? brect.translated(itemd->sceneTransform.dx(), + itemd->sceneTransform.dy()) + : itemd->sceneTransform.mapRect(brect); + keep = sceneBoundingRect.intersects(QRectF(scenePoint, QSizeF(1, 1))); + if (keep) { + QPointF p = itemd->sceneTransformTranslateOnly + ? QPointF(scenePoint.x() - itemd->sceneTransform.dx(), + scenePoint.y() - itemd->sceneTransform.dy()) + : itemd->sceneTransform.inverted().map(scenePoint); + keep = item->contains(p); + } } return keep; @@ -147,7 +171,7 @@ class QGraphicsSceneIndexPathIntersector : public QGraphicsSceneIndexIntersector { public: bool intersect(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode, - const QTransform &transform, const QTransform &deviceTransform) const + const QTransform &deviceTransform) const { QRectF brect = item->boundingRect(); _q_adjustRect(&brect); @@ -156,8 +180,10 @@ public: Q_UNUSED(exposeRect); bool keep = true; - if (QGraphicsItemPrivate::get(item)->itemIsUntransformable()) { + const QGraphicsItemPrivate *itemd = QGraphicsItemPrivate::get(item); + if (itemd->itemIsUntransformable()) { // Untransformable items; map the scene rect to item coordinates. + const QTransform transform = item->deviceTransform(deviceTransform); QPainterPath itemPath = (deviceTransform * transform.inverted()).map(scenePath); if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) keep = itemPath.contains(brect); @@ -166,12 +192,20 @@ public: if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, itemPath, mode); } else { + Q_ASSERT(!itemd->dirtySceneTransform); + const QRectF itemSceneBoundingRect = itemd->sceneTransformTranslateOnly + ? brect.translated(itemd->sceneTransform.dx(), + itemd->sceneTransform.dy()) + : itemd->sceneTransform.mapRect(brect); if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect) - keep = scenePath.contains(transform.mapRect(brect)); + keep = scenePath.contains(itemSceneBoundingRect); else - keep = scenePath.intersects(transform.mapRect(brect)); + keep = scenePath.intersects(itemSceneBoundingRect); if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) { - QPainterPath itemPath = transform.inverted().map(scenePath); + QPainterPath itemPath = itemd->sceneTransformTranslateOnly + ? scenePath.translated(-itemd->sceneTransform.dx(), + -itemd->sceneTransform.dy()) + : itemd->sceneTransform.inverted().map(scenePath); keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, itemPath, mode); } } @@ -236,7 +270,6 @@ bool QGraphicsSceneIndexPrivate::itemCollidesWithPath(const QGraphicsItem *item, void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRectF exposeRect, QGraphicsSceneIndexIntersector *intersector, QList *items, - const QTransform &parentTransform, const QTransform &viewTransform, Qt::ItemSelectionMode mode, Qt::SortOrder order, qreal parentOpacity) const @@ -251,16 +284,23 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity())) return; - // Calculate the full transform for this item. - QTransform transform(parentTransform); - item->d_ptr->combineTransformFromParent(&transform, &viewTransform); + // Update the item's scene transform if dirty. + const bool itemIsUntransformable = item->d_ptr->itemIsUntransformable(); + const bool wasDirtyParentSceneTransform = item->d_ptr->dirtySceneTransform && !itemIsUntransformable; + if (wasDirtyParentSceneTransform) { + item->d_ptr->updateSceneTransformFromParent(); + Q_ASSERT(!item->d_ptr->dirtySceneTransform); + } const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape); bool processItem = !itemIsFullyTransparent; if (processItem) { - processItem = intersector->intersect(item, exposeRect, mode, transform, viewTransform); - if (!processItem && (!itemHasChildren || itemClipsChildrenToShape)) + processItem = intersector->intersect(item, exposeRect, mode, viewTransform); + if (!processItem && (!itemHasChildren || itemClipsChildrenToShape)) { + if (wasDirtyParentSceneTransform) + item->d_ptr->invalidateChildrenSceneTransform(); return; + } } // else we know for sure this item has children we must process. int i = 0; @@ -269,17 +309,24 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe item->d_ptr->ensureSortedChildren(); // Clip to shape. - if (itemClipsChildrenToShape) - exposeRect &= transform.map(item->shape()).controlPointRect(); + if (itemClipsChildrenToShape && !itemIsUntransformable) { + QPainterPath mappedShape = item->d_ptr->sceneTransformTranslateOnly + ? item->shape().translated(item->d_ptr->sceneTransform.dx(), + item->d_ptr->sceneTransform.dy()) + : item->d_ptr->sceneTransform.map(item->shape()); + exposeRect &= mappedShape.controlPointRect(); + } // Process children behind for (i = 0; i < item->d_ptr->children.size(); ++i) { QGraphicsItem *child = item->d_ptr->children.at(i); + if (wasDirtyParentSceneTransform) + child->d_ptr->dirtySceneTransform = 1; if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent)) break; if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity)) continue; - recursive_items_helper(child, exposeRect, intersector, items, transform, viewTransform, + recursive_items_helper(child, exposeRect, intersector, items, viewTransform, mode, order, opacity); } } @@ -292,9 +339,11 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe if (itemHasChildren) { for (; i < item->d_ptr->children.size(); ++i) { QGraphicsItem *child = item->d_ptr->children.at(i); + if (wasDirtyParentSceneTransform) + child->d_ptr->dirtySceneTransform = 1; if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity)) continue; - recursive_items_helper(child, exposeRect, intersector, items, transform, viewTransform, + recursive_items_helper(child, exposeRect, intersector, items, viewTransform, mode, order, opacity); } } diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index 6521765..8cf0294 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -137,7 +137,7 @@ public: void recursive_items_helper(QGraphicsItem *item, QRectF exposeRect, QGraphicsSceneIndexIntersector *intersector, QList *items, - const QTransform &parentTransform, const QTransform &viewTransform, + const QTransform &viewTransform, Qt::ItemSelectionMode mode, Qt::SortOrder order, qreal parentOpacity = 1.0) const; inline void items_helper(const QRectF &rect, QGraphicsSceneIndexIntersector *intersector, QList *items, const QTransform &viewTransform, @@ -155,9 +155,8 @@ inline void QGraphicsSceneIndexPrivate::items_helper(const QRectF &rect, QGraphi { Q_Q(const QGraphicsSceneIndex); const QList tli = q->estimateTopLevelItems(rect, Qt::DescendingOrder); - const QTransform identity; for (int i = 0; i < tli.size(); ++i) - recursive_items_helper(tli.at(i), rect, intersector, items, identity, viewTransform, mode, order); + recursive_items_helper(tli.at(i), rect, intersector, items, viewTransform, mode, order); if (order == Qt::AscendingOrder) { const int n = items->size(); for (int i = 0; i < n / 2; ++i) @@ -171,7 +170,7 @@ public: QGraphicsSceneIndexIntersector() { } virtual ~QGraphicsSceneIndexIntersector() { } virtual bool intersect(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode, - const QTransform &transform, const QTransform &deviceTransform) const = 0; + const QTransform &deviceTransform) const = 0; }; #endif // QT_NO_GRAPHICSVIEW -- cgit v0.12 From e1b6cd9170d9a20fd3ee1b8d7ef11dcd3364e16d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Wed, 8 Jul 2009 12:18:10 +0200 Subject: Optimize QGraphicsViewPrivate::updateRect/updateRegion. We can do QRect::intersects/contains/operator| faster than QRect because we can assume the rects are normalized. Another important factor is our knowledge about the viewport rect, which is always QRect(0, 0, viewport->width(), viewport->height()). Auto-tests included. --- src/gui/graphicsview/qgraphicsview.cpp | 28 ++++-- src/gui/graphicsview/qgraphicsview_p.h | 2 +- tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 115 +++++++++++++++++++++++++ 3 files changed, 138 insertions(+), 7 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 1e34320..b2cc478 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -839,13 +839,29 @@ void QGraphicsViewPrivate::processPendingUpdates() dirtyRegion = QRegion(); } +static inline bool intersectsViewport(const QRect &r, int width, int height) +{ return !(r.left() > width) && !(r.right() < 0) && !(r.top() >= height) && !(r.bottom() < 0); } + +static inline bool containsViewport(const QRect &r, int width, int height) +{ return r.left() <= 0 && r.top() <= 0 && r.right() >= width - 1 && r.bottom() >= height - 1; } + +static inline void QRect_unite(QRect *rect, const QRect &other) +{ + if (rect->isEmpty()) { + *rect = other; + } else { + rect->setCoords(qMin(rect->left(), other.left()), qMin(rect->top(), other.top()), + qMax(rect->right(), other.right()), qMax(rect->bottom(), other.bottom())); + } +} + bool QGraphicsViewPrivate::updateRegion(const QRegion &r) { if (fullUpdatePending || viewportUpdateMode == QGraphicsView::NoViewportUpdate || r.isEmpty()) return false; const QRect boundingRect = r.boundingRect(); - if (!boundingRect.intersects(viewport->rect())) + if (!intersectsViewport(boundingRect, viewport->width(), viewport->height())) return false; // Update region outside viewport. switch (viewportUpdateMode) { @@ -854,8 +870,8 @@ bool QGraphicsViewPrivate::updateRegion(const QRegion &r) viewport->update(); break; case QGraphicsView::BoundingRectViewportUpdate: - dirtyBoundingRect |= boundingRect; - if (dirtyBoundingRect.contains(viewport->rect())) { + QRect_unite(&dirtyBoundingRect, boundingRect); + if (containsViewport(dirtyBoundingRect, viewport->width(), viewport->height())) { fullUpdatePending = true; viewport->update(); } @@ -882,7 +898,7 @@ bool QGraphicsViewPrivate::updateRegion(const QRegion &r) bool QGraphicsViewPrivate::updateRect(const QRect &r) { if (fullUpdatePending || viewportUpdateMode == QGraphicsView::NoViewportUpdate - || !r.intersects(viewport->rect())) { + || !intersectsViewport(r, viewport->width(), viewport->height())) { return false; } @@ -892,8 +908,8 @@ bool QGraphicsViewPrivate::updateRect(const QRect &r) viewport->update(); break; case QGraphicsView::BoundingRectViewportUpdate: - dirtyBoundingRect |= r; - if (dirtyBoundingRect.contains(viewport->rect())) { + QRect_unite(&dirtyBoundingRect, r); + if (containsViewport(dirtyBoundingRect, viewport->width(), viewport->height())) { fullUpdatePending = true; viewport->update(); } diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h index 7b9fd5e..6617622 100644 --- a/src/gui/graphicsview/qgraphicsview_p.h +++ b/src/gui/graphicsview/qgraphicsview_p.h @@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE -class QGraphicsViewPrivate : public QAbstractScrollAreaPrivate +class Q_AUTOTEST_EXPORT QGraphicsViewPrivate : public QAbstractScrollAreaPrivate { Q_DECLARE_PUBLIC(QGraphicsView) public: diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index 6db8f27..297c437 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -63,6 +63,7 @@ #include #include #include +#include //TESTED_CLASS= //TESTED_FILES= @@ -175,6 +176,7 @@ private slots: void transformationAnchor(); void resizeAnchor(); void viewportUpdateMode(); + void viewportUpdateMode2(); void acceptDrops(); void optimizationFlags(); void optimizationFlags_dontSavePainterState(); @@ -195,6 +197,8 @@ private slots: void mouseTracking2(); void render(); void exposeRegion(); + void update_data(); + void update(); // task specific tests below me void task172231_untransformableItems(); @@ -2229,6 +2233,52 @@ void tst_QGraphicsView::viewportUpdateMode() QCOMPARE(view.lastUpdateRegions.size(), 0); } +void tst_QGraphicsView::viewportUpdateMode2() +{ + // Create a view with viewport rect equal to QRect(0, 0, 200, 200). + QGraphicsScene dummyScene; + CustomView view; + view.setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); + view.setScene(&dummyScene); + int left, top, right, bottom; + view.getContentsMargins(&left, &top, &right, &bottom); + view.resize(200 + left + right, 200 + top + bottom); + view.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&view); +#endif + QTest::qWait(300); + const QRect viewportRect = view.viewport()->rect(); + QCOMPARE(viewportRect, QRect(0, 0, 200, 200)); + QGraphicsViewPrivate *viewPrivate = static_cast(qt_widget_private(&view)); + + QRect boundingRect; + const QRect rect1(0, 0, 10, 10); + QVERIFY(viewPrivate->updateRect(rect1)); + QVERIFY(!viewPrivate->fullUpdatePending); + boundingRect |= rect1; + QCOMPARE(viewPrivate->dirtyBoundingRect, boundingRect); + + const QRect rect2(50, 50, 10, 10); + QVERIFY(viewPrivate->updateRect(rect2)); + QVERIFY(!viewPrivate->fullUpdatePending); + boundingRect |= rect2; + QCOMPARE(viewPrivate->dirtyBoundingRect, boundingRect); + + const QRect rect3(190, 190, 10, 10); + QVERIFY(viewPrivate->updateRect(rect3)); + QVERIFY(viewPrivate->fullUpdatePending); + boundingRect |= rect3; + QCOMPARE(viewPrivate->dirtyBoundingRect, boundingRect); + + view.lastUpdateRegions.clear(); + viewPrivate->processPendingUpdates(); + QTest::qWait(50); + QCOMPARE(view.lastUpdateRegions.size(), 1); + // Note that we adjust by 2 for antialiasing. + QCOMPARE(view.lastUpdateRegions.at(0), QRegion(boundingRect.adjusted(-2, -2, 2, 2) & viewportRect)); +} + void tst_QGraphicsView::acceptDrops() { QGraphicsView view; @@ -3351,6 +3401,71 @@ void tst_QGraphicsView::exposeRegion() QCOMPARE(item->paints, 0); } +void tst_QGraphicsView::update_data() +{ + // In view.viewport() coordinates. (viewport rect: QRect(0, 0, 200, 200)) + QTest::addColumn("updateRect"); + QTest::newRow("empty") << QRect(); + QTest::newRow("outside left") << QRect(-200, 0, 100, 100); + QTest::newRow("outside right") << QRect(400, 0 ,100, 100); + QTest::newRow("outside top") << QRect(0, -200, 100, 100); + QTest::newRow("outside bottom") << QRect(0, 400, 100, 100); + QTest::newRow("partially inside left") << QRect(-50, 0, 100, 100); + QTest::newRow("partially inside right") << QRect(-150, 0, 100, 100); + QTest::newRow("partially inside top") << QRect(0, -150, 100, 100); + QTest::newRow("partially inside bottom") << QRect(0, 150, 100, 100); + QTest::newRow("on topLeft edge") << QRect(-100, -100, 100, 100); + QTest::newRow("on topRight edge") << QRect(200, -100, 100, 100); + QTest::newRow("on bottomRight edge") << QRect(200, 200, 100, 100); + QTest::newRow("on bottomLeft edge") << QRect(-200, 200, 100, 100); + QTest::newRow("inside topLeft") << QRect(-99, -99, 100, 100); + QTest::newRow("inside topRight") << QRect(199, -99, 100, 100); + QTest::newRow("inside bottomRight") << QRect(199, 199, 100, 100); + QTest::newRow("inside bottomLeft") << QRect(-199, 199, 100, 100); + QTest::newRow("large1") << QRect(50, -100, 100, 400); + QTest::newRow("large2") << QRect(-100, 50, 400, 100); + QTest::newRow("large3") << QRect(-100, -100, 400, 400); + QTest::newRow("viewport rect") << QRect(0, 0, 200, 200); +} +void tst_QGraphicsView::update() +{ + QFETCH(QRect, updateRect); + + // Create a view with viewport rect equal to QRect(0, 0, 200, 200). + QGraphicsScene dummyScene; + CustomView view; + view.setScene(&dummyScene); + int left, top, right, bottom; + view.getContentsMargins(&left, &top, &right, &bottom); + view.resize(200 + left + right, 200 + top + bottom); + view.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&view); +#endif + QTest::qWait(300); + const QRect viewportRect = view.viewport()->rect(); + QCOMPARE(viewportRect, QRect(0, 0, 200, 200)); + + const bool intersects = updateRect.intersects(viewportRect); + QGraphicsViewPrivate *viewPrivate = static_cast(qt_widget_private(&view)); + QCOMPARE(viewPrivate->updateRect(updateRect), intersects); + QCOMPARE(viewPrivate->updateRegion(updateRect), intersects); + + view.lastUpdateRegions.clear(); + viewPrivate->processPendingUpdates(); + QVERIFY(viewPrivate->dirtyRegion.isEmpty()); + QVERIFY(viewPrivate->dirtyBoundingRect.isEmpty()); + QTest::qWait(50); + if (!intersects) { + QVERIFY(view.lastUpdateRegions.isEmpty()); + } else { + QCOMPARE(view.lastUpdateRegions.size(), 1); + // Note that we adjust by 2 for antialiasing. + QCOMPARE(view.lastUpdateRegions.at(0), QRegion(updateRect.adjusted(-2, -2, 2, 2) & viewportRect)); + } + QVERIFY(!viewPrivate->fullUpdatePending); +} + void tst_QGraphicsView::task253415_reconnectUpdateSceneOnSceneChanged() { QGraphicsView view; -- cgit v0.12 From 34357998f38614a7c724ba4561c0e68b19fffc4a Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 8 Jul 2009 18:19:21 +0200 Subject: Fix possible crash in QDockAreas --- src/gui/widgets/qdockarealayout.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp index b905ccd..ee29b55 100644 --- a/src/gui/widgets/qdockarealayout.cpp +++ b/src/gui/widgets/qdockarealayout.cpp @@ -1707,7 +1707,7 @@ QDockAreaLayoutItem &QDockAreaLayoutInfo::item(const QList &path) Q_ASSERT(!path.isEmpty()); const int index = path.first(); if (path.count() > 1) { - const QDockAreaLayoutItem &item = item_list.at(index); + const QDockAreaLayoutItem &item = item_list[index]; Q_ASSERT(item.subinfo != 0); return item.subinfo->item(path.mid(1)); } -- cgit v0.12 From cfacb284593008094136905a2497843a4bbac639 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 8 Jul 2009 18:22:09 +0200 Subject: QPropertyAnimation: save a Q_GLOBAL_STATIC This is possible because we anyway use a Mutex to access the static hash --- src/corelib/animation/qpropertyanimation.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/corelib/animation/qpropertyanimation.cpp b/src/corelib/animation/qpropertyanimation.cpp index 7526a81..5f224aa 100644 --- a/src/corelib/animation/qpropertyanimation.cpp +++ b/src/corelib/animation/qpropertyanimation.cpp @@ -100,10 +100,6 @@ QT_BEGIN_NAMESPACE -typedef QPair QPropertyAnimationPair; -typedef QHash QPropertyAnimationHash; -Q_GLOBAL_STATIC(QPropertyAnimationHash, _q_runningAnimations) - void QPropertyAnimationPrivate::updateMetaProperty() { if (!target || propertyName.isEmpty()) @@ -286,19 +282,21 @@ void QPropertyAnimation::updateState(QAbstractAnimation::State oldState, QPropertyAnimation *animToStop = 0; { - QPropertyAnimationHash * hash = _q_runningAnimations(); - QMutexLocker locker(QMutexPool::globalInstanceGet(hash)); + QMutexLocker locker(QMutexPool::globalInstanceGet(&staticMetaObject)); + typedef QPair QPropertyAnimationPair; + typedef QHash QPropertyAnimationHash; + static QPropertyAnimationHash hash; QPropertyAnimationPair key(d->target, d->propertyName); if (newState == Running) { d->updateMetaProperty(); - animToStop = hash->value(key, 0); - hash->insert(key, this); + animToStop = hash.value(key, 0); + hash.insert(key, this); // update the default start value if (oldState == Stopped) { d->setDefaultStartValue(d->target->property(d->propertyName.constData())); } - } else if (hash->value(key) == this) { - hash->remove(key); + } else if (hash.value(key) == this) { + hash.remove(key); } } -- cgit v0.12 From 5ed43fa92a0110dce36a38853932187287a153b6 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Wed, 8 Jul 2009 18:26:07 +0200 Subject: Doc: Added information about newer Visual Studio libraries. Reviewed-by: Trust Me As-seen-on: #pyqt (freenode.net) --- doc/src/deployment.qdoc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/src/deployment.qdoc b/doc/src/deployment.qdoc index 0866930..1da2c06 100644 --- a/doc/src/deployment.qdoc +++ b/doc/src/deployment.qdoc @@ -715,17 +715,19 @@ \table 100% \header - \o \o VC++ 6.0 \o VC++ 7.1 (2003) \o VC++ 8.0 (2005) + \o \o VC++ 6.0 \o VC++ 7.1 (2003) \o VC++ 8.0 (2005) \o VC++ 9.0 (2008) \row \o The C run-time \o \c msvcrt.dll \o \c msvcr71.dll \o \c msvcr80.dll + \o \c msvcr90.dll \row \o The C++ run-time \o \c msvcp60.dll \o \c msvcp71.dll \o \c msvcp80.dll + \o \c msvcp90.dll \endtable To verify that the application now can be successfully deployed, @@ -893,7 +895,7 @@ \o \l{qt-conf.html}{Using \c qt.conf}. This approach is the recommended if you have executables in different places sharing the same plugins. - + \o Using QApplication::addLibraryPath() or QApplication::setLibraryPaths(). This approach is recommended if you only have one executable that will use the plugin. @@ -902,10 +904,10 @@ hard-coded paths in the QtCore library. \endlist - + If you add a custom path using QApplication::addLibraryPath it could look like this: - + \snippet doc/src/snippets/code/doc_src_deployment.qdoc 54 Then qApp->libraryPaths() would return something like this: -- cgit v0.12 From e6897a209981d86db3b8bc21944bbbb7a10490a6 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Wed, 8 Jul 2009 18:27:27 +0200 Subject: Doc: Post review fixes to the SQL data types table. Reviewed-by: Trust Me --- doc/src/qsqldatatype-table.qdoc | 123 ++++++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 63 deletions(-) diff --git a/doc/src/qsqldatatype-table.qdoc b/doc/src/qsqldatatype-table.qdoc index 5ab6413..567bb65 100644 --- a/doc/src/qsqldatatype-table.qdoc +++ b/doc/src/qsqldatatype-table.qdoc @@ -40,30 +40,28 @@ ****************************************************************************/ /*! - \module QtSql - - \page qsqldatatype-table.html - - \title QtSql Module - Recommended use of data types + \page sql-types.html + \title QtSql Module - Recommended Use of Data Types - \section1 Recommended use of types and widgets in Qt supported Databases + \section1 Recommended Use of Types in Qt Supported Databases This table shows the recommended data types used when extracting data from the databases supported in Qt. It is important to note that the - types used in Qt not necessary are valid as input to the specific - database. One example could be that a double would work perfect as - input for floating point records in a database, but not necessary - as output to the database since it would be stored with 64-bit in C++. + types used in Qt are not necessarily valid as input to the specific + database. One example could be that a double would work perfectly as + input for floating point records in a database, but not necessarily + as a storage format for output from the database since it would be stored + with 64-bit precision in C++. \tableofcontents - \section2 IBM DB2 data type + \section2 IBM DB2 Data Types - \table - \row - \header IBM DB2 data type - \header SQL Type Description - \header Recommended input (C++ data type and Qt ) + \table 90% + \header + \o IBM DB2 data type + \o SQL type description + \o Recommended input (C++ or Qt data type) \row \o SMALLINT \o 16-bit signed integer @@ -124,13 +122,13 @@ \o Mapped to QDateTime \endtable - \section2 Borland InterBase data type + \section2 Borland InterBase Data Types - \table - \row - \header Borland InterBase data type - \header SQL Type Description - \header Recommended input (C++ data type/Qt Widget) + \table 90% + \header + \o Borland InterBase data type + \o SQL type description + \o Recommended input (C++ or Qt data type) \row \o BOOLEAN \o Boolean @@ -189,13 +187,13 @@ \o Mapped to QDateTime \endtable - \section2 MySQL data type + \section2 MySQL Data Types - \table - \row - \header MySQL data type - \header SQL Type Description - \header Recommended input (C++ data type/Qt Widget) + \table 90% + \header + \o MySQL data type + \o SQL type description + \o Recommended input (C++ or Qt data type) \row \o TINYINT \o 8 bit signed integer @@ -290,13 +288,13 @@ \o Mapped to QString \endtable - \section2 Oracle Call Interface data type + \section2 Oracle Call Interface Data Types - \table - \row - \header Oracle Call Interface data type - \header SQL Type Description - \header Recommended input (C++ data type/Qt Widget) + \table 90% + \header + \o Oracle Call Interface data type + \o SQL type description + \o Recommended input (C++ or Qt data type) \row \o NUMBER \o FLOAT, DOUBLE, PRECISIONc REAL @@ -338,13 +336,13 @@ \o Mapped to QDateTime \endtable - \section2 ODBC data type + \section2 ODBC Data Types - \table - \row - \header ODBC data type - \header SQL Type Description - \header Recommended input (C++ data type/Qt Widget) + \table 90% + \header + \o ODBC data type + \o SQL type description + \o Recommended input (C++ or Qt data type) \row \o BIT \o Boolean @@ -407,13 +405,13 @@ \o Mapped to QDateTime \endtable - \section2 PostgreSQL data type + \section2 PostgreSQL Data Types - \table - \row - \header PostgreSQL data type - \header SQL Type Description - \header Recommended input (C++ data type/Qt Widget) + \table 90% + \header + \o PostgreSQL data type + \o SQL type description + \o Recommended input (C++ or Qt data type) \row \o BOOLEAN \o Boolean @@ -484,13 +482,13 @@ \o Mapped to QDateTime \endtable - \section2 QSQLITE SQLite version 3 data type + \section2 QSQLITE SQLite version 3 Data Types - \table - \row - \header QSQLITE SQLite version 3 data type - \header SQL Type Description - \header Recommended input (C++ data type/Qt Widget) + \table 90% + \header + \o QSQLITE SQLite version 3 data type + \o SQL type description + \o Recommended input (C++ or Qt data type) \row \o NULL \o NULL value. @@ -518,13 +516,13 @@ \o Mapped to QByteArray \endtable - \section2 Sybase Adaptive Server data type + \section2 Sybase Adaptive Server Data Types - \table - \row - \header Sybase Adaptive Server data type - \header SQL Type Description - \header Recommended input (C++ data type/Qt Widget) + \table 90% + \header + \o Sybase Adaptive Server data type + \o SQL type description + \o Recommended input (C++ or Qt data type) \row \o BINARY \o Describes a fixed-length binary value up to 255 bytes in size. @@ -535,8 +533,7 @@ \o Mapped to QString \row \o DATETIME - \o Date and time. Range: 1753-01-01 00:00:00 through - 9999-12-31 23:59:59. + \o Date and time. Range: 1753-01-01 00:00:00 through 9999-12-31 23:59:59. \o Mapped to QDateTime \row \o NCHAR @@ -577,8 +574,8 @@ \endtable \section2 SQLite Version 2 - SQLite V.2 is "typeless". This means that you can store any kind of - data you want in any column of any table, regardless of the declared - data type of that column. We recommend that you map the data to QString. + SQLite version 2 is "typeless". This means that you can store any kind of + data you want in any column of any table, regardless of the declared + data type of that column. We recommend that you map the data to QString. */ -- cgit v0.12 From 6e35b15d75aeb140bf56690ce7369f54342c2739 Mon Sep 17 00:00:00 2001 From: Bill King Date: Thu, 9 Jul 2009 08:41:56 +1000 Subject: Make compile --- src/gui/widgets/qwidgetanimator_p.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/widgets/qwidgetanimator_p.h b/src/gui/widgets/qwidgetanimator_p.h index 64697a9..5a3e39d 100644 --- a/src/gui/widgets/qwidgetanimator_p.h +++ b/src/gui/widgets/qwidgetanimator_p.h @@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE class QWidget; class QMainWindowLayout; class QPropertyAnimation; +class QRect; class QWidgetAnimator : public QObject { -- cgit v0.12 From 53228e1b1993524fb1422a8363647b468b3c7c8d Mon Sep 17 00:00:00 2001 From: Bill King Date: Thu, 9 Jul 2009 09:41:21 +1000 Subject: Hopefully fix isnan/isinf for good (for all platforms) --- src/sql/drivers/psql/qsql_psql.cpp | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index 33f2e2b..4eccf4b 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -59,21 +59,29 @@ #include #include -#if defined(_MSC_VER) -#include -#define isnan(x) _isnan(x) -int isinf(double x) -{ - if(_fpclass(x) == _FPCLASS_NINF) - return -1; - else if(_fpclass(x) == _FPCLASS_PINF) - return 1; - else return 0; -} -#else #include +// below code taken from an example at http://www.gnu.org/software/hello/manual/autoconf/Function-Portability.html +#ifndef isnan + # define isnan(x) \ + (sizeof (x) == sizeof (long double) ? isnan_ld (x) \ + : sizeof (x) == sizeof (double) ? isnan_d (x) \ + : isnan_f (x)) + static inline int isnan_f (float x) { return x != x; } + static inline int isnan_d (double x) { return x != x; } + static inline int isnan_ld (long double x) { return x != x; } #endif +#ifndef isinf + # define isinf(x) \ + (sizeof (x) == sizeof (long double) ? isinf_ld (x) \ + : sizeof (x) == sizeof (double) ? isinf_d (x) \ + : isinf_f (x)) + static inline int isinf_f (float x) { return isnan (x - x); } + static inline int isinf_d (double x) { return isnan (x - x); } + static inline int isinf_ld (long double x) { return isnan (x - x); } +#endif + + // workaround for postgres defining their OIDs in a private header file #define QBOOLOID 16 #define QINT8OID 20 -- cgit v0.12 From 6cb86a552f4f320b47232ef745ae897ad5ead591 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Thu, 9 Jul 2009 10:56:15 +1000 Subject: Remove some left-over mentions of fixed-point in math3d Reviewed-by: trustme --- src/gui/math3d/qmatrix4x4.cpp | 7 +---- src/gui/math3d/qquaternion.cpp | 4 --- src/gui/math3d/qvector2d.cpp | 4 +-- src/gui/math3d/qvector3d.cpp | 4 +-- src/gui/math3d/qvector4d.cpp | 4 --- tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp | 35 +++++++++++------------ tests/auto/math3d/qquaternion/tst_qquaternion.cpp | 4 +-- tests/auto/math3d/qvectornd/tst_qvectornd.cpp | 4 +-- 8 files changed, 23 insertions(+), 43 deletions(-) diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp index b998353..88f58c8 100644 --- a/src/gui/math3d/qmatrix4x4.cpp +++ b/src/gui/math3d/qmatrix4x4.cpp @@ -53,10 +53,6 @@ QT_BEGIN_NAMESPACE \brief The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space. \since 4.6 - The matrix elements are stored internally using the most efficient - numeric representation for the underlying hardware: floating-point - or fixed-point. - \sa QVector3D, QGenericMatrix */ @@ -308,8 +304,7 @@ QMatrix4x4::QMatrix4x4(const QTransform& transform) // The 4x4 matrix inverse algorithm is based on that described at: // http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q24 // Some optimization has been done to avoid making copies of 3x3 -// sub-matrices, to do calculations in fixed-point where required, -// and to unroll the loops. +// sub-matrices and to unroll the loops. // Calculate the determinant of a 3x3 sub-matrix. // | A B C | diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp index 9988e2b..d9d4160 100644 --- a/src/gui/math3d/qquaternion.cpp +++ b/src/gui/math3d/qquaternion.cpp @@ -55,10 +55,6 @@ QT_BEGIN_NAMESPACE Quaternions are used to represent rotations in 3D space, and consist of a 3D rotation axis specified by the x, y, and z coordinates, and a scalar representing the rotation angle. - - The components of a quaternion are stored internally using the most - efficient representation for the GL rendering engine, which will be - either floating-point or fixed-point. */ /*! diff --git a/src/gui/math3d/qvector2d.cpp b/src/gui/math3d/qvector2d.cpp index 9b5d123..b492aa8 100644 --- a/src/gui/math3d/qvector2d.cpp +++ b/src/gui/math3d/qvector2d.cpp @@ -57,9 +57,7 @@ QT_BEGIN_NAMESPACE The QVector2D class can also be used to represent vertices in 2D space. We therefore do not need to provide a separate vertex class. - The coordinates are stored internally using the most efficient - representation for the GL rendering engine, which will be either - floating-point or fixed-point. + \sa QVector3D, QVector4D, QQuaternion */ /*! diff --git a/src/gui/math3d/qvector3d.cpp b/src/gui/math3d/qvector3d.cpp index 977152a..95550cd 100644 --- a/src/gui/math3d/qvector3d.cpp +++ b/src/gui/math3d/qvector3d.cpp @@ -61,9 +61,7 @@ QT_BEGIN_NAMESPACE The QVector3D class can also be used to represent vertices in 3D space. We therefore do not need to provide a separate vertex class. - The coordinates are stored internally using the most efficient - representation for the GL rendering engine, which will be either - floating-point or fixed-point. + \sa QVector2D, QVector4D, QQuaternion */ /*! diff --git a/src/gui/math3d/qvector4d.cpp b/src/gui/math3d/qvector4d.cpp index a28d2a1..1f7d921 100644 --- a/src/gui/math3d/qvector4d.cpp +++ b/src/gui/math3d/qvector4d.cpp @@ -57,10 +57,6 @@ QT_BEGIN_NAMESPACE The QVector4D class can also be used to represent vertices in 4D space. We therefore do not need to provide a separate vertex class. - The coordinates are stored internally using the most efficient - representation for the GL rendering engine, which will be either - floating-point or fixed-point. - \sa QQuaternion, QVector2D, QVector3D */ diff --git a/tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp b/tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp index 7facf4a..d799c1b 100644 --- a/tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp +++ b/tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp @@ -172,22 +172,22 @@ private slots: private: static void setMatrix(QMatrix2x2& m, const qreal *values); - static void setMatrixFixed(QMatrix2x2& m, const qreal *values); + static void setMatrixDirect(QMatrix2x2& m, const qreal *values); static bool isSame(const QMatrix2x2& m, const qreal *values); static bool isIdentity(const QMatrix2x2& m); static void setMatrix(QMatrix3x3& m, const qreal *values); - static void setMatrixFixed(QMatrix3x3& m, const qreal *values); + static void setMatrixDirect(QMatrix3x3& m, const qreal *values); static bool isSame(const QMatrix3x3& m, const qreal *values); static bool isIdentity(const QMatrix3x3& m); static void setMatrix(QMatrix4x4& m, const qreal *values); - static void setMatrixFixed(QMatrix4x4& m, const qreal *values); + static void setMatrixDirect(QMatrix4x4& m, const qreal *values); static bool isSame(const QMatrix4x4& m, const qreal *values); static bool isIdentity(const QMatrix4x4& m); static void setMatrix(QMatrix4x3& m, const qreal *values); - static void setMatrixFixed(QMatrix4x3& m, const qreal *values); + static void setMatrixDirect(QMatrix4x3& m, const qreal *values); static bool isSame(const QMatrix4x3& m, const qreal *values); static bool isIdentity(const QMatrix4x3& m); }; @@ -321,8 +321,9 @@ void tst_QMatrix::setMatrix(QMatrix4x3& m, const qreal *values) } // Set a matrix to a specified array of values, which are assumed -// to be in row-major order. This sets the values using fixed-point. -void tst_QMatrix::setMatrixFixed(QMatrix2x2& m, const qreal *values) +// to be in row-major order. This sets the values directly into +// the internal data() array. +void tst_QMatrix::setMatrixDirect(QMatrix2x2& m, const qreal *values) { float *data = m.data(); for (int row = 0; row < 2; ++row) { @@ -331,7 +332,7 @@ void tst_QMatrix::setMatrixFixed(QMatrix2x2& m, const qreal *values) } } } -void tst_QMatrix::setMatrixFixed(QMatrix3x3& m, const qreal *values) +void tst_QMatrix::setMatrixDirect(QMatrix3x3& m, const qreal *values) { float *data = m.data(); for (int row = 0; row < 3; ++row) { @@ -340,7 +341,7 @@ void tst_QMatrix::setMatrixFixed(QMatrix3x3& m, const qreal *values) } } } -void tst_QMatrix::setMatrixFixed(QMatrix4x4& m, const qreal *values) +void tst_QMatrix::setMatrixDirect(QMatrix4x4& m, const qreal *values) { float *data = m.data(); for (int row = 0; row < 4; ++row) { @@ -349,7 +350,7 @@ void tst_QMatrix::setMatrixFixed(QMatrix4x4& m, const qreal *values) } } } -void tst_QMatrix::setMatrixFixed(QMatrix4x3& m, const qreal *values) +void tst_QMatrix::setMatrixDirect(QMatrix4x3& m, const qreal *values) { float *data = m.data(); for (int row = 0; row < 3; ++row) { @@ -359,8 +360,8 @@ void tst_QMatrix::setMatrixFixed(QMatrix4x3& m, const qreal *values) } } -// qFuzzyCompare isn't quite "fuzzy" enough to handle conversion -// to fixed-point and back again. So create "fuzzier" compares. +// qFuzzyCompare isn't always "fuzzy" enough to handle conversion +// between float, double, and qreal. So create "fuzzier" compares. static bool fuzzyCompare(float x, float y, qreal epsilon = 0.001) { float diff = x - y; @@ -511,7 +512,7 @@ void tst_QMatrix::create2x2() QVERIFY(!m2.isIdentity()); QMatrix2x2 m3; - setMatrixFixed(m3, uniqueValues2); + setMatrixDirect(m3, uniqueValues2); QVERIFY(isSame(m3, uniqueValues2)); QMatrix2x2 m4(m3); @@ -546,7 +547,7 @@ void tst_QMatrix::create3x3() QVERIFY(!m2.isIdentity()); QMatrix3x3 m3; - setMatrixFixed(m3, uniqueValues3); + setMatrixDirect(m3, uniqueValues3); QVERIFY(isSame(m3, uniqueValues3)); QMatrix3x3 m4(m3); @@ -581,7 +582,7 @@ void tst_QMatrix::create4x4() QVERIFY(!m2.isIdentity()); QMatrix4x4 m3; - setMatrixFixed(m3, uniqueValues4); + setMatrixDirect(m3, uniqueValues4); QVERIFY(isSame(m3, uniqueValues4)); QMatrix4x4 m4(m3); @@ -623,7 +624,7 @@ void tst_QMatrix::create4x3() QVERIFY(!m2.isIdentity()); QMatrix4x3 m3; - setMatrixFixed(m3, uniqueValues4x3); + setMatrixDirect(m3, uniqueValues4x3); QVERIFY(isSame(m3, uniqueValues4x3)); QMatrix4x3 m4(m3); @@ -2961,10 +2962,6 @@ void tst_QMatrix::extractTranslation() QVERIFY(fuzzyCompare(vec.y(), y, epsilon)); QVERIFY(fuzzyCompare(vec.z(), z, epsilon)); - // Have to be careful with numbers here, it is really easy to blow away - // the precision of a fixed pointer number, especially when doing distance - // formula for vector normalization - QMatrix4x4 lookAt; QVector3D eye(1.5f, -2.5f, 2.5f); lookAt.lookAt(eye, diff --git a/tests/auto/math3d/qquaternion/tst_qquaternion.cpp b/tests/auto/math3d/qquaternion/tst_qquaternion.cpp index 395032f..16b87a1 100644 --- a/tests/auto/math3d/qquaternion/tst_qquaternion.cpp +++ b/tests/auto/math3d/qquaternion/tst_qquaternion.cpp @@ -95,8 +95,8 @@ private slots: void nlerp(); }; -// qFuzzyCompare isn't quite "fuzzy" enough to handle conversion -// to fixed-point and back again. So create "fuzzier" compares. +// qFuzzyCompare isn't always "fuzzy" enough to handle conversion +// between float, double, and qreal. So create "fuzzier" compares. static bool fuzzyCompare(float x, float y) { float diff = x - y; diff --git a/tests/auto/math3d/qvectornd/tst_qvectornd.cpp b/tests/auto/math3d/qvectornd/tst_qvectornd.cpp index 0eb5b07..9c1ea83 100644 --- a/tests/auto/math3d/qvectornd/tst_qvectornd.cpp +++ b/tests/auto/math3d/qvectornd/tst_qvectornd.cpp @@ -139,8 +139,8 @@ private slots: void dotProduct4(); }; -// qFuzzyCompare isn't quite "fuzzy" enough to handle conversion -// to fixed-point and back again. So create "fuzzier" compares. +// qFuzzyCompare isn't always "fuzzy" enough to handle conversion +// between float, double, and qreal. So create "fuzzier" compares. static bool fuzzyCompare(float x, float y) { float diff = x - y; -- cgit v0.12 From 3e50d680a37401c05d753982eb5d43c0f1225f63 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Thu, 9 Jul 2009 11:11:35 +1000 Subject: Directly copy QGenericMatrix members instead of using qMemCopy() Using qMemCopy limits QGenericMatrix to plain old types like float and double. Copying the values normally will allow copy constructors to work on non plain types. Reviewed-by: trustme --- src/gui/math3d/qgenericmatrix.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/math3d/qgenericmatrix.h b/src/gui/math3d/qgenericmatrix.h index 1131f9b..7bdf70a 100644 --- a/src/gui/math3d/qgenericmatrix.h +++ b/src/gui/math3d/qgenericmatrix.h @@ -119,7 +119,9 @@ Q_INLINE_TEMPLATE QGenericMatrix::QGenericMatrix() template Q_INLINE_TEMPLATE QGenericMatrix::QGenericMatrix(const QGenericMatrix& other) { - qMemCopy(m, other.m, sizeof(m)); + for (int col = 0; col < N; ++col) + for (int row = 0; row < M; ++row) + m[col][row] = other.m[col][row]; } template -- cgit v0.12 From 99cda3446c6ff5c3da4fe8fb4bc8869497f8da8b Mon Sep 17 00:00:00 2001 From: Stian Sandvik Thomassen Date: Thu, 9 Jul 2009 13:26:18 +1000 Subject: Plugged possible memory leak in getPSQLVersion() Call PQclear() regardless of the status of the result returned by PQexec(). Reviewed-by: Bill King --- src/sql/drivers/psql/qsql_psql.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index 4eccf4b..147cd6d 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -626,10 +626,9 @@ static QPSQLDriver::Protocol getPSQLVersion(PGconn* connection) { QPSQLDriver::Protocol serverVersion = QPSQLDriver::Version6; PGresult* result = PQexec(connection, "select version()"); - int status = PQresultStatus(result); + int status = PQresultStatus(result); if (status == PGRES_COMMAND_OK || status == PGRES_TUPLES_OK) { QString val = QString::fromAscii(PQgetvalue(result, 0, 0)); - PQclear(result); QRegExp rx(QLatin1String("(\\d+)\\.(\\d+)")); rx.setMinimal(true); // enforce non-greedy RegExp if (rx.indexIn(val) != -1) { @@ -670,6 +669,7 @@ static QPSQLDriver::Protocol getPSQLVersion(PGconn* connection) } } } + PQclear(result); if (serverVersion < QPSQLDriver::Version71) qWarning("This version of PostgreSQL is not supported and may not work."); -- cgit v0.12 From 5142a27c19fb01ec80010d2d1de12b0e3082751f Mon Sep 17 00:00:00 2001 From: Derick Hawcroft Date: Thu, 9 Jul 2009 13:58:28 +1000 Subject: emit dataChanged() signal Task-number:207874 --- src/sql/models/qsqltablemodel.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index 1acc846..591b506 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -538,6 +538,7 @@ bool QSqlTableModel::setData(const QModelIndex &index, const QVariant &value, in isOk = updateRowInTable(index.row(), d->editBuffer); if (isOk) select(); + emit dataChanged(index, index); break; } case OnRowChange: if (index.row() == d->insertIndex) { -- cgit v0.12 From bae8bc5d23946036b2c1079fc6f1b3bceeaa19ca Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Wed, 8 Jul 2009 10:18:56 +1000 Subject: Disable private unit tests when Qt is configured without -developer-build, part 1. Adds QT_CONFIG+=private_tests to qconfig.pri when Qt is configured with -developer-build. Reviewed-by: Michael Goddard --- configure | 4 +++- tools/configure/configureapp.cpp | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/configure b/configure index f9b3030..bd8b0ca 100755 --- a/configure +++ b/configure @@ -6256,7 +6256,6 @@ esac # debug release # dll staticlib # -# internal # nocrosscompiler # GNUmake # largefile @@ -6736,6 +6735,9 @@ fi if [ "$PLATFORM_MAC" = "yes" ]; then QT_CONFIG="$QT_CONFIG $CFG_MAC_ARCHS" fi +if [ "$CFG_DEV" = "yes" ]; then + QT_CONFIG="$QT_CONFIG private_tests" +fi # Make the application arch follow the Qt arch for single arch builds. # (for multiple-arch builds, set CONFIG manually in the application .pro file) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index ce9fe6b..80cfc64 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -1135,6 +1135,10 @@ void Configure::parseCmdLine() useUnixSeparators = (dictionary["QMAKESPEC"] == "win32-g++"); + // Allow tests for private classes to be compiled against internal builds + if (dictionary["BUILDDEV"] == "yes") + qtConfig += "private_tests"; + #if !defined(EVAL) for( QStringList::Iterator dis = disabledModules.begin(); dis != disabledModules.end(); ++dis ) { @@ -1997,7 +2001,6 @@ bool Configure::verifyConfiguration() no-gif gif dll staticlib - internal nocrosscompiler GNUmake largefile -- cgit v0.12 From 87df094ed204c237393eac1dd0b2fb907e642dcb Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Mon, 6 Jul 2009 16:40:59 +1000 Subject: Disable private unit tests when Qt is configured without -developer-build, part 2. Some autotests use private (unexported) code, either because they're testing private classes or because that's the easiest way to test the public classes. Configuring Qt with `-developer-build' is needed for these tests. This commit fixes the tests so configuring without `-developer-build' only builds the tests which strictly use public API. --- tests/auto/qcombobox/tst_qcombobox.cpp | 6 ++++ tests/auto/qcssparser/qcssparser.pro | 1 + tests/auto/qfiledialog/tst_qfiledialog.cpp | 18 ++++++++++-- .../auto/qfilesystemmodel/tst_qfilesystemmodel.cpp | 2 ++ tests/auto/qgl/qgl.pro | 3 +- tests/auto/qgl/tst_qgl.cpp | 23 ++-------------- .../qhttpnetworkconnection.pro | 2 ++ tests/auto/qhttpnetworkreply/qhttpnetworkreply.pro | 2 ++ .../qitemeditorfactory/tst_qitemeditorfactory.cpp | 10 +++---- tests/auto/qkeysequence/tst_qkeysequence.cpp | 2 +- tests/auto/qmainwindow/tst_qmainwindow.cpp | 6 ++++ .../qnativesocketengine/qnativesocketengine.pro | 2 ++ tests/auto/qnetworkreply/qnetworkreply.pro | 2 ++ tests/auto/qpathclipper/qpathclipper.pro | 2 ++ tests/auto/qplaintextedit/tst_qplaintextedit.cpp | 2 ++ tests/auto/qregion/tst_qregion.cpp | 6 ++-- tests/auto/qsettings/tst_qsettings.cpp | 22 +++++++++++++-- tests/auto/qsharedpointer/qsharedpointer.pro | 1 + tests/auto/qsocketnotifier/qsocketnotifier.pro | 2 ++ .../qsocks5socketengine/qsocks5socketengine.pro | 1 + .../qstandarditemmodel/tst_qstandarditemmodel.cpp | 4 +++ tests/auto/qstatemachine/tst_qstatemachine.cpp | 2 ++ tests/auto/qstylesheetstyle/qstylesheetstyle.pro | 1 + tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp | 4 +++ tests/auto/qtextedit/tst_qtextedit.cpp | 4 +++ tests/auto/qtextpiecetable/qtextpiecetable.pro | 5 ++-- tests/auto/qtextpiecetable/tst_qtextpiecetable.cpp | 32 +--------------------- tests/auto/qurl/tst_qurl.cpp | 4 +++ .../xmlpatternsdiagnosticsts.pro | 1 + tests/auto/xmlpatternsview/xmlpatternsview.pro | 1 + tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro | 3 ++ tests/auto/xmlpatternsxslts/xmlpatternsxslts.pro | 1 + 32 files changed, 108 insertions(+), 69 deletions(-) diff --git a/tests/auto/qcombobox/tst_qcombobox.cpp b/tests/auto/qcombobox/tst_qcombobox.cpp index c94ace0..67c9ac9 100644 --- a/tests/auto/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/qcombobox/tst_qcombobox.cpp @@ -1973,6 +1973,7 @@ void tst_QComboBox::task190351_layout() listCombo.showPopup(); QTest::qWait(100); +#ifdef QT_BUILD_INTERNAL QFrame *container = qFindChild(&listCombo); QVERIFY(container); QCOMPARE(static_cast(list), qFindChild(container)); @@ -1980,6 +1981,7 @@ void tst_QComboBox::task190351_layout() QVERIFY(top); QVERIFY(top->isVisible()); QCOMPARE(top->mapToGlobal(QPoint(0, top->height())).y(), list->mapToGlobal(QPoint()).y()); +#endif QApplication::setStyle(oldStyle); #else @@ -2045,6 +2047,7 @@ void tst_QComboBox::task191329_size() tableCombo.showPopup(); QTest::qWait(100); +#ifdef QT_BUILD_INTERNAL QFrame *container = qFindChild(&tableCombo); QVERIFY(container); QCOMPARE(static_cast(table), qFindChild(container)); @@ -2052,6 +2055,7 @@ void tst_QComboBox::task191329_size() //the popup should be large enough to contains everithing so the top and left button are hidden QVERIFY(!button->isVisible()); } +#endif QApplication::setStyle(oldStyle); #else @@ -2107,9 +2111,11 @@ void tst_QComboBox::task248169_popupWithMinimalSize() comboBox.showPopup(); QTest::qWait(100); +#ifdef QT_BUILD_INTERNAL QFrame *container = qFindChild(&comboBox); QVERIFY(container); QVERIFY(desktop.screenGeometry(container).contains(container->geometry())); +#endif } void tst_QComboBox::task247863_keyBoardSelection() diff --git a/tests/auto/qcssparser/qcssparser.pro b/tests/auto/qcssparser/qcssparser.pro index 57d6804..723e4d3 100644 --- a/tests/auto/qcssparser/qcssparser.pro +++ b/tests/auto/qcssparser/qcssparser.pro @@ -3,6 +3,7 @@ SOURCES += tst_cssparser.cpp DEFINES += SRCDIR=\\\"$$PWD\\\" QT += xml +requires(contains(QT_CONFIG,private_tests)) wince*: { addFiles.sources = testdata diff --git a/tests/auto/qfiledialog/tst_qfiledialog.cpp b/tests/auto/qfiledialog/tst_qfiledialog.cpp index e4fec1d..8bb81e7 100644 --- a/tests/auto/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/qfiledialog/tst_qfiledialog.cpp @@ -231,6 +231,7 @@ void tst_QFiledialog::currentChangedSignal() // only emited from the views, sidebar, or lookin combo void tst_QFiledialog::directoryEnteredSignal() { +#if defined QT_BUILD_INTERNAL QNonNativeFileDialog fd(0, "", QDir::root().path()); fd.setOptions(QFileDialog::DontUseNativeDialog); fd.show(); @@ -274,6 +275,7 @@ void tst_QFiledialog::directoryEnteredSignal() QTest::mouseDClick(listView->viewport(), Qt::LeftButton, 0, listView->visualRect(folder).center()); QTRY_COMPARE(spyDirectoryEntered.count(), 1); */ +#endif } Q_DECLARE_METATYPE(QFileDialog::FileMode) @@ -1314,16 +1316,14 @@ void tst_QFiledialog::hooks() void tst_QFiledialog::listRoot() { +#if defined QT_BUILD_INTERNAL QFileInfoGatherer::fetchedRoot = false; QString dir(QDir::currentPath()); QNonNativeFileDialog fd(0, QString(), dir); fd.show(); -#if defined Q_AUTOTEST_EXPORT QCOMPARE(QFileInfoGatherer::fetchedRoot,false); -#endif fd.setDirectory(""); QTest::qWait(500); -#if defined Q_AUTOTEST_EXPORT QCOMPARE(QFileInfoGatherer::fetchedRoot,true); #endif } @@ -1347,6 +1347,7 @@ struct FriendlyQFileDialog : public QFileDialog void tst_QFiledialog::deleteDirAndFiles() { +#if defined QT_BUILD_INTERNAL QString tempPath = QDir::tempPath() + '/' + "QFileDialogTestDir4FullDelete"; QDir dir; QVERIFY(dir.mkpath(tempPath + "/foo")); @@ -1373,6 +1374,7 @@ void tst_QFiledialog::deleteDirAndFiles() QFileInfo info(tempPath); QTest::qWait(2000); QVERIFY(!info.exists()); +#endif } void tst_QFiledialog::filter() @@ -1583,6 +1585,7 @@ QString &dir, const QString &filter) void tst_QFiledialog::task227304_proxyOnFileDialog() { +#if defined QT_BUILD_INTERNAL QNonNativeFileDialog fd(0, "", QDir::currentPath(), 0); fd.setProxyModel(new FilterDirModel(QDir::currentPath())); fd.show(); @@ -1616,6 +1619,7 @@ void tst_QFiledialog::task227304_proxyOnFileDialog() QTest::mouseClick(sidebar->viewport(), Qt::LeftButton, 0, sidebar->visualRect(sidebar->model()->index(1, 0)).center()); QTest::qWait(250); //We shouldn't crash +#endif } void tst_QFiledialog::task227930_correctNavigationKeyboardBehavior() @@ -1727,6 +1731,7 @@ void tst_QFiledialog::task235069_hideOnEscape() void tst_QFiledialog::task236402_dontWatchDeletedDir() { +#if defined QT_BUILD_INTERNAL //THIS TEST SHOULD NOT DISPLAY WARNINGS QDir current = QDir::currentPath(); //make sure it is the first on the list @@ -1746,6 +1751,7 @@ void tst_QFiledialog::task236402_dontWatchDeletedDir() QTest::qWait(200); fd.d_func()->removeDirectory(current.absolutePath() + "/aaaaaaaaaa/"); QTest::qWait(1000); +#endif } void tst_QFiledialog::task203703_returnProperSeparator() @@ -1870,6 +1876,7 @@ void tst_QFiledialog::task218353_relativePaths() void tst_QFiledialog::task251321_sideBarHiddenEntries() { +#if defined QT_BUILD_INTERNAL QNonNativeFileDialog fd; QDir current = QDir::currentPath(); @@ -1899,8 +1906,10 @@ void tst_QFiledialog::task251321_sideBarHiddenEntries() hiddenSubDir.rmdir("happy"); hiddenDir.rmdir("subdir"); current.rmdir(".hidden"); +#endif } +#if defined QT_BUILD_INTERNAL class MyQSideBar : public QSidebar { public : @@ -1918,9 +1927,11 @@ public : model()->removeRow(indexes.at(i).row()); } }; +#endif void tst_QFiledialog::task251341_sideBarRemoveEntries() { +#if defined QT_BUILD_INTERNAL QNonNativeFileDialog fd; QDir current = QDir::currentPath(); @@ -1980,6 +1991,7 @@ void tst_QFiledialog::task251341_sideBarRemoveEntries() QCOMPARE(mySideBar.urls(), expected); current.rmdir("testDir"); +#endif } void tst_QFiledialog::task254490_selectFileMultipleTimes() diff --git a/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp index e415b02..d49083f 100644 --- a/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp @@ -254,6 +254,7 @@ void tst_QFileSystemModel::naturalCompare_data() void tst_QFileSystemModel::naturalCompare() { +#ifdef QT_BUILD_INTERNAL QFETCH(QString, s1); QFETCH(QString, s2); QFETCH(int, caseSensitive); @@ -271,6 +272,7 @@ void tst_QFileSystemModel::naturalCompare() // created. The scheduler takes its time to recognize ended threads. QTest::qWait(300); #endif +#endif } void tst_QFileSystemModel::readOnly() diff --git a/tests/auto/qgl/qgl.pro b/tests/auto/qgl/qgl.pro index 55e329d..420c4bb 100644 --- a/tests/auto/qgl/qgl.pro +++ b/tests/auto/qgl/qgl.pro @@ -3,7 +3,8 @@ ############################################################ load(qttest_p4) -contains(QT_CONFIG, opengl):QT += opengl +requires(contains(QT_CONFIG,opengl)) +QT += opengl SOURCES += tst_qgl.cpp diff --git a/tests/auto/qgl/tst_qgl.cpp b/tests/auto/qgl/tst_qgl.cpp index 078c559..96f5ddd 100644 --- a/tests/auto/qgl/tst_qgl.cpp +++ b/tests/auto/qgl/tst_qgl.cpp @@ -44,9 +44,7 @@ #include #include -#ifndef QT_NO_OPENGL #include -#endif #include #include @@ -78,7 +76,6 @@ tst_QGL::~tst_QGL() { } -#ifndef QT_NO_OPENGL class MyGLContext : public QGLContext { public: @@ -96,13 +93,10 @@ public: bool autoBufferSwap() const { return QGLWidget::autoBufferSwap(); } void setAutoBufferSwap(bool on) { QGLWidget::setAutoBufferSwap(on); } }; -#endif + // Testing get/set functions void tst_QGL::getSetCheck() { -#ifdef QT_NO_OPENGL - QSKIP("QGL not yet supported", SkipAll); -#else if (!QGLFormat::hasOpenGL()) QSKIP("QGL not supported on this platform", SkipAll); @@ -246,10 +240,9 @@ void tst_QGL::getSetCheck() QCOMPARE(false, obj3.autoBufferSwap()); obj3.setAutoBufferSwap(true); QCOMPARE(true, obj3.autoBufferSwap()); -#endif } -#ifndef QT_NO_OPENGL +#ifdef QT_BUILD_INTERNAL QT_BEGIN_NAMESPACE extern QGLFormat::OpenGLVersionFlags qOpenGLVersionFlagsFromString(const QString &versionString); QT_END_NAMESPACE @@ -257,9 +250,7 @@ QT_END_NAMESPACE void tst_QGL::openGLVersionCheck() { -#ifdef QT_NO_OPENGL - QSKIP("QGL not yet supported", SkipAll); -#else +#ifdef QT_BUILD_INTERNAL if (!QGLFormat::hasOpenGL()) QSKIP("QGL not supported on this platform", SkipAll); @@ -366,9 +357,6 @@ public: void tst_QGL::graphicsViewClipping() { -#ifdef QT_NO_OPENGL - QSKIP("QGL not supported", SkipAll); -#else const int size = 64; UnclippedWidget *widget = new UnclippedWidget; widget->setFixedSize(size, size); @@ -403,7 +391,6 @@ void tst_QGL::graphicsViewClipping() p.end(); QCOMPARE(image, expected); -#endif } void tst_QGL::partialGLWidgetUpdates_data() @@ -420,9 +407,6 @@ void tst_QGL::partialGLWidgetUpdates_data() void tst_QGL::partialGLWidgetUpdates() { -#ifdef QT_NO_OPENGL - QSKIP("QGL not yet supported", SkipAll); -#else if (!QGLFormat::hasOpenGL()) QSKIP("QGL not supported on this platform", SkipAll); @@ -466,7 +450,6 @@ void tst_QGL::partialGLWidgetUpdates() QCOMPARE(widget.paintEventRegion, QRegion(50, 50, 50, 50)); else QCOMPARE(widget.paintEventRegion, QRegion(widget.rect())); -#endif } QTEST_MAIN(tst_QGL) diff --git a/tests/auto/qhttpnetworkconnection/qhttpnetworkconnection.pro b/tests/auto/qhttpnetworkconnection/qhttpnetworkconnection.pro index 3283873..e19d962 100644 --- a/tests/auto/qhttpnetworkconnection/qhttpnetworkconnection.pro +++ b/tests/auto/qhttpnetworkconnection/qhttpnetworkconnection.pro @@ -2,4 +2,6 @@ load(qttest_p4) SOURCES += tst_qhttpnetworkconnection.cpp INCLUDEPATH += $$(QTDIR)/src/3rdparty/zlib +requires(contains(QT_CONFIG,private_tests)) + QT = core network diff --git a/tests/auto/qhttpnetworkreply/qhttpnetworkreply.pro b/tests/auto/qhttpnetworkreply/qhttpnetworkreply.pro index 2e41fcd..f86250a 100644 --- a/tests/auto/qhttpnetworkreply/qhttpnetworkreply.pro +++ b/tests/auto/qhttpnetworkreply/qhttpnetworkreply.pro @@ -2,4 +2,6 @@ load(qttest_p4) SOURCES += tst_qhttpnetworkreply.cpp INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/zlib +requires(contains(QT_CONFIG,private_tests)) + QT = core network diff --git a/tests/auto/qitemeditorfactory/tst_qitemeditorfactory.cpp b/tests/auto/qitemeditorfactory/tst_qitemeditorfactory.cpp index d9a7d56..e235ff5 100644 --- a/tests/auto/qitemeditorfactory/tst_qitemeditorfactory.cpp +++ b/tests/auto/qitemeditorfactory/tst_qitemeditorfactory.cpp @@ -59,13 +59,13 @@ void tst_QItemEditorFactory::createEditor() QCOMPARE(w->metaObject()->className(), "QExpandingLineEdit"); } -void tst_QItemEditorFactory::createCustomEditor() +//we make it inherit from QObject so that we can use QPointer +class MyEditor : public QObject, public QStandardItemEditorCreator { - //we make it inherit from QObject so that we can use QPointer - class MyEditor : public QObject, public QStandardItemEditorCreator - { - }; +}; +void tst_QItemEditorFactory::createCustomEditor() +{ QPointer creator = new MyEditor; QPointer creator2 = new MyEditor; diff --git a/tests/auto/qkeysequence/tst_qkeysequence.cpp b/tests/auto/qkeysequence/tst_qkeysequence.cpp index aeb57ef..2e4b850 100644 --- a/tests/auto/qkeysequence/tst_qkeysequence.cpp +++ b/tests/auto/qkeysequence/tst_qkeysequence.cpp @@ -270,7 +270,7 @@ void tst_QKeySequence::checkMultipleNames() void tst_QKeySequence::ensureSorted() { //### accessing static members from private classes does not work on msvc at the moment -#ifndef Q_WS_WIN +#if defined(QT_BUILD_INTERNAL) && !defined(Q_WS_WIN) uint N = QKeySequencePrivate::numberOfKeyBindings; uint val = QKeySequencePrivate::keyBindings[0].shortcut; for ( uint i = 1 ; i < N ; ++i) { diff --git a/tests/auto/qmainwindow/tst_qmainwindow.cpp b/tests/auto/qmainwindow/tst_qmainwindow.cpp index e46c2e1..6ae7a3e 100644 --- a/tests/auto/qmainwindow/tst_qmainwindow.cpp +++ b/tests/auto/qmainwindow/tst_qmainwindow.cpp @@ -1400,6 +1400,7 @@ void AddDockWidget::apply(QMainWindow *mw) const } } +#ifdef QT_BUILD_INTERNAL struct MoveSeparator { MoveSeparator() {} @@ -1436,6 +1437,7 @@ void MoveSeparator::apply(QMainWindow *mw) const l->layoutState.dockAreaLayout.separatorMove(path, QPoint(0, 0), QPoint(delta, delta)); } +#endif QMap dockWidgetGeometries(QMainWindow *mw) { @@ -1463,6 +1465,7 @@ QMap dockWidgetGeometries(QMainWindow *mw) void tst_QMainWindow::saveRestore_data() { +#ifdef QT_BUILD_INTERNAL QTest::addColumn("addList"); QTest::addColumn("moveList"); @@ -1497,10 +1500,12 @@ void tst_QMainWindow::saveRestore_data() << MoveSeparator(-30, "right1") << MoveSeparator(30, "right2a") ); +#endif } void tst_QMainWindow::saveRestore() { +#ifdef QT_BUILD_INTERNAL QFETCH(AddList, addList); QFETCH(MoveList, moveList); @@ -1570,6 +1575,7 @@ void tst_QMainWindow::saveRestore() mainWindow.show(); COMPARE_DOCK_WIDGET_GEOS(dockWidgetGeos, dockWidgetGeometries(&mainWindow)); } +#endif } void tst_QMainWindow::iconSizeChanged() diff --git a/tests/auto/qnativesocketengine/qnativesocketengine.pro b/tests/auto/qnativesocketengine/qnativesocketengine.pro index 320f24c..ad40d53 100644 --- a/tests/auto/qnativesocketengine/qnativesocketengine.pro +++ b/tests/auto/qnativesocketengine/qnativesocketengine.pro @@ -3,6 +3,8 @@ SOURCES += tst_qnativesocketengine.cpp include(../qnativesocketengine/qsocketengine.pri) +requires(contains(QT_CONFIG,private_tests)) + MOC_DIR=tmp QT = core network diff --git a/tests/auto/qnetworkreply/qnetworkreply.pro b/tests/auto/qnetworkreply/qnetworkreply.pro index 0bcf067..fd8454c 100644 --- a/tests/auto/qnetworkreply/qnetworkreply.pro +++ b/tests/auto/qnetworkreply/qnetworkreply.pro @@ -1,4 +1,6 @@ TEMPLATE = subdirs SUBDIRS = test +requires(contains(QT_CONFIG,private_tests)) + !wince*:SUBDIRS += echo diff --git a/tests/auto/qpathclipper/qpathclipper.pro b/tests/auto/qpathclipper/qpathclipper.pro index 675e463..dc9d60f 100644 --- a/tests/auto/qpathclipper/qpathclipper.pro +++ b/tests/auto/qpathclipper/qpathclipper.pro @@ -3,6 +3,8 @@ INCLUDEPATH += . HEADERS += paths.h SOURCES += tst_qpathclipper.cpp paths.cpp +requires(contains(QT_CONFIG,private_tests)) + unix:!mac:LIBS+=-lm diff --git a/tests/auto/qplaintextedit/tst_qplaintextedit.cpp b/tests/auto/qplaintextedit/tst_qplaintextedit.cpp index fceefd2..40ad539 100644 --- a/tests/auto/qplaintextedit/tst_qplaintextedit.cpp +++ b/tests/auto/qplaintextedit/tst_qplaintextedit.cpp @@ -1106,6 +1106,7 @@ void tst_QPlainTextEdit::mimeDataReimplementations() QCOMPARE(ed.canInsertCallCount, 0); QCOMPARE(ed.insertCallCount, 0); +#ifdef QT_BUILD_INTERNAL QTextControl *control = qFindChild(&ed); QVERIFY(control); @@ -1120,6 +1121,7 @@ void tst_QPlainTextEdit::mimeDataReimplementations() QCOMPARE(ed.createMimeDataCallCount, 1); QCOMPARE(ed.canInsertCallCount, 1); QCOMPARE(ed.insertCallCount, 1); +#endif } void tst_QPlainTextEdit::shiftEnterShouldInsertLineSeparator() diff --git a/tests/auto/qregion/tst_qregion.cpp b/tests/auto/qregion/tst_qregion.cpp index 3ffa87e..2ad202d 100644 --- a/tests/auto/qregion/tst_qregion.cpp +++ b/tests/auto/qregion/tst_qregion.cpp @@ -96,7 +96,7 @@ private slots: #ifdef Q_OS_WIN void handle(); #endif -#ifdef Q_WS_X11 +#if defined(Q_WS_X11) && defined(QT_BUILD_INTERNAL) void clipRectangles(); #endif @@ -865,7 +865,7 @@ void tst_QRegion::handle() } #endif -#ifdef Q_WS_X11 +#if defined(Q_WS_X11) && defined(QT_BUILD_INTERNAL) void tst_QRegion::clipRectangles() { QRegion region(30, 30, 30, 30); @@ -967,6 +967,7 @@ void tst_QRegion::regionToPath_data() void tst_QRegion::regionToPath() { +#ifdef QT_BUILD_INTERNAL extern QPainterPath qt_regionToPath(const QRegion ®ion); QFETCH(QPainterPath, path); @@ -1002,6 +1003,7 @@ void tst_QRegion::regionToPath() QCOMPARE(ia, ib); QCOMPARE(a.boundingRect(), b.boundingRect()); } +#endif } QTEST_MAIN(tst_QRegion) diff --git a/tests/auto/qsettings/tst_qsettings.cpp b/tests/auto/qsettings/tst_qsettings.cpp index f0f446d..77fef1f 100644 --- a/tests/auto/qsettings/tst_qsettings.cpp +++ b/tests/auto/qsettings/tst_qsettings.cpp @@ -713,6 +713,7 @@ void tst_QSettings::testErrorHandling_data() void tst_QSettings::testErrorHandling() { +#ifdef QT_BUILD_INTERNAL #ifdef Q_OS_WIN QSKIP("Windows doesn't support most file modes, including read-only directories, so this test is moot.", SkipAll); #else @@ -776,6 +777,7 @@ void tst_QSettings::testErrorHandling() QCOMPARE((int)settings.status(), statusAfterSetAndSync); } #endif // !Q_OS_WIN +#endif } Q_DECLARE_METATYPE(QVariant) @@ -821,6 +823,7 @@ void tst_QSettings::testIniParsing_data() void tst_QSettings::testIniParsing() { +#ifdef QT_BUILD_INTERNAL qRegisterMetaType("QVariant"); qRegisterMetaType("QSettings::Status"); @@ -854,6 +857,7 @@ void tst_QSettings::testIniParsing() } QCOMPARE(settings.status(), status); +#endif } /* @@ -1058,6 +1062,7 @@ void tst_QSettings::testVariantTypes_data() void tst_QSettings::testVariantTypes() { +#ifdef QT_BUILD_INTERNAL #define testVal(key, val, tp, rtype) \ { \ QSettings settings1(format, QSettings::UserScope, "software.org", "KillerAPP"); \ @@ -1141,6 +1146,7 @@ void tst_QSettings::testVariantTypes() } #undef testVal +#endif } void tst_QSettings::remove() @@ -1801,9 +1807,7 @@ void tst_QSettings::testNormalizedKey_data() void tst_QSettings::testNormalizedKey() { -#ifdef QTEST_REDUCED_EXPORTS - QSKIP("We can't test QSettingsPrivate on Windows", SkipAll); -#else +#ifdef QT_BUILD_INTERNAL QFETCH(QString, inKey); QFETCH(QString, outKey); @@ -1981,6 +1985,7 @@ void tst_QSettings::fromFile() void tst_QSettings::setIniCodec() { +#ifdef QT_BUILD_INTERNAL QByteArray expeContents4, expeContents5; QByteArray actualContents4, actualContents5; @@ -2040,6 +2045,7 @@ void tst_QSettings::setIniCodec() QCOMPARE(settings4.allKeys().first(), settings5.allKeys().first()); QCOMPARE(settings4.value(settings4.allKeys().first()).toString(), settings5.value(settings5.allKeys().first()).toString()); +#endif } static bool containsSubList(QStringList mom, QStringList son) @@ -2316,6 +2322,7 @@ void tst_QSettings::testArrays() settings1.endArray(); } +#ifdef QT_BUILD_INTERNAL static QByteArray iniEscapedKey(const QString &str) { QByteArray result; @@ -2360,6 +2367,7 @@ static QStringList iniUnescapedStringList(const QByteArray &ba) #endif return result; } +#endif QString escapeWeirdChars(const QString &s) { @@ -2383,6 +2391,7 @@ QString escapeWeirdChars(const QString &s) void tst_QSettings::testEscapes() { +#ifdef QT_BUILD_INTERNAL QSettings settings(QSettings::UserScope, "software.org", "KillerAPP"); #define testEscapedKey(plainKey, escKey) \ @@ -2505,6 +2514,7 @@ void tst_QSettings::testEscapes() testBadEscape("@Rect)", "@Rect)"); testBadEscape("@Rect(1 2 3)", "@Rect(1 2 3)"); testBadEscape("@@Rect(1 2 3)", "@Rect(1 2 3)"); +#endif } void tst_QSettings::testCompatFunctions() @@ -3355,6 +3365,7 @@ void tst_QSettings::childGroups_data() void tst_QSettings::childGroups() { +#ifdef QT_BUILD_INTERNAL QFETCH(QSettings::Format, format); { @@ -3408,6 +3419,7 @@ void tst_QSettings::childGroups() QCOMPARE(settings.childGroups(), QStringList() << "alpha" << "gamma" << "omicron" << "zeta"); } +#endif } void tst_QSettings::childKeys_data() @@ -3417,6 +3429,7 @@ void tst_QSettings::childKeys_data() void tst_QSettings::childKeys() { +#ifdef QT_BUILD_INTERNAL QFETCH(QSettings::Format, format); { @@ -3470,6 +3483,7 @@ void tst_QSettings::childKeys() QCOMPARE(settings.childKeys(), QStringList() << "alpha" << "beta" << "gamma"); } +#endif } void tst_QSettings::allKeys_data() @@ -3479,6 +3493,7 @@ void tst_QSettings::allKeys_data() void tst_QSettings::allKeys() { +#ifdef QT_BUILD_INTERNAL QFETCH(QSettings::Format, format); QStringList allKeys; @@ -3527,6 +3542,7 @@ void tst_QSettings::allKeys() QCOMPARE(settings.allKeys(), allKeys); } +#endif } void tst_QSettings::registerFormat() diff --git a/tests/auto/qsharedpointer/qsharedpointer.pro b/tests/auto/qsharedpointer/qsharedpointer.pro index 30c81cb..90fde06 100644 --- a/tests/auto/qsharedpointer/qsharedpointer.pro +++ b/tests/auto/qsharedpointer/qsharedpointer.pro @@ -4,5 +4,6 @@ SOURCES += tst_qsharedpointer.cpp \ forwarddeclared.cpp QT = core DEFINES += SRCDIR=\\\"$$PWD/\\\" +requires(contains(QT_CONFIG,private_tests)) include(externaltests.pri) HEADERS += forwarddeclared.h diff --git a/tests/auto/qsocketnotifier/qsocketnotifier.pro b/tests/auto/qsocketnotifier/qsocketnotifier.pro index 10ed3a5..ec924c1 100644 --- a/tests/auto/qsocketnotifier/qsocketnotifier.pro +++ b/tests/auto/qsocketnotifier/qsocketnotifier.pro @@ -2,6 +2,8 @@ load(qttest_p4) SOURCES += tst_qsocketnotifier.cpp QT = core network +requires(contains(QT_CONFIG,private_tests)) + include(../qnativesocketengine/qsocketengine.pri) diff --git a/tests/auto/qsocks5socketengine/qsocks5socketengine.pro b/tests/auto/qsocks5socketengine/qsocks5socketengine.pro index 2949ee2..d19b732 100644 --- a/tests/auto/qsocks5socketengine/qsocks5socketengine.pro +++ b/tests/auto/qsocks5socketengine/qsocks5socketengine.pro @@ -11,3 +11,4 @@ QT = core network +requires(contains(QT_CONFIG,private_tests)) diff --git a/tests/auto/qstandarditemmodel/tst_qstandarditemmodel.cpp b/tests/auto/qstandarditemmodel/tst_qstandarditemmodel.cpp index fa44034..fba7b1b 100644 --- a/tests/auto/qstandarditemmodel/tst_qstandarditemmodel.cpp +++ b/tests/auto/qstandarditemmodel/tst_qstandarditemmodel.cpp @@ -1454,6 +1454,7 @@ static QStandardItem *itemFromText(QStandardItem *parent, const QString &text) return item; } +#ifdef QT_BUILD_INTERNAL static QModelIndex indexFromText(QStandardItemModel *model, const QString &text) { QStandardItem *item = itemFromText(model->invisibleRootItem(), text); @@ -1467,9 +1468,11 @@ struct FriendlyTreeView : public QTreeView friend class tst_QStandardItemModel; Q_DECLARE_PRIVATE(QTreeView) }; +#endif void tst_QStandardItemModel::treeDragAndDrop() { +#ifdef QT_BUILD_INTERNAL const int nRow = 5; const int nCol = 3; @@ -1605,6 +1608,7 @@ void tst_QStandardItemModel::treeDragAndDrop() QVERIFY(compareModels(&model, &checkModel)); } +#endif } void tst_QStandardItemModel::removeRowsAndColumns() diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index a859866..efcb983 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -1015,6 +1015,7 @@ void tst_QStateMachine::rootState() void tst_QStateMachine::addAndRemoveState() { +#ifdef QT_BUILD_INTERNAL QStateMachine machine; QStatePrivate *root_d = QStatePrivate::get(machine.rootState()); QCOMPARE(root_d->childStates().size(), 0); @@ -1075,6 +1076,7 @@ void tst_QStateMachine::addAndRemoveState() delete s2; // ### how to deal with this? // machine.removeState(machine.errorState()); +#endif } void tst_QStateMachine::stateEntryAndExit() diff --git a/tests/auto/qstylesheetstyle/qstylesheetstyle.pro b/tests/auto/qstylesheetstyle/qstylesheetstyle.pro index 6acb0b4..f6101f4 100644 --- a/tests/auto/qstylesheetstyle/qstylesheetstyle.pro +++ b/tests/auto/qstylesheetstyle/qstylesheetstyle.pro @@ -13,3 +13,4 @@ contains(QT_CONFIG, qt3support): QT += qt3support # Input SOURCES += tst_qstylesheetstyle.cpp RESOURCES += resources.qrc +requires(contains(QT_CONFIG,private_tests)) diff --git a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp index 7b62eae..3f658ec 100644 --- a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp +++ b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp @@ -625,9 +625,11 @@ void tst_QSvgRenderer::testGzLoading() QVERIFY(autoDetectGzData.isValid()); } +#ifdef QT_BUILD_INTERNAL QT_BEGIN_NAMESPACE QByteArray qt_inflateGZipDataFrom(QIODevice *device); QT_END_NAMESPACE +#endif void tst_QSvgRenderer::testGzHelper_data() { @@ -660,6 +662,7 @@ void tst_QSvgRenderer::testGzHelper_data() void tst_QSvgRenderer::testGzHelper() { +#ifdef QT_BUILD_INTERNAL QFETCH(QByteArray, in); QFETCH(QByteArray, out); @@ -668,6 +671,7 @@ void tst_QSvgRenderer::testGzHelper() QVERIFY(buffer.isReadable()); QByteArray result = qt_inflateGZipDataFrom(&buffer); QCOMPARE(result, out); +#endif } #endif diff --git a/tests/auto/qtextedit/tst_qtextedit.cpp b/tests/auto/qtextedit/tst_qtextedit.cpp index 3bc1517..d54645c 100644 --- a/tests/auto/qtextedit/tst_qtextedit.cpp +++ b/tests/auto/qtextedit/tst_qtextedit.cpp @@ -1460,6 +1460,7 @@ void tst_QTextEdit::mimeDataReimplementations() QCOMPARE(ed.canInsertCallCount, 0); QCOMPARE(ed.insertCallCount, 0); +#ifdef QT_BUILD_INTERNAL QTextControl *control = qFindChild(&ed); QVERIFY(control); @@ -1474,6 +1475,7 @@ void tst_QTextEdit::mimeDataReimplementations() QCOMPARE(ed.createMimeDataCallCount, 1); QCOMPARE(ed.canInsertCallCount, 1); QCOMPARE(ed.insertCallCount, 1); +#endif } void tst_QTextEdit::ctrlEnterShouldInsertLineSeparator_NOT() @@ -2066,6 +2068,7 @@ void tst_QTextEdit::cursorRect() void tst_QTextEdit::setDocumentPreservesPalette() { +#ifdef QT_BUILD_INTERNAL QTextControl *control = qFindChild(ed); QVERIFY(control); @@ -2085,6 +2088,7 @@ void tst_QTextEdit::setDocumentPreservesPalette() QVERIFY(control->document() == newDoc); QVERIFY(whitePal.color(QPalette::Active, QPalette::Text) == control->palette().color(QPalette::Active, QPalette::Text)); +#endif } class PublicTextEdit : public QTextEdit diff --git a/tests/auto/qtextpiecetable/qtextpiecetable.pro b/tests/auto/qtextpiecetable/qtextpiecetable.pro index 318a8c7..0926b83 100644 --- a/tests/auto/qtextpiecetable/qtextpiecetable.pro +++ b/tests/auto/qtextpiecetable/qtextpiecetable.pro @@ -2,7 +2,6 @@ load(qttest_p4) SOURCES += tst_qtextpiecetable.cpp HEADERS += ../qtextdocument/common.h -!win32:DEFINES += QTEST_REDUCED_EXPORTS - - +requires(!win32) +requires(contains(QT_CONFIG,private_tests)) diff --git a/tests/auto/qtextpiecetable/tst_qtextpiecetable.cpp b/tests/auto/qtextpiecetable/tst_qtextpiecetable.cpp index accbabb..0e60c16 100644 --- a/tests/auto/qtextpiecetable/tst_qtextpiecetable.cpp +++ b/tests/auto/qtextpiecetable/tst_qtextpiecetable.cpp @@ -42,9 +42,7 @@ #include -#ifdef QTEST_REDUCED_EXPORTS #define private public -#endif #include #include @@ -65,7 +63,6 @@ public: tst_QTextPieceTable(); -#ifdef QTEST_REDUCED_EXPORTS public slots: void init(); void cleanup(); @@ -112,13 +109,7 @@ private slots: void removeFrameDirect(); void removeWithChildFrame(); void clearWithFrames(); -#else -public slots: - void init(); - void cleanup(); -private slots: - void skip(); -#endif + private: QTextDocument *doc; QTextDocumentPrivate *table; @@ -130,8 +121,6 @@ tst_QTextPieceTable::tst_QTextPieceTable() { doc = 0; table = 0; } -#ifdef QTEST_REDUCED_EXPORTS - void tst_QTextPieceTable::init() { doc = new QTextDocument(0); @@ -1148,25 +1137,6 @@ void tst_QTextPieceTable::clearWithFrames() QVERIFY(true); } -#else // QTEST_REDUCED_EXPORTS - -void tst_QTextPieceTable::init() -{ -} - -void tst_QTextPieceTable::cleanup() -{ -} - -void tst_QTextPieceTable::skip() -{ - QSKIP( "Not tested on win32", SkipAll ); -} - - -#endif // QTEST_REDUCED_EXPORTS - - QTEST_MAIN(tst_QTextPieceTable) diff --git a/tests/auto/qurl/tst_qurl.cpp b/tests/auto/qurl/tst_qurl.cpp index ea551da..723f882 100644 --- a/tests/auto/qurl/tst_qurl.cpp +++ b/tests/auto/qurl/tst_qurl.cpp @@ -3057,12 +3057,15 @@ void tst_QUrl::nameprep_testsuite_data() << QString() << 0 << 0; } +#ifdef QT_BUILD_INTERNAL QT_BEGIN_NAMESPACE extern QString qt_nameprep(const QString &source); QT_END_NAMESPACE +#endif void tst_QUrl::nameprep_testsuite() { +#ifdef QT_BUILD_INTERNAL QFETCH(QString, in); QFETCH(QString, out); QFETCH(QString, profile); @@ -3082,6 +3085,7 @@ void tst_QUrl::nameprep_testsuite() QEXPECT_FAIL("Larger test (expanding)", "Investigate further", Continue); QCOMPARE(qt_nameprep(in), out); +#endif } void tst_QUrl::ace_testsuite_data() diff --git a/tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro b/tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro index e90b335..3d82eaf 100644 --- a/tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro +++ b/tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro @@ -2,3 +2,4 @@ TEMPLATE = subdirs CONFIG += ordered SUBDIRS = ../xmlpatternsxqts test +requires(contains(QT_CONFIG,private_tests)) diff --git a/tests/auto/xmlpatternsview/xmlpatternsview.pro b/tests/auto/xmlpatternsview/xmlpatternsview.pro index 3544264..04ee4d0 100644 --- a/tests/auto/xmlpatternsview/xmlpatternsview.pro +++ b/tests/auto/xmlpatternsview/xmlpatternsview.pro @@ -6,3 +6,4 @@ SUBDIRS = ../xmlpatternsxqts test contains(QT_CONFIG,xmlpatterns) { SUBDIRS += view } +requires(contains(QT_CONFIG,private_tests)) diff --git a/tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro b/tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro index 368a028..a3b13da 100644 --- a/tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro +++ b/tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro @@ -9,3 +9,6 @@ contains(QT_CONFIG,xmlpatterns) { # Needed on the win32-g++ setup and on the test machine arsia. INCLUDEPATH += $$QT_BUILD_TREE/include/QtXmlPatterns/private \ ../../../include/QtXmlPatterns/private + +requires(contains(QT_CONFIG,private_tests)) + diff --git a/tests/auto/xmlpatternsxslts/xmlpatternsxslts.pro b/tests/auto/xmlpatternsxslts/xmlpatternsxslts.pro index 4a688c4..9b63a52 100644 --- a/tests/auto/xmlpatternsxslts/xmlpatternsxslts.pro +++ b/tests/auto/xmlpatternsxslts/xmlpatternsxslts.pro @@ -23,3 +23,4 @@ wince*: { DEPLOYMENT += testdata } +requires(contains(QT_CONFIG,private_tests)) -- cgit v0.12 From 21b32a69fc4607e60677b978fbcdc6424cc4f63b Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 9 Jul 2009 14:36:26 +1000 Subject: New configure.exe. Includes: 9b532a999944c70c2e8f57d9156c1887867ad9f1 - qtlibinfix bb8e25a5074a378d5003577fefbeabb1de846a81 - cetest fix 5ea86cfac34f65b2321ceeeb651e4e7099bf59a0 - QT_WA removal 349997b5c4167b07d0bdc55beff175b39f3abe75 - spelling fix bae8bc5d23946036b2c1079fc6f1b3bceeaa19ca - QT_CONFIG+=private_tests --- configure.exe | Bin 835584 -> 1101312 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/configure.exe b/configure.exe index a139116..10b926e 100644 Binary files a/configure.exe and b/configure.exe differ -- cgit v0.12 From 458c547aefcb529fe807a220109e2a7ce6bd9105 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 9 Jul 2009 16:51:41 +1000 Subject: Improved cetest error reporting. Now, if you try to run an unsigned test on a locked device, you'll get: "Error invoking qRemoteLaunch on \Windows\QtRemote.dll: Invalid Signature. (0x80090006)" Instead of what you would previously get: "Error: Could not execute target file" --- tools/qtestlib/wince/cetest/activesyncconnection.cpp | 12 ++++++++---- tools/qtestlib/wince/cetest/remoteconnection.cpp | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/tools/qtestlib/wince/cetest/activesyncconnection.cpp b/tools/qtestlib/wince/cetest/activesyncconnection.cpp index 0f98619..1080477 100644 --- a/tools/qtestlib/wince/cetest/activesyncconnection.cpp +++ b/tools/qtestlib/wince/cetest/activesyncconnection.cpp @@ -385,10 +385,14 @@ bool ActiveSyncConnection::execute(QString program, QString arguments, int timeo DWORD error = 0; HRESULT res = CeRapiInvoke(dllLocation.utf16(), functionName.utf16(), 0, 0, &outputSize, &output, &stream, 0); if (S_OK != res) { - if (S_OK != CeGetLastError()) - debugOutput(QString::fromLatin1("Error: Could not invoke method on QtRemote"),1); - else - debugOutput(QString::fromLatin1("Error: QtRemote return unexpectedly with error Code %1").arg(res), 1); + DWORD ce_error = CeGetLastError(); + if (S_OK != ce_error) { + qWarning("Error invoking %s on %s: %s", qPrintable(functionName), + qPrintable(dllLocation), strwinerror(ce_error).constData()); + } else { + qWarning("Error: %s on %s unexpectedly returned %d", qPrintable(functionName), + qPrintable(dllLocation), res); + } } else { DWORD written; int strSize = program.length(); diff --git a/tools/qtestlib/wince/cetest/remoteconnection.cpp b/tools/qtestlib/wince/cetest/remoteconnection.cpp index 75788e2..3d0c3f3 100644 --- a/tools/qtestlib/wince/cetest/remoteconnection.cpp +++ b/tools/qtestlib/wince/cetest/remoteconnection.cpp @@ -66,8 +66,8 @@ QByteArray strwinerror(DWORD errorcode) out.chop(2); /* Append error number to error message for good measure */ - out.append(" ("); - out.append(QByteArray::number((int)errorcode)); + out.append(" (0x"); + out.append(QByteArray::number(uint(errorcode), 16).rightJustified(8, '0')); out.append(")"); } return out; -- cgit v0.12 From c365e7e91feab7d07653e0086ba297bb1f8a6234 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 9 Jul 2009 17:03:58 +1000 Subject: Let cetest return nonzero when it fails to run a test. --- tools/qtestlib/wince/cetest/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/qtestlib/wince/cetest/main.cpp b/tools/qtestlib/wince/cetest/main.cpp index ba3ef8d..782f6d9 100644 --- a/tools/qtestlib/wince/cetest/main.cpp +++ b/tools/qtestlib/wince/cetest/main.cpp @@ -320,6 +320,7 @@ int main(int argc, char **argv) cout << endl << "Remote Launch:" << qPrintable(TestConfiguration::remoteExecutable) << " " << qPrintable(launchArguments.join(" ")) << endl; if (!connection.execute(TestConfiguration::remoteExecutable, launchArguments.join(" "), timeout)) { cout << "Error: Could not execute target file" << endl; + return -1; } -- cgit v0.12 From 13bc92c6c9c0b1b7b6c9915848175a77ec082a85 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 8 Jul 2009 16:02:55 -0700 Subject: Pass the device arg to the keyboard drivers. We didn't use to pass the device in to the keyboard handlers rendering them mostly useless. Reviewed-by: TrustMe --- src/plugins/kbddrivers/sl5000/main.cpp | 3 +-- src/plugins/kbddrivers/usb/main.cpp | 3 +-- src/plugins/kbddrivers/vr41xx/main.cpp | 3 +-- src/plugins/kbddrivers/yopy/main.cpp | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/plugins/kbddrivers/sl5000/main.cpp b/src/plugins/kbddrivers/sl5000/main.cpp index 4d61266..cc68747 100644 --- a/src/plugins/kbddrivers/sl5000/main.cpp +++ b/src/plugins/kbddrivers/sl5000/main.cpp @@ -66,10 +66,9 @@ QStringList QSL5000KbdDriver::keys() const QWSKeyboardHandler* QSL5000KbdDriver::create(const QString &driver, const QString &device) { - Q_UNUSED(device); if (driver.compare(QLatin1String("SL5000"), Qt::CaseInsensitive)) return 0; - return new QWSSL5000KeyboardHandler(driver); + return new QWSSL5000KeyboardHandler(device); } Q_EXPORT_PLUGIN2(qwssl5000kbddriver, QSL5000KbdDriver) diff --git a/src/plugins/kbddrivers/usb/main.cpp b/src/plugins/kbddrivers/usb/main.cpp index 8f49366..38d460c 100644 --- a/src/plugins/kbddrivers/usb/main.cpp +++ b/src/plugins/kbddrivers/usb/main.cpp @@ -66,10 +66,9 @@ QStringList QUsbKbdDriver::keys() const QWSKeyboardHandler* QUsbKbdDriver::create(const QString &driver, const QString &device) { - Q_UNUSED(device); if (driver.compare(QLatin1String("Usb"), Qt::CaseInsensitive)) return 0; - return new QWSUsbKeyboardHandler(driver); + return new QWSUsbKeyboardHandler(device); } Q_EXPORT_PLUGIN2(qwsusbkbddriver, QUsbKbdDriver) diff --git a/src/plugins/kbddrivers/vr41xx/main.cpp b/src/plugins/kbddrivers/vr41xx/main.cpp index 2cba1f7..c9ba4d7 100644 --- a/src/plugins/kbddrivers/vr41xx/main.cpp +++ b/src/plugins/kbddrivers/vr41xx/main.cpp @@ -66,10 +66,9 @@ QStringList QVr41xxKbdDriver::keys() const QWSKeyboardHandler* QVr41xxKbdDriver::create(const QString &driver, const QString &device) { - Q_UNUSED(device); if (driver.compare(QLatin1String("VR41xx"), Qt::CaseInsensitive)) return 0; - return new QWSVr41xxKeyboardHandler(driver); + return new QWSVr41xxKeyboardHandler(device); } Q_EXPORT_PLUGIN2(qwsvr41xxkbddriver, QVr41xxKbdDriver) diff --git a/src/plugins/kbddrivers/yopy/main.cpp b/src/plugins/kbddrivers/yopy/main.cpp index bfddabe..7079d88 100644 --- a/src/plugins/kbddrivers/yopy/main.cpp +++ b/src/plugins/kbddrivers/yopy/main.cpp @@ -66,10 +66,9 @@ QStringList QYopyKbdDriver::keys() const QWSKeyboardHandler* QYopyKbdDriver::create(const QString &driver, const QString &device) { - Q_UNUSED(device); if (driver.compare(QLatin1String("Yopy"), Qt::CaseInsensitive)) return 0; - return new QWSYopyKeyboardHandler(driver); + return new QWSYopyKeyboardHandler(device); } Q_EXPORT_PLUGIN2(qwsyopykbddriver, QYopyKbdDriver) -- cgit v0.12 From dc2b39a866190e302eed171381c2c0384e152800 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 9 Jul 2009 09:25:30 +0200 Subject: qdoc: Removed unnecessary error report/rule qdoc reported an error if you used \section2 on its owin, i.e. with no outer \section1. While strictly speaking correct, it imposed an unnecessary restriction, e.g. sometimes you just want to use \section2 to get a smaller title for a section. --- tools/qdoc3/doc.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/qdoc3/doc.cpp b/tools/qdoc3/doc.cpp index 222b9a1..d5aca0e 100644 --- a/tools/qdoc3/doc.cpp +++ b/tools/qdoc3/doc.cpp @@ -1677,10 +1677,13 @@ void DocParser::startSection(Doc::SectioningUnit unit, int cmd) leavePara(); if (currentSectioningUnit == Doc::Book) { +#if 0 + // mws didn't think this was necessary. if (unit > Doc::Section1) location().warning(tr("Unexpected '\\%1' without '\\%2'") .arg(cmdName(cmd)) .arg(cmdName(CMD_SECTION1))); +#endif currentSectioningUnit = (Doc::SectioningUnit) (unit - 1); priv->constructExtra(); priv->extra->sectioningUnit = currentSectioningUnit; -- cgit v0.12 From d0a36a9e33937066866ef1ecfde3eaecd578d0b7 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Thu, 9 Jul 2009 10:37:26 +0200 Subject: Add QT_END_HEADER to fix compile on PowerPC Mac and make autotest pass. --- src/corelib/tools/qstring.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 6bb0d8e..235c603 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -1235,6 +1235,8 @@ inline int QStringRef::localeAwareCompare(const QStringRef &s1, const QStringRef QT_END_NAMESPACE +QT_END_HEADER + #ifdef QT_USE_FAST_CONCATENATION #include #endif -- cgit v0.12 From 015946b60c991593d28cd1d9383f0eb7e8c30334 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 9 Jul 2009 10:40:13 +0200 Subject: Remove unneeded assert. Triggered on Designer startup on Linux. Acked-by: Thierry Bastian --- src/gui/widgets/qwidgetanimator.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gui/widgets/qwidgetanimator.cpp b/src/gui/widgets/qwidgetanimator.cpp index 26cf905..1a93b51 100644 --- a/src/gui/widgets/qwidgetanimator.cpp +++ b/src/gui/widgets/qwidgetanimator.cpp @@ -100,7 +100,6 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo m_animation_map[widget] = anim; connect(anim, SIGNAL(finished()), SLOT(animationFinished())); anim->start(QPropertyAnimation::DeleteWhenStopped); - Q_ASSERT(animate || widget->geometry() == final_geometry); #else //we do it in one shot widget->setGeometry(final_geometry); -- cgit v0.12 From def00d15449551cd2e98b1f3f5b4199ad8be92c2 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 9 Jul 2009 12:14:38 +0200 Subject: autotest fix On the font from the font dialog, we can only test family, size and style --- tests/auto/qfontdialog/tst_qfontdialog.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/auto/qfontdialog/tst_qfontdialog.cpp b/tests/auto/qfontdialog/tst_qfontdialog.cpp index 5f1797b..cbdd440 100644 --- a/tests/auto/qfontdialog/tst_qfontdialog.cpp +++ b/tests/auto/qfontdialog/tst_qfontdialog.cpp @@ -170,8 +170,12 @@ void tst_QFontDialog::task256466_wrongStyle() for (int i = 0; i < familyList->model()->rowCount(); ++i) { QModelIndex currentFamily = familyList->model()->index(i, 0); familyList->setCurrentIndex(currentFamily); - QCOMPARE(dialog.currentFont(), fdb.font(currentFamily.data().toString(), - styleList->currentIndex().data().toString(), sizeList->currentIndex().data().toInt())); + const QFont current = dialog.currentFont(), + expected = fdb.font(currentFamily.data().toString(), + styleList->currentIndex().data().toString(), sizeList->currentIndex().data().toInt()); + QCOMPARE(current.family(), expected.family()); + QCOMPARE(current.style(), expected.style()); + QCOMPARE(current.pointSizeF(), expected.pointSizeF()); } } -- cgit v0.12 From ce770ef755e2dae405ea3c91bd0dedda2f267716 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Thu, 9 Jul 2009 10:52:50 +0200 Subject: QRingBuffer micro optimization --- src/corelib/tools/qringbuffer_p.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qringbuffer_p.h b/src/corelib/tools/qringbuffer_p.h index f3daca7..008c068 100644 --- a/src/corelib/tools/qringbuffer_p.h +++ b/src/corelib/tools/qringbuffer_p.h @@ -303,6 +303,9 @@ public: // read an unspecified amount (will read the first buffer) inline QByteArray read() { + if (bufferSize == 0) + return QByteArray(); + // multiple buffers, just take the first one if (head == 0 && tailBuffer != 0) { QByteArray qba = buffers.takeFirst(); @@ -325,7 +328,7 @@ public: // We can avoid by initializing the QRingBuffer with basicBlockSize of 0 // and only using this read() function. QByteArray qba(readPointer(), nextDataBlockSize()); - buffers.takeFirst(); + buffers.removeFirst(); head = 0; if (tailBuffer == 0) { buffers << QByteArray(); -- cgit v0.12 From cdedc4374b02c0c291c110fd03c77eb6cd1ce69d Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Thu, 2 Jul 2009 13:42:09 +0200 Subject: QNAM: httpDownloadPerformance auto test Reviewed-by: Peter Hartmann --- tests/auto/qnetworkreply/tst_qnetworkreply.cpp | 126 +++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 0dd3cd1..18919a7 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -219,6 +219,9 @@ private Q_SLOTS: void proxyChange(); void authorizationError_data(); void authorizationError(); + + void httpDownloadPerformance_data(); + void httpDownloadPerformance(); }; QT_BEGIN_NAMESPACE @@ -3066,5 +3069,128 @@ void tst_QNetworkReply::authorizationError() QCOMPARE(QString(reply->readAll()), httpBody); } +class HttpDownloadPerformanceClient : QObject { + Q_OBJECT; + QIODevice *device; + public: + HttpDownloadPerformanceClient (QIODevice *dev) : device(dev){ + connect(dev, SIGNAL(readyRead()), this, SLOT(readyReadSlot())); + } + + public slots: + void readyReadSlot() { + device->readAll(); + } + +}; + +class HttpDownloadPerformanceServer : QObject { + Q_OBJECT; + qint64 dataSize; + qint64 dataSent; + QTcpServer server; + QTcpSocket *client; + bool serverSendsContentLength; + bool chunkedEncoding; + +public: + HttpDownloadPerformanceServer (qint64 ds, bool sscl, bool ce) : dataSize(ds), dataSent(0), + client(0), serverSendsContentLength(sscl), chunkedEncoding(ce) { + server.listen(); + connect(&server, SIGNAL(newConnection()), this, SLOT(newConnectionSlot())); + } + + int serverPort() { + return server.serverPort(); + } + +public slots: + + void newConnectionSlot() { + client = server.nextPendingConnection(); + client->setParent(this); + connect(client, SIGNAL(readyRead()), this, SLOT(readyReadSlot())); + connect(client, SIGNAL(bytesWritten(qint64)), this, SLOT(bytesWrittenSlot(qint64))); + } + + void readyReadSlot() { + client->readAll(); + client->write("HTTP/1.0 200 OK\n"); + if (serverSendsContentLength) + client->write(QString("Content-Length: " + QString::number(dataSize) + "\n").toAscii()); + if (chunkedEncoding) + client->write(QString("Transfer-Encoding: chunked\n").toAscii()); + client->write("Connection: close\n\n"); + } + + void bytesWrittenSlot(qint64 amount) { + if (dataSent == dataSize && client) { + // close eventually + + // chunked encoding: we have to send a last "empty" chunk + if (chunkedEncoding) + client->write(QString("0\r\n\r\n").toAscii()); + + client->disconnectFromHost(); + server.close(); + client = 0; + return; + } + + // send data + if (client && client->bytesToWrite() < 100*1024 && dataSent < dataSize) { + qint64 amount = qMin(qint64(16*1024), dataSize - dataSent); + QByteArray data(amount, '@'); + + if (chunkedEncoding) { + client->write(QString(QString("%1").arg(amount,0,16).toUpper() + "\r\n").toAscii()); + client->write(data.constData(), amount); + client->write(QString("\r\n").toAscii()); + } else { + client->write(data.constData(), amount); + } + + dataSent += amount; + } + } +}; + +void tst_QNetworkReply::httpDownloadPerformance_data() +{ + QTest::addColumn("serverSendsContentLength"); + QTest::addColumn("chunkedEncoding"); + + QTest::newRow("Server sends no Content-Length") << false << false; + QTest::newRow("Server sends Content-Length") << true << false; + QTest::newRow("Server uses chunked encoding") << false << true; + +} + +void tst_QNetworkReply::httpDownloadPerformance() +{ + QFETCH(bool, serverSendsContentLength); + QFETCH(bool, chunkedEncoding); + + enum {UploadSize = 1000*1024*1024}; // 1000 MB + HttpDownloadPerformanceServer server(UploadSize, serverSendsContentLength, chunkedEncoding); + + QNetworkRequest request(QUrl("http://127.0.0.1:" + QString::number(server.serverPort()) + "/?bare=1")); + QNetworkReply* reply = manager.get(request); + + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection); + HttpDownloadPerformanceClient client(reply); + + QTime time; + time.start(); + QTestEventLoop::instance().enterLoop(40); + QVERIFY(!QTestEventLoop::instance().timeout()); + + qint64 elapsed = time.elapsed(); + qWarning() << "tst_QNetworkReply::httpDownloadPerformance" << elapsed << "msec, " + << ((UploadSize/1024.0)/(elapsed/1000.0)) << " kB/sec"; + + delete reply; +} + QTEST_MAIN(tst_QNetworkReply) #include "tst_qnetworkreply.moc" -- cgit v0.12 From bdb6d461f4889e38296c859446283c0f9397dbdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Thu, 9 Jul 2009 11:08:48 +0200 Subject: Rendering artifacts when hiding a QGraphicsItem. The problem was that update() followed by hide() didn't work as expected because the update() caused all sub-sequent update requests to be discareded. This is correct, however, we have to make sure the ignoreVisible/ignoreOpacity bit is set properly; we won't process a hidden item otherwise. Auto-test included. --- src/gui/graphicsview/qgraphicsscene.cpp | 10 ++++++++++ tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index ae6c53c..0ca72b7 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4358,6 +4358,16 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b /*ignoreVisibleBit=*/force, /*ignoreDirtyBit=*/removingItemFromScene || invalidateChildren, /*ignoreOpacity=*/ignoreOpacity)) { + if (item->d_ptr->dirty) { + // The item is already marked as dirty and will be processed later. However, + // we have to make sure ignoreVisible and ignoreOpacity are set properly; + // otherwise things like: item->update(); item->hide() (force is now true) + // won't work as expected. + if (force) + item->d_ptr->ignoreVisible = 1; + if (ignoreOpacity) + item->d_ptr->ignoreOpacity = 1; + } return; } diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 3f7a50b..d689293 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -6625,6 +6625,17 @@ void tst_QGraphicsItem::update() qApp->processEvents(); QCOMPARE(item->repaints, 0); QCOMPARE(view.repaints, 0); + + // Make sure the area occupied by an item is repainted when hiding it. + view.reset(); + item->repaints = 0; + item->update(); // Full update; all sub-sequent update requests are discarded. + item->hide(); // visible set to 0. ignoreVisible must be set to 1; the item won't be processed otherwise. + qApp->processEvents(); + QCOMPARE(item->repaints, 0); + QCOMPARE(view.repaints, 1); + // The entire item's bounding rect (adjusted for antialiasing) should have been painted. + QCOMPARE(view.paintedRegion, expectedRegion); } void tst_QGraphicsItem::setTransformProperties_data() -- cgit v0.12 From 259575734a52c27018f26e1f7c857ae25a27d39a Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 9 Jul 2009 11:35:56 +0200 Subject: doc: Clarified the meanings in Qt for reentrant and thread-safe. Task-number: 189232 --- doc/src/threads.qdoc | 82 ++++++++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 38 deletions(-) diff --git a/doc/src/threads.qdoc b/doc/src/threads.qdoc index 9f7f857..e3da0d4 100644 --- a/doc/src/threads.qdoc +++ b/doc/src/threads.qdoc @@ -262,48 +262,41 @@ \keyword thread-safe \section1 Reentrancy and Thread-Safety - Throughout the Qt documentation, the terms \e reentrant and \e - thread-safe are used to specify how a function can be used in - multithreaded applications: + Throughout the documentation, the terms \e{reentrant} and + \e{thread-safe} are used to mark classes and functions to indicate + how they can be used in multithread applications: \list - \o A \e reentrant function can be called simultaneously by - multiple threads provided that each invocation of the function - references unique data. - \o A \e thread-safe function can be called simultaneously by - multiple threads when each invocation references shared data. - All access to the shared data is serialized. + \o A \e thread-safe function can be called simultaneously from + multiple threads, even when the invocations use shared data, + because all references to the shared data are serialized. + \o A \e reentrant function can also be called simultaneously from + multiple threads, but only if each invocation uses its own data. \endlist - By extension, a class is said to be reentrant if each and every - one of its functions can be called simultaneously by multiple - threads on different instances of the class. Similarly, the class - is said to be thread-safe if the functions can be called by - different threads on the same instance. + Hence, a \e{thread-safe} function is always \e{reentrant}, but a + \e{reentrant} function is not always \e{thread-safe}. - Classes in the documentation will be documented as thread-safe only - if they are intended to be used by multiple threads. + By extension, a class is said to be \e{reentrant} if its member + functions can be called safely from multiple threads as long as + each thread uses a \e{different} instance of the class. The class + is \e{thread-safe} if its member functions can be called safely + from multiple threads, even if all the threads use the \e{same} + instance of the class. - Note that the terminology in this domain isn't entirely - standardized. POSIX uses a somewhat different definition of - reentrancy and thread-safety for its C APIs. When dealing with an - object-oriented C++ class library such as Qt, the definitions - must be adapted. - - Most C++ classes are inherently reentrant, since they typically - only reference member data. Any thread can call such a member - function on an instance of the class, as long as no other thread - is calling a member function on the same instance. For example, - the \c Counter class below is reentrant: + C++ classes are often reentrant, simply because they only access + their own member data. Any thread can call a member function on an + instance of a reentrant class, as long as no other thread can call + a member function on the \e{same} instance of the class at the + same time. For example, the \c Counter class below is reentrant: \snippet doc/src/snippets/threads/threads.cpp 3 \snippet doc/src/snippets/threads/threads.cpp 4 The class isn't thread-safe, because if multiple threads try to modify the data member \c n, the result is undefined. This is - because C++'s \c ++ and \c -- operators aren't necessarily - atomic. Indeed, they usually expand to three machine - instructions: + because the \c ++ and \c -- operators aren't always atomic. + Indeed, they usually expand to three machine instructions: \list 1 \o Load the variable's value in a register. @@ -332,14 +325,27 @@ declared with the \c mutable qualifier because we need to lock and unlock the mutex in \c value(), which is a const function. - Most Qt classes are reentrant and not thread-safe, to avoid the - overhead of repeatedly locking and unlocking a QMutex. For - example, QString is reentrant, meaning that you can use it in - different threads, but you can't access the same QString object - from different threads simultaneously (unless you protect it with - a mutex yourself). A few classes and functions are thread-safe; - these are mainly thread-related classes such as QMutex, or - fundamental functions such as QCoreApplication::postEvent(). + Most Qt classes are \e{reentrant}, but they are not made + \e{thread-safe}, because making them thread-safe would incur the + extra overhead of repeatedly locking and unlocking a QMutex. For + example, QString is reentrant but not thread-safe. You can safely + access \e{different} instances of QString from multiple threads + simultaneously, but you can't access the \e{same} instance of + QString from multiple threads simultaneously (unless you protect + the accesses yourself with a QMutex). + + Some Qt classes and functions are thread-safe. These are mainly + the thread-related classes (e.g. QMutex) and fundamental functions + (e.g. QCoreApplication::postEvent()). + + \note Qt Classes are only documented as \e{thread-safe} if they + are intended to be used by multiple threads. + + \note Terminology in the multithreading domain isn't entirely + standardized. POSIX uses definitions of reentrant and thread-safe + that are somewhat different for its C APIs. When using other + object-oriented C++ class libraries with Qt, be sure the + definitions in use are understood. \section1 Threads and QObjects -- cgit v0.12 From d64754db278e9fe07dbd6c8b7d297600a10d3ae5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 8 Jul 2009 19:21:37 +0200 Subject: Stop showing then hiding windows on starting designer in top-level mode Kind of like f37bd111f7622a34b3a7bd63f5a82f6042dc0f0d, but the real thing. The widget box wasn't showing on Linux when switching to top-level mode. Incidentally, this was the main window there... Reviewed-by: Friedemann Kleint After some persuasion the Cat also came to see things this way. --- tools/designer/src/designer/qdesigner_workbench.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tools/designer/src/designer/qdesigner_workbench.cpp b/tools/designer/src/designer/qdesigner_workbench.cpp index ce8dde6..5f8d2a9 100644 --- a/tools/designer/src/designer/qdesigner_workbench.cpp +++ b/tools/designer/src/designer/qdesigner_workbench.cpp @@ -462,7 +462,6 @@ void QDesignerWorkbench::switchToTopLevelMode() // make sure that the widgetbox is visible if it is different from neutral. QDesignerToolWindow *widgetBoxWrapper = widgetBoxToolWindow(); Q_ASSERT(widgetBoxWrapper); - const bool needWidgetBoxWrapperVisible = widgetBoxWrapper->action()->isChecked(); switchToNeutralMode(); const QPoint desktopOffset = desktopGeometry().topLeft(); @@ -501,9 +500,6 @@ void QDesignerWorkbench::switchToTopLevelMode() found_visible_window |= tw->isVisible(); } - if (needWidgetBoxWrapperVisible) - widgetBoxWrapper->action()->trigger(); - if (!m_toolWindows.isEmpty() && !found_visible_window) m_toolWindows.first()->show(); -- cgit v0.12 From ed99255e8e998ef3f51de22b31c76107bb9aa0df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 9 Jul 2009 10:55:37 +0200 Subject: Designer: Restore Widget box title when switching to docked mode Reviewed-by: Friedemann Kleint --- tools/designer/src/designer/qdesigner_workbench.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/designer/src/designer/qdesigner_workbench.cpp b/tools/designer/src/designer/qdesigner_workbench.cpp index 5f8d2a9..c9d9fc4 100644 --- a/tools/designer/src/designer/qdesigner_workbench.cpp +++ b/tools/designer/src/designer/qdesigner_workbench.cpp @@ -410,6 +410,12 @@ void QDesignerWorkbench::switchToDockedMode() switchToNeutralMode(); +#ifndef Q_WS_MAC + QDesignerToolWindow *widgetBoxWrapper = widgetBoxToolWindow(); + widgetBoxWrapper->action()->setVisible(true); + widgetBoxWrapper->setWindowTitle(tr("Widget Box")); +#endif + m_mode = DockedMode; const QDesignerSettings settings(m_core); m_dockedMainWindow = new DockedMainWindow(this, m_toolbarMenu, m_toolWindows); -- cgit v0.12 From 14ef40f9b96c5afea9d08701a2a1856388349f9e Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 3 Jul 2009 16:32:26 +0200 Subject: Use 'struct QConcatenable' instead of 'class QConcatenable' to make compiler distinguishing both happy. --- src/corelib/tools/qstringbuilder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h index 852c072..4d6b64b 100644 --- a/src/corelib/tools/qstringbuilder.h +++ b/src/corelib/tools/qstringbuilder.h @@ -69,7 +69,7 @@ private: }; -template class QConcatenable {}; +template struct QConcatenable {}; template class QStringBuilder -- cgit v0.12 From 6574240d8ea657d02c3d5bf5567da7d28f42d69b Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Thu, 9 Jul 2009 12:40:22 +0200 Subject: QHttpNetworkReply: Cache isChunked Cache return value of expensive function. Reviewed-by: Peter Hartmann --- src/network/access/qhttpnetworkreply.cpp | 6 +++++- src/network/access/qhttpnetworkreply_p.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index 483589b..7a616aa 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -201,6 +201,7 @@ bool QHttpNetworkReply::isFinished() const QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl) : QHttpNetworkHeaderPrivate(newUrl), state(NothingDoneState), statusCode(100), majorVersion(0), minorVersion(0), bodyLength(0), contentRead(0), totalProgress(0), + chunkedTransferEncoding(0), currentChunkSize(0), currentChunkRead(0), connection(0), initInflate(false), autoDecompress(false), responseData(0), requestIsPrepared(false) { @@ -506,6 +507,9 @@ qint64 QHttpNetworkReplyPrivate::readHeader(QAbstractSocket *socket) state = ReadingDataState; fragment.clear(); // next fragment bodyLength = contentLength(); // cache the length + + // cache isChunked() since it is called often + chunkedTransferEncoding = headerField("transfer-encoding").toLower().contains("chunked"); } return bytes; } @@ -546,7 +550,7 @@ void QHttpNetworkReplyPrivate::parseHeader(const QByteArray &header) bool QHttpNetworkReplyPrivate::isChunked() { - return headerField("transfer-encoding").toLower().contains("chunked"); + return chunkedTransferEncoding; } bool QHttpNetworkReplyPrivate::connectionCloseEnabled() diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index b86cfaa..5eb70ce 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -198,6 +198,7 @@ public: qint64 contentRead; qint64 totalProgress; QByteArray fragment; // used for header, status, chunk header etc, not for reply data + bool chunkedTransferEncoding; qint64 currentChunkSize; qint64 currentChunkRead; QPointer connection; -- cgit v0.12 From 1c6edd28d528dbb946fcf2a9e0d4349075ca6f9b Mon Sep 17 00:00:00 2001 From: Suneel BS Date: Tue, 7 Jul 2009 14:57:02 +0530 Subject: Fixed inheritence of SVG fill attributes. Fixed inheritence of fill-opacity, fill-rule and fill. Autotest included. Reviewed-by: Kim --- src/svg/qsvghandler.cpp | 57 ++++++++++++++--------- src/svg/qsvgstyle.cpp | 14 +++++- src/svg/qsvgstyle_p.h | 28 +++++++----- tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp | 68 ++++++++++++++++++++++++++++ 4 files changed, 132 insertions(+), 35 deletions(-) diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index 5950fac..f64fb3e 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -631,15 +631,32 @@ static void parseBrush(QSvgNode *node, QString opacity = attributes.value(QLatin1String("fill-opacity")).toString(); QString myId = someId(attributes); - value = value.trimmed(); - fillRule = fillRule.trimmed(); - if (!value.isEmpty() || !fillRule.isEmpty()) { - Qt::FillRule f = Qt::WindingFill; + QSvgFillStyle *inherited = + static_cast(node->parent()->styleProperty( + QSvgStyleProperty::FILL)); + QSvgFillStyle *prop = new QSvgFillStyle(QColor(Qt::black)); + + //fill-rule attribute handling + Qt::FillRule f = Qt::WindingFill; + if (!fillRule.isEmpty() && fillRule != QLatin1String("inherit")) { if (fillRule == QLatin1String("evenodd")) f = Qt::OddEvenFill; + } else if (inherited) { + f = inherited->fillRule(); + } + + //fill-opacity atttribute handling + qreal fillOpacity = 1.0; + if (!opacity.isEmpty() && opacity != QLatin1String("inherit")) { + fillOpacity = qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity))); + } else if (inherited) { + fillOpacity = inherited->fillOpacity(); + } + + //fill attribute handling + if ((!value.isEmpty()) && (value != QLatin1String("inherit")) ) { if (value.startsWith(QLatin1String("url"))) { value = value.remove(0, 3); - QSvgFillStyle *prop = new QSvgFillStyle(0); QSvgStyleProperty *style = styleFromUrl(node, value); if (style) { prop->setFillStyle(style); @@ -648,30 +665,26 @@ static void parseBrush(QSvgNode *node, prop->setGradientId(id); prop->setGradientResolved(false); } - if (!opacity.isEmpty()) { - qreal clampedOpacity = qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity))); - prop->setFillOpacity(clampedOpacity); - } - if (!fillRule.isEmpty()) - prop->setFillRule(f); - node->appendStyleProperty(prop,myId); } else if (value != QLatin1String("none")) { QColor color; - if (constructColor(value, opacity, color, handler)) { - QSvgFillStyle *prop = new QSvgFillStyle(QBrush(color)); - if (!fillRule.isEmpty()) - prop->setFillRule(f); - node->appendStyleProperty(prop, myId); - } + if (resolveColor(value, color, handler)) + prop->setBrush(QBrush(color)); } else { - QSvgFillStyle *prop = new QSvgFillStyle(QBrush(Qt::NoBrush)); - if (!fillRule.isEmpty()) - prop->setFillRule(f); - node->appendStyleProperty(prop, myId); + prop->setBrush(QBrush(Qt::NoBrush)); + } + } else if (inherited) { + if (inherited->style()) { + prop->setFillStyle(inherited->style()); + } else { + prop->setBrush(inherited->qbrush()); } } + prop->setFillOpacity(fillOpacity); + prop->setFillRule(f); + node->appendStyleProperty(prop,myId); } + static void parseQPen(QPen &pen, QSvgNode *node, const QSvgAttributes &attributes, QSvgHandler *handler) diff --git a/src/svg/qsvgstyle.cpp b/src/svg/qsvgstyle.cpp index 556201b..4c8247b 100644 --- a/src/svg/qsvgstyle.cpp +++ b/src/svg/qsvgstyle.cpp @@ -81,12 +81,12 @@ void QSvgQualityStyle::revert(QPainter *, QSvgExtraStates &) } QSvgFillStyle::QSvgFillStyle(const QBrush &brush) - : m_fill(brush), m_style(0), m_fillRuleSet(false), m_fillOpacitySet(false), m_gradientResolved (true) + : m_fill(brush), m_style(0), m_fillRuleSet(false), m_fillOpacitySet(false), m_fillRule(Qt::WindingFill), m_fillOpacity(1.0), m_gradientResolved (true) { } QSvgFillStyle::QSvgFillStyle(QSvgStyleProperty *style) - : m_style(style), m_fillRuleSet(false), m_fillOpacitySet(false), m_gradientResolved (true) + : m_style(style), m_fillRuleSet(false), m_fillOpacitySet(false), m_fillRule(Qt::WindingFill), m_fillOpacity(1.0), m_gradientResolved (true) { } @@ -102,6 +102,16 @@ void QSvgFillStyle::setFillOpacity(qreal opacity) m_fillOpacity = opacity; } +void QSvgFillStyle::setFillStyle(QSvgStyleProperty* style) +{ + m_style = style; +} + +void QSvgFillStyle::setBrush(QBrush brush) +{ + m_fill = brush; +} + static void recursivelySetFill(QSvgNode *node, Qt::FillRule f) { if (node->type() == QSvgNode::PATH) { diff --git a/src/svg/qsvgstyle_p.h b/src/svg/qsvgstyle_p.h index f1d0811..ac5e109 100644 --- a/src/svg/qsvgstyle_p.h +++ b/src/svg/qsvgstyle_p.h @@ -224,12 +224,29 @@ public: void setFillRule(Qt::FillRule f); void setFillOpacity(qreal opacity); + void setFillStyle(QSvgStyleProperty* style); + void setBrush(QBrush brush); const QBrush & qbrush() const { return m_fill; } + qreal fillOpacity() const + { + return m_fillOpacity; + } + + Qt::FillRule fillRule() const + { + return m_fillRule; + } + + QSvgStyleProperty* style() const + { + return m_style; + } + void setGradientId(const QString &Id) { m_gradientId = Id; @@ -240,7 +257,6 @@ public: return m_gradientId; } - void setGradientResolved(bool resolved) { m_gradientResolved = resolved; @@ -251,16 +267,6 @@ public: return m_gradientResolved; } - void setFillStyle(QSvgStyleProperty* style) - { - m_style = style; - } - - void setBrush(QBrush brush) - { - m_fill = brush; - } - private: // fill v v 'inherit' | // fill-opacity v v 'inherit' | diff --git a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp index 3f658ec..68539ef 100644 --- a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp +++ b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp @@ -81,6 +81,7 @@ private slots: void paths(); void displayMode(); void strokeInherit(); + void testFillInheritance(); #ifndef QT_NO_COMPRESS void testGzLoading(); @@ -1053,5 +1054,72 @@ void tst_QSvgRenderer::strokeInherit() } } +void tst_QSvgRenderer::testFillInheritance() +{ + static const char *svgs[] = { + //reference + "" + " " + "", + "" + " " + " " + "", + "" + " " + " " + " " + " " + "", + "" + " " + " " + " " + " " + " " + " " + "", + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + "", + "" + " " + " " + " " + " " + " " + " " + "" + }; + + 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, 200, 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" -- cgit v0.12 From ed564a3fef39b649bd38a181126711431f0b40ab Mon Sep 17 00:00:00 2001 From: Suneel BS Date: Thu, 14 May 2009 14:25:16 +0530 Subject: Fixed handling of some SVG attributes when value is invalid. When the parsing of an SVG attribute fails, it should be given the default value. Fixed handling of invalid viewBox, stop-opacity and stop-offset. Autotest included. Reviewed-by: Kim --- src/svg/qsvghandler.cpp | 48 +++++++++++----- tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp | 84 ++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 14 deletions(-) diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index f64fb3e..5f9d1dd 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -68,6 +68,7 @@ QT_BEGIN_NAMESPACE + double qstrtod(const char *s00, char const **se, bool *ok); static bool parsePathDataFast(const QStringRef &data, QPainterPath &path); @@ -320,6 +321,7 @@ static qreal toDouble(const QChar *&str) ++str; } } + temp[pos] = '\0'; qreal val; @@ -365,16 +367,24 @@ static qreal toDouble(const QChar *&str) return val; } -static qreal toDouble(const QString &str) +static qreal toDouble(const QString &str, bool *ok = NULL) { const QChar *c = str.constData(); - return toDouble(c); + qreal res = toDouble(c); + if (ok) { + *ok = ((*c) == QLatin1Char('\0')); + } + return res; } -static qreal toDouble(const QStringRef &str) +static qreal toDouble(const QStringRef &str, bool *ok = NULL) { const QChar *c = str.constData(); - return toDouble(c); + qreal res = toDouble(c); + if (ok) { + *ok = (c == (str.constData() + str.length())); + } + return res; } static QVector parseNumbersList(const QChar *&str) @@ -497,14 +507,17 @@ static bool constructColor(const QString &colorStr, const QString &opacity, if (!resolveColor(colorStr, color, handler)) return false; if (!opacity.isEmpty()) { - qreal op = qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity))); + bool ok = true; + qreal op = qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity, &ok))); + if (!ok) + op = 1.0; color.setAlphaF(op); } return true; } static qreal parseLength(const QString &str, QSvgHandler::LengthType &type, - QSvgHandler *handler) + QSvgHandler *handler, bool *ok = NULL) { QString numStr = str.trimmed(); @@ -533,15 +546,15 @@ static qreal parseLength(const QString &str, QSvgHandler::LengthType &type, type = handler->defaultCoordinateSystem(); //type = QSvgHandler::LT_OTHER; } - qreal len = toDouble(numStr); + qreal len = toDouble(numStr, ok); //qDebug()<<"len is "<setViewBox(QRectF(x, y, w, h)); - } else if (width && height){ + + } else if (width && height) { if (type == QSvgHandler::LT_PT) { width = convertToPixels(width, false, type); height = convertToPixels(height, false, type); } - node->setViewBox(QRectF(0, 0, width, height)); } - handler->setDefaultCoordinateSystem(QSvgHandler::LT_PX); return node; diff --git a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp index 68539ef..2bbe897 100644 --- a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp +++ b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp @@ -82,6 +82,7 @@ private slots: void displayMode(); void strokeInherit(); void testFillInheritance(); + void testStopOffsetOpacity(); #ifndef QT_NO_COMPRESS void testGzLoading(); @@ -1121,5 +1122,88 @@ void tst_QSvgRenderer::testFillInheritance() } } } +void tst_QSvgRenderer::testStopOffsetOpacity() +{ + static const char *svgs[] = { + //reference + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "", + //Stop Offset + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "", + //Stop Opacity + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "", + //Stop offset and Stop opacity + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + }; + + QImage images[4]; + QPainter p; + + for (int i = 0; i < 4; ++i) { + QByteArray data(svgs[i]); + QSvgRenderer renderer(data); + QVERIFY(renderer.isValid()); + images[i] = QImage(64, 64, QImage::Format_ARGB32_Premultiplied); + images[i].fill(-1); + p.begin(&images[i]); + renderer.render(&p); + p.end(); + } + QCOMPARE(images[0], images[1]); + QCOMPARE(images[0], images[2]); + QCOMPARE(images[0], images[3]); +} + QTEST_MAIN(tst_QSvgRenderer) #include "tst_qsvgrenderer.moc" -- cgit v0.12 From cae93bf07958ea065f4fefd729099bac59a1bf14 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Thu, 9 Jul 2009 13:18:28 +0200 Subject: Fixes a memory corruption when converting data with QIconvCodec This partially reverts 9a5b40a011bd1b15a67d83564af55011761f8ad9 for the QIconvCodec. Reviewed-by: hjk --- src/corelib/codecs/qiconvcodec.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/corelib/codecs/qiconvcodec.cpp b/src/corelib/codecs/qiconvcodec.cpp index 1bf76ea..188ac8c 100644 --- a/src/corelib/codecs/qiconvcodec.cpp +++ b/src/corelib/codecs/qiconvcodec.cpp @@ -225,10 +225,11 @@ QString QIconvCodec::convertToUnicode(const char* chars, int len, ConverterState char *inBytes = const_cast(chars); #endif + QByteArray in; if (remainingCount) { // we have to prepend the remaining bytes from the previous conversion inBytesLeft += remainingCount; - QByteArray in(inBytesLeft, Qt::Uninitialized); + in.resize(inBytesLeft); inBytes = in.data(); memcpy(in.data(), remainingBuffer, remainingCount); @@ -362,9 +363,10 @@ QByteArray QIconvCodec::convertFromUnicode(const QChar *uc, int len, ConverterSt inBytes = const_cast(reinterpret_cast(uc)); inBytesLeft = len * sizeof(QChar); + QByteArray in; if (convState && convState->remainingChars) { // we have one surrogate char to be prepended - QByteArray in(sizeof(QChar) + len, Qt::Uninitialized); + in.resize(sizeof(QChar) + len); inBytes = in.data(); QChar remaining = convState->state_data[0]; -- cgit v0.12 From 916b5c69e1ed5667e4fe97a21e7e15abfd60ec3d Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 9 Jul 2009 13:41:40 +0200 Subject: doc: Minor edits of reentrant/thread-safe expalantion. Task-number: 189232 --- doc/src/threads.qdoc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/src/threads.qdoc b/doc/src/threads.qdoc index e3da0d4..8469f51 100644 --- a/doc/src/threads.qdoc +++ b/doc/src/threads.qdoc @@ -278,7 +278,7 @@ \e{reentrant} function is not always \e{thread-safe}. By extension, a class is said to be \e{reentrant} if its member - functions can be called safely from multiple threads as long as + functions can be called safely from multiple threads, as long as each thread uses a \e{different} instance of the class. The class is \e{thread-safe} if its member functions can be called safely from multiple threads, even if all the threads use the \e{same} @@ -325,14 +325,14 @@ declared with the \c mutable qualifier because we need to lock and unlock the mutex in \c value(), which is a const function. - Most Qt classes are \e{reentrant}, but they are not made + Many Qt classes are \e{reentrant}, but they are not made \e{thread-safe}, because making them thread-safe would incur the extra overhead of repeatedly locking and unlocking a QMutex. For example, QString is reentrant but not thread-safe. You can safely access \e{different} instances of QString from multiple threads - simultaneously, but you can't access the \e{same} instance of - QString from multiple threads simultaneously (unless you protect - the accesses yourself with a QMutex). + simultaneously, but you can't safely access the \e{same} instance + of QString from multiple threads simultaneously (unless you + protect the accesses yourself with a QMutex). Some Qt classes and functions are thread-safe. These are mainly the thread-related classes (e.g. QMutex) and fundamental functions @@ -345,7 +345,7 @@ standardized. POSIX uses definitions of reentrant and thread-safe that are somewhat different for its C APIs. When using other object-oriented C++ class libraries with Qt, be sure the - definitions in use are understood. + definitions are understood. \section1 Threads and QObjects -- cgit v0.12 From c5371bd1f3df4467ca17350ec7c3e3635d16e393 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 9 Jul 2009 12:10:18 +0200 Subject: QTreeView: use QVariantAnimation over QTimeLine --- src/gui/itemviews/qabstractitemview_p.h | 3 -- src/gui/itemviews/qtreeview.cpp | 74 ++++++++++++++------------------- src/gui/itemviews/qtreeview.h | 2 - src/gui/itemviews/qtreeview_p.h | 43 ++++++++++--------- 4 files changed, 55 insertions(+), 67 deletions(-) diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index 2950bcd..3119c9d 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -61,8 +61,6 @@ #include "QtGui/qmime.h" #include "QtGui/qpainter.h" #include "QtCore/qpair.h" -#include "QtCore/qtimer.h" -#include "QtCore/qtimeline.h" #include "QtGui/qregion.h" #include "QtCore/qdebug.h" #include "QtGui/qpainter.h" @@ -376,7 +374,6 @@ public: QBasicTimer updateTimer; QBasicTimer delayedEditing; QBasicTimer delayedAutoScroll; //used when an item is clicked - QTimeLine timeline; QAbstractItemView::ScrollMode verticalScrollMode; QAbstractItemView::ScrollMode horizontalScrollMode; diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index 7c319dc..ab700e9 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -1267,10 +1267,13 @@ void QTreeView::paintEvent(QPaintEvent *event) Q_D(QTreeView); d->executePostedLayout(); QPainter painter(viewport()); +#ifndef QT_NO_ANIMATION if (d->isAnimating()) { - drawTree(&painter, event->region() - d->animationRect()); + drawTree(&painter, event->region() - d->animatedOperation.rect()); d->drawAnimatedOperation(&painter); - } else { + } else +#endif //QT_NO_ANIMATION + { drawTree(&painter, event->region()); #ifndef QT_NO_DRAGANDDROP d->paintDropIndicator(&painter); @@ -2851,10 +2854,6 @@ void QTreeViewPrivate::initialize() header->setStretchLastSection(true); header->setDefaultAlignment(Qt::AlignLeft|Qt::AlignVCenter); q->setHeader(header); - - // animation - QObject::connect(&timeline, SIGNAL(frameChanged(int)), q, SLOT(_q_animate())); - QObject::connect(&timeline, SIGNAL(finished()), q, SLOT(_q_endAnimatedOperation()), Qt::QueuedConnection); } void QTreeViewPrivate::expand(int item, bool emitSignal) @@ -2864,9 +2863,10 @@ void QTreeViewPrivate::expand(int item, bool emitSignal) if (item == -1 || viewItems.at(item).expanded) return; +#ifndef QT_NO_ANIMATION if (emitSignal && animationsEnabled) - prepareAnimatedOperation(item, AnimatedOperation::Expand); - + prepareAnimatedOperation(item, QVariantAnimation::Forward); +#endif //QT_NO_ANIMATION QAbstractItemView::State oldState = q->state(); q->setState(QAbstractItemView::ExpandingState); const QModelIndex index = viewItems.at(item).index; @@ -2877,8 +2877,10 @@ void QTreeViewPrivate::expand(int item, bool emitSignal) if (emitSignal) { emit q->expanded(index); +#ifndef QT_NO_ANIMATION if (animationsEnabled) beginAnimatedOperation(); +#endif //QT_NO_ANIMATION } if (model->canFetchMore(index)) model->fetchMore(index); @@ -2902,8 +2904,10 @@ void QTreeViewPrivate::collapse(int item, bool emitSignal) if (it == expandedIndexes.end() || viewItems.at(item).expanded == false) return; // nothing to do +#ifndef QT_NO_ANIMATION if (emitSignal && animationsEnabled) - prepareAnimatedOperation(item, AnimatedOperation::Collapse); + prepareAnimatedOperation(item, QVariantAnimation::Backward); +#endif //QT_NO_ANIMATION QAbstractItemView::State oldState = q->state(); q->setState(QAbstractItemView::CollapsingState); @@ -2922,29 +2926,33 @@ void QTreeViewPrivate::collapse(int item, bool emitSignal) if (emitSignal) { emit q->collapsed(modelIndex); +#ifndef QT_NO_ANIMATION if (animationsEnabled) beginAnimatedOperation(); +#endif //QT_NO_ANIMATION } } -void QTreeViewPrivate::prepareAnimatedOperation(int item, AnimatedOperation::Type type) +#ifndef QT_NO_ANIMATION +void QTreeViewPrivate::prepareAnimatedOperation(int item, QVariantAnimation::Direction direction) { animatedOperation.item = item; - animatedOperation.type = type; + animatedOperation.view = q_func(); + animatedOperation.setDirection(direction); int top = coordinateForItem(item) + itemHeight(item); QRect rect = viewport->rect(); rect.setTop(top); - if (type == AnimatedOperation::Collapse) { + if (direction == QVariantAnimation::Backward) { const int limit = rect.height() * 2; int h = 0; int c = item + viewItems.at(item).total + 1; for (int i = item + 1; i < c && h < limit; ++i) h += itemHeight(i); rect.setHeight(h); - animatedOperation.duration = h; + animatedOperation.setEndValue(top + h); } - animatedOperation.top = top; + animatedOperation.setStartValue(top); animatedOperation.before = renderTreeToPixmapForAnimation(rect); } @@ -2953,50 +2961,29 @@ void QTreeViewPrivate::beginAnimatedOperation() Q_Q(QTreeView); QRect rect = viewport->rect(); - rect.setTop(animatedOperation.top); - if (animatedOperation.type == AnimatedOperation::Expand) { + rect.setTop(animatedOperation.top()); + if (animatedOperation.direction() == QVariantAnimation::Forward) { const int limit = rect.height() * 2; int h = 0; int c = animatedOperation.item + viewItems.at(animatedOperation.item).total + 1; for (int i = animatedOperation.item + 1; i < c && h < limit; ++i) h += itemHeight(i); rect.setHeight(h); - animatedOperation.duration = h; + animatedOperation.setEndValue(animatedOperation.top() + h); } animatedOperation.after = renderTreeToPixmapForAnimation(rect); q->setState(QAbstractItemView::AnimatingState); - - timeline.stop(); - timeline.setDuration(250); - timeline.setFrameRange(animatedOperation.top, animatedOperation.top + animatedOperation.duration); - timeline.start(); -} - -void QTreeViewPrivate::_q_endAnimatedOperation() -{ - Q_Q(QTreeView); - animatedOperation.before = QPixmap(); - animatedOperation.after = QPixmap(); - q->setState(QAbstractItemView::NoState); - q->updateGeometries(); - viewport->update(); -} - -void QTreeViewPrivate::_q_animate() -{ - QRect rect = viewport->rect(); - rect.moveTop(animatedOperation.top); - viewport->repaint(rect); + animatedOperation.start(); //let's start the animation } void QTreeViewPrivate::drawAnimatedOperation(QPainter *painter) const { - int start = timeline.startFrame(); - int end = timeline.endFrame(); - bool collapsing = animatedOperation.type == AnimatedOperation::Collapse; - int current = collapsing ? end - timeline.currentFrame() + start : timeline.currentFrame(); + const int start = animatedOperation.startValue().toInt(), + end = animatedOperation.endValue().toInt(), + current = animatedOperation.currentValue().toInt(); + bool collapsing = animatedOperation.direction() == QVariantAnimation::Backward; const QPixmap top = collapsing ? animatedOperation.before : animatedOperation.after; painter->drawPixmap(0, start, top, 0, end - current - 1, top.width(), top.height()); const QPixmap bottom = collapsing ? animatedOperation.after : animatedOperation.before; @@ -3038,6 +3025,7 @@ QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) cons return pixmap; } +#endif //QT_NO_ANIMATION void QTreeViewPrivate::_q_currentChanged(const QModelIndex ¤t, const QModelIndex &previous) { diff --git a/src/gui/itemviews/qtreeview.h b/src/gui/itemviews/qtreeview.h index 0347645..34f7630 100644 --- a/src/gui/itemviews/qtreeview.h +++ b/src/gui/itemviews/qtreeview.h @@ -223,8 +223,6 @@ private: Q_DECLARE_PRIVATE(QTreeView) Q_DISABLE_COPY(QTreeView) - Q_PRIVATE_SLOT(d_func(), void _q_endAnimatedOperation()) - Q_PRIVATE_SLOT(d_func(), void _q_animate()) Q_PRIVATE_SLOT(d_func(), void _q_currentChanged(const QModelIndex&, const QModelIndex &)) Q_PRIVATE_SLOT(d_func(), void _q_modelAboutToBeReset()) Q_PRIVATE_SLOT(d_func(), void _q_sortIndicatorChanged(int column, Qt::SortOrder order)) diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h index 6a1dfe5..77e57d6 100644 --- a/src/gui/itemviews/qtreeview_p.h +++ b/src/gui/itemviews/qtreeview_p.h @@ -54,6 +54,7 @@ // #include "private/qabstractitemview_p.h" +#include #ifndef QT_NO_TREEVIEW @@ -81,42 +82,48 @@ public: uniformRowHeights(false), rootDecoration(true), itemsExpandable(true), sortingEnabled(false), expandsOnDoubleClick(true), - allColumnsShowFocus(false), + allColumnsShowFocus(false), current(0), animationsEnabled(false), columnResizeTimerID(0), autoExpandDelay(-1), hoverBranch(-1), geometryRecursionBlock(false) {} ~QTreeViewPrivate() {} void initialize(); - struct AnimatedOperation +#ifndef QT_NO_ANIMATION + struct AnimatedOperation : public QVariantAnimation { - enum Type { Expand, Collapse }; int item; - int top; - int duration; - Type type; QPixmap before; QPixmap after; - }; - - void expand(int item, bool emitSignal); - void collapse(int item, bool emitSignal); - - void prepareAnimatedOperation(int item, AnimatedOperation::Type type); + QTreeView *view; + AnimatedOperation() : item(0) { setEasingCurve(QEasingCurve::InOutQuad); } + int top() const { return startValue().toInt(); } + QRect rect() const { QRect rect = view->viewport()->rect(); rect.moveTop(top()); return rect; } + void updateCurrentValue(const QVariant &) { view->viewport()->update(rect()); } + void updateState(State, State state) + { + if (state == Stopped) { + before = after = QPixmap(); + view->setState(QAbstractItemView::NoState); + view->updateGeometries(); + view->viewport()->update(); + } + } + } animatedOperation; + void prepareAnimatedOperation(int item, QVariantAnimation::Direction d); void beginAnimatedOperation(); - void _q_endAnimatedOperation(); void drawAnimatedOperation(QPainter *painter) const; QPixmap renderTreeToPixmapForAnimation(const QRect &rect) const; +#endif //QT_NO_ANIMATION + + void expand(int item, bool emitSignal); + void collapse(int item, bool emitSignal); - inline QRect animationRect() const - { return QRect(0, animatedOperation.top, viewport->width(), - viewport->height() - animatedOperation.top); } void _q_currentChanged(const QModelIndex&, const QModelIndex&); void _q_columnsAboutToBeRemoved(const QModelIndex &, int, int); void _q_columnsRemoved(const QModelIndex &, int, int); void _q_modelAboutToBeReset(); - void _q_animate(); void _q_sortIndicatorChanged(int column, Qt::SortOrder order); void _q_modelDestroyed(); @@ -177,8 +184,6 @@ public: // used when expanding and collapsing items QSet expandedIndexes; - QStack expandParent; - AnimatedOperation animatedOperation; bool animationsEnabled; inline bool storeExpanded(const QPersistentModelIndex &idx) { -- cgit v0.12 From 17cd046cfd7ab8ff3eaf0c09ae083ff8b2c89c89 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 9 Jul 2009 13:45:35 +0200 Subject: QTreeView: cleanup of useless private slots currentChange is slot in the public class (QAbstractItemView --- src/gui/dialogs/qfiledialog_p.h | 1 - src/gui/itemviews/qtreeview.cpp | 63 +++++++++++++---------------------------- src/gui/itemviews/qtreeview.h | 2 -- src/gui/itemviews/qtreeview_p.h | 2 -- 4 files changed, 20 insertions(+), 48 deletions(-) diff --git a/src/gui/dialogs/qfiledialog_p.h b/src/gui/dialogs/qfiledialog_p.h index d798f9d..4c599cc 100644 --- a/src/gui/dialogs/qfiledialog_p.h +++ b/src/gui/dialogs/qfiledialog_p.h @@ -73,7 +73,6 @@ #include #include #include -#include #include #include "qsidebar_p.h" diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index ab700e9..e4c7cd3 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -262,10 +262,6 @@ void QTreeView::setSelectionModel(QItemSelectionModel *selectionModel) Q_D(QTreeView); Q_ASSERT(selectionModel); if (d->selectionModel) { - if (d->allColumnsShowFocus) { - QObject::disconnect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)), - this, SLOT(_q_currentChanged(QModelIndex,QModelIndex))); - } // support row editing disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)), d->model, SLOT(submit())); @@ -275,10 +271,6 @@ void QTreeView::setSelectionModel(QItemSelectionModel *selectionModel) QAbstractItemView::setSelectionModel(selectionModel); if (d->selectionModel) { - if (d->allColumnsShowFocus) { - QObject::connect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)), - this, SLOT(_q_currentChanged(QModelIndex,QModelIndex))); - } // support row editing connect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)), d->model, SLOT(submit())); @@ -901,15 +893,6 @@ void QTreeView::setAllColumnsShowFocus(bool enable) Q_D(QTreeView); if (d->allColumnsShowFocus == enable) return; - if (d->selectionModel) { - if (enable) { - QObject::connect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)), - this, SLOT(_q_currentChanged(QModelIndex,QModelIndex))); - } else { - QObject::disconnect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)), - this, SLOT(_q_currentChanged(QModelIndex,QModelIndex))); - } - } d->allColumnsShowFocus = enable; d->viewport->update(); } @@ -1309,13 +1292,13 @@ bool QTreeViewPrivate::expandOrCollapseItemAtPos(const QPoint &pos) { Q_Q(QTreeView); // we want to handle mousePress in EditingState (persistent editors) - if ((q->state() != QAbstractItemView::NoState - && q->state() != QAbstractItemView::EditingState) + if ((state != QAbstractItemView::NoState + && state != QAbstractItemView::EditingState) || !viewport->rect().contains(pos)) return true; int i = itemDecorationAt(pos); - if ((i != -1) && q->itemsExpandable() && hasVisibleChildren(viewItems.at(i).index)) { + if ((i != -1) && itemsExpandable && hasVisibleChildren(viewItems.at(i).index)) { if (viewItems.at(i).expanded) collapse(i, true); else @@ -2867,7 +2850,7 @@ void QTreeViewPrivate::expand(int item, bool emitSignal) if (emitSignal && animationsEnabled) prepareAnimatedOperation(item, QVariantAnimation::Forward); #endif //QT_NO_ANIMATION - QAbstractItemView::State oldState = q->state(); + QAbstractItemView::State oldState = state; q->setState(QAbstractItemView::ExpandingState); const QModelIndex index = viewItems.at(item).index; storeExpanded(index); @@ -2909,7 +2892,7 @@ void QTreeViewPrivate::collapse(int item, bool emitSignal) prepareAnimatedOperation(item, QVariantAnimation::Backward); #endif //QT_NO_ANIMATION - QAbstractItemView::State oldState = q->state(); + QAbstractItemView::State oldState = state; q->setState(QAbstractItemView::CollapsingState); expandedIndexes.erase(it); viewItems[item].expanded = false; @@ -3027,27 +3010,6 @@ QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) cons } #endif //QT_NO_ANIMATION -void QTreeViewPrivate::_q_currentChanged(const QModelIndex ¤t, const QModelIndex &previous) -{ - Q_Q(QTreeView); - if (previous.isValid()) { - QRect previousRect = q->visualRect(previous); - if (allColumnsShowFocus) { - previousRect.setX(0); - previousRect.setWidth(viewport->width()); - } - viewport->update(previousRect); - } - if (current.isValid()) { - QRect currentRect = q->visualRect(current); - if (allColumnsShowFocus) { - currentRect.setX(0); - currentRect.setWidth(viewport->width()); - } - viewport->update(currentRect); - } -} - void QTreeViewPrivate::_q_modelAboutToBeReset() { viewItems.clear(); @@ -3775,6 +3737,21 @@ void QTreeView::currentChanged(const QModelIndex ¤t, const QModelIndex &pr } #endif QAbstractItemView::currentChanged(current, previous); + + if (allColumnsShowFocus()) { + if (previous.isValid()) { + QRect previousRect = visualRect(previous); + previousRect.setX(0); + previousRect.setWidth(viewport()->width()); + viewport()->update(previousRect); + } + if (current.isValid()) { + QRect currentRect = visualRect(current); + currentRect.setX(0); + currentRect.setWidth(viewport()->width()); + viewport()->update(currentRect); + } + } } /*! diff --git a/src/gui/itemviews/qtreeview.h b/src/gui/itemviews/qtreeview.h index 34f7630..b2a9de2f 100644 --- a/src/gui/itemviews/qtreeview.h +++ b/src/gui/itemviews/qtreeview.h @@ -223,10 +223,8 @@ private: Q_DECLARE_PRIVATE(QTreeView) Q_DISABLE_COPY(QTreeView) - Q_PRIVATE_SLOT(d_func(), void _q_currentChanged(const QModelIndex&, const QModelIndex &)) Q_PRIVATE_SLOT(d_func(), void _q_modelAboutToBeReset()) Q_PRIVATE_SLOT(d_func(), void _q_sortIndicatorChanged(int column, Qt::SortOrder order)) - Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed()) }; #endif // QT_NO_TREEVIEW diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h index 77e57d6..38f6fd3 100644 --- a/src/gui/itemviews/qtreeview_p.h +++ b/src/gui/itemviews/qtreeview_p.h @@ -119,8 +119,6 @@ public: void expand(int item, bool emitSignal); void collapse(int item, bool emitSignal); - - void _q_currentChanged(const QModelIndex&, const QModelIndex&); void _q_columnsAboutToBeRemoved(const QModelIndex &, int, int); void _q_columnsRemoved(const QModelIndex &, int, int); void _q_modelAboutToBeReset(); -- cgit v0.12 From 8b5f25ef98d29859e14d992ed90d976e64dc6382 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 9 Jul 2009 15:23:58 +0200 Subject: autotest: removed tons of warnings --- tests/auto/qmenubar/tst_qmenubar.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/auto/qmenubar/tst_qmenubar.cpp b/tests/auto/qmenubar/tst_qmenubar.cpp index 500465c..1245de1 100644 --- a/tests/auto/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/qmenubar/tst_qmenubar.cpp @@ -1576,8 +1576,9 @@ void tst_QMenuBar::menubarSizeHint() return 11; case PM_MenuBarPanelWidth: return 1; + default: + return QWindowsStyle::pixelMetric(metric, option, widget); } - return QWindowsStyle::pixelMetric(metric, option, widget); } } style; -- cgit v0.12 From 43760604b1e08792938449885a938a641669c11d Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Thu, 9 Jul 2009 14:20:54 +0200 Subject: Added some links to the appropriate functions to the doc. Reviewed-by: trustme --- doc/src/dnd.qdoc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/doc/src/dnd.qdoc b/doc/src/dnd.qdoc index b5039f6..5ede20c 100644 --- a/doc/src/dnd.qdoc +++ b/doc/src/dnd.qdoc @@ -141,15 +141,17 @@ types of data that the widget accepts. You must reimplement this function if you want to receive either QDragMoveEvent or QDropEvent in your reimplementations of - \l{QWidget::dragMoveEvent()}{dragMoveEvent()} and dropEvent(). + \l{QWidget::dragMoveEvent()}{dragMoveEvent()} and + \l{QWidget::dropEvent()}{dropEvent()}. - The following code shows how dragEnterEvent() can be reimplemented to + The following code shows how \l{QWidget::dragEnterEvent()}{dragEnterEvent()} + can be reimplemented to tell the drag and drop system that we can only handle plain text: \snippet doc/src/snippets/dropevents/window.cpp 3 - The dropEvent() is used to unpack dropped data and handle it in way that - is suitable for your application. + The \l{QWidget::dropEvent()}{dropEvent()} is used to unpack dropped data + and handle it in way that is suitable for your application. In the following code, the text supplied in the event is passed to a QTextBrowser and a QComboBox is filled with the list of MIME types that @@ -159,7 +161,8 @@ In this case, we accept the proposed action without checking what it is. In a real world application, it may be necessary to return from the - dropEvent() function without accepting the proposed action or handling + \l{QWidget::dropEvent()}{dropEvent()} function without accepting the + proposed action or handling the data if the action is not relevant. For example, we may choose to ignore Qt::LinkAction actions if we do not support links to external sources in our application. -- cgit v0.12 From b89e878003c5732482a8afb1be66a42cb9122b9e Mon Sep 17 00:00:00 2001 From: Pierre Rossi Date: Thu, 9 Jul 2009 16:12:49 +0200 Subject: Updated the french phrasebook (some translations from Qt Creator) Reviewed-by: TrustMe --- tools/linguist/phrasebooks/french.qph | 227 +++++++++++++++++++++++++++++++++- 1 file changed, 226 insertions(+), 1 deletion(-) diff --git a/tools/linguist/phrasebooks/french.qph b/tools/linguist/phrasebooks/french.qph index f244013..d38da5a 100644 --- a/tools/linguist/phrasebooks/french.qph +++ b/tools/linguist/phrasebooks/french.qph @@ -1,4 +1,5 @@ - + + About A propos @@ -1101,4 +1102,228 @@ Yes Oui + + Split + Scinder + + + &Edit + &Édition + + + &Redo + Re&faire + + + debugger + débogueur + + + Start Debugger + Lancer le débogueur + + + Executable: + Exécutable: + + + Filter: + Filtre: + + + Clear + Effacer + + + Host and port: + Hôte et port: + + + Architecture: + Architecture: + + + Server start script: + Script de démarrage du serveur: + + + &Undo + Annu&ler + + + Add Bookmark + Ajouter un signet + + + Bookmark: + Signet: + + + Add in Folder: + Ajouter dans le dossier: + + + + + + + + + New Folder + Nouveau dossier + + + Bookmarks + Signets + + + Rename Folder + Renommer le dossier + + + Bookmark + Signet + + + Remove + Retirer + + + Delete Folder + Supprimer le dossier + + + Add + Ajouter + + + Move Up + Vers le Haut + + + Move Down + Vers le Bas + + + Show Bookmark + Afficher le signet + + + Show Bookmark in New Tab + Afficher le signet dans un nouvel onglet + + + Delete Bookmark + Supprimer le signet + + + Rename Bookmark + Renommer le signet + + + Previous Bookmark + Signet précédent + + + Next Bookmark + Signet suivant + + + Condition: + Condition: + + + Working Directory: + Répertoire de travail: + + + Environment + Environnement + + + Arguments + Arguments + + + Build directory: + Répertoire de compilation: + + + Path: + Chemin: + + + General + Général + + + Username: + Nom d'utilisateur: + + + User interface + Interface utilisateur + + + Open Link + Ouvrir le lien + + + [read only] + [lecture seule] + + + [directory] + [répertoire] + + + Close All + Fermer tout + + + Failed! + Échec! + + + Proceed + Continuer + + + Make writable + Rendre inscriptible + + + Qt Creator + Qt Creator + + + &File + &Fichier + + + Activate %1 + Activer %1 + + + New Project + Nouveau projet + + + Close %1 + Fermer %1 + + + * + * + + + &Change + &Modifier + + + Close Other Editors + Fermer les autres éditeurs + + + Close All Except %1 + Fermer tout sauf %1 + -- cgit v0.12 From e96c108e7f71f3e1bd08dc739e6ec46fe4603332 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 9 Jul 2009 15:58:20 +0200 Subject: QTabBar: now uses QVariantAnimation over QTimeLine QTimeLine is now no more used in private APIs --- src/gui/widgets/qprogressbar.cpp | 2 +- src/gui/widgets/qtabbar.cpp | 66 ++++++++++++++------------------------ src/gui/widgets/qtabbar.h | 2 -- src/gui/widgets/qtabbar_p.h | 68 ++++++++++++++++++++++++---------------- 4 files changed, 65 insertions(+), 73 deletions(-) diff --git a/src/gui/widgets/qprogressbar.cpp b/src/gui/widgets/qprogressbar.cpp index ac3338b..d168028 100644 --- a/src/gui/widgets/qprogressbar.cpp +++ b/src/gui/widgets/qprogressbar.cpp @@ -204,7 +204,7 @@ bool QProgressBarPrivate::repaintRequired() const \o A progress bar shown in the Plastique widget style. \endtable - \sa QTimeLine, QProgressDialog, {fowler}{GUI Design Handbook: Progress Indicator} + \sa QProgressDialog, {fowler}{GUI Design Handbook: Progress Indicator} */ /*! diff --git a/src/gui/widgets/qtabbar.cpp b/src/gui/widgets/qtabbar.cpp index 11cb6a1..690e624 100644 --- a/src/gui/widgets/qtabbar.cpp +++ b/src/gui/widgets/qtabbar.cpp @@ -663,7 +663,7 @@ void QTabBarPrivate::refresh() if (pressedIndex != -1 && movable && QApplication::mouseButtons() == Qt::NoButton) { - _q_moveTabFinished(pressedIndex); + moveTabFinished(pressedIndex); if (!validIndex(pressedIndex)) pressedIndex = -1; } @@ -1662,26 +1662,17 @@ void QTabBarPrivate::slide(int from, int to) q->setUpdatesEnabled(true); int postLocation = vertical ? q->tabRect(to).y() : q->tabRect(to).x(); int length = postLocation - preLocation; - tabList[to].makeTimeLine(q); - tabList[to].dragOffset += -1 * length; - tabList[to].timeLine->setFrameRange(tabList[to].dragOffset, 0); - animations[tabList[to].timeLine] = to; - tabList[to].timeLine->setDuration(ANIMATION_DURATION); - if (tabList[to].timeLine->state() != QTimeLine::Running) - tabList[to].timeLine->start(); + tabList[to].dragOffset -= length; + tabList[to].startAnimation(this, ANIMATION_DURATION); } -void QTabBarPrivate::_q_moveTab(int offset) +void QTabBarPrivate::moveTab(int index, int offset) { - Q_Q(QTabBar); - if (QTimeLine *timeLine = qobject_cast(q->sender())) { - int index = animations[timeLine]; - if (!validIndex(index)) - return; - tabList[index].dragOffset = offset; - layoutTab(index); // Make buttons follow tab - q->update(); - } + if (!validIndex(index)) + return; + tabList[index].dragOffset = offset; + layoutTab(index); // Make buttons follow tab + q_func()->update(); } /*!\reimp @@ -1695,7 +1686,7 @@ void QTabBar::mousePressEvent(QMouseEvent *event) } // Be safe! if (d->pressedIndex != -1 && d->movable) - d->_q_moveTabFinished(d->pressedIndex); + d->moveTabFinished(d->pressedIndex); d->pressedIndex = d->indexAtPos(event->pos()); if (d->validIndex(d->pressedIndex)) { @@ -1721,7 +1712,7 @@ void QTabBar::mouseMoveEvent(QMouseEvent *event) // Be safe! if (d->pressedIndex != -1 && event->buttons() == Qt::NoButton) - d->_q_moveTabFinished(d->pressedIndex); + d->moveTabFinished(d->pressedIndex); // Start drag if (!d->dragInProgress && d->pressedIndex != -1) { @@ -1789,16 +1780,6 @@ void QTabBar::mouseMoveEvent(QMouseEvent *event) optTabBase.documentMode = d->documentMode; } -void QTabBarPrivate::_q_moveTabFinished() -{ - Q_Q(QTabBar); - if (QTimeLine *timeLine = qobject_cast(q->sender())) { - int index = animations[timeLine]; - animations.remove(timeLine); - _q_moveTabFinished(index); - } -} - void QTabBarPrivate::setupMovableTab() { Q_Q(QTabBar); @@ -1838,11 +1819,19 @@ void QTabBarPrivate::setupMovableTab() movingTab->setVisible(true); } -void QTabBarPrivate::_q_moveTabFinished(int index) +void QTabBarPrivate::moveTabFinished(int index) { Q_Q(QTabBar); bool cleanup = (pressedIndex == index) || (pressedIndex == -1) || !validIndex(index); - if (animations.isEmpty() && cleanup) { + bool allAnimationsFinished = true; +#ifndef QT_NO_ANIMATION + for(int i = 0; allAnimationsFinished && i < tabList.count(); ++i) { + const Tab &t = tabList.at(i); + if (t.animation && t.animation->state() == QAbstractAnimation::Running) + allAnimationsFinished = false; + } +#endif //QT_NO_ANIMATION + if (allAnimationsFinished && cleanup) { movingTab->setVisible(false); // We might not get a mouse release for (int i = 0; i < tabList.count(); ++i) { tabList[i].dragOffset = 0; @@ -1877,17 +1866,8 @@ void QTabBar::mouseReleaseEvent(QMouseEvent *event) ? tabRect(d->pressedIndex).height() : tabRect(d->pressedIndex).width(); int duration = qMin(ANIMATION_DURATION, - ((length < 0 ? (-1 * length) : length) * ANIMATION_DURATION) / width); - if (duration > 0) { - d->tabList[d->pressedIndex].makeTimeLine(this); - d->tabList[d->pressedIndex].timeLine->setFrameRange(length, 0); - d->animations[d->tabList[d->pressedIndex].timeLine] = d->pressedIndex; - d->tabList[d->pressedIndex].timeLine->setDuration(duration); - if (d->tabList[d->pressedIndex].timeLine->state() != QTimeLine::Running) - d->tabList[d->pressedIndex].timeLine->start(); - } else { - d->_q_moveTabFinished(d->pressedIndex); - } + (qAbs(length) * ANIMATION_DURATION) / width); + d->tabList[d->pressedIndex].startAnimation(d, duration); d->dragInProgress = false; d->movingTab->setVisible(false); d->dragStartPosition = QPoint(); diff --git a/src/gui/widgets/qtabbar.h b/src/gui/widgets/qtabbar.h index 7514486..402f54b 100644 --- a/src/gui/widgets/qtabbar.h +++ b/src/gui/widgets/qtabbar.h @@ -215,8 +215,6 @@ private: Q_DECLARE_PRIVATE(QTabBar) Q_PRIVATE_SLOT(d_func(), void _q_scrollTabs()) Q_PRIVATE_SLOT(d_func(), void _q_closeTab()) - Q_PRIVATE_SLOT(d_func(), void _q_moveTab(int)) - Q_PRIVATE_SLOT(d_func(), void _q_moveTabFinished()) }; #endif // QT_NO_TABBAR diff --git a/src/gui/widgets/qtabbar_p.h b/src/gui/widgets/qtabbar_p.h index dbae055..b9b9fba 100644 --- a/src/gui/widgets/qtabbar_p.h +++ b/src/gui/widgets/qtabbar_p.h @@ -58,9 +58,8 @@ #include #include -#include -#include #include +#include #ifndef QT_NO_TABBAR @@ -75,9 +74,10 @@ class QTabBarPrivate : public QWidgetPrivate Q_DECLARE_PUBLIC(QTabBar) public: QTabBarPrivate() - :currentIndex(-1), pressedIndex(-1), - shape(QTabBar::RoundedNorth), - layoutDirty(false), drawBase(true), scrollOffset(0), expanding(true), closeButtonOnTabs(false), selectionBehaviorOnRemove(QTabBar::SelectRightTab), paintWithOffsets(true), movable(false), dragInProgress(false), documentMode(false), movingTab(0) {} + :currentIndex(-1), pressedIndex(-1), shape(QTabBar::RoundedNorth), layoutDirty(false), + drawBase(true), scrollOffset(0), expanding(true), closeButtonOnTabs(false), + selectionBehaviorOnRemove(QTabBar::SelectRightTab), paintWithOffsets(true), movable(false), + dragInProgress(false), documentMode(false), movingTab(0) {} int currentIndex; int pressedIndex; @@ -88,16 +88,13 @@ public: struct Tab { inline Tab(const QIcon &ico, const QString &txt) - : enabled(true) - , shortcutId(0) - , text(txt) - , icon(ico) - , leftWidget(0) - , rightWidget(0) - , lastTab(-1) - , timeLine(0) - , dragOffset(0) + : enabled(true) , shortcutId(0), text(txt), icon(ico), + leftWidget(0), rightWidget(0), lastTab(-1), dragOffset(0) +#ifndef QT_NO_ANIMATION + , animation(0) +#endif //QT_NO_ANIMATION {} + bool operator==(const Tab &other) const { return &other == this; } bool enabled; int shortcutId; QString text; @@ -117,21 +114,39 @@ public: QWidget *leftWidget; QWidget *rightWidget; int lastTab; - - QTimeLine *timeLine; int dragOffset; - void makeTimeLine(QWidget *q) { - if (timeLine) - return; - timeLine = new QTimeLine(ANIMATION_DURATION, q); - q->connect(timeLine, SIGNAL(frameChanged(int)), q, SLOT(_q_moveTab(int))); - q->connect(timeLine, SIGNAL(finished()), q, SLOT(_q_moveTabFinished())); +#ifndef QT_NO_ANIMATION + ~Tab() { delete animation; } + struct TabBarAnimation : public QVariantAnimation { + TabBarAnimation(Tab *t, QTabBarPrivate *_priv) : tab(t), priv(_priv) + { setEasingCurve(QEasingCurve::InOutQuad); } + + void updateCurrentValue(const QVariant ¤t) + { priv->moveTab(priv->tabList.indexOf(*tab), current.toInt()); } + + void updateState(State, State newState) + { if (newState == Stopped) priv->moveTabFinished(priv->tabList.indexOf(*tab)); } + private: + //these are needed for the callbacks + Tab *tab; + QTabBarPrivate *priv; + } *animation; + + void startAnimation(QTabBarPrivate *priv, int duration) { + if (!animation) + animation = new TabBarAnimation(this, priv); + animation->setStartValue(dragOffset); + animation->setEndValue(0); + animation->setDuration(duration); + animation->start(); } - +#else + void startAnimation(QTabBarPrivate *priv, int duration) + { Q_UNUSED(duration); priv->moveTabFinished(priv->tabList.indexOf(*this)); } +#endif //QT_NO_ANIMATION }; QList tabList; - QHash animations; int calculateNewPosition(int from, int to, int index) const; void slide(int from, int to); @@ -152,9 +167,8 @@ public: void _q_scrollTabs(); void _q_closeTab(); - void _q_moveTab(int); - void _q_moveTabFinished(); - void _q_moveTabFinished(int offset); + void moveTab(int index, int offset); + void moveTabFinished(int index); QRect hoverRect; void refresh(); -- cgit v0.12 From 93c5eddcead6d0fa9601d3ec992086ddcc5656e9 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 9 Jul 2009 16:23:26 +0200 Subject: Fix compile issue --- src/gui/itemviews/qtreeview.cpp | 13 ++++++++++++- src/gui/itemviews/qtreeview.h | 3 +++ src/gui/itemviews/qtreeview_p.h | 17 +++++------------ 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index e4c7cd3..f13ff0c 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -2837,6 +2837,9 @@ void QTreeViewPrivate::initialize() header->setStretchLastSection(true); header->setDefaultAlignment(Qt::AlignLeft|Qt::AlignVCenter); q->setHeader(header); +#ifndef QT_NO_ANIMATION + QObject::connect(&animatedOperation, SIGNAL(finished()), q, SLOT(_q_endAnimatedOperation())); +#endif //QT_NO_ANIMATION } void QTreeViewPrivate::expand(int item, bool emitSignal) @@ -2920,7 +2923,7 @@ void QTreeViewPrivate::collapse(int item, bool emitSignal) void QTreeViewPrivate::prepareAnimatedOperation(int item, QVariantAnimation::Direction direction) { animatedOperation.item = item; - animatedOperation.view = q_func(); + animatedOperation.viewport = viewport; animatedOperation.setDirection(direction); int top = coordinateForItem(item) + itemHeight(item); @@ -3008,6 +3011,14 @@ QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) cons return pixmap; } + +void QTreeViewPrivate::_q_endAnimatedOperation() +{ + Q_Q(QTreeView); + q->setState(QAbstractItemView::NoState); + q->updateGeometries(); + viewport->update(); +} #endif //QT_NO_ANIMATION void QTreeViewPrivate::_q_modelAboutToBeReset() diff --git a/src/gui/itemviews/qtreeview.h b/src/gui/itemviews/qtreeview.h index b2a9de2f..4411781 100644 --- a/src/gui/itemviews/qtreeview.h +++ b/src/gui/itemviews/qtreeview.h @@ -223,6 +223,9 @@ private: Q_DECLARE_PRIVATE(QTreeView) Q_DISABLE_COPY(QTreeView) +#ifndef QT_NO_ANIMATION + Q_PRIVATE_SLOT(d_func(), void _q_endAnimatedOperation()) +#endif //QT_NO_ANIMATION Q_PRIVATE_SLOT(d_func(), void _q_modelAboutToBeReset()) Q_PRIVATE_SLOT(d_func(), void _q_sortIndicatorChanged(int column, Qt::SortOrder order)) }; diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h index 38f6fd3..6fb2e41 100644 --- a/src/gui/itemviews/qtreeview_p.h +++ b/src/gui/itemviews/qtreeview_p.h @@ -95,25 +95,18 @@ public: int item; QPixmap before; QPixmap after; - QTreeView *view; + QWidget *viewport; AnimatedOperation() : item(0) { setEasingCurve(QEasingCurve::InOutQuad); } int top() const { return startValue().toInt(); } - QRect rect() const { QRect rect = view->viewport()->rect(); rect.moveTop(top()); return rect; } - void updateCurrentValue(const QVariant &) { view->viewport()->update(rect()); } - void updateState(State, State state) - { - if (state == Stopped) { - before = after = QPixmap(); - view->setState(QAbstractItemView::NoState); - view->updateGeometries(); - view->viewport()->update(); - } - } + QRect rect() const { QRect rect = viewport->rect(); rect.moveTop(top()); return rect; } + void updateCurrentValue(const QVariant &) { viewport->update(rect()); } + void updateState(State, State state) { if (state == Stopped) before = after = QPixmap(); } } animatedOperation; void prepareAnimatedOperation(int item, QVariantAnimation::Direction d); void beginAnimatedOperation(); void drawAnimatedOperation(QPainter *painter) const; QPixmap renderTreeToPixmapForAnimation(const QRect &rect) const; + void _q_endAnimatedOperation(); #endif //QT_NO_ANIMATION void expand(int item, bool emitSignal); -- cgit v0.12 From f4fb6207a91b62526b31e0f77c0713bdc243e4f2 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Thu, 9 Jul 2009 16:51:59 +0200 Subject: Compile fix. --- src/gui/itemviews/qabstractitemview_p.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index 3119c9d..00647f6 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -64,6 +64,7 @@ #include "QtGui/qregion.h" #include "QtCore/qdebug.h" #include "QtGui/qpainter.h" +#include "QtCore/qbasictimer.h" #ifndef QT_NO_ITEMVIEWS -- cgit v0.12 From 4bec76fceb2297cdbde765b74075046b94bfaf75 Mon Sep 17 00:00:00 2001 From: Nils Christian Roscher-Nielsen Date: Thu, 9 Jul 2009 17:29:46 +0200 Subject: Add the complex control SC_SpinBoxEditField to style option Reviewed-by: Thierry --- src/gui/widgets/qabstractspinbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/widgets/qabstractspinbox.cpp b/src/gui/widgets/qabstractspinbox.cpp index da18d13..433406c 100644 --- a/src/gui/widgets/qabstractspinbox.cpp +++ b/src/gui/widgets/qabstractspinbox.cpp @@ -1577,7 +1577,7 @@ void QAbstractSpinBox::initStyleOption(QStyleOptionSpinBox *option) const option->initFrom(this); option->activeSubControls = QStyle::SC_None; option->buttonSymbols = d->buttonSymbols; - option->subControls = QStyle::SC_SpinBoxFrame; + option->subControls = QStyle::SC_SpinBoxFrame | QStyle::SC_SpinBoxEditField; if (d->buttonSymbols != QAbstractSpinBox::NoButtons) { option->subControls |= QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown; if (d->buttonState & Up) { -- cgit v0.12 From 020ed5b7caaba5cf877cdb9ebaa575db1d15b7f0 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 9 Jul 2009 18:09:12 +0200 Subject: QLocalSocket WriteOnly mode fixed on Windows Write only local sockets silently disconnected after some time. Reason: we cannot call PeekNamedPipe on a write only pipe. Task-number: 257714 Reviewed-by: ossi Autotest: tst_QLocalSocket::writeOnlySocket --- src/network/socket/qlocalsocket_win.cpp | 10 ++++++---- tests/auto/qlocalsocket/tst_qlocalsocket.cpp | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index 1a971f0..794b2b7 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -168,7 +168,7 @@ void QLocalSocket::connectToServer(const QString &name, OpenMode openMode) // we have a valid handle d->serverName = name; - if (setSocketDescriptor((quintptr)localSocket), openMode) { + if (setSocketDescriptor((quintptr)localSocket, ConnectedState, openMode)) { d->handle = localSocket; emit connected(); } @@ -299,8 +299,6 @@ void QLocalSocket::abort() DWORD QLocalSocketPrivate::bytesAvailable() { Q_Q(QLocalSocket); - if (q->state() != QLocalSocket::ConnectedState) - return 0; DWORD bytes; if (PeekNamedPipe(handle, NULL, 0, NULL, &bytes, NULL)) { return bytes; @@ -410,7 +408,7 @@ bool QLocalSocket::setSocketDescriptor(quintptr socketDescriptor, d->handle = (int*)socketDescriptor; d->state = socketState; emit stateChanged(d->state); - if (d->state == ConnectedState) { + if (d->state == ConnectedState && openMode.testFlag(QIODevice::ReadOnly)) { d->startAsyncRead(); d->checkReadyRead(); } @@ -471,6 +469,10 @@ bool QLocalSocket::waitForDisconnected(int msecs) Q_D(QLocalSocket); if (state() == UnconnectedState) return false; + if (!openMode().testFlag(QIODevice::ReadOnly)) { + qWarning("QLocalSocket::waitForDisconnected isn't supported for write only pipes."); + return false; + } QIncrementalSleepTimer timer(msecs); forever { d->bytesAvailable(); // to check if PeekNamedPipe fails diff --git a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp index 0f636a4..a41eecd 100644 --- a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp @@ -104,6 +104,7 @@ private slots: void recycleServer(); void multiConnect(); + void writeOnlySocket(); void debug(); @@ -906,6 +907,22 @@ void tst_QLocalSocket::multiConnect() QVERIFY(server.nextPendingConnection() != 0); } +void tst_QLocalSocket::writeOnlySocket() +{ + QLocalServer server; + QVERIFY(server.listen("writeOnlySocket")); + + QLocalSocket client; + client.connectToServer("writeOnlySocket", QIODevice::WriteOnly); + QVERIFY(client.waitForConnected()); + + QVERIFY(server.waitForNewConnection()); + QLocalSocket* serverSocket = server.nextPendingConnection(); + + QCOMPARE(client.bytesAvailable(), qint64(0)); + QCOMPARE(client.state(), QLocalSocket::ConnectedState); +} + void tst_QLocalSocket::debug() { // Make sure this compiles -- cgit v0.12 From 5c11a5a38bcc68c17da8fe59e8db03d43ea55ac1 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Wed, 8 Jul 2009 17:21:51 +0200 Subject: Ensure that when we hide QToolBar in unified, unified follows. Basically if you would hide a toolbar in the unified toolbar, you would still see a little bit of area at the top instead of having everything flush with the titlebar. This change basically unsures that the unified toolbar makes a decision to hide itself if all the toolbars inside it are hidden. It makes the behavior of clicking on the toolbar button behave more or less correctly since we are going to show the unified toolbar whether we want to or not. This all will get the toolbar button switch event to be dispatched in Cocoa as well. Also add an optimization for checking if we need to change the geometry. If we don't have any items the other toolbar areas, we can skip the set geometry call, which wrecks havoc with things in Cocoa. We still don't solve the case of someone who has hidden the items with the toolbar button then goes full-screen, then goes back out. I'm not motivated to solve it as is because we need to keep track of the hides we do on the button press vs. other hides from the user and still people can workaround it easy enough by handling window state change and doing what is recommended in the docs. Task-number: 208439 Rev-by: Denis --- src/gui/kernel/qcocoapanel_mac.mm | 6 +++ src/gui/kernel/qcocoawindow_mac.mm | 6 +++ src/gui/kernel/qt_cocoa_helpers_mac.mm | 34 +++++++------- src/gui/kernel/qt_cocoa_helpers_mac_p.h | 3 +- src/gui/kernel/qwidget_mac.mm | 3 +- src/gui/widgets/qmainwindow.cpp | 13 ++++-- src/gui/widgets/qmainwindowlayout.cpp | 76 ++++++++++++++++++++++++++++---- src/gui/widgets/qmainwindowlayout_mac.mm | 31 ++++++++++--- src/gui/widgets/qmainwindowlayout_p.h | 2 + src/gui/widgets/qtoolbar.cpp | 29 +++++++++--- 10 files changed, 161 insertions(+), 42 deletions(-) diff --git a/src/gui/kernel/qcocoapanel_mac.mm b/src/gui/kernel/qcocoapanel_mac.mm index bdc7ecb..1e0bbdf 100644 --- a/src/gui/kernel/qcocoapanel_mac.mm +++ b/src/gui/kernel/qcocoapanel_mac.mm @@ -85,6 +85,12 @@ QT_USE_NAMESPACE last resort (i.e., this is code that can potentially be removed). */ +- (void)toggleToolbarShown:(id)sender +{ + macSendToolbarChangeEvent([self QT_MANGLE_NAMESPACE(qt_qwidget)]); + [super toggleToolbarShown:sender]; +} + - (void)keyDown:(NSEvent *)theEvent { bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]); diff --git a/src/gui/kernel/qcocoawindow_mac.mm b/src/gui/kernel/qcocoawindow_mac.mm index 7084416..eb08982 100644 --- a/src/gui/kernel/qcocoawindow_mac.mm +++ b/src/gui/kernel/qcocoawindow_mac.mm @@ -104,6 +104,12 @@ QT_USE_NAMESPACE last resort (i.e., this is code that can potentially be removed). */ +- (void)toggleToolbarShown:(id)sender +{ + macSendToolbarChangeEvent([self QT_MANGLE_NAMESPACE(qt_qwidget)]); + [super toggleToolbarShown:sender]; +} + - (void)keyDown:(NSEvent *)theEvent { bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]); diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index 13b0e50..a98a7f8 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -177,11 +177,10 @@ void macWindowToolbarShow(const QWidget *widget, bool show ) { OSWindowRef wnd = qt_mac_window_for(widget); #if QT_MAC_USE_COCOA - NSToolbar *toolbar = [wnd toolbar]; - if (toolbar) { + if (NSToolbar *toolbar = [wnd toolbar]) { QMacCocoaAutoReleasePool pool; if (show != [toolbar isVisible]) { - [wnd toggleToolbarShown:wnd]; + [toolbar setVisible:show]; } else { // The toolbar may be in sync, but we are not, update our framestrut. qt_widget_private(const_cast(widget))->updateFrameStrut(); @@ -197,22 +196,21 @@ void macWindowToolbarSet( void * /*OSWindowRef*/ window, void *toolbarRef ) { OSWindowRef wnd = static_cast(window); #if QT_MAC_USE_COCOA - [wnd setToolbar:static_cast(toolbarRef)]; + [wnd setToolbar:static_cast(toolbarRef)]; #else SetWindowToolbar(wnd, static_cast(toolbarRef)); #endif } -bool macWindowToolbarVisible( void * /*OSWindowRef*/ window ) +bool macWindowToolbarIsVisible( void * /*OSWindowRef*/ window ) { OSWindowRef wnd = static_cast(window); #if QT_MAC_USE_COCOA - NSToolbar *toolbar = [wnd toolbar]; - if (toolbar) + if (NSToolbar *toolbar = [wnd toolbar]) return [toolbar isVisible]; return false; #else - return IsWindowToolbarVisible(wnd); + return IsWindowToolbarVisible(wnd); #endif } @@ -220,12 +218,12 @@ void macWindowSetHasShadow( void * /*OSWindowRef*/ window, bool hasShadow ) { OSWindowRef wnd = static_cast(window); #if QT_MAC_USE_COCOA - [wnd setHasShadow:BOOL(hasShadow)]; + [wnd setHasShadow:BOOL(hasShadow)]; #else - if (hasShadow) - ChangeWindowAttributes(wnd, 0, kWindowNoShadowAttribute); - else - ChangeWindowAttributes(wnd, kWindowNoShadowAttribute, 0); + if (hasShadow) + ChangeWindowAttributes(wnd, 0, kWindowNoShadowAttribute); + else + ChangeWindowAttributes(wnd, kWindowNoShadowAttribute, 0); #endif } @@ -233,9 +231,9 @@ void macWindowFlush(void * /*OSWindowRef*/ window) { OSWindowRef wnd = static_cast(window); #if QT_MAC_USE_COCOA - [wnd flushWindowIfNeeded]; + [wnd flushWindowIfNeeded]; #else - HIWindowFlush(wnd); + HIWindowFlush(wnd); #endif } @@ -352,6 +350,12 @@ Qt::MouseButton qt_mac_get_button(EventMouseButton button) return Qt::NoButton; } +void macSendToolbarChangeEvent(QWidget *widget) +{ + QToolBarChangeEvent ev(!(GetCurrentKeyModifiers() & cmdKey)); + qt_sendSpontaneousEvent(widget, &ev); +} + Q_GLOBAL_STATIC(QMacTabletHash, tablet_hash) QMacTabletHash *qt_mac_tablet_hash() { diff --git a/src/gui/kernel/qt_cocoa_helpers_mac_p.h b/src/gui/kernel/qt_cocoa_helpers_mac_p.h index 3881ccd..5f6204f 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac_p.h +++ b/src/gui/kernel/qt_cocoa_helpers_mac_p.h @@ -118,9 +118,10 @@ void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds = 0); bool macWindowIsTextured(void * /*OSWindowRef*/ window); void macWindowToolbarShow(const QWidget *widget, bool show ); void macWindowToolbarSet( void * /*OSWindowRef*/ window, void* toolbarRef ); -bool macWindowToolbarVisible( void * /*OSWindowRef*/ window ); +bool macWindowToolbarIsVisible( void * /*OSWindowRef*/ window ); void macWindowSetHasShadow( void * /*OSWindowRef*/ window, bool hasShadow ); void macWindowFlush(void * /*OSWindowRef*/ window); +void macSendToolbarChangeEvent(QWidget *widget); struct HIContentBorderMetrics; void qt_mac_updateContentBorderMetricts(void * /*OSWindowRef */window, const ::HIContentBorderMetrics &metrics); void * /*NSImage */qt_mac_create_nsimage(const QPixmap &pm); diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index dcc5056..5e2dfb6 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -843,8 +843,7 @@ OSStatus QWidgetPrivate::qt_window_event(EventHandlerCallRef er, EventRef event, extern QPointer qt_button_down; //qapplication_mac.cpp qt_button_down = 0; } else if(ekind == kEventWindowToolbarSwitchMode) { - QToolBarChangeEvent ev(!(GetCurrentKeyModifiers() & cmdKey)); - QApplication::sendSpontaneousEvent(widget, &ev); + macSendToolbarChangeEvent(widget); HIToolbarRef toolbar; if (GetWindowToolbar(wid, &toolbar) == noErr) { if (toolbar) { diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp index 0c841eb..c51bed9 100644 --- a/src/gui/widgets/qmainwindow.cpp +++ b/src/gui/widgets/qmainwindow.cpp @@ -1369,20 +1369,25 @@ bool QMainWindow::event(QEvent *event) #ifdef Q_WS_MAC case QEvent::Show: if (unifiedTitleAndToolBarOnMac()) - macWindowToolbarShow(this, true); + d->layout->syncUnifiedToolbarVisibility(); + d->layout->blockVisiblityCheck = false; break; -# ifdef QT_MAC_USE_COCOA case QEvent::WindowStateChange: { + if (isHidden()) { + // We are coming out of a minimize, leave things as is. + d->layout->blockVisiblityCheck = true; + } +# ifdef QT_MAC_USE_COCOA // We need to update the HIToolbar status when we go out of or into fullscreen. QWindowStateChangeEvent *wce = static_cast(event); if ((windowState() & Qt::WindowFullScreen) || (wce->oldState() & Qt::WindowFullScreen)) { d->layout->updateHIToolBarStatus(); } +# endif // Cocoa } break; -# endif // Cocoa -#endif +#endif // Q_WS_MAC #if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR) case QEvent::CursorChange: if (d->cursorAdjusted) { diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp index aba9120..541907e 100644 --- a/src/gui/widgets/qmainwindowlayout.cpp +++ b/src/gui/widgets/qmainwindowlayout.cpp @@ -939,15 +939,70 @@ void QMainWindowLayout::getStyleOptionInfo(QStyleOptionToolBar *option, QToolBar void QMainWindowLayout::toggleToolBarsVisible() { - layoutState.toolBarAreaLayout.visible = !layoutState.toolBarAreaLayout.visible; - if (!layoutState.mainWindow->isMaximized()){ - QPoint topLeft = parentWidget()->geometry().topLeft(); - QRect r = parentWidget()->geometry(); - r = layoutState.toolBarAreaLayout.rectHint(r); - r.moveTo(topLeft); - parentWidget()->setGeometry(r); - } else{ - update(); + bool updateNonUnifiedParts = true; +#ifdef Q_WS_MAC + if (layoutState.mainWindow->unifiedTitleAndToolBarOnMac()) { + // If we hit this case, someone has pressed the "toolbar button" which will + // toggle the unified toolbar visiblity, because that's what the user wants. + // We might be in a situation where someone has hidden all the toolbars + // beforehand (maybe in construction), but now they've hit this button and + // and are expecting the items to show. What do we do? + // 1) Check the visibility of all the toolbars, if one is visible, do nothing, this + // preserves what people would expect (these toolbars were visible when I clicked last time). + // 2) If NONE are visible, then show them all. Again, this preserves the user expectation + // of, "I want to see the toolbars." The user may get more toolbars than expected, but this + // is better seeing nothing. + // Don't worry about any of this if we are going invisible. This does mean we may get + // into issues when switching into and out of fullscreen mode, but this is probably minor. + // If we ever need to do hiding, that would have to be taken care of after the unified toolbar + // has finished hiding. + // People can of course handle the QEvent::ToolBarChange event themselves and do + // WHATEVER they want if they don't like what we are doing (though the unified toolbar + // will fire regardless). + + // Check if we REALLY need to update the geometry below. If we only have items in the + // unified toolbar, all the docks will be empty, so there's very little point + // in doing the geometry as Apple will do it (we also avoid flicker in Cocoa as well). + // FWIW, layoutState.toolBarAreaLayout.visible and the state of the unified toolbar + // visibility can get out of sync. I really don't think it's a big issue. It is kept + // to a minimum because we only change the visibility if we absolutely must. + // update the "non unified parts." + updateNonUnifiedParts = !layoutState.toolBarAreaLayout.isEmpty(); + + // We get this function before the unified toolbar does its thing. + // So, the value will be opposite of what we expect. + bool goingVisible = !macWindowToolbarIsVisible(qt_mac_window_for(layoutState.mainWindow)); + if (goingVisible) { + const int ToolBarCount = qtoolbarsInUnifiedToolbarList.size(); + bool needAllVisible = true; + for (int i = 0; i < ToolBarCount; ++i) { + if (!qtoolbarsInUnifiedToolbarList.at(i)->isHidden()) { + needAllVisible = false; + break; + } + } + if (needAllVisible) { + QBoolBlocker blocker(blockVisiblityCheck); // Disable the visibilty check because + // the toggle has already happened. + for (int i = 0; i < ToolBarCount; ++i) + qtoolbarsInUnifiedToolbarList.at(i)->setVisible(true); + } + } + if (!updateNonUnifiedParts) + layoutState.toolBarAreaLayout.visible = goingVisible; + } +#endif + if (updateNonUnifiedParts) { + layoutState.toolBarAreaLayout.visible = !layoutState.toolBarAreaLayout.visible; + if (!layoutState.mainWindow->isMaximized()) { + QPoint topLeft = parentWidget()->geometry().topLeft(); + QRect r = parentWidget()->geometry(); + r = layoutState.toolBarAreaLayout.rectHint(r); + r.moveTo(topLeft); + parentWidget()->setGeometry(r); + } else { + update(); + } } } @@ -1641,6 +1696,9 @@ QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow) #ifndef QT_NO_RUBBERBAND , gapIndicator(new QRubberBand(QRubberBand::Rectangle, mainwindow)) #endif //QT_NO_RUBBERBAND +#ifdef Q_WS_MAC + , blockVisiblityCheck(false) +#endif { #ifndef QT_NO_DOCKWIDGET #ifndef QT_NO_TABBAR diff --git a/src/gui/widgets/qmainwindowlayout_mac.mm b/src/gui/widgets/qmainwindowlayout_mac.mm index 6632be7..61719c2 100644 --- a/src/gui/widgets/qmainwindowlayout_mac.mm +++ b/src/gui/widgets/qmainwindowlayout_mac.mm @@ -338,18 +338,16 @@ void QMainWindowLayout::updateHIToolBarStatus() 0, kWindowUnifiedTitleAndToolbarAttribute); } #endif - macWindowToolbarShow(layoutState.mainWindow, useMacToolbar); layoutState.mainWindow->setUpdatesEnabled(false); // reduces a little bit of flicker, not all though if (!useMacToolbar) { - OSWindowRef windowRef = qt_mac_window_for(parentWidget()); - macWindowToolbarShow(parentWidget(), false); + macWindowToolbarShow(layoutState.mainWindow, false); // Move everything out of the HIToolbar into the main toolbar. while (!qtoolbarsInUnifiedToolbarList.isEmpty()) { // Should shrink the list by one every time. layoutState.mainWindow->addToolBar(Qt::TopToolBarArea, qtoolbarsInUnifiedToolbarList.first()); } - macWindowToolbarSet(windowRef, NULL); + macWindowToolbarSet(qt_mac_window_for(layoutState.mainWindow), 0); } else { QList toolbars = layoutState.mainWindow->findChildren(); for (int i = 0; i < toolbars.size(); ++i) { @@ -359,6 +357,7 @@ void QMainWindowLayout::updateHIToolBarStatus() layoutState.mainWindow->addToolBar(Qt::TopToolBarArea, toolbar); } } + syncUnifiedToolbarVisibility(); } layoutState.mainWindow->setUpdatesEnabled(true); } @@ -439,7 +438,7 @@ void QMainWindowLayout::insertIntoMacToolbar(QToolBar *before, QToolBar *toolbar #else NSString *toolbarID = kQToolBarNSToolbarIdentifier; toolbarID = [toolbarID stringByAppendingFormat:@"%p", toolbar]; - cocoaItemIDToToolbarHash.insert(QCFString::toQString(CFStringRef(toolbarID)), toolbar); + cocoaItemIDToToolbarHash.insert(qt_mac_NSStringToQString(toolbarID), toolbar); [macToolbar insertItemWithItemIdentifier:toolbarID atIndex:beforeIndex]; #endif } @@ -487,6 +486,7 @@ void QMainWindowLayout::cleanUpMacToolbarItems() void QMainWindowLayout::fixSizeInUnifiedToolbar(QToolBar *tb) const { +#ifdef QT_MAC_USE_COCOA QHash::const_iterator it = unifiedToolbarHash.constBegin(); NSToolbarItem *item = nil; while (it != unifiedToolbarHash.constEnd()) { @@ -507,5 +507,26 @@ void QMainWindowLayout::fixSizeInUnifiedToolbar(QToolBar *tb) const nssize.height = size.height() - 2; [item setMinSize:nssize]; } +#else + Q_UNUSED(tb); +#endif } + +void QMainWindowLayout::syncUnifiedToolbarVisibility() +{ + if (blockVisiblityCheck) + return; + + Q_ASSERT(layoutState.mainWindow->unifiedTitleAndToolBarOnMac()); + bool show = false; + const int ToolBarCount = qtoolbarsInUnifiedToolbarList.count(); + for (int i = 0; i < ToolBarCount; ++i) { + if (qtoolbarsInUnifiedToolbarList.at(i)->isVisible()) { + show = true; + break; + } + } + macWindowToolbarShow(layoutState.mainWindow, show); +} + QT_END_NAMESPACE diff --git a/src/gui/widgets/qmainwindowlayout_p.h b/src/gui/widgets/qmainwindowlayout_p.h index 45f62cd..524fdbf 100644 --- a/src/gui/widgets/qmainwindowlayout_p.h +++ b/src/gui/widgets/qmainwindowlayout_p.h @@ -335,6 +335,8 @@ public: void cleanUpMacToolbarItems(); void fixSizeInUnifiedToolbar(QToolBar *tb) const; bool useHIToolBar; + void syncUnifiedToolbarVisibility(); + bool blockVisiblityCheck; #endif }; QT_END_NAMESPACE diff --git a/src/gui/widgets/qtoolbar.cpp b/src/gui/widgets/qtoolbar.cpp index b249915..b65f1ba 100644 --- a/src/gui/widgets/qtoolbar.cpp +++ b/src/gui/widgets/qtoolbar.cpp @@ -1074,6 +1074,15 @@ static bool waitForPopup(QToolBar *tb, QWidget *popup) return false; } +#if defined(Q_WS_MAC) +static bool toolbarInUnifiedToolBar(QToolBar *toolbar) +{ + const QMainWindow *mainWindow = qobject_cast(toolbar->parentWidget()); + return mainWindow && mainWindow->unifiedTitleAndToolBarOnMac() + && mainWindow->toolBarArea(toolbar) == Qt::TopToolBarArea; +} +#endif + /*! \reimp */ bool QToolBar::event(QEvent *event) { @@ -1096,7 +1105,15 @@ bool QToolBar::event(QEvent *event) // fallthrough intended case QEvent::Show: d->toggleViewAction->setChecked(event->type() == QEvent::Show); -#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA) +#if defined(Q_WS_MAC) + if (toolbarInUnifiedToolBar(this)) { + // I can static_cast because I did the qobject_cast in the if above, therefore + // we must have a QMainWindowLayout here. + QMainWindowLayout *mwLayout = static_cast(parentWidget()->layout()); + mwLayout->fixSizeInUnifiedToolbar(this); + mwLayout->syncUnifiedToolbarVisibility(); + } +# if !defined(QT_MAC_USE_COCOA) // Fall through case QEvent::LayoutRequest: { // There's currently no way to invalidate the size and let @@ -1111,10 +1128,9 @@ bool QToolBar::event(QEvent *event) } if (needUpdate) { - OSWindowRef windowRef = qt_mac_window_for(this); - if (mainWindow->unifiedTitleAndToolBarOnMac() - && mainWindow->toolBarArea(this) == Qt::TopToolBarArea - && macWindowToolbarVisible(windowRef)) { + OSWindowRef windowRef = qt_mac_window_for(mainWindow); + if (toolbarInUnifiedToolBar(this) + && macWindowToolbarIsVisible(windowRef)) { DisableScreenUpdates(); macWindowToolbarShow(this, false); macWindowToolbarShow(this, true); @@ -1126,7 +1142,8 @@ bool QToolBar::event(QEvent *event) return earlyResult; } } -#endif +# endif // !QT_MAC_USE_COCOA +#endif // Q_WS_MAC break; case QEvent::ParentChange: d->layout->checkUsePopupMenu(); -- cgit v0.12 From a21230152c4ea8cd2e641f436230e76a835384c2 Mon Sep 17 00:00:00 2001 From: Bill King Date: Fri, 10 Jul 2009 12:07:38 +1000 Subject: Fixes a heisenbug when using two ODBC connections with diff quoters. Can have situations where 2 odbc connections are active, that have differing quoting charachters. Before this fix, everything fell over. Reviewed-by: Justin McPherson --- src/sql/drivers/odbc/qsql_odbc.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index 50defdf..fa9031a 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -89,7 +89,8 @@ public: enum DefaultCase{Lower, Mixed, Upper, Sensitive}; QODBCDriverPrivate() : hEnv(0), hDbc(0), useSchema(false), disconnectCount(0), isMySqlServer(false), - isMSSqlServer(false), hasSQLFetchScroll(true), hasMultiResultSets(false) + isMSSqlServer(false), hasSQLFetchScroll(true), hasMultiResultSets(false), + isQuoteInitialized(false), quote(QLatin1Char('"')) { unicode = false; } @@ -116,7 +117,10 @@ public: QString &schema, QString &table); DefaultCase defaultCase() const; QString adjustCase(const QString&) const; - QChar quoteChar() const; + QChar quoteChar(); +private: + bool isQuoteInitialized; + QChar quote; }; class QODBCPrivate @@ -566,10 +570,8 @@ static int qGetODBCVersion(const QString &connOpts) return SQL_OV_ODBC2; } -QChar QODBCDriverPrivate::quoteChar() const +QChar QODBCDriverPrivate::quoteChar() { - static bool isQuoteInitialized = false; - static QChar quote = QChar::fromLatin1('"'); if (!isQuoteInitialized) { char driverResponse[4]; SQLSMALLINT length; @@ -579,9 +581,9 @@ QChar QODBCDriverPrivate::quoteChar() const sizeof(driverResponse), &length); if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) { - quote = QChar::fromLatin1(driverResponse[0]); + quote = QLatin1Char(driverResponse[0]); } else { - quote = QChar::fromLatin1('"'); + quote = QLatin1Char('"'); } isQuoteInitialized = true; } -- cgit v0.12 From 0d156972b868c951fa33f21735040ab1e7a76f21 Mon Sep 17 00:00:00 2001 From: Bill King Date: Fri, 10 Jul 2009 12:12:45 +1000 Subject: Get more sql autotests passing or expect-failing. --- tests/auto/qsqlquery/tst_qsqlquery.cpp | 2 ++ .../tst_qsqlrelationaltablemodel.cpp | 18 ++++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp index 9a873cb..f3dd920 100644 --- a/tests/auto/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp @@ -495,7 +495,9 @@ void tst_QSqlQuery::mysqlOutValues() QVERIFY_SQL( q, exec( "create procedure " + qTableName( "qtestproc" ) + " () " "BEGIN select * from " + qTableName( "qtest" ) + " order by id; END" ) ); QVERIFY_SQL( q, exec( "call " + qTableName( "qtestproc" ) + "()" ) ); + QEXPECT_FAIL("", "There's a mysql bug that means only selects think they return data when running in prepared mode", Continue); QVERIFY_SQL( q, next() ); + QEXPECT_FAIL("", "There's a mysql bug that means only selects think they return data when running in prepared mode", Continue); QCOMPARE( q.value( 1 ).toString(), QString( "VarChar1" ) ); QVERIFY_SQL( q, exec( "drop procedure " + qTableName( "qtestproc" ) ) ); diff --git a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp index d934b35..1e23d3d 100644 --- a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp +++ b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp @@ -145,8 +145,17 @@ void tst_QSqlRelationalTableModel::recreateTestTables(QSqlDatabase db) void tst_QSqlRelationalTableModel::initTestCase() { - foreach (const QString &dbname, dbs.dbNames) - recreateTestTables(QSqlDatabase::database(dbname)); + foreach (const QString &dbname, dbs.dbNames) { + QSqlDatabase db=QSqlDatabase::database(dbname); + if (db.driverName().startsWith("QIBASE")) + db.exec("SET DIALECT 3"); + else if (tst_Databases::isSqlServer(db)) { + QSqlQuery q(db); + QVERIFY_SQL(q, exec("SET ANSI_DEFAULTS ON")); + QVERIFY_SQL(q, exec("SET IMPLICIT_TRANSACTIONS OFF")); + } + recreateTestTables(db); + } } void tst_QSqlRelationalTableModel::cleanupTestCase() @@ -490,6 +499,7 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setSort(0, Qt::AscendingOrder); if (!db.driverName().startsWith("QTDS")) model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); @@ -914,8 +924,8 @@ void tst_QSqlRelationalTableModel::casing() QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - if (db.driverName().startsWith("QSQLITE")) - QSKIP("The casing test for SQLITE is irrelevant since SQLITE is case insensitive", SkipAll); + if (db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QIBASE") || tst_Databases::isSqlServer(db)) + QSKIP("The casing test for this database is irrelevant since this database does not treat different cases as separate entities", SkipAll); QSqlQuery q(db); QVERIFY_SQL( q, exec("create table " + qTableName("CASETEST1", db.driver()).toUpper() + -- cgit v0.12 From 5f798ce8208fd5b1f2212246bc6b8ee2ec4652f0 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Thu, 2 Jul 2009 18:16:42 -0700 Subject: Fix QDFBPaintEngine::drawTiledPixmap/fillRect Until this fix very few cases of drawTiledPixmap and fillRect(r, textureBrush) have been handled by DirectFB. This patch makes it possible to accelerate such operations. Reviewed-By: Donald --- .../gfxdrivers/directfb/qdirectfbpaintengine.cpp | 168 ++++++++++++++------- 1 file changed, 111 insertions(+), 57 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 947cc76..27df0da 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -241,7 +241,7 @@ public: void fillRects(const QRectF *rects, int count); void drawRects(const QRectF *rects, int count); - void drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap); + void drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap, const QPointF &pos); void blit(const QRectF &dest, IDirectFBSurface *surface, const QRectF &src); inline void updateClip(); @@ -284,6 +284,7 @@ private: bool unsupportedCompositionMode; QDirectFBPaintEngine *q; + QRect currentClip; friend class QDirectFBPaintEngine; }; @@ -343,6 +344,7 @@ bool QDirectFBPaintEngine::end() #if (Q_DIRECTFB_VERSION >= 0x010000) d->surface->ReleaseSource(d->surface); #endif + d->currentClip = QRect(); d->surface->SetClip(d->surface, NULL); d->surface = 0; return QRasterPaintEngine::end(); @@ -613,30 +615,26 @@ void QDirectFBPaintEngine::drawPixmap(const QPointF &p, const QPixmap &pm) void QDirectFBPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, - const QPointF &sp) + const QPointF &offset) { Q_D(QDirectFBPaintEngine); d->updateClip(); if (pixmap.pixmapData()->classId() != QPixmapData::DirectFBClass) { - RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), sp); + RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), offset); d->lock(); - QRasterPaintEngine::drawTiledPixmap(r, pixmap, sp); - } else if (d->unsupportedCompositionMode || !d->dfbCanHandleClip(r) || d->matrixRotShear || !sp.isNull() + QRasterPaintEngine::drawTiledPixmap(r, pixmap, offset); + } else if (d->unsupportedCompositionMode || !d->dfbCanHandleClip(r) || d->matrixRotShear || d->scale == QDirectFBPaintEnginePrivate::NegativeScale) { - RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), sp); + RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), offset); const QImage *img = static_cast(pixmap.pixmapData())->buffer(DSLF_READ); d->lock(); QRasterPixmapData *data = new QRasterPixmapData(QPixmapData::PixmapType); data->fromImage(*img, Qt::AutoColor); const QPixmap pix(data); - QRasterPaintEngine::drawTiledPixmap(r, pix, sp); + QRasterPaintEngine::drawTiledPixmap(r, pix, offset); } else { d->unlock(); - QPixmapData *data = pixmap.pixmapData(); - Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); - QDirectFBPixmapData *dfbData = static_cast(data); - dfbData->unlockDirectFB(); - d->drawTiledPixmap(r, pixmap); + d->drawTiledPixmap(r, pixmap, offset); } } @@ -733,14 +731,17 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) d->surface->FillRectangle(d->surface, r.x(), r.y(), r.width(), r.height()); return; } - case Qt::TexturePattern: - if (state()->brushOrigin == QPointF() && brush.transform().isIdentity()) { - //could handle certain types of brush.transform() E.g. scale - d->unlock(); - d->drawTiledPixmap(rect, brush.texture()); - return; - } - break; + case Qt::TexturePattern: { + if (d->scale == QDirectFBPaintEnginePrivate::NegativeScale) + break; + + const QPixmap texture = brush.texture(); + if (texture.pixmapData()->classId() != QPixmapData::DirectFBClass) + break; + + d->unlock(); + d->drawTiledPixmap(rect, texture, rect.topLeft() - state()->brushOrigin); + return; } default: break; } @@ -1077,55 +1078,105 @@ void QDirectFBPaintEnginePrivate::blit(const QRectF &dest, IDirectFBSurface *s, DirectFBError("QDirectFBPaintEngine::drawPixmap()", result); } -void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, - const QPixmap &pixmap) +static inline qreal fixCoord(qreal rect_pos, qreal pixmapSize, qreal offset) { + qreal pos = rect_pos - offset; + while (pos > rect_pos) + pos -= pixmapSize; + while (pos + pixmapSize < rect_pos) + pos += pixmapSize; + return pos; +} + +void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap, const QPointF &off) +{ + Q_ASSERT(!dirtyClip); + const QRect destinationRect = transform.mapRect(dest).toRect().normalized(); + QRect newClip = destinationRect; + if (!currentClip.isEmpty()) + newClip &= currentClip; + + if (newClip.isNull()) + return; + + const DFBRegion clip = { + newClip.x(), + newClip.y(), + newClip.x() + newClip.width() - 1, + newClip.y() + newClip.height() - 1 + }; + surface->SetClip(surface, &clip); + + QPointF offset = off; + Q_ASSERT(transform.type() <= QTransform::TxScale); prepareForBlit(pixmap.hasAlphaChannel()); QPixmapData *data = pixmap.pixmapData(); Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); QDirectFBPixmapData *dfbData = static_cast(data); - IDirectFBSurface *s = dfbData->directFBSurface(); - const QRect dr = transform.mapRect(dest).toRect(); - DFBResult result = DFB_OK; - - if (scale == NoScale && dr == QRect(0, 0, fbWidth, fbHeight)) { - result = surface->TileBlit(surface, s, 0, 0, 0); - } else if (scale == NoScale) { - const int dx = pixmap.width(); - const int dy = pixmap.height(); - const DFBRectangle rect = { 0, 0, dx, dy }; - QVarLengthArray rects; - QVarLengthArray points; - - for (int y = dr.y(); y <= dr.bottom(); y += dy) { - for (int x = dr.x(); x <= dr.right(); x += dx) { - rects.append(rect); - const DFBPoint point = { x, y }; - points.append(point); + dfbData->unlockDirectFB(); + const QSize pixmapSize = dfbData->size(); + IDirectFBSurface *sourceSurface = dfbData->directFBSurface(); + if (transform.isScaling()) { + Q_ASSERT(qMin(transform.m11(), transform.m22()) >= 0); + offset.rx() *= transform.m11(); + offset.ry() *= transform.m22(); + + const QSizeF mappedSize(pixmapSize.width() * transform.m11(), pixmapSize.height() * transform.m22()); + qreal y = ::fixCoord(destinationRect.y(), mappedSize.height(), offset.y()); + const qreal startX = ::fixCoord(destinationRect.x(), mappedSize.width(), offset.x()); + while (y < destinationRect.bottom()) { + qreal x = startX; + while (x < destinationRect.right()) { + const DFBRectangle destination = { qRound(x), qRound(y), mappedSize.width(), mappedSize.height() }; + surface->StretchBlit(surface, sourceSurface, 0, &destination); + x += mappedSize.width(); } + y += mappedSize.height(); } - result = surface->BatchBlit(surface, s, rects.constData(), - points.constData(), points.size()); } else { - const QRect sr = transform.mapRect(QRect(0, 0, pixmap.width(), pixmap.height())); - const int dx = sr.width(); - const int dy = sr.height(); - const DFBRectangle sRect = { 0, 0, dx, dy }; - - for (int y = dr.y(); y <= dr.bottom(); y += dy) { - for (int x = dr.x(); x <= dr.right(); x += dx) { - const DFBRectangle dRect = { x, y, dx, dy }; - result = surface->StretchBlit(surface, s, &sRect, &dRect); - if (result != DFB_OK) { - y = dr.bottom() + 1; - break; - } + qreal y = ::fixCoord(destinationRect.y(), pixmapSize.height(), offset.y()); + const qreal startX = ::fixCoord(destinationRect.x(), pixmapSize.width(), offset.x()); + int horizontal = qMax(1, destinationRect.width() / pixmapSize.width()) + 1; + if (startX != destinationRect.x()) + ++horizontal; + int vertical = qMax(1, destinationRect.height() / pixmapSize.height()) + 1; + if (y != destinationRect.y()) + ++vertical; + + const int maxCount = (vertical * horizontal); + QVarLengthArray sourceRects(maxCount); + QVarLengthArray points(maxCount); + + int i = 0; + while (y < destinationRect.bottom()) { + Q_ASSERT(i < maxCount); + qreal x = startX; + while (x < destinationRect.right()) { + points[i].x = qRound(x); + points[i].y = qRound(y); + sourceRects[i].x = 0; + sourceRects[i].y = 0; + sourceRects[i].w = int(pixmapSize.width()); + sourceRects[i].h = int(pixmapSize.height()); + x += pixmapSize.width(); + ++i; } + y += pixmapSize.height(); } + surface->BatchBlit(surface, sourceSurface, sourceRects.constData(), points.constData(), i); } - if (result != DFB_OK) - DirectFBError("QDirectFBPaintEngine::drawTiledPixmap()", result); + if (currentClip.isEmpty()) { + surface->SetClip(surface, 0); + } else { + const DFBRegion clip = { + currentClip.x(), + currentClip.y(), + currentClip.x() + currentClip.width(), + currentClip.y() + currentClip.height() + }; + surface->SetClip(surface, &clip); + } } void QDirectFBPaintEnginePrivate::updateClip() @@ -1133,6 +1184,7 @@ void QDirectFBPaintEnginePrivate::updateClip() if (!dirtyClip) return; + currentClip = QRect(); const QClipData *clipData = clip(); if (!clipData || !clipData->enabled) { surface->SetClip(surface, NULL); @@ -1145,6 +1197,8 @@ void QDirectFBPaintEnginePrivate::updateClip() clipData->clipRect.y() + clipData->clipRect.height() }; surface->SetClip(surface, &r); + currentClip = clipData->clipRect.normalized(); + // ### is this guaranteed to always be normalized? dfbHandledClip = true; } else if (clipData->hasRegionClip && ignoreSystemClip && clipData->clipRegion == systemClip) { dfbHandledClip = true; -- cgit v0.12 From f3acf50b1410d7756788b8f9b6144bf7af61a24e Mon Sep 17 00:00:00 2001 From: Bill King Date: Fri, 10 Jul 2009 13:13:44 +1000 Subject: Update test db definitions. --- tests/auto/qsqldatabase/tst_databases.h | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/auto/qsqldatabase/tst_databases.h b/tests/auto/qsqldatabase/tst_databases.h index 5b19023..9c8c313 100644 --- a/tests/auto/qsqldatabase/tst_databases.h +++ b/tests/auto/qsqldatabase/tst_databases.h @@ -105,7 +105,11 @@ inline static QString qTableName( const QString& prefix, QSqlDriver* driver = 0 inline static bool testWhiteSpaceNames( const QString &name ) { - return name != QLatin1String("QTDS7"); +/* return name.startsWith( "QPSQL" ) + || name.startsWith( "QODBC" ) + || name.startsWith( "QSQLITE" ) + || name.startsWith( "QMYSQL" );*/ + return name != QLatin1String("QSQLITE2"); } inline static QString toHex( const QString& binary ) @@ -246,10 +250,10 @@ public: // addDb( "QODBC", "DRIVER={MySQL ODBC 3.51 Driver};SERVER=mysql5-nokia.trolltech.com.au;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" ); // addDb( "QODBC", "DRIVER={MySQL ODBC 5.1 Driver};SERVER=mysql4-nokia.trolltech.com.au;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" ); -// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=horsehead.nokia.troll.no;DATABASE=testdb;PORT=4101;UID=troll;PWD=trondk;TDS_Version=8.0", "troll", "trondk", "" ); -// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=silence.nokia.troll.no;DATABASE=testdb;PORT=2392;UID=troll;PWD=trond;TDS_Version=8.0", "troll", "trond", "" ); -// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2003-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "testuser", "Ee4Gabf6_", "" ); -// 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( "QODBC", "DRIVER={FreeTDS};SERVER=horsehead.nokia.troll.no;DATABASE=testdb;PORT=4101;UID=troll;PWD=trondk", "troll", "trondk", "" ); +// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=silence.nokia.troll.no;DATABASE=testdb;PORT=2392;UID=troll;PWD=trond", "troll", "trond", "" ); +// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2003-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "", "", "" ); +// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2008-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "", "", "" ); // 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_", "" ); -- cgit v0.12 From 64b485855637ef4fa31d3a4efca694db888ae612 Mon Sep 17 00:00:00 2001 From: Luc Devallonne Date: Fri, 10 Jul 2009 10:10:02 +0200 Subject: Support Tablet coordinate on Windows with non-zero physical origin Most Wacom tablet have a coordinate origin at 0 (Bamboo,Intous), but some tablet (like DTF 720, which have an integrated screen) have a non zero coordinate origin. Which lead to an errounous y/a tablet pos reported by Qt tablet event. Merge-request: 822 Reviewed-by: Norwegian Rock Cat --- src/gui/kernel/qapplication_p.h | 10 ++++++---- src/gui/kernel/qapplication_win.cpp | 20 +++++++++++--------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index db77b07..90eaba0 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -158,17 +158,19 @@ inline QPointF QTabletDeviceData::scaleCoord(int coordX, int coordY, int outOriginY, int outExtentY) const { QPointF ret; + if (sign(outExtentX) == sign(maxX)) - ret.setX(((coordX - minX) * qAbs(outExtentX) / qAbs(qreal(maxX))) + outOriginX); + ret.setX(((coordX - minX) * qAbs(outExtentX) / qAbs(qreal(maxX - minX))) + outOriginX); else - ret.setX(((qAbs(maxX) - (coordX - minX)) * qAbs(outExtentX) / qAbs(qreal(maxX))) + ret.setX(((qAbs(maxX) - (coordX - minX)) * qAbs(outExtentX) / qAbs(qreal(maxX - minX))) + outOriginX); if (sign(outExtentY) == sign(maxY)) - ret.setY(((coordY - minY) * qAbs(outExtentY) / qAbs(qreal(maxY))) + outOriginY); + ret.setY(((coordY - minY) * qAbs(outExtentY) / qAbs(qreal(maxY - minY))) + outOriginY); else - ret.setY(((qAbs(maxY) - (coordY - minY)) * qAbs(outExtentY) / qAbs(qreal(maxY))) + ret.setY(((qAbs(maxY) - (coordY - minY)) * qAbs(outExtentY) / qAbs(qreal(maxY - minY))) + outOriginY); + return ret; } #endif diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index e0eda82..e26d82e 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -3324,17 +3324,19 @@ static void tabletInit(UINT wActiveCsr, HCTX hTab) tdd.minTanPressure = int(np.axMin); tdd.maxTanPressure = int(np.axMax); - ptrWTInfo(WTI_DEVICES + lc.lcDevice, DVC_X, &np); - tdd.minX = int(np.axMin); - tdd.maxX = int(np.axMax); + LOGCONTEXT lcMine; - ptrWTInfo(WTI_DEVICES + lc.lcDevice, DVC_Y, &np); - tdd.minY = int(np.axMin); - tdd.maxY = int(np.axMax); + /* get default region */ + ptrWTInfo(WTI_DEFCONTEXT, 0, &lcMine); - ptrWTInfo(WTI_DEVICES + lc.lcDevice, DVC_Z, &np); - tdd.minZ = int(np.axMin); - tdd.maxZ = int(np.axMax); + tdd.minX = 0; + tdd.maxX = int(lcMine.lcInExtX) - int(lcMine.lcInOrgX); + + tdd.minY = 0; + tdd.maxY = int(lcMine.lcInExtY) - int(lcMine.lcInOrgY); + + tdd.minZ = 0; + tdd.maxZ = int(lcMine.lcInExtZ) - int(lcMine.lcInOrgZ); int csr_type, csr_physid; -- cgit v0.12 From 28f31572b95a28e14f7ed4cebb907cfe1e257177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Fri, 10 Jul 2009 10:37:29 +0200 Subject: Painting artifacts when moving an item with partial updates. Found during manual testing (dndrobotinproxy). The problem was that the paintedViewBoundingRect was set to an empty rect because the partial update area didn't intersect with the viewport. The item itself was partially inside the viewport. Then, when the item was moved, its old area was not repainted due to this empty paintedViewBoundingRect. Auto-test included. --- src/gui/graphicsview/qgraphicsitem.cpp | 1 + src/gui/graphicsview/qgraphicsscene.cpp | 49 +++++++++++++------------- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 47 ++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 24 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 85d76d4..2f646f7 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1821,6 +1821,7 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo if (q_ptr->isSelected()) q_ptr->setSelected(false); } else { + geometryChanged = 1; if (isWidget && scene) { QGraphicsWidget *widget = static_cast(q_ptr); if (widget->windowType() == Qt::Popup) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 0ca72b7..c7c0865 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4517,17 +4517,14 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool item->d_ptr->paintedViewBoundingRectsNeedRepaint = 0; } - if (item->d_ptr->geometryChanged) { + if (!hasSceneRect && item->d_ptr->geometryChanged && item->d_ptr->visible) { // Update growingItemsBoundingRect. - if (!hasSceneRect) { - if (item->d_ptr->sceneTransformTranslateOnly) { - growingItemsBoundingRect |= item->boundingRect().translated(item->d_ptr->sceneTransform.dx(), - item->d_ptr->sceneTransform.dy()); - } else { - growingItemsBoundingRect |= item->d_ptr->sceneTransform.mapRect(item->boundingRect()); - } + if (item->d_ptr->sceneTransformTranslateOnly) { + growingItemsBoundingRect |= item->boundingRect().translated(item->d_ptr->sceneTransform.dx(), + item->d_ptr->sceneTransform.dy()); + } else { + growingItemsBoundingRect |= item->d_ptr->sceneTransform.mapRect(item->boundingRect()); } - item->d_ptr->geometryChanged = 0; } // Process item. @@ -4552,29 +4549,31 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool for (int j = 0; j < views.size(); ++j) { QGraphicsView *view = views.at(j); QGraphicsViewPrivate *viewPrivate = view->d_func(); - if (viewPrivate->fullUpdatePending) - continue; - switch (viewPrivate->viewportUpdateMode) { - case QGraphicsView::NoViewportUpdate: - continue; - case QGraphicsView::FullViewportUpdate: - view->viewport()->update(); - viewPrivate->fullUpdatePending = 1; + QRect &paintedViewBoundingRect = item->d_ptr->paintedViewBoundingRects[viewPrivate->viewport]; + if (viewPrivate->fullUpdatePending + || viewPrivate->viewportUpdateMode == QGraphicsView::NoViewportUpdate) { + // Okay, if we have a full update pending or no viewport update, this item's + // paintedViewBoundingRect will be updated correctly in the next paintEvent if + // it is inside the viewport, but for now we can pretend that it is outside. + paintedViewBoundingRect = QRect(-1, -1, -1, -1); continue; - default: - break; } - QRect &paintedViewBoundingRect = item->d_ptr->paintedViewBoundingRects[viewPrivate->viewport]; - if (item->d_ptr->paintedViewBoundingRectsNeedRepaint) { + if (item->d_ptr->paintedViewBoundingRectsNeedRepaint && !paintedViewBoundingRect.isEmpty()) { paintedViewBoundingRect.translate(viewPrivate->dirtyScrollOffset); if (!viewPrivate->updateRect(paintedViewBoundingRect)) - paintedViewBoundingRect = QRect(); + paintedViewBoundingRect = QRect(-1, -1, -1, -1); // Outside viewport. } if (!item->d_ptr->dirty) continue; + if (!item->d_ptr->geometryChanged + && paintedViewBoundingRect.x() == -1 && paintedViewBoundingRect.y() == -1 + && paintedViewBoundingRect.width() == -1 && paintedViewBoundingRect.height() == -1) { + continue; // Outside viewport. + } + if (uninitializedDirtyRect) { dirtyRect = itemBoundingRect; if (!item->d_ptr->fullUpdatePending) { @@ -4587,8 +4586,10 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool if (dirtyRect.isEmpty()) continue; // Discard updates outside the bounding rect. - if (!updateHelper(viewPrivate, item->d_ptr, dirtyRect, itemIsUntransformable)) - paintedViewBoundingRect = QRect(); + if (!updateHelper(viewPrivate, item->d_ptr, dirtyRect, itemIsUntransformable) + && item->d_ptr->geometryChanged) { + paintedViewBoundingRect = QRect(-1, -1, -1, -1); // Outside viewport. + } } } } diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index d689293..2dbd5f1 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -6580,6 +6580,7 @@ public: void tst_QGraphicsItem::update() { QGraphicsScene scene; + scene.setSceneRect(-100, -100, 200, 200); MyGraphicsView view(&scene); view.show(); @@ -6636,6 +6637,52 @@ void tst_QGraphicsItem::update() QCOMPARE(view.repaints, 1); // The entire item's bounding rect (adjusted for antialiasing) should have been painted. QCOMPARE(view.paintedRegion, expectedRegion); + + // Make sure item is repainted when shown (after being hidden). + view.reset(); + item->repaints = 0; + item->show(); + qApp->processEvents(); + QCOMPARE(item->repaints, 1); + QCOMPARE(view.repaints, 1); + // The entire item's bounding rect (adjusted for antialiasing) should have been painted. + QCOMPARE(view.paintedRegion, expectedRegion); + + item->repaints = 0; + item->hide(); + qApp->processEvents(); + view.reset(); + const QPointF originalPos = item->pos(); + item->setPos(5000, 5000); + qApp->processEvents(); + QCOMPARE(item->repaints, 0); + QCOMPARE(view.repaints, 0); + qApp->processEvents(); + + item->setPos(originalPos); + qApp->processEvents(); + QCOMPARE(item->repaints, 0); + QCOMPARE(view.repaints, 0); + item->show(); + qApp->processEvents(); + QCOMPARE(item->repaints, 1); + QCOMPARE(view.repaints, 1); + // The entire item's bounding rect (adjusted for antialiasing) should have been painted. + QCOMPARE(view.paintedRegion, expectedRegion); + + QGraphicsViewPrivate *viewPrivate = static_cast(qt_widget_private(&view)); + item->setPos(originalPos + QPoint(50, 50)); + viewPrivate->updateAll(); + QVERIFY(viewPrivate->fullUpdatePending); + QTest::qWait(50); + item->repaints = 0; + view.reset(); + item->setPos(originalPos); + QTest::qWait(50); + qApp->processEvents(); + QCOMPARE(item->repaints, 1); + QCOMPARE(view.repaints, 1); + QCOMPARE(view.paintedRegion, expectedRegion + expectedRegion.translated(50, 50)); } void tst_QGraphicsItem::setTransformProperties_data() -- cgit v0.12 From 00cc4c9cfc83fa2a20fc72712c7caf9f8bc6f7bb Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 10 Jul 2009 11:08:24 +0200 Subject: Phonon videos on windows would not show with video acceleration disabled Task-number: 257805 --- src/3rdparty/phonon/ds9/videowidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty/phonon/ds9/videowidget.cpp b/src/3rdparty/phonon/ds9/videowidget.cpp index 0ef653f..34ff8cb 100644 --- a/src/3rdparty/phonon/ds9/videowidget.cpp +++ b/src/3rdparty/phonon/ds9/videowidget.cpp @@ -153,7 +153,7 @@ namespace Phonon } } else if (!isEmbedded()) { m_currentRenderer = m_node->switchRendering(m_currentRenderer); - setAttribute(Qt::WA_PaintOnScreen, true); + setAttribute(Qt::WA_PaintOnScreen, false); } } -- cgit v0.12 From f9128d973f60e225045bebb97a19d292395b865d Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 10 Jul 2009 11:24:35 +0200 Subject: QDoubleSpinBox: make sure people can't choose too many decimals Maximum number of decimals is DBL_MAX_10_EXP + DBL_DIG Task-number: 257291 --- src/gui/widgets/qspinbox.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/gui/widgets/qspinbox.cpp b/src/gui/widgets/qspinbox.cpp index e069a21..3933272 100644 --- a/src/gui/widgets/qspinbox.cpp +++ b/src/gui/widgets/qspinbox.cpp @@ -50,6 +50,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -823,8 +824,8 @@ void QDoubleSpinBox::setRange(double minimum, double maximum) Sets how many decimals the spinbox will use for displaying and interpreting doubles. - \warning The results might not be reliable with very high values - for \a decimals. + \warning The maximum value for \a decimals is DBL_MAX_10_EXP + + DBL_DIG (ie. 323) because of the limitations of the double type. Note: The maximum, minimum and value might change as a result of changing this property. @@ -840,7 +841,7 @@ int QDoubleSpinBox::decimals() const void QDoubleSpinBox::setDecimals(int decimals) { Q_D(QDoubleSpinBox); - d->decimals = qMax(0, decimals); + d->decimals = qBound(0, decimals, DBL_MAX_10_EXP + DBL_DIG); setRange(minimum(), maximum()); // make sure values are rounded setValue(value()); -- cgit v0.12 From fdf5fd0cc63c20579250087905331eb76385d528 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 10 Jul 2009 12:32:26 +0200 Subject: QFileDialog: the side urls are now always cleaned when they are local Task-number: 257579 --- src/gui/dialogs/qsidebar.cpp | 13 +++++++++---- tests/auto/qfiledialog/tst_qfiledialog.cpp | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/gui/dialogs/qsidebar.cpp b/src/gui/dialogs/qsidebar.cpp index 1915e21..e4821ad 100644 --- a/src/gui/dialogs/qsidebar.cpp +++ b/src/gui/dialogs/qsidebar.cpp @@ -247,11 +247,16 @@ void QUrlModel::addUrls(const QList &list, int row, bool move) QUrl url = list.at(i); if (!url.isValid() || url.scheme() != QLatin1String("file")) continue; + //this makes sure the url is clean + const QString cleanUrl = QDir::cleanPath(url.toLocalFile()); + url = QUrl::fromLocalFile(cleanUrl); + for (int j = 0; move && j < rowCount(); ++j) { + QString local = index(j, 0).data(UrlRole).toUrl().toLocalFile(); #if defined(Q_OS_WIN) - if (QDir::cleanPath(index(j, 0).data(UrlRole).toUrl().toLocalFile()).toLower() == QDir::cleanPath(url.toLocalFile()).toLower()) { + if (index(j, 0).data(UrlRole).toUrl().toLocalFile().toLower() == cleanUrl.toLower()) { #else - if (QDir::cleanPath(index(j, 0).data(UrlRole).toUrl().toLocalFile()) == QDir::cleanPath(url.toLocalFile())) { + if (index(j, 0).data(UrlRole).toUrl().toLocalFile() == cleanUrl) { #endif removeRow(j); if (j <= row) @@ -260,12 +265,12 @@ void QUrlModel::addUrls(const QList &list, int row, bool move) } } row = qMax(row, 0); - QModelIndex idx = fileSystemModel->index(url.toLocalFile()); + QModelIndex idx = fileSystemModel->index(cleanUrl); if (!fileSystemModel->isDir(idx)) continue; insertRows(row, 1); setUrl(index(row, 0), url, idx); - watching.append(QPair(idx, url.toLocalFile())); + watching.append(qMakePair(idx, cleanUrl)); } } diff --git a/tests/auto/qfiledialog/tst_qfiledialog.cpp b/tests/auto/qfiledialog/tst_qfiledialog.cpp index 8bb81e7..50cab0e 100644 --- a/tests/auto/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/qfiledialog/tst_qfiledialog.cpp @@ -160,6 +160,7 @@ private slots: void task251321_sideBarHiddenEntries(); void task251341_sideBarRemoveEntries(); void task254490_selectFileMultipleTimes(); + void task257579_sideBarWithNonCleanUrls(); private: QByteArray userSettings; @@ -2026,5 +2027,25 @@ void tst_QFiledialog::task254490_selectFileMultipleTimes() t->deleteLater(); } +void tst_QFiledialog::task257579_sideBarWithNonCleanUrls() +{ + QDir tempDir = QDir::temp(); + QLatin1String dirname("autotest_task257579"); + tempDir.rmdir(dirname); //makes sure it doesn't exist any more + QVERIFY(tempDir.mkdir(dirname)); + QString url = QString::fromLatin1("%1/%2/..").arg(tempDir.absolutePath()).arg(dirname); + QNonNativeFileDialog fd; + fd.setSidebarUrls(QList() << QUrl::fromLocalFile(url)); + QSidebar *sidebar = qFindChild(&fd, "sidebar"); + QCOMPARE(sidebar->urls().count(), 1); + QVERIFY(sidebar->urls().first().toLocalFile() != url); + QCOMPARE(sidebar->urls().first().toLocalFile(), QDir::cleanPath(url)); + QCOMPARE(sidebar->model()->index(0,0).data().toString(), tempDir.dirName()); + + //all tests are finished, we can remove the temporary dir + QVERIFY(tempDir.rmdir(dirname)); +} + + QTEST_MAIN(tst_QFiledialog) #include "tst_qfiledialog.moc" -- cgit v0.12 From 9d073c3c92f732ec73587b0696e8994107a98402 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 10 Jul 2009 11:54:53 +0200 Subject: Fix compilation support with namespaces for QtLibcSupplement Reviewed-By: hjk --- src/corelib/kernel/qcore_unix_p.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index 1bf2425..8d43897 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -69,19 +69,19 @@ struct sockaddr; -QT_BEGIN_NAMESPACE - #if defined(Q_OS_LINUX) && defined(O_CLOEXEC) && defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0204 // Linux supports thread-safe FD_CLOEXEC # define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 1 +QT_BEGIN_NAMESPACE namespace QtLibcSupplement { Q_CORE_EXPORT int accept4(int, sockaddr *, QT_SOCKLEN_T *, int flags); Q_CORE_EXPORT int dup3(int oldfd, int newfd, int flags); Q_CORE_EXPORT int pipe2(int pipes[], int flags); } +QT_END_NAMESPACE +using namespace QT_PREPEND_NAMESPACE(QtLibcSupplement); -using namespace QtLibcSupplement; #else # define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 0 #endif @@ -91,6 +91,7 @@ using namespace QtLibcSupplement; var = cmd; \ } while (var == -1 && errno == EINTR) +QT_BEGIN_NAMESPACE // don't call QT_OPEN or ::open // call qt_safe_open -- cgit v0.12 From c1cf0eb65e87386d1875ed309e5c13cdc0f33e3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Fri, 10 Jul 2009 12:50:10 +0200 Subject: Painting artifacts when closing an embedded popup in Graphics View. Found during manual testing (demos/embeddeddialogs). The problem was that a full update (right before hiding/deleting an item) caused the update request made from the destructor to be discarded. Auto-test included. --- src/gui/graphicsview/qgraphicsitem.cpp | 7 ++-- .../tst_qgraphicsproxywidget.cpp | 39 ++++++++++++++++++++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 2f646f7..0cfaab7 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -4325,12 +4325,11 @@ bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreClipping, bool ignore { // No scene, or if the scene is updating everything, means we have nothing // to do. The only exception is if the scene tracks the growing scene rect. - return (!visible && !ignoreVisibleBit) + return !scene + || (!visible && !ignoreVisibleBit && !this->ignoreVisible) || (!ignoreDirtyBit && fullUpdatePending) - || !scene - || (scene->d_func()->updateAll && scene->d_func()->hasSceneRect) || (!ignoreClipping && (childrenClippedToShape() && isClippedAway())) - || (!ignoreOpacity && childrenCombineOpacity() && isFullyTransparent()); + || (!ignoreOpacity && !this->ignoreOpacity && childrenCombineOpacity() && isFullyTransparent()); } /*! diff --git a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp index 0b1d5cf..3b13bcc 100644 --- a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp +++ b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp @@ -178,6 +178,7 @@ private slots: void windowFlags_data(); void windowFlags(); void comboboxWindowFlags(); + void updateAndDelete(); }; // Subclass that exposes the protected functions. @@ -3217,6 +3218,44 @@ void tst_QGraphicsProxyWidget::comboboxWindowFlags() QVERIFY((static_cast(popupProxy)->windowFlags() & Qt::Popup) == Qt::Popup); } +void tst_QGraphicsProxyWidget::updateAndDelete() +{ + QGraphicsScene scene; + QGraphicsProxyWidget *proxy = scene.addWidget(new QPushButton("Hello World")); + View view(&scene); + view.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&view); +#endif + QTest::qWait(200); + + const QRect itemDeviceBoundingRect = proxy->deviceTransform(view.viewportTransform()) + .mapRect(proxy->boundingRect()).toRect(); + const QRegion expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2); + + view.npaints = 0; + view.paintEventRegion = QRegion(); + + // Update and hide. + proxy->update(); + proxy->hide(); + QTest::qWait(50); + QCOMPARE(view.npaints, 1); + QCOMPARE(view.paintEventRegion, expectedRegion); + + proxy->show(); + QTest::qWait(50); + view.npaints = 0; + view.paintEventRegion = QRegion(); + + // Update and delete. + proxy->update(); + delete proxy; + QTest::qWait(50); + QCOMPARE(view.npaints, 1); + QCOMPARE(view.paintEventRegion, expectedRegion); +} + QTEST_MAIN(tst_QGraphicsProxyWidget) #include "tst_qgraphicsproxywidget.moc" -- cgit v0.12 From b420385f15f109765fc31c5bcc5b4ea9498b82d4 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Fri, 10 Jul 2009 13:17:43 +0200 Subject: doc: Clarified that native messages are being handled. Task-number: 214026 --- src/corelib/kernel/qabstracteventdispatcher.cpp | 25 ++++++++------- src/corelib/kernel/qcoreapplication.cpp | 42 +++++++++++++++++-------- 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp index a98d005..e2682f5 100644 --- a/src/corelib/kernel/qabstracteventdispatcher.cpp +++ b/src/corelib/kernel/qabstracteventdispatcher.cpp @@ -398,20 +398,23 @@ void QAbstractEventDispatcher::closingDown() */ /*! - Sets the event filter \a filter. Returns a pointer to the filter - function previously defined. - - The event filter is a function that receives all messages taken - from the system event loop before the event is dispatched to the - respective target. This includes messages that are not sent to Qt + Replaces the event filter function for this + QAbstractEventDispatcher with \a filter and returns the replaced + event filter function. Only the current event filter function is + called. If you want to use both filter functions, save the + replaced EventFilter in a place where yours can call it. + + The event filter function set here is called for all messages + taken from the system event loop before the event is dispatched to + the respective target, including the messages not meant for Qt objects. - The function can return true to stop the event to be processed by - Qt, or false to continue with the standard event processing. + The event filter function should return true if the message should + be filtered, (i.e. stopped). It should return false to allow + processing the message to continue. - Only one filter can be defined, but the filter can use the return - value to call the previously set event filter. By default, no - filter is set (i.e. the function returns 0). + By default, no event filter function is set (i.e., this function + returns a null EventFilter the first time it is called). */ QAbstractEventDispatcher::EventFilter QAbstractEventDispatcher::setEventFilter(EventFilter filter) { diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 054be70..706dc54 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -2183,21 +2183,37 @@ void QCoreApplication::removeLibraryPath(const QString &path) /*! \fn EventFilter QCoreApplication::setEventFilter(EventFilter filter) - Sets the event filter \a filter. Returns a pointer to the filter - function previously defined. - - The event filter is a function that is called for every message - received in all threads. This does \e not include messages to + Replaces the event filter function for the QCoreApplication with + \a filter and returns the pointer to the replaced event filter + function. Only the current event filter function is called. If you + want to use both filter functions, save the replaced EventFilter + in a place where yours can call it. + + The event filter function set here is called for all messages + received by all threads meant for all Qt objects. It is \e not + called for messages that are not meant for Qt objects. + + The event filter function should return true if the message should + be filtered, (i.e. stopped). It should return false to allow + processing the message to continue. + + By default, no event filter function is set (i.e., this function + returns a null EventFilter the first time it is called). + + \note The filter function set here receives native messages, + i.e. MSG or XEvent structs, that are going to Qt objects. It is + called by QCoreApplication::filterEvent(). If the filter function + returns false to indicate the message should be processed further, + the native message can then be translated into a QEvent and + handled by the standard Qt \l{QEvent} {event} filering, e.g. + QObject::installEventFilter(). + + \note The filter function set here is different form the filter + function set via QAbstractEventDispatcher::setEventFilter(), which + gets all messages received by its thread, even messages meant for objects that are not handled by Qt. - The function can return true to stop the event to be processed by - Qt, or false to continue with the standard event processing. - - Only one filter can be defined, but the filter can use the return - value to call the previously set event filter. By default, no - filter is set (i.e., the function returns 0). - - \sa installEventFilter() + \sa QObject::installEventFilter(), QAbstractEventDispatcher::setEventFilter() */ QCoreApplication::EventFilter QCoreApplication::setEventFilter(QCoreApplication::EventFilter filter) -- cgit v0.12 From bc747a81f4f6f0978f71cd8d19f69060fc8a8041 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 10 Jul 2009 14:30:05 +0200 Subject: QMainWindow: it is useless to apply the stte after a call to plug The layoutState is already current (ie. already applied). --- src/gui/widgets/qmainwindowlayout.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp index 541907e..3936a67 100644 --- a/src/gui/widgets/qmainwindowlayout.cpp +++ b/src/gui/widgets/qmainwindowlayout.cpp @@ -1629,9 +1629,6 @@ void QMainWindowLayout::animationFinished(QWidget *widget) #ifndef QT_NO_DOCKWIDGET #ifndef QT_NO_TABBAR - //it is important to set the current tab before applying the layout - //so that applyState will not try to counter the result of the animation - //by putting the item in negative space if (qobject_cast(widget) != 0) { // info() might return null if the widget is destroyed while // animating but before the animationFinished signal is received. @@ -1641,8 +1638,6 @@ void QMainWindowLayout::animationFinished(QWidget *widget) #endif #endif - applyState(layoutState, false); - savedState.clear(); currentGapPos.clear(); pluggingWidget = 0; -- cgit v0.12 From e2bf5eeee12329ad4aee941b5bb70af4ee5bb32f Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 10 Jul 2009 15:30:01 +0200 Subject: QTableView: horizontal scrollbar could be inoperent with big columns Task-number: 240266 --- src/gui/itemviews/qtableview.cpp | 4 ++++ tests/auto/qtableview/tst_qtableview.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp index c676237..882a213 100644 --- a/src/gui/itemviews/qtableview.cpp +++ b/src/gui/itemviews/qtableview.cpp @@ -1528,6 +1528,8 @@ void QTableView::updateGeometries() ++columnsInViewport; } } + columnsInViewport = qMax(columnsInViewport, 1); //there must be always at least 1 column + if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) { const int visibleColumns = columnCount - d->horizontalHeader->hiddenSectionCount(); horizontalScrollBar()->setRange(0, visibleColumns - columnsInViewport); @@ -1554,6 +1556,8 @@ void QTableView::updateGeometries() ++rowsInViewport; } } + rowsInViewport = qMax(rowsInViewport, 1); //there must be always at least 1 row + if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) { const int visibleRows = rowCount - d->verticalHeader->hiddenSectionCount(); verticalScrollBar()->setRange(0, visibleRows - rowsInViewport); diff --git a/tests/auto/qtableview/tst_qtableview.cpp b/tests/auto/qtableview/tst_qtableview.cpp index ae023ba..0a69b75 100644 --- a/tests/auto/qtableview/tst_qtableview.cpp +++ b/tests/auto/qtableview/tst_qtableview.cpp @@ -175,6 +175,7 @@ private slots: // task-specific tests: void task173773_updateVerticalHeader(); void task227953_setRootIndex(); + void task240266_veryBigColumn(); void mouseWheel_data(); void mouseWheel(); @@ -3127,6 +3128,31 @@ void tst_QTableView::task227953_setRootIndex() QVERIFY(!tableView.verticalHeader()->isHidden()); } +void tst_QTableView::task240266_veryBigColumn() +{ + QTableView table; + table.setFixedSize(500, 300); //just to make sure we have the 2 first columns visible + QStandardItemModel model(1, 3); + table.setModel(&model); + table.setColumnWidth(0, 100); //normal column + table.setColumnWidth(1, 100); //normal column + table.setColumnWidth(2, 9000); //very big column + table.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&view); +#endif + QTest::qWait(100); + + QScrollBar *scroll = table.horizontalScrollBar(); + QCOMPARE(scroll->minimum(), 0); + QCOMPARE(scroll->maximum(), model.columnCount() - 1); + QCOMPARE(scroll->singleStep(), 1); + + //1 is not always a very correct value for pageStep. Ideally this should be dynamic. + //Maybe something for Qt 5 ;-) + QCOMPARE(scroll->pageStep(), 1); + +} void tst_QTableView::mouseWheel_data() { -- cgit v0.12 From 788b8ab3eed9314310408a577d797471d392d582 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 10 Jul 2009 15:46:13 +0200 Subject: adding autotest Task-number: 248688 --- tests/auto/qtableview/tst_qtableview.cpp | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/tests/auto/qtableview/tst_qtableview.cpp b/tests/auto/qtableview/tst_qtableview.cpp index 0a69b75..6fa57f0 100644 --- a/tests/auto/qtableview/tst_qtableview.cpp +++ b/tests/auto/qtableview/tst_qtableview.cpp @@ -176,6 +176,7 @@ private slots: void task173773_updateVerticalHeader(); void task227953_setRootIndex(); void task240266_veryBigColumn(); + void task248688_autoScrollNavigation(); void mouseWheel_data(); void mouseWheel(); @@ -587,7 +588,7 @@ void tst_QTableView::keyboardNavigation() QModelIndex index = model.index(rowCount - 1, columnCount - 1); view.setCurrentIndex(index); - QApplication::instance()->processEvents(); + QApplication::processEvents(); int row = rowCount - 1; int column = columnCount - 1; @@ -619,7 +620,7 @@ void tst_QTableView::keyboardNavigation() } QTest::keyClick(&view, key); - QApplication::instance()->processEvents(); + QApplication::processEvents(); QModelIndex index = model.index(row, column); QCOMPARE(view.currentIndex(), index); @@ -3154,6 +3155,31 @@ void tst_QTableView::task240266_veryBigColumn() } +void tst_QTableView::task248688_autoScrollNavigation() +{ + //we make sure that when navigating with the keyboard the view is correctly scrolled + //to the current item + QStandardItemModel model(16, 16); + QTableView view; + view.setModel(&model); + + view.hideColumn(8); + view.hideRow(8); + view.show(); + for (int r = 0; r < model.rowCount(); ++r) { + if (view.isRowHidden(r)) + continue; + for (int c = 0; c < model.columnCount(); ++c) { + if (view.isColumnHidden(c)) + continue; + QModelIndex index = model.index(r, c); + view.setCurrentIndex(index); + QVERIFY(view.viewport()->rect().contains(view.visualRect(index))); + } + } +} + + void tst_QTableView::mouseWheel_data() { QTest::addColumn("scrollMode"); -- cgit v0.12 From 7cca54d2bd7e8e42419210c499e27a1452447330 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 10 Jul 2009 16:02:24 +0200 Subject: QTableView: auto-scrolling could be broken by invisible sections Task-number: 248688 --- src/gui/itemviews/qtableview.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp index 882a213..2009499 100644 --- a/src/gui/itemviews/qtableview.cpp +++ b/src/gui/itemviews/qtableview.cpp @@ -2040,7 +2040,7 @@ void QTableView::scrollTo(const QModelIndex &index, ScrollHint hint) if (positionAtRight || hint == PositionAtCenter || positionAtLeft) { int hiddenSections = 0; if (d->horizontalHeader->sectionsHidden()) { - for (int s = horizontalIndex; s >= 0; --s) { + for (int s = horizontalIndex - 1; s >= 0; --s) { int column = d->horizontalHeader->logicalIndex(s); if (d->horizontalHeader->isSectionHidden(column)) ++hiddenSections; @@ -2095,7 +2095,7 @@ void QTableView::scrollTo(const QModelIndex &index, ScrollHint hint) if (hint == PositionAtBottom || hint == PositionAtCenter || hint == PositionAtTop) { int hiddenSections = 0; if (d->verticalHeader->sectionsHidden()) { - for (int s = verticalIndex; s >= 0; --s) { + for (int s = verticalIndex - 1; s >= 0; --s) { int row = d->verticalHeader->logicalIndex(s); if (d->verticalHeader->isSectionHidden(row)) ++hiddenSections; -- cgit v0.12 From 4ed3ee42bae92b0feb5c898e4f0fdf7d34e34108 Mon Sep 17 00:00:00 2001 From: Luc Devallonne Date: Fri, 10 Jul 2009 16:22:33 +0200 Subject: Tablet events get delivered to the widget where the tablet down happend. This is basically the Windows version of the bug fixed in change 82e825ed841bce324a6892fcbace03f9936d4f4f Merge-request: 855 Reviewed-by: Norwegian Rock Cat --- src/gui/kernel/qapplication_win.cpp | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index e26d82e..e0c62b7 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -2956,7 +2956,9 @@ bool QETWidget::translateMouseEvent(const MSG &msg) if (alienWidget && alienWidget->internalWinId()) alienWidget = 0; - if (type == QEvent::MouseMove || type == QEvent::NonClientAreaMouseMove) { + if (type == QEvent::MouseMove || type == QEvent::NonClientAreaMouseMove + || type == QEvent::TabletMove) { + if (!(state & Qt::MouseButtonMask)) qt_button_down = 0; #ifndef QT_NO_CURSOR @@ -3087,6 +3089,8 @@ bool QETWidget::translateMouseEvent(const MSG &msg) popupButtonFocus = popupChild; break; case QEvent::MouseButtonRelease: + case QEvent::TabletRelease: + releaseAfter = true; break; default: @@ -3446,13 +3450,34 @@ bool QETWidget::translateTabletEvent(const MSG &msg, PACKET *localPacketBuf, } QPoint globalPos(qRound(hiResGlobal.x()), qRound(hiResGlobal.y())); + if (t == QEvent::TabletPress) + { + qt_button_down = QApplication::widgetAt(globalPos); + } + // make sure the tablet event get's sent to the proper widget... - QWidget *w = QApplication::widgetAt(globalPos); + QWidget *w = 0; + if (qt_button_down) w = qt_button_down; // Pass it to the thing that's grabbed it. + else + w = QApplication::widgetAt(globalPos); if (!w) w = this; + + if (t == QEvent::TabletRelease) + { + if (qt_win_ignoreNextMouseReleaseEvent) { + qt_win_ignoreNextMouseReleaseEvent = false; + if (qt_button_down && qt_button_down->internalWinId() == autoCaptureWnd) { + releaseAutoCapture(); + qt_button_down = 0; + } + } + + } + QPoint localPos = w->mapFromGlobal(globalPos); #ifndef QT_NO_TABLETEVENT if (currentTabletPointer.currentDevice == QTabletEvent::Airbrush) { -- cgit v0.12 From 364aa2a21512d32f3f4271f438e3a6fa799c1e9e Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 10 Jul 2009 16:30:49 +0200 Subject: ItemViews: make the pixmap from drag and drop more efficient We don't need to draw all the items that are selected. We just need those whose rect intersects the one from the viewport. Task-number: 233342 --- src/gui/itemviews/qabstractitemview.cpp | 33 ++++++++++++++++++++------------- src/gui/itemviews/qabstractitemview_p.h | 2 +- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index dd84304..5f347dd 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -3883,28 +3883,35 @@ bool QAbstractItemViewPrivate::openEditor(const QModelIndex &index, QEvent *even QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes, QRect *r) const { + Q_ASSERT(r); Q_Q(const QAbstractItemView); - QRect rect = q->visualRect(indexes.at(0)); + QRect &rect = *r; + const QRect viewportRect = viewport->rect(); QList rects; + QModelIndexList paintedIndexes; for (int i = 0; i < indexes.count(); ++i) { - rects.append(q->visualRect(indexes.at(i))); - rect |= rects.at(i); + const QModelIndex &index = indexes.at(i); + const QRect current = q->visualRect(index); + if (current.intersects(viewportRect)) { + paintedIndexes += index; + rects += current; + rect |= current; + } } - rect = rect.intersected(viewport->rect()); - if (rect.width() <= 0 || rect.height() <= 0) + rect = rect.intersected(viewportRect); + if (rect.isEmpty()) return QPixmap(); - QImage image(rect.size(), QImage::Format_ARGB32_Premultiplied); - image.fill(0); - QPainter painter(&image); + QPixmap pixmap(rect.size()); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); QStyleOptionViewItemV4 option = viewOptionsV4(); option.state |= QStyle::State_Selected; - for (int j = 0; j < indexes.count(); ++j) { + for (int j = 0; j < paintedIndexes.count(); ++j) { + const QModelIndex ¤t = paintedIndexes.at(j); option.rect = QRect(rects.at(j).topLeft() - rect.topLeft(), rects.at(j).size()); - delegateForIndex(indexes.at(j))->paint(&painter, option, indexes.at(j)); + delegateForIndex(current)->paint(&painter, option, current); } - painter.end(); - if (r) *r = rect; - return QPixmap::fromImage(image); + return pixmap; } void QAbstractItemViewPrivate::selectAll(QItemSelectionModel::SelectionFlags command) diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index 00647f6..7443d50 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -221,7 +221,7 @@ public: void clearOrRemove(); void checkPersistentEditorFocus(); - QPixmap renderToPixmap(const QModelIndexList &indexes, QRect *r = 0) const; + QPixmap renderToPixmap(const QModelIndexList &indexes, QRect *r) const; inline QPoint offset() const { const Q_Q(QAbstractItemView); -- cgit v0.12 From 577b3d7efc56f23dcf2b377816caa7d1aa3c7f88 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Fri, 10 Jul 2009 16:36:53 +0200 Subject: Fix compilation on SnowLeopard On 64-bit an id (void *) is 64-bit also, so, it really should be a pointer, but I'll make it a 64-bit int for the time being just so stuff compiles. --- src/gui/kernel/qmultitouch_mac.mm | 6 +++--- src/gui/kernel/qmultitouch_mac_p.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gui/kernel/qmultitouch_mac.mm b/src/gui/kernel/qmultitouch_mac.mm index 3fe85a9..3d2eae6 100644 --- a/src/gui/kernel/qmultitouch_mac.mm +++ b/src/gui/kernel/qmultitouch_mac.mm @@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE #ifdef QT_MAC_USE_COCOA -QHash QCocoaTouch::_currentTouches; +QHash QCocoaTouch::_currentTouches; QPointF QCocoaTouch::_screenReferencePos; QPointF QCocoaTouch::_trackpadReferencePos; int QCocoaTouch::_idAssignmentCount = 0; @@ -62,7 +62,7 @@ QCocoaTouch::QCocoaTouch(NSTouch *nstouch) _touchPoint.setId(_idAssignmentCount++); _touchPoint.setPressure(1.0); - _identity = int([nstouch identity]); + _identity = qint64([nstouch identity]); _currentTouches.insert(_identity, this); updateTouchData(nstouch, NSTouchPhaseBegan); } @@ -100,7 +100,7 @@ void QCocoaTouch::updateTouchData(NSTouch *nstouch, NSTouchPhase phase) QCocoaTouch *QCocoaTouch::findQCocoaTouch(NSTouch *nstouch) { - int identity = int([nstouch identity]); + qint64 identity = qint64([nstouch identity]); if (_currentTouches.contains(identity)) return _currentTouches.value(identity); return 0; diff --git a/src/gui/kernel/qmultitouch_mac_p.h b/src/gui/kernel/qmultitouch_mac_p.h index 3fa8f6c..618e9ca 100644 --- a/src/gui/kernel/qmultitouch_mac_p.h +++ b/src/gui/kernel/qmultitouch_mac_p.h @@ -74,7 +74,7 @@ class QCocoaTouch static void setMouseInDraggingState(bool inDraggingState); private: - static QHash _currentTouches; + static QHash _currentTouches; static QPointF _screenReferencePos; static QPointF _trackpadReferencePos; static int _idAssignmentCount; @@ -82,7 +82,7 @@ class QCocoaTouch static bool _updateInternalStateOnly; QTouchEvent::TouchPoint _touchPoint; - int _identity; + qint64 _identity; QCocoaTouch(NSTouch *nstouch); ~QCocoaTouch(); -- cgit v0.12 From 3384aea1357a0f2e7c633701f467d5f8b0855c50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Fri, 10 Jul 2009 16:42:08 +0200 Subject: Fixes broken item-lookup for untransformable items. Found during manual testing (manualtests/graphicsview/untransformable). At some point it was not possible to click on an untransformable item. The problem was that none of the untransformable items were top-levels, and none of the transformable top-level items were in the same area, resulting in an empty list of estimated top-level items. Auto-test included. --- .../graphicsview/qgraphicsscenebsptreeindex.cpp | 7 ++- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 51 ++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index a7b4828..a54ade9 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -387,8 +387,13 @@ QList QGraphicsSceneBspTreeIndexPrivate::estimateItems(const QR if (onlyTopLevelItems) { for (int i = 0; i < untransformableItems.size(); ++i) { QGraphicsItem *item = untransformableItems.at(i); - if (!item->d_ptr->parent) + if (!item->d_ptr->parent) { rectItems << item; + } else { + item = item->topLevelItem(); + if (!rectItems.contains(item)) + rectItems << item; + } } } else { rectItems += untransformableItems; diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 2dbd5f1..4e669ae 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -231,6 +231,7 @@ private slots: void sorting_data(); void sorting(); void itemHasNoContents(); + void hitTestUntransformableItem(); // task specific tests below me void task141694_textItemEnsureVisible(); @@ -7131,5 +7132,55 @@ void tst_QGraphicsItem::itemHasNoContents() QCOMPARE(_paintedItems, QList() << item2); } +void tst_QGraphicsItem::hitTestUntransformableItem() +{ + QGraphicsScene scene; + scene.setSceneRect(-100, -100, 200, 200); + + QGraphicsView view(&scene); + view.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&view); +#endif + QTest::qWait(100); + + // Confuse the BSP with dummy items. + QGraphicsRectItem *dummy = new QGraphicsRectItem(0, 0, 20, 20); + dummy->setPos(-100, -100); + scene.addItem(dummy); + for (int i = 0; i < 100; ++i) { + QGraphicsItem *parent = dummy; + dummy = new QGraphicsRectItem(0, 0, 20, 20); + dummy->setPos(-100 + i, -100 + i); + dummy->setParentItem(parent); + } + + QGraphicsRectItem *item1 = new QGraphicsRectItem(0, 0, 20, 20); + item1->setPos(-200, -200); + + QGraphicsRectItem *item2 = new QGraphicsRectItem(0, 0, 20, 20); + item2->setFlag(QGraphicsItem::ItemIgnoresTransformations); + item2->setParentItem(item1); + item2->setPos(200, 200); + + QGraphicsRectItem *item3 = new QGraphicsRectItem(0, 0, 20, 20); + item3->setParentItem(item2); + item3->setPos(80, 80); + + scene.addItem(item1); + QTest::qWait(100); + + QList items = scene.items(QPointF(80, 80)); + QCOMPARE(items.size(), 1); + QCOMPARE(items.at(0), static_cast(item3)); + + scene.setItemIndexMethod(QGraphicsScene::NoIndex); + QTest::qWait(100); + + items = scene.items(QPointF(80, 80)); + QCOMPARE(items.size(), 1); + QCOMPARE(items.at(0), static_cast(item3)); +} + QTEST_MAIN(tst_QGraphicsItem) #include "tst_qgraphicsitem.moc" -- cgit v0.12 From 4d31527417419d4f7c1417b9360ef91d72469aa0 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 10 Jul 2009 17:13:06 +0200 Subject: QListView: improve performance on QListView::selectedIndexes Task-number: 233342 --- src/gui/itemviews/qlistview.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp index 4652b91..6ff516a 100644 --- a/src/gui/itemviews/qlistview.cpp +++ b/src/gui/itemviews/qlistview.cpp @@ -1633,14 +1633,16 @@ QRegion QListView::visualRegionForSelection(const QItemSelection &selection) con QModelIndexList QListView::selectedIndexes() const { Q_D(const QListView); - QModelIndexList viewSelected; - QModelIndexList modelSelected; - if (d->selectionModel) - modelSelected = d->selectionModel->selectedIndexes(); - for (int i = 0; i < modelSelected.count(); ++i) { - QModelIndex index = modelSelected.at(i); + if (!d->selectionModel) + return QModelIndexList(); + + QModelIndexList viewSelected = d->selectionModel->selectedIndexes(); + for (int i = 0; i < viewSelected.count(); ++i) { + const QModelIndex &index = viewSelected.at(i); if (!isIndexHidden(index) && index.parent() == d->root && index.column() == d->column) - viewSelected.append(index); + ++i; + else + viewSelected.removeAt(i); } return viewSelected; } -- cgit v0.12 From 5425853ec6a9f29af3378c982f12a0cca4bcb0e0 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 10 Jul 2009 14:46:44 +0200 Subject: make tests independent of PATH contents use absolute paths for the tested executables --- tests/auto/linguist/lconvert/tst_lconvert.cpp | 9 +++++---- tests/auto/linguist/lrelease/tst_lrelease.cpp | 16 +++++++++++----- tests/auto/linguist/lupdate/testlupdate.cpp | 5 +++-- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/tests/auto/linguist/lconvert/tst_lconvert.cpp b/tests/auto/linguist/lconvert/tst_lconvert.cpp index 40be55a..3ad2925 100644 --- a/tests/auto/linguist/lconvert/tst_lconvert.cpp +++ b/tests/auto/linguist/lconvert/tst_lconvert.cpp @@ -47,7 +47,7 @@ class tst_lconvert : public QObject Q_OBJECT public: - tst_lconvert() : dataDir("data/") {} + tst_lconvert() : dataDir("data/"), binDir(QLibraryInfo::location(QLibraryInfo::BinariesPath)) {} private slots: void initTestCase(); @@ -73,6 +73,7 @@ private: const QList &args); QString dataDir; + QString binDir; }; void tst_lconvert::initTestCase() @@ -151,7 +152,7 @@ void tst_lconvert::doCompare(QIODevice *actualDev, const QString &expectedFn) void tst_lconvert::verifyReadFail(const QString &fn) { QProcess cvt; - cvt.start("lconvert", QStringList() << (dataDir + fn)); + cvt.start(binDir + "/lconvert", QStringList() << (dataDir + fn)); QVERIFY(cvt.waitForFinished(1000)); QVERIFY(cvt.exitStatus() == QProcess::NormalExit); QVERIFY2(cvt.exitCode() == 2, "Accepted invalid input"); @@ -178,7 +179,7 @@ void tst_lconvert::convertChain(const QString &_inFileName, const QString &_outF if (!argList.isEmpty()) args += argList[i]; args << "-if" << stations[i] << "-i" << "-" << "-of" << stations[i + 1]; - cvts.at(i)->start("lconvert", args); + cvts.at(i)->start(binDir + "/lconvert", args); } int st = 0; foreach (QProcess *cvt, cvts) @@ -242,7 +243,7 @@ void tst_lconvert::converts() QString outFileNameFq = dataDir + outFileName; QProcess cvt; - cvt.start("lconvert", QStringList() << "-i" << (dataDir + inFileName) << "-of" << format); + cvt.start(binDir + "/lconvert", QStringList() << "-i" << (dataDir + inFileName) << "-of" << format); doWait(&cvt, 0); if (QTest::currentTestFailed()) return; diff --git a/tests/auto/linguist/lrelease/tst_lrelease.cpp b/tests/auto/linguist/lrelease/tst_lrelease.cpp index 512987d..858e477 100644 --- a/tests/auto/linguist/lrelease/tst_lrelease.cpp +++ b/tests/auto/linguist/lrelease/tst_lrelease.cpp @@ -49,6 +49,10 @@ class tst_lrelease : public QObject { Q_OBJECT + +public: + tst_lrelease() : binDir(QLibraryInfo::location(QLibraryInfo::BinariesPath)) {} + private: private slots: @@ -59,6 +63,8 @@ private slots: private: void doCompare(const QStringList &actual, const QString &expectedFn); + + QString binDir; }; void tst_lrelease::doCompare(const QStringList &actual, const QString &expectedFn) @@ -111,7 +117,7 @@ void tst_lrelease::doCompare(const QStringList &actual, const QString &expectedF void tst_lrelease::translate() { - QVERIFY(!QProcess::execute("lrelease testdata/translate.ts")); + QVERIFY(!QProcess::execute(binDir + "/lrelease testdata/translate.ts")); QTranslator translator; QVERIFY(translator.load("testdata/translate.qm")); @@ -161,8 +167,8 @@ void tst_lrelease::translate() void tst_lrelease::mixedcodecs() { - QVERIFY(!QProcess::execute("lrelease testdata/mixedcodecs-ts11.ts")); - QVERIFY(!QProcess::execute("lrelease testdata/mixedcodecs-ts20.ts")); + QVERIFY(!QProcess::execute(binDir + "/lrelease testdata/mixedcodecs-ts11.ts")); + QVERIFY(!QProcess::execute(binDir + "/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")); @@ -176,7 +182,7 @@ void tst_lrelease::mixedcodecs() void tst_lrelease::compressed() { - QVERIFY(!QProcess::execute("lrelease -compress testdata/compressed.ts")); + QVERIFY(!QProcess::execute(binDir + "/lrelease -compress testdata/compressed.ts")); QTranslator translator; QVERIFY(translator.load("testdata/compressed.qm")); @@ -194,7 +200,7 @@ void tst_lrelease::compressed() void tst_lrelease::dupes() { QProcess proc; - proc.start("lrelease testdata/dupes.ts"); + proc.start(binDir + "/lrelease testdata/dupes.ts"); QVERIFY(proc.waitForFinished()); QVERIFY(proc.exitStatus() == QProcess::NormalExit); doCompare(QString(proc.readAllStandardError()).trimmed().remove('\r').split('\n'), "testdata/dupes.errors"); diff --git a/tests/auto/linguist/lupdate/testlupdate.cpp b/tests/auto/linguist/lupdate/testlupdate.cpp index 8abc2b0..04c03f1 100644 --- a/tests/auto/linguist/lupdate/testlupdate.cpp +++ b/tests/auto/linguist/lupdate/testlupdate.cpp @@ -56,8 +56,9 @@ TestLUpdate::TestLUpdate() { childProc = 0; - m_cmdLupdate = QLatin1String("lupdate"); - m_cmdQMake = QLatin1String("qmake"); + QString binPath = QLibraryInfo::location(QLibraryInfo::BinariesPath); + m_cmdLupdate = binPath + QLatin1String("/lupdate"); + m_cmdQMake = binPath + QLatin1String("/qmake"); } TestLUpdate::~TestLUpdate() -- cgit v0.12 From 593f8a322895dc011d88fbe112987f2189d43724 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 10 Jul 2009 18:05:30 +0200 Subject: rewrite makeplurals.sh in perl ... so it works under windows as well. --- tests/auto/linguist/lconvert/data/makeplurals.pl | 42 +++++++++++++++++++++++ tests/auto/linguist/lconvert/data/makeplurals.sh | 43 ------------------------ tests/auto/linguist/lconvert/tst_lconvert.cpp | 2 +- 3 files changed, 43 insertions(+), 44 deletions(-) create mode 100755 tests/auto/linguist/lconvert/data/makeplurals.pl delete mode 100755 tests/auto/linguist/lconvert/data/makeplurals.sh diff --git a/tests/auto/linguist/lconvert/data/makeplurals.pl b/tests/auto/linguist/lconvert/data/makeplurals.pl new file mode 100755 index 0000000..19bffe0 --- /dev/null +++ b/tests/auto/linguist/lconvert/data/makeplurals.pl @@ -0,0 +1,42 @@ +#! /usr/bin/env perl + +sub makeit2($$$) +{ + for (my $i = 0; $i < (1 << $_[0]); $i++) { + print OUTFILE "\n"; + print OUTFILE "$_[2]\n" unless $3 eq ""; + print OUTFILE "msgid \"singular $_[1] $i\"\n"; + print OUTFILE "msgid_plural \"plural $_[1] $i\"\n"; + for (my $j = 0; $j < $_[0]; $j++) { + my $tr; + if (($i & (1 << $j)) == 0) { + $tr = "translated $_[1] $i $j"; + } + print OUTFILE "msgstr[$j] \"$tr\"\n"; + } + } +} + +sub makeit($$) +{ + open OUTFILE, ">${OUTDIR}plural-$_[0].po" || die "cannot write file in $OUTDIR"; + print OUTFILE < ${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/tst_lconvert.cpp b/tests/auto/linguist/lconvert/tst_lconvert.cpp index 3ad2925..1ed71ab 100644 --- a/tests/auto/linguist/lconvert/tst_lconvert.cpp +++ b/tests/auto/linguist/lconvert/tst_lconvert.cpp @@ -79,7 +79,7 @@ private: void tst_lconvert::initTestCase() { if (!QFile::exists(QLatin1String("data/plural-1.po"))) - QProcess::execute(QLatin1String("data/makeplurals.sh"), QStringList() << QLatin1String("data/")); + QProcess::execute(QLatin1String("perl"), QStringList() << QLatin1String("data/makeplurals.pl") << QLatin1String("data/")); QVERIFY(QFile::exists(QLatin1String("data/plural-1.po"))); } -- cgit v0.12 From 435fae071798817f57bc89bf5d1ac20aae488625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Fri, 10 Jul 2009 18:14:48 +0200 Subject: QGraphicsItem not updated properly when moving parent. Found during manual testing (manualtests/graphicsview/movableitems). Moving a child item (via its parent) outside the viewport, and then back again didn't trigger an update on the child. Reason was that we had a cut-off checking the wrong bit (geometryChanged). This bit means exactly the same as the paintedViewBoundingRectsNeedRepaint bit, except that it doesn't propagate to the children (and that's the bug). We use paintedViewBoundingRectsNeedRepaint instead. Auto-test included. --- src/gui/graphicsview/qgraphicsitem.cpp | 1 + src/gui/graphicsview/qgraphicsscene.cpp | 4 ++-- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 33 +++++++++++++++++++++++--- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 0cfaab7..b7385d4 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1822,6 +1822,7 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo q_ptr->setSelected(false); } else { geometryChanged = 1; + paintedViewBoundingRectsNeedRepaint = 1; if (isWidget && scene) { QGraphicsWidget *widget = static_cast(q_ptr); if (widget->windowType() == Qt::Popup) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index c7c0865..aa7fa4c 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4568,7 +4568,7 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool if (!item->d_ptr->dirty) continue; - if (!item->d_ptr->geometryChanged + if (!item->d_ptr->paintedViewBoundingRectsNeedRepaint && paintedViewBoundingRect.x() == -1 && paintedViewBoundingRect.y() == -1 && paintedViewBoundingRect.width() == -1 && paintedViewBoundingRect.height() == -1) { continue; // Outside viewport. @@ -4587,7 +4587,7 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool continue; // Discard updates outside the bounding rect. if (!updateHelper(viewPrivate, item->d_ptr, dirtyRect, itemIsUntransformable) - && item->d_ptr->geometryChanged) { + && item->d_ptr->paintedViewBoundingRectsNeedRepaint) { paintedViewBoundingRect = QRect(-1, -1, -1, -1); // Outside viewport. } } diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 4e669ae..4ca1b48 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -6614,9 +6614,9 @@ void tst_QGraphicsItem::update() qApp->processEvents(); QCOMPARE(item->repaints, 1); QCOMPARE(view.repaints, 1); - const QRect itemDeviceBoundingRect = item->deviceTransform(view.viewportTransform()) - .mapRect(item->boundingRect()).toRect(); - const QRegion expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2); + QRect itemDeviceBoundingRect = item->deviceTransform(view.viewportTransform()) + .mapRect(item->boundingRect()).toRect(); + QRegion expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2); // The entire item's bounding rect (adjusted for antialiasing) should have been painted. QCOMPARE(view.paintedRegion, expectedRegion); @@ -6684,6 +6684,33 @@ void tst_QGraphicsItem::update() QCOMPARE(item->repaints, 1); QCOMPARE(view.repaints, 1); QCOMPARE(view.paintedRegion, expectedRegion + expectedRegion.translated(50, 50)); + + // Make sure moving a parent item triggers an update on the children + // (even though the parent itself is outside the viewport). + QGraphicsRectItem *parent = new QGraphicsRectItem(0, 0, 10, 10); + parent->setPos(-400, 0); + item->setParentItem(parent); + item->setPos(400, 0); + scene.addItem(parent); + QTest::qWait(50); + itemDeviceBoundingRect = item->deviceTransform(view.viewportTransform()) + .mapRect(item->boundingRect()).toRect(); + expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2); + view.reset(); + item->repaints = 0; + parent->translate(-400, 0); + qApp->processEvents(); + QCOMPARE(item->repaints, 0); + QCOMPARE(view.repaints, 1); + QCOMPARE(view.paintedRegion, expectedRegion); + view.reset(); + item->repaints = 0; + parent->translate(400, 0); + qApp->processEvents(); + QCOMPARE(item->repaints, 1); + QCOMPARE(view.repaints, 1); + QCOMPARE(view.paintedRegion, expectedRegion); + QCOMPARE(view.paintedRegion, expectedRegion); } void tst_QGraphicsItem::setTransformProperties_data() -- cgit v0.12 From baacf493e1c968ee2ffa59a8b87754388cb7a61a Mon Sep 17 00:00:00 2001 From: Pierre Rossi Date: Fri, 10 Jul 2009 19:15:25 +0200 Subject: Fixed a crash with input methods The inputContext's focusWidget was not reset when disabling input methods. Thanks to Benjamin P. Task-number: 257832 Reviewed-by: Denis --- src/gui/kernel/qapplication.cpp | 2 +- src/gui/kernel/qwidget.cpp | 7 ++----- tests/auto/qwidget/tst_qwidget.cpp | 15 +++++++++++++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index c6af728..114ebb2 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -126,7 +126,7 @@ int QApplicationPrivate::app_compile_version = 0x040000; //we don't know exactly QApplication::Type qt_appType=QApplication::Tty; QApplicationPrivate *QApplicationPrivate::self = 0; -QInputContext *QApplicationPrivate::inputContext; +QInputContext *QApplicationPrivate::inputContext = 0; bool QApplicationPrivate::quitOnLastWindowClosed = true; diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 9d40b00..fb9084e 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -9879,11 +9879,8 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) QInputContextPrivate::updateImeStatus(this, true); #endif QInputContext *ic = d->ic; - if (!ic) { - // implicitly create input context only if we have a focus - if (hasFocus()) - ic = d->inputContext(); - } + if (!ic && (!on || hasFocus())) + ic = d->inputContext(); if (ic) { if (on && hasFocus() && ic->focusWidget() != this) { ic->setFocusWidget(this); diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 7b68732..1db6eb2 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -350,6 +350,7 @@ private slots: #endif void updateOnDestroyedSignal(); void toplevelLineEditFocus(); + void inputFocus_task257832(); private: bool ensureScreenSize(int width, int height); @@ -8965,5 +8966,19 @@ void tst_QWidget::toplevelLineEditFocus() QCOMPARE(QApplication::focusWidget(), &w); } +void tst_QWidget::inputFocus_task257832() +{ + QLineEdit *widget = new QLineEdit; + QInputContext *context = widget->inputContext(); + if (!context) + QSKIP("No input context", SkipSingle); + widget->setFocus(); + context->setFocusWidget(widget); + QCOMPARE(context->focusWidget(), widget); + widget->setReadOnly(true); + QVERIFY(!context->focusWidget()); + delete widget; +} + QTEST_MAIN(tst_QWidget) #include "tst_qwidget.moc" -- cgit v0.12 From 3ded2e1ea5a74a6fc0d3938fa732f886aa275ca2 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Fri, 10 Jul 2009 20:27:42 +0200 Subject: Remove builtin xml schema file until legal issues are clarified --- src/xmlpatterns/schema/builtinschemas.qrc | 1 - src/xmlpatterns/schema/schemas/xml.xsd | 145 ------------------------------ 2 files changed, 146 deletions(-) delete mode 100644 src/xmlpatterns/schema/schemas/xml.xsd diff --git a/src/xmlpatterns/schema/builtinschemas.qrc b/src/xmlpatterns/schema/builtinschemas.qrc index fb43d78..4ca9cd5 100644 --- a/src/xmlpatterns/schema/builtinschemas.qrc +++ b/src/xmlpatterns/schema/builtinschemas.qrc @@ -1,5 +1,4 @@ - schemas/xml.xsd diff --git a/src/xmlpatterns/schema/schemas/xml.xsd b/src/xmlpatterns/schema/schemas/xml.xsd deleted file mode 100644 index eeb9db5..0000000 --- a/src/xmlpatterns/schema/schemas/xml.xsd +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - See http://www.w3.org/XML/1998/namespace.html and - http://www.w3.org/TR/REC-xml for information about this namespace. - - This schema document describes the XML namespace, in a form - suitable for import by other schema documents. - - Note that local names in this namespace are intended to be defined - only by the World Wide Web Consortium or its subgroups. The - following names are currently defined in this namespace and should - not be used with conflicting semantics by any Working Group, - specification, or document instance: - - base (as an attribute name): denotes an attribute whose value - provides a URI to be used as the base for interpreting any - relative URIs in the scope of the element on which it - appears; its value is inherited. This name is reserved - by virtue of its definition in the XML Base specification. - - id (as an attribute name): denotes an attribute whose value - should be interpreted as if declared to be of type ID. - This name is reserved by virtue of its definition in the - xml:id specification. - - lang (as an attribute name): denotes an attribute whose value - is a language code for the natural language of the content of - any element; its value is inherited. This name is reserved - by virtue of its definition in the XML specification. - - space (as an attribute name): denotes an attribute whose - value is a keyword indicating what whitespace processing - discipline is intended for the content of the element; its - value is inherited. This name is reserved by virtue of its - definition in the XML specification. - - Father (in any context at all): denotes Jon Bosak, the chair of - the original XML Working Group. This name is reserved by - the following decision of the W3C XML Plenary and - XML Coordination groups: - - In appreciation for his vision, leadership and dedication - the W3C XML Plenary on this 10th day of February, 2000 - reserves for Jon Bosak in perpetuity the XML name - xml:Father - - - - - This schema defines attributes and an attribute group - suitable for use by - schemas wishing to allow xml:base, xml:lang, xml:space or xml:id - attributes on elements they define. - - To enable this, such a schema must import this schema - for the XML namespace, e.g. as follows: - <schema . . .> - . . . - <import namespace="http://www.w3.org/XML/1998/namespace" - schemaLocation="http://www.w3.org/2001/xml.xsd"/> - - Subsequently, qualified reference to any of the attributes - or the group defined below will have the desired effect, e.g. - - <type . . .> - . . . - <attributeGroup ref="xml:specialAttrs"/> - - will define a type which will schema-validate an instance - element with any of those attributes - - - - In keeping with the XML Schema WG's standard versioning - policy, this schema document will persist at - http://www.w3.org/2007/08/xml.xsd. - At the date of issue it can also be found at - http://www.w3.org/2001/xml.xsd. - The schema document at that URI may however change in the future, - in order to remain compatible with the latest version of XML Schema - itself, or with the XML namespace itself. In other words, if the XML - Schema or XML namespaces change, the version of this document at - http://www.w3.org/2001/xml.xsd will change - accordingly; the version at - http://www.w3.org/2007/08/xml.xsd will not change. - - - - - - Attempting to install the relevant ISO 2- and 3-letter - codes as the enumerated possible values is probably never - going to be a realistic possibility. See - RFC 3066 at http://www.ietf.org/rfc/rfc3066.txt and the IANA registry - at http://www.iana.org/assignments/lang-tag-apps.htm for - further information. - - The union allows for the 'un-declaration' of xml:lang with - the empty string. - - - - - - - - - - - - - - - - - - - - - - - - See http://www.w3.org/TR/xmlbase/ for - information about this attribute. - - - - - - See http://www.w3.org/TR/xml-id/ for - information about this attribute. - - - - - - - - - - - -- cgit v0.12 From 357d4598512b4b42fc515b4fc0d2d419db604544 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 11 May 2009 17:35:20 +0200 Subject: remove dead code cherry-picked d8b1cc5f0ecbb8de734d241d72a05b325c2bbb2c from creator --- tools/linguist/shared/profileevaluator.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tools/linguist/shared/profileevaluator.cpp b/tools/linguist/shared/profileevaluator.cpp index 8605733..c68ac46 100644 --- a/tools/linguist/shared/profileevaluator.cpp +++ b/tools/linguist/shared/profileevaluator.cpp @@ -1511,16 +1511,6 @@ bool ProFileEvaluator::Private::evaluateFile(const QString &fileName, bool *resu if (result) *result = false; } -/* if (ok && readFeatures) { - QStringList configs = values("CONFIG"); - QSet processed; - foreach (const QString &fn, configs) { - if (!processed.contains(fn)) { - processed.insert(fn); - evaluateFeatureFile(fn, 0); - } - } - } */ return ok; } -- cgit v0.12 From b7cfdc075ce53a5aaf243161c849ee1ee079885c Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 12 May 2009 15:02:32 +0200 Subject: remove totally pointless conditional cherry-picked 167a09b20614d282ec898f69fc2a3f0bafa11229 from creator --- tools/linguist/shared/profileevaluator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/linguist/shared/profileevaluator.cpp b/tools/linguist/shared/profileevaluator.cpp index c68ac46..c56f1d4 100644 --- a/tools/linguist/shared/profileevaluator.cpp +++ b/tools/linguist/shared/profileevaluator.cpp @@ -1501,7 +1501,7 @@ bool ProFileEvaluator::Private::evaluateFile(const QString &fileName, bool *resu ProFile *pro = q->parsedProFile(fileName); if (pro) { m_profileStack.push(pro); - ok = (currentProFile() ? pro->Accept(this) : false); + ok = pro->Accept(this); m_profileStack.pop(); q->releaseParsedProFile(pro); -- cgit v0.12 From 3f9a894acb30ff3fb5907f82327af088f96a088d Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 4 Jun 2009 15:18:14 +0200 Subject: Fix memory leak in $$system() calls from .pro files cherry-picked 07730341bd739aac823ac9b4336d8294510a35e2 from creator --- tools/linguist/shared/profileevaluator.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/linguist/shared/profileevaluator.cpp b/tools/linguist/shared/profileevaluator.cpp index c56f1d4..4ea9c10 100644 --- a/tools/linguist/shared/profileevaluator.cpp +++ b/tools/linguist/shared/profileevaluator.cpp @@ -58,8 +58,10 @@ #ifdef Q_OS_WIN32 #define QT_POPEN _popen +#define QT_PCLOSE _pclose #else #define QT_POPEN popen +#define QT_PCLOSE pclose #endif QT_BEGIN_NAMESPACE @@ -1204,6 +1206,8 @@ QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &fun output += QLatin1String(buff); } ret += split_value_list(output); + if (proc) + QT_PCLOSE(proc); } } break; } -- cgit v0.12 From a701175aef8912b69afe61d23749dcfca765a231 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Sat, 11 Jul 2009 16:56:28 +0200 Subject: ItemViews: make dragging faster when lots of items are selected QListView know exactly what they have on their viewport and we only paint items clipped to the viewport. So we don't need to ask for each item its visualRect. NB: QTreeView and QTableView probably deservee the same treatment --- src/gui/itemviews/qabstractitemview.cpp | 33 ++++++++++++++++++++++----------- src/gui/itemviews/qabstractitemview_p.h | 5 +++++ src/gui/itemviews/qlistview.cpp | 26 ++++++++++++++++++++++++++ src/gui/itemviews/qlistview_p.h | 2 ++ 4 files changed, 55 insertions(+), 11 deletions(-) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index 5f347dd..a4a69c3 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -3881,34 +3881,45 @@ bool QAbstractItemViewPrivate::openEditor(const QModelIndex &index, QEvent *even return true; } -QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes, QRect *r) const +/* + \internal + + returns the pair QRect/QModelIndex that should be painted on the viewports's rect + */ + +QItemViewPaintPairs QAbstractItemViewPrivate::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const { Q_ASSERT(r); Q_Q(const QAbstractItemView); QRect &rect = *r; const QRect viewportRect = viewport->rect(); - QList rects; - QModelIndexList paintedIndexes; + QItemViewPaintPairs ret; for (int i = 0; i < indexes.count(); ++i) { const QModelIndex &index = indexes.at(i); const QRect current = q->visualRect(index); if (current.intersects(viewportRect)) { - paintedIndexes += index; - rects += current; + ret += qMakePair(current, index); rect |= current; } } - rect = rect.intersected(viewportRect); - if (rect.isEmpty()) + rect &= viewportRect; + return ret; +} + +QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes, QRect *r) const +{ + Q_ASSERT(r); + QItemViewPaintPairs paintPairs = draggablePaintPairs(indexes, r); + if (paintPairs.isEmpty()) return QPixmap(); - QPixmap pixmap(rect.size()); + QPixmap pixmap(r->size()); pixmap.fill(Qt::transparent); QPainter painter(&pixmap); QStyleOptionViewItemV4 option = viewOptionsV4(); option.state |= QStyle::State_Selected; - for (int j = 0; j < paintedIndexes.count(); ++j) { - const QModelIndex ¤t = paintedIndexes.at(j); - option.rect = QRect(rects.at(j).topLeft() - rect.topLeft(), rects.at(j).size()); + for (int j = 0; j < paintPairs.count(); ++j) { + option.rect = paintPairs.at(j).first.translated(r->topLeft()); + const QModelIndex ¤t = paintPairs.at(j).second; delegateForIndex(current)->paint(&painter, option, current); } return pixmap; diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index 7443d50..557e98b 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -86,6 +86,9 @@ struct QEditorInfo }; +typedef QPair QItemViewPaintPair; +typedef QList QItemViewPaintPairs; + class QEmptyModel : public QAbstractItemModel { public: @@ -176,7 +179,9 @@ public: q_func()->style()->drawPrimitive(QStyle::PE_IndicatorItemViewItemDrop, &opt, painter, q_func()); } } + #endif + virtual QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const; inline void releaseEditor(QWidget *editor) const { if (editor) { diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp index 6ff516a..44bcf6f 100644 --- a/src/gui/itemviews/qlistview.cpp +++ b/src/gui/itemviews/qlistview.cpp @@ -709,6 +709,32 @@ void QListViewPrivate::selectAll(QItemSelectionModel::SelectionFlags command) selectionModel->select(selection, command); } +/*! + \reimp + + We have a QListView way of knowing what elements are on the viewport + through the intersectingSet function +*/ +QItemViewPaintPairs QListViewPrivate::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const +{ + Q_ASSERT(r); + Q_Q(const QListView); + QRect &rect = *r; + const QRect viewportRect = viewport->rect(); + QItemViewPaintPairs ret; + intersectingSet(viewportRect); + const QSet visibleIndexes = intersectVector.toList().toSet(); + for (int i = 0; i < indexes.count(); ++i) { + const QModelIndex &index = indexes.at(i); + if (visibleIndexes.contains(index)) { + const QRect current = q->visualRect(index); + ret += qMakePair(current, index); + rect |= current; + } + } + rect &= viewportRect; + return ret; +} /*! \internal diff --git a/src/gui/itemviews/qlistview_p.h b/src/gui/itemviews/qlistview_p.h index a7a7000..16f2de9 100644 --- a/src/gui/itemviews/qlistview_p.h +++ b/src/gui/itemviews/qlistview_p.h @@ -351,6 +351,8 @@ public: void scrollElasticBandBy(int dx, int dy); + QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const; + // ### FIXME: we only need one at a time QDynamicListViewBase *dynamicListView; QStaticListViewBase *staticListView; -- cgit v0.12 From 69a3c65d177a4a6ecc3d3fd63455dcd53d62b75f Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Sat, 11 Jul 2009 15:49:51 +0200 Subject: build fix on windows --- src/gui/graphicsview/qgraphicsview_p.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h index 28b4bdc..0fa8b34 100644 --- a/src/gui/graphicsview/qgraphicsview_p.h +++ b/src/gui/graphicsview/qgraphicsview_p.h @@ -59,6 +59,7 @@ #include #include "qgraphicssceneevent.h" +#include #include QT_BEGIN_NAMESPACE -- cgit v0.12 From cbf18d5b24e9ae541bc7e6a7b6698666cce30478 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Sat, 11 Jul 2009 16:20:40 +0200 Subject: ItemViews selection: improve performance of QItemSelection::indexes On windows it makes it 2x faster --- src/gui/itemviews/qitemselectionmodel.cpp | 35 ++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/gui/itemviews/qitemselectionmodel.cpp b/src/gui/itemviews/qitemselectionmodel.cpp index e4cb0f0..87825d9 100644 --- a/src/gui/itemviews/qitemselectionmodel.cpp +++ b/src/gui/itemviews/qitemselectionmodel.cpp @@ -270,24 +270,35 @@ QItemSelectionRange QItemSelectionRange::intersect(const QItemSelectionRange &ot */ -/*! - Returns the list of model index items stored in the selection. -*/ +/* + \internal -QModelIndexList QItemSelectionRange::indexes() const + utility function for getting the indexes from a range + it avoid concatenating list and works on one + */ + +static void indexesFromRange(const QItemSelectionRange &range, QModelIndexList &result) { - QModelIndex index; - QModelIndexList result; - if (isValid() && model()) { - for (int column = left(); column <= right(); ++column) { - for (int row = top(); row <= bottom(); ++row) { - index = model()->index(row, column, parent()); - Qt::ItemFlags flags = model()->flags(index); + if (range.isValid() && range.model()) { + for (int column = range.left(); column <= range.right(); ++column) { + for (int row = range.top(); row <= range.bottom(); ++row) { + QModelIndex index = range.model()->index(row, column, range.parent()); + Qt::ItemFlags flags = range.model()->flags(index); if ((flags & Qt::ItemIsSelectable) && (flags & Qt::ItemIsEnabled)) result.append(index); } } } +} + +/*! + Returns the list of model index items stored in the selection. +*/ + +QModelIndexList QItemSelectionRange::indexes() const +{ + QModelIndexList result; + indexesFromRange(*this, result); return result; } @@ -404,7 +415,7 @@ QModelIndexList QItemSelection::indexes() const QModelIndexList result; QList::const_iterator it = begin(); for (; it != end(); ++it) - result += (*it).indexes(); + indexesFromRange(*it, result); return result; } -- cgit v0.12 From e84e16954e9b96479964368e2dcb3114dd2bd5f1 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Sat, 11 Jul 2009 18:01:49 +0200 Subject: QListView: small refactoring It is useless to store the vector of modelindex from intersectingSet --- src/gui/itemviews/qlistview.cpp | 106 ++++++++++++++++++++-------------------- src/gui/itemviews/qlistview_p.h | 22 +++------ 2 files changed, 61 insertions(+), 67 deletions(-) diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp index 44bcf6f..9a94b31 100644 --- a/src/gui/itemviews/qlistview.cpp +++ b/src/gui/itemviews/qlistview.cpp @@ -723,7 +723,7 @@ QItemViewPaintPairs QListViewPrivate::draggablePaintPairs(const QModelIndexList const QRect viewportRect = viewport->rect(); QItemViewPaintPairs ret; intersectingSet(viewportRect); - const QSet visibleIndexes = intersectVector.toList().toSet(); + const QSet visibleIndexes = intersectingSet(viewportRect).toList().toSet(); for (int i = 0; i < indexes.count(); ++i) { const QModelIndex &index = indexes.at(i); if (visibleIndexes.contains(index)) { @@ -951,9 +951,9 @@ void QListView::dragMoveEvent(QDragMoveEvent *e) QModelIndex index; if (d->movement == Snap) { QRect rect(d->dynamicListView->snapToGrid(e->pos() + d->offset()), d->gridSize()); - d->intersectingSet(rect); - index = d->intersectVector.count() > 0 - ? d->intersectVector.last() : QModelIndex(); + const QVector intersectVector = d->intersectingSet(rect); + index = intersectVector.count() > 0 + ? intersectVector.last() : QModelIndex(); } else { index = indexAt(e->pos()); } @@ -1126,10 +1126,8 @@ void QListView::paintEvent(QPaintEvent *e) return; QStyleOptionViewItemV4 option = d->viewOptionsV4(); QPainter painter(d->viewport); - QRect area = e->rect(); - d->intersectingSet(e->rect().translated(horizontalOffset(), verticalOffset()), false); - const QVector toBeRendered = d->intersectVector; + const QVector toBeRendered = d->intersectingSet(e->rect().translated(horizontalOffset(), verticalOffset()), false); const QModelIndex current = currentIndex(); const QModelIndex hover = d->hover; @@ -1251,9 +1249,9 @@ QModelIndex QListView::indexAt(const QPoint &p) const { Q_D(const QListView); QRect rect(p.x() + horizontalOffset(), p.y() + verticalOffset(), 1, 1); - d->intersectingSet(rect); - QModelIndex index = d->intersectVector.count() > 0 - ? d->intersectVector.last() : QModelIndex(); + const QVector intersectVector = d->intersectingSet(rect); + QModelIndex index = intersectVector.count() > 0 + ? intersectVector.last() : QModelIndex(); if (index.isValid() && visualRect(index).contains(p)) return index; return QModelIndex(); @@ -1351,38 +1349,38 @@ QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie if (d->gridSize().isValid()) rect.setSize(d->gridSize()); QSize contents = d->contentsSize(); - d->intersectVector.clear(); + QVector intersectVector; switch (cursorAction) { case MoveLeft: - while (d->intersectVector.isEmpty()) { + while (intersectVector.isEmpty()) { rect.translate(-rect.width(), 0); if (rect.right() <= 0) return current; if (rect.left() < 0) rect.setLeft(0); - d->intersectingSet(rect); - d->removeCurrentAndDisabled(&d->intersectVector, current); + intersectVector = d->intersectingSet(rect); + d->removeCurrentAndDisabled(&intersectVector, current); } - return d->closestIndex(initialRect, d->intersectVector); + return d->closestIndex(initialRect, intersectVector); case MoveRight: - while (d->intersectVector.isEmpty()) { + while (intersectVector.isEmpty()) { rect.translate(rect.width(), 0); if (rect.left() >= contents.width()) return current; if (rect.right() > contents.width()) rect.setRight(contents.width()); - d->intersectingSet(rect); - d->removeCurrentAndDisabled(&d->intersectVector, current); + intersectVector = d->intersectingSet(rect); + d->removeCurrentAndDisabled(&intersectVector, current); } - return d->closestIndex(initialRect, d->intersectVector); + return d->closestIndex(initialRect, intersectVector); case MovePageUp: rect.moveTop(rect.top() - d->viewport->height()); if (rect.top() < rect.height()) rect.moveTop(rect.height()); case MovePrevious: case MoveUp: - while (d->intersectVector.isEmpty()) { + while (intersectVector.isEmpty()) { rect.translate(0, -rect.height()); if (rect.bottom() <= 0) { #ifdef QT_KEYPAD_NAVIGATION @@ -1398,17 +1396,17 @@ QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie } if (rect.top() < 0) rect.setTop(0); - d->intersectingSet(rect); - d->removeCurrentAndDisabled(&d->intersectVector, current); + intersectVector = d->intersectingSet(rect); + d->removeCurrentAndDisabled(&intersectVector, current); } - return d->closestIndex(initialRect, d->intersectVector); + return d->closestIndex(initialRect, intersectVector); case MovePageDown: rect.moveTop(rect.top() + d->viewport->height()); if (rect.bottom() > contents.height() - rect.height()) rect.moveBottom(contents.height() - rect.height()); case MoveNext: case MoveDown: - while (d->intersectVector.isEmpty()) { + while (intersectVector.isEmpty()) { rect.translate(0, rect.height()); if (rect.top() >= contents.height()) { #ifdef QT_KEYPAD_NAVIGATION @@ -1425,10 +1423,10 @@ QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie } if (rect.bottom() > contents.height()) rect.setBottom(contents.height()); - d->intersectingSet(rect); - d->removeCurrentAndDisabled(&d->intersectVector, current); + intersectVector = d->intersectingSet(rect); + d->removeCurrentAndDisabled(&intersectVector, current); } - return d->closestIndex(initialRect, d->intersectVector); + return d->closestIndex(initialRect, intersectVector); case MoveHome: return d->model->index(0, d->column, d->root); case MoveEnd: @@ -1503,10 +1501,10 @@ void QListView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFl QItemSelection selection; if (rect.width() == 1 && rect.height() == 1) { - d->intersectingSet(rect.translated(horizontalOffset(), verticalOffset())); + const QVector intersectVector = d->intersectingSet(rect.translated(horizontalOffset(), verticalOffset())); QModelIndex tl; - if (!d->intersectVector.isEmpty()) - tl = d->intersectVector.last(); // special case for mouse press; only select the top item + if (!intersectVector.isEmpty()) + tl = intersectVector.last(); // special case for mouse press; only select the top item if (tl.isValid() && d->isIndexEnabled(tl)) selection.select(tl, tl); } else { @@ -1516,14 +1514,14 @@ void QListView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFl QModelIndex tl, br; // get the first item const QRect topLeft(rect.left() + horizontalOffset(), rect.top() + verticalOffset(), 1, 1); - d->intersectingSet(topLeft); - if (!d->intersectVector.isEmpty()) - tl = d->intersectVector.last(); + QVector intersectVector = d->intersectingSet(topLeft); + if (!intersectVector.isEmpty()) + tl = intersectVector.last(); // get the last item const QRect bottomRight(rect.right() + horizontalOffset(), rect.bottom() + verticalOffset(), 1, 1); - d->intersectingSet(bottomRight); - if (!d->intersectVector.isEmpty()) - br = d->intersectVector.last(); + intersectVector = d->intersectingSet(bottomRight); + if (!intersectVector.isEmpty()) + br = intersectVector.last(); // get the ranges if (tl.isValid() && br.isValid() @@ -2144,8 +2142,8 @@ QItemSelection QListViewPrivate::selection(const QRect &rect) const { QItemSelection selection; QModelIndex tl, br; - intersectingSet(rect); - QVector::iterator it = intersectVector.begin(); + const QVector intersectVector = intersectingSet(rect); + QVector::const_iterator it = intersectVector.begin(); for (; it != intersectVector.end(); ++it) { if (!tl.isValid() && !br.isValid()) { tl = br = *it; @@ -2436,9 +2434,9 @@ void QStaticListViewBase::doStaticLayout(const QListViewLayoutInfo &info) Finds the set of items intersecting with \a area. In this function, itemsize is counted from topleft to the start of the next item. */ -void QStaticListViewBase::intersectingStaticSet(const QRect &area) const +QVector QStaticListViewBase::intersectingStaticSet(const QRect &area) const { - clearIntersections(); + QVector ret; int segStartPosition; int segEndPosition; int flowStartPosition; @@ -2455,7 +2453,7 @@ void QStaticListViewBase::intersectingStaticSet(const QRect &area) const flowEndPosition = area.bottom(); } if (segmentPositions.count() < 2 || flowPositions.isEmpty()) - return; + return ret; // the last segment position is actually the edge of the last segment const int segLast = segmentPositions.count() - 2; int seg = qBinarySearch(segmentPositions, segStartPosition, 0, segLast + 1); @@ -2470,13 +2468,14 @@ void QStaticListViewBase::intersectingStaticSet(const QRect &area) const continue; QModelIndex index = modelIndex(row); if (index.isValid()) - appendToIntersections(index); + ret += index; #if 0 // for debugging else qWarning("intersectingStaticSet: row %d was invalid", row); #endif } } + return ret; } int QStaticListViewBase::itemIndex(const QListViewItem &item) const @@ -2797,12 +2796,15 @@ void QDynamicListViewBase::doDynamicLayout(const QListViewLayoutInfo &info) viewport()->update(); } -void QDynamicListViewBase::intersectingDynamicSet(const QRect &area) const +QVector QDynamicListViewBase::intersectingDynamicSet(const QRect &area) const { - clearIntersections(); - QListViewPrivate *that = const_cast(dd); + QDynamicListViewBase *that = const_cast(this); QBspTree::Data data(static_cast(that)); - that->dynamicListView->tree.climbTree(area, &QDynamicListViewBase::addLeaf, data); + QVector res; + that->interSectingVector = &res; + that->tree.climbTree(area, &QDynamicListViewBase::addLeaf, data); + that->interSectingVector = 0; + return res; } void QDynamicListViewBase::createItems(int to) @@ -2879,20 +2881,20 @@ int QDynamicListViewBase::itemIndex(const QListViewItem &item) const } void QDynamicListViewBase::addLeaf(QVector &leaf, const QRect &area, - uint visited, QBspTree::Data data) + uint visited, QBspTree::Data data) { QListViewItem *vi; - QListViewPrivate *_this = static_cast(data.ptr); + QDynamicListViewBase *_this = static_cast(data.ptr); for (int i = 0; i < leaf.count(); ++i) { int idx = leaf.at(i); - if (idx < 0 || idx >= _this->dynamicListView->items.count()) + if (idx < 0 || idx >= _this->items.count()) continue; - vi = &_this->dynamicListView->items[idx]; + vi = &_this->items[idx]; Q_ASSERT(vi); if (vi->isValid() && vi->rect().intersects(area) && vi->visited != visited) { - QModelIndex index = _this->listViewItemToIndex(*vi); + QModelIndex index = _this->dd->listViewItemToIndex(*vi); Q_ASSERT(index.isValid()); - _this->intersectVector.append(index); + _this->interSectingVector->append(index); vi->visited = visited; } } diff --git a/src/gui/itemviews/qlistview_p.h b/src/gui/itemviews/qlistview_p.h index 16f2de9..1727ba4 100644 --- a/src/gui/itemviews/qlistview_p.h +++ b/src/gui/itemviews/qlistview_p.h @@ -153,9 +153,6 @@ public: inline bool isHidden(int row) const; inline int hiddenCount() const; - inline void clearIntersections() const; - inline void appendToIntersections(const QModelIndex &idx) const; - inline bool isRightToLeft() const; QListViewPrivate *dd; @@ -186,7 +183,7 @@ public: QPoint initStaticLayout(const QListViewLayoutInfo &info); void doStaticLayout(const QListViewLayoutInfo &info); - void intersectingStaticSet(const QRect &area) const; + QVector intersectingStaticSet(const QRect &area) const; int itemIndex(const QListViewItem &item) const; @@ -216,7 +213,7 @@ class QDynamicListViewBase : public QCommonListViewBase friend class QListViewPrivate; public: QDynamicListViewBase(QListView *q, QListViewPrivate *d) : QCommonListViewBase(q, d), - batchStartRow(0), batchSavedDeltaSeg(0) {} + batchStartRow(0), batchSavedDeltaSeg(0), interSectingVector(0) {} QBspTree tree; QVector items; @@ -230,6 +227,7 @@ public: // used when laying out in batches int batchStartRow; int batchSavedDeltaSeg; + QVector *interSectingVector; //used from within intersectingDynamicSet void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); bool doBatchedItemLayout(const QListViewLayoutInfo &info, int max); @@ -237,7 +235,7 @@ public: void initBspTree(const QSize &contents); QPoint initDynamicLayout(const QListViewLayoutInfo &info); void doDynamicLayout(const QListViewLayoutInfo &info); - void intersectingDynamicSet(const QRect &area) const; + QVector intersectingDynamicSet(const QRect &area) const; static void addLeaf(QVector &leaf, const QRect &area, uint visited, QBspTree::Data data); @@ -277,11 +275,11 @@ public: bool doItemsLayout(int num); - inline void intersectingSet(const QRect &area, bool doLayout = true) const { + inline QVector intersectingSet(const QRect &area, bool doLayout = true) const { if (doLayout) executePostedLayout(); QRect a = (q_func()->isRightToLeft() ? flipX(area.normalized()) : area.normalized()); - if (viewMode == QListView::ListMode) staticListView->intersectingStaticSet(a); - else dynamicListView->intersectingDynamicSet(a); + return (viewMode == QListView::ListMode) ? staticListView->intersectingStaticSet(a) + : dynamicListView->intersectingDynamicSet(a); } // ### FIXME: @@ -385,9 +383,6 @@ public: QRect layoutBounds; - // used for intersecting set - mutable QVector intersectVector; - // timers QBasicTimer batchLayoutTimer; @@ -440,9 +435,6 @@ inline QAbstractItemDelegate *QCommonListViewBase::delegate(const QModelIndex &i inline bool QCommonListViewBase::isHidden(int row) const { return dd->isHidden(row); } inline int QCommonListViewBase::hiddenCount() const { return dd->hiddenRows.count(); } -inline void QCommonListViewBase::clearIntersections() const { dd->intersectVector.clear(); } -inline void QCommonListViewBase::appendToIntersections(const QModelIndex &idx) const { dd->intersectVector.append(idx); } - inline bool QCommonListViewBase::isRightToLeft() const { return qq->isRightToLeft(); } QT_END_NAMESPACE -- cgit v0.12 From 6fbd79e45330044b059aa55873eaf2b73bdc49b2 Mon Sep 17 00:00:00 2001 From: Bill King Date: Mon, 13 Jul 2009 08:14:02 +1000 Subject: Fixes merge mixup. --- src/sql/drivers/ibase/qsql_ibase.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sql/drivers/ibase/qsql_ibase.cpp b/src/sql/drivers/ibase/qsql_ibase.cpp index c7409e1..0c4fff0 100644 --- a/src/sql/drivers/ibase/qsql_ibase.cpp +++ b/src/sql/drivers/ibase/qsql_ibase.cpp @@ -1621,7 +1621,7 @@ QSqlRecord QIBaseDriver::record(const QString& tablename) const "b.RDB$FIELD_SCALE, b.RDB$FIELD_PRECISION, a.RDB$NULL_FLAG " "FROM RDB$RELATION_FIELDS a, RDB$FIELDS b " "WHERE b.RDB$FIELD_NAME = a.RDB$FIELD_SOURCE " - "AND UPPER(a.RDB$RELATION_NAME) = '") + table.toUpper() + QLatin1String("' " + "AND a.RDB$RELATION_NAME = '") + table + QLatin1String("' " "ORDER BY a.RDB$FIELD_POSITION")); while (q.next()) { @@ -1660,7 +1660,7 @@ QSqlIndex QIBaseDriver::primaryIndex(const QString &table) const q.exec(QLatin1String("SELECT a.RDB$INDEX_NAME, b.RDB$FIELD_NAME, d.RDB$FIELD_TYPE, d.RDB$FIELD_SCALE " "FROM RDB$RELATION_CONSTRAINTS a, RDB$INDEX_SEGMENTS b, RDB$RELATION_FIELDS c, RDB$FIELDS d " "WHERE a.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' " - "AND UPPER(a.RDB$RELATION_NAME) = '") + tablename.toUpper() + + "AND a.RDB$RELATION_NAME = '") + tablename + QLatin1String(" 'AND a.RDB$INDEX_NAME = b.RDB$INDEX_NAME " "AND c.RDB$RELATION_NAME = a.RDB$RELATION_NAME " "AND c.RDB$FIELD_NAME = b.RDB$FIELD_NAME " -- cgit v0.12 From c402f363d8502c688433eb4f21ba3528d9ac89e5 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Mon, 13 Jul 2009 10:36:51 +1000 Subject: Fixed linking of QtSvg with MSVC. --- src/gui/graphicsview/qgraphicsitem_p.h | 17 +++++++++++++++++ src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h | 18 ------------------ src/gui/widgets/qabstractscrollarea_p.h | 2 +- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index ed1982e..9bdd273 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -506,6 +506,23 @@ struct QGraphicsItemPrivate::TransformData { /*! \internal */ +inline bool qt_closestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2) +{ + // Return true if sibling item1 is on top of item2. + const QGraphicsItemPrivate *d1 = item1->d_ptr; + const QGraphicsItemPrivate *d2 = item2->d_ptr; + bool f1 = d1->flags & QGraphicsItem::ItemStacksBehindParent; + bool f2 = d2->flags & QGraphicsItem::ItemStacksBehindParent; + if (f1 != f2) + return f2; + if (d1->z != d2->z) + return d1->z > d2->z; + return d1->siblingIndex > d2->siblingIndex; +} + +/*! + \internal +*/ static inline bool qt_notclosestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2) { return qt_closestLeaf(item2, item1); } diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 3ac922b..2e02458 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -164,24 +164,6 @@ public: bool cached, bool onlyTopLevelItems = false); }; - -/*! - \internal -*/ -inline bool qt_closestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2) -{ - // Return true if sibling item1 is on top of item2. - const QGraphicsItemPrivate *d1 = item1->d_ptr; - const QGraphicsItemPrivate *d2 = item2->d_ptr; - bool f1 = d1->flags & QGraphicsItem::ItemStacksBehindParent; - bool f2 = d2->flags & QGraphicsItem::ItemStacksBehindParent; - if (f1 != f2) - return f2; - if (d1->z != d2->z) - return d1->z > d2->z; - return d1->siblingIndex > d2->siblingIndex; -} - static inline bool QRectF_intersects(const QRectF &s, const QRectF &r) { qreal xp = s.left(); diff --git a/src/gui/widgets/qabstractscrollarea_p.h b/src/gui/widgets/qabstractscrollarea_p.h index 7e0f444..aef8ac5 100644 --- a/src/gui/widgets/qabstractscrollarea_p.h +++ b/src/gui/widgets/qabstractscrollarea_p.h @@ -62,7 +62,7 @@ QT_BEGIN_NAMESPACE class QScrollBar; class QAbstractScrollAreaScrollBarContainer; -class QAbstractScrollAreaPrivate: public QFramePrivate +class Q_AUTOTEST_EXPORT QAbstractScrollAreaPrivate: public QFramePrivate { Q_DECLARE_PUBLIC(QAbstractScrollArea) -- cgit v0.12 From de07df9001586cc18ae267591359541b7ea494a0 Mon Sep 17 00:00:00 2001 From: Bill King Date: Mon, 13 Jul 2009 13:28:52 +1000 Subject: Fixes failure when table has null fields to update Fixes an issue where too many parameters are bound when updating QSqlTableModel where the stored record has NULLs in it. Reviewed-by: Justin McPherson --- src/sql/models/qsqltablemodel.cpp | 2 +- tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp | 62 ++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index 591b506..18d89b4 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -202,7 +202,7 @@ bool QSqlTableModelPrivate::exec(const QString &stmt, bool prepStatement, editQuery.addBindValue(rec.value(i)); } for (i = 0; i < whereValues.count(); ++i) { - if (whereValues.isGenerated(i)) + if (whereValues.isGenerated(i) && !whereValues.isNull(i)) editQuery.addBindValue(whereValues.value(i)); } diff --git a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp index 5d1f9d4..24bc42b 100644 --- a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp +++ b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp @@ -116,6 +116,8 @@ private slots: void insertRecordsInLoop(); void sqlite_attachedDatabase_data() { generic_data("QSQLITE"); } void sqlite_attachedDatabase(); // For task 130799 + void tableModifyWithBlank_data() { generic_data(); } + void tableModifyWithBlank(); // For mail task private: void generic_data(const QString& engine=QString()); @@ -141,6 +143,7 @@ void tst_QSqlTableModel::dropTestTables() tableNames << qTableName("test") << qTableName("test2") << qTableName("test3") + << qTableName("test4") << qTableName("emptytable") << qTableName("bigtable") << qTableName("foo"); @@ -167,6 +170,8 @@ void tst_QSqlTableModel::createTestTables() QVERIFY_SQL( q, exec("create table " + qTableName("test3") + "(id int, random varchar(20), randomtwo varchar(20))")); + QVERIFY_SQL( q, exec("create table " + qTableName("test4") + "(column1 varchar(50), column2 varchar(50), column3 varchar(50))")); + QVERIFY_SQL( q, exec("create table " + qTableName("emptytable") + "(id int)")); if (testWhiteSpaceNames(db.driverName())) { @@ -922,5 +927,62 @@ void tst_QSqlTableModel::sqlite_attachedDatabase() QCOMPARE(model.data(model.index(0, 1), Qt::DisplayRole).toString(), QLatin1String("main")); } + +void tst_QSqlTableModel::tableModifyWithBlank() +{ + QFETCH(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + QSqlTableModel model(0, db); + model.setTable(qTableName("test4")); + model.select(); + + //generate a time stamp for the test. Add one second to the current time to make sure + //it is different than the QSqlQuery test. + QString timeString=QDateTime::currentDateTime().addSecs(1).toString(Qt::ISODate); + + //insert a new row, with column0 being the timestamp. + //Should be equivalent to QSqlQuery INSERT INTO... command) + QVERIFY_SQL(model, insertRow(0)); + QVERIFY_SQL(model, setData(model.index(0,0),timeString)); + QVERIFY_SQL(model, submitAll()); + + //set a filter on the table so the only record we get is the one we just made + //I could just do another setData command, but I want to make sure the TableModel + //matches exactly what is stored in the database + model.setFilter("column1='"+timeString+"'"); //filter to get just the newly entered row + QVERIFY_SQL(model, select()); + + //Make sure we only get one record, and that it is the one we just made + QCOMPARE(model.rowCount(), 1); //verify only one entry + QCOMPARE(model.record(0).value(0).toString(), timeString); //verify correct record + + //At this point we know that the intial value (timestamp) was succsefully stored in the database + //Attempt to modify the data in the new record + //equivalent to query.exec("update test set column3="... command in direct test + //set the data in the first column to "col1ModelData" + QVERIFY_SQL(model, setData(model.index(0,1), "col1ModelData")); + + //do a quick check to make sure that the setData command properly set the value in the model + QCOMPARE(model.record(0).value(1).toString(), QLatin1String("col1ModelData")); + + //submit the changed data to the database + //This is where I have been getting errors. + QVERIFY_SQL(model, submitAll()); + + //make sure the model has the most current data for our record + QVERIFY_SQL(model, select()); + + //verify that our new record was the only record returned + QCOMPARE(model.rowCount(), 1); + + //And that the record returned is, in fact, our test record. + QCOMPARE(model.record(0).value(0).toString(), timeString); + + //Make sure the value of the first column matches what we set it to previously. + QCOMPARE(model.record(0).value(1).toString(), QLatin1String("col1ModelData")); +} + QTEST_MAIN(tst_QSqlTableModel) #include "tst_qsqltablemodel.moc" -- cgit v0.12 From c2f6c3eb4381a987df47601fcbab4e3a98d40813 Mon Sep 17 00:00:00 2001 From: Bill King Date: Mon, 13 Jul 2009 14:56:24 +1000 Subject: Fixes up the autotest for mysql over ODBC connection. --- tests/auto/qsqldriver/tst_qsqldriver.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qsqldriver/tst_qsqldriver.cpp b/tests/auto/qsqldriver/tst_qsqldriver.cpp index 6d428df..b79c093 100644 --- a/tests/auto/qsqldriver/tst_qsqldriver.cpp +++ b/tests/auto/qsqldriver/tst_qsqldriver.cpp @@ -158,7 +158,7 @@ void tst_QSqlDriver::record() //check that we can't get records using incorrect tablename casing that's been quoted rec = db.driver()->record(db.driver()->escapeIdentifier(tablename,QSqlDriver::TableName)); - if (db.driverName().startsWith("QMYSQL") || db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QTDS")) + if (tst_Databases::isMySQL(db) || db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QTDS")) QCOMPARE(rec.count(), 4); //mysql, sqlite and tds will match else QCOMPARE(rec.count(), 0); @@ -204,7 +204,7 @@ void tst_QSqlDriver::primaryIndex() tablename = tablename.toUpper(); index = db.driver()->primaryIndex(db.driver()->escapeIdentifier(tablename, QSqlDriver::TableName)); - if (db.driverName().startsWith("QMYSQL") || db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QTDS")) + if (tst_Databases::isMySQL(db) || db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QTDS")) QCOMPARE(index.count(), 1); //mysql will always find the table name regardless of casing else QCOMPARE(index.count(), 0); -- cgit v0.12 From 049ff0b4f74400ab3c8571f6ba3a73106ca3a9dd Mon Sep 17 00:00:00 2001 From: Bill King Date: Mon, 13 Jul 2009 15:21:01 +1000 Subject: Fixes autotest to match the new code (db level precisionPolicy). --- tests/auto/qsqldatabase/tst_qsqldatabase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index 82e25d7..994a3d7 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -918,7 +918,7 @@ void tst_QSqlDatabase::recordOCI() FieldDef("varchar(20)", QVariant::String, QString("blah2")), FieldDef("nchar(20)", QVariant::String, QString("blah3")), FieldDef("nvarchar2(20)", QVariant::String, QString("blah4")), - FieldDef("number(10,5)", QVariant::String, 1.1234567), + FieldDef("number(10,5)", QVariant::Double, 1.1234567), FieldDef("date", QVariant::DateTime, dt), #ifdef QT3_SUPPORT //X? FieldDef("long raw", QVariant::ByteArray, QByteArray(Q3CString("blah5"))), -- cgit v0.12 From f6079b8407e20942a27f1fe40c4ce0e0a11d3320 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Mon, 13 Jul 2009 10:16:17 +0200 Subject: Fix broken tst_QGraphicsItem::sorting. A top-level window on Windows cannot have a smaller width than 120. Increase the width by 20 and expect another row of items to be painted. --- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 4ca1b48..96ee070 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -7113,7 +7113,7 @@ void tst_QGraphicsItem::sorting() QGraphicsView view(&scene); view.setResizeAnchor(QGraphicsView::NoAnchor); view.setTransformationAnchor(QGraphicsView::NoAnchor); - view.resize(100, 100); + view.resize(120, 100); view.setFrameStyle(0); view.show(); #ifdef Q_WS_X11 @@ -7130,6 +7130,7 @@ void tst_QGraphicsItem::sorting() << grid[1][0] << grid[1][1] << grid[1][2] << grid[1][3] << grid[2][0] << grid[2][1] << grid[2][2] << grid[2][3] << grid[3][0] << grid[3][1] << grid[3][2] << grid[3][3] + << grid[4][0] << grid[4][1] << grid[4][2] << grid[4][3] << item1 << item2); } -- cgit v0.12 From dacfd67ad35ed3edb079e9795088f852b98717e3 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Mon, 13 Jul 2009 10:27:15 +0200 Subject: Stabilize tst_QGraphicsView::mouseTracking2 (on Windows). Use QApplication::sendEvent directly instead of calling the static sendMouseMove function, which also calls QTest::mouseMove. This test failed with spy.count() being 2 instead of 1 (which is correct since we both use QTest::mouseMove and QApplication::sendEvent). --- tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index 77ab977..9a5089b 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -3311,7 +3311,9 @@ void tst_QGraphicsView::mouseTracking2() EventSpy spy(&scene, QEvent::GraphicsSceneMouseMove); QCOMPARE(spy.count(), 0); - sendMouseMove(view.viewport(), view.viewport()->rect().center()); + QMouseEvent event(QEvent::MouseMove,view.viewport()->rect().center(), Qt::NoButton, + Qt::MouseButtons(Qt::NoButton), 0); + QApplication::sendEvent(view.viewport(), &event); QCOMPARE(spy.count(), 1); } -- cgit v0.12 From d705f5cd9d3bac765346af361038f2f9249183e7 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Mon, 13 Jul 2009 10:48:43 +0200 Subject: Fix crash after "Remove QT_WA and non-Unicode code paths, dropping Win9x and NT support" tst_QGraphicsProxyWidget crashed because the QAlphaWidget tried to access a deleted widget. Before we had the if check, but that was removed with this commit: 55137901. Completely wrong, we must check the widget pointer before using it. Reviewed-by: jbache --- src/gui/widgets/qeffects.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/widgets/qeffects.cpp b/src/gui/widgets/qeffects.cpp index d6d0a16..f3b1b76 100644 --- a/src/gui/widgets/qeffects.cpp +++ b/src/gui/widgets/qeffects.cpp @@ -128,7 +128,8 @@ QAlphaWidget::~QAlphaWidget() { #if defined(Q_WS_WIN) && !defined(Q_WS_WINCE) // Restore user-defined opacity value - widget->setWindowOpacity(windowOpacity); + if (widget) + widget->setWindowOpacity(windowOpacity); #endif } -- cgit v0.12 From e8e6e8c1722618a48cb4a2e46b24ecad4b056270 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 13 Jul 2009 11:03:41 +0200 Subject: Added QSyntaxHighlighter::rehighlightBlock(QTextBlock) Merge-request: 379 Reviewed-by: Simon Hausmann --- src/gui/text/qsyntaxhighlighter.cpp | 27 +++++++++++++++++++++++++++ src/gui/text/qsyntaxhighlighter.h | 1 + 2 files changed, 28 insertions(+) diff --git a/src/gui/text/qsyntaxhighlighter.cpp b/src/gui/text/qsyntaxhighlighter.cpp index db1a38e..ccf229e 100644 --- a/src/gui/text/qsyntaxhighlighter.cpp +++ b/src/gui/text/qsyntaxhighlighter.cpp @@ -356,6 +356,8 @@ QTextDocument *QSyntaxHighlighter::document() const \since 4.2 Redoes the highlighting of the whole document. + + \sa rehighlightBlock() */ void QSyntaxHighlighter::rehighlight() { @@ -375,6 +377,31 @@ void QSyntaxHighlighter::rehighlight() } /*! + \since 4.6 + + Redoes the highlighting of the given QTextBlock \a block. + + \sa rehighlight() +*/ +void QSyntaxHighlighter::rehighlightBlock(const QTextBlock &block) +{ + Q_D(QSyntaxHighlighter); + if (!d->doc) + return; + + disconnect(d->doc, SIGNAL(contentsChange(int,int,int)), + this, SLOT(_q_reformatBlocks(int,int,int))); + QTextCursor cursor(block); + cursor.beginEditBlock(); + int from = cursor.position(); + cursor.movePosition(QTextCursor::EndOfBlock); + d->_q_reformatBlocks(from, 0, cursor.position() - from); + cursor.endEditBlock(); + connect(d->doc, SIGNAL(contentsChange(int,int,int)), + this, SLOT(_q_reformatBlocks(int,int,int))); +} + +/*! \fn void QSyntaxHighlighter::highlightBlock(const QString &text) Highlights the given text block. This function is called when diff --git a/src/gui/text/qsyntaxhighlighter.h b/src/gui/text/qsyntaxhighlighter.h index 4e5271b..ee249b8 100644 --- a/src/gui/text/qsyntaxhighlighter.h +++ b/src/gui/text/qsyntaxhighlighter.h @@ -78,6 +78,7 @@ public: public Q_SLOTS: void rehighlight(); + void rehighlightBlock(const QTextBlock &block); protected: virtual void highlightBlock(const QString &text) = 0; -- cgit v0.12 From 9a46bc5f02866134fb66ff1a03863d09382f7d40 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 13 Jul 2009 11:03:42 +0200 Subject: Added QSyntaxHighlighter::rehighlightBlock() auto test Merge-request: 379 Reviewed-by: Simon Hausmann --- .../qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp | 29 +++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/tests/auto/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp b/tests/auto/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp index 22e9455..1699e72 100644 --- a/tests/auto/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp +++ b/tests/auto/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp @@ -99,7 +99,8 @@ private slots: void avoidUnnecessaryRehighlight(); void noContentsChangedDuringHighlight(); void rehighlight(); - + void rehighlightBlock(); + private: QTextDocument *doc; QTestDocumentLayout *lout; @@ -517,6 +518,32 @@ void tst_QSyntaxHighlighter::rehighlight() QCOMPARE(hl->callCount, 1); } +void tst_QSyntaxHighlighter::rehighlightBlock() +{ + TestHighlighter *hl = new TestHighlighter(doc); + + cursor.movePosition(QTextCursor::Start); + cursor.beginEditBlock(); + cursor.insertText("Hello"); + cursor.insertBlock(); + cursor.insertText("World"); + cursor.endEditBlock(); + + hl->callCount = 0; + hl->highlightedText.clear(); + QTextBlock block = doc->begin(); + hl->rehighlightBlock(block); + + QCOMPARE(hl->highlightedText, QString("Hello")); + QCOMPARE(hl->callCount, 1); + + hl->callCount = 0; + hl->highlightedText.clear(); + hl->rehighlightBlock(block.next()); + + QCOMPARE(hl->highlightedText, QString("World")); + QCOMPARE(hl->callCount, 1); +} QTEST_MAIN(tst_QSyntaxHighlighter) #include "tst_qsyntaxhighlighter.moc" -- cgit v0.12 From d5c71b7ede48fd832145cc3921da77b10772053c Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 13 Jul 2009 11:03:44 +0200 Subject: Unified common code in QSyntaxHighlighter::rehighlight() and QSyntaxHighlighter::rehighlightBlock() Merge-request: 379 Reviewed-by: Simon Hausmann --- src/gui/text/qsyntaxhighlighter.cpp | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/gui/text/qsyntaxhighlighter.cpp b/src/gui/text/qsyntaxhighlighter.cpp index ccf229e..f69562d 100644 --- a/src/gui/text/qsyntaxhighlighter.cpp +++ b/src/gui/text/qsyntaxhighlighter.cpp @@ -65,6 +65,18 @@ public: void _q_reformatBlocks(int from, int charsRemoved, int charsAdded); void reformatBlock(QTextBlock block); + + inline void rehighlight(QTextCursor &cursor, QTextCursor::MoveOperation operation) { + QObject::disconnect(doc, SIGNAL(contentsChange(int,int,int)), + q_func(), SLOT(_q_reformatBlocks(int,int,int))); + cursor.beginEditBlock(); + int from = cursor.position(); + cursor.movePosition(operation); + _q_reformatBlocks(from, 0, cursor.position() - from); + cursor.endEditBlock(); + QObject::connect(doc, SIGNAL(contentsChange(int,int,int)), + q_func(), SLOT(_q_reformatBlocks(int,int,int))); + } inline void _q_delayedRehighlight() { if (!rehighlightPending) @@ -365,15 +377,8 @@ void QSyntaxHighlighter::rehighlight() if (!d->doc) return; - disconnect(d->doc, SIGNAL(contentsChange(int,int,int)), - this, SLOT(_q_reformatBlocks(int,int,int))); QTextCursor cursor(d->doc); - cursor.beginEditBlock(); - cursor.movePosition(QTextCursor::End); - d->_q_reformatBlocks(0, 0, cursor.position()); - cursor.endEditBlock(); - connect(d->doc, SIGNAL(contentsChange(int,int,int)), - this, SLOT(_q_reformatBlocks(int,int,int))); + d->rehighlight(cursor, QTextCursor::End); } /*! @@ -389,16 +394,8 @@ void QSyntaxHighlighter::rehighlightBlock(const QTextBlock &block) if (!d->doc) return; - disconnect(d->doc, SIGNAL(contentsChange(int,int,int)), - this, SLOT(_q_reformatBlocks(int,int,int))); QTextCursor cursor(block); - cursor.beginEditBlock(); - int from = cursor.position(); - cursor.movePosition(QTextCursor::EndOfBlock); - d->_q_reformatBlocks(from, 0, cursor.position() - from); - cursor.endEditBlock(); - connect(d->doc, SIGNAL(contentsChange(int,int,int)), - this, SLOT(_q_reformatBlocks(int,int,int))); + d->rehighlight(cursor, QTextCursor::EndOfBlock); } /*! -- cgit v0.12 From 425f9035d6309111cdc8f30e1fdb4995e96c38a6 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Mon, 13 Jul 2009 11:25:02 +0200 Subject: Fix line endings. --- tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp | 44 ++++++++++++------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp index 24bc42b..ded29d7 100644 --- a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp +++ b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp @@ -938,49 +938,49 @@ void tst_QSqlTableModel::tableModifyWithBlank() model.setTable(qTableName("test4")); model.select(); - //generate a time stamp for the test. Add one second to the current time to make sure - //it is different than the QSqlQuery test. - QString timeString=QDateTime::currentDateTime().addSecs(1).toString(Qt::ISODate); - - //insert a new row, with column0 being the timestamp. - //Should be equivalent to QSqlQuery INSERT INTO... command) + //generate a time stamp for the test. Add one second to the current time to make sure + //it is different than the QSqlQuery test. + QString timeString=QDateTime::currentDateTime().addSecs(1).toString(Qt::ISODate); + + //insert a new row, with column0 being the timestamp. + //Should be equivalent to QSqlQuery INSERT INTO... command) QVERIFY_SQL(model, insertRow(0)); QVERIFY_SQL(model, setData(model.index(0,0),timeString)); QVERIFY_SQL(model, submitAll()); - - //set a filter on the table so the only record we get is the one we just made - //I could just do another setData command, but I want to make sure the TableModel - //matches exactly what is stored in the database + + //set a filter on the table so the only record we get is the one we just made + //I could just do another setData command, but I want to make sure the TableModel + //matches exactly what is stored in the database model.setFilter("column1='"+timeString+"'"); //filter to get just the newly entered row QVERIFY_SQL(model, select()); - //Make sure we only get one record, and that it is the one we just made + //Make sure we only get one record, and that it is the one we just made QCOMPARE(model.rowCount(), 1); //verify only one entry QCOMPARE(model.record(0).value(0).toString(), timeString); //verify correct record - //At this point we know that the intial value (timestamp) was succsefully stored in the database - //Attempt to modify the data in the new record - //equivalent to query.exec("update test set column3="... command in direct test - //set the data in the first column to "col1ModelData" + //At this point we know that the intial value (timestamp) was succsefully stored in the database + //Attempt to modify the data in the new record + //equivalent to query.exec("update test set column3="... command in direct test + //set the data in the first column to "col1ModelData" QVERIFY_SQL(model, setData(model.index(0,1), "col1ModelData")); - //do a quick check to make sure that the setData command properly set the value in the model + //do a quick check to make sure that the setData command properly set the value in the model QCOMPARE(model.record(0).value(1).toString(), QLatin1String("col1ModelData")); - //submit the changed data to the database - //This is where I have been getting errors. + //submit the changed data to the database + //This is where I have been getting errors. QVERIFY_SQL(model, submitAll()); - //make sure the model has the most current data for our record + //make sure the model has the most current data for our record QVERIFY_SQL(model, select()); - //verify that our new record was the only record returned + //verify that our new record was the only record returned QCOMPARE(model.rowCount(), 1); - //And that the record returned is, in fact, our test record. + //And that the record returned is, in fact, our test record. QCOMPARE(model.record(0).value(0).toString(), timeString); - //Make sure the value of the first column matches what we set it to previously. + //Make sure the value of the first column matches what we set it to previously. QCOMPARE(model.record(0).value(1).toString(), QLatin1String("col1ModelData")); } -- cgit v0.12 From 839fbd22a602aa4b9fa20e6c302329008c3aab09 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Fri, 10 Jul 2009 14:44:53 +0200 Subject: Removed an assert from the QNetworkReply. It is possible that finished() function will be called several times, for example if the user calls QNetworkReply::close() as a result of the authenticationRequired() signal, the connection will be closed (which results in emitting a finished() signal), and then the authentication will be cancelled, which will also try to emit the same signal, however the connection state will already be set to Finished. The fix is to just make sure if the finished() signal has already been emitted by checking if the connection state is not Finished or Aborted. Reviewed-by: Thiago Macieira --- src/network/access/qnetworkreplyimpl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index de39970..28319bb 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -461,8 +461,8 @@ void QNetworkReplyImplPrivate::appendDownstreamData(QIODevice *data) void QNetworkReplyImplPrivate::finished() { Q_Q(QNetworkReplyImpl); - Q_ASSERT_X(state != Finished, "QNetworkReplyImpl", - "Backend called finished/finishedWithError more than once"); + if (state == Finished || state == Aborted) + return; state = Finished; pendingNotifications.clear(); -- cgit v0.12 From 5cf6c626c6a1a23291dfe65662b914497ce81c05 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Mon, 13 Jul 2009 11:36:37 +0200 Subject: Fixed the lineendings in the tst_qsqltablemodel.cpp --- tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp | 44 ++++++++++++------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp index a30fbdb..576c190 100644 --- a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp +++ b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp @@ -943,49 +943,49 @@ void tst_QSqlTableModel::tableModifyWithBlank() model.setTable(qTableName("test4")); model.select(); - //generate a time stamp for the test. Add one second to the current time to make sure - //it is different than the QSqlQuery test. - QString timeString=QDateTime::currentDateTime().addSecs(1).toString(Qt::ISODate); - - //insert a new row, with column0 being the timestamp. - //Should be equivalent to QSqlQuery INSERT INTO... command) + //generate a time stamp for the test. Add one second to the current time to make sure + //it is different than the QSqlQuery test. + QString timeString=QDateTime::currentDateTime().addSecs(1).toString(Qt::ISODate); + + //insert a new row, with column0 being the timestamp. + //Should be equivalent to QSqlQuery INSERT INTO... command) QVERIFY_SQL(model, insertRow(0)); QVERIFY_SQL(model, setData(model.index(0,0),timeString)); QVERIFY_SQL(model, submitAll()); - - //set a filter on the table so the only record we get is the one we just made - //I could just do another setData command, but I want to make sure the TableModel - //matches exactly what is stored in the database + + //set a filter on the table so the only record we get is the one we just made + //I could just do another setData command, but I want to make sure the TableModel + //matches exactly what is stored in the database model.setFilter("column1='"+timeString+"'"); //filter to get just the newly entered row QVERIFY_SQL(model, select()); - //Make sure we only get one record, and that it is the one we just made + //Make sure we only get one record, and that it is the one we just made QCOMPARE(model.rowCount(), 1); //verify only one entry QCOMPARE(model.record(0).value(0).toString(), timeString); //verify correct record - //At this point we know that the intial value (timestamp) was succsefully stored in the database - //Attempt to modify the data in the new record - //equivalent to query.exec("update test set column3="... command in direct test - //set the data in the first column to "col1ModelData" + //At this point we know that the intial value (timestamp) was succsefully stored in the database + //Attempt to modify the data in the new record + //equivalent to query.exec("update test set column3="... command in direct test + //set the data in the first column to "col1ModelData" QVERIFY_SQL(model, setData(model.index(0,1), "col1ModelData")); - //do a quick check to make sure that the setData command properly set the value in the model + //do a quick check to make sure that the setData command properly set the value in the model QCOMPARE(model.record(0).value(1).toString(), QLatin1String("col1ModelData")); - //submit the changed data to the database - //This is where I have been getting errors. + //submit the changed data to the database + //This is where I have been getting errors. QVERIFY_SQL(model, submitAll()); - //make sure the model has the most current data for our record + //make sure the model has the most current data for our record QVERIFY_SQL(model, select()); - //verify that our new record was the only record returned + //verify that our new record was the only record returned QCOMPARE(model.rowCount(), 1); - //And that the record returned is, in fact, our test record. + //And that the record returned is, in fact, our test record. QCOMPARE(model.record(0).value(0).toString(), timeString); - //Make sure the value of the first column matches what we set it to previously. + //Make sure the value of the first column matches what we set it to previously. QCOMPARE(model.record(0).value(1).toString(), QLatin1String("col1ModelData")); } -- cgit v0.12 From b9ea022e206bad5d80b4b9a7b957e8b8521d9fb9 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 10 Jul 2009 11:33:48 +0200 Subject: fix warning in qstringbuilder.h by using QLatin1Char Reviewed-by: Volker Hilsheimer --- src/corelib/tools/qstringbuilder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h index 97f13ee..3b43253 100644 --- a/src/corelib/tools/qstringbuilder.h +++ b/src/corelib/tools/qstringbuilder.h @@ -211,7 +211,7 @@ template <> struct QConcatenable { const char *data = ba.constData(); while (*data) - *out++ = *data++; + *out++ = QLatin1Char(*data++); } }; #endif -- cgit v0.12 From 486bd135faa2c8269044f9c03597bc6b05644540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 10 Jul 2009 15:36:02 +0200 Subject: Revert "Fixed leak of plugin instances" mjansen reported on #qt-labs that this change crashes KDE applications that were calling delete on their plugins. It turns out that is also how QPluginLoader works, so the commit was a bad idea to start with. This reverts commit 4c7004122a858cd6d891efc7923ba11484fbf997. Reviewed-by: Thiago Macieira --- src/corelib/plugin/qplugin.h | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/corelib/plugin/qplugin.h b/src/corelib/plugin/qplugin.h index ff2b412..233b4f9 100644 --- a/src/corelib/plugin/qplugin.h +++ b/src/corelib/plugin/qplugin.h @@ -63,21 +63,6 @@ typedef QObject *(*QtPluginInstanceFunction)(); void Q_CORE_EXPORT qRegisterStaticPluginInstanceFunction(QtPluginInstanceFunction function); -struct qt_plugin_instance_deleter -{ - qt_plugin_instance_deleter(QPointer &instance) - : instance_(instance) - { - } - - ~qt_plugin_instance_deleter() - { - delete instance_; - } - - QPointer &instance_; -}; - #define Q_IMPORT_PLUGIN(PLUGIN) \ extern QT_PREPEND_NAMESPACE(QObject) *qt_plugin_instance_##PLUGIN(); \ class Static##PLUGIN##PluginInstance{ \ @@ -91,10 +76,8 @@ struct qt_plugin_instance_deleter #define Q_PLUGIN_INSTANCE(IMPLEMENTATION) \ { \ static QT_PREPEND_NAMESPACE(QPointer) _instance; \ - if (!_instance) { \ - static QT_PREPEND_NAMESPACE(qt_plugin_instance_deleter) deleter(_instance); \ + if (!_instance) \ _instance = new IMPLEMENTATION; \ - } \ return _instance; \ } -- cgit v0.12 From 3d55ab91148c13f1905a4c1983d144efb4315297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Mon, 13 Jul 2009 13:00:06 +0200 Subject: Cut-off in QGraphicsView not hit if setting a scene rect. QGraphicsScene::sceneRect() returns the growingItemsBoundingRect if not a particular scene rect is set; otherwise the sceneRect is returned. This cut-off aims to do less processing when the exposed region covers the entire scene, but it won't get hit in case of a sceneRect because we always check against the growingItemsBoundingRect. Task-number: 257192 --- src/gui/graphicsview/qgraphicsview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 3a8a696..bcfd68c 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -971,7 +971,7 @@ QList QGraphicsViewPrivate::findItems(const QRegion &exposedReg // rect does not take into account untransformable items. const QRectF exposedRegionSceneBounds = q->mapToScene(exposedRegion.boundingRect().adjusted(-1, -1, 1, 1)) .boundingRect(); - if (exposedRegionSceneBounds.contains(scene->d_func()->growingItemsBoundingRect)) { + if (exposedRegionSceneBounds.contains(scene->sceneRect())) { Q_ASSERT(allItems); *allItems = true; -- cgit v0.12 From 0aca5cf05288dc4d2175d1c4a78bf62a5ea96b21 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 13 Jul 2009 12:48:33 +0200 Subject: doc: Clarified what Qt::HANDLE is on Windows. Task-number: 193615 --- doc/src/qnamespace.qdoc | 5 +++-- src/corelib/thread/qthread.cpp | 11 ++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/doc/src/qnamespace.qdoc b/doc/src/qnamespace.qdoc index b691ac7..85b020d 100644 --- a/doc/src/qnamespace.qdoc +++ b/doc/src/qnamespace.qdoc @@ -1246,8 +1246,9 @@ /*! \typedef Qt::HANDLE Platform-specific handle type for system objects. This is - equivalent to \c{void *} on Windows and Mac OS X, and embedded - Linux, and to \c{unsigned long} on X11. + equivalent to \c{void *} on Mac OS X and embedded Linux, + and to \c{unsigned long} on X11. On Windows it is the + DWORD returned by the Win32 function getCurrentThreadId(). \warning Using this type is not portable. */ diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index 24522f2..2e31c6d 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -261,9 +261,14 @@ void QAdoptedThread::run() Returns the thread handle of the currently executing thread. \warning The handle returned by this function is used for internal - purposes and should not be used in any application code. On - Windows, the returned value is a pseudo-handle for the current - thread that cannot be used for numerical comparison. + purposes and should not be used in any application code. + + \warning On Windows, the returned value is a pseudo-handle for the + current thread. It can't be used for numerical comparison. i.e., + this function returns the DWORD (Windows-Thread ID) returned by + the Win32 function getCurrentThreadId(), not the HANDLE + (Windows-Thread HANDLE) returned by the Win32 function + getCurrentThread(). */ /*! -- cgit v0.12 From cc24c46c117248ecb98200416e7f25375e6bb476 Mon Sep 17 00:00:00 2001 From: Frans Englich Date: Mon, 13 Jul 2009 13:02:20 +0200 Subject: QFlags::testFlag(): handle the zero case appropriately. Brought up by Andy. See perforce change 314809, 17b07e3ab6192b31f77fd2f126705b9ab53b3937. Related to task 221708. Reviewed-By: Andy Shaw --- src/corelib/global/qglobal.h | 2 +- tests/auto/qflags/tst_qflags.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index a139a55..d6c708c 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -2062,7 +2062,7 @@ public: inline bool operator!() const { return !i; } - inline bool testFlag(Enum f) const { return (i & f) == f; } + inline bool testFlag(Enum f) const { return (i & f) == f && (f != 0 || i == f ); } }; #define Q_DECLARE_FLAGS(Flags, Enum)\ diff --git a/tests/auto/qflags/tst_qflags.cpp b/tests/auto/qflags/tst_qflags.cpp index a5f68dc..87d8258 100644 --- a/tests/auto/qflags/tst_qflags.cpp +++ b/tests/auto/qflags/tst_qflags.cpp @@ -45,6 +45,7 @@ class tst_QFlags: public QObject Q_OBJECT private slots: void testFlag() const; + void testFlagZeroFlag() const; void testFlagMultiBits() const; }; @@ -59,8 +60,31 @@ void tst_QFlags::testFlag() const QVERIFY(!btn.testFlag(Qt::LeftButton)); } +void tst_QFlags::testFlagZeroFlag() const +{ + { + Qt::MouseButtons btn = Qt::LeftButton | Qt::RightButton; + /* Qt::NoButton has the value 0. */ + + QVERIFY(!btn.testFlag(Qt::NoButton)); + } + + { + /* A zero enum set should test true with zero. */ + QVERIFY(Qt::MouseButtons().testFlag(Qt::NoButton)); + } + + { + Qt::MouseButtons btn = Qt::NoButton; + QVERIFY(btn.testFlag(Qt::NoButton)); + } +} + void tst_QFlags::testFlagMultiBits() const { + /* Qt::Window is 0x00000001 + * Qt::Dialog is 0x00000002 | Window + */ { const Qt::WindowFlags onlyWindow(Qt::Window); QVERIFY(!onlyWindow.testFlag(Qt::Dialog)); -- cgit v0.12 From 9b6eacab99673d7d9848b341c4cf36a7c35f07c0 Mon Sep 17 00:00:00 2001 From: Frans Englich Date: Mon, 13 Jul 2009 13:02:20 +0200 Subject: QFlags::testFlag(): handle the zero case appropriately. Brought up by Andy. See perforce change 314809, 17b07e3ab6192b31f77fd2f126705b9ab53b3937. Related to task 221708. Reviewed-By: Andy Shaw (cherry picked from commit cc24c46c117248ecb98200416e7f25375e6bb476) --- src/corelib/global/qglobal.h | 2 +- tests/auto/qflags/tst_qflags.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 63f6c31..f650bd2 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -2017,7 +2017,7 @@ public: inline bool operator!() const { return !i; } - inline bool testFlag(Enum f) const { return (i & f) == f; } + inline bool testFlag(Enum f) const { return (i & f) == f && (f != 0 || i == f ); } }; #define Q_DECLARE_FLAGS(Flags, Enum)\ diff --git a/tests/auto/qflags/tst_qflags.cpp b/tests/auto/qflags/tst_qflags.cpp index a5f68dc..87d8258 100644 --- a/tests/auto/qflags/tst_qflags.cpp +++ b/tests/auto/qflags/tst_qflags.cpp @@ -45,6 +45,7 @@ class tst_QFlags: public QObject Q_OBJECT private slots: void testFlag() const; + void testFlagZeroFlag() const; void testFlagMultiBits() const; }; @@ -59,8 +60,31 @@ void tst_QFlags::testFlag() const QVERIFY(!btn.testFlag(Qt::LeftButton)); } +void tst_QFlags::testFlagZeroFlag() const +{ + { + Qt::MouseButtons btn = Qt::LeftButton | Qt::RightButton; + /* Qt::NoButton has the value 0. */ + + QVERIFY(!btn.testFlag(Qt::NoButton)); + } + + { + /* A zero enum set should test true with zero. */ + QVERIFY(Qt::MouseButtons().testFlag(Qt::NoButton)); + } + + { + Qt::MouseButtons btn = Qt::NoButton; + QVERIFY(btn.testFlag(Qt::NoButton)); + } +} + void tst_QFlags::testFlagMultiBits() const { + /* Qt::Window is 0x00000001 + * Qt::Dialog is 0x00000002 | Window + */ { const Qt::WindowFlags onlyWindow(Qt::Window); QVERIFY(!onlyWindow.testFlag(Qt::Dialog)); -- cgit v0.12 From 1ed4c52dd7ad3cb6b0d846464b69489031ab68a5 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Mon, 13 Jul 2009 13:31:36 +0200 Subject: QNAM: Fix double sending of a HTTP request In some cases, weird timing issues could occur. In those cases, an EOF was sent twice for the upload data, leading to the HTTP code being confused and sending the request headers twice. Task-number: 257662 Reviewed-by: Thiago Macieira --- src/network/access/qnetworkaccesshttpbackend.cpp | 4 ++++ src/network/access/qnetworkreplyimpl.cpp | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index ce800c2..c57157e 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -628,6 +628,10 @@ void QNetworkAccessHttpBackend::closeUpstreamChannel() { // this indicates that the user finished uploading the data for POST Q_ASSERT(uploadDevice); + + if (uploadDevice->eof) + return; // received a 2nd time. should fix 257662 and 256369 + uploadDevice->eof = true; emit uploadDevice->readChannelFinished(); } diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index 63a9c2d..98944fd 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -92,6 +92,9 @@ void QNetworkReplyImplPrivate::_q_startOperation() void QNetworkReplyImplPrivate::_q_sourceReadyRead() { + if (state != Working) + return; + // read data from the outgoingData QIODevice into our internal buffer enum { DesiredBufferSize = 32 * 1024 }; @@ -131,6 +134,8 @@ void QNetworkReplyImplPrivate::_q_sourceReadChannelFinished() void QNetworkReplyImplPrivate::_q_copyReadyRead() { Q_Q(QNetworkReplyImpl); + if (state != Working) + return; if (!copyDevice || !q->isOpen()) return; -- cgit v0.12 From 3af223d89836fbde213aa2f54d775c9cd840f693 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Mon, 13 Jul 2009 13:37:23 +0200 Subject: Fix font propagation issues with QComboBox and the popup menu. This has always been a bit bumpy, the problem is that the popup normally has its own styling from the desktop, plus it's its own top-level and that is normally a boundary for propagation. Of course, people are surprised by this (especially when it works for editable). So, we need to be a bit better propagating the info. Also the QStyleOptionMenuItem has the correct font, but if it's set on a window, by the time it reaches the popup, its resolve mask is very weak, so it will fail to resolve at all. Setting the point size allows the font to have a bit of strength. Task-number: 257486 Reviewed-by: Jens Bache-Wiig --- src/gui/styles/qcleanlooksstyle.cpp | 6 ++++++ src/gui/styles/qmacstyle_mac.mm | 8 ++++++-- src/gui/widgets/qcombobox.cpp | 6 ++++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/gui/styles/qcleanlooksstyle.cpp b/src/gui/styles/qcleanlooksstyle.cpp index 3855ba7..01f19c6 100644 --- a/src/gui/styles/qcleanlooksstyle.cpp +++ b/src/gui/styles/qcleanlooksstyle.cpp @@ -2042,6 +2042,12 @@ void QCleanlooksStyle::drawControl(ControlElement element, const QStyleOption *o s = s.left(t); } QFont font = menuitem->font; + // font may not have any "hard" flags set. We override + // the point size so that when it is resolved against the device, this font will win. + // This is mainly to handle cases where someone sets the font on the window + // and then the combo inherits it and passes it onward. At that point the resolve mask + // is very, very weak. This makes it stonger. + font.setPointSizeF(menuItem->font.pointSizeF()); if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem) font.setBold(true); diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm index b20db5b..c08009b 100644 --- a/src/gui/styles/qmacstyle_mac.mm +++ b/src/gui/styles/qmacstyle_mac.mm @@ -3991,8 +3991,12 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter const int xm = macItemFrame + maxpmw + macItemHMargin; QFont myFont = mi->font; - if (mi->state & QStyle::State_Mini) - myFont.setPointSize(mi->font.pointSize()); + // myFont may not have any "hard" flags set. We override + // the point size so that when it is resolved against the device, this font will win. + // This is mainly to handle cases where someone sets the font on the window + // and then the combo inherits it and passes it onward. At that point the resolve mask + // is very, very weak. This makes it stonger. + myFont.setPointSizeF(mi->font.pointSizeF()); p->setFont(myFont); p->drawText(xpos, yPos, contentRect.width() - xm - tabwidth + 1, contentRect.height(), text_flags ^ Qt::AlignRight, s); diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp index 1ca878d..097f3d0 100644 --- a/src/gui/widgets/qcombobox.cpp +++ b/src/gui/widgets/qcombobox.cpp @@ -148,8 +148,10 @@ QStyleOptionMenuItem QComboMenuDelegate::getStyleOption(const QStyleOptionViewIt menuOption.rect = option.rect; // Make sure fonts set on the combo box also overrides the font for the popup menu. - if (mCombo->testAttribute(Qt::WA_SetFont) || mCombo->testAttribute(Qt::WA_MacSmallSize) - || mCombo->testAttribute(Qt::WA_MacMiniSize)) + if (mCombo->testAttribute(Qt::WA_SetFont) + || mCombo->testAttribute(Qt::WA_MacSmallSize) + || mCombo->testAttribute(Qt::WA_MacMiniSize) + || mCombo->font() != qt_app_fonts_hash()->value("QComboBox", QFont())) menuOption.font = mCombo->font(); else menuOption.font = qt_app_fonts_hash()->value("QComboMenuItem", mCombo->font()); -- cgit v0.12 From 85fbffa12bcd38b08030561335305c3226312bc6 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 13 Jul 2009 13:46:46 +0200 Subject: Doc: Explicitly declare the module for each namespace to prevent strange omissions when qdoc is used in certain Windows environments. Task-number: 256415 Reviewed-by: Trust Me --- doc/src/qnamespace.qdoc | 1 + doc/src/qsql.qdoc | 2 +- src/corelib/concurrent/qtconcurrentmap.cpp | 1 + src/opengl/qgl.cpp | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/src/qnamespace.qdoc b/doc/src/qnamespace.qdoc index b691ac7..d509912 100644 --- a/doc/src/qnamespace.qdoc +++ b/doc/src/qnamespace.qdoc @@ -41,6 +41,7 @@ /*! \namespace Qt + \inmodule QtCore \brief The Qt namespace contains miscellaneous identifiers used throughout the Qt library. diff --git a/doc/src/qsql.qdoc b/doc/src/qsql.qdoc index 5315413..0f690e8 100644 --- a/doc/src/qsql.qdoc +++ b/doc/src/qsql.qdoc @@ -41,12 +41,12 @@ /*! \namespace QSql + \inmodule QtSql \brief The QSql namespace contains miscellaneous identifiers used throughout the Qt SQL library. \ingroup database \mainclass - \omit ### \module sql \endomit \sa {QtSql Module} */ diff --git a/src/corelib/concurrent/qtconcurrentmap.cpp b/src/corelib/concurrent/qtconcurrentmap.cpp index b8c753a..46d2400 100644 --- a/src/corelib/concurrent/qtconcurrentmap.cpp +++ b/src/corelib/concurrent/qtconcurrentmap.cpp @@ -41,6 +41,7 @@ /*! \namespace QtConcurrent + \inmodule QtCore \since 4.4 \brief The QtConcurrent namespace provides high-level APIs that make it possible to write multi-threaded programs without using low-level diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index a9f8ede..0169ea2 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -142,6 +142,7 @@ QGLSignalProxy *QGLSignalProxy::instance() /*! \namespace QGL + \inmodule QtOpenGL \brief The QGL namespace specifies miscellaneous identifiers used in the Qt OpenGL module. -- cgit v0.12 From cb3bddc9a5e4a664500eec3997dedadd67de3652 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Mon, 13 Jul 2009 13:47:50 +0200 Subject: tst_qnetworkreply: qDebug instead of qWarning --- tests/auto/qnetworkreply/tst_qnetworkreply.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 18919a7..ff315de 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -3186,7 +3186,7 @@ void tst_QNetworkReply::httpDownloadPerformance() QVERIFY(!QTestEventLoop::instance().timeout()); qint64 elapsed = time.elapsed(); - qWarning() << "tst_QNetworkReply::httpDownloadPerformance" << elapsed << "msec, " + qDebug() << "tst_QNetworkReply::httpDownloadPerformance" << elapsed << "msec, " << ((UploadSize/1024.0)/(elapsed/1000.0)) << " kB/sec"; delete reply; -- cgit v0.12 From d54224252d56a50b42c8991308840ea1acde8f30 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Mon, 13 Jul 2009 13:51:25 +0200 Subject: tst_qnetworkreply: qDebug instead of qWarning --- tests/auto/qnetworkreply/tst_qnetworkreply.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 8318b60..cb1cb9b 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -3185,7 +3185,7 @@ void tst_QNetworkReply::httpUploadPerformance() QVERIFY(!QTestEventLoop::instance().timeout()); qint64 elapsed = time.elapsed(); - qWarning() << "tst_QNetworkReply::httpUploadPerformance" << elapsed << "msec, " + qDebug() << "tst_QNetworkReply::httpUploadPerformance" << elapsed << "msec, " << ((UploadSize/1024.0)/(elapsed/1000.0)) << " kB/sec"; reader.exit(); @@ -3815,7 +3815,7 @@ void tst_QNetworkReply::httpDownloadPerformance() QVERIFY(!QTestEventLoop::instance().timeout()); qint64 elapsed = time.elapsed(); - qWarning() << "tst_QNetworkReply::httpDownloadPerformance" << elapsed << "msec, " + qDebug() << "tst_QNetworkReply::httpDownloadPerformance" << elapsed << "msec, " << ((UploadSize/1024.0)/(elapsed/1000.0)) << " kB/sec"; delete reply; -- cgit v0.12 From 32182d107fa75e5619ecc91a81f50626f429ebe1 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 13 Jul 2009 14:03:39 +0200 Subject: QTreeView: now dragging lots of items is fast --- src/corelib/kernel/qabstractitemmodel.cpp | 2 +- src/corelib/kernel/qmimedata.cpp | 2 +- src/corelib/kernel/qvariant.cpp | 4 +-- src/gui/itemviews/qabstractitemview.cpp | 2 +- src/gui/itemviews/qlistview.cpp | 1 - src/gui/itemviews/qtreeview.cpp | 44 +++++++++++++++++++++++++++++++ src/gui/itemviews/qtreeview_p.h | 2 ++ 7 files changed, 51 insertions(+), 6 deletions(-) diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp index 914f44f..1c3371f 100644 --- a/src/corelib/kernel/qabstractitemmodel.cpp +++ b/src/corelib/kernel/qabstractitemmodel.cpp @@ -1407,7 +1407,7 @@ QMap QAbstractItemModel::itemData(const QModelIndex &index) const QMap roles; for (int i = 0; i < Qt::UserRole; ++i) { QVariant variantData = data(index, i); - if (variantData.type() != QVariant::Invalid) + if (variantData.isValid()) roles.insert(i, variantData); } return roles; diff --git a/src/corelib/kernel/qmimedata.cpp b/src/corelib/kernel/qmimedata.cpp index 3d2a7cb..4a1ba9f 100644 --- a/src/corelib/kernel/qmimedata.cpp +++ b/src/corelib/kernel/qmimedata.cpp @@ -105,7 +105,7 @@ QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QVariant::Ty Q_Q(const QMimeData); QVariant data = q->retrieveData(format, type); - if (data.type() == type || data.type() == QVariant::Invalid) + if (data.type() == type || !data.isValid()) return data; // provide more conversion possiblities than just what QVariant provides diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 8bf70cb..2ef9de4 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -1905,7 +1905,7 @@ void QVariant::load(QDataStream &s) create(static_cast(u), 0); d.is_null = is_null; - if (d.type == QVariant::Invalid) { + if (!isValid()) { // Since we wrote something, we should read something QString x; s >> x; @@ -1949,7 +1949,7 @@ void QVariant::save(QDataStream &s) const s << QMetaType::typeName(userType()); } - if (d.type == QVariant::Invalid) { + if (!isValid()) { s << QString(); return; } diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index a4a69c3..8887977 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -3918,7 +3918,7 @@ QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes, QStyleOptionViewItemV4 option = viewOptionsV4(); option.state |= QStyle::State_Selected; for (int j = 0; j < paintPairs.count(); ++j) { - option.rect = paintPairs.at(j).first.translated(r->topLeft()); + option.rect = paintPairs.at(j).first.translated(-r->topLeft()); const QModelIndex ¤t = paintPairs.at(j).second; delegateForIndex(current)->paint(&painter, option, current); } diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp index 9a94b31..40f28d4 100644 --- a/src/gui/itemviews/qlistview.cpp +++ b/src/gui/itemviews/qlistview.cpp @@ -722,7 +722,6 @@ QItemViewPaintPairs QListViewPrivate::draggablePaintPairs(const QModelIndexList QRect &rect = *r; const QRect viewportRect = viewport->rect(); QItemViewPaintPairs ret; - intersectingSet(viewportRect); const QSet visibleIndexes = intersectingSet(viewportRect).toList().toSet(); for (int i = 0; i < indexes.count(); ++i) { const QModelIndex &index = indexes.at(i); diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index f13ff0c..7084e6d 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -1321,6 +1321,50 @@ void QTreeViewPrivate::_q_modelDestroyed() } /*! + \reimp + + We have a QTreeView way of knowing what elements are on the viewport +*/ +QItemViewPaintPairs QTreeViewPrivate::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const +{ + Q_ASSERT(r); + return QAbstractItemViewPrivate::draggablePaintPairs(indexes, r); + Q_Q(const QTreeView); + QRect &rect = *r; + const QRect viewportRect = viewport->rect(); + int itemOffset = 0; + int row = firstVisibleItem(&itemOffset); + QPair startEnd = startAndEndColumns(viewportRect); + QVector columns; + for (int i = startEnd.first; i <= startEnd.second; ++i) { + int logical = header->logicalIndex(i); + if (!header->isSectionHidden(logical)) + columns += logical; + } + QSet visibleIndexes; + for (; itemOffset < viewportRect.bottom() && row < viewItems.count(); ++row) { + const QModelIndex &index = viewItems.at(row).index; + for (int colIndex = 0; colIndex < columns.count(); ++colIndex) + visibleIndexes += index.sibling(index.row(), columns.at(colIndex)); + itemOffset += itemHeight(row); + } + + //now that we have the visible indexes, we can try to find those which are selected + QItemViewPaintPairs ret; + for (int i = 0; i < indexes.count(); ++i) { + const QModelIndex &index = indexes.at(i); + if (visibleIndexes.contains(index)) { + const QRect current = q->visualRect(index); + ret += qMakePair(current, index); + rect |= current; + } + } + rect &= viewportRect; + return ret; +} + + +/*! \since 4.2 Draws the part of the tree intersecting the given \a region using the specified \a painter. diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h index 6fb2e41..546dc75 100644 --- a/src/gui/itemviews/qtreeview_p.h +++ b/src/gui/itemviews/qtreeview_p.h @@ -89,6 +89,8 @@ public: ~QTreeViewPrivate() {} void initialize(); + QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const; + #ifndef QT_NO_ANIMATION struct AnimatedOperation : public QVariantAnimation { -- cgit v0.12 From eb594be13ae17361c1de3539e34e84a1d8c324c5 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 13 Jul 2009 15:14:19 +0200 Subject: fix bug in qmake DEPLOYMENT variable The documentation states "The default deployment target path for Windows CE is %CSIDL_PROGRAM_FILES%\target, which usually gets expanded to \Program Files\target." Now this statement is true. Task-number: 257053 Reviewed-by: mauricek --- qmake/generators/win32/msvc_vcproj.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 50f78d7..5f250bf 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -1239,9 +1239,8 @@ void VcprojGenerator::initDeploymentTool() foreach(QString item, project->values("DEPLOYMENT")) { // get item.path QString devicePath = project->first(item + ".path"); - // if the path does not exist, skip it if (devicePath.isEmpty()) - continue; + devicePath = targetPath; // check if item.path is relative (! either /,\ or %) if (!(devicePath.at(0) == QLatin1Char('/') || devicePath.at(0) == QLatin1Char('\\') -- cgit v0.12 From f7a11ee28484320129fec25c00e0f616ff6751bc Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 13 Jul 2009 15:29:37 +0200 Subject: doc: Use \inheaderfile to show which include file to include. Letting qdoc output it automatically produces the wrong header file name. Task-number: 217268 210171 220664 --- doc/src/qsql.qdoc | 1 + src/corelib/concurrent/qtconcurrentmap.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/src/qsql.qdoc b/doc/src/qsql.qdoc index 0f690e8..bb8f090 100644 --- a/doc/src/qsql.qdoc +++ b/doc/src/qsql.qdoc @@ -45,6 +45,7 @@ \brief The QSql namespace contains miscellaneous identifiers used throughout the Qt SQL library. + \inheaderfile QtSql \ingroup database \mainclass diff --git a/src/corelib/concurrent/qtconcurrentmap.cpp b/src/corelib/concurrent/qtconcurrentmap.cpp index 46d2400..797f335 100644 --- a/src/corelib/concurrent/qtconcurrentmap.cpp +++ b/src/corelib/concurrent/qtconcurrentmap.cpp @@ -48,7 +48,7 @@ threading primitives. See the \l {threads.html#qtconcurrent-intro}{Qt Concurrent} section in the \l{threads.html}{threading} documentation. - + \inheaderfile QtCore \ingroup thread */ -- cgit v0.12 From 45efa082135cbf97820a5ce7025685d22bd926ce Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 10 Jul 2009 22:19:46 +0200 Subject: factor out linguist-specific part it is simpler to keep it in sync with creator then. --- tools/linguist/lrelease/main.cpp | 2 +- tools/linguist/lupdate/main.cpp | 1 + tools/linguist/shared/profileevaluator.cpp | 60 ---------------- tools/linguist/shared/profileevaluator.h | 6 -- tools/linguist/shared/proparser.pri | 2 + tools/linguist/shared/proreader.cpp | 108 +++++++++++++++++++++++++++++ tools/linguist/shared/proreader.h | 56 +++++++++++++++ 7 files changed, 168 insertions(+), 67 deletions(-) create mode 100644 tools/linguist/shared/proreader.cpp create mode 100644 tools/linguist/shared/proreader.h diff --git a/tools/linguist/lrelease/main.cpp b/tools/linguist/lrelease/main.cpp index 905a399..845dcb8 100644 --- a/tools/linguist/lrelease/main.cpp +++ b/tools/linguist/lrelease/main.cpp @@ -41,7 +41,7 @@ #include "translator.h" #include "translatortools.h" -#include "profileevaluator.h" +#include "proreader.h" #include #include diff --git a/tools/linguist/lupdate/main.cpp b/tools/linguist/lupdate/main.cpp index 52a57fb..6e8b941 100644 --- a/tools/linguist/lupdate/main.cpp +++ b/tools/linguist/lupdate/main.cpp @@ -42,6 +42,7 @@ #include "translator.h" #include "translatortools.h" #include "profileevaluator.h" +#include "proreader.h" #include #include diff --git a/tools/linguist/shared/profileevaluator.cpp b/tools/linguist/shared/profileevaluator.cpp index 4ea9c10..54c5d9a 100644 --- a/tools/linguist/shared/profileevaluator.cpp +++ b/tools/linguist/shared/profileevaluator.cpp @@ -1726,64 +1726,4 @@ void ProFileEvaluator::setVerbose(bool on) d->m_verbose = on; } -void evaluateProFile(const ProFileEvaluator &visitor, QHash *varMap) -{ - QStringList sourceFiles; - QString codecForTr; - QString codecForSource; - QStringList tsFileNames; - - // app/lib template - sourceFiles += visitor.values(QLatin1String("SOURCES")); - sourceFiles += visitor.values(QLatin1String("HEADERS")); - tsFileNames = visitor.values(QLatin1String("TRANSLATIONS")); - - QStringList trcodec = visitor.values(QLatin1String("CODEC")) - + visitor.values(QLatin1String("DEFAULTCODEC")) - + visitor.values(QLatin1String("CODECFORTR")); - if (!trcodec.isEmpty()) - codecForTr = trcodec.last(); - - QStringList srccodec = visitor.values(QLatin1String("CODECFORSRC")); - if (!srccodec.isEmpty()) - codecForSource = srccodec.last(); - - QStringList forms = visitor.values(QLatin1String("INTERFACES")) - + visitor.values(QLatin1String("FORMS")) - + visitor.values(QLatin1String("FORMS3")); - sourceFiles << forms; - - sourceFiles.sort(); - sourceFiles.removeDuplicates(); - tsFileNames.sort(); - tsFileNames.removeDuplicates(); - - varMap->insert("SOURCES", sourceFiles); - varMap->insert("CODECFORTR", QStringList() << codecForTr); - varMap->insert("CODECFORSRC", QStringList() << codecForSource); - varMap->insert("TRANSLATIONS", tsFileNames); -} - -bool evaluateProFile(const QString &fileName, bool verbose, QHash *varMap) -{ - QFileInfo fi(fileName); - if (!fi.exists()) - return false; - - ProFile pro(fi.absoluteFilePath()); - - ProFileEvaluator visitor; - visitor.setVerbose(verbose); - - if (!visitor.queryProFile(&pro)) - return false; - - if (!visitor.accept(&pro)) - return false; - - evaluateProFile(visitor, varMap); - - return true; -} - QT_END_NAMESPACE diff --git a/tools/linguist/shared/profileevaluator.h b/tools/linguist/shared/profileevaluator.h index 5f35ea8..78d8fce 100644 --- a/tools/linguist/shared/profileevaluator.h +++ b/tools/linguist/shared/profileevaluator.h @@ -52,12 +52,6 @@ QT_BEGIN_NAMESPACE -class ProFile; -class ProFileEvaluator; - -void evaluateProFile(const ProFileEvaluator &visitor, QHash *varMap); -bool evaluateProFile(const QString &fileName, bool verbose, QHash *varMap); - class ProFileEvaluator { public: diff --git a/tools/linguist/shared/proparser.pri b/tools/linguist/shared/proparser.pri index 372247e..99d32e7 100644 --- a/tools/linguist/shared/proparser.pri +++ b/tools/linguist/shared/proparser.pri @@ -2,11 +2,13 @@ INCLUDEPATH *= $$PWD HEADERS += \ + $$PWD/proreader.h \ $$PWD/abstractproitemvisitor.h \ $$PWD/proitems.h \ $$PWD/profileevaluator.h \ $$PWD/proparserutils.h SOURCES += \ + $$PWD/proreader.cpp \ $$PWD/proitems.cpp \ $$PWD/profileevaluator.cpp diff --git a/tools/linguist/shared/proreader.cpp b/tools/linguist/shared/proreader.cpp new file mode 100644 index 0000000..492c2ef --- /dev/null +++ b/tools/linguist/shared/proreader.cpp @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Linguist 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 "profileevaluator.h" + +#include + +QT_BEGIN_NAMESPACE + +void evaluateProFile(const ProFileEvaluator &visitor, QHash *varMap) +{ + QStringList sourceFiles; + QString codecForTr; + QString codecForSource; + QStringList tsFileNames; + + // app/lib template + sourceFiles += visitor.values(QLatin1String("SOURCES")); + sourceFiles += visitor.values(QLatin1String("HEADERS")); + tsFileNames = visitor.values(QLatin1String("TRANSLATIONS")); + + QStringList trcodec = visitor.values(QLatin1String("CODEC")) + + visitor.values(QLatin1String("DEFAULTCODEC")) + + visitor.values(QLatin1String("CODECFORTR")); + if (!trcodec.isEmpty()) + codecForTr = trcodec.last(); + + QStringList srccodec = visitor.values(QLatin1String("CODECFORSRC")); + if (!srccodec.isEmpty()) + codecForSource = srccodec.last(); + + QStringList forms = visitor.values(QLatin1String("INTERFACES")) + + visitor.values(QLatin1String("FORMS")) + + visitor.values(QLatin1String("FORMS3")); + sourceFiles << forms; + + sourceFiles.sort(); + sourceFiles.removeDuplicates(); + tsFileNames.sort(); + tsFileNames.removeDuplicates(); + + varMap->insert("SOURCES", sourceFiles); + varMap->insert("CODECFORTR", QStringList() << codecForTr); + varMap->insert("CODECFORSRC", QStringList() << codecForSource); + varMap->insert("TRANSLATIONS", tsFileNames); +} + +bool evaluateProFile(const QString &fileName, bool verbose, QHash *varMap) +{ + QFileInfo fi(fileName); + if (!fi.exists()) + return false; + + ProFile pro(fi.absoluteFilePath()); + + ProFileEvaluator visitor; + visitor.setVerbose(verbose); + + if (!visitor.queryProFile(&pro)) + return false; + + if (!visitor.accept(&pro)) + return false; + + evaluateProFile(visitor, varMap); + + return true; +} + +QT_END_NAMESPACE diff --git a/tools/linguist/shared/proreader.h b/tools/linguist/shared/proreader.h new file mode 100644 index 0000000..31e2e6f --- /dev/null +++ b/tools/linguist/shared/proreader.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Linguist 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$ +** +****************************************************************************/ + +#ifndef PROREADER_H +#define PROREADER_H + +#include + +QT_BEGIN_NAMESPACE + +class ProFileEvaluator; + +void evaluateProFile(const ProFileEvaluator &visitor, QHash *varMap); +bool evaluateProFile(const QString &fileName, bool verbose, QHash *varMap); + +QT_END_NAMESPACE + +#endif // PROREADER_H -- cgit v0.12 From e2f381365bf2158095c5c7236fc4b2f842b9fa8c Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 13 Jul 2009 16:20:44 +0200 Subject: implement proper vpath handling this also removes the bogus special casing of various filename-containing variables inside the pro parser. while this is a feature as such, it restores backwards compatibility without damaging the correct behavior again, so it qualifies for 4.5. based on a2f40fce2a1cf3c19a13fa27eea08192493ab76e from creator Task-number: 254098 --- .../testdata/good/proparsingpaths/file1.cpp | 9 ++ .../testdata/good/proparsingpaths/filter.cpp | 9 ++ .../testdata/good/proparsingpaths/project.pro | 10 ++ .../good/proparsingpaths/project.ts.result | 31 +++++ .../testdata/good/proparsingpaths/sub/sub.pri | 3 + .../testdata/good/proparsingpaths/sub/subfile1.cpp | 9 ++ .../good/proparsingpaths/sub/subfilter.cpp | 9 ++ tools/linguist/lupdate/main.cpp | 2 +- tools/linguist/shared/profileevaluator.cpp | 155 +++++++-------------- tools/linguist/shared/profileevaluator.h | 4 + tools/linguist/shared/proreader.cpp | 43 ++++-- tools/linguist/shared/proreader.h | 3 +- 12 files changed, 173 insertions(+), 114 deletions(-) create mode 100644 tests/auto/linguist/lupdate/testdata/good/proparsingpaths/file1.cpp create mode 100644 tests/auto/linguist/lupdate/testdata/good/proparsingpaths/filter.cpp create mode 100644 tests/auto/linguist/lupdate/testdata/good/proparsingpaths/project.pro create mode 100644 tests/auto/linguist/lupdate/testdata/good/proparsingpaths/project.ts.result create mode 100644 tests/auto/linguist/lupdate/testdata/good/proparsingpaths/sub/sub.pri create mode 100644 tests/auto/linguist/lupdate/testdata/good/proparsingpaths/sub/subfile1.cpp create mode 100644 tests/auto/linguist/lupdate/testdata/good/proparsingpaths/sub/subfilter.cpp diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/file1.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/file1.cpp new file mode 100644 index 0000000..ad87e70 --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/file1.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", "top-level wildcard"); +} + + diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/filter.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/filter.cpp new file mode 100644 index 0000000..912963d --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/filter.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", "top-level direct"); +} + + diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/project.pro b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/project.pro new file mode 100644 index 0000000..820b4fa --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/project.pro @@ -0,0 +1,10 @@ +SOURCES += file*.cpp filter.cpp non-existing.cpp + +include(sub/sub.pri) + +TRANSLATIONS = project.ts + +exists( $$TRANSLATIONS ) { + win32: system(del $$TRANSLATIONS) + unix: system(rm -f $$TRANSLATIONS) +} diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/project.ts.result new file mode 100644 index 0000000..470d6eb --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/project.ts.result @@ -0,0 +1,31 @@ + + + + + QApplication + + + Hello world + top-level wildcard + + + + + Hello world + top-level direct + + + + + Hello world + nested wildcard + + + + + Hello world + nested direct + + + + diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/sub/sub.pri b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/sub/sub.pri new file mode 100644 index 0000000..a6079f9 --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/sub/sub.pri @@ -0,0 +1,3 @@ +VPATH += $$PWD + +SOURCES += sub/subfile?.cpp subfilter.cpp diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/sub/subfile1.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/sub/subfile1.cpp new file mode 100644 index 0000000..807d296 --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/sub/subfile1.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", "nested wildcard"); +} + + diff --git a/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/sub/subfilter.cpp b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/sub/subfilter.cpp new file mode 100644 index 0000000..6e5dd25 --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/proparsingpaths/sub/subfilter.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", "nested direct"); +} + + diff --git a/tools/linguist/lupdate/main.cpp b/tools/linguist/lupdate/main.cpp index 6e8b941..78e5b5f 100644 --- a/tools/linguist/lupdate/main.cpp +++ b/tools/linguist/lupdate/main.cpp @@ -452,7 +452,7 @@ int main(int argc, char **argv) continue; } - evaluateProFile(visitor, &variables); + evaluateProFile(visitor, &variables, pfi.absolutePath()); sourceFiles = variables.value("SOURCES"); diff --git a/tools/linguist/shared/profileevaluator.cpp b/tools/linguist/shared/profileevaluator.cpp index 54c5d9a..3b8a1b8 100644 --- a/tools/linguist/shared/profileevaluator.cpp +++ b/tools/linguist/shared/profileevaluator.cpp @@ -107,9 +107,6 @@ public: QString propertyValue(const QString &val) const; bool isActiveConfig(const QString &config, bool regex = false); - QStringList expandPattern(const QString &pattern); - void expandPatternHelper(const QString &relName, const QString &absName, - QStringList &sources_out); QStringList expandVariableReferences(const QString &value); QStringList evaluateExpandFunction(const QString &function, const QString &arguments); QString format(const char *format) const; @@ -559,29 +556,6 @@ bool ProFileEvaluator::Private::visitProValue(ProValue *value) m_prevLineNo = m_lineNo; m_prevProFile = currentProFile(); - // The following two blocks fix bug 180128 by making all "interesting" - // file name absolute in each .pro file, not just the top most one - if (varName == QLatin1String("SOURCES") - || varName == QLatin1String("HEADERS") - || varName == QLatin1String("INTERFACES") - || varName == QLatin1String("FORMS") - || varName == QLatin1String("FORMS3") - || varName == QLatin1String("RESOURCES")) { - // matches only existent files, expand certain(?) patterns - QStringList vv; - for (int i = v.count(); --i >= 0; ) - vv << expandPattern(v[i]); - v = vv; - } - - if (varName == QLatin1String("TRANSLATIONS")) { - // also matches non-existent files, but does not expand pattern - QString dir = QFileInfo(currentFileName()).absolutePath(); - dir += QLatin1Char('/'); - for (int i = v.count(); --i >= 0; ) - v[i] = QFileInfo(dir, v[i]).absoluteFilePath(); - } - switch (m_variableOperator) { case ProVariable::UniqueAddOperator: // * insertUnique(&m_valuemap, varName, v, true); @@ -1537,82 +1511,6 @@ bool ProFileEvaluator::Private::evaluateFeatureFile(const QString &fileName, boo return fn.isEmpty() ? false : evaluateFile(fn, result); } -void ProFileEvaluator::Private::expandPatternHelper(const QString &relName, const QString &absName, - QStringList &sources_out) -{ - const QStringList vpaths = values(QLatin1String("VPATH")) - + values(QLatin1String("QMAKE_ABSOLUTE_SOURCE_PATH")) - + values(QLatin1String("DEPENDPATH")) - + values(QLatin1String("VPATH_SOURCES")); - - QFileInfo fi(absName); - bool found = fi.exists(); - // Search in all vpaths - if (!found) { - foreach (const QString &vpath, vpaths) { - fi.setFile(vpath + QDir::separator() + relName); - if (fi.exists()) { - found = true; - break; - } - } - } - - if (found) { - sources_out += fi.absoluteFilePath(); // Not resolving symlinks - } else { - QString val = relName; - QString dir; - QString wildcard = val; - QString real_dir; - if (wildcard.lastIndexOf(QLatin1Char('/')) != -1) { - dir = wildcard.left(wildcard.lastIndexOf(QLatin1Char('/')) + 1); - real_dir = dir; - wildcard = wildcard.right(wildcard.length() - dir.length()); - } - - if (real_dir.isEmpty() || QFileInfo(real_dir).exists()) { - QStringList files = QDir(real_dir).entryList(QStringList(wildcard)); - if (files.isEmpty()) { - q->logMessage(format("Failure to find %1").arg(val)); - } else { - QString a; - for (int i = files.count() - 1; i >= 0; --i) { - if (files[i] == QLatin1String(".") || files[i] == QLatin1String("..")) - continue; - a = dir + files[i]; - sources_out += a; - } - } - } else { - q->logMessage(format("Cannot match %1/%2, as %3 does not exist.") - .arg(real_dir).arg(wildcard).arg(real_dir)); - } - } -} - - -/* - * Lookup of files are done in this order: - * 1. look in pwd - * 2. look in vpaths - * 3. expand wild card files relative from the profiles folder - **/ - -// FIXME: This code supports something that I'd consider a flaw in .pro file syntax -// which is not even documented. So arguably this can be ditched completely... -QStringList ProFileEvaluator::Private::expandPattern(const QString& pattern) -{ - if (!currentProFile()) - return QStringList(); - - QStringList sources_out; - const QString absName = QDir::cleanPath(QDir::current().absoluteFilePath(pattern)); - - expandPatternHelper(pattern, absName, sources_out); - return sources_out; -} - QString ProFileEvaluator::Private::format(const char *fmt) const { ProFile *pro = currentProFile(); @@ -1654,6 +1552,59 @@ QStringList ProFileEvaluator::values(const QString &variableName, const ProFile return d->values(variableName, pro); } +QStringList ProFileEvaluator::absolutePathValues( + const QString &variable, const QString &baseDirectory) const +{ + QStringList result; + foreach (const QString &el, values(variable)) { + const QFileInfo info = QFileInfo(baseDirectory, el); + if (info.isDir()) + result << QDir::cleanPath(info.absoluteFilePath()); + } + return result; +} + +QStringList ProFileEvaluator::absoluteFileValues( + const QString &variable, const QString &baseDirectory, const QStringList &searchDirs, + const ProFile *pro) const +{ + QStringList result; + foreach (const QString &el, pro ? values(variable, pro) : values(variable)) { + QFileInfo info(el); + if (info.isAbsolute()) { + if (info.exists()) { + result << QDir::cleanPath(el); + goto next; + } + } else { + foreach (const QString &dir, searchDirs) { + QFileInfo info(dir, el); + if (info.isFile()) { + result << QDir::cleanPath(info.filePath()); + goto next; + } + } + if (baseDirectory.isEmpty()) + goto next; + info = QFileInfo(baseDirectory, el); + } + { + QFileInfo baseInfo(info.absolutePath()); + if (baseInfo.exists()) { + QString wildcard = info.fileName(); + if (wildcard.contains(QLatin1Char('*')) || wildcard.contains(QLatin1Char('?'))) { + QDir theDir(QDir::cleanPath(baseInfo.filePath())); + foreach (const QString &fn, theDir.entryList(QStringList(wildcard))) + if (fn != QLatin1String(".") && fn != QLatin1String("..")) + result << theDir.absoluteFilePath(fn); + } + } + } + next: ; + } + return result; +} + ProFileEvaluator::TemplateType ProFileEvaluator::templateType() { QStringList templ = values(QLatin1String("TEMPLATE")); diff --git a/tools/linguist/shared/profileevaluator.h b/tools/linguist/shared/profileevaluator.h index 78d8fce..ae09a59 100644 --- a/tools/linguist/shared/profileevaluator.h +++ b/tools/linguist/shared/profileevaluator.h @@ -76,6 +76,10 @@ public: void addProperties(const QHash &properties); QStringList values(const QString &variableName) const; QStringList values(const QString &variableName, const ProFile *pro) const; + QStringList absolutePathValues(const QString &variable, const QString &baseDirectory) const; + QStringList absoluteFileValues( + const QString &variable, const QString &baseDirectory, const QStringList &searchDirs, + const ProFile *pro) const; QString propertyValue(const QString &val) const; // for our descendents diff --git a/tools/linguist/shared/proreader.cpp b/tools/linguist/shared/proreader.cpp index 492c2ef..3400f20 100644 --- a/tools/linguist/shared/proreader.cpp +++ b/tools/linguist/shared/proreader.cpp @@ -41,21 +41,49 @@ #include "profileevaluator.h" +#include #include QT_BEGIN_NAMESPACE -void evaluateProFile(const ProFileEvaluator &visitor, QHash *varMap) +static QStringList getSources(const char *var, const char *vvar, const QStringList &baseVPaths, + const QString &projectDir, const ProFileEvaluator &visitor) { + QStringList vPaths = + visitor.absolutePathValues(QLatin1String(vvar), projectDir); + vPaths += baseVPaths; + vPaths.removeDuplicates(); + return visitor.absoluteFileValues(QLatin1String(var), projectDir, vPaths, 0); +} + +void evaluateProFile(const ProFileEvaluator &visitor, QHash *varMap, + const QString &projectDir) +{ + QStringList baseVPaths; + baseVPaths += visitor.absolutePathValues(QLatin1String("VPATH"), projectDir); + baseVPaths << projectDir; // QMAKE_ABSOLUTE_SOURCE_PATH + baseVPaths += visitor.absolutePathValues(QLatin1String("DEPENDPATH"), projectDir); + baseVPaths.removeDuplicates(); + QStringList sourceFiles; QString codecForTr; QString codecForSource; QStringList tsFileNames; // app/lib template - sourceFiles += visitor.values(QLatin1String("SOURCES")); - sourceFiles += visitor.values(QLatin1String("HEADERS")); - tsFileNames = visitor.values(QLatin1String("TRANSLATIONS")); + sourceFiles += getSources("SOURCES", "VPATH_SOURCES", baseVPaths, projectDir, visitor); + + sourceFiles += getSources("FORMS", "VPATH_FORMS", baseVPaths, projectDir, visitor); + sourceFiles += getSources("FORMS3", "VPATH_FORMS3", baseVPaths, projectDir, visitor); + + QStringList vPathsInc = baseVPaths; + vPathsInc += visitor.absolutePathValues(QLatin1String("INCLUDEPATH"), projectDir); + vPathsInc.removeDuplicates(); + sourceFiles += visitor.absoluteFileValues(QLatin1String("HEADERS"), projectDir, vPathsInc, 0); + + QDir proDir(projectDir); + foreach (const QString &tsFile, visitor.values(QLatin1String("TRANSLATIONS"))) + tsFileNames << QFileInfo(proDir, tsFile).filePath(); QStringList trcodec = visitor.values(QLatin1String("CODEC")) + visitor.values(QLatin1String("DEFAULTCODEC")) @@ -67,11 +95,6 @@ void evaluateProFile(const ProFileEvaluator &visitor, QHash *varMap); +void evaluateProFile(const ProFileEvaluator &visitor, QHash *varMap, + const QString &projectDir); bool evaluateProFile(const QString &fileName, bool verbose, QHash *varMap); QT_END_NAMESPACE -- cgit v0.12 From 8f65472671406ad5881b119ba32b075b828bbb1a Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 13 Jul 2009 16:57:38 +0200 Subject: Updated WebKit from /home/shausman/src/webkit/trunk to origin/qtwebkit-4.5 ( eb4957a561d3f85d4cd5602832375c66f378b521 ) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes in WebKit since the last update: ++ b/LayoutTests/ChangeLog 2009-06-04 Ariya Hidayat Rubber-stamped by Tor Arne Vestbø. Added Qt-specific expected result for Canvas pointInPath's test. Qt's QPainterPath::contains(point) returns false if the point is exactly along one of the edges (except the origin). Until we find a workaround for this, compensate it in the expected result. * platform/qt/fast/canvas/pointInPath-expected.txt: Added. 2009-01-11 Simon Fraser Reviewed by Oliver Hunt https://bugs.webkit.org/show_bug.cgi?id=23242 Add testcase for incremental repaint after use of ctx.transform(), and enhanced isPointInPath testcase to do testing after use of ctx.transform(). * fast/canvas/canvas-incremental-repaint-2.html: Added. * fast/canvas/pointInPath-expected.txt: * fast/canvas/pointInPath.js: * platform/mac/fast/canvas/canvas-incremental-repaint-2-expected.checksum: Added. * platform/mac/fast/canvas/canvas-incremental-repaint-2-expected.png: Added. * platform/mac/fast/canvas/canvas-incremental-repaint-2-expected.txt: Added. ++ b/WebCore/ChangeLog 2008-12-18 Bernhard Rosenkraenzer Reviewed by Darin Adler. https://bugs.webkit.org/show_bug.cgi?id=22205 Fix compatibility with bison 2.4, partially based on older patch by Priit Laes * WebCore/css/CSSGrammar.y: Made compatible with bison 2.4 2009-07-13 Cédric Luthi Reviewed by Tor Arne Vestbø. Fix NPWindow clip rect in PluginViewMac The rect should be in window-coordinates. This bug can be observed with Flash 10 here: http://www.permadi.com/tutorial/cursorTracker/ * plugins/mac/PluginViewMac.cpp: 2009-07-13 Simon Hausmann Reviewed by Ariya Hidayat. Fix Qt implementation of WebCore::directoryName to return the absolute directory name instead of the base file name. * platform/qt/FileSystemQt.cpp: (WebCore::directoryName): 2009-07-13 Simon Hausmann Reviewed by Ariya Hidayat. Fix WebCore::Path::isEmpty() for the Qt port to return true if there is no element in the path. QPainterPath::isEmpty() returns also true if there is one single MoveTo element inside, which makes sense but doesn't patch Webcore's is-empty definition. * platform/graphics/qt/PathQt.cpp: (WebCore::Path::isEmpty): Use elementCount() == 0. 2009-01-11 Simon Fraser Reviewed by Oliver Hunt https://bugs.webkit.org/show_bug.cgi?id=23242 Fix CanvasRenderingContext2D::transform to do a pre-multiply, rather than a post-multiply into m_transform. This bug did not affect drawing, but did cause m_transform to be incorrect, which impacted willDraw(), and isPointInPath. Test: fast/canvas/canvas-incremental-repaint-2.html * html/CanvasRenderingContext2D.cpp: (WebCore::CanvasRenderingContext2D::transform): 2009-07-04 Sriram Yadavalli Reviewed by Simon Hausmann. https://bugs.webkit.org/show_bug.cgi?id=26439 QtWebKit fails in loading www.nytimes.com in Windows/Linux QNetworkReplyHandler is ignoring content associated with 401 error. This causes the XHR response handling to fail. Simon: Added also ProxyAuthenticationRequiredError, to handle the same case when going through proxies, as suggested by Prasanth. * platform/network/qt/QNetworkReplyHandler.cpp: (WebCore::QNetworkReplyHandler::finish): ++ b/WebKit/qt/ChangeLog Fix crash with plugins when the plugin stream is cancelled. Similar to r26667 handle the case where didReceiveResponse on the plugin view results in failure to set up the stream and setMainDocumentError being called instead. This will set the m_pluginView back to 0 and we need check for it before calling didReceiveData. This was triggered by consecutive execution of LayoutTests/plugins/return-error-from-new-stream-callback-in-full-frame-plugin.html followed by LayoutTests/scrollbars/scrollbar-crash-on-refresh.html * WebCoreSupport/FrameLoaderClientQt.cpp: (WebCore::FrameLoaderClientQt::committedLoad): 2009-07-13 Simon Hausmann Reviewed by Ariya Hidayat. --- .../webkit/JavaScriptCore/generated/Grammar.cpp | 1002 ++++++--- .../webkit/JavaScriptCore/generated/Grammar.h | 109 +- src/3rdparty/webkit/VERSION | 2 +- src/3rdparty/webkit/WebCore/ChangeLog | 78 + src/3rdparty/webkit/WebCore/css/CSSGrammar.y | 10 +- .../webkit/WebCore/generated/CSSGrammar.cpp | 2342 ++++++++++++-------- src/3rdparty/webkit/WebCore/generated/CSSGrammar.h | 231 +- src/3rdparty/webkit/WebCore/generated/Grammar.cpp | 1002 ++++++--- src/3rdparty/webkit/WebCore/generated/Grammar.h | 109 +- .../webkit/WebCore/generated/XPathGrammar.cpp | 418 ++-- .../webkit/WebCore/generated/XPathGrammar.h | 64 +- .../WebCore/html/CanvasRenderingContext2D.cpp | 4 +- .../webkit/WebCore/platform/graphics/qt/PathQt.cpp | 4 +- .../platform/network/qt/QNetworkReplyHandler.cpp | 6 +- .../webkit/WebCore/platform/qt/FileSystemQt.cpp | 2 +- .../webkit/WebCore/plugins/mac/PluginViewMac.cpp | 8 +- src/3rdparty/webkit/WebKit/qt/ChangeLog | 19 + .../qt/WebCoreSupport/FrameLoaderClientQt.cpp | 5 + 18 files changed, 3375 insertions(+), 2040 deletions(-) diff --git a/src/3rdparty/webkit/JavaScriptCore/generated/Grammar.cpp b/src/3rdparty/webkit/JavaScriptCore/generated/Grammar.cpp index 1652b24..d25683a 100644 --- a/src/3rdparty/webkit/JavaScriptCore/generated/Grammar.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/generated/Grammar.cpp @@ -1,24 +1,23 @@ -/* A Bison parser, made by GNU Bison 2.3. */ -/* Skeleton implementation for Bison's Yacc-like parsers in C +/* A Bison parser, made by GNU Bison 2.4.1. */ - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -29,7 +28,7 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ @@ -47,7 +46,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.3" +#define YYBISON_VERSION "2.4.1" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -55,159 +54,28 @@ /* Pure parsers. */ #define YYPURE 1 +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + /* Using locations. */ #define YYLSP_NEEDED 1 /* Substitute the variable and function names. */ -#define yyparse jscyyparse -#define yylex jscyylex -#define yyerror jscyyerror -#define yylval jscyylval -#define yychar jscyychar -#define yydebug jscyydebug -#define yynerrs jscyynerrs -#define yylloc jscyylloc - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - NULLTOKEN = 258, - TRUETOKEN = 259, - FALSETOKEN = 260, - BREAK = 261, - CASE = 262, - DEFAULT = 263, - FOR = 264, - NEW = 265, - VAR = 266, - CONSTTOKEN = 267, - CONTINUE = 268, - FUNCTION = 269, - RETURN = 270, - VOIDTOKEN = 271, - DELETETOKEN = 272, - IF = 273, - THISTOKEN = 274, - DO = 275, - WHILE = 276, - INTOKEN = 277, - INSTANCEOF = 278, - TYPEOF = 279, - SWITCH = 280, - WITH = 281, - RESERVED = 282, - THROW = 283, - TRY = 284, - CATCH = 285, - FINALLY = 286, - DEBUGGER = 287, - IF_WITHOUT_ELSE = 288, - ELSE = 289, - EQEQ = 290, - NE = 291, - STREQ = 292, - STRNEQ = 293, - LE = 294, - GE = 295, - OR = 296, - AND = 297, - PLUSPLUS = 298, - MINUSMINUS = 299, - LSHIFT = 300, - RSHIFT = 301, - URSHIFT = 302, - PLUSEQUAL = 303, - MINUSEQUAL = 304, - MULTEQUAL = 305, - DIVEQUAL = 306, - LSHIFTEQUAL = 307, - RSHIFTEQUAL = 308, - URSHIFTEQUAL = 309, - ANDEQUAL = 310, - MODEQUAL = 311, - XOREQUAL = 312, - OREQUAL = 313, - OPENBRACE = 314, - CLOSEBRACE = 315, - NUMBER = 316, - IDENT = 317, - STRING = 318, - AUTOPLUSPLUS = 319, - AUTOMINUSMINUS = 320 - }; -#endif -/* Tokens. */ -#define NULLTOKEN 258 -#define TRUETOKEN 259 -#define FALSETOKEN 260 -#define BREAK 261 -#define CASE 262 -#define DEFAULT 263 -#define FOR 264 -#define NEW 265 -#define VAR 266 -#define CONSTTOKEN 267 -#define CONTINUE 268 -#define FUNCTION 269 -#define RETURN 270 -#define VOIDTOKEN 271 -#define DELETETOKEN 272 -#define IF 273 -#define THISTOKEN 274 -#define DO 275 -#define WHILE 276 -#define INTOKEN 277 -#define INSTANCEOF 278 -#define TYPEOF 279 -#define SWITCH 280 -#define WITH 281 -#define RESERVED 282 -#define THROW 283 -#define TRY 284 -#define CATCH 285 -#define FINALLY 286 -#define DEBUGGER 287 -#define IF_WITHOUT_ELSE 288 -#define ELSE 289 -#define EQEQ 290 -#define NE 291 -#define STREQ 292 -#define STRNEQ 293 -#define LE 294 -#define GE 295 -#define OR 296 -#define AND 297 -#define PLUSPLUS 298 -#define MINUSMINUS 299 -#define LSHIFT 300 -#define RSHIFT 301 -#define URSHIFT 302 -#define PLUSEQUAL 303 -#define MINUSEQUAL 304 -#define MULTEQUAL 305 -#define DIVEQUAL 306 -#define LSHIFTEQUAL 307 -#define RSHIFTEQUAL 308 -#define URSHIFTEQUAL 309 -#define ANDEQUAL 310 -#define MODEQUAL 311 -#define XOREQUAL 312 -#define OREQUAL 313 -#define OPENBRACE 314 -#define CLOSEBRACE 315 -#define NUMBER 316 -#define IDENT 317 -#define STRING 318 -#define AUTOPLUSPLUS 319 -#define AUTOMINUSMINUS 320 - - - +#define yyparse jscyyparse +#define yylex jscyylex +#define yyerror jscyyerror +#define yylval jscyylval +#define yychar jscyychar +#define yydebug jscyydebug +#define yynerrs jscyynerrs +#define yylloc jscyylloc /* Copy the first part of user declarations. */ + +/* Line 189 of yacc.c */ #line 3 "../parser/Grammar.y" @@ -363,6 +231,9 @@ static inline void appendToVarDeclarationList(void* globalPtr, ParserRefCountedD +/* Line 189 of yacc.c */ +#line 236 "Grammar.tab.c" + /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -381,10 +252,88 @@ static inline void appendToVarDeclarationList(void* globalPtr, ParserRefCountedD # define YYTOKEN_TABLE 0 #endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + NULLTOKEN = 258, + TRUETOKEN = 259, + FALSETOKEN = 260, + BREAK = 261, + CASE = 262, + DEFAULT = 263, + FOR = 264, + NEW = 265, + VAR = 266, + CONSTTOKEN = 267, + CONTINUE = 268, + FUNCTION = 269, + RETURN = 270, + VOIDTOKEN = 271, + DELETETOKEN = 272, + IF = 273, + THISTOKEN = 274, + DO = 275, + WHILE = 276, + INTOKEN = 277, + INSTANCEOF = 278, + TYPEOF = 279, + SWITCH = 280, + WITH = 281, + RESERVED = 282, + THROW = 283, + TRY = 284, + CATCH = 285, + FINALLY = 286, + DEBUGGER = 287, + IF_WITHOUT_ELSE = 288, + ELSE = 289, + EQEQ = 290, + NE = 291, + STREQ = 292, + STRNEQ = 293, + LE = 294, + GE = 295, + OR = 296, + AND = 297, + PLUSPLUS = 298, + MINUSMINUS = 299, + LSHIFT = 300, + RSHIFT = 301, + URSHIFT = 302, + PLUSEQUAL = 303, + MINUSEQUAL = 304, + MULTEQUAL = 305, + DIVEQUAL = 306, + LSHIFTEQUAL = 307, + RSHIFTEQUAL = 308, + URSHIFTEQUAL = 309, + ANDEQUAL = 310, + MODEQUAL = 311, + XOREQUAL = 312, + OREQUAL = 313, + OPENBRACE = 314, + CLOSEBRACE = 315, + NUMBER = 316, + IDENT = 317, + STRING = 318, + AUTOPLUSPLUS = 319, + AUTOMINUSMINUS = 320 + }; +#endif + + + #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 157 "../parser/Grammar.y" { + +/* Line 214 of yacc.c */ +#line 157 "../parser/Grammar.y" + int intValue; double doubleValue; Identifier* ident; @@ -414,13 +363,15 @@ typedef union YYSTYPE ParameterListInfo parameterList; Operator op; -} -/* Line 187 of yacc.c. */ -#line 420 "Grammar.tab.c" - YYSTYPE; + + + +/* Line 214 of yacc.c */ +#line 371 "Grammar.tab.c" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 #endif #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED @@ -440,8 +391,8 @@ typedef struct YYLTYPE /* Copy the second part of user declarations. */ -/* Line 216 of yacc.c. */ -#line 445 "Grammar.tab.c" +/* Line 264 of yacc.c */ +#line 396 "Grammar.tab.c" #ifdef short # undef short @@ -516,14 +467,14 @@ typedef short int yytype_int16; #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int -YYID (int i) +YYID (int yyi) #else static int -YYID (i) - int i; +YYID (yyi) + int yyi; #endif { - return i; + return yyi; } #endif @@ -605,9 +556,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ /* A type that is properly aligned for any stack member. */ union yyalloc { - yytype_int16 yyss; - YYSTYPE yyvs; - YYLTYPE yyls; + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; + YYLTYPE yyls_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ @@ -642,12 +593,12 @@ union yyalloc elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ -# define YYSTACK_RELOCATE(Stack) \ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ @@ -2361,17 +2312,20 @@ yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp) #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) #else static void -yy_stack_print (bottom, top) - yytype_int16 *bottom; - yytype_int16 *top; +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; #endif { YYFPRINTF (stderr, "Stack now"); - for (; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } YYFPRINTF (stderr, "\n"); } @@ -2406,11 +2360,11 @@ yy_reduce_print (yyvsp, yylsp, yyrule) /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { - fprintf (stderr, " $%d = ", yyi + 1); + YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) , &(yylsp[(yyi + 1) - (yynrhs)]) ); - fprintf (stderr, "\n"); + YYFPRINTF (stderr, "\n"); } } @@ -2692,10 +2646,8 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp) break; } } - /* Prevent warnings from -Wmissing-prototypes. */ - #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); @@ -2714,10 +2666,9 @@ int yyparse (); - -/*----------. -| yyparse. | -`----------*/ +/*-------------------------. +| yyparse or yypush_parse. | +`-------------------------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ @@ -2741,88 +2692,97 @@ yyparse () #endif #endif { - /* The look-ahead symbol. */ +/* The lookahead symbol. */ int yychar; -/* The semantic value of the look-ahead symbol. */ +/* The semantic value of the lookahead symbol. */ YYSTYPE yylval; -/* Number of syntax errors so far. */ -int yynerrs; -/* Location data for the look-ahead symbol. */ +/* Location data for the lookahead symbol. */ YYLTYPE yylloc; - int yystate; - int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Look-ahead token as an internal (translated) token number. */ - int yytoken = 0; -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif + /* Number of syntax errors so far. */ + int yynerrs; - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + `yyls': related to locations. - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss = yyssa; - yytype_int16 *yyssp; + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp; + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; - /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[2]; + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) + /* The location stack. */ + YYLTYPE yylsa[YYINITDEPTH]; + YYLTYPE *yyls; + YYLTYPE *yylsp; + + /* The locations where the error started and ended. */ + YYLTYPE yyerror_range[2]; - YYSIZE_T yystacksize = YYINITDEPTH; + YYSIZE_T yystacksize; + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; YYLTYPE yyloc; +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) + /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yyls = yylsa; + yystacksize = YYINITDEPTH; + YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ + yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ - yyssp = yyss; yyvsp = yyvs; yylsp = yyls; + #if YYLTYPE_IS_TRIVIAL /* Initialize the default location before parsing starts. */ yylloc.first_line = yylloc.last_line = 1; - yylloc.first_column = yylloc.last_column = 0; + yylloc.first_column = yylloc.last_column = 1; #endif goto yysetstate; @@ -2861,6 +2821,7 @@ YYLTYPE yylloc; &yyvs1, yysize * sizeof (*yyvsp), &yyls1, yysize * sizeof (*yylsp), &yystacksize); + yyls = yyls1; yyss = yyss1; yyvs = yyvs1; @@ -2882,9 +2843,9 @@ YYLTYPE yylloc; (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - YYSTACK_RELOCATE (yyls); + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); + YYSTACK_RELOCATE (yyls_alloc, yyls); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); @@ -2905,6 +2866,9 @@ YYLTYPE yylloc; YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + if (yystate == YYFINAL) + YYACCEPT; + goto yybackup; /*-----------. @@ -2913,16 +2877,16 @@ YYLTYPE yylloc; yybackup: /* Do appropriate processing given the current state. Read a - look-ahead token if we need one and don't already have one. */ + lookahead token if we need one and don't already have one. */ - /* First try to decide what to do without reference to look-ahead token. */ + /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; - /* Not known => get a look-ahead token if don't already have one. */ + /* Not known => get a lookahead token if don't already have one. */ - /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); @@ -2954,20 +2918,16 @@ yybackup: goto yyreduce; } - if (yyn == YYFINAL) - YYACCEPT; - /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; - /* Shift the look-ahead token. */ + /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - /* Discard the shifted token unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; + /* Discard the shifted token. */ + yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; @@ -3008,31 +2968,43 @@ yyreduce: switch (yyn) { case 2: + +/* Line 1455 of yacc.c */ #line 290 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new NullNode(GLOBAL_DATA), 0, 1); ;} break; case 3: + +/* Line 1455 of yacc.c */ #line 291 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new BooleanNode(GLOBAL_DATA, true), 0, 1); ;} break; case 4: + +/* Line 1455 of yacc.c */ #line 292 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new BooleanNode(GLOBAL_DATA, false), 0, 1); ;} break; case 5: + +/* Line 1455 of yacc.c */ #line 293 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeNumberNode(GLOBAL_DATA, (yyvsp[(1) - (1)].doubleValue)), 0, 1); ;} break; case 6: + +/* Line 1455 of yacc.c */ #line 294 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new StringNode(GLOBAL_DATA, *(yyvsp[(1) - (1)].ident)), 0, 1); ;} break; case 7: + +/* Line 1455 of yacc.c */ #line 295 "../parser/Grammar.y" { Lexer& l = *LEXER; @@ -3046,6 +3018,8 @@ yyreduce: break; case 8: + +/* Line 1455 of yacc.c */ #line 304 "../parser/Grammar.y" { Lexer& l = *LEXER; @@ -3059,26 +3033,36 @@ yyreduce: break; case 9: + +/* Line 1455 of yacc.c */ #line 316 "../parser/Grammar.y" { (yyval.propertyNode) = createNodeInfo(new PropertyNode(GLOBAL_DATA, *(yyvsp[(1) - (3)].ident), (yyvsp[(3) - (3)].expressionNode).m_node, PropertyNode::Constant), (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 10: + +/* Line 1455 of yacc.c */ #line 317 "../parser/Grammar.y" { (yyval.propertyNode) = createNodeInfo(new PropertyNode(GLOBAL_DATA, *(yyvsp[(1) - (3)].ident), (yyvsp[(3) - (3)].expressionNode).m_node, PropertyNode::Constant), (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 11: + +/* Line 1455 of yacc.c */ #line 318 "../parser/Grammar.y" { (yyval.propertyNode) = createNodeInfo(new PropertyNode(GLOBAL_DATA, Identifier(GLOBAL_DATA, UString::from((yyvsp[(1) - (3)].doubleValue))), (yyvsp[(3) - (3)].expressionNode).m_node, PropertyNode::Constant), (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 12: + +/* Line 1455 of yacc.c */ #line 319 "../parser/Grammar.y" { (yyval.propertyNode) = createNodeInfo(makeGetterOrSetterPropertyNode(globalPtr, *(yyvsp[(1) - (7)].ident), *(yyvsp[(2) - (7)].ident), 0, (yyvsp[(6) - (7)].functionBodyNode), LEXER->sourceCode((yyvsp[(5) - (7)].intValue), (yyvsp[(7) - (7)].intValue), (yylsp[(5) - (7)]).first_line)), ClosureFeature, 0); DBG((yyvsp[(6) - (7)].functionBodyNode), (yylsp[(5) - (7)]), (yylsp[(7) - (7)])); if (!(yyval.propertyNode).m_node) YYABORT; ;} break; case 13: + +/* Line 1455 of yacc.c */ #line 321 "../parser/Grammar.y" { (yyval.propertyNode) = createNodeInfo(makeGetterOrSetterPropertyNode(globalPtr, *(yyvsp[(1) - (8)].ident), *(yyvsp[(2) - (8)].ident), (yyvsp[(4) - (8)].parameterList).m_node.head, (yyvsp[(7) - (8)].functionBodyNode), LEXER->sourceCode((yyvsp[(6) - (8)].intValue), (yyvsp[(8) - (8)].intValue), (yylsp[(6) - (8)]).first_line)), (yyvsp[(4) - (8)].parameterList).m_features | ClosureFeature, 0); @@ -3091,6 +3075,8 @@ yyreduce: break; case 14: + +/* Line 1455 of yacc.c */ #line 332 "../parser/Grammar.y" { (yyval.propertyList).m_node.head = new PropertyListNode(GLOBAL_DATA, (yyvsp[(1) - (1)].propertyNode).m_node); (yyval.propertyList).m_node.tail = (yyval.propertyList).m_node.head; @@ -3099,6 +3085,8 @@ yyreduce: break; case 15: + +/* Line 1455 of yacc.c */ #line 336 "../parser/Grammar.y" { (yyval.propertyList).m_node.head = (yyvsp[(1) - (3)].propertyList).m_node.head; (yyval.propertyList).m_node.tail = new PropertyListNode(GLOBAL_DATA, (yyvsp[(3) - (3)].propertyNode).m_node, (yyvsp[(1) - (3)].propertyList).m_node.tail); @@ -3107,51 +3095,71 @@ yyreduce: break; case 17: + +/* Line 1455 of yacc.c */ #line 344 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ObjectLiteralNode(GLOBAL_DATA), 0, 0); ;} break; case 18: + +/* Line 1455 of yacc.c */ #line 345 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ObjectLiteralNode(GLOBAL_DATA, (yyvsp[(2) - (3)].propertyList).m_node.head), (yyvsp[(2) - (3)].propertyList).m_features, (yyvsp[(2) - (3)].propertyList).m_numConstants); ;} break; case 19: + +/* Line 1455 of yacc.c */ #line 347 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ObjectLiteralNode(GLOBAL_DATA, (yyvsp[(2) - (4)].propertyList).m_node.head), (yyvsp[(2) - (4)].propertyList).m_features, (yyvsp[(2) - (4)].propertyList).m_numConstants); ;} break; case 20: + +/* Line 1455 of yacc.c */ #line 351 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ThisNode(GLOBAL_DATA), ThisFeature, 0); ;} break; case 23: + +/* Line 1455 of yacc.c */ #line 354 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ResolveNode(GLOBAL_DATA, *(yyvsp[(1) - (1)].ident), (yylsp[(1) - (1)]).first_column), (*(yyvsp[(1) - (1)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0, 0); ;} break; case 24: + +/* Line 1455 of yacc.c */ #line 355 "../parser/Grammar.y" { (yyval.expressionNode) = (yyvsp[(2) - (3)].expressionNode); ;} break; case 25: + +/* Line 1455 of yacc.c */ #line 359 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ArrayNode(GLOBAL_DATA, (yyvsp[(2) - (3)].intValue)), 0, (yyvsp[(2) - (3)].intValue) ? 1 : 0); ;} break; case 26: + +/* Line 1455 of yacc.c */ #line 360 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ArrayNode(GLOBAL_DATA, (yyvsp[(2) - (3)].elementList).m_node.head), (yyvsp[(2) - (3)].elementList).m_features, (yyvsp[(2) - (3)].elementList).m_numConstants); ;} break; case 27: + +/* Line 1455 of yacc.c */ #line 361 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ArrayNode(GLOBAL_DATA, (yyvsp[(4) - (5)].intValue), (yyvsp[(2) - (5)].elementList).m_node.head), (yyvsp[(2) - (5)].elementList).m_features, (yyvsp[(4) - (5)].intValue) ? (yyvsp[(2) - (5)].elementList).m_numConstants + 1 : (yyvsp[(2) - (5)].elementList).m_numConstants); ;} break; case 28: + +/* Line 1455 of yacc.c */ #line 365 "../parser/Grammar.y" { (yyval.elementList).m_node.head = new ElementNode(GLOBAL_DATA, (yyvsp[(1) - (2)].intValue), (yyvsp[(2) - (2)].expressionNode).m_node); (yyval.elementList).m_node.tail = (yyval.elementList).m_node.head; @@ -3160,6 +3168,8 @@ yyreduce: break; case 29: + +/* Line 1455 of yacc.c */ #line 370 "../parser/Grammar.y" { (yyval.elementList).m_node.head = (yyvsp[(1) - (4)].elementList).m_node.head; (yyval.elementList).m_node.tail = new ElementNode(GLOBAL_DATA, (yyvsp[(1) - (4)].elementList).m_node.tail, (yyvsp[(3) - (4)].intValue), (yyvsp[(4) - (4)].expressionNode).m_node); @@ -3168,26 +3178,36 @@ yyreduce: break; case 30: + +/* Line 1455 of yacc.c */ #line 377 "../parser/Grammar.y" { (yyval.intValue) = 0; ;} break; case 32: + +/* Line 1455 of yacc.c */ #line 382 "../parser/Grammar.y" { (yyval.intValue) = 1; ;} break; case 33: + +/* Line 1455 of yacc.c */ #line 383 "../parser/Grammar.y" { (yyval.intValue) = (yyvsp[(1) - (2)].intValue) + 1; ;} break; case 35: + +/* Line 1455 of yacc.c */ #line 388 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo((yyvsp[(1) - (1)].funcExprNode).m_node, (yyvsp[(1) - (1)].funcExprNode).m_features, (yyvsp[(1) - (1)].funcExprNode).m_numConstants); ;} break; case 36: + +/* Line 1455 of yacc.c */ #line 389 "../parser/Grammar.y" { BracketAccessorNode* node = new BracketAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (4)]).first_column, (yylsp[(1) - (4)]).last_column, (yylsp[(4) - (4)]).last_column); @@ -3196,6 +3216,8 @@ yyreduce: break; case 37: + +/* Line 1455 of yacc.c */ #line 393 "../parser/Grammar.y" { DotAccessorNode* node = new DotAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, *(yyvsp[(3) - (3)].ident)); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); @@ -3204,6 +3226,8 @@ yyreduce: break; case 38: + +/* Line 1455 of yacc.c */ #line 397 "../parser/Grammar.y" { NewExprNode* node = new NewExprNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].argumentsNode).m_node); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); @@ -3212,6 +3236,8 @@ yyreduce: break; case 40: + +/* Line 1455 of yacc.c */ #line 405 "../parser/Grammar.y" { BracketAccessorNode* node = new BracketAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (4)]).first_column, (yylsp[(1) - (4)]).last_column, (yylsp[(4) - (4)]).last_column); @@ -3220,6 +3246,8 @@ yyreduce: break; case 41: + +/* Line 1455 of yacc.c */ #line 409 "../parser/Grammar.y" { DotAccessorNode* node = new DotAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, *(yyvsp[(3) - (3)].ident)); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); @@ -3228,6 +3256,8 @@ yyreduce: break; case 42: + +/* Line 1455 of yacc.c */ #line 413 "../parser/Grammar.y" { NewExprNode* node = new NewExprNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].argumentsNode).m_node); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); @@ -3236,6 +3266,8 @@ yyreduce: break; case 44: + +/* Line 1455 of yacc.c */ #line 421 "../parser/Grammar.y" { NewExprNode* node = new NewExprNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); @@ -3244,6 +3276,8 @@ yyreduce: break; case 46: + +/* Line 1455 of yacc.c */ #line 429 "../parser/Grammar.y" { NewExprNode* node = new NewExprNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); @@ -3252,16 +3286,22 @@ yyreduce: break; case 47: + +/* Line 1455 of yacc.c */ #line 436 "../parser/Grammar.y" { (yyval.expressionNode) = makeFunctionCallNode(globalPtr, (yyvsp[(1) - (2)].expressionNode), (yyvsp[(2) - (2)].argumentsNode), (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); ;} break; case 48: + +/* Line 1455 of yacc.c */ #line 437 "../parser/Grammar.y" { (yyval.expressionNode) = makeFunctionCallNode(globalPtr, (yyvsp[(1) - (2)].expressionNode), (yyvsp[(2) - (2)].argumentsNode), (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); ;} break; case 49: + +/* Line 1455 of yacc.c */ #line 438 "../parser/Grammar.y" { BracketAccessorNode* node = new BracketAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (4)]).first_column, (yylsp[(1) - (4)]).last_column, (yylsp[(4) - (4)]).last_column); @@ -3270,6 +3310,8 @@ yyreduce: break; case 50: + +/* Line 1455 of yacc.c */ #line 442 "../parser/Grammar.y" { DotAccessorNode* node = new DotAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, *(yyvsp[(3) - (3)].ident)); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); @@ -3277,16 +3319,22 @@ yyreduce: break; case 51: + +/* Line 1455 of yacc.c */ #line 448 "../parser/Grammar.y" { (yyval.expressionNode) = makeFunctionCallNode(globalPtr, (yyvsp[(1) - (2)].expressionNode), (yyvsp[(2) - (2)].argumentsNode), (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); ;} break; case 52: + +/* Line 1455 of yacc.c */ #line 449 "../parser/Grammar.y" { (yyval.expressionNode) = makeFunctionCallNode(globalPtr, (yyvsp[(1) - (2)].expressionNode), (yyvsp[(2) - (2)].argumentsNode), (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); ;} break; case 53: + +/* Line 1455 of yacc.c */ #line 450 "../parser/Grammar.y" { BracketAccessorNode* node = new BracketAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (4)]).first_column, (yylsp[(1) - (4)]).last_column, (yylsp[(4) - (4)]).last_column); @@ -3295,6 +3343,8 @@ yyreduce: break; case 54: + +/* Line 1455 of yacc.c */ #line 454 "../parser/Grammar.y" { DotAccessorNode* node = new DotAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, *(yyvsp[(3) - (3)].ident)); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); @@ -3303,16 +3353,22 @@ yyreduce: break; case 55: + +/* Line 1455 of yacc.c */ #line 461 "../parser/Grammar.y" { (yyval.argumentsNode) = createNodeInfo(new ArgumentsNode(GLOBAL_DATA), 0, 0); ;} break; case 56: + +/* Line 1455 of yacc.c */ #line 462 "../parser/Grammar.y" { (yyval.argumentsNode) = createNodeInfo(new ArgumentsNode(GLOBAL_DATA, (yyvsp[(2) - (3)].argumentList).m_node.head), (yyvsp[(2) - (3)].argumentList).m_features, (yyvsp[(2) - (3)].argumentList).m_numConstants); ;} break; case 57: + +/* Line 1455 of yacc.c */ #line 466 "../parser/Grammar.y" { (yyval.argumentList).m_node.head = new ArgumentListNode(GLOBAL_DATA, (yyvsp[(1) - (1)].expressionNode).m_node); (yyval.argumentList).m_node.tail = (yyval.argumentList).m_node.head; @@ -3321,6 +3377,8 @@ yyreduce: break; case 58: + +/* Line 1455 of yacc.c */ #line 470 "../parser/Grammar.y" { (yyval.argumentList).m_node.head = (yyvsp[(1) - (3)].argumentList).m_node.head; (yyval.argumentList).m_node.tail = new ArgumentListNode(GLOBAL_DATA, (yyvsp[(1) - (3)].argumentList).m_node.tail, (yyvsp[(3) - (3)].expressionNode).m_node); @@ -3329,181 +3387,253 @@ yyreduce: break; case 64: + +/* Line 1455 of yacc.c */ #line 488 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makePostfixNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode).m_node, OpPlusPlus, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column), (yyvsp[(1) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (2)].expressionNode).m_numConstants); ;} break; case 65: + +/* Line 1455 of yacc.c */ #line 489 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makePostfixNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode).m_node, OpMinusMinus, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column), (yyvsp[(1) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (2)].expressionNode).m_numConstants); ;} break; case 67: + +/* Line 1455 of yacc.c */ #line 494 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makePostfixNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode).m_node, OpPlusPlus, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column), (yyvsp[(1) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (2)].expressionNode).m_numConstants); ;} break; case 68: + +/* Line 1455 of yacc.c */ #line 495 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makePostfixNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode).m_node, OpMinusMinus, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column), (yyvsp[(1) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (2)].expressionNode).m_numConstants); ;} break; case 69: + +/* Line 1455 of yacc.c */ #line 499 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeDeleteNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).last_column, (yylsp[(2) - (2)]).last_column), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 70: + +/* Line 1455 of yacc.c */ #line 500 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new VoidNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants + 1); ;} break; case 71: + +/* Line 1455 of yacc.c */ #line 501 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeTypeOfNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 72: + +/* Line 1455 of yacc.c */ #line 502 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makePrefixNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node, OpPlusPlus, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column), (yyvsp[(2) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 73: + +/* Line 1455 of yacc.c */ #line 503 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makePrefixNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node, OpPlusPlus, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column), (yyvsp[(2) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 74: + +/* Line 1455 of yacc.c */ #line 504 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makePrefixNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node, OpMinusMinus, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column), (yyvsp[(2) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 75: + +/* Line 1455 of yacc.c */ #line 505 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makePrefixNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node, OpMinusMinus, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column), (yyvsp[(2) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 76: + +/* Line 1455 of yacc.c */ #line 506 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new UnaryPlusNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 77: + +/* Line 1455 of yacc.c */ #line 507 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeNegateNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 78: + +/* Line 1455 of yacc.c */ #line 508 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeBitwiseNotNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 79: + +/* Line 1455 of yacc.c */ #line 509 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LogicalNotNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 85: + +/* Line 1455 of yacc.c */ #line 523 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeMultNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 86: + +/* Line 1455 of yacc.c */ #line 524 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeDivNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 87: + +/* Line 1455 of yacc.c */ #line 525 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ModNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 89: + +/* Line 1455 of yacc.c */ #line 531 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeMultNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 90: + +/* Line 1455 of yacc.c */ #line 533 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeDivNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 91: + +/* Line 1455 of yacc.c */ #line 535 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ModNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 93: + +/* Line 1455 of yacc.c */ #line 540 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeAddNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 94: + +/* Line 1455 of yacc.c */ #line 541 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeSubNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 96: + +/* Line 1455 of yacc.c */ #line 547 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeAddNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 97: + +/* Line 1455 of yacc.c */ #line 549 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeSubNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 99: + +/* Line 1455 of yacc.c */ #line 554 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeLeftShiftNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 100: + +/* Line 1455 of yacc.c */ #line 555 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeRightShiftNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 101: + +/* Line 1455 of yacc.c */ #line 556 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new UnsignedRightShiftNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 103: + +/* Line 1455 of yacc.c */ #line 561 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeLeftShiftNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 104: + +/* Line 1455 of yacc.c */ #line 562 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeRightShiftNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 105: + +/* Line 1455 of yacc.c */ #line 563 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new UnsignedRightShiftNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 107: + +/* Line 1455 of yacc.c */ #line 568 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LessNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 108: + +/* Line 1455 of yacc.c */ #line 569 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new GreaterNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 109: + +/* Line 1455 of yacc.c */ #line 570 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LessEqNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 110: + +/* Line 1455 of yacc.c */ #line 571 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new GreaterEqNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 111: + +/* Line 1455 of yacc.c */ #line 572 "../parser/Grammar.y" { InstanceOfNode* node = new InstanceOfNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); @@ -3511,6 +3641,8 @@ yyreduce: break; case 112: + +/* Line 1455 of yacc.c */ #line 575 "../parser/Grammar.y" { InNode* node = new InNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); @@ -3518,26 +3650,36 @@ yyreduce: break; case 114: + +/* Line 1455 of yacc.c */ #line 582 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LessNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 115: + +/* Line 1455 of yacc.c */ #line 583 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new GreaterNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 116: + +/* Line 1455 of yacc.c */ #line 584 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LessEqNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 117: + +/* Line 1455 of yacc.c */ #line 585 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new GreaterEqNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 118: + +/* Line 1455 of yacc.c */ #line 587 "../parser/Grammar.y" { InstanceOfNode* node = new InstanceOfNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); @@ -3545,26 +3687,36 @@ yyreduce: break; case 120: + +/* Line 1455 of yacc.c */ #line 594 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LessNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 121: + +/* Line 1455 of yacc.c */ #line 595 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new GreaterNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 122: + +/* Line 1455 of yacc.c */ #line 596 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LessEqNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 123: + +/* Line 1455 of yacc.c */ #line 597 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new GreaterEqNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 124: + +/* Line 1455 of yacc.c */ #line 599 "../parser/Grammar.y" { InstanceOfNode* node = new InstanceOfNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); @@ -3572,6 +3724,8 @@ yyreduce: break; case 125: + +/* Line 1455 of yacc.c */ #line 603 "../parser/Grammar.y" { InNode* node = new InNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); @@ -3579,156 +3733,218 @@ yyreduce: break; case 127: + +/* Line 1455 of yacc.c */ #line 610 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new EqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 128: + +/* Line 1455 of yacc.c */ #line 611 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new NotEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 129: + +/* Line 1455 of yacc.c */ #line 612 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new StrictEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 130: + +/* Line 1455 of yacc.c */ #line 613 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new NotStrictEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 132: + +/* Line 1455 of yacc.c */ #line 619 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new EqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 133: + +/* Line 1455 of yacc.c */ #line 621 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new NotEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 134: + +/* Line 1455 of yacc.c */ #line 623 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new StrictEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 135: + +/* Line 1455 of yacc.c */ #line 625 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new NotStrictEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 137: + +/* Line 1455 of yacc.c */ #line 631 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new EqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 138: + +/* Line 1455 of yacc.c */ #line 632 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new NotEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 139: + +/* Line 1455 of yacc.c */ #line 634 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new StrictEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 140: + +/* Line 1455 of yacc.c */ #line 636 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new NotStrictEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 142: + +/* Line 1455 of yacc.c */ #line 641 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new BitAndNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 144: + +/* Line 1455 of yacc.c */ #line 647 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new BitAndNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 146: + +/* Line 1455 of yacc.c */ #line 652 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new BitAndNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 148: + +/* Line 1455 of yacc.c */ #line 657 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new BitXOrNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 150: + +/* Line 1455 of yacc.c */ #line 663 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new BitXOrNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 152: + +/* Line 1455 of yacc.c */ #line 669 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new BitXOrNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 154: + +/* Line 1455 of yacc.c */ #line 674 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new BitOrNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 156: + +/* Line 1455 of yacc.c */ #line 680 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new BitOrNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 158: + +/* Line 1455 of yacc.c */ #line 686 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new BitOrNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 160: + +/* Line 1455 of yacc.c */ #line 691 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LogicalOpNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, OpLogicalAnd), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 162: + +/* Line 1455 of yacc.c */ #line 697 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LogicalOpNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, OpLogicalAnd), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 164: + +/* Line 1455 of yacc.c */ #line 703 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LogicalOpNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, OpLogicalAnd), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 166: + +/* Line 1455 of yacc.c */ #line 708 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LogicalOpNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, OpLogicalOr), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 168: + +/* Line 1455 of yacc.c */ #line 714 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LogicalOpNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, OpLogicalOr), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 170: + +/* Line 1455 of yacc.c */ #line 719 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LogicalOpNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, OpLogicalOr), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 172: + +/* Line 1455 of yacc.c */ #line 725 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ConditionalNode(GLOBAL_DATA, (yyvsp[(1) - (5)].expressionNode).m_node, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].expressionNode).m_node), (yyvsp[(1) - (5)].expressionNode).m_features | (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].expressionNode).m_features, (yyvsp[(1) - (5)].expressionNode).m_numConstants + (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].expressionNode).m_numConstants); ;} break; case 174: + +/* Line 1455 of yacc.c */ #line 731 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ConditionalNode(GLOBAL_DATA, (yyvsp[(1) - (5)].expressionNode).m_node, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].expressionNode).m_node), (yyvsp[(1) - (5)].expressionNode).m_features | (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].expressionNode).m_features, (yyvsp[(1) - (5)].expressionNode).m_numConstants + (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].expressionNode).m_numConstants); ;} break; case 176: + +/* Line 1455 of yacc.c */ #line 737 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ConditionalNode(GLOBAL_DATA, (yyvsp[(1) - (5)].expressionNode).m_node, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].expressionNode).m_node), (yyvsp[(1) - (5)].expressionNode).m_features | (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].expressionNode).m_features, (yyvsp[(1) - (5)].expressionNode).m_numConstants + (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].expressionNode).m_numConstants); ;} break; case 178: + +/* Line 1455 of yacc.c */ #line 743 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeAssignNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(2) - (3)].op), (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(1) - (3)].expressionNode).m_features & AssignFeature, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).first_column + 1, (yylsp[(3) - (3)]).last_column), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); @@ -3736,6 +3952,8 @@ yyreduce: break; case 180: + +/* Line 1455 of yacc.c */ #line 751 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeAssignNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(2) - (3)].op), (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(1) - (3)].expressionNode).m_features & AssignFeature, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).first_column + 1, (yylsp[(3) - (3)]).last_column), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); @@ -3743,6 +3961,8 @@ yyreduce: break; case 182: + +/* Line 1455 of yacc.c */ #line 759 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeAssignNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(2) - (3)].op), (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(1) - (3)].expressionNode).m_features & AssignFeature, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).first_column + 1, (yylsp[(3) - (3)]).last_column), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); @@ -3750,99 +3970,137 @@ yyreduce: break; case 183: + +/* Line 1455 of yacc.c */ #line 765 "../parser/Grammar.y" { (yyval.op) = OpEqual; ;} break; case 184: + +/* Line 1455 of yacc.c */ #line 766 "../parser/Grammar.y" { (yyval.op) = OpPlusEq; ;} break; case 185: + +/* Line 1455 of yacc.c */ #line 767 "../parser/Grammar.y" { (yyval.op) = OpMinusEq; ;} break; case 186: + +/* Line 1455 of yacc.c */ #line 768 "../parser/Grammar.y" { (yyval.op) = OpMultEq; ;} break; case 187: + +/* Line 1455 of yacc.c */ #line 769 "../parser/Grammar.y" { (yyval.op) = OpDivEq; ;} break; case 188: + +/* Line 1455 of yacc.c */ #line 770 "../parser/Grammar.y" { (yyval.op) = OpLShift; ;} break; case 189: + +/* Line 1455 of yacc.c */ #line 771 "../parser/Grammar.y" { (yyval.op) = OpRShift; ;} break; case 190: + +/* Line 1455 of yacc.c */ #line 772 "../parser/Grammar.y" { (yyval.op) = OpURShift; ;} break; case 191: + +/* Line 1455 of yacc.c */ #line 773 "../parser/Grammar.y" { (yyval.op) = OpAndEq; ;} break; case 192: + +/* Line 1455 of yacc.c */ #line 774 "../parser/Grammar.y" { (yyval.op) = OpXOrEq; ;} break; case 193: + +/* Line 1455 of yacc.c */ #line 775 "../parser/Grammar.y" { (yyval.op) = OpOrEq; ;} break; case 194: + +/* Line 1455 of yacc.c */ #line 776 "../parser/Grammar.y" { (yyval.op) = OpModEq; ;} break; case 196: + +/* Line 1455 of yacc.c */ #line 781 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new CommaNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 198: + +/* Line 1455 of yacc.c */ #line 786 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new CommaNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 200: + +/* Line 1455 of yacc.c */ #line 791 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new CommaNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 218: + +/* Line 1455 of yacc.c */ #line 815 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new BlockNode(GLOBAL_DATA, 0), 0, 0, 0, 0); DBG((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;} break; case 219: + +/* Line 1455 of yacc.c */ #line 817 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new BlockNode(GLOBAL_DATA, (yyvsp[(2) - (3)].sourceElements).m_node), (yyvsp[(2) - (3)].sourceElements).m_varDeclarations, (yyvsp[(2) - (3)].sourceElements).m_funcDeclarations, (yyvsp[(2) - (3)].sourceElements).m_features, (yyvsp[(2) - (3)].sourceElements).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;} break; case 220: + +/* Line 1455 of yacc.c */ #line 822 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(makeVarStatementNode(GLOBAL_DATA, (yyvsp[(2) - (3)].varDeclList).m_node), (yyvsp[(2) - (3)].varDeclList).m_varDeclarations, (yyvsp[(2) - (3)].varDeclList).m_funcDeclarations, (yyvsp[(2) - (3)].varDeclList).m_features, (yyvsp[(2) - (3)].varDeclList).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;} break; case 221: + +/* Line 1455 of yacc.c */ #line 824 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(makeVarStatementNode(GLOBAL_DATA, (yyvsp[(2) - (3)].varDeclList).m_node), (yyvsp[(2) - (3)].varDeclList).m_varDeclarations, (yyvsp[(2) - (3)].varDeclList).m_funcDeclarations, (yyvsp[(2) - (3)].varDeclList).m_features, (yyvsp[(2) - (3)].varDeclList).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); @@ -3850,6 +4108,8 @@ yyreduce: break; case 222: + +/* Line 1455 of yacc.c */ #line 830 "../parser/Grammar.y" { (yyval.varDeclList).m_node = 0; (yyval.varDeclList).m_varDeclarations = new ParserRefCountedData(GLOBAL_DATA); @@ -3861,6 +4121,8 @@ yyreduce: break; case 223: + +/* Line 1455 of yacc.c */ #line 837 "../parser/Grammar.y" { AssignResolveNode* node = new AssignResolveNode(GLOBAL_DATA, *(yyvsp[(1) - (2)].ident), (yyvsp[(2) - (2)].expressionNode).m_node, (yyvsp[(2) - (2)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column); @@ -3874,6 +4136,8 @@ yyreduce: break; case 224: + +/* Line 1455 of yacc.c */ #line 847 "../parser/Grammar.y" { (yyval.varDeclList).m_node = (yyvsp[(1) - (3)].varDeclList).m_node; (yyval.varDeclList).m_varDeclarations = (yyvsp[(1) - (3)].varDeclList).m_varDeclarations; @@ -3885,6 +4149,8 @@ yyreduce: break; case 225: + +/* Line 1455 of yacc.c */ #line 855 "../parser/Grammar.y" { AssignResolveNode* node = new AssignResolveNode(GLOBAL_DATA, *(yyvsp[(3) - (4)].ident), (yyvsp[(4) - (4)].expressionNode).m_node, (yyvsp[(4) - (4)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(3) - (4)]).first_column, (yylsp[(4) - (4)]).first_column + 1, (yylsp[(4) - (4)]).last_column); @@ -3898,6 +4164,8 @@ yyreduce: break; case 226: + +/* Line 1455 of yacc.c */ #line 867 "../parser/Grammar.y" { (yyval.varDeclList).m_node = 0; (yyval.varDeclList).m_varDeclarations = new ParserRefCountedData(GLOBAL_DATA); @@ -3909,6 +4177,8 @@ yyreduce: break; case 227: + +/* Line 1455 of yacc.c */ #line 874 "../parser/Grammar.y" { AssignResolveNode* node = new AssignResolveNode(GLOBAL_DATA, *(yyvsp[(1) - (2)].ident), (yyvsp[(2) - (2)].expressionNode).m_node, (yyvsp[(2) - (2)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column); @@ -3922,6 +4192,8 @@ yyreduce: break; case 228: + +/* Line 1455 of yacc.c */ #line 884 "../parser/Grammar.y" { (yyval.varDeclList).m_node = (yyvsp[(1) - (3)].varDeclList).m_node; (yyval.varDeclList).m_varDeclarations = (yyvsp[(1) - (3)].varDeclList).m_varDeclarations; @@ -3933,6 +4205,8 @@ yyreduce: break; case 229: + +/* Line 1455 of yacc.c */ #line 892 "../parser/Grammar.y" { AssignResolveNode* node = new AssignResolveNode(GLOBAL_DATA, *(yyvsp[(3) - (4)].ident), (yyvsp[(4) - (4)].expressionNode).m_node, (yyvsp[(4) - (4)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(3) - (4)]).first_column, (yylsp[(4) - (4)]).first_column + 1, (yylsp[(4) - (4)]).last_column); @@ -3946,18 +4220,24 @@ yyreduce: break; case 230: + +/* Line 1455 of yacc.c */ #line 904 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new ConstStatementNode(GLOBAL_DATA, (yyvsp[(2) - (3)].constDeclList).m_node.head), (yyvsp[(2) - (3)].constDeclList).m_varDeclarations, (yyvsp[(2) - (3)].constDeclList).m_funcDeclarations, (yyvsp[(2) - (3)].constDeclList).m_features, (yyvsp[(2) - (3)].constDeclList).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;} break; case 231: + +/* Line 1455 of yacc.c */ #line 907 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new ConstStatementNode(GLOBAL_DATA, (yyvsp[(2) - (3)].constDeclList).m_node.head), (yyvsp[(2) - (3)].constDeclList).m_varDeclarations, (yyvsp[(2) - (3)].constDeclList).m_funcDeclarations, (yyvsp[(2) - (3)].constDeclList).m_features, (yyvsp[(2) - (3)].constDeclList).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); AUTO_SEMICOLON; ;} break; case 232: + +/* Line 1455 of yacc.c */ #line 912 "../parser/Grammar.y" { (yyval.constDeclList).m_node.head = (yyvsp[(1) - (1)].constDeclNode).m_node; (yyval.constDeclList).m_node.tail = (yyval.constDeclList).m_node.head; @@ -3970,6 +4250,8 @@ yyreduce: break; case 233: + +/* Line 1455 of yacc.c */ #line 921 "../parser/Grammar.y" { (yyval.constDeclList).m_node.head = (yyvsp[(1) - (3)].constDeclList).m_node.head; (yyvsp[(1) - (3)].constDeclList).m_node.tail->m_next = (yyvsp[(3) - (3)].constDeclNode).m_node; @@ -3982,49 +4264,67 @@ yyreduce: break; case 234: + +/* Line 1455 of yacc.c */ #line 932 "../parser/Grammar.y" { (yyval.constDeclNode) = createNodeInfo(new ConstDeclNode(GLOBAL_DATA, *(yyvsp[(1) - (1)].ident), 0), (*(yyvsp[(1) - (1)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0, 0); ;} break; case 235: + +/* Line 1455 of yacc.c */ #line 933 "../parser/Grammar.y" { (yyval.constDeclNode) = createNodeInfo(new ConstDeclNode(GLOBAL_DATA, *(yyvsp[(1) - (2)].ident), (yyvsp[(2) - (2)].expressionNode).m_node), ((*(yyvsp[(1) - (2)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 236: + +/* Line 1455 of yacc.c */ #line 937 "../parser/Grammar.y" { (yyval.expressionNode) = (yyvsp[(2) - (2)].expressionNode); ;} break; case 237: + +/* Line 1455 of yacc.c */ #line 941 "../parser/Grammar.y" { (yyval.expressionNode) = (yyvsp[(2) - (2)].expressionNode); ;} break; case 238: + +/* Line 1455 of yacc.c */ #line 945 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new EmptyStatementNode(GLOBAL_DATA), 0, 0, 0, 0); ;} break; case 239: + +/* Line 1455 of yacc.c */ #line 949 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new ExprStatementNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode).m_node), 0, 0, (yyvsp[(1) - (2)].expressionNode).m_features, (yyvsp[(1) - (2)].expressionNode).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;} break; case 240: + +/* Line 1455 of yacc.c */ #line 951 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new ExprStatementNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode).m_node), 0, 0, (yyvsp[(1) - (2)].expressionNode).m_features, (yyvsp[(1) - (2)].expressionNode).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; ;} break; case 241: + +/* Line 1455 of yacc.c */ #line 957 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new IfNode(GLOBAL_DATA, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].statementNode).m_node), (yyvsp[(5) - (5)].statementNode).m_varDeclarations, (yyvsp[(5) - (5)].statementNode).m_funcDeclarations, (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].statementNode).m_features, (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].statementNode).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (5)]), (yylsp[(4) - (5)])); ;} break; case 242: + +/* Line 1455 of yacc.c */ #line 960 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new IfElseNode(GLOBAL_DATA, (yyvsp[(3) - (7)].expressionNode).m_node, (yyvsp[(5) - (7)].statementNode).m_node, (yyvsp[(7) - (7)].statementNode).m_node), mergeDeclarationLists((yyvsp[(5) - (7)].statementNode).m_varDeclarations, (yyvsp[(7) - (7)].statementNode).m_varDeclarations), mergeDeclarationLists((yyvsp[(5) - (7)].statementNode).m_funcDeclarations, (yyvsp[(7) - (7)].statementNode).m_funcDeclarations), @@ -4034,24 +4334,32 @@ yyreduce: break; case 243: + +/* Line 1455 of yacc.c */ #line 968 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new DoWhileNode(GLOBAL_DATA, (yyvsp[(2) - (7)].statementNode).m_node, (yyvsp[(5) - (7)].expressionNode).m_node), (yyvsp[(2) - (7)].statementNode).m_varDeclarations, (yyvsp[(2) - (7)].statementNode).m_funcDeclarations, (yyvsp[(2) - (7)].statementNode).m_features | (yyvsp[(5) - (7)].expressionNode).m_features, (yyvsp[(2) - (7)].statementNode).m_numConstants + (yyvsp[(5) - (7)].expressionNode).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (7)]), (yylsp[(3) - (7)])); ;} break; case 244: + +/* Line 1455 of yacc.c */ #line 970 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new DoWhileNode(GLOBAL_DATA, (yyvsp[(2) - (7)].statementNode).m_node, (yyvsp[(5) - (7)].expressionNode).m_node), (yyvsp[(2) - (7)].statementNode).m_varDeclarations, (yyvsp[(2) - (7)].statementNode).m_funcDeclarations, (yyvsp[(2) - (7)].statementNode).m_features | (yyvsp[(5) - (7)].expressionNode).m_features, (yyvsp[(2) - (7)].statementNode).m_numConstants + (yyvsp[(5) - (7)].expressionNode).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (7)]), (yylsp[(3) - (7)])); ;} break; case 245: + +/* Line 1455 of yacc.c */ #line 972 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new WhileNode(GLOBAL_DATA, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].statementNode).m_node), (yyvsp[(5) - (5)].statementNode).m_varDeclarations, (yyvsp[(5) - (5)].statementNode).m_funcDeclarations, (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].statementNode).m_features, (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].statementNode).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (5)]), (yylsp[(4) - (5)])); ;} break; case 246: + +/* Line 1455 of yacc.c */ #line 975 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new ForNode(GLOBAL_DATA, (yyvsp[(3) - (9)].expressionNode).m_node, (yyvsp[(5) - (9)].expressionNode).m_node, (yyvsp[(7) - (9)].expressionNode).m_node, (yyvsp[(9) - (9)].statementNode).m_node, false), (yyvsp[(9) - (9)].statementNode).m_varDeclarations, (yyvsp[(9) - (9)].statementNode).m_funcDeclarations, (yyvsp[(3) - (9)].expressionNode).m_features | (yyvsp[(5) - (9)].expressionNode).m_features | (yyvsp[(7) - (9)].expressionNode).m_features | (yyvsp[(9) - (9)].statementNode).m_features, @@ -4061,6 +4369,8 @@ yyreduce: break; case 247: + +/* Line 1455 of yacc.c */ #line 981 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new ForNode(GLOBAL_DATA, (yyvsp[(4) - (10)].varDeclList).m_node, (yyvsp[(6) - (10)].expressionNode).m_node, (yyvsp[(8) - (10)].expressionNode).m_node, (yyvsp[(10) - (10)].statementNode).m_node, true), mergeDeclarationLists((yyvsp[(4) - (10)].varDeclList).m_varDeclarations, (yyvsp[(10) - (10)].statementNode).m_varDeclarations), @@ -4071,6 +4381,8 @@ yyreduce: break; case 248: + +/* Line 1455 of yacc.c */ #line 988 "../parser/Grammar.y" { ForInNode* node = new ForInNode(GLOBAL_DATA, (yyvsp[(3) - (7)].expressionNode).m_node, (yyvsp[(5) - (7)].expressionNode).m_node, (yyvsp[(7) - (7)].statementNode).m_node); @@ -4083,6 +4395,8 @@ yyreduce: break; case 249: + +/* Line 1455 of yacc.c */ #line 997 "../parser/Grammar.y" { ForInNode *forIn = new ForInNode(GLOBAL_DATA, *(yyvsp[(4) - (8)].ident), 0, (yyvsp[(6) - (8)].expressionNode).m_node, (yyvsp[(8) - (8)].statementNode).m_node, (yylsp[(5) - (8)]).first_column, (yylsp[(5) - (8)]).first_column - (yylsp[(4) - (8)]).first_column, (yylsp[(6) - (8)]).last_column - (yylsp[(5) - (8)]).first_column); SET_EXCEPTION_LOCATION(forIn, (yylsp[(4) - (8)]).first_column, (yylsp[(5) - (8)]).first_column + 1, (yylsp[(6) - (8)]).last_column); @@ -4092,6 +4406,8 @@ yyreduce: break; case 250: + +/* Line 1455 of yacc.c */ #line 1003 "../parser/Grammar.y" { ForInNode *forIn = new ForInNode(GLOBAL_DATA, *(yyvsp[(4) - (9)].ident), (yyvsp[(5) - (9)].expressionNode).m_node, (yyvsp[(7) - (9)].expressionNode).m_node, (yyvsp[(9) - (9)].statementNode).m_node, (yylsp[(5) - (9)]).first_column, (yylsp[(5) - (9)]).first_column - (yylsp[(4) - (9)]).first_column, (yylsp[(5) - (9)]).last_column - (yylsp[(5) - (9)]).first_column); SET_EXCEPTION_LOCATION(forIn, (yylsp[(4) - (9)]).first_column, (yylsp[(6) - (9)]).first_column + 1, (yylsp[(7) - (9)]).last_column); @@ -4103,16 +4419,22 @@ yyreduce: break; case 251: + +/* Line 1455 of yacc.c */ #line 1013 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(0, 0, 0); ;} break; case 253: + +/* Line 1455 of yacc.c */ #line 1018 "../parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(0, 0, 0); ;} break; case 255: + +/* Line 1455 of yacc.c */ #line 1023 "../parser/Grammar.y" { ContinueNode* node = new ContinueNode(GLOBAL_DATA); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); @@ -4121,6 +4443,8 @@ yyreduce: break; case 256: + +/* Line 1455 of yacc.c */ #line 1027 "../parser/Grammar.y" { ContinueNode* node = new ContinueNode(GLOBAL_DATA); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); @@ -4129,6 +4453,8 @@ yyreduce: break; case 257: + +/* Line 1455 of yacc.c */ #line 1031 "../parser/Grammar.y" { ContinueNode* node = new ContinueNode(GLOBAL_DATA, *(yyvsp[(2) - (3)].ident)); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4137,6 +4463,8 @@ yyreduce: break; case 258: + +/* Line 1455 of yacc.c */ #line 1035 "../parser/Grammar.y" { ContinueNode* node = new ContinueNode(GLOBAL_DATA, *(yyvsp[(2) - (3)].ident)); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4145,6 +4473,8 @@ yyreduce: break; case 259: + +/* Line 1455 of yacc.c */ #line 1042 "../parser/Grammar.y" { BreakNode* node = new BreakNode(GLOBAL_DATA); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); @@ -4152,6 +4482,8 @@ yyreduce: break; case 260: + +/* Line 1455 of yacc.c */ #line 1045 "../parser/Grammar.y" { BreakNode* node = new BreakNode(GLOBAL_DATA); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); @@ -4159,6 +4491,8 @@ yyreduce: break; case 261: + +/* Line 1455 of yacc.c */ #line 1048 "../parser/Grammar.y" { BreakNode* node = new BreakNode(GLOBAL_DATA, *(yyvsp[(2) - (3)].ident)); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4166,6 +4500,8 @@ yyreduce: break; case 262: + +/* Line 1455 of yacc.c */ #line 1051 "../parser/Grammar.y" { BreakNode* node = new BreakNode(GLOBAL_DATA, *(yyvsp[(2) - (3)].ident)); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4173,6 +4509,8 @@ yyreduce: break; case 263: + +/* Line 1455 of yacc.c */ #line 1057 "../parser/Grammar.y" { ReturnNode* node = new ReturnNode(GLOBAL_DATA, 0); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); @@ -4180,6 +4518,8 @@ yyreduce: break; case 264: + +/* Line 1455 of yacc.c */ #line 1060 "../parser/Grammar.y" { ReturnNode* node = new ReturnNode(GLOBAL_DATA, 0); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); @@ -4187,6 +4527,8 @@ yyreduce: break; case 265: + +/* Line 1455 of yacc.c */ #line 1063 "../parser/Grammar.y" { ReturnNode* node = new ReturnNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4194,6 +4536,8 @@ yyreduce: break; case 266: + +/* Line 1455 of yacc.c */ #line 1066 "../parser/Grammar.y" { ReturnNode* node = new ReturnNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4201,6 +4545,8 @@ yyreduce: break; case 267: + +/* Line 1455 of yacc.c */ #line 1072 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new WithNode(GLOBAL_DATA, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].statementNode).m_node, (yylsp[(3) - (5)]).last_column, (yylsp[(3) - (5)]).last_column - (yylsp[(3) - (5)]).first_column), (yyvsp[(5) - (5)].statementNode).m_varDeclarations, (yyvsp[(5) - (5)].statementNode).m_funcDeclarations, (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].statementNode).m_features | WithFeature, (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].statementNode).m_numConstants); @@ -4208,6 +4554,8 @@ yyreduce: break; case 268: + +/* Line 1455 of yacc.c */ #line 1078 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new SwitchNode(GLOBAL_DATA, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].caseBlockNode).m_node), (yyvsp[(5) - (5)].caseBlockNode).m_varDeclarations, (yyvsp[(5) - (5)].caseBlockNode).m_funcDeclarations, (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].caseBlockNode).m_features, (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].caseBlockNode).m_numConstants); @@ -4215,11 +4563,15 @@ yyreduce: break; case 269: + +/* Line 1455 of yacc.c */ #line 1084 "../parser/Grammar.y" { (yyval.caseBlockNode) = createNodeDeclarationInfo(new CaseBlockNode(GLOBAL_DATA, (yyvsp[(2) - (3)].clauseList).m_node.head, 0, 0), (yyvsp[(2) - (3)].clauseList).m_varDeclarations, (yyvsp[(2) - (3)].clauseList).m_funcDeclarations, (yyvsp[(2) - (3)].clauseList).m_features, (yyvsp[(2) - (3)].clauseList).m_numConstants); ;} break; case 270: + +/* Line 1455 of yacc.c */ #line 1086 "../parser/Grammar.y" { (yyval.caseBlockNode) = createNodeDeclarationInfo(new CaseBlockNode(GLOBAL_DATA, (yyvsp[(2) - (5)].clauseList).m_node.head, (yyvsp[(3) - (5)].caseClauseNode).m_node, (yyvsp[(4) - (5)].clauseList).m_node.head), mergeDeclarationLists(mergeDeclarationLists((yyvsp[(2) - (5)].clauseList).m_varDeclarations, (yyvsp[(3) - (5)].caseClauseNode).m_varDeclarations), (yyvsp[(4) - (5)].clauseList).m_varDeclarations), @@ -4229,11 +4581,15 @@ yyreduce: break; case 271: + +/* Line 1455 of yacc.c */ #line 1094 "../parser/Grammar.y" { (yyval.clauseList).m_node.head = 0; (yyval.clauseList).m_node.tail = 0; (yyval.clauseList).m_varDeclarations = 0; (yyval.clauseList).m_funcDeclarations = 0; (yyval.clauseList).m_features = 0; (yyval.clauseList).m_numConstants = 0; ;} break; case 273: + +/* Line 1455 of yacc.c */ #line 1099 "../parser/Grammar.y" { (yyval.clauseList).m_node.head = new ClauseListNode(GLOBAL_DATA, (yyvsp[(1) - (1)].caseClauseNode).m_node); (yyval.clauseList).m_node.tail = (yyval.clauseList).m_node.head; @@ -4244,6 +4600,8 @@ yyreduce: break; case 274: + +/* Line 1455 of yacc.c */ #line 1105 "../parser/Grammar.y" { (yyval.clauseList).m_node.head = (yyvsp[(1) - (2)].clauseList).m_node.head; (yyval.clauseList).m_node.tail = new ClauseListNode(GLOBAL_DATA, (yyvsp[(1) - (2)].clauseList).m_node.tail, (yyvsp[(2) - (2)].caseClauseNode).m_node); @@ -4255,26 +4613,36 @@ yyreduce: break; case 275: + +/* Line 1455 of yacc.c */ #line 1115 "../parser/Grammar.y" { (yyval.caseClauseNode) = createNodeDeclarationInfo(new CaseClauseNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node), 0, 0, (yyvsp[(2) - (3)].expressionNode).m_features, (yyvsp[(2) - (3)].expressionNode).m_numConstants); ;} break; case 276: + +/* Line 1455 of yacc.c */ #line 1116 "../parser/Grammar.y" { (yyval.caseClauseNode) = createNodeDeclarationInfo(new CaseClauseNode(GLOBAL_DATA, (yyvsp[(2) - (4)].expressionNode).m_node, (yyvsp[(4) - (4)].sourceElements).m_node), (yyvsp[(4) - (4)].sourceElements).m_varDeclarations, (yyvsp[(4) - (4)].sourceElements).m_funcDeclarations, (yyvsp[(2) - (4)].expressionNode).m_features | (yyvsp[(4) - (4)].sourceElements).m_features, (yyvsp[(2) - (4)].expressionNode).m_numConstants + (yyvsp[(4) - (4)].sourceElements).m_numConstants); ;} break; case 277: + +/* Line 1455 of yacc.c */ #line 1120 "../parser/Grammar.y" { (yyval.caseClauseNode) = createNodeDeclarationInfo(new CaseClauseNode(GLOBAL_DATA, 0), 0, 0, 0, 0); ;} break; case 278: + +/* Line 1455 of yacc.c */ #line 1121 "../parser/Grammar.y" { (yyval.caseClauseNode) = createNodeDeclarationInfo(new CaseClauseNode(GLOBAL_DATA, 0, (yyvsp[(3) - (3)].sourceElements).m_node), (yyvsp[(3) - (3)].sourceElements).m_varDeclarations, (yyvsp[(3) - (3)].sourceElements).m_funcDeclarations, (yyvsp[(3) - (3)].sourceElements).m_features, (yyvsp[(3) - (3)].sourceElements).m_numConstants); ;} break; case 279: + +/* Line 1455 of yacc.c */ #line 1125 "../parser/Grammar.y" { LabelNode* node = new LabelNode(GLOBAL_DATA, *(yyvsp[(1) - (3)].ident), (yyvsp[(3) - (3)].statementNode).m_node); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4282,6 +4650,8 @@ yyreduce: break; case 280: + +/* Line 1455 of yacc.c */ #line 1131 "../parser/Grammar.y" { ThrowNode* node = new ThrowNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4290,6 +4660,8 @@ yyreduce: break; case 281: + +/* Line 1455 of yacc.c */ #line 1135 "../parser/Grammar.y" { ThrowNode* node = new ThrowNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4298,6 +4670,8 @@ yyreduce: break; case 282: + +/* Line 1455 of yacc.c */ #line 1142 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new TryNode(GLOBAL_DATA, (yyvsp[(2) - (4)].statementNode).m_node, GLOBAL_DATA->propertyNames->nullIdentifier, false, 0, (yyvsp[(4) - (4)].statementNode).m_node), mergeDeclarationLists((yyvsp[(2) - (4)].statementNode).m_varDeclarations, (yyvsp[(4) - (4)].statementNode).m_varDeclarations), @@ -4308,6 +4682,8 @@ yyreduce: break; case 283: + +/* Line 1455 of yacc.c */ #line 1148 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new TryNode(GLOBAL_DATA, (yyvsp[(2) - (7)].statementNode).m_node, *(yyvsp[(5) - (7)].ident), ((yyvsp[(7) - (7)].statementNode).m_features & EvalFeature) != 0, (yyvsp[(7) - (7)].statementNode).m_node, 0), mergeDeclarationLists((yyvsp[(2) - (7)].statementNode).m_varDeclarations, (yyvsp[(7) - (7)].statementNode).m_varDeclarations), @@ -4318,6 +4694,8 @@ yyreduce: break; case 284: + +/* Line 1455 of yacc.c */ #line 1155 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new TryNode(GLOBAL_DATA, (yyvsp[(2) - (9)].statementNode).m_node, *(yyvsp[(5) - (9)].ident), ((yyvsp[(7) - (9)].statementNode).m_features & EvalFeature) != 0, (yyvsp[(7) - (9)].statementNode).m_node, (yyvsp[(9) - (9)].statementNode).m_node), mergeDeclarationLists(mergeDeclarationLists((yyvsp[(2) - (9)].statementNode).m_varDeclarations, (yyvsp[(7) - (9)].statementNode).m_varDeclarations), (yyvsp[(9) - (9)].statementNode).m_varDeclarations), @@ -4328,23 +4706,31 @@ yyreduce: break; case 285: + +/* Line 1455 of yacc.c */ #line 1164 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new DebuggerStatementNode(GLOBAL_DATA), 0, 0, 0, 0); DBG((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;} break; case 286: + +/* Line 1455 of yacc.c */ #line 1166 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new DebuggerStatementNode(GLOBAL_DATA), 0, 0, 0, 0); DBG((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; ;} break; case 287: + +/* Line 1455 of yacc.c */ #line 1171 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new FuncDeclNode(GLOBAL_DATA, *(yyvsp[(2) - (7)].ident), (yyvsp[(6) - (7)].functionBodyNode), LEXER->sourceCode((yyvsp[(5) - (7)].intValue), (yyvsp[(7) - (7)].intValue), (yylsp[(5) - (7)]).first_line)), 0, new ParserRefCountedData(GLOBAL_DATA), ((*(yyvsp[(2) - (7)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | ClosureFeature, 0); DBG((yyvsp[(6) - (7)].functionBodyNode), (yylsp[(5) - (7)]), (yylsp[(7) - (7)])); (yyval.statementNode).m_funcDeclarations->data.append(static_cast((yyval.statementNode).m_node)); ;} break; case 288: + +/* Line 1455 of yacc.c */ #line 1173 "../parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new FuncDeclNode(GLOBAL_DATA, *(yyvsp[(2) - (8)].ident), (yyvsp[(7) - (8)].functionBodyNode), LEXER->sourceCode((yyvsp[(6) - (8)].intValue), (yyvsp[(8) - (8)].intValue), (yylsp[(6) - (8)]).first_line), (yyvsp[(4) - (8)].parameterList).m_node.head), 0, new ParserRefCountedData(GLOBAL_DATA), ((*(yyvsp[(2) - (8)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | (yyvsp[(4) - (8)].parameterList).m_features | ClosureFeature, 0); @@ -4356,11 +4742,15 @@ yyreduce: break; case 289: + +/* Line 1455 of yacc.c */ #line 1183 "../parser/Grammar.y" { (yyval.funcExprNode) = createNodeInfo(new FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, (yyvsp[(5) - (6)].functionBodyNode), LEXER->sourceCode((yyvsp[(4) - (6)].intValue), (yyvsp[(6) - (6)].intValue), (yylsp[(4) - (6)]).first_line)), ClosureFeature, 0); DBG((yyvsp[(5) - (6)].functionBodyNode), (yylsp[(4) - (6)]), (yylsp[(6) - (6)])); ;} break; case 290: + +/* Line 1455 of yacc.c */ #line 1185 "../parser/Grammar.y" { (yyval.funcExprNode) = createNodeInfo(new FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, (yyvsp[(6) - (7)].functionBodyNode), LEXER->sourceCode((yyvsp[(5) - (7)].intValue), (yyvsp[(7) - (7)].intValue), (yylsp[(5) - (7)]).first_line), (yyvsp[(3) - (7)].parameterList).m_node.head), (yyvsp[(3) - (7)].parameterList).m_features | ClosureFeature, 0); @@ -4371,11 +4761,15 @@ yyreduce: break; case 291: + +/* Line 1455 of yacc.c */ #line 1191 "../parser/Grammar.y" { (yyval.funcExprNode) = createNodeInfo(new FuncExprNode(GLOBAL_DATA, *(yyvsp[(2) - (7)].ident), (yyvsp[(6) - (7)].functionBodyNode), LEXER->sourceCode((yyvsp[(5) - (7)].intValue), (yyvsp[(7) - (7)].intValue), (yylsp[(5) - (7)]).first_line)), ClosureFeature, 0); DBG((yyvsp[(6) - (7)].functionBodyNode), (yylsp[(5) - (7)]), (yylsp[(7) - (7)])); ;} break; case 292: + +/* Line 1455 of yacc.c */ #line 1193 "../parser/Grammar.y" { (yyval.funcExprNode) = createNodeInfo(new FuncExprNode(GLOBAL_DATA, *(yyvsp[(2) - (8)].ident), (yyvsp[(7) - (8)].functionBodyNode), LEXER->sourceCode((yyvsp[(6) - (8)].intValue), (yyvsp[(8) - (8)].intValue), (yylsp[(6) - (8)]).first_line), (yyvsp[(4) - (8)].parameterList).m_node.head), (yyvsp[(4) - (8)].parameterList).m_features | ClosureFeature, 0); @@ -4386,6 +4780,8 @@ yyreduce: break; case 293: + +/* Line 1455 of yacc.c */ #line 1202 "../parser/Grammar.y" { (yyval.parameterList).m_node.head = new ParameterNode(GLOBAL_DATA, *(yyvsp[(1) - (1)].ident)); (yyval.parameterList).m_features = (*(yyvsp[(1) - (1)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0; @@ -4393,6 +4789,8 @@ yyreduce: break; case 294: + +/* Line 1455 of yacc.c */ #line 1205 "../parser/Grammar.y" { (yyval.parameterList).m_node.head = (yyvsp[(1) - (3)].parameterList).m_node.head; (yyval.parameterList).m_features = (yyvsp[(1) - (3)].parameterList).m_features | ((*(yyvsp[(3) - (3)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0); @@ -4400,27 +4798,37 @@ yyreduce: break; case 295: + +/* Line 1455 of yacc.c */ #line 1211 "../parser/Grammar.y" { (yyval.functionBodyNode) = FunctionBodyNode::create(GLOBAL_DATA); ;} break; case 296: + +/* Line 1455 of yacc.c */ #line 1212 "../parser/Grammar.y" { (yyval.functionBodyNode) = FunctionBodyNode::create(GLOBAL_DATA); ;} break; case 297: + +/* Line 1455 of yacc.c */ #line 1216 "../parser/Grammar.y" { GLOBAL_DATA->parser->didFinishParsing(new SourceElements(GLOBAL_DATA), 0, 0, NoFeatures, (yylsp[(0) - (0)]).last_line, 0); ;} break; case 298: + +/* Line 1455 of yacc.c */ #line 1217 "../parser/Grammar.y" { GLOBAL_DATA->parser->didFinishParsing((yyvsp[(1) - (1)].sourceElements).m_node, (yyvsp[(1) - (1)].sourceElements).m_varDeclarations, (yyvsp[(1) - (1)].sourceElements).m_funcDeclarations, (yyvsp[(1) - (1)].sourceElements).m_features, (yylsp[(1) - (1)]).last_line, (yyvsp[(1) - (1)].sourceElements).m_numConstants); ;} break; case 299: + +/* Line 1455 of yacc.c */ #line 1222 "../parser/Grammar.y" { (yyval.sourceElements).m_node = new SourceElements(GLOBAL_DATA); (yyval.sourceElements).m_node->append((yyvsp[(1) - (1)].statementNode).m_node); @@ -4432,6 +4840,8 @@ yyreduce: break; case 300: + +/* Line 1455 of yacc.c */ #line 1229 "../parser/Grammar.y" { (yyval.sourceElements).m_node->append((yyvsp[(2) - (2)].statementNode).m_node); (yyval.sourceElements).m_varDeclarations = mergeDeclarationLists((yyvsp[(1) - (2)].sourceElements).m_varDeclarations, (yyvsp[(2) - (2)].statementNode).m_varDeclarations); @@ -4442,188 +4852,261 @@ yyreduce: break; case 304: + +/* Line 1455 of yacc.c */ #line 1243 "../parser/Grammar.y" { ;} break; case 305: + +/* Line 1455 of yacc.c */ #line 1244 "../parser/Grammar.y" { ;} break; case 306: + +/* Line 1455 of yacc.c */ #line 1245 "../parser/Grammar.y" { Lexer& l = *LEXER; if (!l.scanRegExp()) YYABORT; ;} break; case 307: + +/* Line 1455 of yacc.c */ #line 1246 "../parser/Grammar.y" { Lexer& l = *LEXER; if (!l.scanRegExp()) YYABORT; ;} break; case 308: + +/* Line 1455 of yacc.c */ #line 1250 "../parser/Grammar.y" { ;} break; case 309: + +/* Line 1455 of yacc.c */ #line 1251 "../parser/Grammar.y" { ;} break; case 310: + +/* Line 1455 of yacc.c */ #line 1252 "../parser/Grammar.y" { ;} break; case 311: + +/* Line 1455 of yacc.c */ #line 1253 "../parser/Grammar.y" { if (*(yyvsp[(1) - (7)].ident) != "get" && *(yyvsp[(1) - (7)].ident) != "set") YYABORT; ;} break; case 312: + +/* Line 1455 of yacc.c */ #line 1254 "../parser/Grammar.y" { if (*(yyvsp[(1) - (8)].ident) != "get" && *(yyvsp[(1) - (8)].ident) != "set") YYABORT; ;} break; case 316: + +/* Line 1455 of yacc.c */ #line 1264 "../parser/Grammar.y" { ;} break; case 317: + +/* Line 1455 of yacc.c */ #line 1265 "../parser/Grammar.y" { ;} break; case 318: + +/* Line 1455 of yacc.c */ #line 1267 "../parser/Grammar.y" { ;} break; case 322: + +/* Line 1455 of yacc.c */ #line 1274 "../parser/Grammar.y" { ;} break; case 517: + +/* Line 1455 of yacc.c */ #line 1642 "../parser/Grammar.y" { ;} break; case 518: + +/* Line 1455 of yacc.c */ #line 1643 "../parser/Grammar.y" { ;} break; case 520: + +/* Line 1455 of yacc.c */ #line 1648 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 521: + +/* Line 1455 of yacc.c */ #line 1652 "../parser/Grammar.y" { ;} break; case 522: + +/* Line 1455 of yacc.c */ #line 1653 "../parser/Grammar.y" { ;} break; case 525: + +/* Line 1455 of yacc.c */ #line 1659 "../parser/Grammar.y" { ;} break; case 526: + +/* Line 1455 of yacc.c */ #line 1660 "../parser/Grammar.y" { ;} break; case 530: + +/* Line 1455 of yacc.c */ #line 1667 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 533: + +/* Line 1455 of yacc.c */ #line 1676 "../parser/Grammar.y" { ;} break; case 534: + +/* Line 1455 of yacc.c */ #line 1677 "../parser/Grammar.y" { ;} break; case 539: + +/* Line 1455 of yacc.c */ #line 1694 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 555: + +/* Line 1455 of yacc.c */ #line 1725 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 557: + +/* Line 1455 of yacc.c */ #line 1727 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 559: + +/* Line 1455 of yacc.c */ #line 1732 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 561: + +/* Line 1455 of yacc.c */ #line 1734 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 563: + +/* Line 1455 of yacc.c */ #line 1739 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 565: + +/* Line 1455 of yacc.c */ #line 1741 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 568: + +/* Line 1455 of yacc.c */ #line 1753 "../parser/Grammar.y" { ;} break; case 569: + +/* Line 1455 of yacc.c */ #line 1754 "../parser/Grammar.y" { ;} break; case 578: + +/* Line 1455 of yacc.c */ #line 1778 "../parser/Grammar.y" { ;} break; case 580: + +/* Line 1455 of yacc.c */ #line 1783 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 585: + +/* Line 1455 of yacc.c */ #line 1794 "../parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 592: + +/* Line 1455 of yacc.c */ #line 1810 "../parser/Grammar.y" { ;} break; -/* Line 1267 of yacc.c. */ -#line 4627 "Grammar.tab.c" + +/* Line 1455 of yacc.c */ +#line 5110 "Grammar.tab.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -4699,7 +5182,7 @@ yyerrlab: if (yyerrstatus == 3) { - /* If just tried and failed to reuse look-ahead token after an + /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) @@ -4716,7 +5199,7 @@ yyerrlab: } } - /* Else will try to reuse look-ahead token after shifting the error + /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; @@ -4774,14 +5257,11 @@ yyerrlab1: YY_STACK_PRINT (yyss, yyssp); } - if (yyn == YYFINAL) - YYACCEPT; - *++yyvsp = yylval; yyerror_range[1] = yylloc; /* Using YYLLOC is tempting, but would change the location of - the look-ahead. YYLOC is available though. */ + the lookahead. YYLOC is available though. */ YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); *++yylsp = yyloc; @@ -4806,7 +5286,7 @@ yyabortlab: yyresult = 1; goto yyreturn; -#ifndef yyoverflow +#if !defined(yyoverflow) || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ @@ -4817,7 +5297,7 @@ yyexhaustedlab: #endif yyreturn: - if (yychar != YYEOF && yychar != YYEMPTY) + if (yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc); /* Do not reclaim the symbols of the rule which action triggered @@ -4843,6 +5323,8 @@ yyreturn: } + +/* Line 1675 of yacc.c */ #line 1826 "../parser/Grammar.y" diff --git a/src/3rdparty/webkit/JavaScriptCore/generated/Grammar.h b/src/3rdparty/webkit/JavaScriptCore/generated/Grammar.h index 99dbd4c..293aa73 100644 --- a/src/3rdparty/webkit/JavaScriptCore/generated/Grammar.h +++ b/src/3rdparty/webkit/JavaScriptCore/generated/Grammar.h @@ -1,24 +1,23 @@ -/* A Bison parser, made by GNU Bison 2.3. */ -/* Skeleton interface for Bison's Yacc-like parsers in C +/* A Bison parser, made by GNU Bison 2.4.1. */ - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +/* Skeleton interface for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -29,10 +28,11 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ + /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE @@ -104,78 +104,16 @@ AUTOMINUSMINUS = 320 }; #endif -/* Tokens. */ -#define NULLTOKEN 258 -#define TRUETOKEN 259 -#define FALSETOKEN 260 -#define BREAK 261 -#define CASE 262 -#define DEFAULT 263 -#define FOR 264 -#define NEW 265 -#define VAR 266 -#define CONSTTOKEN 267 -#define CONTINUE 268 -#define FUNCTION 269 -#define RETURN 270 -#define VOIDTOKEN 271 -#define DELETETOKEN 272 -#define IF 273 -#define THISTOKEN 274 -#define DO 275 -#define WHILE 276 -#define INTOKEN 277 -#define INSTANCEOF 278 -#define TYPEOF 279 -#define SWITCH 280 -#define WITH 281 -#define RESERVED 282 -#define THROW 283 -#define TRY 284 -#define CATCH 285 -#define FINALLY 286 -#define DEBUGGER 287 -#define IF_WITHOUT_ELSE 288 -#define ELSE 289 -#define EQEQ 290 -#define NE 291 -#define STREQ 292 -#define STRNEQ 293 -#define LE 294 -#define GE 295 -#define OR 296 -#define AND 297 -#define PLUSPLUS 298 -#define MINUSMINUS 299 -#define LSHIFT 300 -#define RSHIFT 301 -#define URSHIFT 302 -#define PLUSEQUAL 303 -#define MINUSEQUAL 304 -#define MULTEQUAL 305 -#define DIVEQUAL 306 -#define LSHIFTEQUAL 307 -#define RSHIFTEQUAL 308 -#define URSHIFTEQUAL 309 -#define ANDEQUAL 310 -#define MODEQUAL 311 -#define XOREQUAL 312 -#define OREQUAL 313 -#define OPENBRACE 314 -#define CLOSEBRACE 315 -#define NUMBER 316 -#define IDENT 317 -#define STRING 318 -#define AUTOPLUSPLUS 319 -#define AUTOMINUSMINUS 320 - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 157 "../parser/Grammar.y" { + +/* Line 1676 of yacc.c */ +#line 157 "../parser/Grammar.y" + int intValue; double doubleValue; Identifier* ident; @@ -205,13 +143,15 @@ typedef union YYSTYPE ParameterListInfo parameterList; Operator op; -} -/* Line 1489 of yacc.c. */ -#line 211 "Grammar.tab.h" - YYSTYPE; + + + +/* Line 1676 of yacc.c */ +#line 151 "Grammar.tab.h" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 #endif @@ -230,3 +170,4 @@ typedef struct YYLTYPE #endif + diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index e084e27..368d2b5 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - e65b4879116f4a8b0ee8b09607eef666c68c61d6 + eb4957a561d3f85d4cd5602832375c66f378b521 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index c3b6c37..be6922f 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,81 @@ +2008-12-18 Bernhard Rosenkraenzer + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=22205 + Fix compatibility with bison 2.4, partially based on older patch by + Priit Laes + + * WebCore/css/CSSGrammar.y: Made compatible with bison 2.4 + +2009-07-13 Cédric Luthi + + Reviewed by Tor Arne Vestbø. + + Fix NPWindow clip rect in PluginViewMac + + The rect should be in window-coordinates. This bug can be observed + with Flash 10 here: http://www.permadi.com/tutorial/cursorTracker/ + + * plugins/mac/PluginViewMac.cpp: + +2009-07-13 Simon Hausmann + + Reviewed by Ariya Hidayat. + + Fix Qt implementation of WebCore::directoryName to return the absolute + directory name instead of the base file name. + + * platform/qt/FileSystemQt.cpp: + (WebCore::directoryName): + +2009-07-13 Simon Hausmann + + Reviewed by Ariya Hidayat. + + Fix WebCore::Path::isEmpty() for the Qt port to return true + if there is no element in the path. + + QPainterPath::isEmpty() returns also true if there is one single + MoveTo element inside, which makes sense but doesn't patch Webcore's + is-empty definition. + + * platform/graphics/qt/PathQt.cpp: + (WebCore::Path::isEmpty): Use elementCount() == 0. + +2009-01-11 Simon Fraser + + Reviewed by Oliver Hunt + + https://bugs.webkit.org/show_bug.cgi?id=23242 + + Fix CanvasRenderingContext2D::transform to do a pre-multiply, + rather than a post-multiply into m_transform. This bug did not affect + drawing, but did cause m_transform to be incorrect, which impacted + willDraw(), and isPointInPath. + + Test: fast/canvas/canvas-incremental-repaint-2.html + + * html/CanvasRenderingContext2D.cpp: + (WebCore::CanvasRenderingContext2D::transform): + +2009-07-04 Sriram Yadavalli + + Reviewed by Simon Hausmann. + + https://bugs.webkit.org/show_bug.cgi?id=26439 + + QtWebKit fails in loading www.nytimes.com in Windows/Linux + + QNetworkReplyHandler is ignoring content associated with 401 error. + This causes the XHR response handling to fail. + + Simon: Added also ProxyAuthenticationRequiredError, to handle the same + case when going through proxies, as suggested by Prasanth. + + * platform/network/qt/QNetworkReplyHandler.cpp: + (WebCore::QNetworkReplyHandler::finish): + 2009-06-25 Simon Hausmann Reviewed by and done with Tor Arne Vestbø. diff --git a/src/3rdparty/webkit/WebCore/css/CSSGrammar.y b/src/3rdparty/webkit/WebCore/css/CSSGrammar.y index 9ee9c93..31f1c8b 100644 --- a/src/3rdparty/webkit/WebCore/css/CSSGrammar.y +++ b/src/3rdparty/webkit/WebCore/css/CSSGrammar.y @@ -94,6 +94,8 @@ static int cssyylex(YYSTYPE* yylval, void* parser) %expect 49 +%nonassoc LOWEST_PREC + %left UNIMPORTANT_TOK %token WHITESPACE SGML_CD @@ -349,7 +351,7 @@ maybe_charset: closing_brace: '}' - | %prec maybe_sgml TOKEN_EOF + | %prec LOWEST_PREC TOKEN_EOF ; charset: @@ -1355,10 +1357,10 @@ term: $$.string = $1; } /* We might need to actually parse the number from a dimension, but we can't just put something that uses $$.string into unary_term. */ - | DIMEN maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_DIMENSION } - | unary_operator DIMEN maybe_space { $$.id = 0; $$.string = $2; $$.unit = CSSPrimitiveValue::CSS_DIMENSION } + | DIMEN maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; } + | unary_operator DIMEN maybe_space { $$.id = 0; $$.string = $2; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; } | URI maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_URI; } - | UNICODERANGE maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_UNICODE_RANGE } + | UNICODERANGE maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_UNICODE_RANGE; } | hexcolor { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; } | '#' maybe_space { $$.id = 0; $$.string = CSSParserString(); $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; } /* Handle error case: "color: #;" */ /* FIXME: according to the specs a function can have a unary_operator in front. I know no case where this makes sense */ diff --git a/src/3rdparty/webkit/WebCore/generated/CSSGrammar.cpp b/src/3rdparty/webkit/WebCore/generated/CSSGrammar.cpp index b980a0a..03a7829 100644 --- a/src/3rdparty/webkit/WebCore/generated/CSSGrammar.cpp +++ b/src/3rdparty/webkit/WebCore/generated/CSSGrammar.cpp @@ -1,24 +1,23 @@ -/* A Bison parser, made by GNU Bison 2.3. */ -/* Skeleton implementation for Bison's Yacc-like parsers in C +/* A Bison parser, made by GNU Bison 2.4.1. */ - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -29,7 +28,7 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ @@ -47,7 +46,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.3" +#define YYBISON_VERSION "2.4.1" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -55,157 +54,28 @@ /* Pure parsers. */ #define YYPURE 1 +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + /* Using locations. */ #define YYLSP_NEEDED 0 /* Substitute the variable and function names. */ -#define yyparse cssyyparse -#define yylex cssyylex -#define yyerror cssyyerror -#define yylval cssyylval -#define yychar cssyychar -#define yydebug cssyydebug -#define yynerrs cssyynerrs - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - TOKEN_EOF = 0, - UNIMPORTANT_TOK = 258, - WHITESPACE = 259, - SGML_CD = 260, - INCLUDES = 261, - DASHMATCH = 262, - BEGINSWITH = 263, - ENDSWITH = 264, - CONTAINS = 265, - STRING = 266, - IDENT = 267, - NTH = 268, - HEX = 269, - IDSEL = 270, - IMPORT_SYM = 271, - PAGE_SYM = 272, - MEDIA_SYM = 273, - FONT_FACE_SYM = 274, - CHARSET_SYM = 275, - NAMESPACE_SYM = 276, - WEBKIT_RULE_SYM = 277, - WEBKIT_DECLS_SYM = 278, - WEBKIT_KEYFRAME_RULE_SYM = 279, - WEBKIT_KEYFRAMES_SYM = 280, - WEBKIT_VALUE_SYM = 281, - WEBKIT_MEDIAQUERY_SYM = 282, - WEBKIT_SELECTOR_SYM = 283, - WEBKIT_VARIABLES_SYM = 284, - WEBKIT_DEFINE_SYM = 285, - VARIABLES_FOR = 286, - WEBKIT_VARIABLES_DECLS_SYM = 287, - ATKEYWORD = 288, - IMPORTANT_SYM = 289, - MEDIA_ONLY = 290, - MEDIA_NOT = 291, - MEDIA_AND = 292, - QEMS = 293, - EMS = 294, - EXS = 295, - PXS = 296, - CMS = 297, - MMS = 298, - INS = 299, - PTS = 300, - PCS = 301, - DEGS = 302, - RADS = 303, - GRADS = 304, - TURNS = 305, - MSECS = 306, - SECS = 307, - HERZ = 308, - KHERZ = 309, - DIMEN = 310, - PERCENTAGE = 311, - FLOATTOKEN = 312, - INTEGER = 313, - URI = 314, - FUNCTION = 315, - NOTFUNCTION = 316, - UNICODERANGE = 317, - VARCALL = 318 - }; -#endif -/* Tokens. */ -#define TOKEN_EOF 0 -#define UNIMPORTANT_TOK 258 -#define WHITESPACE 259 -#define SGML_CD 260 -#define INCLUDES 261 -#define DASHMATCH 262 -#define BEGINSWITH 263 -#define ENDSWITH 264 -#define CONTAINS 265 -#define STRING 266 -#define IDENT 267 -#define NTH 268 -#define HEX 269 -#define IDSEL 270 -#define IMPORT_SYM 271 -#define PAGE_SYM 272 -#define MEDIA_SYM 273 -#define FONT_FACE_SYM 274 -#define CHARSET_SYM 275 -#define NAMESPACE_SYM 276 -#define WEBKIT_RULE_SYM 277 -#define WEBKIT_DECLS_SYM 278 -#define WEBKIT_KEYFRAME_RULE_SYM 279 -#define WEBKIT_KEYFRAMES_SYM 280 -#define WEBKIT_VALUE_SYM 281 -#define WEBKIT_MEDIAQUERY_SYM 282 -#define WEBKIT_SELECTOR_SYM 283 -#define WEBKIT_VARIABLES_SYM 284 -#define WEBKIT_DEFINE_SYM 285 -#define VARIABLES_FOR 286 -#define WEBKIT_VARIABLES_DECLS_SYM 287 -#define ATKEYWORD 288 -#define IMPORTANT_SYM 289 -#define MEDIA_ONLY 290 -#define MEDIA_NOT 291 -#define MEDIA_AND 292 -#define QEMS 293 -#define EMS 294 -#define EXS 295 -#define PXS 296 -#define CMS 297 -#define MMS 298 -#define INS 299 -#define PTS 300 -#define PCS 301 -#define DEGS 302 -#define RADS 303 -#define GRADS 304 -#define TURNS 305 -#define MSECS 306 -#define SECS 307 -#define HERZ 308 -#define KHERZ 309 -#define DIMEN 310 -#define PERCENTAGE 311 -#define FLOATTOKEN 312 -#define INTEGER 313 -#define URI 314 -#define FUNCTION 315 -#define NOTFUNCTION 316 -#define UNICODERANGE 317 -#define VARCALL 318 - - +#define yyparse cssyyparse +#define yylex cssyylex +#define yyerror cssyyerror +#define yylval cssyylval +#define yychar cssyychar +#define yydebug cssyydebug +#define yynerrs cssyynerrs /* Copy the first part of user declarations. */ + +/* Line 189 of yacc.c */ #line 1 "../css/CSSGrammar.y" @@ -261,6 +131,9 @@ using namespace HTMLNames; +/* Line 189 of yacc.c */ +#line 136 "WebCore/tmp/../generated/CSSGrammar.tab.c" + /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -279,10 +152,88 @@ using namespace HTMLNames; # define YYTOKEN_TABLE 0 #endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + TOKEN_EOF = 0, + LOWEST_PREC = 258, + UNIMPORTANT_TOK = 259, + WHITESPACE = 260, + SGML_CD = 261, + INCLUDES = 262, + DASHMATCH = 263, + BEGINSWITH = 264, + ENDSWITH = 265, + CONTAINS = 266, + STRING = 267, + IDENT = 268, + NTH = 269, + HEX = 270, + IDSEL = 271, + IMPORT_SYM = 272, + PAGE_SYM = 273, + MEDIA_SYM = 274, + FONT_FACE_SYM = 275, + CHARSET_SYM = 276, + NAMESPACE_SYM = 277, + WEBKIT_RULE_SYM = 278, + WEBKIT_DECLS_SYM = 279, + WEBKIT_KEYFRAME_RULE_SYM = 280, + WEBKIT_KEYFRAMES_SYM = 281, + WEBKIT_VALUE_SYM = 282, + WEBKIT_MEDIAQUERY_SYM = 283, + WEBKIT_SELECTOR_SYM = 284, + WEBKIT_VARIABLES_SYM = 285, + WEBKIT_DEFINE_SYM = 286, + VARIABLES_FOR = 287, + WEBKIT_VARIABLES_DECLS_SYM = 288, + ATKEYWORD = 289, + IMPORTANT_SYM = 290, + MEDIA_ONLY = 291, + MEDIA_NOT = 292, + MEDIA_AND = 293, + QEMS = 294, + EMS = 295, + EXS = 296, + PXS = 297, + CMS = 298, + MMS = 299, + INS = 300, + PTS = 301, + PCS = 302, + DEGS = 303, + RADS = 304, + GRADS = 305, + TURNS = 306, + MSECS = 307, + SECS = 308, + HERZ = 309, + KHERZ = 310, + DIMEN = 311, + PERCENTAGE = 312, + FLOATTOKEN = 313, + INTEGER = 314, + URI = 315, + FUNCTION = 316, + NOTFUNCTION = 317, + UNICODERANGE = 318, + VARCALL = 319 + }; +#endif + + + #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 57 "../css/CSSGrammar.y" { + +/* Line 214 of yacc.c */ +#line 57 "../css/CSSGrammar.y" + bool boolean; char character; int integer; @@ -304,18 +255,21 @@ typedef union YYSTYPE WebKitCSSKeyframeRule* keyframeRule; WebKitCSSKeyframesRule* keyframesRule; float val; -} -/* Line 187 of yacc.c. */ -#line 310 "WebCore/tmp/../generated/CSSGrammar.tab.c" - YYSTYPE; + + + +/* Line 214 of yacc.c */ +#line 263 "WebCore/tmp/../generated/CSSGrammar.tab.c" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 #endif - /* Copy the second part of user declarations. */ + +/* Line 264 of yacc.c */ #line 81 "../css/CSSGrammar.y" @@ -331,8 +285,8 @@ static int cssyylex(YYSTYPE* yylval, void* parser) -/* Line 216 of yacc.c. */ -#line 336 "WebCore/tmp/../generated/CSSGrammar.tab.c" +/* Line 264 of yacc.c */ +#line 290 "WebCore/tmp/../generated/CSSGrammar.tab.c" #ifdef short # undef short @@ -407,14 +361,14 @@ typedef short int yytype_int16; #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int -YYID (int i) +YYID (int yyi) #else static int -YYID (i) - int i; +YYID (yyi) + int yyi; #endif { - return i; + return yyi; } #endif @@ -495,9 +449,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ /* A type that is properly aligned for any stack member. */ union yyalloc { - yytype_int16 yyss; - YYSTYPE yyvs; - }; + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) @@ -531,12 +485,12 @@ union yyalloc elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ -# define YYSTACK_RELOCATE(Stack) \ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ @@ -547,10 +501,10 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 28 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 1274 +#define YYLAST 1315 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 84 +#define YYNTOKENS 85 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 90 /* YYNRULES -- Number of rules. */ @@ -560,7 +514,7 @@ union yyalloc /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 318 +#define YYMAXUTOK 319 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -571,16 +525,16 @@ static const yytype_uint8 yytranslate[] = 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 82, 2, 83, 2, 2, - 72, 73, 19, 75, 74, 78, 17, 81, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 16, 71, - 2, 80, 77, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 83, 2, 84, 2, 2, + 73, 74, 20, 76, 75, 79, 18, 82, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 17, 72, + 2, 81, 78, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 18, 2, 79, 2, 2, 2, 2, 2, 2, + 2, 19, 2, 80, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 69, 20, 70, 76, 2, 2, 2, + 2, 2, 2, 70, 21, 71, 77, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -595,11 +549,11 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 15, 16, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68 + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69 }; #if YYDEBUG @@ -639,130 +593,130 @@ static const yytype_uint16 yyprhs[] = /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int16 yyrhs[] = { - 85, 0, -1, 96, 95, 99, 100, 101, 102, -1, - 87, 94, -1, 89, 94, -1, 91, 94, -1, 92, - 94, -1, 93, 94, -1, 90, 94, -1, 88, 94, - -1, 103, -1, 108, -1, 27, 69, 94, 86, 94, - 70, -1, 29, 69, 94, 132, 94, 70, -1, 28, - 69, 94, 154, 70, -1, 37, 69, 94, 111, 70, - -1, 31, 69, 94, 159, 70, -1, 32, 4, 94, - 124, 70, -1, 33, 69, 94, 140, 70, -1, -1, - 94, 4, -1, -1, 95, 5, -1, 95, 4, -1, - -1, 98, -1, 70, -1, 0, -1, 25, 94, 11, - 94, 71, -1, 25, 1, 172, -1, 25, 1, 71, - -1, -1, 99, 108, 95, -1, 168, -1, -1, 100, - 109, 95, -1, -1, 101, 115, 95, -1, -1, 102, - 104, 95, -1, 139, -1, 127, -1, 135, -1, 136, - -1, 129, -1, 103, -1, 171, -1, 167, -1, 169, - -1, -1, 105, 107, 95, -1, 139, -1, 135, -1, - 136, -1, 129, -1, 106, -1, 171, -1, 167, -1, - 169, -1, 170, -1, 21, 94, 117, 94, 125, 71, - -1, 21, 94, 117, 94, 125, 172, -1, 21, 1, - 71, -1, 21, 1, 172, -1, 34, 94, 125, 69, - 94, 111, 70, -1, 35, 94, 110, 69, 94, 111, - 70, -1, -1, 36, 4, 126, -1, 113, -1, 112, - 113, -1, 112, -1, 1, 173, 1, -1, 1, -1, - 112, 1, -1, 113, 71, 94, -1, 113, 173, 71, - 94, -1, 1, 71, 94, -1, 1, 173, 1, 71, - 94, -1, 112, 113, 71, 94, -1, 112, 1, 71, - 94, -1, 112, 1, 173, 1, 71, 94, -1, 114, - 16, 94, 159, -1, 114, 94, 69, 94, 154, 70, - 94, -1, 114, 1, -1, 114, 16, 94, 1, 159, - -1, 114, 16, 94, -1, 114, 16, 94, 1, -1, - 12, 94, -1, 26, 94, 116, 117, 94, 71, -1, - 26, 1, 172, -1, 26, 1, 71, -1, -1, 12, - 4, -1, 11, -1, 64, -1, 12, 94, -1, -1, - 16, 94, 159, 94, -1, 72, 94, 118, 94, 119, - 73, 94, -1, 120, -1, 121, 94, 42, 94, 120, - -1, -1, 42, 94, 121, -1, -1, 40, -1, 41, - -1, 121, -1, 123, 94, 128, 122, -1, -1, 126, - -1, 124, -1, 126, 74, 94, 124, -1, 126, 1, - -1, 23, 94, 126, 69, 94, 105, 166, -1, 23, - 94, 69, 94, 105, 166, -1, 12, 94, -1, 30, - 94, 130, 94, 69, 94, 131, 70, -1, 12, -1, - 11, -1, -1, 131, 132, 94, -1, 133, 94, 69, - 94, 154, 70, -1, 134, -1, 133, 94, 74, 94, - 134, -1, 61, -1, 12, -1, 22, 1, 172, -1, - 22, 1, 71, -1, 24, 94, 69, 94, 154, 70, - 94, -1, 24, 1, 172, -1, 24, 1, 71, -1, - 75, 94, -1, 76, 94, -1, 77, 94, -1, 78, - -1, 75, -1, 140, 69, 94, 154, 97, -1, 142, - -1, 140, 74, 94, 142, -1, 140, 1, -1, 142, - 4, -1, 144, -1, 141, -1, 141, 144, -1, 142, - 137, 144, -1, 142, 1, -1, 20, -1, 19, 20, - -1, 12, 20, -1, 145, -1, 145, 146, -1, 146, - -1, 143, 145, -1, 143, 145, 146, -1, 143, 146, - -1, 12, -1, 19, -1, 147, -1, 146, 147, -1, - 146, 1, -1, 15, -1, 14, -1, 148, -1, 150, - -1, 153, -1, 17, 12, -1, 12, 94, -1, 18, - 94, 149, 79, -1, 18, 94, 149, 151, 94, 152, - 94, 79, -1, 18, 94, 143, 149, 79, -1, 18, - 94, 143, 149, 151, 94, 152, 94, 79, -1, 80, - -1, 6, -1, 7, -1, 8, -1, 9, -1, 10, - -1, 12, -1, 11, -1, 16, 12, -1, 16, 16, - 12, -1, 16, 65, 13, 73, -1, 16, 65, 63, - 73, -1, 16, 65, 12, 73, -1, 16, 66, 94, - 144, 94, 73, -1, 156, -1, 155, 156, -1, 155, - -1, 1, 173, 1, -1, 1, -1, 155, 1, -1, - 155, 173, -1, 156, 71, 94, -1, 156, 173, 71, - 94, -1, 1, 71, 94, -1, 1, 173, 1, 71, - 94, -1, 155, 156, 71, 94, -1, 155, 1, 71, - 94, -1, 155, 1, 173, 1, 71, 94, -1, 157, - 16, 94, 159, 158, -1, 163, 94, -1, 157, 1, - -1, 157, 16, 94, 1, 159, 158, -1, 157, 16, - 94, 159, 158, 1, -1, 39, 94, -1, 157, 16, - 94, -1, 157, 16, 94, 1, -1, 157, 172, -1, - 12, 94, -1, 39, 94, -1, -1, 161, -1, 159, - 160, 161, -1, 159, 1, -1, 81, 94, -1, 74, - 94, -1, -1, 162, -1, 138, 162, -1, 11, 94, - -1, 12, 94, -1, 60, 94, -1, 138, 60, 94, - -1, 64, 94, -1, 67, 94, -1, 165, -1, 82, - 94, -1, 164, -1, 163, 94, -1, 83, 94, -1, - 63, 94, -1, 62, 94, -1, 61, 94, -1, 46, - 94, -1, 47, 94, -1, 48, 94, -1, 49, 94, - -1, 50, 94, -1, 51, 94, -1, 52, 94, -1, - 53, 94, -1, 54, 94, -1, 55, 94, -1, 56, - 94, -1, 57, 94, -1, 58, 94, -1, 59, 94, - -1, 44, 94, -1, 43, 94, -1, 45, 94, -1, - 68, -1, 65, 94, 159, 73, 94, -1, 65, 94, - 1, -1, 14, 94, -1, 15, 94, -1, 97, -1, - 1, 97, -1, 38, 1, 172, -1, 38, 1, 71, - -1, 167, 95, -1, 168, 167, 95, -1, 108, -1, - 127, -1, 1, 172, -1, 69, 1, 173, 1, 97, - -1, 69, 1, 97, -1, 172, -1, 173, 1, 172, + 86, 0, -1, 97, 96, 100, 101, 102, 103, -1, + 88, 95, -1, 90, 95, -1, 92, 95, -1, 93, + 95, -1, 94, 95, -1, 91, 95, -1, 89, 95, + -1, 104, -1, 109, -1, 28, 70, 95, 87, 95, + 71, -1, 30, 70, 95, 133, 95, 71, -1, 29, + 70, 95, 155, 71, -1, 38, 70, 95, 112, 71, + -1, 32, 70, 95, 160, 71, -1, 33, 5, 95, + 125, 71, -1, 34, 70, 95, 141, 71, -1, -1, + 95, 5, -1, -1, 96, 6, -1, 96, 5, -1, + -1, 99, -1, 71, -1, 0, -1, 26, 95, 12, + 95, 72, -1, 26, 1, 173, -1, 26, 1, 72, + -1, -1, 100, 109, 96, -1, 169, -1, -1, 101, + 110, 96, -1, -1, 102, 116, 96, -1, -1, 103, + 105, 96, -1, 140, -1, 128, -1, 136, -1, 137, + -1, 130, -1, 104, -1, 172, -1, 168, -1, 170, + -1, -1, 106, 108, 96, -1, 140, -1, 136, -1, + 137, -1, 130, -1, 107, -1, 172, -1, 168, -1, + 170, -1, 171, -1, 22, 95, 118, 95, 126, 72, + -1, 22, 95, 118, 95, 126, 173, -1, 22, 1, + 72, -1, 22, 1, 173, -1, 35, 95, 126, 70, + 95, 112, 71, -1, 36, 95, 111, 70, 95, 112, + 71, -1, -1, 37, 5, 127, -1, 114, -1, 113, + 114, -1, 113, -1, 1, 174, 1, -1, 1, -1, + 113, 1, -1, 114, 72, 95, -1, 114, 174, 72, + 95, -1, 1, 72, 95, -1, 1, 174, 1, 72, + 95, -1, 113, 114, 72, 95, -1, 113, 1, 72, + 95, -1, 113, 1, 174, 1, 72, 95, -1, 115, + 17, 95, 160, -1, 115, 95, 70, 95, 155, 71, + 95, -1, 115, 1, -1, 115, 17, 95, 1, 160, + -1, 115, 17, 95, -1, 115, 17, 95, 1, -1, + 13, 95, -1, 27, 95, 117, 118, 95, 72, -1, + 27, 1, 173, -1, 27, 1, 72, -1, -1, 13, + 5, -1, 12, -1, 65, -1, 13, 95, -1, -1, + 17, 95, 160, 95, -1, 73, 95, 119, 95, 120, + 74, 95, -1, 121, -1, 122, 95, 43, 95, 121, + -1, -1, 43, 95, 122, -1, -1, 41, -1, 42, + -1, 122, -1, 124, 95, 129, 123, -1, -1, 127, + -1, 125, -1, 127, 75, 95, 125, -1, 127, 1, + -1, 24, 95, 127, 70, 95, 106, 167, -1, 24, + 95, 70, 95, 106, 167, -1, 13, 95, -1, 31, + 95, 131, 95, 70, 95, 132, 71, -1, 13, -1, + 12, -1, -1, 132, 133, 95, -1, 134, 95, 70, + 95, 155, 71, -1, 135, -1, 134, 95, 75, 95, + 135, -1, 62, -1, 13, -1, 23, 1, 173, -1, + 23, 1, 72, -1, 25, 95, 70, 95, 155, 71, + 95, -1, 25, 1, 173, -1, 25, 1, 72, -1, + 76, 95, -1, 77, 95, -1, 78, 95, -1, 79, + -1, 76, -1, 141, 70, 95, 155, 98, -1, 143, + -1, 141, 75, 95, 143, -1, 141, 1, -1, 143, + 5, -1, 145, -1, 142, -1, 142, 145, -1, 143, + 138, 145, -1, 143, 1, -1, 21, -1, 20, 21, + -1, 13, 21, -1, 146, -1, 146, 147, -1, 147, + -1, 144, 146, -1, 144, 146, 147, -1, 144, 147, + -1, 13, -1, 20, -1, 148, -1, 147, 148, -1, + 147, 1, -1, 16, -1, 15, -1, 149, -1, 151, + -1, 154, -1, 18, 13, -1, 13, 95, -1, 19, + 95, 150, 80, -1, 19, 95, 150, 152, 95, 153, + 95, 80, -1, 19, 95, 144, 150, 80, -1, 19, + 95, 144, 150, 152, 95, 153, 95, 80, -1, 81, + -1, 7, -1, 8, -1, 9, -1, 10, -1, 11, + -1, 13, -1, 12, -1, 17, 13, -1, 17, 17, + 13, -1, 17, 66, 14, 74, -1, 17, 66, 64, + 74, -1, 17, 66, 13, 74, -1, 17, 67, 95, + 145, 95, 74, -1, 157, -1, 156, 157, -1, 156, + -1, 1, 174, 1, -1, 1, -1, 156, 1, -1, + 156, 174, -1, 157, 72, 95, -1, 157, 174, 72, + 95, -1, 1, 72, 95, -1, 1, 174, 1, 72, + 95, -1, 156, 157, 72, 95, -1, 156, 1, 72, + 95, -1, 156, 1, 174, 1, 72, 95, -1, 158, + 17, 95, 160, 159, -1, 164, 95, -1, 158, 1, + -1, 158, 17, 95, 1, 160, 159, -1, 158, 17, + 95, 160, 159, 1, -1, 40, 95, -1, 158, 17, + 95, -1, 158, 17, 95, 1, -1, 158, 173, -1, + 13, 95, -1, 40, 95, -1, -1, 162, -1, 160, + 161, 162, -1, 160, 1, -1, 82, 95, -1, 75, + 95, -1, -1, 163, -1, 139, 163, -1, 12, 95, + -1, 13, 95, -1, 61, 95, -1, 139, 61, 95, + -1, 65, 95, -1, 68, 95, -1, 166, -1, 83, + 95, -1, 165, -1, 164, 95, -1, 84, 95, -1, + 64, 95, -1, 63, 95, -1, 62, 95, -1, 47, + 95, -1, 48, 95, -1, 49, 95, -1, 50, 95, + -1, 51, 95, -1, 52, 95, -1, 53, 95, -1, + 54, 95, -1, 55, 95, -1, 56, 95, -1, 57, + 95, -1, 58, 95, -1, 59, 95, -1, 60, 95, + -1, 45, 95, -1, 44, 95, -1, 46, 95, -1, + 69, -1, 66, 95, 160, 74, 95, -1, 66, 95, + 1, -1, 15, 95, -1, 16, 95, -1, 98, -1, + 1, 98, -1, 39, 1, 173, -1, 39, 1, 72, + -1, 168, 96, -1, 169, 168, 96, -1, 109, -1, + 128, -1, 1, 173, -1, 70, 1, 174, 1, 98, + -1, 70, 1, 98, -1, 173, -1, 174, 1, 173, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 263, 263, 264, 265, 266, 267, 268, 269, 270, - 274, 275, 279, 285, 291, 297, 303, 317, 324, 334, - 335, 338, 340, 341, 344, 346, 351, 352, 356, 362, - 364, 368, 370, 375, 379, 381, 388, 390, 393, 395, - 403, 404, 405, 406, 407, 411, 412, 413, 414, 418, - 419, 430, 431, 432, 433, 437, 438, 439, 440, 441, - 446, 449, 452, 455, 461, 465, 471, 475, 481, 484, - 489, 492, 495, 498, 504, 507, 510, 513, 516, 521, - 524, 530, 534, 538, 542, 546, 551, 558, 564, 569, - 570, 574, 575, 579, 580, 584, 590, 593, 599, 606, - 611, 618, 621, 627, 630, 633, 639, 644, 652, 655, - 659, 664, 669, 675, 678, 684, 690, 697, 698, 702, - 703, 711, 717, 722, 731, 732, 756, 759, 765, 769, - 772, 778, 779, 780, 784, 785, 789, 795, 804, 812, - 818, 824, 827, 831, 847, 867, 873, 874, 875, 879, - 884, 891, 897, 907, 919, 932, 940, 948, 951, 964, - 970, 978, 990, 991, 992, 996, 1007, 1018, 1023, 1029, - 1037, 1049, 1052, 1055, 1058, 1061, 1064, 1070, 1071, 1075, - 1100, 1115, 1133, 1151, 1170, 1185, 1188, 1193, 1196, 1199, - 1202, 1205, 1211, 1214, 1217, 1220, 1223, 1228, 1231, 1237, - 1251, 1263, 1267, 1274, 1279, 1284, 1289, 1294, 1301, 1307, - 1308, 1312, 1317, 1331, 1337, 1340, 1343, 1349, 1350, 1351, - 1352, 1358, 1359, 1360, 1361, 1362, 1363, 1365, 1368, 1371, - 1375, 1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, - 1385, 1386, 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394, - 1398, 1406, 1415, 1431, 1432, 1439, 1442, 1448, 1451, 1457, - 1458, 1462, 1468, 1474, 1492, 1493, 1497, 1498 + 0, 265, 265, 266, 267, 268, 269, 270, 271, 272, + 276, 277, 281, 287, 293, 299, 305, 319, 326, 336, + 337, 340, 342, 343, 346, 348, 353, 354, 358, 364, + 366, 370, 372, 377, 381, 383, 390, 392, 395, 397, + 405, 406, 407, 408, 409, 413, 414, 415, 416, 420, + 421, 432, 433, 434, 435, 439, 440, 441, 442, 443, + 448, 451, 454, 457, 463, 467, 473, 477, 483, 486, + 491, 494, 497, 500, 506, 509, 512, 515, 518, 523, + 526, 532, 536, 540, 544, 548, 553, 560, 566, 571, + 572, 576, 577, 581, 582, 586, 592, 595, 601, 608, + 613, 620, 623, 629, 632, 635, 641, 646, 654, 657, + 661, 666, 671, 677, 680, 686, 692, 699, 700, 704, + 705, 713, 719, 724, 733, 734, 758, 761, 767, 771, + 774, 780, 781, 782, 786, 787, 791, 797, 806, 814, + 820, 826, 829, 833, 849, 869, 875, 876, 877, 881, + 886, 893, 899, 909, 921, 934, 942, 950, 953, 966, + 972, 980, 992, 993, 994, 998, 1009, 1020, 1025, 1031, + 1039, 1051, 1054, 1057, 1060, 1063, 1066, 1072, 1073, 1077, + 1102, 1117, 1135, 1153, 1172, 1187, 1190, 1195, 1198, 1201, + 1204, 1207, 1213, 1216, 1219, 1222, 1225, 1230, 1233, 1239, + 1253, 1265, 1269, 1276, 1281, 1286, 1291, 1296, 1303, 1309, + 1310, 1314, 1319, 1333, 1339, 1342, 1345, 1351, 1352, 1353, + 1354, 1360, 1361, 1362, 1363, 1364, 1365, 1367, 1370, 1373, + 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1386, + 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394, 1395, 1396, + 1400, 1408, 1417, 1433, 1434, 1441, 1444, 1450, 1453, 1459, + 1460, 1464, 1470, 1476, 1494, 1495, 1499, 1500 }; #endif @@ -771,27 +725,28 @@ static const yytype_uint16 yyrline[] = First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { - "TOKEN_EOF", "error", "$undefined", "UNIMPORTANT_TOK", "WHITESPACE", - "SGML_CD", "INCLUDES", "DASHMATCH", "BEGINSWITH", "ENDSWITH", "CONTAINS", - "STRING", "IDENT", "NTH", "HEX", "IDSEL", "':'", "'.'", "'['", "'*'", - "'|'", "IMPORT_SYM", "PAGE_SYM", "MEDIA_SYM", "FONT_FACE_SYM", - "CHARSET_SYM", "NAMESPACE_SYM", "WEBKIT_RULE_SYM", "WEBKIT_DECLS_SYM", - "WEBKIT_KEYFRAME_RULE_SYM", "WEBKIT_KEYFRAMES_SYM", "WEBKIT_VALUE_SYM", - "WEBKIT_MEDIAQUERY_SYM", "WEBKIT_SELECTOR_SYM", "WEBKIT_VARIABLES_SYM", - "WEBKIT_DEFINE_SYM", "VARIABLES_FOR", "WEBKIT_VARIABLES_DECLS_SYM", - "ATKEYWORD", "IMPORTANT_SYM", "MEDIA_ONLY", "MEDIA_NOT", "MEDIA_AND", - "QEMS", "EMS", "EXS", "PXS", "CMS", "MMS", "INS", "PTS", "PCS", "DEGS", - "RADS", "GRADS", "TURNS", "MSECS", "SECS", "HERZ", "KHERZ", "DIMEN", - "PERCENTAGE", "FLOATTOKEN", "INTEGER", "URI", "FUNCTION", "NOTFUNCTION", - "UNICODERANGE", "VARCALL", "'{'", "'}'", "';'", "'('", "')'", "','", - "'+'", "'~'", "'>'", "'-'", "']'", "'='", "'/'", "'#'", "'%'", "$accept", - "stylesheet", "valid_rule_or_import", "webkit_rule", - "webkit_keyframe_rule", "webkit_decls", "webkit_variables_decls", - "webkit_value", "webkit_mediaquery", "webkit_selector", "maybe_space", - "maybe_sgml", "maybe_charset", "closing_brace", "charset", "import_list", - "variables_list", "namespace_list", "rule_list", "valid_rule", "rule", - "block_rule_list", "block_valid_rule", "block_rule", "import", - "variables_rule", "variables_media_list", "variables_declaration_list", + "TOKEN_EOF", "error", "$undefined", "LOWEST_PREC", "UNIMPORTANT_TOK", + "WHITESPACE", "SGML_CD", "INCLUDES", "DASHMATCH", "BEGINSWITH", + "ENDSWITH", "CONTAINS", "STRING", "IDENT", "NTH", "HEX", "IDSEL", "':'", + "'.'", "'['", "'*'", "'|'", "IMPORT_SYM", "PAGE_SYM", "MEDIA_SYM", + "FONT_FACE_SYM", "CHARSET_SYM", "NAMESPACE_SYM", "WEBKIT_RULE_SYM", + "WEBKIT_DECLS_SYM", "WEBKIT_KEYFRAME_RULE_SYM", "WEBKIT_KEYFRAMES_SYM", + "WEBKIT_VALUE_SYM", "WEBKIT_MEDIAQUERY_SYM", "WEBKIT_SELECTOR_SYM", + "WEBKIT_VARIABLES_SYM", "WEBKIT_DEFINE_SYM", "VARIABLES_FOR", + "WEBKIT_VARIABLES_DECLS_SYM", "ATKEYWORD", "IMPORTANT_SYM", "MEDIA_ONLY", + "MEDIA_NOT", "MEDIA_AND", "QEMS", "EMS", "EXS", "PXS", "CMS", "MMS", + "INS", "PTS", "PCS", "DEGS", "RADS", "GRADS", "TURNS", "MSECS", "SECS", + "HERZ", "KHERZ", "DIMEN", "PERCENTAGE", "FLOATTOKEN", "INTEGER", "URI", + "FUNCTION", "NOTFUNCTION", "UNICODERANGE", "VARCALL", "'{'", "'}'", + "';'", "'('", "')'", "','", "'+'", "'~'", "'>'", "'-'", "']'", "'='", + "'/'", "'#'", "'%'", "$accept", "stylesheet", "valid_rule_or_import", + "webkit_rule", "webkit_keyframe_rule", "webkit_decls", + "webkit_variables_decls", "webkit_value", "webkit_mediaquery", + "webkit_selector", "maybe_space", "maybe_sgml", "maybe_charset", + "closing_brace", "charset", "import_list", "variables_list", + "namespace_list", "rule_list", "valid_rule", "rule", "block_rule_list", + "block_valid_rule", "block_rule", "import", "variables_rule", + "variables_media_list", "variables_declaration_list", "variables_decl_list", "variables_declaration", "variable_name", "namespace", "maybe_ns_prefix", "string_or_uri", "media_feature", "maybe_media_value", "media_query_exp", "media_query_exp_list", @@ -816,47 +771,47 @@ static const char *const yytname[] = static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 58, 46, 91, 42, - 124, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 265, 266, 267, 268, 269, 270, 271, 58, 46, 91, + 42, 124, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, 318, 123, - 125, 59, 40, 41, 44, 43, 126, 62, 45, 93, - 61, 47, 35, 37 + 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, + 123, 125, 59, 40, 41, 44, 43, 126, 62, 45, + 93, 61, 47, 35, 37 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 84, 85, 85, 85, 85, 85, 85, 85, 85, - 86, 86, 87, 88, 89, 90, 91, 92, 93, 94, - 94, 95, 95, 95, 96, 96, 97, 97, 98, 98, - 98, 99, 99, 99, 100, 100, 101, 101, 102, 102, - 103, 103, 103, 103, 103, 104, 104, 104, 104, 105, - 105, 106, 106, 106, 106, 107, 107, 107, 107, 107, - 108, 108, 108, 108, 109, 109, 110, 110, 111, 111, - 111, 111, 111, 111, 112, 112, 112, 112, 112, 112, - 112, 113, 113, 113, 113, 113, 113, 114, 115, 115, - 115, 116, 116, 117, 117, 118, 119, 119, 120, 121, - 121, 122, 122, 123, 123, 123, 124, 124, 125, 125, - 126, 126, 126, 127, 127, 128, 129, 130, 130, 131, - 131, 132, 133, 133, 134, 134, 135, 135, 136, 136, - 136, 137, 137, 137, 138, 138, 139, 140, 140, 140, - 141, 142, 142, 142, 142, 142, 143, 143, 143, 144, - 144, 144, 144, 144, 144, 145, 145, 146, 146, 146, - 147, 147, 147, 147, 147, 148, 149, 150, 150, 150, - 150, 151, 151, 151, 151, 151, 151, 152, 152, 153, - 153, 153, 153, 153, 153, 154, 154, 154, 154, 154, - 154, 154, 155, 155, 155, 155, 155, 155, 155, 156, - 156, 156, 156, 156, 156, 156, 156, 156, 157, 158, - 158, 159, 159, 159, 160, 160, 160, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, + 0, 85, 86, 86, 86, 86, 86, 86, 86, 86, + 87, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 95, 96, 96, 96, 97, 97, 98, 98, 99, 99, + 99, 100, 100, 100, 101, 101, 102, 102, 103, 103, + 104, 104, 104, 104, 104, 105, 105, 105, 105, 106, + 106, 107, 107, 107, 107, 108, 108, 108, 108, 108, + 109, 109, 109, 109, 110, 110, 111, 111, 112, 112, + 112, 112, 112, 112, 113, 113, 113, 113, 113, 113, + 113, 114, 114, 114, 114, 114, 114, 115, 116, 116, + 116, 117, 117, 118, 118, 119, 120, 120, 121, 122, + 122, 123, 123, 124, 124, 124, 125, 125, 126, 126, + 127, 127, 127, 128, 128, 129, 130, 131, 131, 132, + 132, 133, 134, 134, 135, 135, 136, 136, 137, 137, + 137, 138, 138, 138, 139, 139, 140, 141, 141, 141, + 142, 143, 143, 143, 143, 143, 144, 144, 144, 145, + 145, 145, 145, 145, 145, 146, 146, 147, 147, 147, + 148, 148, 148, 148, 148, 149, 150, 151, 151, 151, + 151, 152, 152, 152, 152, 152, 152, 153, 153, 154, + 154, 154, 154, 154, 154, 155, 155, 155, 155, 155, + 155, 155, 156, 156, 156, 156, 156, 156, 156, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 158, 159, + 159, 160, 160, 160, 161, 161, 161, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, - 163, 164, 164, 165, 165, 166, 166, 167, 167, 168, - 168, 169, 170, 171, 172, 172, 173, 173 + 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, + 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, + 164, 165, 165, 166, 166, 167, 167, 168, 168, 169, + 169, 170, 171, 172, 173, 173, 174, 174 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -966,75 +921,75 @@ static const yytype_int16 yydefgoto[] = /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -299 +#define YYPACT_NINF -435 static const yytype_int16 yypact[] = { - 466, 425, -26, -20, 75, 118, 189, 139, 151, 263, - -299, -299, -299, -299, -299, -299, -299, -299, -299, 359, - 300, -299, -299, -299, -299, -299, -299, -299, -299, 278, - 278, 278, 278, 278, 278, 278, 33, 338, -299, -299, - -299, -299, 749, 313, 32, 1074, 12, 545, 44, -299, - -299, 345, 346, -299, 335, 223, 194, 354, -299, -299, - 419, 380, -299, 383, -299, 403, 408, -299, 163, -299, - -299, -299, -299, -299, -299, -299, -299, -299, 86, 561, - 199, 620, -299, 626, 161, -299, -299, -299, -299, 374, - -299, -299, -299, 351, 239, 378, 179, -299, -299, -299, - -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, - -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, - -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, - -299, -299, -299, -299, -299, 645, 882, -299, -299, -299, - -299, -299, -299, -299, -299, -299, 30, -299, 363, 82, - 402, -299, 364, 185, 410, 190, 421, 28, -299, 301, - -299, -299, -299, -299, -299, 423, -299, -299, -299, 426, - 337, -299, -299, 35, -299, 542, 397, 640, 1, 691, - 26, 448, 220, -299, -299, -299, -299, -299, -299, -299, - -299, -299, 561, -299, -299, 626, 343, 381, -299, -299, - -299, 443, 278, 278, -299, 705, 377, 27, -299, 59, - -299, -299, -299, 278, 242, 178, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 1012, 278, 278, 278, -299, -299, -299, -299, - -299, -299, 1132, 278, 201, 368, 312, -299, -299, -299, - 464, 278, -299, 706, 395, -299, 87, -299, -299, 188, - -299, -299, -299, -299, 442, -299, 301, 301, 223, -299, - 409, 413, 414, 545, 354, 383, 488, 69, -299, -299, - -299, -299, -299, -299, -299, -299, -299, 135, -299, -299, - -299, -299, -299, -299, -299, 313, 545, 278, 278, 278, - -299, 554, 278, 709, -299, 475, -299, 432, 278, -299, - 539, -299, -299, -299, -299, 947, 278, 278, 278, -299, - -299, -299, -299, -299, 462, 278, 712, -299, 528, -299, - 278, -299, 744, -299, 294, 165, 382, 1229, -299, 301, - -299, -299, -299, -299, -299, -299, 278, -299, 209, -299, - -299, -299, -299, -299, -299, -299, -299, 339, 278, -299, - -299, -299, 313, 257, 174, 210, -299, 278, 713, 278, - 278, 1132, 463, 313, 32, -299, 278, 42, 181, 278, - -299, -299, -299, 278, 754, 278, 278, 1132, 604, 313, - 467, 97, 531, 473, 764, 329, 432, -299, -299, -299, - -299, -299, -299, 301, 61, -299, -299, 458, 765, 1204, - 278, 12, 477, -299, -299, 278, -299, 463, -299, 172, - 478, -299, 278, -299, 479, -299, 181, 278, -299, 669, - 486, -299, 10, -299, -299, -299, 562, 217, -299, 301, - -299, 458, -299, -299, -299, -299, -299, 223, -299, -299, - -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, - -299, 1204, -299, -299, 278, 278, -299, 278, -299, -299, - 1074, -299, 30, 278, -299, 44, 152, 44, -299, -299, - -299, 2, -299, 301, -299, 278, 307, 817, 278, 278, - 497, 504, 225, 15, -299, -299, -299, 278, -299, -299, - -299, -299, 278 + 818, 44, -36, -18, 112, 127, 66, 141, 162, 243, + -435, -435, -435, -435, -435, -435, -435, -435, -435, 239, + 43, -435, -435, -435, -435, -435, -435, -435, -435, 250, + 250, 250, 250, 250, 250, 250, 37, 304, -435, -435, + -435, -435, 763, 354, 31, 1114, 144, 622, 49, -435, + -435, 346, 344, -435, 332, 27, 23, 358, -435, -435, + 401, 370, -435, 371, -435, 381, 406, -435, 193, -435, + -435, -435, -435, -435, -435, -435, -435, -435, 171, 702, + 143, 631, -435, 756, 159, -435, -435, -435, -435, 240, + -435, -435, -435, 329, 303, 254, 199, -435, -435, -435, + -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, + -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, + -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, + -435, -435, -435, -435, -435, 949, 903, -435, -435, -435, + -435, -435, -435, -435, -435, -435, 34, -435, 342, 4, + 274, -435, 353, 59, 291, 223, 331, 395, -435, 438, + -435, -435, -435, -435, -435, 437, -435, -435, -435, 448, + 24, -435, -435, 415, -435, 349, 295, 377, 375, 399, + 198, 421, 190, -435, -435, -435, -435, -435, -435, -435, + -435, -435, 702, -435, -435, 756, 334, 380, -435, -435, + -435, 463, 250, 250, -435, 409, 398, 180, -435, 15, + -435, -435, -435, 250, 221, 182, 250, 250, 250, 250, + 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, + 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, + 250, 250, 1052, 250, 250, 250, -435, -435, -435, -435, + -435, -435, 1172, 250, 188, 166, 301, -435, -435, -435, + 472, 250, -435, 412, 404, -435, 62, -435, -435, 220, + -435, -435, -435, -435, 458, -435, 438, 438, 27, -435, + 413, 417, 430, 622, 358, 371, 473, 158, -435, -435, + -435, -435, -435, -435, -435, -435, -435, 172, -435, -435, + -435, -435, -435, -435, -435, 354, 622, 250, 250, 250, + -435, 555, 250, 420, -435, 502, -435, 459, 250, -435, + 535, -435, -435, -435, -435, 976, 250, 250, 250, -435, + -435, -435, -435, -435, 496, 250, 423, -435, 541, -435, + 250, -435, 754, -435, 424, 36, 552, 685, -435, 438, + -435, -435, -435, -435, -435, -435, 250, -435, 277, -435, + -435, -435, -435, -435, -435, -435, -435, 856, 250, -435, + -435, -435, 354, 226, 65, 203, -435, 250, 428, 250, + 250, 1172, 462, 354, 31, -435, 250, 53, 186, 250, + -435, -435, -435, 250, 429, 250, 250, 1172, 608, 354, + 479, 83, 538, 485, 482, 320, 459, -435, -435, -435, + -435, -435, -435, 438, 78, -435, -435, 447, 489, 1244, + 250, 144, 487, -435, -435, 250, -435, 462, -435, 205, + 491, -435, 250, -435, 492, -435, 186, 250, -435, 681, + 497, -435, 5, -435, -435, -435, 558, 150, -435, 438, + -435, 447, -435, -435, -435, -435, -435, 27, -435, -435, + -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, + -435, 1244, -435, -435, 250, 250, -435, 250, -435, -435, + 1114, -435, 34, 250, -435, 49, 178, 49, -435, -435, + -435, 1, -435, 438, -435, 250, 306, 827, 250, 250, + 498, 504, 151, 14, -435, -435, -435, 250, -435, -435, + -435, -435, 250 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -299, -299, -299, -299, -299, -299, -299, -299, -299, -299, - -1, -21, -299, -51, -299, -299, -299, -299, -299, 265, - -299, 200, -299, -299, 258, -299, -299, 352, -299, 472, - -299, -299, -299, 186, -299, -299, 238, 240, -299, -299, - -45, 279, -176, -238, -299, -194, -299, -299, 149, -299, - 293, -116, -66, -299, -299, -48, 663, -299, 429, 568, - -61, 661, -50, -55, -299, 460, -299, 391, 303, -299, - -298, -299, 692, -299, 330, -185, -299, 533, 675, -35, - -299, -299, 349, -19, -299, 469, -299, 470, -16, -3 + -435, -435, -435, -435, -435, -435, -435, -435, -435, -435, + -1, -21, -435, -51, -435, -435, -435, -435, -435, 229, + -435, 147, -435, -435, 256, -435, -435, -434, -435, 425, + -435, -435, -435, 130, -435, -435, 214, 174, -435, -435, + -45, 241, -176, -389, -435, -227, -435, -435, 116, -435, + 231, -154, -137, -435, -435, -130, 566, -435, 310, 449, + -61, 547, -50, -55, -435, 348, -435, 278, 194, -435, + -298, -435, 581, -435, 261, -185, -435, 443, 546, -35, + -435, -435, 218, -19, -435, 352, -435, 364, -16, -3 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -1044,324 +999,332 @@ static const yytype_int16 yypgoto[] = #define YYTABLE_NINF -217 static const yytype_int16 yytable[] = { - 20, 148, 297, 39, 163, 40, 40, 374, 97, 29, - 30, 31, 32, 33, 34, 35, 40, 53, 186, 40, - 42, 43, 44, 45, 46, 47, 48, -191, 317, 199, - 40, 196, 159, 197, -19, 160, 40, 49, 50, 40, - 56, 142, 143, 21, 98, 150, 40, 284, 40, 22, - 142, 143, 142, 143, 285, 64, 151, 325, 433, 97, - 317, 173, 272, 273, 176, 40, 178, 180, 181, 182, - 295, 51, -19, 144, 422, 359, 360, 361, 362, 363, - 212, 504, 144, 183, 144, 430, 201, 183, 317, 202, - 203, 207, 209, 99, 511, 300, 213, -191, 369, 214, + 20, 148, 297, 39, 163, 183, 40, 374, 97, 29, + 30, 31, 32, 33, 34, 35, 317, 53, 186, 40, + 42, 43, 44, 45, 46, 47, 48, 161, 40, 199, + 461, 196, 159, 197, 21, 160, 40, 280, 281, -19, + 56, 40, 49, 50, 98, 19, 142, 143, 40, -19, + 150, 500, 22, 501, 40, 41, -19, 325, 40, 97, + 263, 173, 151, 317, 176, 161, 178, 180, 181, 182, + 433, 25, 151, 402, 422, 258, 51, -19, 144, 185, + 212, 504, 461, 40, 369, 430, 201, 319, 282, 202, + 203, 207, 209, 99, 511, 166, 213, 37, 162, 214, 215, 440, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, - 319, 310, 244, 245, 450, 382, 369, 276, 253, 277, - 271, 199, 199, 254, 23, 311, 256, 260, 364, 365, - 261, 266, 258, 369, 269, 184, 185, 398, 341, 289, - 185, 294, 198, 299, 179, -151, -109, -19, -109, 40, - 283, 371, -199, 478, 161, 58, 59, 60, 61, 62, - 210, 461, 40, 305, 306, 40, 263, 24, 307, 308, - 309, 267, 40, 25, -19, 211, 427, 151, 40, 312, - 187, 402, 315, 188, 370, 40, 268, 318, 26, 371, - 320, 187, 439, 330, 188, 359, 360, 361, 362, 363, - 27, -67, 355, 161, 40, 462, 371, 350, 290, 40, - -151, -151, -19, 461, -151, -151, -151, -151, -151, -187, - 205, -199, -199, -199, 162, 326, 40, 322, 37, 327, - 328, 90, 323, 144, 349, -70, 199, 343, 335, -19, - 338, 40, 351, 28, 340, 166, 486, 342, -137, -137, - 97, 344, 345, -137, 189, 190, 191, 462, 91, -138, - -138, 291, 40, 356, -138, 189, 190, 191, 415, 365, - 304, 367, 37, 162, 368, 497, 510, 351, 40, 372, - 72, 351, 373, 463, 40, 49, 50, 92, 37, -187, - 158, 41, 321, 377, 89, 379, 40, 40, 380, 98, - 351, 383, 384, 424, 333, 90, 423, 413, 410, 386, - 387, 388, 389, 40, 142, 143, 393, 97, 395, 55, - 396, 446, 399, 40, 198, 405, 156, -154, 97, 280, - 281, -103, 91, 464, 414, 463, 356, 58, 59, 60, - 61, 62, 351, -108, 97, 417, 144, 65, 99, 420, - 421, 465, 40, 51, 167, 425, 472, 505, 351, 142, - 143, 92, 198, 404, 432, -150, -19, 449, 445, 436, - 448, 437, 172, -19, -19, 58, 59, 60, 61, 62, - 282, 40, 456, 174, 175, 464, 492, -19, 290, 177, - 332, 144, -154, -154, -19, 451, -154, -154, -154, -154, - -154, 204, 474, 465, 278, 475, 19, 477, 37, -19, - 38, 168, 480, 257, 262, 169, -19, 483, 279, 493, - 485, 448, 487, 37, 313, 200, -19, 37, 316, 208, - -150, -150, 40, 491, -150, -150, -150, -150, -150, 301, - 302, 291, 40, -210, 248, 336, 339, -19, 346, 452, - 453, 37, 495, 259, -216, -216, 378, -216, -216, 37, - 498, 265, 352, 499, 170, 171, 353, 354, 502, 503, - 37, 1, 270, 2, 3, 4, 507, 5, 6, 7, - 357, 37, 428, 8, 390, 512, -216, -216, -216, -216, + -70, 310, 244, 245, 341, 382, 162, 276, 253, 277, + 271, 199, 199, 254, 187, 311, 256, 260, 188, 40, + 261, 266, 450, -109, 269, -109, 40, 398, 371, 289, + 198, 294, 290, 299, -151, 359, 360, 361, 362, 363, + 283, 40, 183, 369, 58, 59, 60, 61, 62, 369, + -191, 317, 23, 305, 306, 142, 143, 40, 307, 308, + 309, 40, 462, 40, 179, 40, 427, 24, -19, 312, + 210, 330, 315, 40, 187, -199, 478, 318, 188, 332, + 320, 26, 439, -137, -137, 291, 211, 144, -137, 189, + 190, 191, 355, 510, 267, 40, 40, 350, -19, -151, + -151, 40, 27, -151, -151, -151, -151, -151, 364, 365, + 268, 184, 370, 28, 462, 326, 185, 371, -67, 327, + 328, -191, 322, 371, 349, 40, 199, 323, 335, 144, + 338, 304, 351, -19, 340, 463, 486, 342, 300, 37, + 97, 344, 345, -138, -138, -199, -199, -199, -138, 189, + 190, 191, 464, 356, 359, 360, 361, 362, 363, 465, + 343, 367, 321, -19, 368, 497, 423, 351, 72, 372, + 40, 351, 373, -187, 205, 55, 40, 290, 158, 37, + 37, 38, 200, 377, 333, 379, 90, 463, 380, 98, + 351, 383, 384, 424, 37, 40, 208, 413, 410, 386, + 387, 388, 389, 446, 464, 198, 393, 97, 395, -154, + 396, 465, 399, 91, 37, 405, 259, 156, 97, 58, + 59, 60, 61, 62, 414, 89, 356, 415, 365, 40, + 291, 37, 351, 265, 97, 417, 65, 90, 99, 420, + 421, 51, 92, 37, -187, 425, 472, 505, 351, 167, + 40, 198, 175, 172, 432, -150, -19, 449, 445, 436, + 448, 437, 174, -19, 91, 58, 59, 60, 61, 62, + 204, 37, 456, 270, -154, -154, 492, 177, -154, -154, + -154, -154, -154, 257, 168, 451, 142, 143, 169, 37, + 40, 288, 474, 92, 262, 475, 40, 477, 284, 40, + 272, 273, 480, 301, 302, 285, 64, 483, 278, 493, + 485, 448, 487, 49, 50, 295, -19, 37, 144, 293, + -150, -150, 40, 491, -150, -150, -150, -150, -150, 452, + 453, 279, -210, 248, 313, 142, 143, 170, 171, 37, + 316, 298, 495, 336, -216, -216, 339, -216, -216, 37, + 498, 314, 37, 499, 337, 346, 357, 352, 502, 503, + 37, 353, 376, 37, -108, 392, 507, 144, 37, 37, + 426, 438, 428, 378, 354, 512, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, - -216, -216, -216, -216, -216, -216, -216, -216, -216, 394, - -216, -216, -210, -210, -210, 442, 441, 250, -216, -205, - 381, -216, 443, 40, 251, -216, -216, 473, 479, 40, - 103, 104, 481, 105, 106, 198, 484, 57, -153, 58, - 59, 60, 61, 62, 63, 64, 488, 508, 58, 59, - 60, 61, 62, 57, 509, 58, 59, 60, 61, 62, - 63, 64, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, - 125, 126, 127, 128, 129, 248, 130, 92, -205, -205, - -205, 37, 407, 288, 131, -216, -216, 132, -216, -216, - 471, 133, 134, -153, -153, 264, 435, -153, -153, -153, - -153, -153, 193, 489, 58, 59, 60, 61, 62, 194, - 58, 59, 60, 61, 62, 506, 418, -216, -216, -216, + -216, -216, -216, -216, -216, -216, -216, -216, -216, 37, + -216, -216, -210, -210, -210, -205, 381, 250, -216, 390, + 40, -216, 394, 442, 251, -216, -216, 103, 104, 441, + 105, 106, 37, 404, 444, 443, 198, -19, 473, 37, + -153, 455, 479, 488, -19, -19, 481, 471, 484, 508, + 58, 59, 60, 61, 62, 509, 407, 489, 264, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 435, 130, 92, -205, -205, -205, 418, 248, + 482, 131, 506, 149, 132, 431, 375, -19, 133, 134, + -216, -216, 286, -216, -216, -153, -153, 40, 195, -153, + -153, -153, -153, -153, 358, 57, 416, 58, 59, 60, + 61, 62, 63, 64, 193, 490, 58, 59, 60, 61, + 62, 194, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, + -216, -216, -216, -216, -216, 206, -216, -216, -81, -81, + -81, 247, 248, 250, -216, -2, 406, -216, 476, 494, + 251, -216, -216, -216, -216, 329, -216, -216, 57, 411, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 412, 0, 0, 0, 57, 69, 58, 59, 60, + 61, 62, 63, 64, 51, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, - 248, -216, -216, -81, -81, -81, 482, 431, 250, -216, - -216, -216, -216, -216, -216, 251, -216, -216, 107, 108, + -216, -216, -216, -216, -216, -216, -216, -216, 0, -216, + -216, -84, -84, -84, 0, 397, 250, -216, 0, 40, + -216, 0, 0, 251, -216, -216, 103, 104, 40, 105, + 106, 58, 59, 60, 61, 62, 57, 0, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 0, + 0, 0, 0, 0, 69, 0, 0, 0, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, - 119, 120, 121, 122, 123, 246, 125, 126, 127, 37, - 149, 293, -216, -216, -216, -216, -216, -216, -216, -216, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 0, 130, 92, -85, -85, -85, 0, 248, 0, + 131, 0, -19, 132, 0, 0, 0, 133, 134, -216, + -216, 0, -216, -216, 1, 0, 2, 3, 4, 0, + 5, 6, 7, 0, 0, 0, 8, 0, 0, 0, + 0, 40, 0, 0, 0, 0, 0, 0, 0, -103, + 0, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, - -216, -216, -216, -216, -216, 375, -216, -216, -84, -84, - -84, 286, 195, 250, -216, 397, 358, -216, 40, 416, - 251, -216, -216, 40, 490, 103, 104, 476, 105, 106, - 37, 57, 298, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 37, 37, 314, 337, 37, 69, - 376, 37, 37, 392, 426, 329, 206, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 247, 130, 92, -85, -85, -85, 411, 412, 248, 131, - 494, -19, 132, 37, 0, 438, 133, 134, -216, -216, - 0, -216, -216, 37, 37, 444, 455, 500, 0, 501, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -216, -216, -216, -216, 0, -216, -216, 142, 143, 0, + 0, -19, 250, -216, 248, 0, -216, 0, 0, 251, + -216, -216, 0, 0, 0, -216, -216, 0, -216, -216, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, - -216, -216, -216, 248, -216, -216, 0, 0, 0, 0, - -19, 250, -216, -216, -216, -216, -216, -216, 251, -216, - -216, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, -216, -216, -216, -216, -216, + 0, -216, -216, 0, 249, 0, 0, 248, 250, -216, + 0, 0, -216, 0, 0, 251, -216, -216, -216, -216, + 0, -216, -216, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, + 246, 125, 126, 127, 0, 0, 0, 0, 0, 0, + -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, - -216, -216, -216, -216, -216, -216, -216, -216, 248, -216, - -216, 0, 249, 0, 0, 0, 250, -216, -216, -216, - -216, -216, -216, 251, -216, -216, 0, 0, 0, 0, + -216, -216, -216, 0, -216, -216, 0, 0, 0, 0, + 385, 250, -216, 324, 0, -216, 0, 40, 251, -216, + -216, 0, 0, 0, 103, 104, 0, 105, 106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, - -216, -216, -216, -216, -216, -216, -216, -216, -216, -216, - -216, -216, -216, 324, -216, -216, 40, 0, 0, 0, - 385, 250, -216, 103, 104, -216, 105, 106, 251, -216, - -216, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 40, + 130, 92, 0, 0, 0, 0, 103, 104, 131, 105, + 106, 132, 0, 0, 0, 133, 134, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 0, 130, 92, 103, 104, 0, 105, 106, 0, + 131, 0, 0, 132, 0, 0, 0, 133, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 128, 129, 40, 130, - 92, 0, 0, 0, 0, 103, 104, 131, 105, 106, - 132, 0, 0, 0, 133, 134, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 0, + 130, 92, 0, 0, 161, 457, 0, 0, 131, 0, + 0, 132, 0, 0, 0, 133, 134, 57, 0, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, + 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 0, 130, 92, 103, 104, 0, 105, 106, 0, 131, - 0, 0, 132, 0, 0, 0, 133, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 128, 129, 0, 130, - 92, 0, 0, 0, 161, 457, 0, 131, 0, 0, - 132, 0, 0, 0, 133, 134, 57, 0, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, -2, - 406, 0, 0, 0, 69, 0, 0, 0, 0, 0, - 0, 57, 51, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 0, 0, 0, 0, 0, 69, - 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, - 0, 0, 0, 0, 162 + 0, 0, 0, 0, 0, 162 }; static const yytype_int16 yycheck[] = { - 1, 46, 178, 19, 55, 4, 4, 305, 43, 10, - 11, 12, 13, 14, 15, 16, 4, 36, 79, 4, - 21, 22, 23, 24, 25, 26, 27, 0, 1, 84, - 4, 81, 53, 83, 4, 54, 4, 4, 5, 4, - 41, 40, 41, 69, 12, 1, 4, 12, 4, 69, - 40, 41, 40, 41, 19, 20, 12, 242, 16, 94, - 1, 62, 34, 35, 65, 4, 67, 68, 69, 70, - 69, 38, 42, 72, 372, 6, 7, 8, 9, 10, - 96, 79, 72, 1, 72, 383, 89, 1, 1, 90, - 91, 94, 95, 61, 79, 69, 97, 70, 1, 100, + 1, 46, 178, 19, 55, 1, 5, 305, 43, 10, + 11, 12, 13, 14, 15, 16, 1, 36, 79, 5, + 21, 22, 23, 24, 25, 26, 27, 0, 5, 84, + 419, 81, 53, 83, 70, 54, 5, 13, 14, 5, + 41, 5, 5, 6, 13, 1, 41, 42, 5, 5, + 1, 485, 70, 487, 5, 12, 12, 242, 5, 94, + 1, 62, 13, 1, 65, 0, 67, 68, 69, 70, + 17, 5, 13, 37, 372, 71, 39, 43, 73, 75, + 96, 80, 471, 5, 1, 383, 89, 72, 64, 90, + 91, 94, 95, 62, 80, 72, 97, 70, 71, 100, 101, 399, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, - 71, 192, 133, 134, 73, 320, 1, 158, 139, 160, - 156, 196, 197, 144, 69, 195, 147, 150, 79, 80, - 151, 154, 70, 1, 155, 69, 74, 342, 71, 175, - 74, 177, 1, 179, 1, 4, 69, 4, 71, 4, - 171, 74, 0, 1, 0, 14, 15, 16, 17, 18, - 1, 419, 4, 184, 185, 4, 1, 69, 189, 190, - 191, 1, 4, 4, 4, 16, 381, 12, 4, 200, - 1, 36, 205, 4, 69, 4, 16, 208, 69, 74, - 211, 1, 397, 12, 4, 6, 7, 8, 9, 10, - 69, 69, 283, 0, 4, 419, 74, 278, 11, 4, - 69, 70, 69, 471, 73, 74, 75, 76, 77, 0, - 1, 69, 70, 71, 70, 246, 4, 69, 69, 250, - 251, 12, 74, 72, 275, 70, 311, 69, 259, 69, - 263, 4, 278, 0, 265, 71, 442, 268, 69, 70, - 305, 272, 273, 74, 75, 76, 77, 471, 39, 69, - 70, 64, 4, 284, 74, 75, 76, 77, 79, 80, - 70, 292, 69, 70, 295, 480, 71, 313, 4, 300, - 42, 317, 303, 419, 4, 4, 5, 68, 69, 70, - 52, 11, 70, 314, 1, 316, 4, 4, 319, 12, - 336, 322, 323, 374, 12, 12, 69, 348, 347, 330, - 331, 332, 333, 4, 40, 41, 337, 372, 339, 1, - 341, 12, 343, 4, 1, 346, 1, 4, 383, 12, - 13, 12, 39, 419, 355, 471, 357, 14, 15, 16, - 17, 18, 378, 69, 399, 366, 72, 21, 61, 370, - 371, 419, 4, 38, 20, 376, 421, 70, 394, 40, - 41, 68, 1, 1, 385, 4, 4, 408, 404, 390, - 406, 392, 12, 11, 12, 14, 15, 16, 17, 18, - 63, 4, 418, 20, 1, 471, 457, 4, 11, 1, - 42, 72, 69, 70, 11, 416, 73, 74, 75, 76, - 77, 70, 423, 471, 1, 426, 1, 428, 69, 4, - 71, 12, 433, 70, 70, 16, 11, 438, 12, 460, - 441, 457, 443, 69, 1, 71, 64, 69, 71, 71, - 69, 70, 4, 454, 73, 74, 75, 76, 77, 11, - 12, 64, 4, 0, 1, 1, 71, 64, 26, 11, - 12, 69, 473, 71, 11, 12, 1, 14, 15, 69, - 481, 71, 73, 484, 65, 66, 73, 73, 489, 490, - 69, 25, 71, 27, 28, 29, 497, 31, 32, 33, - 12, 69, 39, 37, 42, 506, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 1, - 67, 68, 69, 70, 71, 4, 69, 74, 75, 0, - 1, 78, 69, 4, 81, 82, 83, 70, 70, 4, - 11, 12, 73, 14, 15, 1, 70, 12, 4, 14, - 15, 16, 17, 18, 19, 20, 4, 70, 14, 15, - 16, 17, 18, 12, 70, 14, 15, 16, 17, 18, - 19, 20, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 1, 67, 68, 69, 70, - 71, 69, 347, 71, 75, 11, 12, 78, 14, 15, - 420, 82, 83, 69, 70, 153, 388, 73, 74, 75, - 76, 77, 12, 447, 14, 15, 16, 17, 18, 19, - 14, 15, 16, 17, 18, 496, 367, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 1, 67, 68, 69, 70, 71, 436, 384, 74, 75, - 11, 12, 78, 14, 15, 81, 82, 83, 43, 44, + 71, 192, 133, 134, 72, 320, 71, 158, 139, 160, + 156, 196, 197, 144, 1, 195, 147, 150, 5, 5, + 151, 154, 74, 70, 155, 72, 5, 342, 75, 175, + 1, 177, 12, 179, 5, 7, 8, 9, 10, 11, + 171, 5, 1, 1, 15, 16, 17, 18, 19, 1, + 0, 1, 70, 184, 185, 41, 42, 5, 189, 190, + 191, 5, 419, 5, 1, 5, 381, 70, 5, 200, + 1, 13, 205, 5, 1, 0, 1, 208, 5, 43, + 211, 70, 397, 70, 71, 65, 17, 73, 75, 76, + 77, 78, 283, 72, 1, 5, 5, 278, 5, 70, + 71, 5, 70, 74, 75, 76, 77, 78, 80, 81, + 17, 70, 70, 0, 471, 246, 75, 75, 70, 250, + 251, 71, 70, 75, 275, 5, 311, 75, 259, 73, + 263, 71, 278, 70, 265, 419, 442, 268, 70, 70, + 305, 272, 273, 70, 71, 70, 71, 72, 75, 76, + 77, 78, 419, 284, 7, 8, 9, 10, 11, 419, + 70, 292, 71, 70, 295, 480, 70, 313, 42, 300, + 5, 317, 303, 0, 1, 1, 5, 12, 52, 70, + 70, 72, 72, 314, 13, 316, 13, 471, 319, 13, + 336, 322, 323, 374, 70, 5, 72, 348, 347, 330, + 331, 332, 333, 13, 471, 1, 337, 372, 339, 5, + 341, 471, 343, 40, 70, 346, 72, 1, 383, 15, + 16, 17, 18, 19, 355, 1, 357, 80, 81, 5, + 65, 70, 378, 72, 399, 366, 22, 13, 62, 370, + 371, 39, 69, 70, 71, 376, 421, 71, 394, 21, + 5, 1, 1, 13, 385, 5, 5, 408, 404, 390, + 406, 392, 21, 12, 40, 15, 16, 17, 18, 19, + 71, 70, 418, 72, 70, 71, 457, 1, 74, 75, + 76, 77, 78, 71, 13, 416, 41, 42, 17, 70, + 5, 72, 423, 69, 71, 426, 5, 428, 13, 5, + 35, 36, 433, 12, 13, 20, 21, 438, 1, 460, + 441, 457, 443, 5, 6, 70, 65, 70, 73, 72, + 70, 71, 5, 454, 74, 75, 76, 77, 78, 12, + 13, 13, 0, 1, 1, 41, 42, 66, 67, 70, + 72, 72, 473, 1, 12, 13, 72, 15, 16, 70, + 481, 72, 70, 484, 72, 27, 13, 74, 489, 490, + 70, 74, 72, 70, 70, 72, 497, 73, 70, 70, + 72, 72, 40, 1, 74, 506, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 70, + 68, 69, 70, 71, 72, 0, 1, 75, 76, 43, + 5, 79, 1, 5, 82, 83, 84, 12, 13, 70, + 15, 16, 70, 1, 72, 70, 1, 5, 71, 70, + 5, 72, 71, 5, 12, 13, 74, 420, 71, 71, + 15, 16, 17, 18, 19, 71, 347, 447, 153, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 69, - 47, 71, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 306, 67, 68, 69, 70, - 71, 173, 81, 74, 75, 1, 286, 78, 4, 358, - 81, 82, 83, 4, 451, 11, 12, 427, 14, 15, - 69, 12, 71, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 69, 69, 71, 71, 69, 30, - 71, 69, 69, 71, 71, 252, 94, 43, 44, 45, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 388, 68, 69, 70, 71, 72, 367, 1, + 436, 76, 496, 47, 79, 384, 306, 65, 83, 84, + 12, 13, 173, 15, 16, 70, 71, 5, 81, 74, + 75, 76, 77, 78, 286, 13, 358, 15, 16, 17, + 18, 19, 20, 21, 13, 451, 15, 16, 17, 18, + 19, 20, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 94, 68, 69, 70, 71, + 72, 135, 1, 75, 76, 0, 1, 79, 427, 471, + 82, 83, 84, 12, 13, 252, 15, 16, 13, 347, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 347, -1, -1, -1, 13, 31, 15, 16, 17, + 18, 19, 20, 21, 39, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, -1, 68, + 69, 70, 71, 72, -1, 1, 75, 76, -1, 5, + 79, -1, -1, 82, 83, 84, 12, 13, 5, 15, + 16, 15, 16, 17, 18, 19, 13, -1, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, + -1, -1, -1, -1, 31, -1, -1, -1, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 135, 67, 68, 69, 70, 71, 347, 347, 1, 75, - 471, 4, 78, 69, -1, 71, 82, 83, 11, 12, - -1, 14, 15, 69, 69, 71, 71, 485, -1, 487, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 66, -1, 68, 69, 70, 71, 72, -1, 1, -1, + 76, -1, 5, 79, -1, -1, -1, 83, 84, 12, + 13, -1, 15, 16, 26, -1, 28, 29, 30, -1, + 32, 33, 34, -1, -1, -1, 38, -1, -1, -1, + -1, 5, -1, -1, -1, -1, -1, -1, -1, 13, + -1, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 1, 67, 68, -1, -1, -1, -1, - 73, 74, 75, 11, 12, 78, 14, 15, 81, 82, - 83, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 1, 67, - 68, -1, 70, -1, -1, -1, 74, 75, 11, 12, - 78, 14, 15, 81, 82, 83, -1, -1, -1, -1, + 63, 64, 65, 66, -1, 68, 69, 41, 42, -1, + -1, 74, 75, 76, 1, -1, 79, -1, -1, 82, + 83, 84, -1, -1, -1, 12, 13, -1, 15, 16, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 73, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + -1, 68, 69, -1, 71, -1, -1, 1, 75, 76, + -1, -1, 79, -1, -1, 82, 83, 84, 12, 13, + -1, 15, 16, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, -1, -1, -1, -1, -1, -1, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, -1, 68, 69, -1, -1, -1, -1, + 74, 75, 76, 1, -1, 79, -1, 5, 82, 83, + 84, -1, -1, -1, 12, 13, -1, 15, 16, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 1, 67, 68, 4, -1, -1, -1, - 73, 74, 75, 11, 12, 78, 14, 15, 81, 82, - 83, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 43, 44, 45, 46, 47, + -1, -1, -1, -1, -1, -1, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 4, 67, - 68, -1, -1, -1, -1, 11, 12, 75, 14, 15, - 78, -1, -1, -1, 82, 83, -1, -1, -1, -1, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 5, + 68, 69, -1, -1, -1, -1, 12, 13, 76, 15, + 16, 79, -1, -1, -1, 83, 84, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 43, 44, 45, + -1, -1, -1, -1, -1, -1, -1, -1, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - -1, 67, 68, 11, 12, -1, 14, 15, -1, 75, - -1, -1, 78, -1, -1, -1, 82, 83, -1, -1, + 66, -1, 68, 69, 12, 13, -1, 15, 16, -1, + 76, -1, -1, 79, -1, -1, -1, 83, 84, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 43, 44, 45, 46, 47, + -1, -1, -1, -1, -1, -1, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, -1, 67, - 68, -1, -1, -1, 0, 1, -1, 75, -1, -1, - 78, -1, -1, -1, 82, 83, 12, -1, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 0, - 1, -1, -1, -1, 30, -1, -1, -1, -1, -1, - -1, 12, 38, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, -1, -1, -1, -1, -1, 30, - -1, -1, -1, -1, -1, -1, -1, 38, -1, -1, - -1, -1, -1, -1, 70 + 58, 59, 60, 61, 62, 63, 64, 65, 66, -1, + 68, 69, -1, -1, 0, 1, -1, -1, 76, -1, + -1, 79, -1, -1, -1, 83, 84, 13, -1, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + -1, -1, -1, -1, -1, 31, -1, -1, -1, -1, + -1, -1, -1, 39, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 71 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 25, 27, 28, 29, 31, 32, 33, 37, 85, - 87, 88, 89, 90, 91, 92, 93, 96, 98, 1, - 94, 69, 69, 69, 69, 4, 69, 69, 0, 94, - 94, 94, 94, 94, 94, 94, 95, 69, 71, 172, - 4, 11, 94, 94, 94, 94, 94, 94, 94, 4, - 5, 38, 99, 167, 168, 1, 94, 12, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 30, - 86, 103, 108, 127, 129, 135, 136, 139, 140, 141, - 142, 143, 144, 145, 146, 147, 148, 150, 153, 1, - 12, 39, 68, 154, 155, 156, 157, 163, 12, 61, - 132, 133, 134, 11, 12, 14, 15, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 67, 75, 78, 82, 83, 138, 159, 161, 162, 163, - 164, 165, 40, 41, 72, 120, 121, 123, 124, 140, - 1, 12, 111, 112, 113, 114, 1, 100, 108, 95, - 167, 0, 70, 97, 172, 173, 71, 20, 12, 16, - 65, 66, 12, 94, 20, 1, 94, 1, 94, 1, - 94, 94, 94, 1, 69, 74, 144, 1, 4, 75, - 76, 77, 137, 12, 19, 145, 146, 146, 1, 147, - 71, 173, 94, 94, 70, 1, 156, 173, 71, 173, - 1, 16, 172, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 60, 162, 1, 70, - 74, 81, 160, 94, 94, 94, 94, 70, 70, 71, - 173, 94, 70, 1, 113, 71, 173, 1, 16, 94, - 71, 172, 34, 35, 101, 109, 95, 95, 1, 12, - 12, 13, 63, 94, 12, 19, 143, 149, 71, 172, - 11, 64, 117, 71, 172, 69, 124, 126, 71, 172, - 69, 11, 12, 130, 70, 94, 94, 94, 94, 94, - 144, 146, 94, 1, 71, 173, 71, 1, 94, 71, - 94, 70, 69, 74, 1, 159, 94, 94, 94, 161, - 12, 118, 42, 12, 128, 94, 1, 71, 173, 71, - 94, 71, 94, 69, 94, 94, 26, 102, 115, 95, - 97, 172, 73, 73, 73, 144, 94, 12, 149, 6, - 7, 8, 9, 10, 79, 80, 151, 94, 94, 1, - 69, 74, 94, 94, 154, 142, 71, 94, 1, 94, - 94, 1, 159, 94, 94, 73, 94, 94, 94, 94, - 42, 122, 71, 94, 1, 94, 94, 1, 159, 94, - 125, 126, 36, 110, 1, 94, 1, 103, 104, 108, - 167, 169, 171, 95, 94, 79, 151, 94, 125, 105, - 94, 94, 154, 69, 97, 94, 71, 159, 39, 158, - 154, 134, 94, 16, 119, 120, 94, 94, 71, 159, - 154, 69, 4, 69, 71, 172, 12, 116, 172, 95, - 73, 94, 11, 12, 152, 71, 172, 1, 97, 106, - 107, 127, 129, 135, 136, 139, 166, 167, 169, 170, - 171, 105, 124, 70, 94, 94, 158, 94, 1, 70, - 94, 73, 121, 94, 70, 94, 126, 94, 4, 117, - 152, 94, 97, 95, 166, 94, 131, 159, 94, 94, - 111, 111, 94, 94, 79, 70, 132, 94, 70, 70, - 71, 79, 94 + 0, 26, 28, 29, 30, 32, 33, 34, 38, 86, + 88, 89, 90, 91, 92, 93, 94, 97, 99, 1, + 95, 70, 70, 70, 70, 5, 70, 70, 0, 95, + 95, 95, 95, 95, 95, 95, 96, 70, 72, 173, + 5, 12, 95, 95, 95, 95, 95, 95, 95, 5, + 6, 39, 100, 168, 169, 1, 95, 13, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 31, + 87, 104, 109, 128, 130, 136, 137, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 151, 154, 1, + 13, 40, 69, 155, 156, 157, 158, 164, 13, 62, + 133, 134, 135, 12, 13, 15, 16, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 68, 76, 79, 83, 84, 139, 160, 162, 163, 164, + 165, 166, 41, 42, 73, 121, 122, 124, 125, 141, + 1, 13, 112, 113, 114, 115, 1, 101, 109, 96, + 168, 0, 71, 98, 173, 174, 72, 21, 13, 17, + 66, 67, 13, 95, 21, 1, 95, 1, 95, 1, + 95, 95, 95, 1, 70, 75, 145, 1, 5, 76, + 77, 78, 138, 13, 20, 146, 147, 147, 1, 148, + 72, 174, 95, 95, 71, 1, 157, 174, 72, 174, + 1, 17, 173, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 61, 163, 1, 71, + 75, 82, 161, 95, 95, 95, 95, 71, 71, 72, + 174, 95, 71, 1, 114, 72, 174, 1, 17, 95, + 72, 173, 35, 36, 102, 110, 96, 96, 1, 13, + 13, 14, 64, 95, 13, 20, 144, 150, 72, 173, + 12, 65, 118, 72, 173, 70, 125, 127, 72, 173, + 70, 12, 13, 131, 71, 95, 95, 95, 95, 95, + 145, 147, 95, 1, 72, 174, 72, 1, 95, 72, + 95, 71, 70, 75, 1, 160, 95, 95, 95, 162, + 13, 119, 43, 13, 129, 95, 1, 72, 174, 72, + 95, 72, 95, 70, 95, 95, 27, 103, 116, 96, + 98, 173, 74, 74, 74, 145, 95, 13, 150, 7, + 8, 9, 10, 11, 80, 81, 152, 95, 95, 1, + 70, 75, 95, 95, 155, 143, 72, 95, 1, 95, + 95, 1, 160, 95, 95, 74, 95, 95, 95, 95, + 43, 123, 72, 95, 1, 95, 95, 1, 160, 95, + 126, 127, 37, 111, 1, 95, 1, 104, 105, 109, + 168, 170, 172, 96, 95, 80, 152, 95, 126, 106, + 95, 95, 155, 70, 98, 95, 72, 160, 40, 159, + 155, 135, 95, 17, 120, 121, 95, 95, 72, 160, + 155, 70, 5, 70, 72, 173, 13, 117, 173, 96, + 74, 95, 12, 13, 153, 72, 173, 1, 98, 107, + 108, 128, 130, 136, 137, 140, 167, 168, 170, 171, + 172, 106, 125, 71, 95, 95, 159, 95, 1, 71, + 95, 74, 122, 95, 71, 95, 127, 95, 5, 118, + 153, 95, 98, 96, 167, 95, 132, 160, 95, 95, + 112, 112, 95, 95, 80, 71, 133, 95, 71, 71, + 72, 80, 95 }; #define yyerrok (yyerrstatus = 0) @@ -1546,17 +1509,20 @@ yy_symbol_print (yyoutput, yytype, yyvaluep) #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) #else static void -yy_stack_print (bottom, top) - yytype_int16 *bottom; - yytype_int16 *top; +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; #endif { YYFPRINTF (stderr, "Stack now"); - for (; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } YYFPRINTF (stderr, "\n"); } @@ -1590,11 +1556,11 @@ yy_reduce_print (yyvsp, yyrule) /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { - fprintf (stderr, " $%d = ", yyi + 1); + YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) ); - fprintf (stderr, "\n"); + YYFPRINTF (stderr, "\n"); } } @@ -1874,10 +1840,8 @@ yydestruct (yymsg, yytype, yyvaluep) break; } } - /* Prevent warnings from -Wmissing-prototypes. */ - #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); @@ -1896,10 +1860,9 @@ int yyparse (); - -/*----------. -| yyparse. | -`----------*/ +/*-------------------------. +| yyparse or yypush_parse. | +`-------------------------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ @@ -1923,74 +1886,75 @@ yyparse () #endif #endif { - /* The look-ahead symbol. */ +/* The lookahead symbol. */ int yychar; -/* The semantic value of the look-ahead symbol. */ +/* The semantic value of the lookahead symbol. */ YYSTYPE yylval; -/* Number of syntax errors so far. */ -int yynerrs; - - int yystate; - int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Look-ahead token as an internal (translated) token number. */ - int yytoken = 0; -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ + /* Number of syntax errors so far. */ + int yynerrs; - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss = yyssa; - yytype_int16 *yyssp; + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp; + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; - YYSIZE_T yystacksize = YYINITDEPTH; + YYSIZE_T yystacksize; + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yystacksize = YYINITDEPTH; + YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ + yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ - yyssp = yyss; yyvsp = yyvs; @@ -2020,7 +1984,6 @@ int yynerrs; YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; - /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might @@ -2028,7 +1991,6 @@ int yynerrs; yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); yyss = yyss1; @@ -2051,9 +2013,8 @@ int yynerrs; (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); @@ -2064,7 +2025,6 @@ int yynerrs; yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; - YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); @@ -2074,6 +2034,9 @@ int yynerrs; YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + if (yystate == YYFINAL) + YYACCEPT; + goto yybackup; /*-----------. @@ -2082,16 +2045,16 @@ int yynerrs; yybackup: /* Do appropriate processing given the current state. Read a - look-ahead token if we need one and don't already have one. */ + lookahead token if we need one and don't already have one. */ - /* First try to decide what to do without reference to look-ahead token. */ + /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; - /* Not known => get a look-ahead token if don't already have one. */ + /* Not known => get a lookahead token if don't already have one. */ - /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); @@ -2123,20 +2086,16 @@ yybackup: goto yyreduce; } - if (yyn == YYFINAL) - YYACCEPT; - /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; - /* Shift the look-ahead token. */ + /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - /* Discard the shifted token unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; + /* Discard the shifted token. */ + yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; @@ -2176,35 +2135,45 @@ yyreduce: switch (yyn) { case 12: -#line 279 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 281 "../css/CSSGrammar.y" { static_cast(parser)->m_rule = (yyvsp[(4) - (6)].rule); ;} break; case 13: -#line 285 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 287 "../css/CSSGrammar.y" { static_cast(parser)->m_keyframe = (yyvsp[(4) - (6)].keyframeRule); ;} break; case 14: -#line 291 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 293 "../css/CSSGrammar.y" { /* can be empty */ ;} break; case 15: -#line 297 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 299 "../css/CSSGrammar.y" { /* can be empty */ ;} break; case 16: -#line 303 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 305 "../css/CSSGrammar.y" { CSSParser* p = static_cast(parser); if ((yyvsp[(4) - (5)].valueList)) { @@ -2219,7 +2188,9 @@ yyreduce: break; case 17: -#line 317 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 319 "../css/CSSGrammar.y" { CSSParser* p = static_cast(parser); p->m_mediaQuery = p->sinkFloatingMediaQuery((yyvsp[(4) - (5)].mediaQuery)); @@ -2227,7 +2198,9 @@ yyreduce: break; case 18: -#line 324 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 326 "../css/CSSGrammar.y" { if ((yyvsp[(4) - (5)].selectorList)) { CSSParser* p = static_cast(parser); @@ -2238,13 +2211,17 @@ yyreduce: break; case 25: -#line 346 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 348 "../css/CSSGrammar.y" { ;} break; case 28: -#line 356 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 358 "../css/CSSGrammar.y" { CSSParser* p = static_cast(parser); (yyval.rule) = static_cast(parser)->createCharsetRule((yyvsp[(3) - (5)].string)); @@ -2254,19 +2231,25 @@ yyreduce: break; case 29: -#line 362 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 364 "../css/CSSGrammar.y" { ;} break; case 30: -#line 364 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 366 "../css/CSSGrammar.y" { ;} break; case 32: -#line 370 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 372 "../css/CSSGrammar.y" { CSSParser* p = static_cast(parser); if ((yyvsp[(2) - (3)].rule) && p->m_styleSheet) @@ -2275,13 +2258,17 @@ yyreduce: break; case 33: -#line 375 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 377 "../css/CSSGrammar.y" { ;} break; case 35: -#line 381 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 383 "../css/CSSGrammar.y" { CSSParser* p = static_cast(parser); if ((yyvsp[(2) - (3)].rule) && p->m_styleSheet) @@ -2290,7 +2277,9 @@ yyreduce: break; case 39: -#line 395 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 397 "../css/CSSGrammar.y" { CSSParser* p = static_cast(parser); if ((yyvsp[(2) - (3)].rule) && p->m_styleSheet) @@ -2299,12 +2288,16 @@ yyreduce: break; case 49: -#line 418 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 420 "../css/CSSGrammar.y" { (yyval.ruleList) = 0; ;} break; case 50: -#line 419 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 421 "../css/CSSGrammar.y" { (yyval.ruleList) = (yyvsp[(1) - (3)].ruleList); if ((yyvsp[(2) - (3)].rule)) { @@ -2316,70 +2309,90 @@ yyreduce: break; case 60: -#line 446 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 448 "../css/CSSGrammar.y" { (yyval.rule) = static_cast(parser)->createImportRule((yyvsp[(3) - (6)].string), (yyvsp[(5) - (6)].mediaList)); ;} break; case 61: -#line 449 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 451 "../css/CSSGrammar.y" { (yyval.rule) = 0; ;} break; case 62: -#line 452 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 454 "../css/CSSGrammar.y" { (yyval.rule) = 0; ;} break; case 63: -#line 455 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 457 "../css/CSSGrammar.y" { (yyval.rule) = 0; ;} break; case 64: -#line 461 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 463 "../css/CSSGrammar.y" { (yyval.rule) = static_cast(parser)->createVariablesRule((yyvsp[(3) - (7)].mediaList), true); ;} break; case 65: -#line 465 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 467 "../css/CSSGrammar.y" { (yyval.rule) = static_cast(parser)->createVariablesRule((yyvsp[(3) - (7)].mediaList), false); ;} break; case 66: -#line 471 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 473 "../css/CSSGrammar.y" { (yyval.mediaList) = static_cast(parser)->createMediaList(); ;} break; case 67: -#line 475 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 477 "../css/CSSGrammar.y" { (yyval.mediaList) = (yyvsp[(3) - (3)].mediaList); ;} break; case 68: -#line 481 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 483 "../css/CSSGrammar.y" { (yyval.boolean) = (yyvsp[(1) - (1)].boolean); ;} break; case 69: -#line 484 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 486 "../css/CSSGrammar.y" { (yyval.boolean) = (yyvsp[(1) - (2)].boolean); if ((yyvsp[(2) - (2)].boolean)) @@ -2388,63 +2401,81 @@ yyreduce: break; case 70: -#line 489 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 491 "../css/CSSGrammar.y" { (yyval.boolean) = (yyvsp[(1) - (1)].boolean); ;} break; case 71: -#line 492 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 494 "../css/CSSGrammar.y" { (yyval.boolean) = false; ;} break; case 72: -#line 495 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 497 "../css/CSSGrammar.y" { (yyval.boolean) = false; ;} break; case 73: -#line 498 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 500 "../css/CSSGrammar.y" { (yyval.boolean) = (yyvsp[(1) - (2)].boolean); ;} break; case 74: -#line 504 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 506 "../css/CSSGrammar.y" { (yyval.boolean) = (yyvsp[(1) - (3)].boolean); ;} break; case 75: -#line 507 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 509 "../css/CSSGrammar.y" { (yyval.boolean) = false; ;} break; case 76: -#line 510 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 512 "../css/CSSGrammar.y" { (yyval.boolean) = false; ;} break; case 77: -#line 513 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 515 "../css/CSSGrammar.y" { (yyval.boolean) = false; ;} break; case 78: -#line 516 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 518 "../css/CSSGrammar.y" { (yyval.boolean) = (yyvsp[(1) - (4)].boolean); if ((yyvsp[(2) - (4)].boolean)) @@ -2453,49 +2484,63 @@ yyreduce: break; case 79: -#line 521 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 523 "../css/CSSGrammar.y" { (yyval.boolean) = (yyvsp[(1) - (4)].boolean); ;} break; case 80: -#line 524 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 526 "../css/CSSGrammar.y" { (yyval.boolean) = (yyvsp[(1) - (6)].boolean); ;} break; case 81: -#line 530 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 532 "../css/CSSGrammar.y" { (yyval.boolean) = static_cast(parser)->addVariable((yyvsp[(1) - (4)].string), (yyvsp[(4) - (4)].valueList)); ;} break; case 82: -#line 534 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 536 "../css/CSSGrammar.y" { (yyval.boolean) = static_cast(parser)->addVariableDeclarationBlock((yyvsp[(1) - (7)].string)); ;} break; case 83: -#line 538 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 540 "../css/CSSGrammar.y" { (yyval.boolean) = false; ;} break; case 84: -#line 542 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 544 "../css/CSSGrammar.y" { (yyval.boolean) = false; ;} break; case 85: -#line 546 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 548 "../css/CSSGrammar.y" { /* @variables { varname: } Just reduce away this variable with no value. */ (yyval.boolean) = false; @@ -2503,7 +2548,9 @@ yyreduce: break; case 86: -#line 551 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 553 "../css/CSSGrammar.y" { /* if we come across rules with invalid values like this case: @variables { varname: *; }, just discard the property/value pair */ (yyval.boolean) = false; @@ -2511,14 +2558,18 @@ yyreduce: break; case 87: -#line 558 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 560 "../css/CSSGrammar.y" { (yyval.string) = (yyvsp[(1) - (2)].string); ;} break; case 88: -#line 564 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 566 "../css/CSSGrammar.y" { CSSParser* p = static_cast(parser); if (p->m_styleSheet) @@ -2527,38 +2578,50 @@ yyreduce: break; case 91: -#line 574 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 576 "../css/CSSGrammar.y" { (yyval.string).characters = 0; ;} break; case 92: -#line 575 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 577 "../css/CSSGrammar.y" { (yyval.string) = (yyvsp[(1) - (2)].string); ;} break; case 95: -#line 584 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 586 "../css/CSSGrammar.y" { (yyval.string) = (yyvsp[(1) - (2)].string); ;} break; case 96: -#line 590 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 592 "../css/CSSGrammar.y" { (yyval.valueList) = 0; ;} break; case 97: -#line 593 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 595 "../css/CSSGrammar.y" { (yyval.valueList) = (yyvsp[(3) - (4)].valueList); ;} break; case 98: -#line 599 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 601 "../css/CSSGrammar.y" { (yyvsp[(3) - (7)].string).lower(); (yyval.mediaQueryExp) = static_cast(parser)->createFloatingMediaQueryExp((yyvsp[(3) - (7)].string), (yyvsp[(5) - (7)].valueList)); @@ -2566,7 +2629,9 @@ yyreduce: break; case 99: -#line 606 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 608 "../css/CSSGrammar.y" { CSSParser* p = static_cast(parser); (yyval.mediaQueryExpList) = p->createFloatingMediaQueryExpList(); @@ -2575,7 +2640,9 @@ yyreduce: break; case 100: -#line 611 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 613 "../css/CSSGrammar.y" { (yyval.mediaQueryExpList) = (yyvsp[(1) - (5)].mediaQueryExpList); (yyval.mediaQueryExpList)->append(static_cast(parser)->sinkFloatingMediaQueryExp((yyvsp[(5) - (5)].mediaQueryExp))); @@ -2583,42 +2650,54 @@ yyreduce: break; case 101: -#line 618 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 620 "../css/CSSGrammar.y" { (yyval.mediaQueryExpList) = static_cast(parser)->createFloatingMediaQueryExpList(); ;} break; case 102: -#line 621 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 623 "../css/CSSGrammar.y" { (yyval.mediaQueryExpList) = (yyvsp[(3) - (3)].mediaQueryExpList); ;} break; case 103: -#line 627 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 629 "../css/CSSGrammar.y" { (yyval.mediaQueryRestrictor) = MediaQuery::None; ;} break; case 104: -#line 630 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 632 "../css/CSSGrammar.y" { (yyval.mediaQueryRestrictor) = MediaQuery::Only; ;} break; case 105: -#line 633 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 635 "../css/CSSGrammar.y" { (yyval.mediaQueryRestrictor) = MediaQuery::Not; ;} break; case 106: -#line 639 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 641 "../css/CSSGrammar.y" { CSSParser* p = static_cast(parser); (yyval.mediaQuery) = p->createFloatingMediaQuery(p->sinkFloatingMediaQueryExpList((yyvsp[(1) - (1)].mediaQueryExpList))); @@ -2626,7 +2705,9 @@ yyreduce: break; case 107: -#line 644 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 646 "../css/CSSGrammar.y" { CSSParser* p = static_cast(parser); (yyvsp[(3) - (4)].string).lower(); @@ -2635,14 +2716,18 @@ yyreduce: break; case 108: -#line 652 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 654 "../css/CSSGrammar.y" { (yyval.mediaList) = static_cast(parser)->createMediaList(); ;} break; case 110: -#line 659 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 661 "../css/CSSGrammar.y" { CSSParser* p = static_cast(parser); (yyval.mediaList) = p->createMediaList(); @@ -2651,7 +2736,9 @@ yyreduce: break; case 111: -#line 664 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 666 "../css/CSSGrammar.y" { (yyval.mediaList) = (yyvsp[(1) - (4)].mediaList); if ((yyval.mediaList)) @@ -2660,35 +2747,45 @@ yyreduce: break; case 112: -#line 669 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 671 "../css/CSSGrammar.y" { (yyval.mediaList) = 0; ;} break; case 113: -#line 675 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 677 "../css/CSSGrammar.y" { (yyval.rule) = static_cast(parser)->createMediaRule((yyvsp[(3) - (7)].mediaList), (yyvsp[(6) - (7)].ruleList)); ;} break; case 114: -#line 678 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 680 "../css/CSSGrammar.y" { (yyval.rule) = static_cast(parser)->createMediaRule(0, (yyvsp[(5) - (6)].ruleList)); ;} break; case 115: -#line 684 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 686 "../css/CSSGrammar.y" { (yyval.string) = (yyvsp[(1) - (2)].string); ;} break; case 116: -#line 690 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 692 "../css/CSSGrammar.y" { (yyval.rule) = (yyvsp[(7) - (8)].keyframesRule); (yyvsp[(7) - (8)].keyframesRule)->setNameInternal((yyvsp[(3) - (8)].string)); @@ -2696,12 +2793,16 @@ yyreduce: break; case 119: -#line 702 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 704 "../css/CSSGrammar.y" { (yyval.keyframesRule) = static_cast(parser)->createKeyframesRule(); ;} break; case 120: -#line 703 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 705 "../css/CSSGrammar.y" { (yyval.keyframesRule) = (yyvsp[(1) - (3)].keyframesRule); if ((yyvsp[(2) - (3)].keyframeRule)) @@ -2710,14 +2811,18 @@ yyreduce: break; case 121: -#line 711 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 713 "../css/CSSGrammar.y" { (yyval.keyframeRule) = static_cast(parser)->createKeyframeRule((yyvsp[(1) - (6)].valueList)); ;} break; case 122: -#line 717 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 719 "../css/CSSGrammar.y" { CSSParser* p = static_cast(parser); (yyval.valueList) = p->createFloatingValueList(); @@ -2726,7 +2831,9 @@ yyreduce: break; case 123: -#line 722 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 724 "../css/CSSGrammar.y" { CSSParser* p = static_cast(parser); (yyval.valueList) = (yyvsp[(1) - (5)].valueList); @@ -2736,12 +2843,16 @@ yyreduce: break; case 124: -#line 731 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 733 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).isInt = false; (yyval.value).fValue = (yyvsp[(1) - (1)].number); (yyval.value).unit = CSSPrimitiveValue::CSS_NUMBER; ;} break; case 125: -#line 732 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 734 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).isInt = false; (yyval.value).unit = CSSPrimitiveValue::CSS_NUMBER; CSSParserString& str = (yyvsp[(1) - (1)].string); @@ -2755,74 +2866,98 @@ yyreduce: break; case 126: -#line 756 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 758 "../css/CSSGrammar.y" { (yyval.rule) = 0; ;} break; case 127: -#line 759 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 761 "../css/CSSGrammar.y" { (yyval.rule) = 0; ;} break; case 128: -#line 766 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 768 "../css/CSSGrammar.y" { (yyval.rule) = static_cast(parser)->createFontFaceRule(); ;} break; case 129: -#line 769 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 771 "../css/CSSGrammar.y" { (yyval.rule) = 0; ;} break; case 130: -#line 772 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 774 "../css/CSSGrammar.y" { (yyval.rule) = 0; ;} break; case 131: -#line 778 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 780 "../css/CSSGrammar.y" { (yyval.relation) = CSSSelector::DirectAdjacent; ;} break; case 132: -#line 779 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 781 "../css/CSSGrammar.y" { (yyval.relation) = CSSSelector::IndirectAdjacent; ;} break; case 133: -#line 780 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 782 "../css/CSSGrammar.y" { (yyval.relation) = CSSSelector::Child; ;} break; case 134: -#line 784 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 786 "../css/CSSGrammar.y" { (yyval.integer) = -1; ;} break; case 135: -#line 785 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 787 "../css/CSSGrammar.y" { (yyval.integer) = 1; ;} break; case 136: -#line 789 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 791 "../css/CSSGrammar.y" { (yyval.rule) = static_cast(parser)->createStyleRule((yyvsp[(1) - (5)].selectorList)); ;} break; case 137: -#line 795 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 797 "../css/CSSGrammar.y" { if ((yyvsp[(1) - (1)].selector)) { CSSParser* p = static_cast(parser); @@ -2835,7 +2970,9 @@ yyreduce: break; case 138: -#line 804 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 806 "../css/CSSGrammar.y" { if ((yyvsp[(1) - (4)].selectorList) && (yyvsp[(4) - (4)].selector)) { CSSParser* p = static_cast(parser); @@ -2847,35 +2984,45 @@ yyreduce: break; case 139: -#line 812 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 814 "../css/CSSGrammar.y" { (yyval.selectorList) = 0; ;} break; case 140: -#line 818 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 820 "../css/CSSGrammar.y" { (yyval.selector) = (yyvsp[(1) - (2)].selector); ;} break; case 141: -#line 824 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 826 "../css/CSSGrammar.y" { (yyval.selector) = (yyvsp[(1) - (1)].selector); ;} break; case 142: -#line 828 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 830 "../css/CSSGrammar.y" { (yyval.selector) = (yyvsp[(1) - (1)].selector); ;} break; case 143: -#line 832 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 834 "../css/CSSGrammar.y" { (yyval.selector) = (yyvsp[(2) - (2)].selector); if (!(yyvsp[(1) - (2)].selector)) @@ -2894,7 +3041,9 @@ yyreduce: break; case 144: -#line 847 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 849 "../css/CSSGrammar.y" { (yyval.selector) = (yyvsp[(3) - (3)].selector); if (!(yyvsp[(1) - (3)].selector)) @@ -2918,29 +3067,39 @@ yyreduce: break; case 145: -#line 867 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 869 "../css/CSSGrammar.y" { (yyval.selector) = 0; ;} break; case 146: -#line 873 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 875 "../css/CSSGrammar.y" { (yyval.string).characters = 0; (yyval.string).length = 0; ;} break; case 147: -#line 874 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 876 "../css/CSSGrammar.y" { static UChar star = '*'; (yyval.string).characters = ☆ (yyval.string).length = 1; ;} break; case 148: -#line 875 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 877 "../css/CSSGrammar.y" { (yyval.string) = (yyvsp[(1) - (2)].string); ;} break; case 149: -#line 879 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 881 "../css/CSSGrammar.y" { CSSParser* p = static_cast(parser); (yyval.selector) = p->createFloatingSelector(); @@ -2949,7 +3108,9 @@ yyreduce: break; case 150: -#line 884 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 886 "../css/CSSGrammar.y" { (yyval.selector) = (yyvsp[(2) - (2)].selector); if ((yyval.selector)) { @@ -2960,7 +3121,9 @@ yyreduce: break; case 151: -#line 891 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 893 "../css/CSSGrammar.y" { (yyval.selector) = (yyvsp[(1) - (1)].selector); CSSParser* p = static_cast(parser); @@ -2970,7 +3133,9 @@ yyreduce: break; case 152: -#line 897 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 899 "../css/CSSGrammar.y" { AtomicString namespacePrefix = (yyvsp[(1) - (2)].string); CSSParser* p = static_cast(parser); @@ -2984,7 +3149,9 @@ yyreduce: break; case 153: -#line 907 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 909 "../css/CSSGrammar.y" { (yyval.selector) = (yyvsp[(3) - (3)].selector); if ((yyval.selector)) { @@ -3000,7 +3167,9 @@ yyreduce: break; case 154: -#line 919 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 921 "../css/CSSGrammar.y" { (yyval.selector) = (yyvsp[(2) - (2)].selector); if ((yyval.selector)) { @@ -3014,7 +3183,9 @@ yyreduce: break; case 155: -#line 932 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 934 "../css/CSSGrammar.y" { CSSParserString& str = (yyvsp[(1) - (1)].string); CSSParser* p = static_cast(parser); @@ -3026,7 +3197,9 @@ yyreduce: break; case 156: -#line 940 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 942 "../css/CSSGrammar.y" { static UChar star = '*'; (yyval.string).characters = ☆ @@ -3035,14 +3208,18 @@ yyreduce: break; case 157: -#line 948 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 950 "../css/CSSGrammar.y" { (yyval.selector) = (yyvsp[(1) - (1)].selector); ;} break; case 158: -#line 951 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 953 "../css/CSSGrammar.y" { if (!(yyvsp[(2) - (2)].selector)) (yyval.selector) = 0; @@ -3059,14 +3236,18 @@ yyreduce: break; case 159: -#line 964 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 966 "../css/CSSGrammar.y" { (yyval.selector) = 0; ;} break; case 160: -#line 970 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 972 "../css/CSSGrammar.y" { CSSParser* p = static_cast(parser); (yyval.selector) = p->createFloatingSelector(); @@ -3078,7 +3259,9 @@ yyreduce: break; case 161: -#line 978 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 980 "../css/CSSGrammar.y" { if ((yyvsp[(1) - (1)].string).characters[0] >= '0' && (yyvsp[(1) - (1)].string).characters[0] <= '9') { (yyval.selector) = 0; @@ -3094,7 +3277,9 @@ yyreduce: break; case 165: -#line 996 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 998 "../css/CSSGrammar.y" { CSSParser* p = static_cast(parser); (yyval.selector) = p->createFloatingSelector(); @@ -3106,7 +3291,9 @@ yyreduce: break; case 166: -#line 1007 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1009 "../css/CSSGrammar.y" { CSSParserString& str = (yyvsp[(1) - (2)].string); CSSParser* p = static_cast(parser); @@ -3118,7 +3305,9 @@ yyreduce: break; case 167: -#line 1018 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1020 "../css/CSSGrammar.y" { (yyval.selector) = static_cast(parser)->createFloatingSelector(); (yyval.selector)->setAttribute(QualifiedName(nullAtom, (yyvsp[(3) - (4)].string), nullAtom)); @@ -3127,7 +3316,9 @@ yyreduce: break; case 168: -#line 1023 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1025 "../css/CSSGrammar.y" { (yyval.selector) = static_cast(parser)->createFloatingSelector(); (yyval.selector)->setAttribute(QualifiedName(nullAtom, (yyvsp[(3) - (8)].string), nullAtom)); @@ -3137,7 +3328,9 @@ yyreduce: break; case 169: -#line 1029 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1031 "../css/CSSGrammar.y" { AtomicString namespacePrefix = (yyvsp[(3) - (5)].string); CSSParser* p = static_cast(parser); @@ -3149,7 +3342,9 @@ yyreduce: break; case 170: -#line 1037 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1039 "../css/CSSGrammar.y" { AtomicString namespacePrefix = (yyvsp[(3) - (9)].string); CSSParser* p = static_cast(parser); @@ -3162,49 +3357,63 @@ yyreduce: break; case 171: -#line 1049 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1051 "../css/CSSGrammar.y" { (yyval.integer) = CSSSelector::Exact; ;} break; case 172: -#line 1052 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1054 "../css/CSSGrammar.y" { (yyval.integer) = CSSSelector::List; ;} break; case 173: -#line 1055 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1057 "../css/CSSGrammar.y" { (yyval.integer) = CSSSelector::Hyphen; ;} break; case 174: -#line 1058 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1060 "../css/CSSGrammar.y" { (yyval.integer) = CSSSelector::Begin; ;} break; case 175: -#line 1061 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1063 "../css/CSSGrammar.y" { (yyval.integer) = CSSSelector::End; ;} break; case 176: -#line 1064 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1066 "../css/CSSGrammar.y" { (yyval.integer) = CSSSelector::Contain; ;} break; case 179: -#line 1075 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1077 "../css/CSSGrammar.y" { (yyval.selector) = static_cast(parser)->createFloatingSelector(); (yyval.selector)->m_match = CSSSelector::PseudoClass; @@ -3233,7 +3442,9 @@ yyreduce: break; case 180: -#line 1100 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1102 "../css/CSSGrammar.y" { (yyval.selector) = static_cast(parser)->createFloatingSelector(); (yyval.selector)->m_match = CSSSelector::PseudoElement; @@ -3251,7 +3462,9 @@ yyreduce: break; case 181: -#line 1115 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1117 "../css/CSSGrammar.y" { CSSParser *p = static_cast(parser); (yyval.selector) = p->createFloatingSelector(); @@ -3272,7 +3485,9 @@ yyreduce: break; case 182: -#line 1133 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1135 "../css/CSSGrammar.y" { CSSParser *p = static_cast(parser); (yyval.selector) = p->createFloatingSelector(); @@ -3293,7 +3508,9 @@ yyreduce: break; case 183: -#line 1151 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1153 "../css/CSSGrammar.y" { CSSParser *p = static_cast(parser); (yyval.selector) = p->createFloatingSelector(); @@ -3315,7 +3532,9 @@ yyreduce: break; case 184: -#line 1170 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1172 "../css/CSSGrammar.y" { if (!(yyvsp[(4) - (6)].selector)) (yyval.selector) = 0; @@ -3331,14 +3550,18 @@ yyreduce: break; case 185: -#line 1185 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1187 "../css/CSSGrammar.y" { (yyval.boolean) = (yyvsp[(1) - (1)].boolean); ;} break; case 186: -#line 1188 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1190 "../css/CSSGrammar.y" { (yyval.boolean) = (yyvsp[(1) - (2)].boolean); if ( (yyvsp[(2) - (2)].boolean) ) @@ -3347,70 +3570,90 @@ yyreduce: break; case 187: -#line 1193 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1195 "../css/CSSGrammar.y" { (yyval.boolean) = (yyvsp[(1) - (1)].boolean); ;} break; case 188: -#line 1196 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1198 "../css/CSSGrammar.y" { (yyval.boolean) = false; ;} break; case 189: -#line 1199 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1201 "../css/CSSGrammar.y" { (yyval.boolean) = false; ;} break; case 190: -#line 1202 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1204 "../css/CSSGrammar.y" { (yyval.boolean) = (yyvsp[(1) - (2)].boolean); ;} break; case 191: -#line 1205 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1207 "../css/CSSGrammar.y" { (yyval.boolean) = (yyvsp[(1) - (2)].boolean); ;} break; case 192: -#line 1211 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1213 "../css/CSSGrammar.y" { (yyval.boolean) = (yyvsp[(1) - (3)].boolean); ;} break; case 193: -#line 1214 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1216 "../css/CSSGrammar.y" { (yyval.boolean) = false; ;} break; case 194: -#line 1217 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1219 "../css/CSSGrammar.y" { (yyval.boolean) = false; ;} break; case 195: -#line 1220 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1222 "../css/CSSGrammar.y" { (yyval.boolean) = false; ;} break; case 196: -#line 1223 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1225 "../css/CSSGrammar.y" { (yyval.boolean) = (yyvsp[(1) - (4)].boolean); if ((yyvsp[(2) - (4)].boolean)) @@ -3419,21 +3662,27 @@ yyreduce: break; case 197: -#line 1228 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1230 "../css/CSSGrammar.y" { (yyval.boolean) = (yyvsp[(1) - (4)].boolean); ;} break; case 198: -#line 1231 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1233 "../css/CSSGrammar.y" { (yyval.boolean) = (yyvsp[(1) - (6)].boolean); ;} break; case 199: -#line 1237 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1239 "../css/CSSGrammar.y" { (yyval.boolean) = false; CSSParser* p = static_cast(parser); @@ -3450,7 +3699,9 @@ yyreduce: break; case 200: -#line 1251 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1253 "../css/CSSGrammar.y" { CSSParser* p = static_cast(parser); p->m_valueList = new CSSParserValueList; @@ -3465,14 +3716,18 @@ yyreduce: break; case 201: -#line 1263 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1265 "../css/CSSGrammar.y" { (yyval.boolean) = false; ;} break; case 202: -#line 1267 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1269 "../css/CSSGrammar.y" { /* The default movable type template has letter-spacing: .none; Handle this by looking for error tokens at the start of an expr, recover the expr and then treat as an error, cleaning @@ -3482,7 +3737,9 @@ yyreduce: break; case 203: -#line 1274 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1276 "../css/CSSGrammar.y" { /* When we encounter something like p {color: red !important fail;} we should drop the declaration */ (yyval.boolean) = false; @@ -3490,7 +3747,9 @@ yyreduce: break; case 204: -#line 1279 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1281 "../css/CSSGrammar.y" { /* Handle this case: div { text-align: center; !important } Just reduce away the stray !important. */ (yyval.boolean) = false; @@ -3498,7 +3757,9 @@ yyreduce: break; case 205: -#line 1284 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1286 "../css/CSSGrammar.y" { /* div { font-family: } Just reduce away this property with no value. */ (yyval.boolean) = false; @@ -3506,7 +3767,9 @@ yyreduce: break; case 206: -#line 1289 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1291 "../css/CSSGrammar.y" { /* if we come across rules with invalid values like this case: p { weight: *; }, just discard the rule */ (yyval.boolean) = false; @@ -3514,7 +3777,9 @@ yyreduce: break; case 207: -#line 1294 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1296 "../css/CSSGrammar.y" { /* if we come across: div { color{;color:maroon} }, ignore everything within curly brackets */ (yyval.boolean) = false; @@ -3522,24 +3787,32 @@ yyreduce: break; case 208: -#line 1301 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1303 "../css/CSSGrammar.y" { (yyval.integer) = cssPropertyID((yyvsp[(1) - (2)].string)); ;} break; case 209: -#line 1307 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1309 "../css/CSSGrammar.y" { (yyval.boolean) = true; ;} break; case 210: -#line 1308 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1310 "../css/CSSGrammar.y" { (yyval.boolean) = false; ;} break; case 211: -#line 1312 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1314 "../css/CSSGrammar.y" { CSSParser* p = static_cast(parser); (yyval.valueList) = p->createFloatingValueList(); @@ -3548,7 +3821,9 @@ yyreduce: break; case 212: -#line 1317 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1319 "../css/CSSGrammar.y" { CSSParser* p = static_cast(parser); (yyval.valueList) = (yyvsp[(1) - (3)].valueList); @@ -3566,50 +3841,66 @@ yyreduce: break; case 213: -#line 1331 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1333 "../css/CSSGrammar.y" { (yyval.valueList) = 0; ;} break; case 214: -#line 1337 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1339 "../css/CSSGrammar.y" { (yyval.character) = '/'; ;} break; case 215: -#line 1340 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1342 "../css/CSSGrammar.y" { (yyval.character) = ','; ;} break; case 216: -#line 1343 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1345 "../css/CSSGrammar.y" { (yyval.character) = 0; ;} break; case 217: -#line 1349 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1351 "../css/CSSGrammar.y" { (yyval.value) = (yyvsp[(1) - (1)].value); ;} break; case 218: -#line 1350 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1352 "../css/CSSGrammar.y" { (yyval.value) = (yyvsp[(2) - (2)].value); (yyval.value).fValue *= (yyvsp[(1) - (2)].integer); ;} break; case 219: -#line 1351 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1353 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).string = (yyvsp[(1) - (2)].string); (yyval.value).unit = CSSPrimitiveValue::CSS_STRING; ;} break; case 220: -#line 1352 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1354 "../css/CSSGrammar.y" { (yyval.value).id = cssValueKeywordID((yyvsp[(1) - (2)].string)); (yyval.value).unit = CSSPrimitiveValue::CSS_IDENT; @@ -3618,156 +3909,216 @@ yyreduce: break; case 221: -#line 1358 "../css/CSSGrammar.y" - { (yyval.value).id = 0; (yyval.value).string = (yyvsp[(1) - (2)].string); (yyval.value).unit = CSSPrimitiveValue::CSS_DIMENSION ;} + +/* Line 1455 of yacc.c */ +#line 1360 "../css/CSSGrammar.y" + { (yyval.value).id = 0; (yyval.value).string = (yyvsp[(1) - (2)].string); (yyval.value).unit = CSSPrimitiveValue::CSS_DIMENSION; ;} break; case 222: -#line 1359 "../css/CSSGrammar.y" - { (yyval.value).id = 0; (yyval.value).string = (yyvsp[(2) - (3)].string); (yyval.value).unit = CSSPrimitiveValue::CSS_DIMENSION ;} + +/* Line 1455 of yacc.c */ +#line 1361 "../css/CSSGrammar.y" + { (yyval.value).id = 0; (yyval.value).string = (yyvsp[(2) - (3)].string); (yyval.value).unit = CSSPrimitiveValue::CSS_DIMENSION; ;} break; case 223: -#line 1360 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1362 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).string = (yyvsp[(1) - (2)].string); (yyval.value).unit = CSSPrimitiveValue::CSS_URI; ;} break; case 224: -#line 1361 "../css/CSSGrammar.y" - { (yyval.value).id = 0; (yyval.value).string = (yyvsp[(1) - (2)].string); (yyval.value).unit = CSSPrimitiveValue::CSS_UNICODE_RANGE ;} + +/* Line 1455 of yacc.c */ +#line 1363 "../css/CSSGrammar.y" + { (yyval.value).id = 0; (yyval.value).string = (yyvsp[(1) - (2)].string); (yyval.value).unit = CSSPrimitiveValue::CSS_UNICODE_RANGE; ;} break; case 225: -#line 1362 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1364 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).string = (yyvsp[(1) - (1)].string); (yyval.value).unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; ;} break; case 226: -#line 1363 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1365 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).string = CSSParserString(); (yyval.value).unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; ;} break; case 227: -#line 1365 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1367 "../css/CSSGrammar.y" { (yyval.value) = (yyvsp[(1) - (1)].value); ;} break; case 228: -#line 1368 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1370 "../css/CSSGrammar.y" { (yyval.value) = (yyvsp[(1) - (2)].value); ;} break; case 229: -#line 1371 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1373 "../css/CSSGrammar.y" {;} break; case 230: -#line 1375 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1377 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).isInt = true; (yyval.value).fValue = (yyvsp[(1) - (2)].number); (yyval.value).unit = CSSPrimitiveValue::CSS_NUMBER; ;} break; case 231: -#line 1376 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1378 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).isInt = false; (yyval.value).fValue = (yyvsp[(1) - (2)].number); (yyval.value).unit = CSSPrimitiveValue::CSS_NUMBER; ;} break; case 232: -#line 1377 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1379 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).fValue = (yyvsp[(1) - (2)].number); (yyval.value).unit = CSSPrimitiveValue::CSS_PERCENTAGE; ;} break; case 233: -#line 1378 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1380 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).fValue = (yyvsp[(1) - (2)].number); (yyval.value).unit = CSSPrimitiveValue::CSS_PX; ;} break; case 234: -#line 1379 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1381 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).fValue = (yyvsp[(1) - (2)].number); (yyval.value).unit = CSSPrimitiveValue::CSS_CM; ;} break; case 235: -#line 1380 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1382 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).fValue = (yyvsp[(1) - (2)].number); (yyval.value).unit = CSSPrimitiveValue::CSS_MM; ;} break; case 236: -#line 1381 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1383 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).fValue = (yyvsp[(1) - (2)].number); (yyval.value).unit = CSSPrimitiveValue::CSS_IN; ;} break; case 237: -#line 1382 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1384 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).fValue = (yyvsp[(1) - (2)].number); (yyval.value).unit = CSSPrimitiveValue::CSS_PT; ;} break; case 238: -#line 1383 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1385 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).fValue = (yyvsp[(1) - (2)].number); (yyval.value).unit = CSSPrimitiveValue::CSS_PC; ;} break; case 239: -#line 1384 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1386 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).fValue = (yyvsp[(1) - (2)].number); (yyval.value).unit = CSSPrimitiveValue::CSS_DEG; ;} break; case 240: -#line 1385 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1387 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).fValue = (yyvsp[(1) - (2)].number); (yyval.value).unit = CSSPrimitiveValue::CSS_RAD; ;} break; case 241: -#line 1386 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1388 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).fValue = (yyvsp[(1) - (2)].number); (yyval.value).unit = CSSPrimitiveValue::CSS_GRAD; ;} break; case 242: -#line 1387 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1389 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).fValue = (yyvsp[(1) - (2)].number); (yyval.value).unit = CSSPrimitiveValue::CSS_TURN; ;} break; case 243: -#line 1388 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1390 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).fValue = (yyvsp[(1) - (2)].number); (yyval.value).unit = CSSPrimitiveValue::CSS_MS; ;} break; case 244: -#line 1389 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1391 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).fValue = (yyvsp[(1) - (2)].number); (yyval.value).unit = CSSPrimitiveValue::CSS_S; ;} break; case 245: -#line 1390 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1392 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).fValue = (yyvsp[(1) - (2)].number); (yyval.value).unit = CSSPrimitiveValue::CSS_HZ; ;} break; case 246: -#line 1391 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1393 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).fValue = (yyvsp[(1) - (2)].number); (yyval.value).unit = CSSPrimitiveValue::CSS_KHZ; ;} break; case 247: -#line 1392 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1394 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).fValue = (yyvsp[(1) - (2)].number); (yyval.value).unit = CSSPrimitiveValue::CSS_EMS; ;} break; case 248: -#line 1393 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1395 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).fValue = (yyvsp[(1) - (2)].number); (yyval.value).unit = CSSParserValue::Q_EMS; ;} break; case 249: -#line 1394 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1396 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).fValue = (yyvsp[(1) - (2)].number); (yyval.value).unit = CSSPrimitiveValue::CSS_EXS; ;} break; case 250: -#line 1398 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1400 "../css/CSSGrammar.y" { (yyval.value).id = 0; (yyval.value).string = (yyvsp[(1) - (1)].string); @@ -3776,7 +4127,9 @@ yyreduce: break; case 251: -#line 1406 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1408 "../css/CSSGrammar.y" { CSSParser* p = static_cast(parser); CSSParserFunction* f = p->createFloatingFunction(); @@ -3789,7 +4142,9 @@ yyreduce: break; case 252: -#line 1415 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1417 "../css/CSSGrammar.y" { CSSParser* p = static_cast(parser); CSSParserFunction* f = p->createFloatingFunction(); @@ -3802,67 +4157,86 @@ yyreduce: break; case 253: -#line 1431 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1433 "../css/CSSGrammar.y" { (yyval.string) = (yyvsp[(1) - (2)].string); ;} break; case 254: -#line 1432 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1434 "../css/CSSGrammar.y" { (yyval.string) = (yyvsp[(1) - (2)].string); ;} break; case 255: -#line 1439 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1441 "../css/CSSGrammar.y" { (yyval.rule) = 0; ;} break; case 256: -#line 1442 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1444 "../css/CSSGrammar.y" { (yyval.rule) = 0; ;} break; case 257: -#line 1448 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1450 "../css/CSSGrammar.y" { (yyval.rule) = 0; ;} break; case 258: -#line 1451 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1453 "../css/CSSGrammar.y" { (yyval.rule) = 0; ;} break; case 261: -#line 1462 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1464 "../css/CSSGrammar.y" { (yyval.rule) = 0; ;} break; case 262: -#line 1468 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1470 "../css/CSSGrammar.y" { (yyval.rule) = 0; ;} break; case 263: -#line 1474 "../css/CSSGrammar.y" + +/* Line 1455 of yacc.c */ +#line 1476 "../css/CSSGrammar.y" { (yyval.rule) = 0; ;} break; -/* Line 1267 of yacc.c. */ -#line 3866 "WebCore/tmp/../generated/CSSGrammar.tab.c" + +/* Line 1455 of yacc.c */ +#line 4240 "WebCore/tmp/../generated/CSSGrammar.tab.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -3873,7 +4247,6 @@ yyreduce: *++yyvsp = yyval; - /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ @@ -3938,7 +4311,7 @@ yyerrlab: if (yyerrstatus == 3) { - /* If just tried and failed to reuse look-ahead token after an + /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) @@ -3955,7 +4328,7 @@ yyerrlab: } } - /* Else will try to reuse look-ahead token after shifting the error + /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; @@ -4012,9 +4385,6 @@ yyerrlab1: YY_STACK_PRINT (yyss, yyssp); } - if (yyn == YYFINAL) - YYACCEPT; - *++yyvsp = yylval; @@ -4039,7 +4409,7 @@ yyabortlab: yyresult = 1; goto yyreturn; -#ifndef yyoverflow +#if !defined(yyoverflow) || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ @@ -4050,7 +4420,7 @@ yyexhaustedlab: #endif yyreturn: - if (yychar != YYEOF && yychar != YYEMPTY) + if (yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval); /* Do not reclaim the symbols of the rule which action triggered @@ -4076,6 +4446,8 @@ yyreturn: } -#line 1501 "../css/CSSGrammar.y" + +/* Line 1675 of yacc.c */ +#line 1503 "../css/CSSGrammar.y" diff --git a/src/3rdparty/webkit/WebCore/generated/CSSGrammar.h b/src/3rdparty/webkit/WebCore/generated/CSSGrammar.h index 1b60c68..84ad511 100644 --- a/src/3rdparty/webkit/WebCore/generated/CSSGrammar.h +++ b/src/3rdparty/webkit/WebCore/generated/CSSGrammar.h @@ -1,26 +1,25 @@ #ifndef CSSGRAMMAR_H #define CSSGRAMMAR_H -/* A Bison parser, made by GNU Bison 2.3. */ -/* Skeleton interface for Bison's Yacc-like parsers in C +/* A Bison parser, made by GNU Bison 2.4.1. */ - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +/* Skeleton interface for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -31,10 +30,11 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ + /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE @@ -42,140 +42,80 @@ know about them. */ enum yytokentype { TOKEN_EOF = 0, - UNIMPORTANT_TOK = 258, - WHITESPACE = 259, - SGML_CD = 260, - INCLUDES = 261, - DASHMATCH = 262, - BEGINSWITH = 263, - ENDSWITH = 264, - CONTAINS = 265, - STRING = 266, - IDENT = 267, - NTH = 268, - HEX = 269, - IDSEL = 270, - IMPORT_SYM = 271, - PAGE_SYM = 272, - MEDIA_SYM = 273, - FONT_FACE_SYM = 274, - CHARSET_SYM = 275, - NAMESPACE_SYM = 276, - WEBKIT_RULE_SYM = 277, - WEBKIT_DECLS_SYM = 278, - WEBKIT_KEYFRAME_RULE_SYM = 279, - WEBKIT_KEYFRAMES_SYM = 280, - WEBKIT_VALUE_SYM = 281, - WEBKIT_MEDIAQUERY_SYM = 282, - WEBKIT_SELECTOR_SYM = 283, - WEBKIT_VARIABLES_SYM = 284, - WEBKIT_DEFINE_SYM = 285, - VARIABLES_FOR = 286, - WEBKIT_VARIABLES_DECLS_SYM = 287, - ATKEYWORD = 288, - IMPORTANT_SYM = 289, - MEDIA_ONLY = 290, - MEDIA_NOT = 291, - MEDIA_AND = 292, - QEMS = 293, - EMS = 294, - EXS = 295, - PXS = 296, - CMS = 297, - MMS = 298, - INS = 299, - PTS = 300, - PCS = 301, - DEGS = 302, - RADS = 303, - GRADS = 304, - TURNS = 305, - MSECS = 306, - SECS = 307, - HERZ = 308, - KHERZ = 309, - DIMEN = 310, - PERCENTAGE = 311, - FLOATTOKEN = 312, - INTEGER = 313, - URI = 314, - FUNCTION = 315, - NOTFUNCTION = 316, - UNICODERANGE = 317, - VARCALL = 318 + LOWEST_PREC = 258, + UNIMPORTANT_TOK = 259, + WHITESPACE = 260, + SGML_CD = 261, + INCLUDES = 262, + DASHMATCH = 263, + BEGINSWITH = 264, + ENDSWITH = 265, + CONTAINS = 266, + STRING = 267, + IDENT = 268, + NTH = 269, + HEX = 270, + IDSEL = 271, + IMPORT_SYM = 272, + PAGE_SYM = 273, + MEDIA_SYM = 274, + FONT_FACE_SYM = 275, + CHARSET_SYM = 276, + NAMESPACE_SYM = 277, + WEBKIT_RULE_SYM = 278, + WEBKIT_DECLS_SYM = 279, + WEBKIT_KEYFRAME_RULE_SYM = 280, + WEBKIT_KEYFRAMES_SYM = 281, + WEBKIT_VALUE_SYM = 282, + WEBKIT_MEDIAQUERY_SYM = 283, + WEBKIT_SELECTOR_SYM = 284, + WEBKIT_VARIABLES_SYM = 285, + WEBKIT_DEFINE_SYM = 286, + VARIABLES_FOR = 287, + WEBKIT_VARIABLES_DECLS_SYM = 288, + ATKEYWORD = 289, + IMPORTANT_SYM = 290, + MEDIA_ONLY = 291, + MEDIA_NOT = 292, + MEDIA_AND = 293, + QEMS = 294, + EMS = 295, + EXS = 296, + PXS = 297, + CMS = 298, + MMS = 299, + INS = 300, + PTS = 301, + PCS = 302, + DEGS = 303, + RADS = 304, + GRADS = 305, + TURNS = 306, + MSECS = 307, + SECS = 308, + HERZ = 309, + KHERZ = 310, + DIMEN = 311, + PERCENTAGE = 312, + FLOATTOKEN = 313, + INTEGER = 314, + URI = 315, + FUNCTION = 316, + NOTFUNCTION = 317, + UNICODERANGE = 318, + VARCALL = 319 }; #endif -/* Tokens. */ -#define TOKEN_EOF 0 -#define UNIMPORTANT_TOK 258 -#define WHITESPACE 259 -#define SGML_CD 260 -#define INCLUDES 261 -#define DASHMATCH 262 -#define BEGINSWITH 263 -#define ENDSWITH 264 -#define CONTAINS 265 -#define STRING 266 -#define IDENT 267 -#define NTH 268 -#define HEX 269 -#define IDSEL 270 -#define IMPORT_SYM 271 -#define PAGE_SYM 272 -#define MEDIA_SYM 273 -#define FONT_FACE_SYM 274 -#define CHARSET_SYM 275 -#define NAMESPACE_SYM 276 -#define WEBKIT_RULE_SYM 277 -#define WEBKIT_DECLS_SYM 278 -#define WEBKIT_KEYFRAME_RULE_SYM 279 -#define WEBKIT_KEYFRAMES_SYM 280 -#define WEBKIT_VALUE_SYM 281 -#define WEBKIT_MEDIAQUERY_SYM 282 -#define WEBKIT_SELECTOR_SYM 283 -#define WEBKIT_VARIABLES_SYM 284 -#define WEBKIT_DEFINE_SYM 285 -#define VARIABLES_FOR 286 -#define WEBKIT_VARIABLES_DECLS_SYM 287 -#define ATKEYWORD 288 -#define IMPORTANT_SYM 289 -#define MEDIA_ONLY 290 -#define MEDIA_NOT 291 -#define MEDIA_AND 292 -#define QEMS 293 -#define EMS 294 -#define EXS 295 -#define PXS 296 -#define CMS 297 -#define MMS 298 -#define INS 299 -#define PTS 300 -#define PCS 301 -#define DEGS 302 -#define RADS 303 -#define GRADS 304 -#define TURNS 305 -#define MSECS 306 -#define SECS 307 -#define HERZ 308 -#define KHERZ 309 -#define DIMEN 310 -#define PERCENTAGE 311 -#define FLOATTOKEN 312 -#define INTEGER 313 -#define URI 314 -#define FUNCTION 315 -#define NOTFUNCTION 316 -#define UNICODERANGE 317 -#define VARCALL 318 - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 57 "../css/CSSGrammar.y" { + +/* Line 1676 of yacc.c */ +#line 57 "../css/CSSGrammar.y" + bool boolean; char character; int integer; @@ -197,15 +137,18 @@ typedef union YYSTYPE WebKitCSSKeyframeRule* keyframeRule; WebKitCSSKeyframesRule* keyframesRule; float val; -} -/* Line 1489 of yacc.c. */ -#line 201 "WebCore/tmp/../generated/CSSGrammar.tab.h" - YYSTYPE; + + + +/* Line 1676 of yacc.c */ +#line 143 "WebCore/tmp/../generated/CSSGrammar.tab.h" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 #endif + #endif diff --git a/src/3rdparty/webkit/WebCore/generated/Grammar.cpp b/src/3rdparty/webkit/WebCore/generated/Grammar.cpp index 6f09be8..fd20f69 100644 --- a/src/3rdparty/webkit/WebCore/generated/Grammar.cpp +++ b/src/3rdparty/webkit/WebCore/generated/Grammar.cpp @@ -1,24 +1,23 @@ -/* A Bison parser, made by GNU Bison 2.3. */ -/* Skeleton implementation for Bison's Yacc-like parsers in C +/* A Bison parser, made by GNU Bison 2.4.1. */ - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -29,7 +28,7 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ @@ -47,7 +46,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.3" +#define YYBISON_VERSION "2.4.1" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -55,159 +54,28 @@ /* Pure parsers. */ #define YYPURE 1 +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + /* Using locations. */ #define YYLSP_NEEDED 1 /* Substitute the variable and function names. */ -#define yyparse jscyyparse -#define yylex jscyylex -#define yyerror jscyyerror -#define yylval jscyylval -#define yychar jscyychar -#define yydebug jscyydebug -#define yynerrs jscyynerrs -#define yylloc jscyylloc - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - NULLTOKEN = 258, - TRUETOKEN = 259, - FALSETOKEN = 260, - BREAK = 261, - CASE = 262, - DEFAULT = 263, - FOR = 264, - NEW = 265, - VAR = 266, - CONSTTOKEN = 267, - CONTINUE = 268, - FUNCTION = 269, - RETURN = 270, - VOIDTOKEN = 271, - DELETETOKEN = 272, - IF = 273, - THISTOKEN = 274, - DO = 275, - WHILE = 276, - INTOKEN = 277, - INSTANCEOF = 278, - TYPEOF = 279, - SWITCH = 280, - WITH = 281, - RESERVED = 282, - THROW = 283, - TRY = 284, - CATCH = 285, - FINALLY = 286, - DEBUGGER = 287, - IF_WITHOUT_ELSE = 288, - ELSE = 289, - EQEQ = 290, - NE = 291, - STREQ = 292, - STRNEQ = 293, - LE = 294, - GE = 295, - OR = 296, - AND = 297, - PLUSPLUS = 298, - MINUSMINUS = 299, - LSHIFT = 300, - RSHIFT = 301, - URSHIFT = 302, - PLUSEQUAL = 303, - MINUSEQUAL = 304, - MULTEQUAL = 305, - DIVEQUAL = 306, - LSHIFTEQUAL = 307, - RSHIFTEQUAL = 308, - URSHIFTEQUAL = 309, - ANDEQUAL = 310, - MODEQUAL = 311, - XOREQUAL = 312, - OREQUAL = 313, - OPENBRACE = 314, - CLOSEBRACE = 315, - NUMBER = 316, - IDENT = 317, - STRING = 318, - AUTOPLUSPLUS = 319, - AUTOMINUSMINUS = 320 - }; -#endif -/* Tokens. */ -#define NULLTOKEN 258 -#define TRUETOKEN 259 -#define FALSETOKEN 260 -#define BREAK 261 -#define CASE 262 -#define DEFAULT 263 -#define FOR 264 -#define NEW 265 -#define VAR 266 -#define CONSTTOKEN 267 -#define CONTINUE 268 -#define FUNCTION 269 -#define RETURN 270 -#define VOIDTOKEN 271 -#define DELETETOKEN 272 -#define IF 273 -#define THISTOKEN 274 -#define DO 275 -#define WHILE 276 -#define INTOKEN 277 -#define INSTANCEOF 278 -#define TYPEOF 279 -#define SWITCH 280 -#define WITH 281 -#define RESERVED 282 -#define THROW 283 -#define TRY 284 -#define CATCH 285 -#define FINALLY 286 -#define DEBUGGER 287 -#define IF_WITHOUT_ELSE 288 -#define ELSE 289 -#define EQEQ 290 -#define NE 291 -#define STREQ 292 -#define STRNEQ 293 -#define LE 294 -#define GE 295 -#define OR 296 -#define AND 297 -#define PLUSPLUS 298 -#define MINUSMINUS 299 -#define LSHIFT 300 -#define RSHIFT 301 -#define URSHIFT 302 -#define PLUSEQUAL 303 -#define MINUSEQUAL 304 -#define MULTEQUAL 305 -#define DIVEQUAL 306 -#define LSHIFTEQUAL 307 -#define RSHIFTEQUAL 308 -#define URSHIFTEQUAL 309 -#define ANDEQUAL 310 -#define MODEQUAL 311 -#define XOREQUAL 312 -#define OREQUAL 313 -#define OPENBRACE 314 -#define CLOSEBRACE 315 -#define NUMBER 316 -#define IDENT 317 -#define STRING 318 -#define AUTOPLUSPLUS 319 -#define AUTOMINUSMINUS 320 - - - +#define yyparse jscyyparse +#define yylex jscyylex +#define yyerror jscyyerror +#define yylval jscyylval +#define yychar jscyychar +#define yydebug jscyydebug +#define yynerrs jscyynerrs +#define yylloc jscyylloc /* Copy the first part of user declarations. */ + +/* Line 189 of yacc.c */ #line 3 "../../JavaScriptCore/parser/Grammar.y" @@ -363,6 +231,9 @@ static inline void appendToVarDeclarationList(void* globalPtr, ParserRefCountedD +/* Line 189 of yacc.c */ +#line 236 "Grammar.tab.c" + /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -381,10 +252,88 @@ static inline void appendToVarDeclarationList(void* globalPtr, ParserRefCountedD # define YYTOKEN_TABLE 0 #endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + NULLTOKEN = 258, + TRUETOKEN = 259, + FALSETOKEN = 260, + BREAK = 261, + CASE = 262, + DEFAULT = 263, + FOR = 264, + NEW = 265, + VAR = 266, + CONSTTOKEN = 267, + CONTINUE = 268, + FUNCTION = 269, + RETURN = 270, + VOIDTOKEN = 271, + DELETETOKEN = 272, + IF = 273, + THISTOKEN = 274, + DO = 275, + WHILE = 276, + INTOKEN = 277, + INSTANCEOF = 278, + TYPEOF = 279, + SWITCH = 280, + WITH = 281, + RESERVED = 282, + THROW = 283, + TRY = 284, + CATCH = 285, + FINALLY = 286, + DEBUGGER = 287, + IF_WITHOUT_ELSE = 288, + ELSE = 289, + EQEQ = 290, + NE = 291, + STREQ = 292, + STRNEQ = 293, + LE = 294, + GE = 295, + OR = 296, + AND = 297, + PLUSPLUS = 298, + MINUSMINUS = 299, + LSHIFT = 300, + RSHIFT = 301, + URSHIFT = 302, + PLUSEQUAL = 303, + MINUSEQUAL = 304, + MULTEQUAL = 305, + DIVEQUAL = 306, + LSHIFTEQUAL = 307, + RSHIFTEQUAL = 308, + URSHIFTEQUAL = 309, + ANDEQUAL = 310, + MODEQUAL = 311, + XOREQUAL = 312, + OREQUAL = 313, + OPENBRACE = 314, + CLOSEBRACE = 315, + NUMBER = 316, + IDENT = 317, + STRING = 318, + AUTOPLUSPLUS = 319, + AUTOMINUSMINUS = 320 + }; +#endif + + + #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 157 "../../JavaScriptCore/parser/Grammar.y" { + +/* Line 214 of yacc.c */ +#line 157 "../../JavaScriptCore/parser/Grammar.y" + int intValue; double doubleValue; Identifier* ident; @@ -414,13 +363,15 @@ typedef union YYSTYPE ParameterListInfo parameterList; Operator op; -} -/* Line 187 of yacc.c. */ -#line 420 "Grammar.tab.c" - YYSTYPE; + + + +/* Line 214 of yacc.c */ +#line 371 "Grammar.tab.c" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 #endif #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED @@ -440,8 +391,8 @@ typedef struct YYLTYPE /* Copy the second part of user declarations. */ -/* Line 216 of yacc.c. */ -#line 445 "Grammar.tab.c" +/* Line 264 of yacc.c */ +#line 396 "Grammar.tab.c" #ifdef short # undef short @@ -516,14 +467,14 @@ typedef short int yytype_int16; #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int -YYID (int i) +YYID (int yyi) #else static int -YYID (i) - int i; +YYID (yyi) + int yyi; #endif { - return i; + return yyi; } #endif @@ -605,9 +556,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ /* A type that is properly aligned for any stack member. */ union yyalloc { - yytype_int16 yyss; - YYSTYPE yyvs; - YYLTYPE yyls; + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; + YYLTYPE yyls_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ @@ -642,12 +593,12 @@ union yyalloc elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ -# define YYSTACK_RELOCATE(Stack) \ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ @@ -2361,17 +2312,20 @@ yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp) #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) #else static void -yy_stack_print (bottom, top) - yytype_int16 *bottom; - yytype_int16 *top; +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; #endif { YYFPRINTF (stderr, "Stack now"); - for (; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } YYFPRINTF (stderr, "\n"); } @@ -2406,11 +2360,11 @@ yy_reduce_print (yyvsp, yylsp, yyrule) /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { - fprintf (stderr, " $%d = ", yyi + 1); + YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) , &(yylsp[(yyi + 1) - (yynrhs)]) ); - fprintf (stderr, "\n"); + YYFPRINTF (stderr, "\n"); } } @@ -2692,10 +2646,8 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp) break; } } - /* Prevent warnings from -Wmissing-prototypes. */ - #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); @@ -2714,10 +2666,9 @@ int yyparse (); - -/*----------. -| yyparse. | -`----------*/ +/*-------------------------. +| yyparse or yypush_parse. | +`-------------------------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ @@ -2741,88 +2692,97 @@ yyparse () #endif #endif { - /* The look-ahead symbol. */ +/* The lookahead symbol. */ int yychar; -/* The semantic value of the look-ahead symbol. */ +/* The semantic value of the lookahead symbol. */ YYSTYPE yylval; -/* Number of syntax errors so far. */ -int yynerrs; -/* Location data for the look-ahead symbol. */ +/* Location data for the lookahead symbol. */ YYLTYPE yylloc; - int yystate; - int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Look-ahead token as an internal (translated) token number. */ - int yytoken = 0; -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif + /* Number of syntax errors so far. */ + int yynerrs; - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + `yyls': related to locations. - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss = yyssa; - yytype_int16 *yyssp; + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp; + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; - /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[2]; + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) + /* The location stack. */ + YYLTYPE yylsa[YYINITDEPTH]; + YYLTYPE *yyls; + YYLTYPE *yylsp; + + /* The locations where the error started and ended. */ + YYLTYPE yyerror_range[2]; - YYSIZE_T yystacksize = YYINITDEPTH; + YYSIZE_T yystacksize; + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; YYLTYPE yyloc; +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) + /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yyls = yylsa; + yystacksize = YYINITDEPTH; + YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ + yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ - yyssp = yyss; yyvsp = yyvs; yylsp = yyls; + #if YYLTYPE_IS_TRIVIAL /* Initialize the default location before parsing starts. */ yylloc.first_line = yylloc.last_line = 1; - yylloc.first_column = yylloc.last_column = 0; + yylloc.first_column = yylloc.last_column = 1; #endif goto yysetstate; @@ -2861,6 +2821,7 @@ YYLTYPE yylloc; &yyvs1, yysize * sizeof (*yyvsp), &yyls1, yysize * sizeof (*yylsp), &yystacksize); + yyls = yyls1; yyss = yyss1; yyvs = yyvs1; @@ -2882,9 +2843,9 @@ YYLTYPE yylloc; (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - YYSTACK_RELOCATE (yyls); + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); + YYSTACK_RELOCATE (yyls_alloc, yyls); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); @@ -2905,6 +2866,9 @@ YYLTYPE yylloc; YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + if (yystate == YYFINAL) + YYACCEPT; + goto yybackup; /*-----------. @@ -2913,16 +2877,16 @@ YYLTYPE yylloc; yybackup: /* Do appropriate processing given the current state. Read a - look-ahead token if we need one and don't already have one. */ + lookahead token if we need one and don't already have one. */ - /* First try to decide what to do without reference to look-ahead token. */ + /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; - /* Not known => get a look-ahead token if don't already have one. */ + /* Not known => get a lookahead token if don't already have one. */ - /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); @@ -2954,20 +2918,16 @@ yybackup: goto yyreduce; } - if (yyn == YYFINAL) - YYACCEPT; - /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; - /* Shift the look-ahead token. */ + /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - /* Discard the shifted token unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; + /* Discard the shifted token. */ + yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; @@ -3008,31 +2968,43 @@ yyreduce: switch (yyn) { case 2: + +/* Line 1455 of yacc.c */ #line 290 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new NullNode(GLOBAL_DATA), 0, 1); ;} break; case 3: + +/* Line 1455 of yacc.c */ #line 291 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new BooleanNode(GLOBAL_DATA, true), 0, 1); ;} break; case 4: + +/* Line 1455 of yacc.c */ #line 292 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new BooleanNode(GLOBAL_DATA, false), 0, 1); ;} break; case 5: + +/* Line 1455 of yacc.c */ #line 293 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeNumberNode(GLOBAL_DATA, (yyvsp[(1) - (1)].doubleValue)), 0, 1); ;} break; case 6: + +/* Line 1455 of yacc.c */ #line 294 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new StringNode(GLOBAL_DATA, *(yyvsp[(1) - (1)].ident)), 0, 1); ;} break; case 7: + +/* Line 1455 of yacc.c */ #line 295 "../../JavaScriptCore/parser/Grammar.y" { Lexer& l = *LEXER; @@ -3046,6 +3018,8 @@ yyreduce: break; case 8: + +/* Line 1455 of yacc.c */ #line 304 "../../JavaScriptCore/parser/Grammar.y" { Lexer& l = *LEXER; @@ -3059,26 +3033,36 @@ yyreduce: break; case 9: + +/* Line 1455 of yacc.c */ #line 316 "../../JavaScriptCore/parser/Grammar.y" { (yyval.propertyNode) = createNodeInfo(new PropertyNode(GLOBAL_DATA, *(yyvsp[(1) - (3)].ident), (yyvsp[(3) - (3)].expressionNode).m_node, PropertyNode::Constant), (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 10: + +/* Line 1455 of yacc.c */ #line 317 "../../JavaScriptCore/parser/Grammar.y" { (yyval.propertyNode) = createNodeInfo(new PropertyNode(GLOBAL_DATA, *(yyvsp[(1) - (3)].ident), (yyvsp[(3) - (3)].expressionNode).m_node, PropertyNode::Constant), (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 11: + +/* Line 1455 of yacc.c */ #line 318 "../../JavaScriptCore/parser/Grammar.y" { (yyval.propertyNode) = createNodeInfo(new PropertyNode(GLOBAL_DATA, Identifier(GLOBAL_DATA, UString::from((yyvsp[(1) - (3)].doubleValue))), (yyvsp[(3) - (3)].expressionNode).m_node, PropertyNode::Constant), (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 12: + +/* Line 1455 of yacc.c */ #line 319 "../../JavaScriptCore/parser/Grammar.y" { (yyval.propertyNode) = createNodeInfo(makeGetterOrSetterPropertyNode(globalPtr, *(yyvsp[(1) - (7)].ident), *(yyvsp[(2) - (7)].ident), 0, (yyvsp[(6) - (7)].functionBodyNode), LEXER->sourceCode((yyvsp[(5) - (7)].intValue), (yyvsp[(7) - (7)].intValue), (yylsp[(5) - (7)]).first_line)), ClosureFeature, 0); DBG((yyvsp[(6) - (7)].functionBodyNode), (yylsp[(5) - (7)]), (yylsp[(7) - (7)])); if (!(yyval.propertyNode).m_node) YYABORT; ;} break; case 13: + +/* Line 1455 of yacc.c */ #line 321 "../../JavaScriptCore/parser/Grammar.y" { (yyval.propertyNode) = createNodeInfo(makeGetterOrSetterPropertyNode(globalPtr, *(yyvsp[(1) - (8)].ident), *(yyvsp[(2) - (8)].ident), (yyvsp[(4) - (8)].parameterList).m_node.head, (yyvsp[(7) - (8)].functionBodyNode), LEXER->sourceCode((yyvsp[(6) - (8)].intValue), (yyvsp[(8) - (8)].intValue), (yylsp[(6) - (8)]).first_line)), (yyvsp[(4) - (8)].parameterList).m_features | ClosureFeature, 0); @@ -3091,6 +3075,8 @@ yyreduce: break; case 14: + +/* Line 1455 of yacc.c */ #line 332 "../../JavaScriptCore/parser/Grammar.y" { (yyval.propertyList).m_node.head = new PropertyListNode(GLOBAL_DATA, (yyvsp[(1) - (1)].propertyNode).m_node); (yyval.propertyList).m_node.tail = (yyval.propertyList).m_node.head; @@ -3099,6 +3085,8 @@ yyreduce: break; case 15: + +/* Line 1455 of yacc.c */ #line 336 "../../JavaScriptCore/parser/Grammar.y" { (yyval.propertyList).m_node.head = (yyvsp[(1) - (3)].propertyList).m_node.head; (yyval.propertyList).m_node.tail = new PropertyListNode(GLOBAL_DATA, (yyvsp[(3) - (3)].propertyNode).m_node, (yyvsp[(1) - (3)].propertyList).m_node.tail); @@ -3107,51 +3095,71 @@ yyreduce: break; case 17: + +/* Line 1455 of yacc.c */ #line 344 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ObjectLiteralNode(GLOBAL_DATA), 0, 0); ;} break; case 18: + +/* Line 1455 of yacc.c */ #line 345 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ObjectLiteralNode(GLOBAL_DATA, (yyvsp[(2) - (3)].propertyList).m_node.head), (yyvsp[(2) - (3)].propertyList).m_features, (yyvsp[(2) - (3)].propertyList).m_numConstants); ;} break; case 19: + +/* Line 1455 of yacc.c */ #line 347 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ObjectLiteralNode(GLOBAL_DATA, (yyvsp[(2) - (4)].propertyList).m_node.head), (yyvsp[(2) - (4)].propertyList).m_features, (yyvsp[(2) - (4)].propertyList).m_numConstants); ;} break; case 20: + +/* Line 1455 of yacc.c */ #line 351 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ThisNode(GLOBAL_DATA), ThisFeature, 0); ;} break; case 23: + +/* Line 1455 of yacc.c */ #line 354 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ResolveNode(GLOBAL_DATA, *(yyvsp[(1) - (1)].ident), (yylsp[(1) - (1)]).first_column), (*(yyvsp[(1) - (1)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0, 0); ;} break; case 24: + +/* Line 1455 of yacc.c */ #line 355 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = (yyvsp[(2) - (3)].expressionNode); ;} break; case 25: + +/* Line 1455 of yacc.c */ #line 359 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ArrayNode(GLOBAL_DATA, (yyvsp[(2) - (3)].intValue)), 0, (yyvsp[(2) - (3)].intValue) ? 1 : 0); ;} break; case 26: + +/* Line 1455 of yacc.c */ #line 360 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ArrayNode(GLOBAL_DATA, (yyvsp[(2) - (3)].elementList).m_node.head), (yyvsp[(2) - (3)].elementList).m_features, (yyvsp[(2) - (3)].elementList).m_numConstants); ;} break; case 27: + +/* Line 1455 of yacc.c */ #line 361 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ArrayNode(GLOBAL_DATA, (yyvsp[(4) - (5)].intValue), (yyvsp[(2) - (5)].elementList).m_node.head), (yyvsp[(2) - (5)].elementList).m_features, (yyvsp[(4) - (5)].intValue) ? (yyvsp[(2) - (5)].elementList).m_numConstants + 1 : (yyvsp[(2) - (5)].elementList).m_numConstants); ;} break; case 28: + +/* Line 1455 of yacc.c */ #line 365 "../../JavaScriptCore/parser/Grammar.y" { (yyval.elementList).m_node.head = new ElementNode(GLOBAL_DATA, (yyvsp[(1) - (2)].intValue), (yyvsp[(2) - (2)].expressionNode).m_node); (yyval.elementList).m_node.tail = (yyval.elementList).m_node.head; @@ -3160,6 +3168,8 @@ yyreduce: break; case 29: + +/* Line 1455 of yacc.c */ #line 370 "../../JavaScriptCore/parser/Grammar.y" { (yyval.elementList).m_node.head = (yyvsp[(1) - (4)].elementList).m_node.head; (yyval.elementList).m_node.tail = new ElementNode(GLOBAL_DATA, (yyvsp[(1) - (4)].elementList).m_node.tail, (yyvsp[(3) - (4)].intValue), (yyvsp[(4) - (4)].expressionNode).m_node); @@ -3168,26 +3178,36 @@ yyreduce: break; case 30: + +/* Line 1455 of yacc.c */ #line 377 "../../JavaScriptCore/parser/Grammar.y" { (yyval.intValue) = 0; ;} break; case 32: + +/* Line 1455 of yacc.c */ #line 382 "../../JavaScriptCore/parser/Grammar.y" { (yyval.intValue) = 1; ;} break; case 33: + +/* Line 1455 of yacc.c */ #line 383 "../../JavaScriptCore/parser/Grammar.y" { (yyval.intValue) = (yyvsp[(1) - (2)].intValue) + 1; ;} break; case 35: + +/* Line 1455 of yacc.c */ #line 388 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo((yyvsp[(1) - (1)].funcExprNode).m_node, (yyvsp[(1) - (1)].funcExprNode).m_features, (yyvsp[(1) - (1)].funcExprNode).m_numConstants); ;} break; case 36: + +/* Line 1455 of yacc.c */ #line 389 "../../JavaScriptCore/parser/Grammar.y" { BracketAccessorNode* node = new BracketAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (4)]).first_column, (yylsp[(1) - (4)]).last_column, (yylsp[(4) - (4)]).last_column); @@ -3196,6 +3216,8 @@ yyreduce: break; case 37: + +/* Line 1455 of yacc.c */ #line 393 "../../JavaScriptCore/parser/Grammar.y" { DotAccessorNode* node = new DotAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, *(yyvsp[(3) - (3)].ident)); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); @@ -3204,6 +3226,8 @@ yyreduce: break; case 38: + +/* Line 1455 of yacc.c */ #line 397 "../../JavaScriptCore/parser/Grammar.y" { NewExprNode* node = new NewExprNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].argumentsNode).m_node); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); @@ -3212,6 +3236,8 @@ yyreduce: break; case 40: + +/* Line 1455 of yacc.c */ #line 405 "../../JavaScriptCore/parser/Grammar.y" { BracketAccessorNode* node = new BracketAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (4)]).first_column, (yylsp[(1) - (4)]).last_column, (yylsp[(4) - (4)]).last_column); @@ -3220,6 +3246,8 @@ yyreduce: break; case 41: + +/* Line 1455 of yacc.c */ #line 409 "../../JavaScriptCore/parser/Grammar.y" { DotAccessorNode* node = new DotAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, *(yyvsp[(3) - (3)].ident)); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); @@ -3228,6 +3256,8 @@ yyreduce: break; case 42: + +/* Line 1455 of yacc.c */ #line 413 "../../JavaScriptCore/parser/Grammar.y" { NewExprNode* node = new NewExprNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].argumentsNode).m_node); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); @@ -3236,6 +3266,8 @@ yyreduce: break; case 44: + +/* Line 1455 of yacc.c */ #line 421 "../../JavaScriptCore/parser/Grammar.y" { NewExprNode* node = new NewExprNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); @@ -3244,6 +3276,8 @@ yyreduce: break; case 46: + +/* Line 1455 of yacc.c */ #line 429 "../../JavaScriptCore/parser/Grammar.y" { NewExprNode* node = new NewExprNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); @@ -3252,16 +3286,22 @@ yyreduce: break; case 47: + +/* Line 1455 of yacc.c */ #line 436 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = makeFunctionCallNode(globalPtr, (yyvsp[(1) - (2)].expressionNode), (yyvsp[(2) - (2)].argumentsNode), (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); ;} break; case 48: + +/* Line 1455 of yacc.c */ #line 437 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = makeFunctionCallNode(globalPtr, (yyvsp[(1) - (2)].expressionNode), (yyvsp[(2) - (2)].argumentsNode), (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); ;} break; case 49: + +/* Line 1455 of yacc.c */ #line 438 "../../JavaScriptCore/parser/Grammar.y" { BracketAccessorNode* node = new BracketAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (4)]).first_column, (yylsp[(1) - (4)]).last_column, (yylsp[(4) - (4)]).last_column); @@ -3270,6 +3310,8 @@ yyreduce: break; case 50: + +/* Line 1455 of yacc.c */ #line 442 "../../JavaScriptCore/parser/Grammar.y" { DotAccessorNode* node = new DotAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, *(yyvsp[(3) - (3)].ident)); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); @@ -3277,16 +3319,22 @@ yyreduce: break; case 51: + +/* Line 1455 of yacc.c */ #line 448 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = makeFunctionCallNode(globalPtr, (yyvsp[(1) - (2)].expressionNode), (yyvsp[(2) - (2)].argumentsNode), (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); ;} break; case 52: + +/* Line 1455 of yacc.c */ #line 449 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = makeFunctionCallNode(globalPtr, (yyvsp[(1) - (2)].expressionNode), (yyvsp[(2) - (2)].argumentsNode), (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); ;} break; case 53: + +/* Line 1455 of yacc.c */ #line 450 "../../JavaScriptCore/parser/Grammar.y" { BracketAccessorNode* node = new BracketAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (4)]).first_column, (yylsp[(1) - (4)]).last_column, (yylsp[(4) - (4)]).last_column); @@ -3295,6 +3343,8 @@ yyreduce: break; case 54: + +/* Line 1455 of yacc.c */ #line 454 "../../JavaScriptCore/parser/Grammar.y" { DotAccessorNode* node = new DotAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, *(yyvsp[(3) - (3)].ident)); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column, (yylsp[(3) - (3)]).last_column); @@ -3303,16 +3353,22 @@ yyreduce: break; case 55: + +/* Line 1455 of yacc.c */ #line 461 "../../JavaScriptCore/parser/Grammar.y" { (yyval.argumentsNode) = createNodeInfo(new ArgumentsNode(GLOBAL_DATA), 0, 0); ;} break; case 56: + +/* Line 1455 of yacc.c */ #line 462 "../../JavaScriptCore/parser/Grammar.y" { (yyval.argumentsNode) = createNodeInfo(new ArgumentsNode(GLOBAL_DATA, (yyvsp[(2) - (3)].argumentList).m_node.head), (yyvsp[(2) - (3)].argumentList).m_features, (yyvsp[(2) - (3)].argumentList).m_numConstants); ;} break; case 57: + +/* Line 1455 of yacc.c */ #line 466 "../../JavaScriptCore/parser/Grammar.y" { (yyval.argumentList).m_node.head = new ArgumentListNode(GLOBAL_DATA, (yyvsp[(1) - (1)].expressionNode).m_node); (yyval.argumentList).m_node.tail = (yyval.argumentList).m_node.head; @@ -3321,6 +3377,8 @@ yyreduce: break; case 58: + +/* Line 1455 of yacc.c */ #line 470 "../../JavaScriptCore/parser/Grammar.y" { (yyval.argumentList).m_node.head = (yyvsp[(1) - (3)].argumentList).m_node.head; (yyval.argumentList).m_node.tail = new ArgumentListNode(GLOBAL_DATA, (yyvsp[(1) - (3)].argumentList).m_node.tail, (yyvsp[(3) - (3)].expressionNode).m_node); @@ -3329,181 +3387,253 @@ yyreduce: break; case 64: + +/* Line 1455 of yacc.c */ #line 488 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makePostfixNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode).m_node, OpPlusPlus, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column), (yyvsp[(1) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (2)].expressionNode).m_numConstants); ;} break; case 65: + +/* Line 1455 of yacc.c */ #line 489 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makePostfixNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode).m_node, OpMinusMinus, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column), (yyvsp[(1) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (2)].expressionNode).m_numConstants); ;} break; case 67: + +/* Line 1455 of yacc.c */ #line 494 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makePostfixNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode).m_node, OpPlusPlus, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column), (yyvsp[(1) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (2)].expressionNode).m_numConstants); ;} break; case 68: + +/* Line 1455 of yacc.c */ #line 495 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makePostfixNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode).m_node, OpMinusMinus, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column), (yyvsp[(1) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (2)].expressionNode).m_numConstants); ;} break; case 69: + +/* Line 1455 of yacc.c */ #line 499 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeDeleteNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).last_column, (yylsp[(2) - (2)]).last_column), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 70: + +/* Line 1455 of yacc.c */ #line 500 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new VoidNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants + 1); ;} break; case 71: + +/* Line 1455 of yacc.c */ #line 501 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeTypeOfNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 72: + +/* Line 1455 of yacc.c */ #line 502 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makePrefixNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node, OpPlusPlus, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column), (yyvsp[(2) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 73: + +/* Line 1455 of yacc.c */ #line 503 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makePrefixNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node, OpPlusPlus, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column), (yyvsp[(2) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 74: + +/* Line 1455 of yacc.c */ #line 504 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makePrefixNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node, OpMinusMinus, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column), (yyvsp[(2) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 75: + +/* Line 1455 of yacc.c */ #line 505 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makePrefixNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node, OpMinusMinus, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column), (yyvsp[(2) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 76: + +/* Line 1455 of yacc.c */ #line 506 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new UnaryPlusNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 77: + +/* Line 1455 of yacc.c */ #line 507 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeNegateNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 78: + +/* Line 1455 of yacc.c */ #line 508 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeBitwiseNotNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 79: + +/* Line 1455 of yacc.c */ #line 509 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LogicalNotNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 85: + +/* Line 1455 of yacc.c */ #line 523 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeMultNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 86: + +/* Line 1455 of yacc.c */ #line 524 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeDivNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 87: + +/* Line 1455 of yacc.c */ #line 525 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ModNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 89: + +/* Line 1455 of yacc.c */ #line 531 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeMultNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 90: + +/* Line 1455 of yacc.c */ #line 533 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeDivNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 91: + +/* Line 1455 of yacc.c */ #line 535 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ModNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 93: + +/* Line 1455 of yacc.c */ #line 540 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeAddNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 94: + +/* Line 1455 of yacc.c */ #line 541 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeSubNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 96: + +/* Line 1455 of yacc.c */ #line 547 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeAddNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 97: + +/* Line 1455 of yacc.c */ #line 549 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeSubNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 99: + +/* Line 1455 of yacc.c */ #line 554 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeLeftShiftNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 100: + +/* Line 1455 of yacc.c */ #line 555 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeRightShiftNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 101: + +/* Line 1455 of yacc.c */ #line 556 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new UnsignedRightShiftNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 103: + +/* Line 1455 of yacc.c */ #line 561 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeLeftShiftNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 104: + +/* Line 1455 of yacc.c */ #line 562 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeRightShiftNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 105: + +/* Line 1455 of yacc.c */ #line 563 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new UnsignedRightShiftNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 107: + +/* Line 1455 of yacc.c */ #line 568 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LessNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 108: + +/* Line 1455 of yacc.c */ #line 569 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new GreaterNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 109: + +/* Line 1455 of yacc.c */ #line 570 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LessEqNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 110: + +/* Line 1455 of yacc.c */ #line 571 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new GreaterEqNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 111: + +/* Line 1455 of yacc.c */ #line 572 "../../JavaScriptCore/parser/Grammar.y" { InstanceOfNode* node = new InstanceOfNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); @@ -3511,6 +3641,8 @@ yyreduce: break; case 112: + +/* Line 1455 of yacc.c */ #line 575 "../../JavaScriptCore/parser/Grammar.y" { InNode* node = new InNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); @@ -3518,26 +3650,36 @@ yyreduce: break; case 114: + +/* Line 1455 of yacc.c */ #line 582 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LessNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 115: + +/* Line 1455 of yacc.c */ #line 583 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new GreaterNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 116: + +/* Line 1455 of yacc.c */ #line 584 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LessEqNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 117: + +/* Line 1455 of yacc.c */ #line 585 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new GreaterEqNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 118: + +/* Line 1455 of yacc.c */ #line 587 "../../JavaScriptCore/parser/Grammar.y" { InstanceOfNode* node = new InstanceOfNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); @@ -3545,26 +3687,36 @@ yyreduce: break; case 120: + +/* Line 1455 of yacc.c */ #line 594 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LessNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 121: + +/* Line 1455 of yacc.c */ #line 595 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new GreaterNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 122: + +/* Line 1455 of yacc.c */ #line 596 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LessEqNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 123: + +/* Line 1455 of yacc.c */ #line 597 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new GreaterEqNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 124: + +/* Line 1455 of yacc.c */ #line 599 "../../JavaScriptCore/parser/Grammar.y" { InstanceOfNode* node = new InstanceOfNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); @@ -3572,6 +3724,8 @@ yyreduce: break; case 125: + +/* Line 1455 of yacc.c */ #line 603 "../../JavaScriptCore/parser/Grammar.y" { InNode* node = new InNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column); @@ -3579,156 +3733,218 @@ yyreduce: break; case 127: + +/* Line 1455 of yacc.c */ #line 610 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new EqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 128: + +/* Line 1455 of yacc.c */ #line 611 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new NotEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 129: + +/* Line 1455 of yacc.c */ #line 612 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new StrictEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 130: + +/* Line 1455 of yacc.c */ #line 613 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new NotStrictEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 132: + +/* Line 1455 of yacc.c */ #line 619 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new EqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 133: + +/* Line 1455 of yacc.c */ #line 621 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new NotEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 134: + +/* Line 1455 of yacc.c */ #line 623 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new StrictEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 135: + +/* Line 1455 of yacc.c */ #line 625 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new NotStrictEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 137: + +/* Line 1455 of yacc.c */ #line 631 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new EqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 138: + +/* Line 1455 of yacc.c */ #line 632 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new NotEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 139: + +/* Line 1455 of yacc.c */ #line 634 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new StrictEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 140: + +/* Line 1455 of yacc.c */ #line 636 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new NotStrictEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 142: + +/* Line 1455 of yacc.c */ #line 641 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new BitAndNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 144: + +/* Line 1455 of yacc.c */ #line 647 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new BitAndNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 146: + +/* Line 1455 of yacc.c */ #line 652 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new BitAndNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 148: + +/* Line 1455 of yacc.c */ #line 657 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new BitXOrNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 150: + +/* Line 1455 of yacc.c */ #line 663 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new BitXOrNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 152: + +/* Line 1455 of yacc.c */ #line 669 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new BitXOrNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 154: + +/* Line 1455 of yacc.c */ #line 674 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new BitOrNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 156: + +/* Line 1455 of yacc.c */ #line 680 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new BitOrNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 158: + +/* Line 1455 of yacc.c */ #line 686 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new BitOrNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 160: + +/* Line 1455 of yacc.c */ #line 691 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LogicalOpNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, OpLogicalAnd), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 162: + +/* Line 1455 of yacc.c */ #line 697 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LogicalOpNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, OpLogicalAnd), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 164: + +/* Line 1455 of yacc.c */ #line 703 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LogicalOpNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, OpLogicalAnd), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 166: + +/* Line 1455 of yacc.c */ #line 708 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LogicalOpNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, OpLogicalOr), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 168: + +/* Line 1455 of yacc.c */ #line 714 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LogicalOpNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, OpLogicalOr), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 170: + +/* Line 1455 of yacc.c */ #line 719 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new LogicalOpNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, OpLogicalOr), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 172: + +/* Line 1455 of yacc.c */ #line 725 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ConditionalNode(GLOBAL_DATA, (yyvsp[(1) - (5)].expressionNode).m_node, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].expressionNode).m_node), (yyvsp[(1) - (5)].expressionNode).m_features | (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].expressionNode).m_features, (yyvsp[(1) - (5)].expressionNode).m_numConstants + (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].expressionNode).m_numConstants); ;} break; case 174: + +/* Line 1455 of yacc.c */ #line 731 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ConditionalNode(GLOBAL_DATA, (yyvsp[(1) - (5)].expressionNode).m_node, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].expressionNode).m_node), (yyvsp[(1) - (5)].expressionNode).m_features | (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].expressionNode).m_features, (yyvsp[(1) - (5)].expressionNode).m_numConstants + (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].expressionNode).m_numConstants); ;} break; case 176: + +/* Line 1455 of yacc.c */ #line 737 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new ConditionalNode(GLOBAL_DATA, (yyvsp[(1) - (5)].expressionNode).m_node, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].expressionNode).m_node), (yyvsp[(1) - (5)].expressionNode).m_features | (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].expressionNode).m_features, (yyvsp[(1) - (5)].expressionNode).m_numConstants + (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].expressionNode).m_numConstants); ;} break; case 178: + +/* Line 1455 of yacc.c */ #line 743 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeAssignNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(2) - (3)].op), (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(1) - (3)].expressionNode).m_features & AssignFeature, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).first_column + 1, (yylsp[(3) - (3)]).last_column), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); @@ -3736,6 +3952,8 @@ yyreduce: break; case 180: + +/* Line 1455 of yacc.c */ #line 751 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeAssignNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(2) - (3)].op), (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(1) - (3)].expressionNode).m_features & AssignFeature, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).first_column + 1, (yylsp[(3) - (3)]).last_column), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); @@ -3743,6 +3961,8 @@ yyreduce: break; case 182: + +/* Line 1455 of yacc.c */ #line 759 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(makeAssignNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(2) - (3)].op), (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(1) - (3)].expressionNode).m_features & AssignFeature, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).first_column + 1, (yylsp[(3) - (3)]).last_column), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); @@ -3750,99 +3970,137 @@ yyreduce: break; case 183: + +/* Line 1455 of yacc.c */ #line 765 "../../JavaScriptCore/parser/Grammar.y" { (yyval.op) = OpEqual; ;} break; case 184: + +/* Line 1455 of yacc.c */ #line 766 "../../JavaScriptCore/parser/Grammar.y" { (yyval.op) = OpPlusEq; ;} break; case 185: + +/* Line 1455 of yacc.c */ #line 767 "../../JavaScriptCore/parser/Grammar.y" { (yyval.op) = OpMinusEq; ;} break; case 186: + +/* Line 1455 of yacc.c */ #line 768 "../../JavaScriptCore/parser/Grammar.y" { (yyval.op) = OpMultEq; ;} break; case 187: + +/* Line 1455 of yacc.c */ #line 769 "../../JavaScriptCore/parser/Grammar.y" { (yyval.op) = OpDivEq; ;} break; case 188: + +/* Line 1455 of yacc.c */ #line 770 "../../JavaScriptCore/parser/Grammar.y" { (yyval.op) = OpLShift; ;} break; case 189: + +/* Line 1455 of yacc.c */ #line 771 "../../JavaScriptCore/parser/Grammar.y" { (yyval.op) = OpRShift; ;} break; case 190: + +/* Line 1455 of yacc.c */ #line 772 "../../JavaScriptCore/parser/Grammar.y" { (yyval.op) = OpURShift; ;} break; case 191: + +/* Line 1455 of yacc.c */ #line 773 "../../JavaScriptCore/parser/Grammar.y" { (yyval.op) = OpAndEq; ;} break; case 192: + +/* Line 1455 of yacc.c */ #line 774 "../../JavaScriptCore/parser/Grammar.y" { (yyval.op) = OpXOrEq; ;} break; case 193: + +/* Line 1455 of yacc.c */ #line 775 "../../JavaScriptCore/parser/Grammar.y" { (yyval.op) = OpOrEq; ;} break; case 194: + +/* Line 1455 of yacc.c */ #line 776 "../../JavaScriptCore/parser/Grammar.y" { (yyval.op) = OpModEq; ;} break; case 196: + +/* Line 1455 of yacc.c */ #line 781 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new CommaNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 198: + +/* Line 1455 of yacc.c */ #line 786 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new CommaNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 200: + +/* Line 1455 of yacc.c */ #line 791 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(new CommaNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;} break; case 218: + +/* Line 1455 of yacc.c */ #line 815 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new BlockNode(GLOBAL_DATA, 0), 0, 0, 0, 0); DBG((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;} break; case 219: + +/* Line 1455 of yacc.c */ #line 817 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new BlockNode(GLOBAL_DATA, (yyvsp[(2) - (3)].sourceElements).m_node), (yyvsp[(2) - (3)].sourceElements).m_varDeclarations, (yyvsp[(2) - (3)].sourceElements).m_funcDeclarations, (yyvsp[(2) - (3)].sourceElements).m_features, (yyvsp[(2) - (3)].sourceElements).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;} break; case 220: + +/* Line 1455 of yacc.c */ #line 822 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(makeVarStatementNode(GLOBAL_DATA, (yyvsp[(2) - (3)].varDeclList).m_node), (yyvsp[(2) - (3)].varDeclList).m_varDeclarations, (yyvsp[(2) - (3)].varDeclList).m_funcDeclarations, (yyvsp[(2) - (3)].varDeclList).m_features, (yyvsp[(2) - (3)].varDeclList).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;} break; case 221: + +/* Line 1455 of yacc.c */ #line 824 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(makeVarStatementNode(GLOBAL_DATA, (yyvsp[(2) - (3)].varDeclList).m_node), (yyvsp[(2) - (3)].varDeclList).m_varDeclarations, (yyvsp[(2) - (3)].varDeclList).m_funcDeclarations, (yyvsp[(2) - (3)].varDeclList).m_features, (yyvsp[(2) - (3)].varDeclList).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); @@ -3850,6 +4108,8 @@ yyreduce: break; case 222: + +/* Line 1455 of yacc.c */ #line 830 "../../JavaScriptCore/parser/Grammar.y" { (yyval.varDeclList).m_node = 0; (yyval.varDeclList).m_varDeclarations = new ParserRefCountedData(GLOBAL_DATA); @@ -3861,6 +4121,8 @@ yyreduce: break; case 223: + +/* Line 1455 of yacc.c */ #line 837 "../../JavaScriptCore/parser/Grammar.y" { AssignResolveNode* node = new AssignResolveNode(GLOBAL_DATA, *(yyvsp[(1) - (2)].ident), (yyvsp[(2) - (2)].expressionNode).m_node, (yyvsp[(2) - (2)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column); @@ -3874,6 +4136,8 @@ yyreduce: break; case 224: + +/* Line 1455 of yacc.c */ #line 847 "../../JavaScriptCore/parser/Grammar.y" { (yyval.varDeclList).m_node = (yyvsp[(1) - (3)].varDeclList).m_node; (yyval.varDeclList).m_varDeclarations = (yyvsp[(1) - (3)].varDeclList).m_varDeclarations; @@ -3885,6 +4149,8 @@ yyreduce: break; case 225: + +/* Line 1455 of yacc.c */ #line 855 "../../JavaScriptCore/parser/Grammar.y" { AssignResolveNode* node = new AssignResolveNode(GLOBAL_DATA, *(yyvsp[(3) - (4)].ident), (yyvsp[(4) - (4)].expressionNode).m_node, (yyvsp[(4) - (4)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(3) - (4)]).first_column, (yylsp[(4) - (4)]).first_column + 1, (yylsp[(4) - (4)]).last_column); @@ -3898,6 +4164,8 @@ yyreduce: break; case 226: + +/* Line 1455 of yacc.c */ #line 867 "../../JavaScriptCore/parser/Grammar.y" { (yyval.varDeclList).m_node = 0; (yyval.varDeclList).m_varDeclarations = new ParserRefCountedData(GLOBAL_DATA); @@ -3909,6 +4177,8 @@ yyreduce: break; case 227: + +/* Line 1455 of yacc.c */ #line 874 "../../JavaScriptCore/parser/Grammar.y" { AssignResolveNode* node = new AssignResolveNode(GLOBAL_DATA, *(yyvsp[(1) - (2)].ident), (yyvsp[(2) - (2)].expressionNode).m_node, (yyvsp[(2) - (2)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column); @@ -3922,6 +4192,8 @@ yyreduce: break; case 228: + +/* Line 1455 of yacc.c */ #line 884 "../../JavaScriptCore/parser/Grammar.y" { (yyval.varDeclList).m_node = (yyvsp[(1) - (3)].varDeclList).m_node; (yyval.varDeclList).m_varDeclarations = (yyvsp[(1) - (3)].varDeclList).m_varDeclarations; @@ -3933,6 +4205,8 @@ yyreduce: break; case 229: + +/* Line 1455 of yacc.c */ #line 892 "../../JavaScriptCore/parser/Grammar.y" { AssignResolveNode* node = new AssignResolveNode(GLOBAL_DATA, *(yyvsp[(3) - (4)].ident), (yyvsp[(4) - (4)].expressionNode).m_node, (yyvsp[(4) - (4)].expressionNode).m_features & AssignFeature); SET_EXCEPTION_LOCATION(node, (yylsp[(3) - (4)]).first_column, (yylsp[(4) - (4)]).first_column + 1, (yylsp[(4) - (4)]).last_column); @@ -3946,18 +4220,24 @@ yyreduce: break; case 230: + +/* Line 1455 of yacc.c */ #line 904 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new ConstStatementNode(GLOBAL_DATA, (yyvsp[(2) - (3)].constDeclList).m_node.head), (yyvsp[(2) - (3)].constDeclList).m_varDeclarations, (yyvsp[(2) - (3)].constDeclList).m_funcDeclarations, (yyvsp[(2) - (3)].constDeclList).m_features, (yyvsp[(2) - (3)].constDeclList).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;} break; case 231: + +/* Line 1455 of yacc.c */ #line 907 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new ConstStatementNode(GLOBAL_DATA, (yyvsp[(2) - (3)].constDeclList).m_node.head), (yyvsp[(2) - (3)].constDeclList).m_varDeclarations, (yyvsp[(2) - (3)].constDeclList).m_funcDeclarations, (yyvsp[(2) - (3)].constDeclList).m_features, (yyvsp[(2) - (3)].constDeclList).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); AUTO_SEMICOLON; ;} break; case 232: + +/* Line 1455 of yacc.c */ #line 912 "../../JavaScriptCore/parser/Grammar.y" { (yyval.constDeclList).m_node.head = (yyvsp[(1) - (1)].constDeclNode).m_node; (yyval.constDeclList).m_node.tail = (yyval.constDeclList).m_node.head; @@ -3970,6 +4250,8 @@ yyreduce: break; case 233: + +/* Line 1455 of yacc.c */ #line 921 "../../JavaScriptCore/parser/Grammar.y" { (yyval.constDeclList).m_node.head = (yyvsp[(1) - (3)].constDeclList).m_node.head; (yyvsp[(1) - (3)].constDeclList).m_node.tail->m_next = (yyvsp[(3) - (3)].constDeclNode).m_node; @@ -3982,49 +4264,67 @@ yyreduce: break; case 234: + +/* Line 1455 of yacc.c */ #line 932 "../../JavaScriptCore/parser/Grammar.y" { (yyval.constDeclNode) = createNodeInfo(new ConstDeclNode(GLOBAL_DATA, *(yyvsp[(1) - (1)].ident), 0), (*(yyvsp[(1) - (1)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0, 0); ;} break; case 235: + +/* Line 1455 of yacc.c */ #line 933 "../../JavaScriptCore/parser/Grammar.y" { (yyval.constDeclNode) = createNodeInfo(new ConstDeclNode(GLOBAL_DATA, *(yyvsp[(1) - (2)].ident), (yyvsp[(2) - (2)].expressionNode).m_node), ((*(yyvsp[(1) - (2)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;} break; case 236: + +/* Line 1455 of yacc.c */ #line 937 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = (yyvsp[(2) - (2)].expressionNode); ;} break; case 237: + +/* Line 1455 of yacc.c */ #line 941 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = (yyvsp[(2) - (2)].expressionNode); ;} break; case 238: + +/* Line 1455 of yacc.c */ #line 945 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new EmptyStatementNode(GLOBAL_DATA), 0, 0, 0, 0); ;} break; case 239: + +/* Line 1455 of yacc.c */ #line 949 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new ExprStatementNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode).m_node), 0, 0, (yyvsp[(1) - (2)].expressionNode).m_features, (yyvsp[(1) - (2)].expressionNode).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;} break; case 240: + +/* Line 1455 of yacc.c */ #line 951 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new ExprStatementNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode).m_node), 0, 0, (yyvsp[(1) - (2)].expressionNode).m_features, (yyvsp[(1) - (2)].expressionNode).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; ;} break; case 241: + +/* Line 1455 of yacc.c */ #line 957 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new IfNode(GLOBAL_DATA, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].statementNode).m_node), (yyvsp[(5) - (5)].statementNode).m_varDeclarations, (yyvsp[(5) - (5)].statementNode).m_funcDeclarations, (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].statementNode).m_features, (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].statementNode).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (5)]), (yylsp[(4) - (5)])); ;} break; case 242: + +/* Line 1455 of yacc.c */ #line 960 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new IfElseNode(GLOBAL_DATA, (yyvsp[(3) - (7)].expressionNode).m_node, (yyvsp[(5) - (7)].statementNode).m_node, (yyvsp[(7) - (7)].statementNode).m_node), mergeDeclarationLists((yyvsp[(5) - (7)].statementNode).m_varDeclarations, (yyvsp[(7) - (7)].statementNode).m_varDeclarations), mergeDeclarationLists((yyvsp[(5) - (7)].statementNode).m_funcDeclarations, (yyvsp[(7) - (7)].statementNode).m_funcDeclarations), @@ -4034,24 +4334,32 @@ yyreduce: break; case 243: + +/* Line 1455 of yacc.c */ #line 968 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new DoWhileNode(GLOBAL_DATA, (yyvsp[(2) - (7)].statementNode).m_node, (yyvsp[(5) - (7)].expressionNode).m_node), (yyvsp[(2) - (7)].statementNode).m_varDeclarations, (yyvsp[(2) - (7)].statementNode).m_funcDeclarations, (yyvsp[(2) - (7)].statementNode).m_features | (yyvsp[(5) - (7)].expressionNode).m_features, (yyvsp[(2) - (7)].statementNode).m_numConstants + (yyvsp[(5) - (7)].expressionNode).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (7)]), (yylsp[(3) - (7)])); ;} break; case 244: + +/* Line 1455 of yacc.c */ #line 970 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new DoWhileNode(GLOBAL_DATA, (yyvsp[(2) - (7)].statementNode).m_node, (yyvsp[(5) - (7)].expressionNode).m_node), (yyvsp[(2) - (7)].statementNode).m_varDeclarations, (yyvsp[(2) - (7)].statementNode).m_funcDeclarations, (yyvsp[(2) - (7)].statementNode).m_features | (yyvsp[(5) - (7)].expressionNode).m_features, (yyvsp[(2) - (7)].statementNode).m_numConstants + (yyvsp[(5) - (7)].expressionNode).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (7)]), (yylsp[(3) - (7)])); ;} break; case 245: + +/* Line 1455 of yacc.c */ #line 972 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new WhileNode(GLOBAL_DATA, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].statementNode).m_node), (yyvsp[(5) - (5)].statementNode).m_varDeclarations, (yyvsp[(5) - (5)].statementNode).m_funcDeclarations, (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].statementNode).m_features, (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].statementNode).m_numConstants); DBG((yyval.statementNode).m_node, (yylsp[(1) - (5)]), (yylsp[(4) - (5)])); ;} break; case 246: + +/* Line 1455 of yacc.c */ #line 975 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new ForNode(GLOBAL_DATA, (yyvsp[(3) - (9)].expressionNode).m_node, (yyvsp[(5) - (9)].expressionNode).m_node, (yyvsp[(7) - (9)].expressionNode).m_node, (yyvsp[(9) - (9)].statementNode).m_node, false), (yyvsp[(9) - (9)].statementNode).m_varDeclarations, (yyvsp[(9) - (9)].statementNode).m_funcDeclarations, (yyvsp[(3) - (9)].expressionNode).m_features | (yyvsp[(5) - (9)].expressionNode).m_features | (yyvsp[(7) - (9)].expressionNode).m_features | (yyvsp[(9) - (9)].statementNode).m_features, @@ -4061,6 +4369,8 @@ yyreduce: break; case 247: + +/* Line 1455 of yacc.c */ #line 981 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new ForNode(GLOBAL_DATA, (yyvsp[(4) - (10)].varDeclList).m_node, (yyvsp[(6) - (10)].expressionNode).m_node, (yyvsp[(8) - (10)].expressionNode).m_node, (yyvsp[(10) - (10)].statementNode).m_node, true), mergeDeclarationLists((yyvsp[(4) - (10)].varDeclList).m_varDeclarations, (yyvsp[(10) - (10)].statementNode).m_varDeclarations), @@ -4071,6 +4381,8 @@ yyreduce: break; case 248: + +/* Line 1455 of yacc.c */ #line 988 "../../JavaScriptCore/parser/Grammar.y" { ForInNode* node = new ForInNode(GLOBAL_DATA, (yyvsp[(3) - (7)].expressionNode).m_node, (yyvsp[(5) - (7)].expressionNode).m_node, (yyvsp[(7) - (7)].statementNode).m_node); @@ -4083,6 +4395,8 @@ yyreduce: break; case 249: + +/* Line 1455 of yacc.c */ #line 997 "../../JavaScriptCore/parser/Grammar.y" { ForInNode *forIn = new ForInNode(GLOBAL_DATA, *(yyvsp[(4) - (8)].ident), 0, (yyvsp[(6) - (8)].expressionNode).m_node, (yyvsp[(8) - (8)].statementNode).m_node, (yylsp[(5) - (8)]).first_column, (yylsp[(5) - (8)]).first_column - (yylsp[(4) - (8)]).first_column, (yylsp[(6) - (8)]).last_column - (yylsp[(5) - (8)]).first_column); SET_EXCEPTION_LOCATION(forIn, (yylsp[(4) - (8)]).first_column, (yylsp[(5) - (8)]).first_column + 1, (yylsp[(6) - (8)]).last_column); @@ -4092,6 +4406,8 @@ yyreduce: break; case 250: + +/* Line 1455 of yacc.c */ #line 1003 "../../JavaScriptCore/parser/Grammar.y" { ForInNode *forIn = new ForInNode(GLOBAL_DATA, *(yyvsp[(4) - (9)].ident), (yyvsp[(5) - (9)].expressionNode).m_node, (yyvsp[(7) - (9)].expressionNode).m_node, (yyvsp[(9) - (9)].statementNode).m_node, (yylsp[(5) - (9)]).first_column, (yylsp[(5) - (9)]).first_column - (yylsp[(4) - (9)]).first_column, (yylsp[(5) - (9)]).last_column - (yylsp[(5) - (9)]).first_column); SET_EXCEPTION_LOCATION(forIn, (yylsp[(4) - (9)]).first_column, (yylsp[(6) - (9)]).first_column + 1, (yylsp[(7) - (9)]).last_column); @@ -4103,16 +4419,22 @@ yyreduce: break; case 251: + +/* Line 1455 of yacc.c */ #line 1013 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(0, 0, 0); ;} break; case 253: + +/* Line 1455 of yacc.c */ #line 1018 "../../JavaScriptCore/parser/Grammar.y" { (yyval.expressionNode) = createNodeInfo(0, 0, 0); ;} break; case 255: + +/* Line 1455 of yacc.c */ #line 1023 "../../JavaScriptCore/parser/Grammar.y" { ContinueNode* node = new ContinueNode(GLOBAL_DATA); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); @@ -4121,6 +4443,8 @@ yyreduce: break; case 256: + +/* Line 1455 of yacc.c */ #line 1027 "../../JavaScriptCore/parser/Grammar.y" { ContinueNode* node = new ContinueNode(GLOBAL_DATA); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); @@ -4129,6 +4453,8 @@ yyreduce: break; case 257: + +/* Line 1455 of yacc.c */ #line 1031 "../../JavaScriptCore/parser/Grammar.y" { ContinueNode* node = new ContinueNode(GLOBAL_DATA, *(yyvsp[(2) - (3)].ident)); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4137,6 +4463,8 @@ yyreduce: break; case 258: + +/* Line 1455 of yacc.c */ #line 1035 "../../JavaScriptCore/parser/Grammar.y" { ContinueNode* node = new ContinueNode(GLOBAL_DATA, *(yyvsp[(2) - (3)].ident)); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4145,6 +4473,8 @@ yyreduce: break; case 259: + +/* Line 1455 of yacc.c */ #line 1042 "../../JavaScriptCore/parser/Grammar.y" { BreakNode* node = new BreakNode(GLOBAL_DATA); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); @@ -4152,6 +4482,8 @@ yyreduce: break; case 260: + +/* Line 1455 of yacc.c */ #line 1045 "../../JavaScriptCore/parser/Grammar.y" { BreakNode* node = new BreakNode(GLOBAL_DATA); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); @@ -4159,6 +4491,8 @@ yyreduce: break; case 261: + +/* Line 1455 of yacc.c */ #line 1048 "../../JavaScriptCore/parser/Grammar.y" { BreakNode* node = new BreakNode(GLOBAL_DATA, *(yyvsp[(2) - (3)].ident)); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4166,6 +4500,8 @@ yyreduce: break; case 262: + +/* Line 1455 of yacc.c */ #line 1051 "../../JavaScriptCore/parser/Grammar.y" { BreakNode* node = new BreakNode(GLOBAL_DATA, *(yyvsp[(2) - (3)].ident)); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4173,6 +4509,8 @@ yyreduce: break; case 263: + +/* Line 1455 of yacc.c */ #line 1057 "../../JavaScriptCore/parser/Grammar.y" { ReturnNode* node = new ReturnNode(GLOBAL_DATA, 0); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); @@ -4180,6 +4518,8 @@ yyreduce: break; case 264: + +/* Line 1455 of yacc.c */ #line 1060 "../../JavaScriptCore/parser/Grammar.y" { ReturnNode* node = new ReturnNode(GLOBAL_DATA, 0); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column); @@ -4187,6 +4527,8 @@ yyreduce: break; case 265: + +/* Line 1455 of yacc.c */ #line 1063 "../../JavaScriptCore/parser/Grammar.y" { ReturnNode* node = new ReturnNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4194,6 +4536,8 @@ yyreduce: break; case 266: + +/* Line 1455 of yacc.c */ #line 1066 "../../JavaScriptCore/parser/Grammar.y" { ReturnNode* node = new ReturnNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4201,6 +4545,8 @@ yyreduce: break; case 267: + +/* Line 1455 of yacc.c */ #line 1072 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new WithNode(GLOBAL_DATA, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].statementNode).m_node, (yylsp[(3) - (5)]).last_column, (yylsp[(3) - (5)]).last_column - (yylsp[(3) - (5)]).first_column), (yyvsp[(5) - (5)].statementNode).m_varDeclarations, (yyvsp[(5) - (5)].statementNode).m_funcDeclarations, (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].statementNode).m_features | WithFeature, (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].statementNode).m_numConstants); @@ -4208,6 +4554,8 @@ yyreduce: break; case 268: + +/* Line 1455 of yacc.c */ #line 1078 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new SwitchNode(GLOBAL_DATA, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].caseBlockNode).m_node), (yyvsp[(5) - (5)].caseBlockNode).m_varDeclarations, (yyvsp[(5) - (5)].caseBlockNode).m_funcDeclarations, (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].caseBlockNode).m_features, (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].caseBlockNode).m_numConstants); @@ -4215,11 +4563,15 @@ yyreduce: break; case 269: + +/* Line 1455 of yacc.c */ #line 1084 "../../JavaScriptCore/parser/Grammar.y" { (yyval.caseBlockNode) = createNodeDeclarationInfo(new CaseBlockNode(GLOBAL_DATA, (yyvsp[(2) - (3)].clauseList).m_node.head, 0, 0), (yyvsp[(2) - (3)].clauseList).m_varDeclarations, (yyvsp[(2) - (3)].clauseList).m_funcDeclarations, (yyvsp[(2) - (3)].clauseList).m_features, (yyvsp[(2) - (3)].clauseList).m_numConstants); ;} break; case 270: + +/* Line 1455 of yacc.c */ #line 1086 "../../JavaScriptCore/parser/Grammar.y" { (yyval.caseBlockNode) = createNodeDeclarationInfo(new CaseBlockNode(GLOBAL_DATA, (yyvsp[(2) - (5)].clauseList).m_node.head, (yyvsp[(3) - (5)].caseClauseNode).m_node, (yyvsp[(4) - (5)].clauseList).m_node.head), mergeDeclarationLists(mergeDeclarationLists((yyvsp[(2) - (5)].clauseList).m_varDeclarations, (yyvsp[(3) - (5)].caseClauseNode).m_varDeclarations), (yyvsp[(4) - (5)].clauseList).m_varDeclarations), @@ -4229,11 +4581,15 @@ yyreduce: break; case 271: + +/* Line 1455 of yacc.c */ #line 1094 "../../JavaScriptCore/parser/Grammar.y" { (yyval.clauseList).m_node.head = 0; (yyval.clauseList).m_node.tail = 0; (yyval.clauseList).m_varDeclarations = 0; (yyval.clauseList).m_funcDeclarations = 0; (yyval.clauseList).m_features = 0; (yyval.clauseList).m_numConstants = 0; ;} break; case 273: + +/* Line 1455 of yacc.c */ #line 1099 "../../JavaScriptCore/parser/Grammar.y" { (yyval.clauseList).m_node.head = new ClauseListNode(GLOBAL_DATA, (yyvsp[(1) - (1)].caseClauseNode).m_node); (yyval.clauseList).m_node.tail = (yyval.clauseList).m_node.head; @@ -4244,6 +4600,8 @@ yyreduce: break; case 274: + +/* Line 1455 of yacc.c */ #line 1105 "../../JavaScriptCore/parser/Grammar.y" { (yyval.clauseList).m_node.head = (yyvsp[(1) - (2)].clauseList).m_node.head; (yyval.clauseList).m_node.tail = new ClauseListNode(GLOBAL_DATA, (yyvsp[(1) - (2)].clauseList).m_node.tail, (yyvsp[(2) - (2)].caseClauseNode).m_node); @@ -4255,26 +4613,36 @@ yyreduce: break; case 275: + +/* Line 1455 of yacc.c */ #line 1115 "../../JavaScriptCore/parser/Grammar.y" { (yyval.caseClauseNode) = createNodeDeclarationInfo(new CaseClauseNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node), 0, 0, (yyvsp[(2) - (3)].expressionNode).m_features, (yyvsp[(2) - (3)].expressionNode).m_numConstants); ;} break; case 276: + +/* Line 1455 of yacc.c */ #line 1116 "../../JavaScriptCore/parser/Grammar.y" { (yyval.caseClauseNode) = createNodeDeclarationInfo(new CaseClauseNode(GLOBAL_DATA, (yyvsp[(2) - (4)].expressionNode).m_node, (yyvsp[(4) - (4)].sourceElements).m_node), (yyvsp[(4) - (4)].sourceElements).m_varDeclarations, (yyvsp[(4) - (4)].sourceElements).m_funcDeclarations, (yyvsp[(2) - (4)].expressionNode).m_features | (yyvsp[(4) - (4)].sourceElements).m_features, (yyvsp[(2) - (4)].expressionNode).m_numConstants + (yyvsp[(4) - (4)].sourceElements).m_numConstants); ;} break; case 277: + +/* Line 1455 of yacc.c */ #line 1120 "../../JavaScriptCore/parser/Grammar.y" { (yyval.caseClauseNode) = createNodeDeclarationInfo(new CaseClauseNode(GLOBAL_DATA, 0), 0, 0, 0, 0); ;} break; case 278: + +/* Line 1455 of yacc.c */ #line 1121 "../../JavaScriptCore/parser/Grammar.y" { (yyval.caseClauseNode) = createNodeDeclarationInfo(new CaseClauseNode(GLOBAL_DATA, 0, (yyvsp[(3) - (3)].sourceElements).m_node), (yyvsp[(3) - (3)].sourceElements).m_varDeclarations, (yyvsp[(3) - (3)].sourceElements).m_funcDeclarations, (yyvsp[(3) - (3)].sourceElements).m_features, (yyvsp[(3) - (3)].sourceElements).m_numConstants); ;} break; case 279: + +/* Line 1455 of yacc.c */ #line 1125 "../../JavaScriptCore/parser/Grammar.y" { LabelNode* node = new LabelNode(GLOBAL_DATA, *(yyvsp[(1) - (3)].ident), (yyvsp[(3) - (3)].statementNode).m_node); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4282,6 +4650,8 @@ yyreduce: break; case 280: + +/* Line 1455 of yacc.c */ #line 1131 "../../JavaScriptCore/parser/Grammar.y" { ThrowNode* node = new ThrowNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4290,6 +4660,8 @@ yyreduce: break; case 281: + +/* Line 1455 of yacc.c */ #line 1135 "../../JavaScriptCore/parser/Grammar.y" { ThrowNode* node = new ThrowNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node); SET_EXCEPTION_LOCATION(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column); @@ -4298,6 +4670,8 @@ yyreduce: break; case 282: + +/* Line 1455 of yacc.c */ #line 1142 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new TryNode(GLOBAL_DATA, (yyvsp[(2) - (4)].statementNode).m_node, GLOBAL_DATA->propertyNames->nullIdentifier, false, 0, (yyvsp[(4) - (4)].statementNode).m_node), mergeDeclarationLists((yyvsp[(2) - (4)].statementNode).m_varDeclarations, (yyvsp[(4) - (4)].statementNode).m_varDeclarations), @@ -4308,6 +4682,8 @@ yyreduce: break; case 283: + +/* Line 1455 of yacc.c */ #line 1148 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new TryNode(GLOBAL_DATA, (yyvsp[(2) - (7)].statementNode).m_node, *(yyvsp[(5) - (7)].ident), ((yyvsp[(7) - (7)].statementNode).m_features & EvalFeature) != 0, (yyvsp[(7) - (7)].statementNode).m_node, 0), mergeDeclarationLists((yyvsp[(2) - (7)].statementNode).m_varDeclarations, (yyvsp[(7) - (7)].statementNode).m_varDeclarations), @@ -4318,6 +4694,8 @@ yyreduce: break; case 284: + +/* Line 1455 of yacc.c */ #line 1155 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new TryNode(GLOBAL_DATA, (yyvsp[(2) - (9)].statementNode).m_node, *(yyvsp[(5) - (9)].ident), ((yyvsp[(7) - (9)].statementNode).m_features & EvalFeature) != 0, (yyvsp[(7) - (9)].statementNode).m_node, (yyvsp[(9) - (9)].statementNode).m_node), mergeDeclarationLists(mergeDeclarationLists((yyvsp[(2) - (9)].statementNode).m_varDeclarations, (yyvsp[(7) - (9)].statementNode).m_varDeclarations), (yyvsp[(9) - (9)].statementNode).m_varDeclarations), @@ -4328,23 +4706,31 @@ yyreduce: break; case 285: + +/* Line 1455 of yacc.c */ #line 1164 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new DebuggerStatementNode(GLOBAL_DATA), 0, 0, 0, 0); DBG((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;} break; case 286: + +/* Line 1455 of yacc.c */ #line 1166 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new DebuggerStatementNode(GLOBAL_DATA), 0, 0, 0, 0); DBG((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; ;} break; case 287: + +/* Line 1455 of yacc.c */ #line 1171 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new FuncDeclNode(GLOBAL_DATA, *(yyvsp[(2) - (7)].ident), (yyvsp[(6) - (7)].functionBodyNode), LEXER->sourceCode((yyvsp[(5) - (7)].intValue), (yyvsp[(7) - (7)].intValue), (yylsp[(5) - (7)]).first_line)), 0, new ParserRefCountedData(GLOBAL_DATA), ((*(yyvsp[(2) - (7)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | ClosureFeature, 0); DBG((yyvsp[(6) - (7)].functionBodyNode), (yylsp[(5) - (7)]), (yylsp[(7) - (7)])); (yyval.statementNode).m_funcDeclarations->data.append(static_cast((yyval.statementNode).m_node)); ;} break; case 288: + +/* Line 1455 of yacc.c */ #line 1173 "../../JavaScriptCore/parser/Grammar.y" { (yyval.statementNode) = createNodeDeclarationInfo(new FuncDeclNode(GLOBAL_DATA, *(yyvsp[(2) - (8)].ident), (yyvsp[(7) - (8)].functionBodyNode), LEXER->sourceCode((yyvsp[(6) - (8)].intValue), (yyvsp[(8) - (8)].intValue), (yylsp[(6) - (8)]).first_line), (yyvsp[(4) - (8)].parameterList).m_node.head), 0, new ParserRefCountedData(GLOBAL_DATA), ((*(yyvsp[(2) - (8)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | (yyvsp[(4) - (8)].parameterList).m_features | ClosureFeature, 0); @@ -4356,11 +4742,15 @@ yyreduce: break; case 289: + +/* Line 1455 of yacc.c */ #line 1183 "../../JavaScriptCore/parser/Grammar.y" { (yyval.funcExprNode) = createNodeInfo(new FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, (yyvsp[(5) - (6)].functionBodyNode), LEXER->sourceCode((yyvsp[(4) - (6)].intValue), (yyvsp[(6) - (6)].intValue), (yylsp[(4) - (6)]).first_line)), ClosureFeature, 0); DBG((yyvsp[(5) - (6)].functionBodyNode), (yylsp[(4) - (6)]), (yylsp[(6) - (6)])); ;} break; case 290: + +/* Line 1455 of yacc.c */ #line 1185 "../../JavaScriptCore/parser/Grammar.y" { (yyval.funcExprNode) = createNodeInfo(new FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, (yyvsp[(6) - (7)].functionBodyNode), LEXER->sourceCode((yyvsp[(5) - (7)].intValue), (yyvsp[(7) - (7)].intValue), (yylsp[(5) - (7)]).first_line), (yyvsp[(3) - (7)].parameterList).m_node.head), (yyvsp[(3) - (7)].parameterList).m_features | ClosureFeature, 0); @@ -4371,11 +4761,15 @@ yyreduce: break; case 291: + +/* Line 1455 of yacc.c */ #line 1191 "../../JavaScriptCore/parser/Grammar.y" { (yyval.funcExprNode) = createNodeInfo(new FuncExprNode(GLOBAL_DATA, *(yyvsp[(2) - (7)].ident), (yyvsp[(6) - (7)].functionBodyNode), LEXER->sourceCode((yyvsp[(5) - (7)].intValue), (yyvsp[(7) - (7)].intValue), (yylsp[(5) - (7)]).first_line)), ClosureFeature, 0); DBG((yyvsp[(6) - (7)].functionBodyNode), (yylsp[(5) - (7)]), (yylsp[(7) - (7)])); ;} break; case 292: + +/* Line 1455 of yacc.c */ #line 1193 "../../JavaScriptCore/parser/Grammar.y" { (yyval.funcExprNode) = createNodeInfo(new FuncExprNode(GLOBAL_DATA, *(yyvsp[(2) - (8)].ident), (yyvsp[(7) - (8)].functionBodyNode), LEXER->sourceCode((yyvsp[(6) - (8)].intValue), (yyvsp[(8) - (8)].intValue), (yylsp[(6) - (8)]).first_line), (yyvsp[(4) - (8)].parameterList).m_node.head), (yyvsp[(4) - (8)].parameterList).m_features | ClosureFeature, 0); @@ -4386,6 +4780,8 @@ yyreduce: break; case 293: + +/* Line 1455 of yacc.c */ #line 1202 "../../JavaScriptCore/parser/Grammar.y" { (yyval.parameterList).m_node.head = new ParameterNode(GLOBAL_DATA, *(yyvsp[(1) - (1)].ident)); (yyval.parameterList).m_features = (*(yyvsp[(1) - (1)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0; @@ -4393,6 +4789,8 @@ yyreduce: break; case 294: + +/* Line 1455 of yacc.c */ #line 1205 "../../JavaScriptCore/parser/Grammar.y" { (yyval.parameterList).m_node.head = (yyvsp[(1) - (3)].parameterList).m_node.head; (yyval.parameterList).m_features = (yyvsp[(1) - (3)].parameterList).m_features | ((*(yyvsp[(3) - (3)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0); @@ -4400,27 +4798,37 @@ yyreduce: break; case 295: + +/* Line 1455 of yacc.c */ #line 1211 "../../JavaScriptCore/parser/Grammar.y" { (yyval.functionBodyNode) = FunctionBodyNode::create(GLOBAL_DATA); ;} break; case 296: + +/* Line 1455 of yacc.c */ #line 1212 "../../JavaScriptCore/parser/Grammar.y" { (yyval.functionBodyNode) = FunctionBodyNode::create(GLOBAL_DATA); ;} break; case 297: + +/* Line 1455 of yacc.c */ #line 1216 "../../JavaScriptCore/parser/Grammar.y" { GLOBAL_DATA->parser->didFinishParsing(new SourceElements(GLOBAL_DATA), 0, 0, NoFeatures, (yylsp[(0) - (0)]).last_line, 0); ;} break; case 298: + +/* Line 1455 of yacc.c */ #line 1217 "../../JavaScriptCore/parser/Grammar.y" { GLOBAL_DATA->parser->didFinishParsing((yyvsp[(1) - (1)].sourceElements).m_node, (yyvsp[(1) - (1)].sourceElements).m_varDeclarations, (yyvsp[(1) - (1)].sourceElements).m_funcDeclarations, (yyvsp[(1) - (1)].sourceElements).m_features, (yylsp[(1) - (1)]).last_line, (yyvsp[(1) - (1)].sourceElements).m_numConstants); ;} break; case 299: + +/* Line 1455 of yacc.c */ #line 1222 "../../JavaScriptCore/parser/Grammar.y" { (yyval.sourceElements).m_node = new SourceElements(GLOBAL_DATA); (yyval.sourceElements).m_node->append((yyvsp[(1) - (1)].statementNode).m_node); @@ -4432,6 +4840,8 @@ yyreduce: break; case 300: + +/* Line 1455 of yacc.c */ #line 1229 "../../JavaScriptCore/parser/Grammar.y" { (yyval.sourceElements).m_node->append((yyvsp[(2) - (2)].statementNode).m_node); (yyval.sourceElements).m_varDeclarations = mergeDeclarationLists((yyvsp[(1) - (2)].sourceElements).m_varDeclarations, (yyvsp[(2) - (2)].statementNode).m_varDeclarations); @@ -4442,188 +4852,261 @@ yyreduce: break; case 304: + +/* Line 1455 of yacc.c */ #line 1243 "../../JavaScriptCore/parser/Grammar.y" { ;} break; case 305: + +/* Line 1455 of yacc.c */ #line 1244 "../../JavaScriptCore/parser/Grammar.y" { ;} break; case 306: + +/* Line 1455 of yacc.c */ #line 1245 "../../JavaScriptCore/parser/Grammar.y" { Lexer& l = *LEXER; if (!l.scanRegExp()) YYABORT; ;} break; case 307: + +/* Line 1455 of yacc.c */ #line 1246 "../../JavaScriptCore/parser/Grammar.y" { Lexer& l = *LEXER; if (!l.scanRegExp()) YYABORT; ;} break; case 308: + +/* Line 1455 of yacc.c */ #line 1250 "../../JavaScriptCore/parser/Grammar.y" { ;} break; case 309: + +/* Line 1455 of yacc.c */ #line 1251 "../../JavaScriptCore/parser/Grammar.y" { ;} break; case 310: + +/* Line 1455 of yacc.c */ #line 1252 "../../JavaScriptCore/parser/Grammar.y" { ;} break; case 311: + +/* Line 1455 of yacc.c */ #line 1253 "../../JavaScriptCore/parser/Grammar.y" { if (*(yyvsp[(1) - (7)].ident) != "get" && *(yyvsp[(1) - (7)].ident) != "set") YYABORT; ;} break; case 312: + +/* Line 1455 of yacc.c */ #line 1254 "../../JavaScriptCore/parser/Grammar.y" { if (*(yyvsp[(1) - (8)].ident) != "get" && *(yyvsp[(1) - (8)].ident) != "set") YYABORT; ;} break; case 316: + +/* Line 1455 of yacc.c */ #line 1264 "../../JavaScriptCore/parser/Grammar.y" { ;} break; case 317: + +/* Line 1455 of yacc.c */ #line 1265 "../../JavaScriptCore/parser/Grammar.y" { ;} break; case 318: + +/* Line 1455 of yacc.c */ #line 1267 "../../JavaScriptCore/parser/Grammar.y" { ;} break; case 322: + +/* Line 1455 of yacc.c */ #line 1274 "../../JavaScriptCore/parser/Grammar.y" { ;} break; case 517: + +/* Line 1455 of yacc.c */ #line 1642 "../../JavaScriptCore/parser/Grammar.y" { ;} break; case 518: + +/* Line 1455 of yacc.c */ #line 1643 "../../JavaScriptCore/parser/Grammar.y" { ;} break; case 520: + +/* Line 1455 of yacc.c */ #line 1648 "../../JavaScriptCore/parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 521: + +/* Line 1455 of yacc.c */ #line 1652 "../../JavaScriptCore/parser/Grammar.y" { ;} break; case 522: + +/* Line 1455 of yacc.c */ #line 1653 "../../JavaScriptCore/parser/Grammar.y" { ;} break; case 525: + +/* Line 1455 of yacc.c */ #line 1659 "../../JavaScriptCore/parser/Grammar.y" { ;} break; case 526: + +/* Line 1455 of yacc.c */ #line 1660 "../../JavaScriptCore/parser/Grammar.y" { ;} break; case 530: + +/* Line 1455 of yacc.c */ #line 1667 "../../JavaScriptCore/parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 533: + +/* Line 1455 of yacc.c */ #line 1676 "../../JavaScriptCore/parser/Grammar.y" { ;} break; case 534: + +/* Line 1455 of yacc.c */ #line 1677 "../../JavaScriptCore/parser/Grammar.y" { ;} break; case 539: + +/* Line 1455 of yacc.c */ #line 1694 "../../JavaScriptCore/parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 555: + +/* Line 1455 of yacc.c */ #line 1725 "../../JavaScriptCore/parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 557: + +/* Line 1455 of yacc.c */ #line 1727 "../../JavaScriptCore/parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 559: + +/* Line 1455 of yacc.c */ #line 1732 "../../JavaScriptCore/parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 561: + +/* Line 1455 of yacc.c */ #line 1734 "../../JavaScriptCore/parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 563: + +/* Line 1455 of yacc.c */ #line 1739 "../../JavaScriptCore/parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 565: + +/* Line 1455 of yacc.c */ #line 1741 "../../JavaScriptCore/parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 568: + +/* Line 1455 of yacc.c */ #line 1753 "../../JavaScriptCore/parser/Grammar.y" { ;} break; case 569: + +/* Line 1455 of yacc.c */ #line 1754 "../../JavaScriptCore/parser/Grammar.y" { ;} break; case 578: + +/* Line 1455 of yacc.c */ #line 1778 "../../JavaScriptCore/parser/Grammar.y" { ;} break; case 580: + +/* Line 1455 of yacc.c */ #line 1783 "../../JavaScriptCore/parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 585: + +/* Line 1455 of yacc.c */ #line 1794 "../../JavaScriptCore/parser/Grammar.y" { AUTO_SEMICOLON; ;} break; case 592: + +/* Line 1455 of yacc.c */ #line 1810 "../../JavaScriptCore/parser/Grammar.y" { ;} break; -/* Line 1267 of yacc.c. */ -#line 4627 "Grammar.tab.c" + +/* Line 1455 of yacc.c */ +#line 5110 "Grammar.tab.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -4699,7 +5182,7 @@ yyerrlab: if (yyerrstatus == 3) { - /* If just tried and failed to reuse look-ahead token after an + /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) @@ -4716,7 +5199,7 @@ yyerrlab: } } - /* Else will try to reuse look-ahead token after shifting the error + /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; @@ -4774,14 +5257,11 @@ yyerrlab1: YY_STACK_PRINT (yyss, yyssp); } - if (yyn == YYFINAL) - YYACCEPT; - *++yyvsp = yylval; yyerror_range[1] = yylloc; /* Using YYLLOC is tempting, but would change the location of - the look-ahead. YYLOC is available though. */ + the lookahead. YYLOC is available though. */ YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); *++yylsp = yyloc; @@ -4806,7 +5286,7 @@ yyabortlab: yyresult = 1; goto yyreturn; -#ifndef yyoverflow +#if !defined(yyoverflow) || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ @@ -4817,7 +5297,7 @@ yyexhaustedlab: #endif yyreturn: - if (yychar != YYEOF && yychar != YYEMPTY) + if (yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc); /* Do not reclaim the symbols of the rule which action triggered @@ -4843,6 +5323,8 @@ yyreturn: } + +/* Line 1675 of yacc.c */ #line 1826 "../../JavaScriptCore/parser/Grammar.y" diff --git a/src/3rdparty/webkit/WebCore/generated/Grammar.h b/src/3rdparty/webkit/WebCore/generated/Grammar.h index 4805844..0073f41 100644 --- a/src/3rdparty/webkit/WebCore/generated/Grammar.h +++ b/src/3rdparty/webkit/WebCore/generated/Grammar.h @@ -1,24 +1,23 @@ -/* A Bison parser, made by GNU Bison 2.3. */ -/* Skeleton interface for Bison's Yacc-like parsers in C +/* A Bison parser, made by GNU Bison 2.4.1. */ - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +/* Skeleton interface for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -29,10 +28,11 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ + /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE @@ -104,78 +104,16 @@ AUTOMINUSMINUS = 320 }; #endif -/* Tokens. */ -#define NULLTOKEN 258 -#define TRUETOKEN 259 -#define FALSETOKEN 260 -#define BREAK 261 -#define CASE 262 -#define DEFAULT 263 -#define FOR 264 -#define NEW 265 -#define VAR 266 -#define CONSTTOKEN 267 -#define CONTINUE 268 -#define FUNCTION 269 -#define RETURN 270 -#define VOIDTOKEN 271 -#define DELETETOKEN 272 -#define IF 273 -#define THISTOKEN 274 -#define DO 275 -#define WHILE 276 -#define INTOKEN 277 -#define INSTANCEOF 278 -#define TYPEOF 279 -#define SWITCH 280 -#define WITH 281 -#define RESERVED 282 -#define THROW 283 -#define TRY 284 -#define CATCH 285 -#define FINALLY 286 -#define DEBUGGER 287 -#define IF_WITHOUT_ELSE 288 -#define ELSE 289 -#define EQEQ 290 -#define NE 291 -#define STREQ 292 -#define STRNEQ 293 -#define LE 294 -#define GE 295 -#define OR 296 -#define AND 297 -#define PLUSPLUS 298 -#define MINUSMINUS 299 -#define LSHIFT 300 -#define RSHIFT 301 -#define URSHIFT 302 -#define PLUSEQUAL 303 -#define MINUSEQUAL 304 -#define MULTEQUAL 305 -#define DIVEQUAL 306 -#define LSHIFTEQUAL 307 -#define RSHIFTEQUAL 308 -#define URSHIFTEQUAL 309 -#define ANDEQUAL 310 -#define MODEQUAL 311 -#define XOREQUAL 312 -#define OREQUAL 313 -#define OPENBRACE 314 -#define CLOSEBRACE 315 -#define NUMBER 316 -#define IDENT 317 -#define STRING 318 -#define AUTOPLUSPLUS 319 -#define AUTOMINUSMINUS 320 - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 157 "../../JavaScriptCore/parser/Grammar.y" { + +/* Line 1676 of yacc.c */ +#line 157 "../../JavaScriptCore/parser/Grammar.y" + int intValue; double doubleValue; Identifier* ident; @@ -205,13 +143,15 @@ typedef union YYSTYPE ParameterListInfo parameterList; Operator op; -} -/* Line 1489 of yacc.c. */ -#line 211 "Grammar.tab.h" - YYSTYPE; + + + +/* Line 1676 of yacc.c */ +#line 151 "Grammar.tab.h" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 #endif @@ -230,3 +170,4 @@ typedef struct YYLTYPE #endif + diff --git a/src/3rdparty/webkit/WebCore/generated/XPathGrammar.cpp b/src/3rdparty/webkit/WebCore/generated/XPathGrammar.cpp index 1e67ca6..c47664b 100644 --- a/src/3rdparty/webkit/WebCore/generated/XPathGrammar.cpp +++ b/src/3rdparty/webkit/WebCore/generated/XPathGrammar.cpp @@ -1,24 +1,23 @@ -/* A Bison parser, made by GNU Bison 2.3. */ -/* Skeleton implementation for Bison's Yacc-like parsers in C +/* A Bison parser, made by GNU Bison 2.4.1. */ - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -29,7 +28,7 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ @@ -47,7 +46,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.3" +#define YYBISON_VERSION "2.4.1" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -55,69 +54,28 @@ /* Pure parsers. */ #define YYPURE 1 +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + /* Using locations. */ #define YYLSP_NEEDED 0 /* Substitute the variable and function names. */ -#define yyparse xpathyyparse -#define yylex xpathyylex -#define yyerror xpathyyerror -#define yylval xpathyylval -#define yychar xpathyychar -#define yydebug xpathyydebug -#define yynerrs xpathyynerrs - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - MULOP = 258, - RELOP = 259, - EQOP = 260, - MINUS = 261, - PLUS = 262, - AND = 263, - OR = 264, - AXISNAME = 265, - NODETYPE = 266, - PI = 267, - FUNCTIONNAME = 268, - LITERAL = 269, - VARIABLEREFERENCE = 270, - NUMBER = 271, - DOTDOT = 272, - SLASHSLASH = 273, - NAMETEST = 274, - XPATH_ERROR = 275 - }; -#endif -/* Tokens. */ -#define MULOP 258 -#define RELOP 259 -#define EQOP 260 -#define MINUS 261 -#define PLUS 262 -#define AND 263 -#define OR 264 -#define AXISNAME 265 -#define NODETYPE 266 -#define PI 267 -#define FUNCTIONNAME 268 -#define LITERAL 269 -#define VARIABLEREFERENCE 270 -#define NUMBER 271 -#define DOTDOT 272 -#define SLASHSLASH 273 -#define NAMETEST 274 -#define XPATH_ERROR 275 - - +#define yyparse xpathyyparse +#define yylex xpathyylex +#define yyerror xpathyyerror +#define yylval xpathyylval +#define yychar xpathyychar +#define yydebug xpathyydebug +#define yynerrs xpathyynerrs /* Copy the first part of user declarations. */ + +/* Line 189 of yacc.c */ #line 28 "../xml/XPathGrammar.y" @@ -144,6 +102,9 @@ using namespace XPath; +/* Line 189 of yacc.c */ +#line 107 "XPathGrammar.tab.c" + /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -162,10 +123,43 @@ using namespace XPath; # define YYTOKEN_TABLE 0 #endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + MULOP = 258, + RELOP = 259, + EQOP = 260, + MINUS = 261, + PLUS = 262, + AND = 263, + OR = 264, + AXISNAME = 265, + NODETYPE = 266, + PI = 267, + FUNCTIONNAME = 268, + LITERAL = 269, + VARIABLEREFERENCE = 270, + NUMBER = 271, + DOTDOT = 272, + SLASHSLASH = 273, + NAMETEST = 274, + XPATH_ERROR = 275 + }; +#endif + + + #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 56 "../xml/XPathGrammar.y" { + +/* Line 214 of yacc.c */ +#line 56 "../xml/XPathGrammar.y" + Step::Axis axis; Step::NodeTest* nodeTest; NumericOp::Opcode numop; @@ -176,18 +170,21 @@ typedef union YYSTYPE Vector* argList; Step* step; LocationPath* locationPath; -} -/* Line 187 of yacc.c. */ -#line 182 "XPathGrammar.tab.c" - YYSTYPE; + + + +/* Line 214 of yacc.c */ +#line 178 "XPathGrammar.tab.c" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 #endif - /* Copy the second part of user declarations. */ + +/* Line 264 of yacc.c */ #line 69 "../xml/XPathGrammar.y" @@ -196,8 +193,8 @@ void xpathyyerror(const char*) { } -/* Line 216 of yacc.c. */ -#line 201 "XPathGrammar.tab.c" +/* Line 264 of yacc.c */ +#line 198 "XPathGrammar.tab.c" #ifdef short # undef short @@ -272,14 +269,14 @@ typedef short int yytype_int16; #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int -YYID (int i) +YYID (int yyi) #else static int -YYID (i) - int i; +YYID (yyi) + int yyi; #endif { - return i; + return yyi; } #endif @@ -360,9 +357,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ /* A type that is properly aligned for any stack member. */ union yyalloc { - yytype_int16 yyss; - YYSTYPE yyvs; - }; + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) @@ -396,12 +393,12 @@ union yyalloc elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ -# define YYSTACK_RELOCATE(Stack) \ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ @@ -854,17 +851,20 @@ yy_symbol_print (yyoutput, yytype, yyvaluep) #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) #else static void -yy_stack_print (bottom, top) - yytype_int16 *bottom; - yytype_int16 *top; +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; #endif { YYFPRINTF (stderr, "Stack now"); - for (; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } YYFPRINTF (stderr, "\n"); } @@ -898,11 +898,11 @@ yy_reduce_print (yyvsp, yyrule) /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { - fprintf (stderr, " $%d = ", yyi + 1); + YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) ); - fprintf (stderr, "\n"); + YYFPRINTF (stderr, "\n"); } } @@ -1182,10 +1182,8 @@ yydestruct (yymsg, yytype, yyvaluep) break; } } - /* Prevent warnings from -Wmissing-prototypes. */ - #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); @@ -1204,10 +1202,9 @@ int yyparse (); - -/*----------. -| yyparse. | -`----------*/ +/*-------------------------. +| yyparse or yypush_parse. | +`-------------------------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ @@ -1231,74 +1228,75 @@ yyparse () #endif #endif { - /* The look-ahead symbol. */ +/* The lookahead symbol. */ int yychar; -/* The semantic value of the look-ahead symbol. */ +/* The semantic value of the lookahead symbol. */ YYSTYPE yylval; -/* Number of syntax errors so far. */ -int yynerrs; - - int yystate; - int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Look-ahead token as an internal (translated) token number. */ - int yytoken = 0; -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ + /* Number of syntax errors so far. */ + int yynerrs; - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss = yyssa; - yytype_int16 *yyssp; + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp; + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; - YYSIZE_T yystacksize = YYINITDEPTH; + YYSIZE_T yystacksize; + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yystacksize = YYINITDEPTH; + YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ + yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ - yyssp = yyss; yyvsp = yyvs; @@ -1328,7 +1326,6 @@ int yynerrs; YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; - /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might @@ -1336,7 +1333,6 @@ int yynerrs; yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); yyss = yyss1; @@ -1359,9 +1355,8 @@ int yynerrs; (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); @@ -1372,7 +1367,6 @@ int yynerrs; yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; - YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); @@ -1382,6 +1376,9 @@ int yynerrs; YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + if (yystate == YYFINAL) + YYACCEPT; + goto yybackup; /*-----------. @@ -1390,16 +1387,16 @@ int yynerrs; yybackup: /* Do appropriate processing given the current state. Read a - look-ahead token if we need one and don't already have one. */ + lookahead token if we need one and don't already have one. */ - /* First try to decide what to do without reference to look-ahead token. */ + /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; - /* Not known => get a look-ahead token if don't already have one. */ + /* Not known => get a lookahead token if don't already have one. */ - /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); @@ -1431,20 +1428,16 @@ yybackup: goto yyreduce; } - if (yyn == YYFINAL) - YYACCEPT; - /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; - /* Shift the look-ahead token. */ + /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - /* Discard the shifted token unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; + /* Discard the shifted token. */ + yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; @@ -1484,6 +1477,8 @@ yyreduce: switch (yyn) { case 2: + +/* Line 1455 of yacc.c */ #line 118 "../xml/XPathGrammar.y" { PARSER->m_topExpr = (yyvsp[(1) - (1)].expr); @@ -1491,6 +1486,8 @@ yyreduce: break; case 3: + +/* Line 1455 of yacc.c */ #line 125 "../xml/XPathGrammar.y" { (yyval.locationPath)->setAbsolute(false); @@ -1498,6 +1495,8 @@ yyreduce: break; case 4: + +/* Line 1455 of yacc.c */ #line 130 "../xml/XPathGrammar.y" { (yyval.locationPath)->setAbsolute(true); @@ -1505,6 +1504,8 @@ yyreduce: break; case 5: + +/* Line 1455 of yacc.c */ #line 137 "../xml/XPathGrammar.y" { (yyval.locationPath) = new LocationPath; @@ -1513,6 +1514,8 @@ yyreduce: break; case 6: + +/* Line 1455 of yacc.c */ #line 143 "../xml/XPathGrammar.y" { (yyval.locationPath) = (yyvsp[(2) - (2)].locationPath); @@ -1520,6 +1523,8 @@ yyreduce: break; case 7: + +/* Line 1455 of yacc.c */ #line 148 "../xml/XPathGrammar.y" { (yyval.locationPath) = (yyvsp[(2) - (2)].locationPath); @@ -1529,6 +1534,8 @@ yyreduce: break; case 8: + +/* Line 1455 of yacc.c */ #line 157 "../xml/XPathGrammar.y" { (yyval.locationPath) = new LocationPath; @@ -1539,6 +1546,8 @@ yyreduce: break; case 9: + +/* Line 1455 of yacc.c */ #line 165 "../xml/XPathGrammar.y" { (yyval.locationPath)->appendStep((yyvsp[(3) - (3)].step)); @@ -1547,6 +1556,8 @@ yyreduce: break; case 10: + +/* Line 1455 of yacc.c */ #line 171 "../xml/XPathGrammar.y" { (yyval.locationPath)->appendStep((yyvsp[(2) - (3)].step)); @@ -1557,6 +1568,8 @@ yyreduce: break; case 11: + +/* Line 1455 of yacc.c */ #line 181 "../xml/XPathGrammar.y" { if ((yyvsp[(2) - (2)].predList)) { @@ -1570,6 +1583,8 @@ yyreduce: break; case 12: + +/* Line 1455 of yacc.c */ #line 192 "../xml/XPathGrammar.y" { String localName; @@ -1590,6 +1605,8 @@ yyreduce: break; case 13: + +/* Line 1455 of yacc.c */ #line 210 "../xml/XPathGrammar.y" { if ((yyvsp[(3) - (3)].predList)) { @@ -1603,6 +1620,8 @@ yyreduce: break; case 14: + +/* Line 1455 of yacc.c */ #line 221 "../xml/XPathGrammar.y" { String localName; @@ -1623,6 +1642,8 @@ yyreduce: break; case 17: + +/* Line 1455 of yacc.c */ #line 245 "../xml/XPathGrammar.y" { (yyval.axis) = Step::AttributeAxis; @@ -1630,6 +1651,8 @@ yyreduce: break; case 18: + +/* Line 1455 of yacc.c */ #line 252 "../xml/XPathGrammar.y" { if (*(yyvsp[(1) - (3)].str) == "node") @@ -1645,6 +1668,8 @@ yyreduce: break; case 19: + +/* Line 1455 of yacc.c */ #line 265 "../xml/XPathGrammar.y" { (yyval.nodeTest) = new Step::NodeTest(Step::NodeTest::ProcessingInstructionNodeTest); @@ -1654,6 +1679,8 @@ yyreduce: break; case 20: + +/* Line 1455 of yacc.c */ #line 272 "../xml/XPathGrammar.y" { (yyval.nodeTest) = new Step::NodeTest(Step::NodeTest::ProcessingInstructionNodeTest, (yyvsp[(3) - (4)].str)->stripWhiteSpace()); @@ -1664,6 +1691,8 @@ yyreduce: break; case 21: + +/* Line 1455 of yacc.c */ #line 282 "../xml/XPathGrammar.y" { (yyval.predList) = 0; @@ -1671,6 +1700,8 @@ yyreduce: break; case 23: + +/* Line 1455 of yacc.c */ #line 291 "../xml/XPathGrammar.y" { (yyval.predList) = new Vector; @@ -1681,6 +1712,8 @@ yyreduce: break; case 24: + +/* Line 1455 of yacc.c */ #line 299 "../xml/XPathGrammar.y" { (yyval.predList)->append(new Predicate((yyvsp[(2) - (2)].expr))); @@ -1689,6 +1722,8 @@ yyreduce: break; case 25: + +/* Line 1455 of yacc.c */ #line 307 "../xml/XPathGrammar.y" { (yyval.expr) = (yyvsp[(2) - (3)].expr); @@ -1696,6 +1731,8 @@ yyreduce: break; case 26: + +/* Line 1455 of yacc.c */ #line 314 "../xml/XPathGrammar.y" { (yyval.step) = new Step(Step::DescendantOrSelfAxis, Step::NodeTest(Step::NodeTest::AnyNodeTest)); @@ -1704,6 +1741,8 @@ yyreduce: break; case 27: + +/* Line 1455 of yacc.c */ #line 322 "../xml/XPathGrammar.y" { (yyval.step) = new Step(Step::SelfAxis, Step::NodeTest(Step::NodeTest::AnyNodeTest)); @@ -1712,6 +1751,8 @@ yyreduce: break; case 28: + +/* Line 1455 of yacc.c */ #line 328 "../xml/XPathGrammar.y" { (yyval.step) = new Step(Step::ParentAxis, Step::NodeTest(Step::NodeTest::AnyNodeTest)); @@ -1720,6 +1761,8 @@ yyreduce: break; case 29: + +/* Line 1455 of yacc.c */ #line 336 "../xml/XPathGrammar.y" { (yyval.expr) = new VariableReference(*(yyvsp[(1) - (1)].str)); @@ -1729,6 +1772,8 @@ yyreduce: break; case 30: + +/* Line 1455 of yacc.c */ #line 343 "../xml/XPathGrammar.y" { (yyval.expr) = (yyvsp[(2) - (3)].expr); @@ -1736,6 +1781,8 @@ yyreduce: break; case 31: + +/* Line 1455 of yacc.c */ #line 348 "../xml/XPathGrammar.y" { (yyval.expr) = new StringExpression(*(yyvsp[(1) - (1)].str)); @@ -1745,6 +1792,8 @@ yyreduce: break; case 32: + +/* Line 1455 of yacc.c */ #line 355 "../xml/XPathGrammar.y" { (yyval.expr) = new Number((yyvsp[(1) - (1)].str)->toDouble()); @@ -1754,6 +1803,8 @@ yyreduce: break; case 34: + +/* Line 1455 of yacc.c */ #line 366 "../xml/XPathGrammar.y" { (yyval.expr) = createFunction(*(yyvsp[(1) - (3)].str)); @@ -1765,6 +1816,8 @@ yyreduce: break; case 35: + +/* Line 1455 of yacc.c */ #line 375 "../xml/XPathGrammar.y" { (yyval.expr) = createFunction(*(yyvsp[(1) - (4)].str), *(yyvsp[(3) - (4)].argList)); @@ -1777,6 +1830,8 @@ yyreduce: break; case 36: + +/* Line 1455 of yacc.c */ #line 387 "../xml/XPathGrammar.y" { (yyval.argList) = new Vector; @@ -1787,6 +1842,8 @@ yyreduce: break; case 37: + +/* Line 1455 of yacc.c */ #line 395 "../xml/XPathGrammar.y" { (yyval.argList)->append((yyvsp[(3) - (3)].expr)); @@ -1795,6 +1852,8 @@ yyreduce: break; case 40: + +/* Line 1455 of yacc.c */ #line 409 "../xml/XPathGrammar.y" { (yyval.expr) = new Union; @@ -1807,6 +1866,8 @@ yyreduce: break; case 41: + +/* Line 1455 of yacc.c */ #line 421 "../xml/XPathGrammar.y" { (yyval.expr) = (yyvsp[(1) - (1)].locationPath); @@ -1814,6 +1875,8 @@ yyreduce: break; case 43: + +/* Line 1455 of yacc.c */ #line 428 "../xml/XPathGrammar.y" { (yyvsp[(3) - (3)].locationPath)->setAbsolute(true); @@ -1825,6 +1888,8 @@ yyreduce: break; case 44: + +/* Line 1455 of yacc.c */ #line 437 "../xml/XPathGrammar.y" { (yyvsp[(3) - (3)].locationPath)->insertFirstStep((yyvsp[(2) - (3)].step)); @@ -1838,6 +1903,8 @@ yyreduce: break; case 46: + +/* Line 1455 of yacc.c */ #line 452 "../xml/XPathGrammar.y" { (yyval.expr) = new Filter((yyvsp[(1) - (2)].expr), *(yyvsp[(2) - (2)].predList)); @@ -1848,6 +1915,8 @@ yyreduce: break; case 48: + +/* Line 1455 of yacc.c */ #line 464 "../xml/XPathGrammar.y" { (yyval.expr) = new LogicalOp(LogicalOp::OP_Or, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); @@ -1858,6 +1927,8 @@ yyreduce: break; case 50: + +/* Line 1455 of yacc.c */ #line 476 "../xml/XPathGrammar.y" { (yyval.expr) = new LogicalOp(LogicalOp::OP_And, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); @@ -1868,6 +1939,8 @@ yyreduce: break; case 52: + +/* Line 1455 of yacc.c */ #line 488 "../xml/XPathGrammar.y" { (yyval.expr) = new EqTestOp((yyvsp[(2) - (3)].eqop), (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); @@ -1878,6 +1951,8 @@ yyreduce: break; case 54: + +/* Line 1455 of yacc.c */ #line 500 "../xml/XPathGrammar.y" { (yyval.expr) = new EqTestOp((yyvsp[(2) - (3)].eqop), (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); @@ -1888,6 +1963,8 @@ yyreduce: break; case 56: + +/* Line 1455 of yacc.c */ #line 512 "../xml/XPathGrammar.y" { (yyval.expr) = new NumericOp(NumericOp::OP_Add, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); @@ -1898,6 +1975,8 @@ yyreduce: break; case 57: + +/* Line 1455 of yacc.c */ #line 520 "../xml/XPathGrammar.y" { (yyval.expr) = new NumericOp(NumericOp::OP_Sub, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); @@ -1908,6 +1987,8 @@ yyreduce: break; case 59: + +/* Line 1455 of yacc.c */ #line 532 "../xml/XPathGrammar.y" { (yyval.expr) = new NumericOp((yyvsp[(2) - (3)].numop), (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); @@ -1918,6 +1999,8 @@ yyreduce: break; case 61: + +/* Line 1455 of yacc.c */ #line 544 "../xml/XPathGrammar.y" { (yyval.expr) = new Negative; @@ -1928,8 +2011,9 @@ yyreduce: break; -/* Line 1267 of yacc.c. */ -#line 1933 "XPathGrammar.tab.c" + +/* Line 1455 of yacc.c */ +#line 2017 "XPathGrammar.tab.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -1940,7 +2024,6 @@ yyreduce: *++yyvsp = yyval; - /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ @@ -2005,7 +2088,7 @@ yyerrlab: if (yyerrstatus == 3) { - /* If just tried and failed to reuse look-ahead token after an + /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) @@ -2022,7 +2105,7 @@ yyerrlab: } } - /* Else will try to reuse look-ahead token after shifting the error + /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; @@ -2079,9 +2162,6 @@ yyerrlab1: YY_STACK_PRINT (yyss, yyssp); } - if (yyn == YYFINAL) - YYACCEPT; - *++yyvsp = yylval; @@ -2106,7 +2186,7 @@ yyabortlab: yyresult = 1; goto yyreturn; -#ifndef yyoverflow +#if !defined(yyoverflow) || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ @@ -2117,7 +2197,7 @@ yyexhaustedlab: #endif yyreturn: - if (yychar != YYEOF && yychar != YYEMPTY) + if (yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval); /* Do not reclaim the symbols of the rule which action triggered @@ -2143,6 +2223,8 @@ yyreturn: } + +/* Line 1675 of yacc.c */ #line 552 "../xml/XPathGrammar.y" diff --git a/src/3rdparty/webkit/WebCore/generated/XPathGrammar.h b/src/3rdparty/webkit/WebCore/generated/XPathGrammar.h index cabe35a..f6c314d 100644 --- a/src/3rdparty/webkit/WebCore/generated/XPathGrammar.h +++ b/src/3rdparty/webkit/WebCore/generated/XPathGrammar.h @@ -1,24 +1,23 @@ -/* A Bison parser, made by GNU Bison 2.3. */ -/* Skeleton interface for Bison's Yacc-like parsers in C +/* A Bison parser, made by GNU Bison 2.4.1. */ - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +/* Skeleton interface for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -29,10 +28,11 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ + /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE @@ -59,33 +59,16 @@ XPATH_ERROR = 275 }; #endif -/* Tokens. */ -#define MULOP 258 -#define RELOP 259 -#define EQOP 260 -#define MINUS 261 -#define PLUS 262 -#define AND 263 -#define OR 264 -#define AXISNAME 265 -#define NODETYPE 266 -#define PI 267 -#define FUNCTIONNAME 268 -#define LITERAL 269 -#define VARIABLEREFERENCE 270 -#define NUMBER 271 -#define DOTDOT 272 -#define SLASHSLASH 273 -#define NAMETEST 274 -#define XPATH_ERROR 275 - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 56 "../xml/XPathGrammar.y" { + +/* Line 1676 of yacc.c */ +#line 56 "../xml/XPathGrammar.y" + Step::Axis axis; Step::NodeTest* nodeTest; NumericOp::Opcode numop; @@ -96,14 +79,17 @@ typedef union YYSTYPE Vector* argList; Step* step; LocationPath* locationPath; -} -/* Line 1489 of yacc.c. */ -#line 102 "XPathGrammar.tab.h" - YYSTYPE; + + + +/* Line 1676 of yacc.c */ +#line 87 "XPathGrammar.tab.h" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 #endif + diff --git a/src/3rdparty/webkit/WebCore/html/CanvasRenderingContext2D.cpp b/src/3rdparty/webkit/WebCore/html/CanvasRenderingContext2D.cpp index ceea77a..d50fef8 100644 --- a/src/3rdparty/webkit/WebCore/html/CanvasRenderingContext2D.cpp +++ b/src/3rdparty/webkit/WebCore/html/CanvasRenderingContext2D.cpp @@ -422,9 +422,7 @@ void CanvasRenderingContext2D::transform(float m11, float m12, float m21, float return; TransformationMatrix transform(m11, m12, m21, m22, dx, dy); - - TransformationMatrix newTransform = state().m_transform; - newTransform.multiply(transform); + TransformationMatrix newTransform = transform * state().m_transform; if (!newTransform.isInvertible()) { state().m_invertibleCTM = false; return; diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/qt/PathQt.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/qt/PathQt.cpp index e68be2b..5c39e11 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/qt/PathQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/graphics/qt/PathQt.cpp @@ -275,7 +275,9 @@ void Path::clear() bool Path::isEmpty() const { - return m_path->isEmpty(); + // Don't use QPainterPath::isEmpty(), as that also returns true if there's only + // one initial MoveTo element in the path. + return m_path->elementCount() == 0; } String Path::debugString() const diff --git a/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp index 3e9b239..83f4b1e 100644 --- a/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp +++ b/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp @@ -214,9 +214,11 @@ void QNetworkReplyHandler::finish() resetState(); start(); } else if (m_reply->error() != QNetworkReply::NoError - // a web page that returns 403/404 can still have content + // a web page that returns 401/403/404 can still have content && m_reply->error() != QNetworkReply::ContentOperationNotPermittedError - && m_reply->error() != QNetworkReply::ContentNotFoundError) { + && m_reply->error() != QNetworkReply::ContentNotFoundError + && m_reply->error() != QNetworkReply::AuthenticationRequiredError + && m_reply->error() != QNetworkReply::ProxyAuthenticationRequiredError) { QUrl url = m_reply->url(); ResourceError error(url.host(), m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), url.toString(), m_reply->errorString()); diff --git a/src/3rdparty/webkit/WebCore/platform/qt/FileSystemQt.cpp b/src/3rdparty/webkit/WebCore/platform/qt/FileSystemQt.cpp index 6dbe464..a369ddc 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/FileSystemQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/qt/FileSystemQt.cpp @@ -97,7 +97,7 @@ String pathGetFileName(const String& path) String directoryName(const String& path) { - return String(QFileInfo(path).baseName()); + return String(QFileInfo(path).absolutePath()); } Vector listDirectory(const String& path, const String& filter) diff --git a/src/3rdparty/webkit/WebCore/plugins/mac/PluginViewMac.cpp b/src/3rdparty/webkit/WebCore/plugins/mac/PluginViewMac.cpp index 569ed37..b85c748 100644 --- a/src/3rdparty/webkit/WebCore/plugins/mac/PluginViewMac.cpp +++ b/src/3rdparty/webkit/WebCore/plugins/mac/PluginViewMac.cpp @@ -369,10 +369,10 @@ void PluginView::setNPWindowIfNeeded() m_npWindow.height = m_windowRect.height(); // TODO: (also clip against scrollbars, etc.) - m_npWindow.clipRect.left = 0; - m_npWindow.clipRect.top = 0; - m_npWindow.clipRect.right = m_windowRect.width(); - m_npWindow.clipRect.bottom = m_windowRect.height(); + m_npWindow.clipRect.left = max(0, m_windowRect.x()); + m_npWindow.clipRect.top = max(0, m_windowRect.y()); + m_npWindow.clipRect.right = m_windowRect.x() + m_windowRect.width(); + m_npWindow.clipRect.bottom = m_windowRect.y() + m_windowRect.height(); PluginView::setCurrentPluginView(this); JSC::JSLock::DropAllLocks dropAllLocks(false); diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog index afbc770..a7e176d 100644 --- a/src/3rdparty/webkit/WebKit/qt/ChangeLog +++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog @@ -12,6 +12,25 @@ Reviewed by Simon Hausmann. + Fix crash with plugins when the plugin stream is cancelled. + + Similar to r26667 handle the case where didReceiveResponse on the + plugin view results in failure to set up the stream and + setMainDocumentError being called instead. This will set the + m_pluginView back to 0 and we need check for it before calling + didReceiveData. + + This was triggered by consecutive execution of + LayoutTests/plugins/return-error-from-new-stream-callback-in-full-frame-plugin.html + followed by LayoutTests/scrollbars/scrollbar-crash-on-refresh.html + + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::committedLoad): + +2009-07-13 Simon Hausmann + + Reviewed by Ariya Hidayat. + Fix a plugin bug in the WebKit code, similar to the one in WebCore. The problem is when a non visible QtPluginWidget would show it self diff --git a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp index a2b33c0..680a67a 100644 --- a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp +++ b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp @@ -680,6 +680,11 @@ void FrameLoaderClientQt::committedLoad(WebCore::DocumentLoader* loader, const c if (m_pluginView) { if (!m_hasSentResponseToPlugin) { m_pluginView->didReceiveResponse(loader->response()); + // didReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in + // setting up this stream can cause the main document load to be cancelled, setting m_pluginView + // to null + if (!m_pluginView) + return; m_hasSentResponseToPlugin = true; } m_pluginView->didReceiveData(data, length); -- cgit v0.12 From 8e0121795a784a1bcedfe3108e2aaf77f26eff6f Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 13 Jul 2009 17:08:11 +0200 Subject: Fix initialization of the HTML 5 offline storage. Place the databases into the normal data location. Reviewed-by: Ariya --- demos/browser/browserapplication.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/demos/browser/browserapplication.cpp b/demos/browser/browserapplication.cpp index 5ef3ce6..b27b5c1 100644 --- a/demos/browser/browserapplication.cpp +++ b/demos/browser/browserapplication.cpp @@ -205,6 +205,7 @@ void BrowserApplication::postLaunch() if (directory.isEmpty()) directory = QDir::homePath() + QLatin1String("/.") + QCoreApplication::applicationName(); QWebSettings::setIconDatabasePath(directory); + QWebSettings::setOfflineStoragePath(directory); setWindowIcon(QIcon(QLatin1String(":browser.svg"))); -- cgit v0.12 From dab07d0b8ec229bd601d99b6a20326bec3fd33c3 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 13 Jul 2009 17:14:23 +0200 Subject: Removed two generated files. They were added by accident. Nevermind :) Reviewed-by: Trust me --- .../webkit/JavaScriptCore/libJavaScriptCore.la | 28 ---------------------- .../JavaScriptCore/pkgconfig/JavaScriptCore.pc | 15 ------------ 2 files changed, 43 deletions(-) delete mode 100644 src/3rdparty/webkit/JavaScriptCore/libJavaScriptCore.la delete mode 100644 src/3rdparty/webkit/JavaScriptCore/pkgconfig/JavaScriptCore.pc diff --git a/src/3rdparty/webkit/JavaScriptCore/libJavaScriptCore.la b/src/3rdparty/webkit/JavaScriptCore/libJavaScriptCore.la deleted file mode 100644 index 10d3f1e..0000000 --- a/src/3rdparty/webkit/JavaScriptCore/libJavaScriptCore.la +++ /dev/null @@ -1,28 +0,0 @@ -# libJavaScriptCore.la - a libtool library file -# Generated by qmake/libtool (2.01a) (Qt 4.6.0) on: Mon Jun 15 18:55:09 2009 -# The name that we can dlopen(3). -dlname='' - -# Names of this library. -library_names=' ' - -# The name of the static archive. -old_library='libJavaScriptCore.a' - -# Libraries that this one depends upon. -dependency_libs='-L/depot/obuddenh/qt/lib -lQtGui -L/depot/obuddenh/qt/lib -L/usr/X11R6/lib -pthread -lpng -lfreetype -lgobject-2.0 -lSM -lICE -pthread -pthread -lXrender -lfontconfig -lXext -lX11 -lQtCore -lz -lm -pthread -lgthread-2.0 -lrt -lglib-2.0 -lpthread -ldl ' - -# Version information for libJavaScriptCore.la -current=46 -age=0 -revision=0 - -# Is this an already installed library. -installed=yes - -# Files to dlopen/dlpreopen. -dlopen='' -dlpreopen='' - -# Directory that this library needs to be installed in: -libdir='/depot/obuddenh/qt/lib' diff --git a/src/3rdparty/webkit/JavaScriptCore/pkgconfig/JavaScriptCore.pc b/src/3rdparty/webkit/JavaScriptCore/pkgconfig/JavaScriptCore.pc deleted file mode 100644 index fb90b0c..0000000 --- a/src/3rdparty/webkit/JavaScriptCore/pkgconfig/JavaScriptCore.pc +++ /dev/null @@ -1,15 +0,0 @@ -prefix=/depot/obuddenh/qt -exec_prefix=${prefix} -libdir=${prefix}/lib -includedir=${prefix}/include/JavaScriptCore -qt_config=lex yacc debug uic resources qt incremental link_prl exceptions no_mocdepend debug stl qt_no_framework debug largefile stl precompile_header separate_debug_info mmx 3dnow sse sse2 dylib create_prl link_prl depend_includepath QTDIR_build use_libmysqlclient_r building-libs staticlib depend_includepath qt_install_headers qt depend_includepath qmake_cache target_qt hide_symbols create_libtool create_pc explicitlib moc thread static staticlib -moc_location=${prefix}/bin/moc -uic_location=${prefix}/bin/uic - -Name: Javascriptcore -Description: Javascriptcore Library -Version: 4.6.0 -Libs: -L${libdir} -lJavaScriptCore -Libs.private: -L/depot/obuddenh/qt/lib -lQtGui -L/depot/obuddenh/qt/lib -L/usr/X11R6/lib -pthread -lpng -lfreetype -lgobject-2.0 -lSM -lICE -pthread -pthread -lXrender -lfontconfig -lXext -lX11 -lQtCore -lz -lm -pthread -lgthread-2.0 -lrt -lglib-2.0 -lpthread -ldl -Cflags: -DQT_SHARED -I/depot/obuddenh/qt/include -I${includedir} - -- cgit v0.12 From e15d415acbd426e58fb1e967eb331fe41488dfff Mon Sep 17 00:00:00 2001 From: Nils Jeisecke Date: Tue, 12 May 2009 14:47:49 +0200 Subject: Added QTextListFormat::ListUpperRoman and QTextListFormat::ListLowerRoman for roman numbering of lists as supported by HTML/ODF Reviewed-by: Olivier Goffart Merge-request: 681 --- demos/textedit/textedit.cpp | 8 ++++++ src/gui/text/qcssparser.cpp | 10 ++++--- src/gui/text/qcssparser_p.h | 2 ++ src/gui/text/qtextdocument.cpp | 7 ++++- src/gui/text/qtextdocumentlayout.cpp | 6 ++++- src/gui/text/qtextformat.cpp | 2 ++ src/gui/text/qtextformat.h | 2 ++ src/gui/text/qtexthtmlparser.cpp | 6 +++++ src/gui/text/qtextlist.cpp | 49 ++++++++++++++++++++++++++++++++++ src/gui/text/qtextodfwriter.cpp | 8 +++++- tests/auto/qtextlist/tst_qtextlist.cpp | 36 +++++++++++++++++++++++++ 11 files changed, 129 insertions(+), 7 deletions(-) diff --git a/demos/textedit/textedit.cpp b/demos/textedit/textedit.cpp index 17516b4..5eee855 100644 --- a/demos/textedit/textedit.cpp +++ b/demos/textedit/textedit.cpp @@ -336,6 +336,8 @@ void TextEdit::setupTextActions() comboStyle->addItem("Ordered List (Decimal)"); comboStyle->addItem("Ordered List (Alpha lower)"); comboStyle->addItem("Ordered List (Alpha upper)"); + comboStyle->addItem("Ordered List (Roman lower)"); + comboStyle->addItem("Ordered List (Roman upper)"); connect(comboStyle, SIGNAL(activated(int)), this, SLOT(textStyle(int))); @@ -573,6 +575,12 @@ void TextEdit::textStyle(int styleIndex) case 6: style = QTextListFormat::ListUpperAlpha; break; + case 7: + style = QTextListFormat::ListLowerRoman; + break; + case 8: + style = QTextListFormat::ListUpperRoman; + break; } cursor.beginEditBlock(); diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index ab69e5c..db5ed7c 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -199,6 +199,7 @@ static const QCssKnownValue values[NumKnownValues - 1] = { { "link", Value_Link }, { "link-visited", Value_LinkVisited }, { "lower-alpha", Value_LowerAlpha }, + { "lower-roman", Value_LowerRoman }, { "lowercase", Value_Lowercase }, { "medium", Value_Medium }, { "mid", Value_Mid }, @@ -230,6 +231,7 @@ static const QCssKnownValue values[NumKnownValues - 1] = { { "transparent", Value_Transparent }, { "underline", Value_Underline }, { "upper-alpha", Value_UpperAlpha }, + { "upper-roman", Value_UpperRoman }, { "uppercase", Value_Uppercase }, { "wave", Value_Wave }, { "window", Value_Window }, @@ -239,10 +241,10 @@ static const QCssKnownValue values[NumKnownValues - 1] = { }; //Map id to strings as they appears in the 'values' array above -static const short indexOfId[NumKnownValues] = { 0, 40, 47, 41, 48, 53, 34, 26, 68, 69, 25, 42, 5, 62, 46, - 29, 57, 58, 27, 50, 60, 6, 10, 38, 55, 19, 13, 17, 18, 20, 21, 49, 24, 45, 65, 36, 3, 2, 39, 61, 16, - 11, 56, 14, 32, 63, 54, 64, 33, 67, 8, 28, 37, 12, 35, 59, 7, 9, 4, 66, 52, 22, 23, 30, 31, 1, 15, 0, - 51, 44, 43 }; +static const short indexOfId[NumKnownValues] = { 0, 41, 48, 42, 49, 54, 35, 26, 70, 71, 25, 43, 5, 63, 47, + 29, 58, 59, 27, 51, 61, 6, 10, 39, 56, 19, 13, 17, 18, 20, 21, 50, 24, 46, 67, 37, 3, 2, 40, 62, 16, + 11, 57, 14, 32, 64, 33, 65, 55, 66, 34, 69, 8, 28, 38, 12, 36, 60, 7, 9, 4, 68, 53, 22, 23, 30, 31, + 1, 15, 0, 52, 45, 44 }; QString Value::toString() const { diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h index 8056f4d..b07acd5 100644 --- a/src/gui/text/qcssparser_p.h +++ b/src/gui/text/qcssparser_p.h @@ -223,6 +223,8 @@ enum KnownValue { Value_Decimal, Value_LowerAlpha, Value_UpperAlpha, + Value_LowerRoman, + Value_UpperRoman, Value_SmallCaps, Value_Uppercase, Value_Lowercase, diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 3287f31..3531699 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -2416,7 +2416,10 @@ void QTextHtmlExporter::emitFragment(const QTextFragment &fragment) static bool isOrderedList(int style) { return style == QTextListFormat::ListDecimal || style == QTextListFormat::ListLowerAlpha - || style == QTextListFormat::ListUpperAlpha; + || style == QTextListFormat::ListUpperAlpha + || style == QTextListFormat::ListUpperRoman + || style == QTextListFormat::ListLowerRoman + ; } void QTextHtmlExporter::emitBlockAttributes(const QTextBlock &block) @@ -2513,6 +2516,8 @@ void QTextHtmlExporter::emitBlock(const QTextBlock &block) case QTextListFormat::ListSquare: html += QLatin1String("
    (object)->itemText(bl); size.setWidth(fontMetrics.width(itemText)); size.setHeight(fontMetrics.height()); @@ -1426,7 +1428,9 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p switch (style) { case QTextListFormat::ListDecimal: case QTextListFormat::ListLowerAlpha: - case QTextListFormat::ListUpperAlpha: { + case QTextListFormat::ListUpperAlpha: + case QTextListFormat::ListLowerRoman: + case QTextListFormat::ListUpperRoman: { QTextLayout layout(itemText, font, q->paintDevice()); layout.setCacheEnabled(true); QTextOption option(Qt::AlignLeft | Qt::AlignAbsolute); diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index 9bc62b1..4e43418 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -2078,6 +2078,8 @@ QList QTextBlockFormat::tabPositions() const \value ListDecimal decimal values in ascending order \value ListLowerAlpha lower case Latin characters in alphabetical order \value ListUpperAlpha upper case Latin characters in alphabetical order + \value ListLowerRoman lower case roman numerals (supports up to 4999 items only) + \value ListUpperRoman upper case roman numerals (supports up to 4999 items only) \omitvalue ListStyleUndefined */ diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h index d269687..9697105 100644 --- a/src/gui/text/qtextformat.h +++ b/src/gui/text/qtextformat.h @@ -604,6 +604,8 @@ public: ListDecimal = -4, ListLowerAlpha = -5, ListUpperAlpha = -6, + ListLowerRoman = -7, + ListUpperRoman = -8, ListStyleUndefined = 0 }; diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp index 1bff162..a88cd17 100644 --- a/src/gui/text/qtexthtmlparser.cpp +++ b/src/gui/text/qtexthtmlparser.cpp @@ -1206,6 +1206,8 @@ void QTextHtmlParserNode::setListStyle(const QVector &cssValues) case QCss::Value_Decimal: hasOwnListStyle = true; listStyle = QTextListFormat::ListDecimal; break; case QCss::Value_LowerAlpha: hasOwnListStyle = true; listStyle = QTextListFormat::ListLowerAlpha; break; case QCss::Value_UpperAlpha: hasOwnListStyle = true; listStyle = QTextListFormat::ListUpperAlpha; break; + case QCss::Value_LowerRoman: hasOwnListStyle = true; listStyle = QTextListFormat::ListLowerRoman; break; + case QCss::Value_UpperRoman: hasOwnListStyle = true; listStyle = QTextListFormat::ListUpperRoman; break; default: break; } } @@ -1540,6 +1542,10 @@ void QTextHtmlParser::applyAttributes(const QStringList &attributes) node->listStyle = QTextListFormat::ListLowerAlpha; } else if (value == QLatin1String("A")) { node->listStyle = QTextListFormat::ListUpperAlpha; + } else if (value == QLatin1String("i")) { + node->listStyle = QTextListFormat::ListLowerRoman; + } else if (value == QLatin1String("I")) { + node->listStyle = QTextListFormat::ListUpperRoman; } else { value = value.toLower(); if (value == QLatin1String("square")) diff --git a/src/gui/text/qtextlist.cpp b/src/gui/text/qtextlist.cpp index addd7a5..02b1c63 100644 --- a/src/gui/text/qtextlist.cpp +++ b/src/gui/text/qtextlist.cpp @@ -212,6 +212,55 @@ QString QTextList::itemText(const QTextBlock &blockIt) const } } break; + case QTextListFormat::ListLowerRoman: + case QTextListFormat::ListUpperRoman: + { + if (item < 5000) { + QByteArray romanNumeral; + + // works for up to 4999 items + static const char romanSymbolsLower[] = "iiivixxxlxcccdcmmmm"; + static const char romanSymbolsUpper[] = "IIIVIXXXLXCCCDCMMMM"; + QByteArray romanSymbols; // wrap to have "mid" + if (style == QTextListFormat::ListLowerRoman) + romanSymbols = QByteArray::fromRawData(romanSymbolsLower, sizeof(romanSymbolsLower)); + else + romanSymbols = QByteArray::fromRawData(romanSymbolsUpper, sizeof(romanSymbolsUpper)); + + int c[] = { 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000 }; + int n = item; + for (int i = 12; i >= 0; n %= c[i], i--) { + int q = n / c[i]; + if (q > 0) { + int startDigit = i + (i+3)/4; + int numDigits; + if (i % 4) { + // c[i] == 4|5|9|40|50|90|400|500|900 + if ((i-2) % 4) { + // c[i] == 4|9|40|90|400|900 => with substraction (IV, IX, XL, XC, ...) + numDigits = 2; + } + else { + // c[i] == 5|50|500 (V, L, D) + numDigits = 1; + } + } + else { + // c[i] == 1|10|100|1000 (I, II, III, X, XX, ...) + numDigits = q; + } + + romanNumeral.append(romanSymbols.mid(startDigit, numDigits)); + } + } + result = QString::fromLatin1(romanNumeral); + } + else { + result = QLatin1String("?"); + } + + } + break; default: Q_ASSERT(false); } diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp index b0c16ee..883cf80 100644 --- a/src/gui/text/qtextodfwriter.cpp +++ b/src/gui/text/qtextodfwriter.cpp @@ -174,6 +174,10 @@ static QString bulletChar(QTextListFormat::Style style) return QString::fromLatin1("a"); case QTextListFormat::ListUpperAlpha: return QString::fromLatin1("A"); + case QTextListFormat::ListLowerRoman: + return QString::fromLatin1("i"); + case QTextListFormat::ListUpperRoman: + return QString::fromLatin1("I"); default: case QTextListFormat::ListStyleUndefined: return QString(); @@ -619,7 +623,9 @@ void QTextOdfWriter::writeListFormat(QXmlStreamWriter &writer, QTextListFormat f QTextListFormat::Style style = format.style(); if (style == QTextListFormat::ListDecimal || style == QTextListFormat::ListLowerAlpha - || style == QTextListFormat::ListUpperAlpha) { + || style == QTextListFormat::ListUpperAlpha + || style == QTextListFormat::ListLowerRoman + || style == QTextListFormat::ListUpperRoman) { writer.writeStartElement(textNS, QString::fromLatin1("list-level-style-number")); writer.writeAttribute(styleNS, QString::fromLatin1("num-format"), bulletChar(style)); writer.writeAttribute(styleNS, QString::fromLatin1("num-suffix"), QString::fromLatin1(".")); diff --git a/tests/auto/qtextlist/tst_qtextlist.cpp b/tests/auto/qtextlist/tst_qtextlist.cpp index 658b8bb..e41d3be 100644 --- a/tests/auto/qtextlist/tst_qtextlist.cpp +++ b/tests/auto/qtextlist/tst_qtextlist.cpp @@ -67,6 +67,8 @@ private slots: void item(); void autoNumbering(); void autoNumberingRTL(); + void romanNumbering(); + void romanNumberingLimit(); void formatChange(); void cursorNavigation(); void partialRemoval(); @@ -142,6 +144,40 @@ void tst_QTextList::autoNumberingRTL() QVERIFY(cursor.currentList()->itemText(cursor.block()) == ".B"); } +void tst_QTextList::romanNumbering() +{ + QTextListFormat fmt; + fmt.setStyle(QTextListFormat::ListUpperRoman); + QTextList *list = cursor.createList(fmt); + QVERIFY(list); + + for (int i = 0; i < 4998; ++i) + cursor.insertBlock(); + + QVERIFY(list->count() == 4999); + + QVERIFY(cursor.currentList()); + QVERIFY(cursor.currentList()->itemNumber(cursor.block()) == 4998); + QVERIFY(cursor.currentList()->itemText(cursor.block()) == "MMMMCMXCIX."); +} + +void tst_QTextList::romanNumberingLimit() +{ + QTextListFormat fmt; + fmt.setStyle(QTextListFormat::ListLowerRoman); + QTextList *list = cursor.createList(fmt); + QVERIFY(list); + + for (int i = 0; i < 4999; ++i) + cursor.insertBlock(); + + QVERIFY(list->count() == 5000); + + QVERIFY(cursor.currentList()); + QVERIFY(cursor.currentList()->itemNumber(cursor.block()) == 4999); + QVERIFY(cursor.currentList()->itemText(cursor.block()) == "?."); +} + void tst_QTextList::formatChange() { // testing the formatChanged slot in QTextListManager -- cgit v0.12 From 9db4b800a2c8da5916a6d5da9e37a17d185cdc5e Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 13 Jul 2009 17:07:42 +0200 Subject: More tests for list numbering --- .../tst_qtextdocumentfragment.cpp | 10 ++++++ tests/auto/qtextlist/tst_qtextlist.cpp | 40 ++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/tests/auto/qtextdocumentfragment/tst_qtextdocumentfragment.cpp b/tests/auto/qtextdocumentfragment/tst_qtextdocumentfragment.cpp index 56f5e7a..4559daa 100644 --- a/tests/auto/qtextdocumentfragment/tst_qtextdocumentfragment.cpp +++ b/tests/auto/qtextdocumentfragment/tst_qtextdocumentfragment.cpp @@ -2758,6 +2758,16 @@ void tst_QTextDocumentFragment::css_listStyleType() QVERIFY(cursor.currentList()); QVERIFY(cursor.currentList()->format().style() == QTextListFormat::ListUpperAlpha); + doc->setHtml("
    • Blah
    "); + cursor.movePosition(QTextCursor::End); + QVERIFY(cursor.currentList()); + QVERIFY(cursor.currentList()->format().style() == QTextListFormat::ListUpperRoman); + + doc->setHtml("
    • Blah
    "); + cursor.movePosition(QTextCursor::End); + QVERIFY(cursor.currentList()); + QVERIFY(cursor.currentList()->format().style() == QTextListFormat::ListLowerRoman); + // ignore the unsupported list-style-position inside the list-style shorthand property doc->setHtml("
    • Blah
    "); cursor.movePosition(QTextCursor::End); diff --git a/tests/auto/qtextlist/tst_qtextlist.cpp b/tests/auto/qtextlist/tst_qtextlist.cpp index e41d3be..4ab6f5a 100644 --- a/tests/auto/qtextlist/tst_qtextlist.cpp +++ b/tests/auto/qtextlist/tst_qtextlist.cpp @@ -77,6 +77,8 @@ private slots: void add(); void defaultIndent(); void blockUpdate(); + void numbering_data(); + void numbering(); private: QTextDocument *doc; @@ -336,5 +338,43 @@ void tst_QTextList::blockUpdate() QVERIFY(!layout->error); } +void tst_QTextList::numbering_data() +{ + QTest::addColumn("format"); + QTest::addColumn("number"); + QTest::addColumn("result"); + + QTest::newRow("E.") << int(QTextListFormat::ListUpperAlpha) << 5 << "E."; + QTest::newRow("abc.") << int(QTextListFormat::ListLowerAlpha) << (26 + 2) * 26 + 3 << "abc."; + QTest::newRow("12.") << int(QTextListFormat::ListDecimal) << 12 << "12."; + QTest::newRow("XXIV.") << int(QTextListFormat::ListUpperRoman) << 24 << "XXIV."; + QTest::newRow("VIII.") << int(QTextListFormat::ListUpperRoman) << 8 << "VIII."; + QTest::newRow("xxx.") << int(QTextListFormat::ListLowerRoman) << 30 << "xxx."; + QTest::newRow("xxix.") << int(QTextListFormat::ListLowerRoman) << 29 << "xxix."; +// QTest::newRow("xxx. alpha") << int(QTextListFormat::ListLowerAlpha) << (24 * 26 + 24) * 26 + 24 << "xxx."; //Too slow +} + +void tst_QTextList::numbering() +{ + QFETCH(int, format); + QFETCH(int, number); + QFETCH(QString, result); + + + QTextListFormat fmt; + fmt.setStyle(QTextListFormat::Style(format)); + QTextList *list = cursor.createList(fmt); + QVERIFY(list); + + for (int i = 1; i < number; ++i) + cursor.insertBlock(); + + QCOMPARE(list->count(), number); + + QVERIFY(cursor.currentList()); + QCOMPARE(cursor.currentList()->itemNumber(cursor.block()), number - 1); + QCOMPARE(cursor.currentList()->itemText(cursor.block()), result); +} + QTEST_MAIN(tst_QTextList) #include "tst_qtextlist.moc" -- cgit v0.12 From ecffc68ab222309e30d83a55022169cef9acfd81 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 13 Jul 2009 17:24:43 +0200 Subject: Fix WebKit import url Fix the contents of src/3rdparty/webkit/VERSION to point to gitorious.org Reviewed-by: Trust me --- util/webkit/mkdist-webkit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/webkit/mkdist-webkit b/util/webkit/mkdist-webkit index c26fdc1..f63bf22 100755 --- a/util/webkit/mkdist-webkit +++ b/util/webkit/mkdist-webkit @@ -268,7 +268,7 @@ rm -rf $srcdir/WebKitBuild cat >$srcdir/VERSION < Date: Mon, 13 Jul 2009 17:26:02 +0200 Subject: Fix import of WebKit from the trunk Don't try to remove the scons files, as they were removed upstream. Reviewed-by: Trust me --- util/webkit/mkdist-webkit | 2 -- 1 file changed, 2 deletions(-) diff --git a/util/webkit/mkdist-webkit b/util/webkit/mkdist-webkit index 1837dd5..9e9d656 100755 --- a/util/webkit/mkdist-webkit +++ b/util/webkit/mkdist-webkit @@ -154,10 +154,8 @@ files_to_remove="$files_to_remove WebKit/qt/QtLauncher/main.cpp" files_to_remove="$files_to_remove JavaScriptCore/AllInOneFile.cpp" files_to_remove="$files_to_remove JavaScriptCore/JavaScriptCoreSources.bkl" -files_to_remove="$files_to_remove JavaScriptCore/SConstruct" files_to_remove="$files_to_remove JavaScriptCore/jscore.bkl" -files_to_remove="$files_to_remove WebCore/SConstruct" files_to_remove="$files_to_remove WebCore/WebCoreSources.bkl" files_to_remove="$files_to_remove WebCore/webcore-base.bkl" files_to_remove="$files_to_remove WebCore/webcore-wx.bkl" -- cgit v0.12 From 3e5d7444b883778663d1e31e54afffae65921da3 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 13 Jul 2009 17:45:53 +0200 Subject: Updated WebKit from /home/shausman/src/webkit/trunk to origin/qtwebkit-4.5 ( a3e05ad8acdead3b534d0cef772b85f002e80b8d ) Changes in WebKit since the last update: ++ b/LayoutTests/ChangeLog 2009-06-18 Chris Evans Reviewed by Adam Barth. Added test for bug 26454 (broken 8-digit hex entities). https://bugs.webkit.org/show_bug.cgi?id=26454 * fast/parser/eightdigithexentity-expected.txt: Added. * fast/parser/eightdigithexentity.html: Added. 2009-06-20 Sam Weinig Reviewed by Adam Barth. Test for https://bugs.webkit.org/show_bug.cgi?id=26554 Test writing to parent and top. * http/tests/security/cross-frame-access-put-expected.txt: * http/tests/security/cross-frame-access-put.html: * http/tests/security/resources/cross-frame-iframe-for-put-test.html: ++ b/WebCore/ChangeLog 2009-06-18 Chris Evans Reviewed by Adam Barth. Fix 8-digit long hex entities. Fixes bug 26454 https://bugs.webkit.org/show_bug.cgi?id=26454 Test: fast/parser/eightdigithexentity.html * html/HTMLTokenizer.cpp: fix off-by-ones. 2009-06-20 Sam Weinig Reviewed by Adam Barth. Fix for https://bugs.webkit.org/show_bug.cgi?id=26554 Shadowing of top and parent * page/DOMWindow.idl: --- src/3rdparty/webkit/VERSION | 4 ++-- src/3rdparty/webkit/WebCore/ChangeLog | 20 ++++++++++++++++++++ .../webkit/WebCore/generated/JSDOMWindow.cpp | 4 ++++ src/3rdparty/webkit/WebCore/html/HTMLTokenizer.cpp | 8 ++++++-- src/3rdparty/webkit/WebCore/page/DOMWindow.idl | 4 ++-- 5 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 368d2b5..88f32d9 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -1,6 +1,6 @@ This is a snapshot of the Qt port of WebKit from - git://code.staikos.net/webkit + git://gitorious.org/qtwebkit/qtwebkit.git The commit imported was from the @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - eb4957a561d3f85d4cd5602832375c66f378b521 + a3e05ad8acdead3b534d0cef772b85f002e80b8d diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index be6922f..19bb36a 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,23 @@ +2009-06-18 Chris Evans + + Reviewed by Adam Barth. + + Fix 8-digit long hex entities. Fixes bug 26454 + https://bugs.webkit.org/show_bug.cgi?id=26454 + + Test: fast/parser/eightdigithexentity.html + + * html/HTMLTokenizer.cpp: fix off-by-ones. + +2009-06-20 Sam Weinig + + Reviewed by Adam Barth. + + Fix for https://bugs.webkit.org/show_bug.cgi?id=26554 + Shadowing of top and parent + + * page/DOMWindow.idl: + 2008-12-18 Bernhard Rosenkraenzer Reviewed by Darin Adler. diff --git a/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.cpp b/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.cpp index c6906b6..d692150 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.cpp @@ -2496,11 +2496,15 @@ void setJSDOMWindowOpener(ExecState* exec, JSObject* thisObject, JSValuePtr valu void setJSDOMWindowParent(ExecState* exec, JSObject* thisObject, JSValuePtr value) { + if (!static_cast(thisObject)->allowsAccessFrom(exec)) + return; static_cast(thisObject)->putDirect(Identifier(exec, "parent"), value); } void setJSDOMWindowTop(ExecState* exec, JSObject* thisObject, JSValuePtr value) { + if (!static_cast(thisObject)->allowsAccessFrom(exec)) + return; static_cast(thisObject)->putDirect(Identifier(exec, "top"), value); } diff --git a/src/3rdparty/webkit/WebCore/html/HTMLTokenizer.cpp b/src/3rdparty/webkit/WebCore/html/HTMLTokenizer.cpp index 6de9951..b6a5418 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLTokenizer.cpp +++ b/src/3rdparty/webkit/WebCore/html/HTMLTokenizer.cpp @@ -867,7 +867,9 @@ HTMLTokenizer::State HTMLTokenizer::parseEntity(SegmentedString& src, UChar*& de } } else { // FIXME: We should eventually colorize entities by sending them as a special token. - checkBuffer(11); + // 12 bytes required: up to 10 bytes in m_cBuffer plus the + // leading '&' and trailing ';' + checkBuffer(12); *dest++ = '&'; for (unsigned i = 0; i < cBufferPos; i++) dest[i] = m_cBuffer[i]; @@ -878,7 +880,9 @@ HTMLTokenizer::State HTMLTokenizer::parseEntity(SegmentedString& src, UChar*& de } } } else { - checkBuffer(10); + // 11 bytes required: up to 10 bytes in m_cBuffer plus the + // leading '&' + checkBuffer(11); // ignore the sequence, add it to the buffer as plaintext *dest++ = '&'; for (unsigned i = 0; i < cBufferPos; i++) diff --git a/src/3rdparty/webkit/WebCore/page/DOMWindow.idl b/src/3rdparty/webkit/WebCore/page/DOMWindow.idl index d0114e6..71c3137 100644 --- a/src/3rdparty/webkit/WebCore/page/DOMWindow.idl +++ b/src/3rdparty/webkit/WebCore/page/DOMWindow.idl @@ -121,8 +121,8 @@ module window { attribute [Replaceable, DoNotCheckDomainSecurityOnGet] DOMWindow frames; attribute [Replaceable, DoNotCheckDomainSecurityOnGet] DOMWindow opener; - attribute [Replaceable, DoNotCheckDomainSecurity] DOMWindow parent; - attribute [Replaceable, DoNotCheckDomainSecurity] DOMWindow top; + attribute [Replaceable, DoNotCheckDomainSecurityOnGet] DOMWindow parent; + attribute [Replaceable, DoNotCheckDomainSecurityOnGet] DOMWindow top; // DOM Level 2 AbstractView Interface readonly attribute Document document; -- cgit v0.12 From 46df9f83cb64541f7d9ecd34645ef1558ce1c0c6 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Mon, 13 Jul 2009 17:53:34 +0200 Subject: Fixed a potential memory leak on XP Calling OpenThemeData directly causes a leak when changing the style as we do not call the corresponding CloseThemeData. Task-number:257916 Reviewed-by:prasanth --- src/gui/styles/qwindowsxpstyle.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/styles/qwindowsxpstyle.cpp b/src/gui/styles/qwindowsxpstyle.cpp index 2abf3bc..1b8ceae 100644 --- a/src/gui/styles/qwindowsxpstyle.cpp +++ b/src/gui/styles/qwindowsxpstyle.cpp @@ -1202,7 +1202,8 @@ QRect QWindowsXPStyle::subElementRect(SubElement sr, const QStyleOption *option, if (const QStyleOptionButton *btn = qstyleoption_cast(option)) { MARGINS borderSize; if (widget) { - HTHEME theme = pOpenThemeData(QWindowsXPStylePrivate::winId(widget), L"Button"); + XPThemeData buttontheme(widget, 0, QLatin1String("Button")); + HTHEME theme = buttontheme.handle(); if (theme) { int stateId; if (!(option->state & State_Enabled)) @@ -3611,7 +3612,8 @@ QSize QWindowsXPStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt case CT_LineEdit: case CT_ComboBox: { - HTHEME theme = pOpenThemeData(QWindowsXPStylePrivate::winId(widget), L"Button"); + XPThemeData buttontheme(widget, 0, QLatin1String("Button")); + HTHEME theme = buttontheme.handle(); MARGINS borderSize; if (theme) { int result = pGetThemeMargins(theme, -- cgit v0.12 From b7598e32617ea8608d7c82800e1706d9180ddbd9 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 13 Jul 2009 17:53:49 +0200 Subject: make examples/activeqt/webbrowser work on Windows CE This example only worked on desktop Windows and Windows mobile. Windows CE uses the same GUID for the Internet Explorer ActiveX control like desktop Windows. Task-number: 255111 Reviewed-by: thartman --- examples/activeqt/webbrowser/main.cpp | 4 +- .../webbrowser/mainwindow_windowsmobile.ui | 299 +++++++++++++++++++++ examples/activeqt/webbrowser/webbrowser.pro | 2 +- examples/activeqt/webbrowser/wincemainwindow.ui | 299 --------------------- 4 files changed, 302 insertions(+), 302 deletions(-) create mode 100644 examples/activeqt/webbrowser/mainwindow_windowsmobile.ui delete mode 100644 examples/activeqt/webbrowser/wincemainwindow.ui diff --git a/examples/activeqt/webbrowser/main.cpp b/examples/activeqt/webbrowser/main.cpp index ab14c0b..e83ef56 100644 --- a/examples/activeqt/webbrowser/main.cpp +++ b/examples/activeqt/webbrowser/main.cpp @@ -46,8 +46,8 @@ #include #include -#if defined(Q_OS_WINCE) -#include "ui_wincemainwindow.h" +#if defined(Q_WS_WINCE_WM) +#include "ui_mainwindow_windowsmobile.h" #include #else #include "ui_mainwindow.h" diff --git a/examples/activeqt/webbrowser/mainwindow_windowsmobile.ui b/examples/activeqt/webbrowser/mainwindow_windowsmobile.ui new file mode 100644 index 0000000..98a9ddb --- /dev/null +++ b/examples/activeqt/webbrowser/mainwindow_windowsmobile.ui @@ -0,0 +1,299 @@ + + MainWindow + + + MainWindow + + + + 0 + 0 + 812 + 605 + + + + Qt WebBrowser + + + + + unnamed + + + 0 + + + 6 + + + + + Frame3 + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + unnamed + + + 1 + + + 0 + + + + + WebBrowser + + + Qt::StrongFocus + + + {F5AFC7EF-1571-48B6-A69C-F1833F4C3A44} + + + + + + + + + + + tbNavigate + + + Navigation + + + + + + + + + + + + tbAddress + + + Address + + + + lblAddress + + + Address + + + + + addressEdit + + + + + + + menubar + + + + PopupMenu + + + &File + + + + FileNewGroup_2 + + + New + + + + + + + + + + + unnamed + + + &Help + + + + + + + + + + actionGo + + + image0 + + + Go + + + + + actionBack + + + image1 + + + Back + + + Backspace + + + + + actionForward + + + image2 + + + Forward + + + + + actionStop + + + image3 + + + Stop + + + + + actionRefresh + + + image4 + + + Refresh + + + + + actionHome + + + image5 + + + Home + + + + + actionFileClose + + + Close + + + C&lose + + + + + actionSearch + + + image6 + + + Search + + + + + actionAbout + + + About + + + + + actionAboutQt + + + About Qt + + + + + + actionNewWindow + + + Window + + + Ctrl+N + + + + FileNewGroup + + + + + + addressEdit + returnPressed() + actionGo + trigger() + + + + + + 789cd3d7528808f055d0d2e72a2e492cc94c5648ce482c52d04a29cdcdad8c8eb5ade65232365200210543251d2e253d856405bffcbc54103b11c8563600020b03105719c4b530b08072f50880513560a09c080338d5209420294a4451a38c90426621ab5146d10de524a2aa417505445122861a547722bb0c971a3d2aa921c2ae446c6a9431fc85a9064551220e354009653dec00294e712a1ac4e97078a9a9b5e6020013b3f563 + + + 789ce596497332470c86effe15947573a5f4c1cc30cc542a07ef60bc808dd7540e3d9b6df006186c93ca7f8fba2535ce57be98dc9292313c487a2575f7ccf063a376d53baa6dfc589bbe9ad7fbbc96df99496da3983d3e7efcfec76f7faead87418dfe1a51500bd67f595befbfd6f2daf1f35369014e08a05e6fd4ab96e31e73d0282bc7a7cae23ff3ccfe8170ca6cee9843f51f3b4ec8cff9efccdebf2d2cf9b06bb9417a25c74f98bdff99390a84fb8e49af70f39891b2e40bfbf8b6b0917e87968346a8f5a6cc51c07ab02f2cf1983237552f709c86691e3bbd5be5821998a32067bd1765d13f67563d530a4b3df8b01c523d8ec74059faed086bfc82390e851b8ed3c86485e34365a9bfc5ece3df8433e10bcb5140f5dd3cf0e099f32f99e350cecb5858f2b1c1dc52fda663d334a277c0ecfd5d61c9373973120967969b548fd71b079e797d8e985b21eb63aecceb85e7c299f4ffaa2ce7739359ebc195631387c6ad1f5e302791ccbba72cf173e15cfa2d2cc7619cf1fa63c9dccaa4ff4bcfdc7fa82cfdf7999348f6bf299c4bfd4c59ea0f99535dafca71d60a65ffebca52ff8c3989e47cce98351fb785759e7bcbad65bf0be624ca9a8e87caac0fb1702ef191b2cc9731a7b9ec4f87d934659e27e142f8c671e6eb9d0ae7b2be07cc6924ccf999698a7e4f58f572e64cebb9f393444994e68e4365d9ff7be15caef70766ad678cb0f8f18359ebe109b3af27f199fadd794cf254eb196599774758e77d5496f5dd64a67959af122ef87c639b59eb81d34ba97fe3f4215196f3922acbbc28acf527cc792c7a857029ecf63bcded05efb8a52cf3cc9833ed2f66563dac0b8b1ebe3317ea77f73352173db8f6ccf54a66df0f30fb7c777d9bc214d2cf88d9cf73cfece3ddf3296b66da7fe199d7a32b5cc8feef31fbfe8f99bdde96b0faddf3272bac390665b99e90d9e7ef33972de9d73d7ff3d873255c49fc1b73257ee4f8d2eb5d336b3e8e8535ff86d9e7bbf35f2cf51366ef77cfeb6299df62563f3c0a8b1fdcf3d3569778773f756e66f7fcac967e175f797ffff5dfd9ff4103010d6698a35955030b2cb1c25bbcc3fbd5344861882352b8c5077c5c45836678c267ca7fc1314ebeaf81537cc599eb608e6ff88e1f2b682c705314b6486182dbb8f31d0ddca529f644619ff2db641d3cf82a8bfa9d62d7da670d3cc4233c760a63eaa08d2734478fac8f87ffc833788a6738c073bc20ebe3255eb1069d863e5e3b851bacfb7c6b0d0c30c488f24a3a2d4ddaf1986a3d600b13179be280ef597809e876e206000c69d8ec0e590f32c8a18012b7a0825b9799e018eee0de4e0b4318c103ff2ea2985b78c47d28a487ce276b634cca40356d1655801c3bf044af2136e0195ef8b711be4045ab50ff42e16bdbb6463d8e610253fe3d4855ec3ed80abd9f62397ef9c9e6cee835249bc31bbc731ff0010beacbcdbfaca29f2836a3e839fd1f3acb5cb6fd6e13b6605b34766097d6664cdf0d7faad9813dd827df08daf4de812ddaa7061c4017baf43ea6daef70c8fb0247704c932dc897b94e67da09553a811ef4a94a0f4ee10c069435216b630ae7a43b800b7fc6164ea543ea73ea75663b22a50e5cc215ec50956beaf606ead08080147b64c76403d20ebdc6142268528d3655ee3a1db6f88b535ee015b42081d4205ee1f4f335878501ea7644331dc81acecdb7ef63b86b32eae59956cff63237f92af7319c9a82669c989256bd0b6fa6fabe86bbfe0ecdadb9a399ce61b49a86355adfbedd45736756bc27b30afd161a9a9179585de33bf69fd2f8ebd7b5bf014644b906 + + + 789ce5965b4f23471085dff915d6d6db2aaac5e3b92aca037703cbc55c8c21ca43cf8c8d0dd85c6c307694ff9eeaaed3bd68771f968d14298a0a109fabebd4e99a9ef17cfad8e81d1f343e7e5a99cecc6c5435aaa1796a7cac9fc7e3c5ef7ffcf6e7ca8756d4909f661c35a20fbfac7ce8cc1a55e3f07ed2b7409702b4badaccfb996563020f5c7ecbf340b9a31c3591dff7ac7943e002cc8e73cf74acdcc27a8a2d37a5be4e1d9f04567f9fc105f25dcfea9726caad62a07c1158f58f94e3087e868ea57fa5fa0be590bfb11c3525affd4e03ebfa25b8507fbcaa1c47ca66e459fdf10c6c30af4dcfda8f5f9513dfffce71e1f5a956967adddfaeb25f4f7b60e8d199e596f42f6bc787ca213f554e5be06dc7a28ffdee282791cedb5c83d19fd795a55ecf4b3fb0ee07ebd312fae796e3283665e238524e2265de031bcc774d396d61be25b8c4fe1f02abfeab67f49f2867decfbd6393b6a03f03438f3bca19fa51cb33fc6f80fd7eae2c27e257e7cb4de5b4045f78d679f24960ddcfb172e6f73357ce63e88fc115ce43e558fcabbeb905fb7e47cae24ff5daca41af007bbd81e5b425f53aff6160d52f95f318f37d01a39ee7ca05f4790a469e0e1c97590bfa1b81f53c3e2bfbf5ecf697b532efe754398f31af437085eb65948b18e723f70cbf9e2bcc633db0f65b533609fcbafb372bf318fdcfc015e65b281731ee0ff6acf70767ca5e8f7be01abcab5cfa7e89e53cce2ba3fd1681b5df8172013f44e00acfbf4a39e8ef287b7dbe02234feefce795d727a36c12ccf75239d4b7c1bede9def42fcc0ef7960d5cbc05ebf543635aed752b94aa1ff02ee83ddf3b6a87c3d3f2b9b047a4fcaa17e0cf6f5eef928ab13f5476960d5eb7ac6f5dd07d7e04839e83d29d7be9ffbfe31b50dc723cfa87f08acf947e51a7ad457ee6760773ecaa4f47e36036bfd96673c3fb6c13578a01cf41f9505d5af3b2f655dc28fa93da33e550ef523e5e06f08861eb9e7b94cdfe7ddf753d50feb6f94437e00f67edcf3aa4e831ed8afe73bb05fefe655f7c37edcfd62bb81ddfb82935776cfeb41c87766ff2cfe7f1a4c6cb8e48ae91f68d4dce7015ff390473fad71c3b77cc7639ef03d3ffcb48f013ff293a84c79c6d54f693c8bc28b28589539bff2e2ed647e586389184bacf13a6ff0e6d71a32f92dde96bfdf9dbccc6387dba2d086caae4c668ff7bf68f0673ee0433ee263eef0099ff2199f8b62d0e32e5f704fea2fe5b70d3f57729556b91b349a1c718b634e64faa9fc7fc919e772220a91213254ca273b884bf72b4a54f1846ad925e93b1af56940d734a4110fe4efb5c40dddda907311734c7752d10b3a1ae289c634a17b7dafe331e995b3b124fbdfd25d85471763596fab7aa2a4f53d444653ded3773bb96e8faeae1de2ea8dff9da0b0ebfcd858e3357aa667bb1f68b4a5e7d256853559e8f56d64aefe85e6f44a0b5aea3bac5c2bebf74b8775fb6bfbb858771e7a6f1df09c36f89a36698bb6f53d5c4ef08ee4e6a2dd269b9d488729ed4a171b7bd40ece3228cce5d305edd3673ed7773139bd133a14d5233a96cff7a9237142a77446e7125dba900e70681564f5a6acdc1285ae9e0feaf150d675e8d2d59dd315ad52931fec2973d1a5489c6698e29c5a508829797bd629a52665bcf9fdd32ed95c1d50217b5c18b67390f34befb8e78873a9b6b39ad285216328a2de3bef5b32a59db5ccec42a6b565aaf7dffba6e663d3972b211ea86b065f3cbccbc7b53890399a21a55f677f5863e4f670c337df667f58e3d6dc99dbef3dd5ff6bdf73ff82c65fbfaefc0d4fb5b868 + + + 789cd3d7528808f055d0d2e72a2e492cc94c5648ce482c52d04a29cdcdad8c8eb5ade65232325500210543251d2e25658564056503300071f540dc3430007371012a492a830156496538c094848922c9c2259134c099304914e3604c8424aa5e6449b0044216ca824ba2da8b4512218b4d122e8b55520fee5974072164511da487ea490c7f22cba249e20d3efc018f3fcae0d2702eb5d2106992b5d65c00b9a48974 + + + 789cd3d7528808f055d0d2e72a2e492cc94c5648ce482c52d04a29cdcdad8c8eb5ade65232365200210543251d2e253d856405bffcbc54105b19c8563600020b03103711c4b530b08072f50880513524ab518681443435ca984ae08ae06a94114a10ac443435ca3043904d4c4453a38ca604ae11590d9a0ab80bd0d46078914c35c4d885a608871a547f61f81d5d117a1862018930e5b8d5c0950c741a1b1e6a6aadb90086a9d853 + + + 789ca5985973db480ec7dff3295cc15b6a0b2351a428d6d63ef83e255bbe647b6a1fd02465dd872d9f53f3dd076c005dc926ce6a32eed8553f37fadf7fa0c1a69cdfbe6cdc9cb537befcf6e97145ab61be910fe861e34bf1349dbefdfedffffcf1e97323dae07f51bdbe117dfed7a7cfddd546bed199cfca0ae888016afeab62e8796ef110ee545caf05be16ae5bfc6ee096e7b6e756983f51b6f53b81257ecfb8eee7e9b162f66af1c78125fe48987f23f3fb81657e691cd5bddecc7316d555efd058f7eb2867aa771058f4de8c55cffb6dd4a34cf5b68d357e681c6515634db81a7e3ef59c35cccf5560bf9ef6953389c77660af074f15c751e05c38a6d81f2ef9f3a848f4e9d658f2c36b635dbfa54cc2383556bd33e12492fc70df38f1f3f8ae4cc2745a711285fda7caa4f95e06967a2d8c63f27a8fc2a60fa4acfa980a371b898f0767dc6cf8fdbc9f84c27e4de124d2fabe186b3dee8c75ff1365dbef2db0ccef0987fd2f2a6632fd576552fd2b63d57b08ecd7d39d70b321fd0560acfb6d1a4b7e3050764de7d79f08a70de937ea7b7689e68f4de1e0776e2c7ab8abecb47eb170aa7ee822b0e89f1b4b7fd24dc529abe9794f02cbf99e2b3badc7a5b1ee97089b3e0e8d253f3c364e253e5576120ff7c63a9f7966d2e771d358e75bca4ef3bb0e2cf9758db5fe47c6b21eeb81bd3f07c2ad58ebd130d67e6a194b3cf97e62b2fa24c67a1f5d2aab3f8781a53e17c6eaa7082cfa3de156acf9d5034b7e3563f1eb96c6eaf7c0b815fbf8d2739e3aedefb1b1de9723618b77a49cebf946c6e20f5f8d251e753e8b5bb9e74c980a4afc7a7fbf66b1ed8fb7c67a9ec7c2ad5cfd74038bdfa6b1f6cbd458fd2e84b358efbb0363f5b71358fccd8c33596f9c4bfddcc458fac78d8cf5797b3296f5f82c4c49e6f5c9bf9fb23ce41307967e3935d6f36c0b67b1ce3f188b5f3757367f5363b98fdc38b0cc0f8cf5f90bf3ea97028bfe50981289777d63edcf81b1c4439897f3c52d615738cfe0df371c1deb7db265acf98d8d253f7a50d67a60c758cfcbf4cc7f2fb0f8bf1736bfae30d6f35f1a4b3ce6c6e2df95ca85f6f7dc58f3db0e5c783e14e6ebc533e87e963fbe0873f9fd3cc97c91693fd028b0d4e3c558f3eb0b9b5f972bab3fe78c353f3056bfabc0e2371636bfe4cf9b29d1e76b69acfdb863accfd33cb0dc2fa7c6e2179e03cb79ae940b7dffbf1b6bfd1363f53b12367f581a6b3d1bca56df6e60a9bfc6e765def4ecef6bc7eafaf9e8d558fbb7a15ce87d7263acf7ffbdb1e40f33e1e0cf29ebfea8eb6d7ff29f17f8f4137dfe51d8fa0117ca65ee3fbfe3bd705116b2de9f775e3af50313e1a229f1f0682cf1b052e6e1d9dfbf1cddd4fd2363cdcfef5fb05b7d1f0c944bed4f67ac9f5f27c265bf4c3d9f07eefb787f1f96695eaa1e0a174d7d7f81b1ee4f81a5fe75e552d9bf1fca7e617e9e8d556f33b0c4fbcf5ffdb44c956bc6a2d75dfd6c2020fd3ce2ff69a0c31c0b2cff91461fef71804374bfaa81231ce3044b9ce2ecd734380fc2392e70890ff888bfa6f184cff8c24e5ef10ddf71f3a37c3ed6c015afdec26dfeb983bbb887fb78f0f734380fe031c7437f3247788c27d8fe713e1f6a1076f014cfb08be7ac7481977885d75c951fe4f3630dcea3c3eb7b9cc70d6b9ce12d9fee26de610debeb69b0fb578cb89a0d8c399711e794609373d9c39455f2b53466d8c20c17809c45cc7a3c00f011081cffccff379fef35388f1d0428a0c401f459e58c3d45700f0003cee71d8678fc730d7430e2557d3c8331f7568c37308129cc7006733e9d262c6008cb6ff3f94ea3c72bc678ca3f1fb80a637884154c71c974c55d72c91a4feca4fdf553f8ad46554d8e9ee30a9eb1efab31611f2ff0ca346427bb9c11e114debe7e7ebed328318702e7f0ce9dbee47a1c724655b745b0c94ea6b0c55519f059b98f73d19a6cc30eecc21eecfb7100877004c770026de8e070bdfe805338832e9cc3055cc2955f7b0d3de8f0cfebb5356ee016eea0c6a30e11342086049a907aadcd35355a90111250f5e5288706bfdb4bea572a78b49e06ddd3a0d2807a2502110d6944639ad09466ebf9e8ae684e0bf5b1a4075ab28f11ffa1df678dc7f57cb0c68a9ee899355e7c2ddbf40a31bdb1c63bcdfe86c6803669cb9f4555c76b38a76dcee57d5d1f5c8f1d5af0b9745581bb029a5c8f3eedd21eed73b70ebe56fa91061dd061f05139e9d1116b1cfb9aee55c4fcf6330d5cd289d778a6b65fdd831dea702e256b9cf2b974a84367d4fd580347744e17744957acc13e7cfc095d538f356ed8cd2ddd518dea147da4c1956890ffcf295ed5e4c83b4a59f182b9455935e3b801ab791c7fa4e188d7a4bcbee66353feaef9df8852ca2f3e9ee3ef73840f359cabfec22979f4ddbd1bf018ba118f318f899bf298b9b95bb8e537cffe9ffffef4171c39a0bf + + + 789c8d96c9521c490c86ef3c458775734cc8ddd5b5c6c41c303b180cc60b66620eaacc2c9aa5599b7562de7da45fc5180c8e98fa39f091522e4a49c9bbb783bdedcdc1db77735733991d864198c8e5e06dbc9e4eeffffceb8fbfe7de64d9407f466531c8defc36f76667360883adb3d364c013051ae2039f8147266359068f4dc6740a2e4db05f05d726f0253898c017c6a3cc04ffafce79aa3af0143c36c17e055caa0aacbf06aeb2203e5f09ae4d185f75ce472de6e7737063c2fcb57356b702fed673e32c473d4bcf3760198f02e69325706b022f3a676df0f567e05035d1ed273dc79883e7c1d1045e70ae2456d84fd9738a589f0b703261bc72ae25e17ee4b0e7d8f3b5733374e603e32c37c11ff36970db12f193f7e07c1c6bec87c6e0c604ff0e1c4db03f36cec7e3a6f4fd2e38e779eee7bd05e7e350fa7e4fc0455ee6b84fb9eab913bfdf1c5ce5758efba54fffb1e75302d726f8af3817a5f8f922584cf06fc0211f951ebfd0b30afe07ce4510dfdf1e38e665e9f9f1e01c32cf1fda06a73c2f7c7eac5f8c8b61eef582f315b909dc82f1c17e07dc1459e5f1c77d953abb787e0ab832611cf957366dd9c707f556762a3fcf8673ddd6d8afdc1957b909fe98af2a65d4c787c08d09e3c8bfaad504f378de83a309e35fc049d9d747bda19c7dbe8f602d88d6fd11af3a33c1ffde398e02ec69178c0b04bb7fa12be03e08e7ab4b895e2f74ec1ca2e73f6d811b2d37df1feaa9969082f71ff4a73a98c01f9cdb3678fde27eea58f7f9cdc8bfba33c11efda2199ac01bcead048fd72678a4e9e3f6a86f6d172acc87fc69f290f9386f3d72f478a1bf348509fea8b7a66c9b80fec1a8b7a66a53f47cc2fe9b5ae77346fe35ad09e761703081d12f9b68c2fc57ce6d0c1e6fe463934ce0efc63234c11ffd5b4a13c66f9cb53d79fded832bcd27f47f5aeb59055e744eb1df3fe2251aeee4e7453f9264c27aa847b44f7f4f909fda3efb7ae30c5c84b65f1fef435b9a608ff7a4ad4c981ffb6b6b13d8fda5edfb37eff4dcb65e2f787f5a7cb0f7fd0413ecf13eb49d09f6783ff07cf97d8ec0a3f8d8df516f483faf07c45b1f27e9f30ff989e9fdbe11ff1034fd3c9eebe068c238fa9f6677f2fb27ac1f475dd3f97da25fc6c204be755673ef3f8db3360c1f1f824b13c651df2877c44fd0df511efe5ea39f44318151cf9a4e2ab0af870d63fee4dc55fdfe109f880ff3fb788a8ff98df733762630fa471aa6febda2839e5b3f0fe1bef4f18bc9fb01fa7dca4ce0bb9e5b671ef69c3cff18f99cc626d853cf551f3fe453ca531bbdde979cbb2c793e207f536102a39fa5ca0446bf4279f97b89feaabb5181511f38bedf2ffa47373461bdcfe0dc8471d46387860fc6fbaad155c11ef7a5d953747ede69cf2a30fe3fd06c5121fe88572726f8a37f68720ffbfdadf7ac02fb7e82098c7e85ebf2fde37dea92098cf7acc367bc33fbff7a6ecfc4c22d078eaac41d1ff0e4d7f66a7df84293e71ecfec858f9ee8d1fef8a9c733fb139ef2299ff1395ff0255fc167c233befee1f1cc3ef10ddff21ddff303cfabe77bd584177891971e3d7ed8db4e7b2df30aaff29a7aac3ff9ebe4a9bdf2067fe04ddee28ffafb36eff027de558fcfbaab2ffc95bf3db5578b3dfecefb3ce411673c56ceb9e0b23f47a5fbac7fb26f889988742f2a129e504b81a246e0c8ec293cb7a7441d0b1dd0840ee9883486744253bea4533a7bd5fe9c2ed4feb29fff4aff32a36b8dd5e92fe6bfa15bddcf1dddd303cd93c6911668aa2b5cbc363f3c16799f9630fbb2d20aadd21aadeb3d547a8617f6f0d8a00fb4495bfadb47daa61dfa84f977e933c597f64f6e6c9fbed057fa467bf49df669c8bb34a2eca53d8d35576ef88e722aa8a48a6a6a448320a20fd36bf3eb7f407c2c89efb5500f6422877224c77222533915e6b397fbd117f54ccee54275295732936bb9915bb9937b797869ff34e7649ecfe4bd2ce81a8bbc2a4bb2fc5a3dfe2c59915559fb75fdfe8f7affe7f7b97f011cdd9635 + + + diff --git a/examples/activeqt/webbrowser/webbrowser.pro b/examples/activeqt/webbrowser/webbrowser.pro index 992d871..32eac71 100644 --- a/examples/activeqt/webbrowser/webbrowser.pro +++ b/examples/activeqt/webbrowser/webbrowser.pro @@ -7,7 +7,7 @@ QTDIR_build:REQUIRES = shared HEADERS = webaxwidget.h SOURCES = main.cpp FORMS = mainwindow.ui -wince*: FORMS = wincemainwindow.ui +wincewm*: FORMS = mainwindow_windowsmobile.ui # install diff --git a/examples/activeqt/webbrowser/wincemainwindow.ui b/examples/activeqt/webbrowser/wincemainwindow.ui deleted file mode 100644 index 98a9ddb..0000000 --- a/examples/activeqt/webbrowser/wincemainwindow.ui +++ /dev/null @@ -1,299 +0,0 @@ - - MainWindow - - - MainWindow - - - - 0 - 0 - 812 - 605 - - - - Qt WebBrowser - - - - - unnamed - - - 0 - - - 6 - - - - - Frame3 - - - QFrame::StyledPanel - - - QFrame::Sunken - - - - unnamed - - - 1 - - - 0 - - - - - WebBrowser - - - Qt::StrongFocus - - - {F5AFC7EF-1571-48B6-A69C-F1833F4C3A44} - - - - - - - - - - - tbNavigate - - - Navigation - - - - - - - - - - - - tbAddress - - - Address - - - - lblAddress - - - Address - - - - - addressEdit - - - - - - - menubar - - - - PopupMenu - - - &File - - - - FileNewGroup_2 - - - New - - - - - - - - - - - unnamed - - - &Help - - - - - - - - - - actionGo - - - image0 - - - Go - - - - - actionBack - - - image1 - - - Back - - - Backspace - - - - - actionForward - - - image2 - - - Forward - - - - - actionStop - - - image3 - - - Stop - - - - - actionRefresh - - - image4 - - - Refresh - - - - - actionHome - - - image5 - - - Home - - - - - actionFileClose - - - Close - - - C&lose - - - - - actionSearch - - - image6 - - - Search - - - - - actionAbout - - - About - - - - - actionAboutQt - - - About Qt - - - - - - actionNewWindow - - - Window - - - Ctrl+N - - - - FileNewGroup - - - - - - addressEdit - returnPressed() - actionGo - trigger() - - - - - - 789cd3d7528808f055d0d2e72a2e492cc94c5648ce482c52d04a29cdcdad8c8eb5ade65232365200210543251d2e253d856405bffcbc54103b11c8563600020b03105719c4b530b08072f50880513560a09c080338d5209420294a4451a38c90426621ab5146d10de524a2aa417505445122861a547722bb0c971a3d2aa921c2ae446c6a9431fc85a9064551220e354009653dec00294e712a1ac4e97078a9a9b5e6020013b3f563 - - - 789ce596497332470c86effe15947573a5f4c1cc30cc542a07ef60bc808dd7540e3d9b6df006186c93ca7f8fba2535ce57be98dc9292313c487a2575f7ccf063a376d53baa6dfc589bbe9ad7fbbc96df99496da3983d3e7efcfec76f7faead87418dfe1a51500bd67f595befbfd6f2daf1f35369014e08a05e6fd4ab96e31e73d0282bc7a7cae23ff3ccfe8170ca6cee9843f51f3b4ec8cff9efccdebf2d2cf9b06bb9417a25c74f98bdff99390a84fb8e49af70f39891b2e40bfbf8b6b0917e87968346a8f5a6cc51c07ab02f2cf1983237552f709c86691e3bbd5be5821998a32067bd1765d13f67563d530a4b3df8b01c523d8ec74059faed086bfc82390e851b8ed3c86485e34365a9bfc5ece3df8433e10bcb5140f5dd3cf0e099f32f99e350cecb5858f2b1c1dc52fda663d334a277c0ecfd5d61c9373973120967969b548fd71b079e797d8e985b21eb63aecceb85e7c299f4ffaa2ce7739359ebc195631387c6ad1f5e302791ccbba72cf173e15cfa2d2cc7619cf1fa63c9dccaa4ff4bcfdc7fa82cfdf7999348f6bf299c4bfd4c59ea0f99535dafca71d60a65ffebca52ff8c3989e47cce98351fb785759e7bcbad65bf0be624ca9a8e87caac0fb1702ef191b2cc9731a7b9ec4f87d934659e27e142f8c671e6eb9d0ae7b2be07cc6924ccf999698a7e4f58f572e64cebb9f393444994e68e4365d9ff7be15caef70766ad678cb0f8f18359ebe109b3af27f199fadd794cf254eb196599774758e77d5496f5dd64a67959af122ef87c639b59eb81d34ba97fe3f4215196f3922acbbc28acf527cc792c7a857029ecf63bcded05efb8a52cf3cc9833ed2f66563dac0b8b1ebe3317ea77f73352173db8f6ccf54a66df0f30fb7c777d9bc214d2cf88d9cf73cfece3ddf3296b66da7fe199d7a32b5cc8feef31fbfe8f99bdde96b0faddf3272bac390665b99e90d9e7ef33972de9d73d7ff3d873255c49fc1b73257ee4f8d2eb5d336b3e8e8535ff86d9e7bbf35f2cf51366ef77cfeb6299df62563f3c0a8b1fdcf3d3569778773f756e66f7fcac967e175f797ffff5dfd9ff4103010d6698a35955030b2cb1c25bbcc3fbd5344861882352b8c5077c5c45836678c267ca7fc1314ebeaf81537cc599eb608e6ff88e1f2b682c705314b6486182dbb8f31d0ddca529f644619ff2db641d3cf82a8bfa9d62d7da670d3cc4233c760a63eaa08d2734478fac8f87ffc833788a6738c073bc20ebe3255eb1069d863e5e3b851bacfb7c6b0d0c30c488f24a3a2d4ddaf1986a3d600b13179be280ef597809e876e206000c69d8ec0e590f32c8a18012b7a0825b9799e018eee0de4e0b4318c103ff2ea2985b78c47d28a487ce276b634cca40356d1655801c3bf044af2136e0195ef8b711be4045ab50ff42e16bdbb6463d8e610253fe3d4855ec3ed80abd9f62397ef9c9e6cee835249bc31bbc731ff0010beacbcdbfaca29f2836a3e839fd1f3acb5cb6fd6e13b6605b34766097d6664cdf0d7faad9813dd827df08daf4de812ddaa7061c4017baf43ea6daef70c8fb0247704c932dc897b94e67da09553a811ef4a94a0f4ee10c069435216b630ae7a43b800b7fc6164ea543ea73ea75663b22a50e5cc215ec50956beaf606ead08080147b64c76403d20ebdc6142268528d3655ee3a1db6f88b535ee015b42081d4205ee1f4f335878501ea7644331dc81acecdb7ef63b86b32eae59956cff63237f92af7319c9a82669c989256bd0b6fa6fabe86bbfe0ecdadb9a399ce61b49a86355adfbedd45736756bc27b30afd161a9a9179585de33bf69fd2f8ebd7b5bf014644b906 - - - 789ce5965b4f23471085dff915d6d6db2aaac5e3b92aca037703cbc55c8c21ca43cf8c8d0dd85c6c307694ff9eeaaed3bd68771f968d14298a0a109fabebd4e99a9ef17cfad8e81d1f343e7e5a99cecc6c5435aaa1796a7cac9fc7e3c5ef7ffcf6e7ca8756d4909f661c35a20fbfac7ce8cc1a55e3f07ed2b7409702b4badaccfb996563020f5c7ecbf340b9a31c3591dff7ac7943e002cc8e73cf74acdcc27a8a2d37a5be4e1d9f04567f9fc105f25dcfea9726caad62a07c1158f58f94e3087e868ea57fa5fa0be590bfb11c3525affd4e03ebfa25b8507fbcaa1c47ca66e459fdf10c6c30af4dcfda8f5f9513dfffce71e1f5a956967adddfaeb25f4f7b60e8d199e596f42f6bc787ca213f554e5be06dc7a28ffdee282791cedb5c83d19fd795a55ecf4b3fb0ee07ebd312fae796e3283665e238524e2265de031bcc774d396d61be25b8c4fe1f02abfeab67f49f2867decfbd6393b6a03f03438f3bca19fa51cb33fc6f80fd7eae2c27e257e7cb4de5b4045f78d679f24960ddcfb172e6f73357ce63e88fc115ce43e558fcabbeb905fb7e47cae24ff5daca41af007bbd81e5b425f53aff6160d52f95f318f37d01a39ee7ca05f4790a469e0e1c97590bfa1b81f53c3e2bfbf5ecf697b532efe754398f31af437085eb65948b18e723f70cbf9e2bcc633db0f65b533609fcbafb372bf318fdcfc015e65b281731ee0ff6acf70767ca5e8f7be01abcab5cfa7e89e53cce2ba3fd1681b5df8172013f44e00acfbf4a39e8ef287b7dbe02234feefce795d727a36c12ccf75239d4b7c1bede9def42fcc0ef7960d5cbc05ebf543635aed752b94aa1ff02ee83ddf3b6a87c3d3f2b9b047a4fcaa17e0cf6f5eef928ab13f5476960d5eb7ac6f5dd07d7e04839e83d29d7be9ffbfe31b50dc723cfa87f08acf947e51a7ad457ee6760773ecaa4f47e36036bfd96673c3fb6c13578a01cf41f9505d5af3b2f655dc28fa93da33e550ef523e5e06f08861eb9e7b94cdfe7ddf753d50feb6f94437e00f67edcf3aa4e831ed8afe73bb05fefe655f7c37edcfd62bb81ddfb82935776cfeb41c87766ff2cfe7f1a4c6cb8e48ae91f68d4dce7015ff390473fad71c3b77cc7639ef03d3ffcb48f013ff293a84c79c6d54f693c8bc28b28589539bff2e2ed647e586389184bacf13a6ff0e6d71a32f92dde96bfdf9dbccc6387dba2d086caae4c668ff7bf68f0673ee0433ee263eef0099ff2199f8b62d0e32e5f704fea2fe5b70d3f57729556b91b349a1c718b634e64faa9fc7fc919e772220a91213254ca273b884bf72b4a54f1846ad925e93b1af56940d734a4110fe4efb5c40dddda907311734c7752d10b3a1ae289c634a17b7dafe331e995b3b124fbdfd25d85471763596fab7aa2a4f53d444653ded3773bb96e8faeae1de2ea8dff9da0b0ebfcd858e3357aa667bb1f68b4a5e7d256853559e8f56d64aefe85e6f44a0b5aea3bac5c2bebf74b8775fb6bfbb858771e7a6f1df09c36f89a36698bb6f53d5c4ef08ee4e6a2dd269b9d488729ed4a171b7bd40ece3228cce5d305edd3673ed7773139bd133a14d5233a96cff7a9237142a77446e7125dba900e70681564f5a6acdc1285ae9e0feaf150d675e8d2d59dd315ad52931fec2973d1a5489c6698e29c5a508829797bd629a52665bcf9fdd32ed95c1d50217b5c18b67390f34befb8e78873a9b6b39ad285216328a2de3bef5b32a59db5ccec42a6b565aaf7dffba6e663d3972b211ea86b065f3cbccbc7b53890399a21a55f677f5863e4f670c337df667f58e3d6dc99dbef3dd5ff6bdf73ff82c65fbfaefc0d4fb5b868 - - - 789cd3d7528808f055d0d2e72a2e492cc94c5648ce482c52d04a29cdcdad8c8eb5ade65232325500210543251d2e25658564056503300071f540dc3430007371012a492a830156496538c094848922c9c2259134c099304914e3604c8424aa5e6449b0044216ca824ba2da8b4512218b4d122e8b55520fee5974072164511da487ea490c7f22cba249e20d3efc018f3fcae0d2702eb5d2106992b5d65c00b9a48974 - - - 789cd3d7528808f055d0d2e72a2e492cc94c5648ce482c52d04a29cdcdad8c8eb5ade65232365200210543251d2e253d856405bffcbc54105b19c8563600020b03103711c4b530b08072f50880513524ab518681443435ca984ae08ae06a94114a10ac443435ca3043904d4c4453a38ca604ae11590d9a0ab80bd0d46078914c35c4d885a608871a547f61f81d5d117a1862018930e5b8d5c0950c741a1b1e6a6aadb90086a9d853 - - - 789ca5985973db480ec7dff3295cc15b6a0b2351a428d6d63ef83e255bbe647b6a1fd02465dd872d9f53f3dd076c005dc926ce6a32eed8553f37fadf7fa0c1a69cdfbe6cdc9cb537befcf6e97145ab61be910fe861e34bf1349dbefdfedffffcf1e97323dae07f51bdbe117dfed7a7cfddd546bed199cfca0ae888016afeab62e8796ef110ee545caf05be16ae5bfc6ee096e7b6e756983f51b6f53b81257ecfb8eee7e9b162f66af1c78125fe48987f23f3fb81657e691cd5bddecc7316d555efd058f7eb2867aa771058f4de8c55cffb6dd4a34cf5b68d357e681c6515634db81a7e3ef59c35cccf5560bf9ef6953389c77660af074f15c751e05c38a6d81f2ef9f3a848f4e9d658f2c36b635dbfa54cc2383556bd33e12492fc70df38f1f3f8ae4cc2745a711285fda7caa4f95e06967a2d8c63f27a8fc2a60fa4acfa980a371b898f0767dc6cf8fdbc9f84c27e4de124d2fabe186b3dee8c75ff1365dbef2db0ccef0987fd2f2a6632fd576552fd2b63d57b08ecd7d39d70b321fd0560acfb6d1a4b7e3050764de7d79f08a70de937ea7b7689e68f4de1e0776e2c7ab8abecb47eb170aa7ee822b0e89f1b4b7fd24dc529abe9794f02cbf99e2b3badc7a5b1ee97089b3e0e8d253f3c364e253e5576120ff7c63a9f7966d2e771d358e75bca4ef3bb0e2cf9758db5fe47c6b21eeb81bd3f07c2ad58ebd130d67e6a194b3cf97e62b2fa24c67a1f5d2aab3f8781a53e17c6eaa7082cfa3de156acf9d5034b7e3563f1eb96c6eaf7c0b815fbf8d2739e3aedefb1b1de9723618b77a49cebf946c6e20f5f8d251e753e8b5bb9e74c980a4afc7a7fbf66b1ed8fb7c67a9ec7c2ad5cfd74038bdfa6b1f6cbd458fd2e84b358efbb0363f5b71358fccd8c33596f9c4bfddcc458fac78d8cf5797b3296f5f82c4c49e6f5c9bf9fb23ce41307967e3935d6f36c0b67b1ce3f188b5f3757367f5363b98fdc38b0cc0f8cf5f90bf3ea97028bfe50981289777d63edcf81b1c4439897f3c52d615738cfe0df371c1deb7db265acf98d8d253f7a50d67a60c758cfcbf4cc7f2fb0f8bf1736bfae30d6f35f1a4b3ce6c6e2df95ca85f6f7dc58f3db0e5c783e14e6ebc533e87e963fbe0873f9fd3cc97c91693fd028b0d4e3c558f3eb0b9b5f972bab3fe78c353f3056bfabc0e2371636bfe4cf9b29d1e76b69acfdb863accfd33cb0dc2fa7c6e2179e03cb79ae940b7dffbf1b6bfd1363f53b12367f581a6b3d1bca56df6e60a9bfc6e765def4ecef6bc7eafaf9e8d558fbb7a15ce87d7263acf7ffbdb1e40f33e1e0cf29ebfea8eb6d7ff29f17f8f4137dfe51d8fa0117ca65ee3fbfe3bd705116b2de9f775e3af50313e1a229f1f0682cf1b052e6e1d9dfbf1cddd4fd2363cdcfef5fb05b7d1f0c944bed4f67ac9f5f27c265bf4c3d9f07eefb787f1f96695eaa1e0a174d7d7f81b1ee4f81a5fe75e552d9bf1fca7e617e9e8d556f33b0c4fbcf5ffdb44c956bc6a2d75dfd6c2020fd3ce2ff69a0c31c0b2cff91461fef71804374bfaa81231ce3044b9ce2ecd734380fc2392e70890ff888bfa6f184cff8c24e5ef10ddf71f3a37c3ed6c015afdec26dfeb983bbb887fb78f0f734380fe031c7437f3247788c27d8fe713e1f6a1076f014cfb08be7ac7481977885d75c951fe4f3630dcea3c3eb7b9cc70d6b9ce12d9fee26de610debeb69b0fb578cb89a0d8c399711e794609373d9c39455f2b53466d8c20c17809c45cc7a3c00f011081cffccff379fef35388f1d0428a0c401f459e58c3d45700f0003cee71d8678fc730d7430e2557d3c8331f7568c37308129cc7006733e9d262c6008cb6ff3f94ea3c72bc678ca3f1fb80a637884154c71c974c55d72c91a4feca4fdf553f8ad46554d8e9ee30a9eb1efab31611f2ff0ca346427bb9c11e114debe7e7ebed328318702e7f0ce9dbee47a1c724655b745b0c94ea6b0c55519f059b98f73d19a6cc30eecc21eecfb7100877004c770026de8e070bdfe805338832e9cc3055cc2955f7b0d3de8f0cfebb5356ee016eea0c6a30e11342086049a907aadcd35355a90111250f5e5288706bfdb4bea572a78b49e06ddd3a0d2807a2502110d6944639ad09466ebf9e8ae684e0bf5b1a4075ab28f11ffa1df678dc7f57cb0c68a9ee899355e7c2ddbf40a31bdb1c63bcdfe86c6803669cb9f4555c76b38a76dcee57d5d1f5c8f1d5af0b9745581bb029a5c8f3eedd21eed73b70ebe56fa91061dd061f05139e9d1116b1cfb9aee55c4fcf6330d5cd289d778a6b65fdd831dea702e256b9cf2b974a84367d4fd580347744e17744957acc13e7cfc095d538f356ed8cd2ddd518dea147da4c1956890ffcf295ed5e4c83b4a59f182b9455935e3b801ab791c7fa4e188d7a4bcbee66353feaef9df8852ca2f3e9ee3ef73840f359cabfec22979f4ddbd1bf018ba118f318f899bf298b9b95bb8e537cffe9ffffef4171c39a0bf - - - 789c8d96c9521c490c86ef3c458775734cc8ddd5b5c6c41c303b180cc60b66620eaacc2c9aa5599b7562de7da45fc5180c8e98fa39f091522e4a49c9bbb783bdedcdc1db77735733991d864198c8e5e06dbc9e4eeffffceb8fbfe7de64d9407f466531c8defc36f76667360883adb3d364c013051ae2039f8147266359068f4dc6740a2e4db05f05d726f0253898c017c6a3cc04ffafce79aa3af0143c36c17e055caa0aacbf06aeb2203e5f09ae4d185f75ce472de6e7737063c2fcb57356b702fed673e32c473d4bcf3760198f02e69325706b022f3a676df0f567e05035d1ed273dc79883e7c1d1045e70ae2456d84fd9738a589f0b703261bc72ae25e17ee4b0e7d8f3b5733374e603e32c37c11ff36970db12f193f7e07c1c6bec87c6e0c604ff0e1c4db03f36cec7e3a6f4fd2e38e779eee7bd05e7e350fa7e4fc0455ee6b84fb9eab913bfdf1c5ce5758efba54fffb1e75302d726f8af3817a5f8f922584cf06fc0211f951ebfd0b30afe07ce4510dfdf1e38e665e9f9f1e01c32cf1fda06a73c2f7c7eac5f8c8b61eef582f315b909dc82f1c17e07dc1459e5f1c77d953abb787e0ab832611cf957366dd9c707f556762a3fcf8673ddd6d8afdc1957b909fe98af2a65d4c787c08d09e3c8bfaad504f378de83a309e35fc049d9d747bda19c7dbe8f602d88d6fd11af3a33c1ffde398e02ec69178c0b04bb7fa12be03e08e7ab4b895e2f74ec1ca2e73f6d811b2d37df1feaa9969082f71ff4a73a98c01f9cdb3678fde27eea58f7f9cdc8bfba33c11efda2199ac01bcead048fd72678a4e9e3f6a86f6d172acc87fc69f290f9386f3d72f478a1bf348509fea8b7a66c9b80fec1a8b7a66a53f47cc2fe9b5ae77346fe35ad09e761703081d12f9b68c2fc57ce6d0c1e6fe463934ce0efc63234c11ffd5b4a13c66f9cb53d79fded832bcd27f47f5aeb59055e744eb1df3fe2251aeee4e7453f9264c27aa847b44f7f4f909fda3efb7ae30c5c84b65f1fef435b9a608ff7a4ad4c981ffb6b6b13d8fda5edfb37eff4dcb65e2f787f5a7cb0f7fd0413ecf13eb49d09f6783ff07cf97d8ec0a3f8d8df516f483faf07c45b1f27e9f30ff989e9fdbe11ff1034fd3c9eebe068c238fa9f6677f2fb27ac1f475dd3f97da25fc6c204be755673ef3f8db3360c1f1f824b13c651df2877c44fd0df511efe5ea39f44318151cf9a4e2ab0af870d63fee4dc55fdfe109f880ff3fb788a8ff98df733762630fa471aa6febda2839e5b3f0fe1bef4f18bc9fb01fa7dca4ce0bb9e5b671ef69c3cff18f99cc626d853cf551f3fe453ca531bbdde979cbb2c793e207f536102a39fa5ca0446bf4279f97b89feaabb5181511f38bedf2ffa47373461bdcfe0dc8471d46387860fc6fbaad155c11ef7a5d953747ede69cf2a30fe3fd06c5121fe88572726f8a37f68720ffbfdadf7ac02fb7e82098c7e85ebf2fde37dea92098cf7acc367bc33fbff7a6ecfc4c22d078eaac41d1ff0e4d7f66a7df84293e71ecfec858f9ee8d1fef8a9c733fb139ef2299ff1395ff0255fc167c233befee1f1cc3ef10ddff21ddff303cfabe77bd584177891971e3d7ed8db4e7b2df30aaff29a7aac3ff9ebe4a9bdf2067fe04ddee28ffafb36eff027de558fcfbaab2ffc95bf3db5578b3dfecefb3ce411673c56ceb9e0b23f47a5fbac7fb26f889988742f2a129e504b81a246e0c8ec293cb7a7441d0b1dd0840ee9883486744253bea4533a7bd5fe9c2ed4feb29fff4aff32a36b8dd5e92fe6bfa15bddcf1dddd303cd93c6911668aa2b5cbc363f3c16799f9630fbb2d20aadd21aadeb3d547a8617f6f0d8a00fb4495bfadb47daa61dfa84f977e933c597f64f6e6c9fbed057fa467bf49df669c8bb34a2eca53d8d35576ef88e722aa8a48a6a6a448320a20fd36bf3eb7f407c2c89efb5500f6422877224c77222533915e6b397fbd117f54ccee54275295732936bb9915bb9937b797869ff34e7649ecfe4bd2ce81a8bbc2a4bb2fc5a3dfe2c59915559fb75fdfe8f7affe7f7b97f011cdd9635 - - - -- cgit v0.12 From 1cea2ed930377b1bb0d1ce583eacae87d999fc16 Mon Sep 17 00:00:00 2001 From: Thomas Sondergaard Date: Mon, 13 Jul 2009 17:32:02 +0200 Subject: QToolTip: Uses QPalette::ToolTipText default text color for rich text. Task-number: 248429 Merge-request: 786 Reviewed-by: Olivier Goffart --- src/gui/kernel/qwhatsthis.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/kernel/qwhatsthis.cpp b/src/gui/kernel/qwhatsthis.cpp index f38b0f6..f569c97 100644 --- a/src/gui/kernel/qwhatsthis.cpp +++ b/src/gui/kernel/qwhatsthis.cpp @@ -351,6 +351,7 @@ void QWhatsThat::paintEvent(QPaintEvent*) rect.translate(-r.x(), -r.y()); p.setClipRect(rect); QAbstractTextDocumentLayout::PaintContext context; + context.palette.setColor(QPalette::Text, context.palette.toolTipText()); doc->documentLayout()->draw(&p, context); } else -- cgit v0.12 From 808a6b824fe194d958f5ed1a0fd4f03362ced767 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Mon, 13 Jul 2009 18:27:05 +0200 Subject: Revert "Remove builtin xml schema file until legal issues are clarified" This reverts commit 3ded2e1ea5a74a6fc0d3938fa732f886aa275ca2. --- src/xmlpatterns/schema/builtinschemas.qrc | 1 + src/xmlpatterns/schema/schemas/xml.xsd | 145 ++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 src/xmlpatterns/schema/schemas/xml.xsd diff --git a/src/xmlpatterns/schema/builtinschemas.qrc b/src/xmlpatterns/schema/builtinschemas.qrc index 4ca9cd5..fb43d78 100644 --- a/src/xmlpatterns/schema/builtinschemas.qrc +++ b/src/xmlpatterns/schema/builtinschemas.qrc @@ -1,4 +1,5 @@ + schemas/xml.xsd diff --git a/src/xmlpatterns/schema/schemas/xml.xsd b/src/xmlpatterns/schema/schemas/xml.xsd new file mode 100644 index 0000000..eeb9db5 --- /dev/null +++ b/src/xmlpatterns/schema/schemas/xml.xsd @@ -0,0 +1,145 @@ + + + + + + See http://www.w3.org/XML/1998/namespace.html and + http://www.w3.org/TR/REC-xml for information about this namespace. + + This schema document describes the XML namespace, in a form + suitable for import by other schema documents. + + Note that local names in this namespace are intended to be defined + only by the World Wide Web Consortium or its subgroups. The + following names are currently defined in this namespace and should + not be used with conflicting semantics by any Working Group, + specification, or document instance: + + base (as an attribute name): denotes an attribute whose value + provides a URI to be used as the base for interpreting any + relative URIs in the scope of the element on which it + appears; its value is inherited. This name is reserved + by virtue of its definition in the XML Base specification. + + id (as an attribute name): denotes an attribute whose value + should be interpreted as if declared to be of type ID. + This name is reserved by virtue of its definition in the + xml:id specification. + + lang (as an attribute name): denotes an attribute whose value + is a language code for the natural language of the content of + any element; its value is inherited. This name is reserved + by virtue of its definition in the XML specification. + + space (as an attribute name): denotes an attribute whose + value is a keyword indicating what whitespace processing + discipline is intended for the content of the element; its + value is inherited. This name is reserved by virtue of its + definition in the XML specification. + + Father (in any context at all): denotes Jon Bosak, the chair of + the original XML Working Group. This name is reserved by + the following decision of the W3C XML Plenary and + XML Coordination groups: + + In appreciation for his vision, leadership and dedication + the W3C XML Plenary on this 10th day of February, 2000 + reserves for Jon Bosak in perpetuity the XML name + xml:Father + + + + + This schema defines attributes and an attribute group + suitable for use by + schemas wishing to allow xml:base, xml:lang, xml:space or xml:id + attributes on elements they define. + + To enable this, such a schema must import this schema + for the XML namespace, e.g. as follows: + <schema . . .> + . . . + <import namespace="http://www.w3.org/XML/1998/namespace" + schemaLocation="http://www.w3.org/2001/xml.xsd"/> + + Subsequently, qualified reference to any of the attributes + or the group defined below will have the desired effect, e.g. + + <type . . .> + . . . + <attributeGroup ref="xml:specialAttrs"/> + + will define a type which will schema-validate an instance + element with any of those attributes + + + + In keeping with the XML Schema WG's standard versioning + policy, this schema document will persist at + http://www.w3.org/2007/08/xml.xsd. + At the date of issue it can also be found at + http://www.w3.org/2001/xml.xsd. + The schema document at that URI may however change in the future, + in order to remain compatible with the latest version of XML Schema + itself, or with the XML namespace itself. In other words, if the XML + Schema or XML namespaces change, the version of this document at + http://www.w3.org/2001/xml.xsd will change + accordingly; the version at + http://www.w3.org/2007/08/xml.xsd will not change. + + + + + + Attempting to install the relevant ISO 2- and 3-letter + codes as the enumerated possible values is probably never + going to be a realistic possibility. See + RFC 3066 at http://www.ietf.org/rfc/rfc3066.txt and the IANA registry + at http://www.iana.org/assignments/lang-tag-apps.htm for + further information. + + The union allows for the 'un-declaration' of xml:lang with + the empty string. + + + + + + + + + + + + + + + + + + + + + + + + See http://www.w3.org/TR/xmlbase/ for + information about this attribute. + + + + + + See http://www.w3.org/TR/xml-id/ for + information about this attribute. + + + + + + + + + + + -- cgit v0.12 From 2567ec486d5d95dc4ca06874cf75bf03bd7502b9 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Mon, 13 Jul 2009 18:32:31 +0200 Subject: Add W3C license text for xml.xsd --- src/xmlpatterns/schema/xml.xsd-LICENSE | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/xmlpatterns/schema/xml.xsd-LICENSE diff --git a/src/xmlpatterns/schema/xml.xsd-LICENSE b/src/xmlpatterns/schema/xml.xsd-LICENSE new file mode 100644 index 0000000..2c687d8 --- /dev/null +++ b/src/xmlpatterns/schema/xml.xsd-LICENSE @@ -0,0 +1,40 @@ +W3C® SOFTWARE NOTICE AND LICENSE + +This license came from: http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + +This work (and included software, documentation such as READMEs, or other +related items) is being provided by the copyright holders under the following +license. By obtaining, using and/or copying this work, you (the licensee) +agree that you have read, understood, and will comply with the following +terms and conditions. + +Permission to copy, modify, and distribute this software and its +documentation, with or without modification, for any purpose and without +fee or royalty is hereby granted, provided that you include the following on +ALL copies of the software and documentation or portions thereof, including +modifications: + + 1. The full text of this NOTICE in a location viewable to users of the + redistributed or derivative work. + 2. Any pre-existing intellectual property disclaimers, notices, or terms + and conditions. If none exist, the W3C Software Short Notice should be + included (hypertext is preferred, text is permitted) + within the body of any redistributed or derivative code. + 3. Notice of any changes or modifications to the files, including the date + changes were made. (We recommend you provide URIs to the location from + which the code is derived.) + +THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS +MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR +PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE +ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. + +COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR +DOCUMENTATION. + +The name and trademarks of copyright holders may NOT be used in +advertising or publicity pertaining to the software without specific, written +prior permission. Title to copyright in this software and any associated +documentation will at all times remain with copyright holders. -- cgit v0.12 From c549bda8cd38a099118f3cf4c7e5462010cb7259 Mon Sep 17 00:00:00 2001 From: Noah White-Hamerslough Date: Mon, 13 Jul 2009 18:58:48 +0200 Subject: Fixes: The keyboard navigation of QComboBox don't work with the completion Merge-request: 653 Reviewed-by: Olivier Goffart Task-number: 247560 --- src/gui/util/qcompleter.cpp | 4 ++-- tests/auto/qcompleter/tst_qcompleter.cpp | 40 ++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/gui/util/qcompleter.cpp b/src/gui/util/qcompleter.cpp index f4adcea..d68e309 100644 --- a/src/gui/util/qcompleter.cpp +++ b/src/gui/util/qcompleter.cpp @@ -1182,7 +1182,7 @@ bool QCompleter::eventFilter(QObject *o, QEvent *e) case Qt::Key_Up: if (!curIndex.isValid()) { int rowCount = d->proxy->rowCount(); - QModelIndex lastIndex = d->proxy->index(rowCount - 1, 0); + QModelIndex lastIndex = d->proxy->index(rowCount - 1, d->column); d->setCurrentIndex(lastIndex); return true; } else if (curIndex.row() == 0) { @@ -1194,7 +1194,7 @@ bool QCompleter::eventFilter(QObject *o, QEvent *e) case Qt::Key_Down: if (!curIndex.isValid()) { - QModelIndex firstIndex = d->proxy->index(0, 0); + QModelIndex firstIndex = d->proxy->index(0, d->column); d->setCurrentIndex(firstIndex); return true; } else if (curIndex.row() == d->proxy->rowCount() - 1) { diff --git a/tests/auto/qcompleter/tst_qcompleter.cpp b/tests/auto/qcompleter/tst_qcompleter.cpp index baea419..bbc01cc 100644 --- a/tests/auto/qcompleter/tst_qcompleter.cpp +++ b/tests/auto/qcompleter/tst_qcompleter.cpp @@ -146,6 +146,8 @@ private slots: void task253125_lineEditCompletion_data(); void task253125_lineEditCompletion(); + void task247560_keyboardNavigation(); + private: void filter(); void testRowCount(); @@ -1230,5 +1232,43 @@ void tst_QCompleter::task253125_lineEditCompletion() QCOMPARE(edit.text(), QString("iota")); } +void tst_QCompleter::task247560_keyboardNavigation() +{ + QStandardItemModel model; + + for (int i = 0; i < 5; i++) { + for (int j = 0; j < 5; j++) { + model.setItem(i, j, new QStandardItem(QString("row %1 column %2").arg(i).arg(j))); + } + } + + + QCompleter completer(&model); + completer.setCompletionColumn(1); + + QLineEdit edit; + edit.setCompleter(&completer); + edit.show(); + edit.setFocus(); + + QTest::qWait(100); + + QTest::keyClick(&edit, 'r'); + QTest::keyClick(edit.completer()->popup(), Qt::Key_Down); + QTest::keyClick(edit.completer()->popup(), Qt::Key_Down); + QTest::keyClick(edit.completer()->popup(), Qt::Key_Enter); + + QCOMPARE(edit.text(), QString("row 1 column 1")); + + edit.clear(); + + QTest::keyClick(&edit, 'r'); + QTest::keyClick(edit.completer()->popup(), Qt::Key_Up); + QTest::keyClick(edit.completer()->popup(), Qt::Key_Up); + QTest::keyClick(edit.completer()->popup(), Qt::Key_Enter); + + QCOMPARE(edit.text(), QString("row 3 column 1")); +} + QTEST_MAIN(tst_QCompleter) #include "tst_qcompleter.moc" -- cgit v0.12 From 0c3068761598e9decd2bdc903be5431d093b8eac Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 13 Jul 2009 19:09:33 +0200 Subject: Make test faster + fix whitespace --- tests/auto/qcompleter/tst_qcompleter.cpp | 41 ++++++++++++++++---------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/tests/auto/qcompleter/tst_qcompleter.cpp b/tests/auto/qcompleter/tst_qcompleter.cpp index bbc01cc..fb03e1a 100644 --- a/tests/auto/qcompleter/tst_qcompleter.cpp +++ b/tests/auto/qcompleter/tst_qcompleter.cpp @@ -58,9 +58,9 @@ class CsvCompleter : public QCompleter Q_OBJECT public: CsvCompleter(QObject *parent = 0) : QCompleter(parent), csv(true) { } - - QString pathFromIndex(const QModelIndex& sourceIndex) const; - + + QString pathFromIndex(const QModelIndex& sourceIndex) const; + void setCsvCompletion(bool set) { csv = set; } protected: @@ -178,7 +178,7 @@ tst_QCompleter::~tst_QCompleter() } void tst_QCompleter::setSourceModel(ModelType type) -{ +{ QString text; QTreeWidgetItem *parent, *child; treeWidget->clear(); @@ -284,7 +284,7 @@ void tst_QCompleter::csMatchingOnCsSortedModel_data() for (int i = 0; i < 2; i++) { if (i == 1) QTest::newRow("FILTERING_OFF") << "FILTERING_OFF" << "" << "" << ""; - + // Plain text filter QTest::newRow("()") << "" << "" << "P0" << "P0"; QTest::newRow("()F") << "" << "F" << "P0" << "P0"; @@ -301,7 +301,7 @@ void tst_QCompleter::csMatchingOnCsSortedModel_data() QTest::newRow("(p)NNNN") << "p" << "NNNN" << "p4" << "p4"; QTest::newRow("(p1)") << "p1" << "" << "p1" << "p1"; QTest::newRow("(p11)") << "p11" << "" << "" << ""; - + // Tree filter QTest::newRow("(P0,)") << "P0," << "" << "c0P0" << "P0,c0P0"; QTest::newRow("(P0,c)") << "P0,c" << "" << "c0P0" << "P0,c0P0"; @@ -335,7 +335,7 @@ void tst_QCompleter::ciMatchingOnCiSortedModel_data() QTest::addColumn("completion"); QTest::addColumn("completionText"); - for (int i = 0; i < 2; i++) { + for (int i = 0; i < 2; i++) { if (i == 1) QTest::newRow("FILTERING_OFF") << "FILTERING_OFF" << "" << "" << ""; @@ -354,7 +354,7 @@ void tst_QCompleter::ciMatchingOnCiSortedModel_data() QTest::newRow("(p1)") << "p1" << "" << "P1" << "P1"; QTest::newRow("(p1)N") << "p1" << "N" << "p1" << "p1"; QTest::newRow("(p11)") << "p11" << "" << "" << ""; - + //// Tree filter QTest::newRow("(p0,)") << "p0," << "" << "c0P0" << "P0,c0P0"; QTest::newRow("(p0,c)") << "p0,c" << "" << "c0P0" << "P0,c0P0"; @@ -406,7 +406,7 @@ void tst_QCompleter::ciMatchingOnCsSortedModel_data() QTest::newRow("(p1)") << "p1" << "" << "P1" << "P1"; QTest::newRow("(p1)N") << "p1" << "N" << "p1" << "p1"; QTest::newRow("(p11)") << "p11" << "" << "" << ""; - + // Tree filter QTest::newRow("(p0,)") << "p0," << "" << "c0P0" << "P0,c0P0"; QTest::newRow("(p0,c)") << "p0,c" << "" << "c0P0" << "P0,c0P0"; @@ -458,7 +458,7 @@ void tst_QCompleter::csMatchingOnCiSortedModel_data() QTest::newRow("(p)NNN") << "p" << "NNN" << "p3" << "p3"; QTest::newRow("(p1)") << "p1" << "" << "p1" << "p1"; QTest::newRow("(p11)") << "p11" << "" << "" << ""; - + //// Tree filter QTest::newRow("(p0,)") << "p0," << "" << "c0p0" << "p0,c0p0"; QTest::newRow("(p0,c)") << "p0,c" << "" << "c0p0" << "p0,c0p0"; @@ -471,7 +471,7 @@ void tst_QCompleter::csMatchingOnCiSortedModel_data() QTest::newRow("(p3,,c)") << "p3,,c" << "" << "" << ""; QTest::newRow("(p3,c0P3,)") << "p3,c0P3," << "" << "" << ""; QTest::newRow("(p,)") << "p," << "" << "" << ""; - + QTest::newRow("FILTERING_OFF") << "FILTERING_OFF" << "" << "" << ""; } } @@ -509,13 +509,13 @@ void tst_QCompleter::directoryModel_data() QTest::newRow("()") << "C:\\Program" << "" << "Program Files" << "C:\\Program Files"; #elif defined (Q_OS_MAC) QTest::newRow("()") << "" << "" << "/" << "/"; - QTest::newRow("(/a)") << "/a" << "" << "Applications" << "/Applications"; + QTest::newRow("(/a)") << "/a" << "" << "Applications" << "/Applications"; QTest::newRow("(/d)") << "/d" << "" << "Developer" << "/Developer"; #else QTest::newRow("()") << "" << "" << "/" << "/"; #if !defined(Q_OS_IRIX) && !defined(Q_OS_AIX) && !defined(Q_OS_HPUX) QTest::newRow("(/h)") << "/h" << "" << "home" << "/home"; -#endif +#endif QTest::newRow("(/et)") << "/et" << "" << "etc" << "/etc"; QTest::newRow("(/etc/passw)") << "/etc/passw" << "" << "passwd" << "/etc/passwd"; #endif @@ -661,7 +661,7 @@ void tst_QCompleter::currentRow() completer->setModelSorting(QCompleter::CaseInsensitivelySortedModel); completer->setCaseSensitivity(Qt::CaseInsensitive); setSourceModel(CASE_INSENSITIVELY_SORTED_MODEL); - + // blank text completer->setCompletionPrefix(""); QCOMPARE(completer->currentRow(), 0); @@ -693,7 +693,7 @@ void tst_QCompleter::sortedEngineMapFromSource() QModelIndex si1, si2, pi; QAbstractItemModel *sourceModel = completer->model(); - const QAbstractProxyModel *completionModel = + const QAbstractProxyModel *completionModel = qobject_cast(completer->completionModel()); // Fitering ON @@ -764,7 +764,7 @@ void tst_QCompleter::unsortedEngineMapFromSource() QModelIndex si, si2, si3, pi; QAbstractItemModel *sourceModel = completer->model(); - const QAbstractProxyModel *completionModel = + const QAbstractProxyModel *completionModel = qobject_cast(completer->completionModel()); si = sourceModel->index(6, completionColumn); // "P3" @@ -846,7 +846,7 @@ void tst_QCompleter::historySearch() completer->setCaseSensitivity(Qt::CaseSensitive); setSourceModel(HISTORY_MODEL); - const QAbstractProxyModel *completionModel = + const QAbstractProxyModel *completionModel = qobject_cast(completer->completionModel()); // "p3,c3p3" and "p2,c4p2" are added in the tree root @@ -954,7 +954,7 @@ void tst_QCompleter::multipleWidgets() #ifdef Q_WS_X11 qt_x11_wait_for_window_manager(&window); #endif - QTest::qWait(5000); + QTest::qWait(50); QTRY_VERIFY(qApp->focusWidget() == comboBox); comboBox->lineEdit()->setText("it"); QCOMPARE(comboBox->currentText(), QString("it")); // should not complete with setText @@ -967,7 +967,8 @@ void tst_QCompleter::multipleWidgets() lineEdit->setCompleter(&completer); lineEdit->show(); lineEdit->setFocus(); - QTest::qWait(5000); + QTest::qWait(50); + QTRY_VERIFY(qApp->focusWidget() == lineEdit); lineEdit->setText("it"); QCOMPARE(lineEdit->text(), QString("it")); // should not completer with setText QCOMPARE(comboBox->currentText(), QString("")); // combo box text must not change! @@ -1029,7 +1030,7 @@ void tst_QCompleter::dynamicSortOrder() QCOMPARE(completer.completionCount(), 12); completer.setCompletionPrefix("13"); QCOMPARE(completer.completionCount(), 2); - + root->sortChildren(0, Qt::DescendingOrder); completer.setCompletionPrefix("13"); QCOMPARE(completer.completionCount(), 2); -- cgit v0.12 From 449f033b88a18204404356664b654b85cc086092 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 13 Jul 2009 20:49:43 +0200 Subject: Compile without qt3support --- src/gui/kernel/qwhatsthis.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qwhatsthis.cpp b/src/gui/kernel/qwhatsthis.cpp index f569c97..62b5863 100644 --- a/src/gui/kernel/qwhatsthis.cpp +++ b/src/gui/kernel/qwhatsthis.cpp @@ -351,7 +351,7 @@ void QWhatsThat::paintEvent(QPaintEvent*) rect.translate(-r.x(), -r.y()); p.setClipRect(rect); QAbstractTextDocumentLayout::PaintContext context; - context.palette.setColor(QPalette::Text, context.palette.toolTipText()); + context.palette.setBrush(QPalette::Text, context.palette.toolTipText()); doc->documentLayout()->draw(&p, context); } else -- cgit v0.12 From 8e186f42278c7033a2df08f4a986419087457efc Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 13 Jul 2009 11:42:07 -0700 Subject: Clean up QDirectFBPaintEngine code - Remove unnecessary copy of QTransform - Fold matrixRotShear and scale into transformationFlags. Note that transformationFlags is not a proper bitset of the types of transform but rather set to the most complex operation (from QTransform::type()) and having NegativeScale added if qMin(transform.m11(), transform.m22()) < 0 - Fix a bug whereby setState didn't call setRenderHints - Make everything more readable - Don't initialize state in QDirectFBPaintEngine::begin() QDirectFBPaintEngine::setState will be called from QPainter::begin just before QDirectFBPaintEngine::begin Reviewed-by: Donald --- .../gfxdrivers/directfb/qdirectfbpaintengine.cpp | 137 +++++++++++---------- 1 file changed, 71 insertions(+), 66 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 27df0da..db08240 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -80,7 +80,7 @@ template inline const T *ptr(const T &t) { return &t; } template <> inline const bool* ptr(const bool &) { return 0; } template static void rasterFallbackWarn(const char *msg, const char *func, const device *dev, - int scale, bool matrixRotShear, bool simplePen, + uint transformationType, bool simplePen, bool dfbHandledClip, bool unsupportedCompositionMode, const char *nameOne, const T1 &one, const char *nameTwo, const T2 &two, @@ -95,8 +95,7 @@ static void rasterFallbackWarn(const char *msg, const char *func, const device * dbg << dev << "of type" << dev->devType(); } - dbg << "scale" << scale - << "matrixRotShear" << matrixRotShear + dbg << QString("transformationType 0x%1").arg(transformationType, 3, 16, QLatin1Char('0')) << "simplePen" << simplePen << "dfbHandledClip" << dfbHandledClip << "unsupportedCompositionMode" << unsupportedCompositionMode; @@ -123,9 +122,10 @@ static void rasterFallbackWarn(const char *msg, const char *func, const device * if (op & (QT_DIRECTFB_WARN_ON_RASTERFALLBACKS)) \ rasterFallbackWarn("Disabled raster engine operation", \ __FUNCTION__, state()->painter->device(), \ - d_func()->scale, d_func()->matrixRotShear, \ - d_func()->simplePen, d_func()->dfbCanHandleClip(), \ - d_func()->unsupportedCompositionMode, \ + d_func()->transformationType, \ + d_func()->simplePen, \ + d_func()->dfbCanHandleClip(), \ + d_func()->unsupportedCompositionMode, \ #one, one, #two, two, #three, three); \ if (op & (QT_DIRECTFB_DISABLE_RASTERFALLBACKS)) \ return; @@ -138,9 +138,10 @@ static void rasterFallbackWarn(const char *msg, const char *func, const device * if (op & (QT_DIRECTFB_WARN_ON_RASTERFALLBACKS)) \ rasterFallbackWarn("Falling back to raster engine for", \ __FUNCTION__, state()->painter->device(), \ - d_func()->scale, d_func()->matrixRotShear, \ - d_func()->simplePen, d_func()->dfbCanHandleClip(), \ - d_func()->unsupportedCompositionMode, \ + d_func()->transformationType, \ + d_func()->simplePen, \ + d_func()->dfbCanHandleClip(), \ + d_func()->unsupportedCompositionMode, \ #one, one, #two, two, #three, three); #else #define RASTERFALLBACK(op, one, two, three) @@ -211,16 +212,19 @@ static QCache imageCache(4*1024*1024); // 4 MB class QDirectFBPaintEnginePrivate : public QRasterPaintEnginePrivate { public: - enum Scale { NoScale, Scaled, NegativeScale }; - + enum TransformationTypeFlags { + NegativeScale = 0x100, + RectsUnsupported = (QTransform::TxRotate|QTransform::TxShear|QTransform::TxProject), + BlitUnsupported = (NegativeScale|RectsUnsupported) + }; QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p); ~QDirectFBPaintEnginePrivate(); - void setTransform(const QTransform &m); - void setPen(const QPen &pen); + inline void setTransform(const QTransform &transforma); + inline void setPen(const QPen &pen); inline void setCompositionMode(QPainter::CompositionMode mode); inline void setOpacity(quint8 value); - void setRenderHints(QPainter::RenderHints hints); + inline void setRenderHints(QPainter::RenderHints hints); inline void setDFBColor(const QColor &color); @@ -263,11 +267,9 @@ private: bool simplePen; - bool matrixRotShear; - Scale scale; + uint transformationType; // this is QTransform::type() + NegativeScale if qMin(transform.m11(), transform.m22()) < 0 SurfaceCache *surfaceCache; - QTransform transform; int lastLockedHeight; IDirectFB *fb; @@ -288,6 +290,7 @@ private: friend class QDirectFBPaintEngine; }; + QDirectFBPaintEngine::QDirectFBPaintEngine(QPaintDevice *device) : QRasterPaintEngine(*(new QDirectFBPaintEnginePrivate(this)), device) { @@ -318,21 +321,11 @@ bool QDirectFBPaintEngine::begin(QPaintDevice *device) device->devType()); } d->lockedMemory = 0; - d->surface->GetSize(d->surface, &d->fbWidth, &d->fbHeight); - d->setTransform(QTransform()); - d->antialiased = false; - d->setOpacity(255); - d->setCompositionMode(state()->compositionMode()); - d->dirtyClip = true; - d->setPen(state()->pen); - const bool status = QRasterPaintEngine::begin(device); - // XXX: QRasterPaintEngine::begin() resets the capabilities gccaps |= PorterDuff; - return status; } @@ -389,30 +382,27 @@ void QDirectFBPaintEngine::renderHintsChanged() void QDirectFBPaintEngine::transformChanged() { Q_D(QDirectFBPaintEngine); - const QDirectFBPaintEnginePrivate::Scale old = d->scale; - d->setTransform(state()->transform()); - if (d->scale != old) { - d->setPen(state()->pen); - } + d->setTransform(state()->matrix); QRasterPaintEngine::transformChanged(); } -void QDirectFBPaintEngine::setState(QPainterState *s) +void QDirectFBPaintEngine::setState(QPainterState *state) { Q_D(QDirectFBPaintEngine); - QRasterPaintEngine::setState(s); + QRasterPaintEngine::setState(state); d->dirtyClip = true; - d->setPen(state()->pen); - d->setOpacity(quint8(state()->opacity * 255)); - d->setCompositionMode(state()->compositionMode()); - d->setTransform(state()->transform()); + d->setPen(state->pen); + d->setOpacity(quint8(state->opacity * 255)); + d->setCompositionMode(state->compositionMode()); + d->setTransform(state->transform()); + d->setRenderHints(state->renderHints); } void QDirectFBPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) { Q_D(QDirectFBPaintEngine); d->dirtyClip = true; - const QPoint bottom = d->transform.map(QPoint(0, int(path.controlPointRect().y2))); + const QPoint bottom = state()->matrix.map(QPoint(0, int(path.controlPointRect().y2))); if (bottom.y() > d->lastLockedHeight) d->lock(); QRasterPaintEngine::clip(path, op); @@ -423,7 +413,7 @@ void QDirectFBPaintEngine::clip(const QRect &rect, Qt::ClipOperation op) Q_D(QDirectFBPaintEngine); d->dirtyClip = true; if (d->clip() && !d->clip()->hasRectClip && d->clip()->enabled) { - const QPoint bottom = d->transform.map(QPoint(0, rect.bottom())); + const QPoint bottom = state()->matrix.map(QPoint(0, rect.bottom())); if (bottom.y() > d->lastLockedHeight) d->lock(); } @@ -436,8 +426,11 @@ void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount) Q_D(QDirectFBPaintEngine); d->updateClip(); const QBrush &brush = state()->brush; - if (d->unsupportedCompositionMode || !d->dfbCanHandleClip() || d->matrixRotShear - || !d->simplePen || !d->isSimpleBrush(brush)) { + if (d->unsupportedCompositionMode + || (d->transformationType & QDirectFBPaintEnginePrivate::RectsUnsupported) + || !d->simplePen + || !d->dfbCanHandleClip() + || !d->isSimpleBrush(brush)) { RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG()); d->lock(); QRasterPaintEngine::drawRects(rects, rectCount); @@ -461,8 +454,11 @@ void QDirectFBPaintEngine::drawRects(const QRectF *rects, int rectCount) Q_D(QDirectFBPaintEngine); d->updateClip(); const QBrush &brush = state()->brush; - if (d->unsupportedCompositionMode || !d->dfbCanHandleClip() || d->matrixRotShear - || !d->simplePen || !d->isSimpleBrush(brush)) { + if (d->unsupportedCompositionMode + || (d->transformationType & QDirectFBPaintEnginePrivate::RectsUnsupported) + || !d->simplePen + || !d->dfbCanHandleClip() + || !d->isSimpleBrush(brush)) { RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG()); d->lock(); QRasterPaintEngine::drawRects(rects, rectCount); @@ -544,8 +540,7 @@ void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image, d->updateClip(); #if !defined QT_NO_DIRECTFB_PREALLOCATED || defined QT_DIRECTFB_IMAGECACHE if (d->unsupportedCompositionMode - || d->matrixRotShear - || d->scale == QDirectFBPaintEnginePrivate::NegativeScale + || (d->transformationType & QDirectFBPaintEnginePrivate::BlitUnsupported) || !d->dfbCanHandleClip(r) #ifndef QT_DIRECTFB_IMAGECACHE || QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN @@ -590,8 +585,9 @@ void QDirectFBPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap, RASTERFALLBACK(DRAW_PIXMAP, r, pixmap.size(), sr); d->lock(); QRasterPaintEngine::drawPixmap(r, pixmap, sr); - } else if (d->unsupportedCompositionMode || !d->dfbCanHandleClip(r) || d->matrixRotShear - || d->scale == QDirectFBPaintEnginePrivate::NegativeScale) { + } else if (d->unsupportedCompositionMode + || (d->transformationType & QDirectFBPaintEnginePrivate::BlitUnsupported) + || !d->dfbCanHandleClip(r)) { RASTERFALLBACK(DRAW_PIXMAP, r, pixmap.size(), sr); const QImage *img = static_cast(pixmap.pixmapData())->buffer(DSLF_READ); d->lock(); @@ -623,8 +619,9 @@ void QDirectFBPaintEngine::drawTiledPixmap(const QRectF &r, RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), offset); d->lock(); QRasterPaintEngine::drawTiledPixmap(r, pixmap, offset); - } else if (d->unsupportedCompositionMode || !d->dfbCanHandleClip(r) || d->matrixRotShear - || d->scale == QDirectFBPaintEnginePrivate::NegativeScale) { + } else if (d->unsupportedCompositionMode + || (d->transformationType & QDirectFBPaintEnginePrivate::BlitUnsupported) + || !d->dfbCanHandleClip(r)) { RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), offset); const QImage *img = static_cast(pixmap.pixmapData())->buffer(DSLF_READ); d->lock(); @@ -719,7 +716,9 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) { Q_D(QDirectFBPaintEngine); d->updateClip(); - if (!d->unsupportedCompositionMode && d->dfbCanHandleClip(rect) && !d->matrixRotShear) { + if (!d->unsupportedCompositionMode + && !(d->transformationType & (QDirectFBPaintEnginePrivate::RectsUnsupported)) + && d->dfbCanHandleClip(rect)) { switch (brush.style()) { case Qt::SolidPattern: { const QColor color = brush.color(); @@ -727,12 +726,12 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) return; d->unlock(); d->setDFBColor(color); - const QRect r = d->transform.mapRect(rect).toRect(); + const QRect r = state()->matrix.mapRect(rect).toRect(); d->surface->FillRectangle(d->surface, r.x(), r.y(), r.width(), r.height()); return; } case Qt::TexturePattern: { - if (d->scale == QDirectFBPaintEnginePrivate::NegativeScale) + if (d->transformationType & QDirectFBPaintEnginePrivate::NegativeScale) break; const QPixmap texture = brush.texture(); @@ -757,14 +756,16 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QColor &color) return; Q_D(QDirectFBPaintEngine); d->updateClip(); - if (d->unsupportedCompositionMode || !d->dfbCanHandleClip() || d->matrixRotShear) { + if (d->unsupportedCompositionMode + || (d->transformationType & QDirectFBPaintEnginePrivate::RectsUnsupported) + || !d->dfbCanHandleClip()) { RASTERFALLBACK(FILL_RECT, rect, color, VOID_ARG()); d->lock(); QRasterPaintEngine::fillRect(rect, color); } else { d->unlock(); d->setDFBColor(color); - const QRect r = d->transform.mapRect(rect).toRect(); + const QRect r = state()->matrix.mapRect(rect).toRect(); d->surface->FillRectangle(d->surface, r.x(), r.y(), r.width(), r.height()); } @@ -835,7 +836,7 @@ void QDirectFBPaintEngine::initImageCache(int size) QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p) : surface(0), antialiased(false), simplePen(false), - matrixRotShear(false), scale(NoScale), lastLockedHeight(-1), + transformationType(0), lastLockedHeight(-1), fbWidth(-1), fbHeight(-1), opacity(255), dirtyClip(true), dfbHandledClip(false), dfbDevice(0), lockedMemory(0), unsupportedCompositionMode(false), q(p) @@ -894,17 +895,13 @@ void QDirectFBPaintEnginePrivate::unlock() lockedMemory = 0; } -void QDirectFBPaintEnginePrivate::setTransform(const QTransform &m) +void QDirectFBPaintEnginePrivate::setTransform(const QTransform &transform) { - transform = m; - matrixRotShear = (transform.m12() != 0 || transform.m21() != 0); + transformationType = transform.type(); if (qMin(transform.m11(), transform.m22()) < 0) { - scale = NegativeScale; - } else if (transform.m11() != 1 || transform.m22() != 1) { - scale = Scaled; - } else { - scale = NoScale; + transformationType |= QDirectFBPaintEnginePrivate::NegativeScale; } + setPen(q->state()->pen); } void QDirectFBPaintEnginePrivate::setPen(const QPen &p) @@ -916,7 +913,7 @@ void QDirectFBPaintEnginePrivate::setPen(const QPen &p) && !antialiased && pen.brush().style() == Qt::SolidPattern && pen.widthF() <= 1.0 - && (scale == NoScale || pen.isCosmetic())) { + && (transformationType < QTransform::TxScale || pen.isCosmetic())) { simplePen = true; } else { simplePen = false; @@ -965,6 +962,7 @@ void QDirectFBPaintEnginePrivate::setDFBColor(const QColor &color) void QDirectFBPaintEnginePrivate::drawLines(const QLine *lines, int n) { + const QTransform &transform = q->state()->matrix; for (int i = 0; i < n; ++i) { const QLine l = transform.map(lines[i]); surface->DrawLine(surface, l.x1(), l.y1(), l.x2(), l.y2()); @@ -973,6 +971,7 @@ void QDirectFBPaintEnginePrivate::drawLines(const QLine *lines, int n) void QDirectFBPaintEnginePrivate::drawLines(const QLineF *lines, int n) { + const QTransform &transform = q->state()->matrix; for (int i = 0; i < n; ++i) { const QLine l = transform.map(lines[i]).toLine(); surface->DrawLine(surface, l.x1(), l.y1(), l.x2(), l.y2()); @@ -990,6 +989,7 @@ void QDirectFBPaintEnginePrivate::fillRegion(const QRegion ®ion) void QDirectFBPaintEnginePrivate::fillRects(const QRect *rects, int n) { + const QTransform &transform = q->state()->matrix; for (int i = 0; i < n; ++i) { const QRect r = transform.mapRect(rects[i]); surface->FillRectangle(surface, r.x(), r.y(), @@ -999,6 +999,7 @@ void QDirectFBPaintEnginePrivate::fillRects(const QRect *rects, int n) void QDirectFBPaintEnginePrivate::fillRects(const QRectF *rects, int n) { + const QTransform &transform = q->state()->matrix; for (int i = 0; i < n; ++i) { const QRect r = transform.mapRect(rects[i]).toRect(); surface->FillRectangle(surface, r.x(), r.y(), @@ -1008,6 +1009,7 @@ void QDirectFBPaintEnginePrivate::fillRects(const QRectF *rects, int n) void QDirectFBPaintEnginePrivate::drawRects(const QRect *rects, int n) { + const QTransform &transform = q->state()->matrix; for (int i = 0; i < n; ++i) { const QRect r = transform.mapRect(rects[i]); surface->DrawRectangle(surface, r.x(), r.y(), @@ -1017,6 +1019,7 @@ void QDirectFBPaintEnginePrivate::drawRects(const QRect *rects, int n) void QDirectFBPaintEnginePrivate::drawRects(const QRectF *rects, int n) { + const QTransform &transform = q->state()->matrix; for (int i = 0; i < n; ++i) { const QRect r = transform.mapRect(rects[i]).toRect(); surface->DrawRectangle(surface, r.x(), r.y(), @@ -1062,7 +1065,7 @@ IDirectFBSurface *QDirectFBPaintEnginePrivate::getSurface(const QImage &img, boo void QDirectFBPaintEnginePrivate::blit(const QRectF &dest, IDirectFBSurface *s, const QRectF &src) { const QRect sr = src.toRect(); - const QRect dr = transform.mapRect(dest).toRect(); + const QRect dr = q->state()->matrix.mapRect(dest).toRect(); if (dr.isEmpty()) return; const DFBRectangle sRect = { sr.x(), sr.y(), sr.width(), sr.height() }; @@ -1091,6 +1094,8 @@ static inline qreal fixCoord(qreal rect_pos, qreal pixmapSize, qreal offset) void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap, const QPointF &off) { Q_ASSERT(!dirtyClip); + Q_ASSERT(!(transformationType & BlitUnsupported)); + const QTransform &transform = q->state()->matrix; const QRect destinationRect = transform.mapRect(dest).toRect().normalized(); QRect newClip = destinationRect; if (!currentClip.isEmpty()) -- cgit v0.12 From 74c95015686ad5576b53fef5f653442ea2c4053a Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 13 Jul 2009 12:50:34 -0700 Subject: Code cleanup in QDirectFBPaintEngine Take out the QPen member. Reviewed-by: Donald --- .../gfxdrivers/directfb/qdirectfbpaintengine.cpp | 26 +++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index db08240..eda83b2 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -261,10 +261,7 @@ public: private: IDirectFBSurface *surface; - QPen pen; - bool antialiased; - bool simplePen; uint transformationType; // this is QTransform::type() + NegativeScale if qMin(transform.m11(), transform.m22()) < 0 @@ -443,8 +440,9 @@ void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount) d->setDFBColor(brush.color()); d->fillRects(rects, rectCount); } - if (d->pen != Qt::NoPen) { - d->setDFBColor(d->pen.color()); + const QPen &pen = state()->pen; + if (pen != Qt::NoPen) { + d->setDFBColor(pen.color()); d->drawRects(rects, rectCount); } } @@ -471,8 +469,9 @@ void QDirectFBPaintEngine::drawRects(const QRectF *rects, int rectCount) d->setDFBColor(brush.color()); d->fillRects(rects, rectCount); } - if (d->pen != Qt::NoPen) { - d->setDFBColor(d->pen.color()); + const QPen &pen = state()->pen; + if (pen != Qt::NoPen) { + d->setDFBColor(pen.color()); d->drawRects(rects, rectCount); } } @@ -488,9 +487,10 @@ void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount) return; } - if (d->pen != Qt::NoPen) { + const QPen &pen = state()->pen; + if (pen != Qt::NoPen) { d->unlock(); - d->setDFBColor(d->pen.color()); + d->setDFBColor(pen.color()); d->drawLines(lines, lineCount); } } @@ -506,9 +506,10 @@ void QDirectFBPaintEngine::drawLines(const QLineF *lines, int lineCount) return; } - if (d->pen != Qt::NoPen) { + const QPen &pen = state()->pen; + if (pen != Qt::NoPen) { d->unlock(); - d->setDFBColor(d->pen.color()); + d->setDFBColor(pen.color()); d->drawLines(lines, lineCount); } } @@ -904,9 +905,8 @@ void QDirectFBPaintEnginePrivate::setTransform(const QTransform &transform) setPen(q->state()->pen); } -void QDirectFBPaintEnginePrivate::setPen(const QPen &p) +void QDirectFBPaintEnginePrivate::setPen(const QPen &pen) { - pen = p; if (pen.style() == Qt::NoPen) { simplePen = true; } else if (pen.style() == Qt::SolidLine -- cgit v0.12 From 3f14a6f5bf06ffa2451226928a925f5d23e343c3 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 13 Jul 2009 11:44:24 -0700 Subject: Remove unused variables in QDirectFBPaintEngine fbWidth/fbHeight were never used for anything Reviewed-by: Donald --- src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index eda83b2..4ede69a 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -270,8 +270,6 @@ private: int lastLockedHeight; IDirectFB *fb; - int fbWidth; - int fbHeight; quint8 opacity; @@ -318,7 +316,6 @@ bool QDirectFBPaintEngine::begin(QPaintDevice *device) device->devType()); } d->lockedMemory = 0; - d->surface->GetSize(d->surface, &d->fbWidth, &d->fbHeight); const bool status = QRasterPaintEngine::begin(device); // XXX: QRasterPaintEngine::begin() resets the capabilities @@ -838,7 +835,7 @@ void QDirectFBPaintEngine::initImageCache(int size) QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p) : surface(0), antialiased(false), simplePen(false), transformationType(0), lastLockedHeight(-1), - fbWidth(-1), fbHeight(-1), opacity(255), dirtyClip(true), + opacity(255), dirtyClip(true), dfbHandledClip(false), dfbDevice(0), lockedMemory(0), unsupportedCompositionMode(false), q(p) { -- cgit v0.12 From 815eec62128d9b971306d698c9beee52a604d455 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 13 Jul 2009 11:47:09 -0700 Subject: Remove QDirectFBPaintEnginePrivate::setOpacity The function only sets a variable anyway. Replace with: d->opacity = state()->opacity * 255 Reviewed-by: Donald --- src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 4ede69a..1ea0325 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -223,7 +223,6 @@ public: inline void setTransform(const QTransform &transforma); inline void setPen(const QPen &pen); inline void setCompositionMode(QPainter::CompositionMode mode); - inline void setOpacity(quint8 value); inline void setRenderHints(QPainter::RenderHints hints); inline void setDFBColor(const QColor &color); @@ -355,7 +354,7 @@ void QDirectFBPaintEngine::penChanged() void QDirectFBPaintEngine::opacityChanged() { Q_D(QDirectFBPaintEngine); - d->setOpacity(quint8(state()->opacity * 255)); + d->opacity = quint8(state()->opacity * 255); QRasterPaintEngine::opacityChanged(); } @@ -386,7 +385,7 @@ void QDirectFBPaintEngine::setState(QPainterState *state) QRasterPaintEngine::setState(state); d->dirtyClip = true; d->setPen(state->pen); - d->setOpacity(quint8(state->opacity * 255)); + d->opacity = quint8(state->opacity * 255); d->setCompositionMode(state->compositionMode()); d->setTransform(state->transform()); d->setRenderHints(state->renderHints); @@ -922,12 +921,6 @@ void QDirectFBPaintEnginePrivate::setCompositionMode(QPainter::CompositionMode m unsupportedCompositionMode = (mode != QPainter::CompositionMode_SourceOver); } - -void QDirectFBPaintEnginePrivate::setOpacity(quint8 op) -{ - opacity = op; -} - void QDirectFBPaintEnginePrivate::setRenderHints(QPainter::RenderHints hints) { const bool old = antialiased; -- cgit v0.12 From fd302ab05face6c592944187fb594c1f55d62c5d Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 13 Jul 2009 21:55:57 +0200 Subject: Update to today's WebKit 4.6 snapshot --- util/webkit/mkdist-webkit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/webkit/mkdist-webkit b/util/webkit/mkdist-webkit index 9e9d656..a843c83 100755 --- a/util/webkit/mkdist-webkit +++ b/util/webkit/mkdist-webkit @@ -5,7 +5,7 @@ die() { exit 1 } -default_tag="qtwebkit-4.6-snapshot-29062009" +default_tag="qtwebkit-4.6-snapshot-13072009" if [ $# -eq 0 ]; then tag="$default_tag" -- cgit v0.12 From afb4dfc7b9536b7e7f443a89e94f331f8946de07 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 13 Jul 2009 12:52:49 -0700 Subject: Move ALPHA_PREMULT It's only used once and I want to unclutter the top of qdirectfbpaintengine.cpp Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 1ea0325..605324e 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -147,13 +147,6 @@ static void rasterFallbackWarn(const char *msg, const char *func, const device * #define RASTERFALLBACK(op, one, two, three) #endif -static inline uint ALPHA_MUL(uint x, uint a) -{ - uint t = x * a; - t = ((t + (t >> 8) + 0x80) >> 8) & 0xff; - return t; -} - class SurfaceCache { public: @@ -940,6 +933,13 @@ void QDirectFBPaintEnginePrivate::prepareForBlit(bool alpha) surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blittingFlags)); } +static inline uint ALPHA_MUL(uint x, uint a) +{ + uint t = x * a; + t = ((t + (t >> 8) + 0x80) >> 8) & 0xff; + return t; +} + void QDirectFBPaintEnginePrivate::setDFBColor(const QColor &color) { Q_ASSERT(surface); -- cgit v0.12 From f23fa541a04abd1ddc36815a285ec824d5b5c5e0 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 13 Jul 2009 22:00:20 +0200 Subject: Updated WebKit from /home/shausman/src/webkit/trunk to qtwebkit-4.6-snapshot-13072009 ( b2abc0c271880b8135507861056af497f895adf5 ) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes in WebKit/qt since the last update: ++ b/WebKit/qt/ChangeLog 2009-07-13 Simon Hausmann Reviewed by Ariya Hidayat. Fix qdoc warnings for QWebPage::shouldInterruptJavaScript() and mention how to re-implement it. * Api/qwebpage.cpp: 2009-07-13 Simon Hausmann Reviewed by Ariya Hidayat. Fix crash with plugins when the plugin stream is cancelled. Similar to r26667 handle the case where didReceiveResponse on the plugin view results in failure to set up the stream and setMainDocumentError being called instead. This will set the m_pluginView back to 0 and we need check for it before calling didReceiveData. This was triggered by consecutive execution of LayoutTests/plugins/return-error-from-new-stream-callback-in-full-frame-plugin.html followed by LayoutTests/scrollbars/scrollbar-crash-on-refresh.html * WebCoreSupport/FrameLoaderClientQt.cpp: (WebCore::FrameLoaderClientQt::committedLoad): 2009-07-13 Simon Hausmann Reviewed by Ariya Hidayat. Added QWebDatabase::removeAllDatabases, as a way to delete all databases from the offline storage path. Used by the Qt DRT. * Api/qwebdatabase.cpp: (QWebDatabase::removeAllDatabases): * Api/qwebdatabase.h: 2009-07-13 Simon Hausmann Reviewed by Ariya Hidayat. Added loadStarted() and loadFinished() signals to QWebFrame, to allow load tracking of individual frames, as opposed to QWebPage's loadStarted/loadFinished signals that are emitted whenever _any_ child frame loads/finishes. * Api/qwebframe.cpp: Document new signals. * Api/qwebframe.h: Add new signals. * WebCoreSupport/FrameLoaderClientQt.cpp: (WebCore::FrameLoaderClientQt::setFrame): Connect new signals. 2009-07-13 Simon Hausmann Reviewed by Ariya Hidayat. Add hooks for the GCController JavaScript interface needed by the Qt DRT. Fixed sort order of includes in qwebframe.cpp. * Api/qwebframe.cpp: (qt_drt_javaScriptObjectsCount): (qt_drt_garbageCollector_collect): (qt_drt_garbageCollector_collectOnAlternateThread): 2009-07-13 Simon Hausmann Reviewed by Ariya Hidayat. Add hooks for the GCController JavaScript interface needed by the Qt DRT. Fixed sort order of includes in qwebframe.cpp. * Api/qwebframe.cpp: (qt_drt_javaScriptObjectsCount): (qt_drt_garbageCollector_collect): (qt_drt_garbageCollector_collectOnAlternateThread): 2009-07-12 Brent Fulgham Speculative build fix after http://trac.webkit.org/changeset/45786. * WebCoreSupport/ChromeClientQt.cpp: (WebCore::ChromeClientQt::addMessageToConsole): * WebCoreSupport/ChromeClientQt.h: 2009-07-10 Yael Aharon Reviewed by Holger Freyther. https://bugs.webkit.org/show_bug.cgi?id=27136 Fix a bug where webkit hangs when executing infinite JavaScript loop. * Api/qwebpage.cpp: (QWebPage::shouldInterruptJavaScript): * Api/qwebpage.h: * WebCoreSupport/ChromeClientQt.cpp: (WebCore::ChromeClientQt::shouldInterruptJavaScript): * tests/qwebpage/tst_qwebpage.cpp: (JSTestPage::JSTestPage): (JSTestPage::shouldInterruptJavaScript): (tst_QWebPage::infiniteLoopJS): 2009-07-10 Simon Hausmann Reviewed by Holger Freyther. https://bugs.webkit.org/show_bug.cgi?id=27108 Fix crash when in frame tree of a new frame before the new frame has been installed in the frame tree, similar to r35088. After calling Frame::init() the frame it may have been removed from the frame tree again through JavaScript. Detect this by checking the page() afterwards. To make this check safe the Frame::init() code was moved into QWebFrameData's constructor, where a RefPtr holds a reference to the frame. After the check back in FrameLoaderClientQt we would hold the single reference left and after release() the frame, its frame loader, its client as well as the QWebFrame should have disappeared then. * Api/qwebframe.cpp: (QWebFramePrivate::init): Only call Frame::init here, the rest is done in QWebFrameData's constructor. (QWebFrame::QWebFrame): * Api/qwebframe_p.h: Adjust declaration. (QWebFrameData::QWebFrameData): Create the Frame here. * Api/qwebpage.cpp: (QWebPagePrivate::createMainFrame): Adjust and simplify to new QWebFrame constructor. * WebCoreSupport/FrameLoaderClientQt.cpp: (WebCore::FrameLoaderClientQt::createFrame): Adjust to new QWebFrame construction using QWebFrameData and add the check like in r35088. 2009-07-09 Beth Dakin Reviewed by Dave Hyatt. Make Widget RefCounted to fix: REGRESSION (TOT): In Mail, a crash occurs at WebCore::Widget::afterMouseDown() after clicking To Do's close box WER #16: Repro Access Violation in WebCore::PluginView::bindingInstance (1310178023) -and- WER #13: Crash in WebKit! WebCore::PluginView::performRequest+203 (1311461169) * WebCoreSupport/FrameLoaderClientQt.cpp: (WebCore::FrameLoaderClientQt::createPlugin): (WebCore::FrameLoaderClientQt::createJavaAppletWidget): * WebCoreSupport/FrameLoaderClientQt.h: 2009-07-08 Pradeepto Bhattacharya Reviewed by Ariya Hidayat. Build fix. * WebCoreSupport/FrameLoaderClientQt.h: Removed the slot slotCallPolicyFunction(). 2009-07-08 Simon Hausmann Reviewed by Tor Arne Vestbø. https://bugs.webkit.org/show_bug.cgi?id=27080 Fix DRT instability issues with fast/loader/submit-form-while-parsing-2.html When the form is submitted we call the policy function in the frame loader delayed with a queued connection. That queued connection sometimes interferes with the javascript timeout set in the testcase. Eliminate the entire delayed policy function mechanism and instead always call back directly, like in the other ports. In most other places we called the slot directly anyway. * WebCoreSupport/FrameLoaderClientQt.cpp: (WebCore::FrameLoaderClientQt::FrameLoaderClientQt): Remove m_policyFunction. (WebCore::FrameLoaderClientQt::callPolicyFunction): Call the policy function directly instead of emitting the queued signal. (WebCore::FrameLoaderClientQt::cancelPolicyCheck): Call callPolicyFunction directly. (WebCore::FrameLoaderClientQt::dispatchWillSubmitForm): Ditto. (WebCore::FrameLoaderClientQt::dispatchDecidePolicyForMIMEType): Ditto. (WebCore::FrameLoaderClientQt::dispatchDecidePolicyForNewWindowAction): Ditto. (WebCore::FrameLoaderClientQt::dispatchDecidePolicyForNavigationAction): Ditto. * WebCoreSupport/FrameLoaderClientQt.h: Remove m_policyFunction as well as the associated signal. 2009-07-07 Simon Hausmann Reviewed by Holger Freyther. Add Qt DRT hook for clearing the frame name. * Api/qwebframe.cpp: (qt_drt_clearFrameName): 2009-07-05 Simon Hausmann Reviewed by Holger Freyther. Fix two qdoc warnings. Added missing \property for QWebFrame::hasFocus and added \a tag for pos of QWebPage::frameAt. * Api/qwebframe.cpp: * Api/qwebpage.cpp: 2009-07-04 Holger Hans Peter Freyther Reviewed by Simon Hausmann. Use the recently introduced FocusController::setFocused Use the recently introduced FocusController::setFocused in the Qt platform. The SelectionController will be updated from within the FocusController now. * Api/qwebpage.cpp: (QWebPagePrivate::focusInEvent): (QWebPagePrivate::focusOutEvent): 2009-07-02 Simon Hausmann Reviewed by Ariya Hidayat. Improve documentation of QWebFrame::setFocus and hasFocus() Added missing Q_PROPERTY for QWebFrame::hasFocus. * Api/qwebframe.cpp: Clarify the docs. * Api/qwebframe.h: add Q_PROPERTY(focus). 2009-07-02 Joe Ligman Reviewed by Simon Hausmann. Bug 26855: [Qt] New methods for QWebFrame to check and set focus. Added new public methods QWebFrame::hasFocus() and QWebFrame::setFocus() Added auto test. * Api/qwebframe.cpp: (QWebFrame::hasFocus): (QWebFrame::setFocus): * Api/qwebframe.h: * tests/qwebframe/tst_qwebframe.cpp: 2009-07-01 Robert Hogan Reviewed by NOBODY. Fix Qt segfault when javascript disabled. If clients call addToJavaScriptWindowObject even though JavascriptEnabled is false webkit will segfault on the assert: ASSERTION FAILED: _rootObject (../../../WebCore/bridge/runtime.cpp:52 JSC::Bindings::Instance::Instance(WTF::PassRefPtr)) Fix is to ensure JavaScript is enabled when client calls addToJavaScriptWindowObject. https://bugs.webkit.org/show_bug.cgi?id=26906 * Api/qwebframe.cpp: (QWebFrame::addToJavaScriptWindowObject): 2009-07-01 Jakub Wieczorek Reviewed by Simon Hausmann. [Qt] Move some API headers from WebCore.pro to headers.pri so that they get installed when running make install from the build directory. * Api/headers.pri: 2009-07-01 Balazs Kelemen Reviewed by Simon Hausmann. Fixed robotized QtLauncher to work when there is no index.html in the user's home. * QtLauncher/main.cpp: (main): 2009-06-30 Brian Weinstein Reviewed by Adam Roben. Renamed scrollbarUnderPoint to scrollbarAtPoint to follow conventions. * Api/qwebpage.cpp: (QWebPage::swallowContextMenuEvent): 2009-06-30 Joe Ligman Reviewed by Adam Treat. Bug 26422: [Qt] QWebPagePrivate::frameAt calculates wrong frame Added a public method QWebPage::frameAt Removed QWebPagePrivate::frameAt, which calcuated the wrong frame Modified QWebPage::swallowContextMenuEvent to use the new frameAt method New test case for frameAt added to tst_qwebpage.cpp * Api/qwebpage.cpp: (QWebPage::frameAt): (QWebPage::swallowContextMenuEvent): * Api/qwebpage.h: * Api/qwebpage_p.h: * tests/qwebpage/frametest/iframe.html: Added. * tests/qwebpage/frametest/iframe2.html: Added. * tests/qwebpage/frametest/iframe3.html: Added. * tests/qwebpage/tst_qwebpage.cpp: (frameAtHelper): (tst_QWebPage::frameAt): * tests/qwebpage/tst_qwebpage.qrc: 2009-06-30 Jakub Wieczorek Reviewed by Simon Hausmann. Add QWebFrame::baseUrl() function that exposes the base URL of a frame. Autotests included. * Api/qwebframe.cpp: (QWebFrame::baseUrl): * Api/qwebframe.h: * tests/qwebframe/tst_qwebframe.cpp: --- src/3rdparty/webkit/ChangeLog | 69 + src/3rdparty/webkit/JavaScriptCore/ChangeLog | 461 ++ .../webkit/JavaScriptCore/JavaScriptCore.gypi | 452 ++ .../webkit/JavaScriptCore/bytecode/CodeBlock.cpp | 25 +- .../webkit/JavaScriptCore/bytecode/CodeBlock.h | 39 +- .../webkit/JavaScriptCore/bytecode/Opcode.h | 1 - .../bytecompiler/BytecodeGenerator.cpp | 87 +- .../bytecompiler/BytecodeGenerator.h | 14 +- .../webkit/JavaScriptCore/create_hash_table | 2 +- .../webkit/JavaScriptCore/debugger/Debugger.h | 2 +- .../JavaScriptCore/generated/ArrayPrototype.lut.h | 2 +- .../JavaScriptCore/generated/DatePrototype.lut.h | 2 +- .../webkit/JavaScriptCore/generated/Grammar.cpp | 1002 +++- .../webkit/JavaScriptCore/generated/Grammar.h | 109 +- .../JavaScriptCore/generated/JSONObject.lut.h | 2 +- .../webkit/JavaScriptCore/generated/Lexer.lut.h | 2 +- .../JavaScriptCore/generated/MathObject.lut.h | 2 +- .../generated/NumberConstructor.lut.h | 2 +- .../generated/RegExpConstructor.lut.h | 2 +- .../JavaScriptCore/generated/RegExpObject.lut.h | 2 +- .../JavaScriptCore/generated/StringPrototype.lut.h | 2 +- .../webkit/JavaScriptCore/interpreter/CallFrame.h | 19 +- .../JavaScriptCore/interpreter/Interpreter.cpp | 562 +- .../JavaScriptCore/interpreter/Interpreter.h | 1 - src/3rdparty/webkit/JavaScriptCore/jit/JIT.cpp | 1 - .../webkit/JavaScriptCore/jit/JITOpcodes.cpp | 13 +- src/3rdparty/webkit/JavaScriptCore/jsc.cpp | 6 +- .../JavaScriptCore/parser/NodeConstructors.h | 5 + .../webkit/JavaScriptCore/parser/Nodes.cpp | 6 +- src/3rdparty/webkit/JavaScriptCore/parser/Nodes.h | 2 + .../webkit/JavaScriptCore/runtime/JSActivation.cpp | 2 +- .../webkit/JavaScriptCore/runtime/JSGlobalData.cpp | 16 +- .../JavaScriptCore/runtime/LiteralParser.cpp | 6 +- .../webkit/JavaScriptCore/runtime/Lookup.h | 7 + .../webkit/JavaScriptCore/runtime/RegExp.cpp | 41 +- .../webkit/JavaScriptCore/runtime/RegExp.h | 3 +- .../JavaScriptCore/runtime/RegExpConstructor.cpp | 53 +- .../JavaScriptCore/runtime/StringPrototype.cpp | 3 +- .../webkit/JavaScriptCore/wtf/FastMalloc.cpp | 21 +- .../webkit/JavaScriptCore/wtf/FastMalloc.h | 7 + src/3rdparty/webkit/JavaScriptCore/wtf/HashSet.h | 16 +- .../webkit/JavaScriptCore/wtf/OwnPtrCommon.h | 3 + .../webkit/JavaScriptCore/wtf/OwnPtrWin.cpp | 7 + src/3rdparty/webkit/JavaScriptCore/wtf/Platform.h | 18 +- .../webkit/JavaScriptCore/wtf/PtrAndFlags.h | 15 +- src/3rdparty/webkit/JavaScriptCore/wtf/dtoa.cpp | 216 +- .../webkit/JavaScriptCore/yarr/RegexJIT.cpp | 2 + src/3rdparty/webkit/VERSION | 6 +- src/3rdparty/webkit/WebCore/ChangeLog | 5485 ++++++++++++++++++++ src/3rdparty/webkit/WebCore/DerivedSources.cpp | 1 + src/3rdparty/webkit/WebCore/WebCore.gypi | 3334 ++++++++++++ src/3rdparty/webkit/WebCore/WebCore.order | 1 - src/3rdparty/webkit/WebCore/WebCore.pro | 48 +- .../WebCore/accessibility/AccessibilityObject.h | 5 +- .../accessibility/AccessibilityRenderObject.cpp | 46 +- .../accessibility/AccessibilityRenderObject.h | 1 + .../WebCore/bindings/js/JSAbstractWorkerCustom.cpp | 93 + .../bindings/js/JSCustomXPathNSResolver.cpp | 2 +- .../webkit/WebCore/bindings/js/JSDOMBinding.cpp | 5 + .../webkit/WebCore/bindings/js/JSDOMBinding.h | 12 +- .../webkit/WebCore/bindings/js/JSDOMWindowBase.cpp | 2 +- .../WebCore/bindings/js/JSDOMWindowCustom.cpp | 8 + .../bindings/js/JSDataGridColumnListCustom.cpp | 5 + .../WebCore/bindings/js/JSDataGridDataSource.cpp | 35 +- .../WebCore/bindings/js/JSDataGridDataSource.h | 5 +- .../webkit/WebCore/bindings/js/JSEventTarget.cpp | 14 + .../bindings/js/JSHTMLDataGridElementCustom.cpp | 10 + .../bindings/js/JSHTMLFormElementCustom.cpp | 2 +- .../WebCore/bindings/js/JSLazyEventListener.cpp | 8 +- .../WebCore/bindings/js/JSNamedNodesCollection.cpp | 4 +- .../webkit/WebCore/bindings/js/JSRGBColor.cpp | 4 +- .../bindings/js/JSSharedWorkerConstructor.cpp | 83 + .../bindings/js/JSSharedWorkerConstructor.h | 56 + .../WebCore/bindings/js/JSSharedWorkerCustom.cpp | 57 + .../WebCore/bindings/js/JSWorkerContextCustom.cpp | 11 + .../webkit/WebCore/bindings/js/JSWorkerCustom.cpp | 1 + .../WebCore/bindings/js/ScriptController.cpp | 13 +- .../WebCore/bindings/js/ScriptObjectQuarantine.cpp | 2 +- .../WebCore/bindings/scripts/CodeGeneratorJS.pm | 14 +- .../WebCore/bindings/scripts/CodeGeneratorV8.pm | 103 +- .../webkit/WebCore/bridge/qt/qt_instance.cpp | 2 +- .../webkit/WebCore/bridge/qt/qt_runtime.cpp | 2 +- .../webkit/WebCore/bridge/runtime_array.cpp | 8 +- .../webkit/WebCore/bridge/runtime_method.cpp | 7 +- .../webkit/WebCore/bridge/runtime_object.cpp | 4 +- .../webkit/WebCore/bridge/runtime_root.cpp | 1 + src/3rdparty/webkit/WebCore/bridge/runtime_root.h | 2 +- src/3rdparty/webkit/WebCore/css/CSSParser.cpp | 45 +- .../webkit/WebCore/css/CSSPrimitiveValueMappings.h | 10 +- src/3rdparty/webkit/WebCore/css/CSSRule.idl | 1 + src/3rdparty/webkit/WebCore/css/CSSSelector.cpp | 12 + src/3rdparty/webkit/WebCore/css/CSSSelector.h | 3 + .../webkit/WebCore/css/CSSStyleSelector.cpp | 48 +- src/3rdparty/webkit/WebCore/css/CSSStyleSelector.h | 7 + src/3rdparty/webkit/WebCore/css/CSSValue.idl | 1 + .../webkit/WebCore/css/CSSValueKeywords.in | 4 +- src/3rdparty/webkit/WebCore/css/MediaList.cpp | 2 +- src/3rdparty/webkit/WebCore/css/MediaQuery.h | 3 +- .../webkit/WebCore/css/MediaQueryEvaluator.cpp | 2 +- .../webkit/WebCore/css/MediaQueryEvaluator.h | 3 +- src/3rdparty/webkit/WebCore/css/MediaQueryExp.h | 6 +- src/3rdparty/webkit/WebCore/css/StyleSheet.idl | 1 + src/3rdparty/webkit/WebCore/css/WebKitCSSMatrix.h | 2 +- src/3rdparty/webkit/WebCore/css/html.css | 613 +++ src/3rdparty/webkit/WebCore/css/html4.css | 617 --- src/3rdparty/webkit/WebCore/css/mediaControls.css | 13 +- .../webkit/WebCore/css/mediaControlsQT.css | 115 +- src/3rdparty/webkit/WebCore/css/themeWin.css | 2 +- src/3rdparty/webkit/WebCore/dom/Comment.h | 3 +- src/3rdparty/webkit/WebCore/dom/ContainerNode.cpp | 2 + src/3rdparty/webkit/WebCore/dom/Document.cpp | 24 +- src/3rdparty/webkit/WebCore/dom/Document.h | 8 +- src/3rdparty/webkit/WebCore/dom/Document.idl | 2 +- .../webkit/WebCore/dom/DocumentFragment.cpp | 2 +- src/3rdparty/webkit/WebCore/dom/DocumentFragment.h | 3 +- .../webkit/WebCore/dom/DynamicNodeList.cpp | 13 +- src/3rdparty/webkit/WebCore/dom/DynamicNodeList.h | 9 +- src/3rdparty/webkit/WebCore/dom/EditingText.h | 3 +- src/3rdparty/webkit/WebCore/dom/Element.cpp | 32 +- src/3rdparty/webkit/WebCore/dom/Element.h | 2 + src/3rdparty/webkit/WebCore/dom/Event.idl | 1 + src/3rdparty/webkit/WebCore/dom/EventTarget.cpp | 7 + src/3rdparty/webkit/WebCore/dom/EventTarget.h | 6 + .../webkit/WebCore/dom/HTMLAllCollection.idl | 40 + src/3rdparty/webkit/WebCore/dom/MessageChannel.cpp | 4 +- .../webkit/WebCore/dom/MessagePortChannel.cpp | 17 - .../webkit/WebCore/dom/MessagePortChannel.h | 2 + src/3rdparty/webkit/WebCore/dom/NamedAttrMap.cpp | 2 +- src/3rdparty/webkit/WebCore/dom/Node.cpp | 28 +- src/3rdparty/webkit/WebCore/dom/Node.idl | 2 +- src/3rdparty/webkit/WebCore/dom/NodeRareData.h | 21 +- src/3rdparty/webkit/WebCore/dom/Notation.h | 3 +- .../webkit/WebCore/dom/ProcessingInstruction.h | 3 +- src/3rdparty/webkit/WebCore/dom/Range.cpp | 10 +- .../webkit/WebCore/dom/ScriptExecutionContext.h | 2 +- src/3rdparty/webkit/WebCore/dom/SelectElement.cpp | 13 + src/3rdparty/webkit/WebCore/dom/SelectElement.h | 3 +- src/3rdparty/webkit/WebCore/dom/StyledElement.cpp | 5 +- .../webkit/WebCore/dom/XMLTokenizerLibxml2.cpp | 17 +- src/3rdparty/webkit/WebCore/dom/XMLTokenizerQt.cpp | 7 +- .../dom/default/PlatformMessagePortChannel.cpp | 21 + .../webkit/WebCore/editing/ApplyStyleCommand.cpp | 4 +- .../WebCore/editing/CompositeEditCommand.cpp | 2 + .../WebCore/editing/DeleteSelectionCommand.cpp | 2 +- src/3rdparty/webkit/WebCore/editing/Editor.cpp | 12 +- .../webkit/WebCore/editing/EditorCommand.cpp | 3 +- .../WebCore/editing/IndentOutdentCommand.cpp | 10 +- .../webkit/WebCore/editing/IndentOutdentCommand.h | 3 + .../webkit/WebCore/editing/SelectionController.cpp | 3 +- .../webkit/WebCore/editing/SmartReplaceICU.cpp | 3 +- .../webkit/WebCore/editing/TextIterator.cpp | 96 +- .../WebCore/editing/gtk/SelectionControllerGtk.cpp | 4 +- .../webkit/WebCore/generated/ArrayPrototype.lut.h | 2 +- .../webkit/WebCore/generated/CSSGrammar.cpp | 877 +++- src/3rdparty/webkit/WebCore/generated/CSSGrammar.h | 109 +- .../webkit/WebCore/generated/CSSValueKeywords.c | 547 +- .../webkit/WebCore/generated/CSSValueKeywords.h | 426 +- .../webkit/WebCore/generated/DatePrototype.lut.h | 2 +- src/3rdparty/webkit/WebCore/generated/Grammar.cpp | 1002 +++- src/3rdparty/webkit/WebCore/generated/Grammar.h | 109 +- .../WebCore/generated/HTMLElementFactory.cpp | 28 + .../webkit/WebCore/generated/HTMLNames.cpp | 20 +- src/3rdparty/webkit/WebCore/generated/HTMLNames.h | 4 + src/3rdparty/webkit/WebCore/generated/JSAttr.cpp | 6 +- .../webkit/WebCore/generated/JSBarInfo.cpp | 4 +- .../webkit/WebCore/generated/JSCDATASection.cpp | 6 +- .../webkit/WebCore/generated/JSCSSCharsetRule.cpp | 6 +- .../webkit/WebCore/generated/JSCSSFontFaceRule.cpp | 6 +- .../webkit/WebCore/generated/JSCSSImportRule.cpp | 6 +- .../webkit/WebCore/generated/JSCSSMediaRule.cpp | 6 +- .../webkit/WebCore/generated/JSCSSPageRule.cpp | 6 +- .../WebCore/generated/JSCSSPrimitiveValue.cpp | 6 +- .../webkit/WebCore/generated/JSCSSRule.cpp | 6 +- .../webkit/WebCore/generated/JSCSSRuleList.cpp | 6 +- .../WebCore/generated/JSCSSStyleDeclaration.cpp | 6 +- .../webkit/WebCore/generated/JSCSSStyleRule.cpp | 6 +- .../webkit/WebCore/generated/JSCSSStyleSheet.cpp | 6 +- .../webkit/WebCore/generated/JSCSSValue.cpp | 6 +- .../webkit/WebCore/generated/JSCSSValueList.cpp | 6 +- .../generated/JSCSSVariablesDeclaration.cpp | 6 +- .../WebCore/generated/JSCSSVariablesRule.cpp | 6 +- .../webkit/WebCore/generated/JSCanvasGradient.cpp | 2 +- .../webkit/WebCore/generated/JSCanvasPattern.cpp | 2 +- .../generated/JSCanvasRenderingContext2D.cpp | 6 +- .../webkit/WebCore/generated/JSCharacterData.cpp | 6 +- .../webkit/WebCore/generated/JSClientRect.cpp | 6 +- .../webkit/WebCore/generated/JSClientRectList.cpp | 6 +- .../webkit/WebCore/generated/JSClipboard.cpp | 6 +- .../webkit/WebCore/generated/JSComment.cpp | 6 +- .../webkit/WebCore/generated/JSConsole.cpp | 4 +- .../webkit/WebCore/generated/JSCoordinates.cpp | 4 +- .../webkit/WebCore/generated/JSCounter.cpp | 6 +- .../WebCore/generated/JSDOMApplicationCache.cpp | 4 +- .../WebCore/generated/JSDOMCoreException.cpp | 6 +- .../WebCore/generated/JSDOMImplementation.cpp | 6 +- .../webkit/WebCore/generated/JSDOMParser.cpp | 6 +- .../webkit/WebCore/generated/JSDOMSelection.cpp | 4 +- .../webkit/WebCore/generated/JSDOMWindow.cpp | 71 +- .../webkit/WebCore/generated/JSDOMWindow.h | 7 + .../webkit/WebCore/generated/JSDataGridColumn.cpp | 11 +- .../webkit/WebCore/generated/JSDataGridColumn.h | 4 + .../WebCore/generated/JSDataGridColumnList.cpp | 11 +- .../WebCore/generated/JSDataGridColumnList.h | 4 + .../webkit/WebCore/generated/JSDatabase.cpp | 4 +- .../webkit/WebCore/generated/JSDocument.cpp | 6 +- .../WebCore/generated/JSDocumentFragment.cpp | 6 +- .../webkit/WebCore/generated/JSDocumentType.cpp | 6 +- .../webkit/WebCore/generated/JSElement.cpp | 6 +- src/3rdparty/webkit/WebCore/generated/JSEntity.cpp | 6 +- .../webkit/WebCore/generated/JSEntityReference.cpp | 6 +- src/3rdparty/webkit/WebCore/generated/JSEvent.cpp | 6 +- .../webkit/WebCore/generated/JSEventException.cpp | 6 +- src/3rdparty/webkit/WebCore/generated/JSFile.cpp | 6 +- .../webkit/WebCore/generated/JSFileList.cpp | 6 +- .../webkit/WebCore/generated/JSGeolocation.cpp | 4 +- .../webkit/WebCore/generated/JSGeoposition.cpp | 4 +- .../WebCore/generated/JSHTMLAnchorElement.cpp | 6 +- .../WebCore/generated/JSHTMLAppletElement.cpp | 6 +- .../webkit/WebCore/generated/JSHTMLAreaElement.cpp | 6 +- .../WebCore/generated/JSHTMLAudioElement.cpp | 6 +- .../webkit/WebCore/generated/JSHTMLBRElement.cpp | 6 +- .../webkit/WebCore/generated/JSHTMLBaseElement.cpp | 6 +- .../WebCore/generated/JSHTMLBaseFontElement.cpp | 6 +- .../WebCore/generated/JSHTMLBlockquoteElement.cpp | 6 +- .../webkit/WebCore/generated/JSHTMLBodyElement.cpp | 6 +- .../WebCore/generated/JSHTMLButtonElement.cpp | 18 +- .../webkit/WebCore/generated/JSHTMLButtonElement.h | 1 + .../WebCore/generated/JSHTMLCanvasElement.cpp | 6 +- .../webkit/WebCore/generated/JSHTMLCollection.cpp | 6 +- .../WebCore/generated/JSHTMLDListElement.cpp | 6 +- .../generated/JSHTMLDataGridCellElement.cpp | 11 +- .../WebCore/generated/JSHTMLDataGridCellElement.h | 4 + .../WebCore/generated/JSHTMLDataGridColElement.cpp | 11 +- .../WebCore/generated/JSHTMLDataGridColElement.h | 4 + .../WebCore/generated/JSHTMLDataGridElement.cpp | 11 +- .../WebCore/generated/JSHTMLDataGridElement.h | 4 + .../WebCore/generated/JSHTMLDataGridRowElement.cpp | 11 +- .../WebCore/generated/JSHTMLDataGridRowElement.h | 4 + .../WebCore/generated/JSHTMLDirectoryElement.cpp | 6 +- .../webkit/WebCore/generated/JSHTMLDivElement.cpp | 6 +- .../webkit/WebCore/generated/JSHTMLDocument.cpp | 6 +- .../webkit/WebCore/generated/JSHTMLElement.cpp | 6 +- .../generated/JSHTMLElementWrapperFactory.cpp | 24 + .../WebCore/generated/JSHTMLEmbedElement.cpp | 6 +- .../WebCore/generated/JSHTMLFieldSetElement.cpp | 18 +- .../WebCore/generated/JSHTMLFieldSetElement.h | 1 + .../webkit/WebCore/generated/JSHTMLFontElement.cpp | 6 +- .../webkit/WebCore/generated/JSHTMLFormElement.cpp | 6 +- .../WebCore/generated/JSHTMLFrameElement.cpp | 6 +- .../WebCore/generated/JSHTMLFrameSetElement.cpp | 6 +- .../webkit/WebCore/generated/JSHTMLHRElement.cpp | 6 +- .../webkit/WebCore/generated/JSHTMLHeadElement.cpp | 6 +- .../WebCore/generated/JSHTMLHeadingElement.cpp | 6 +- .../webkit/WebCore/generated/JSHTMLHtmlElement.cpp | 6 +- .../WebCore/generated/JSHTMLIFrameElement.cpp | 6 +- .../WebCore/generated/JSHTMLImageElement.cpp | 6 +- .../WebCore/generated/JSHTMLInputElement.cpp | 18 +- .../webkit/WebCore/generated/JSHTMLInputElement.h | 1 + .../WebCore/generated/JSHTMLIsIndexElement.cpp | 6 +- .../webkit/WebCore/generated/JSHTMLLIElement.cpp | 6 +- .../WebCore/generated/JSHTMLLabelElement.cpp | 6 +- .../WebCore/generated/JSHTMLLegendElement.cpp | 6 +- .../webkit/WebCore/generated/JSHTMLLinkElement.cpp | 6 +- .../webkit/WebCore/generated/JSHTMLMapElement.cpp | 6 +- .../WebCore/generated/JSHTMLMarqueeElement.cpp | 6 +- .../WebCore/generated/JSHTMLMediaElement.cpp | 6 +- .../webkit/WebCore/generated/JSHTMLMenuElement.cpp | 6 +- .../webkit/WebCore/generated/JSHTMLMetaElement.cpp | 6 +- .../webkit/WebCore/generated/JSHTMLModElement.cpp | 6 +- .../WebCore/generated/JSHTMLOListElement.cpp | 6 +- .../WebCore/generated/JSHTMLObjectElement.cpp | 6 +- .../WebCore/generated/JSHTMLOptGroupElement.cpp | 6 +- .../WebCore/generated/JSHTMLOptionElement.cpp | 6 +- .../WebCore/generated/JSHTMLOptionsCollection.cpp | 4 +- .../WebCore/generated/JSHTMLParagraphElement.cpp | 6 +- .../WebCore/generated/JSHTMLParamElement.cpp | 6 +- .../webkit/WebCore/generated/JSHTMLPreElement.cpp | 6 +- .../WebCore/generated/JSHTMLQuoteElement.cpp | 6 +- .../WebCore/generated/JSHTMLScriptElement.cpp | 6 +- .../WebCore/generated/JSHTMLSelectElement.cpp | 20 +- .../webkit/WebCore/generated/JSHTMLSelectElement.h | 1 + .../WebCore/generated/JSHTMLSourceElement.cpp | 6 +- .../WebCore/generated/JSHTMLStyleElement.cpp | 6 +- .../generated/JSHTMLTableCaptionElement.cpp | 6 +- .../WebCore/generated/JSHTMLTableCellElement.cpp | 6 +- .../WebCore/generated/JSHTMLTableColElement.cpp | 6 +- .../WebCore/generated/JSHTMLTableElement.cpp | 6 +- .../WebCore/generated/JSHTMLTableRowElement.cpp | 6 +- .../generated/JSHTMLTableSectionElement.cpp | 6 +- .../WebCore/generated/JSHTMLTextAreaElement.cpp | 20 +- .../WebCore/generated/JSHTMLTextAreaElement.h | 1 + .../WebCore/generated/JSHTMLTitleElement.cpp | 6 +- .../WebCore/generated/JSHTMLUListElement.cpp | 6 +- .../WebCore/generated/JSHTMLVideoElement.cpp | 6 +- .../webkit/WebCore/generated/JSHistory.cpp | 4 +- .../webkit/WebCore/generated/JSImageData.cpp | 6 +- .../WebCore/generated/JSInspectorController.cpp | 6 +- .../WebCore/generated/JSJavaScriptCallFrame.cpp | 4 +- .../webkit/WebCore/generated/JSKeyboardEvent.cpp | 6 +- .../webkit/WebCore/generated/JSLocation.cpp | 4 +- .../webkit/WebCore/generated/JSMediaError.cpp | 6 +- .../webkit/WebCore/generated/JSMediaList.cpp | 6 +- .../webkit/WebCore/generated/JSMessageChannel.cpp | 4 +- .../webkit/WebCore/generated/JSMessageEvent.cpp | 6 +- .../webkit/WebCore/generated/JSMessagePort.cpp | 6 +- .../webkit/WebCore/generated/JSMimeType.cpp | 6 +- .../webkit/WebCore/generated/JSMimeTypeArray.cpp | 6 +- .../webkit/WebCore/generated/JSMouseEvent.cpp | 6 +- .../webkit/WebCore/generated/JSMutationEvent.cpp | 6 +- .../webkit/WebCore/generated/JSNamedNodeMap.cpp | 6 +- .../webkit/WebCore/generated/JSNavigator.cpp | 4 +- src/3rdparty/webkit/WebCore/generated/JSNode.cpp | 6 +- .../webkit/WebCore/generated/JSNodeFilter.cpp | 6 +- .../webkit/WebCore/generated/JSNodeIterator.cpp | 6 +- .../webkit/WebCore/generated/JSNodeList.cpp | 6 +- .../webkit/WebCore/generated/JSNotation.cpp | 6 +- .../webkit/WebCore/generated/JSONObject.lut.h | 2 +- .../webkit/WebCore/generated/JSOverflowEvent.cpp | 6 +- src/3rdparty/webkit/WebCore/generated/JSPlugin.cpp | 6 +- .../webkit/WebCore/generated/JSPluginArray.cpp | 6 +- .../webkit/WebCore/generated/JSPositionError.cpp | 6 +- .../WebCore/generated/JSProcessingInstruction.cpp | 6 +- .../webkit/WebCore/generated/JSProgressEvent.cpp | 6 +- .../webkit/WebCore/generated/JSRGBColor.lut.h | 2 +- src/3rdparty/webkit/WebCore/generated/JSRange.cpp | 6 +- .../webkit/WebCore/generated/JSRangeException.cpp | 6 +- src/3rdparty/webkit/WebCore/generated/JSRect.cpp | 6 +- .../webkit/WebCore/generated/JSSQLError.cpp | 4 +- .../webkit/WebCore/generated/JSSQLResultSet.cpp | 4 +- .../WebCore/generated/JSSQLResultSetRowList.cpp | 4 +- .../webkit/WebCore/generated/JSSQLTransaction.cpp | 2 +- .../webkit/WebCore/generated/JSSVGAElement.cpp | 4 +- .../WebCore/generated/JSSVGAltGlyphElement.cpp | 4 +- .../webkit/WebCore/generated/JSSVGAngle.cpp | 6 +- .../WebCore/generated/JSSVGAnimateColorElement.cpp | 2 +- .../WebCore/generated/JSSVGAnimateElement.cpp | 2 +- .../generated/JSSVGAnimateTransformElement.cpp | 2 +- .../WebCore/generated/JSSVGAnimatedAngle.cpp | 4 +- .../WebCore/generated/JSSVGAnimatedBoolean.cpp | 4 +- .../WebCore/generated/JSSVGAnimatedEnumeration.cpp | 4 +- .../WebCore/generated/JSSVGAnimatedInteger.cpp | 4 +- .../WebCore/generated/JSSVGAnimatedLength.cpp | 4 +- .../WebCore/generated/JSSVGAnimatedLengthList.cpp | 4 +- .../WebCore/generated/JSSVGAnimatedNumber.cpp | 4 +- .../WebCore/generated/JSSVGAnimatedNumberList.cpp | 4 +- .../generated/JSSVGAnimatedPreserveAspectRatio.cpp | 4 +- .../webkit/WebCore/generated/JSSVGAnimatedRect.cpp | 4 +- .../WebCore/generated/JSSVGAnimatedString.cpp | 4 +- .../generated/JSSVGAnimatedTransformList.cpp | 4 +- .../WebCore/generated/JSSVGAnimationElement.cpp | 4 +- .../WebCore/generated/JSSVGCircleElement.cpp | 4 +- .../WebCore/generated/JSSVGClipPathElement.cpp | 4 +- .../webkit/WebCore/generated/JSSVGColor.cpp | 6 +- .../JSSVGComponentTransferFunctionElement.cpp | 6 +- .../WebCore/generated/JSSVGCursorElement.cpp | 4 +- .../generated/JSSVGDefinitionSrcElement.cpp | 2 +- .../webkit/WebCore/generated/JSSVGDefsElement.cpp | 4 +- .../webkit/WebCore/generated/JSSVGDescElement.cpp | 4 +- .../webkit/WebCore/generated/JSSVGDocument.cpp | 4 +- .../webkit/WebCore/generated/JSSVGElement.cpp | 4 +- .../WebCore/generated/JSSVGElementInstance.cpp | 4 +- .../WebCore/generated/JSSVGElementInstanceList.cpp | 4 +- .../WebCore/generated/JSSVGEllipseElement.cpp | 4 +- .../webkit/WebCore/generated/JSSVGException.cpp | 6 +- .../WebCore/generated/JSSVGFEBlendElement.cpp | 6 +- .../generated/JSSVGFEColorMatrixElement.cpp | 6 +- .../generated/JSSVGFEComponentTransferElement.cpp | 4 +- .../WebCore/generated/JSSVGFECompositeElement.cpp | 6 +- .../generated/JSSVGFEDiffuseLightingElement.cpp | 4 +- .../generated/JSSVGFEDisplacementMapElement.cpp | 6 +- .../generated/JSSVGFEDistantLightElement.cpp | 4 +- .../WebCore/generated/JSSVGFEFloodElement.cpp | 6 +- .../WebCore/generated/JSSVGFEFuncAElement.cpp | 2 +- .../WebCore/generated/JSSVGFEFuncBElement.cpp | 2 +- .../WebCore/generated/JSSVGFEFuncGElement.cpp | 2 +- .../WebCore/generated/JSSVGFEFuncRElement.cpp | 2 +- .../generated/JSSVGFEGaussianBlurElement.cpp | 4 +- .../WebCore/generated/JSSVGFEImageElement.cpp | 4 +- .../WebCore/generated/JSSVGFEMergeElement.cpp | 4 +- .../WebCore/generated/JSSVGFEMergeNodeElement.cpp | 4 +- .../WebCore/generated/JSSVGFEOffsetElement.cpp | 4 +- .../WebCore/generated/JSSVGFEPointLightElement.cpp | 4 +- .../generated/JSSVGFESpecularLightingElement.cpp | 4 +- .../WebCore/generated/JSSVGFESpotLightElement.cpp | 4 +- .../WebCore/generated/JSSVGFETileElement.cpp | 4 +- .../WebCore/generated/JSSVGFETurbulenceElement.cpp | 6 +- .../WebCore/generated/JSSVGFilterElement.cpp | 4 +- .../webkit/WebCore/generated/JSSVGFontElement.cpp | 2 +- .../WebCore/generated/JSSVGFontFaceElement.cpp | 2 +- .../generated/JSSVGFontFaceFormatElement.cpp | 2 +- .../WebCore/generated/JSSVGFontFaceNameElement.cpp | 2 +- .../WebCore/generated/JSSVGFontFaceSrcElement.cpp | 2 +- .../WebCore/generated/JSSVGFontFaceUriElement.cpp | 2 +- .../generated/JSSVGForeignObjectElement.cpp | 4 +- .../webkit/WebCore/generated/JSSVGGElement.cpp | 4 +- .../webkit/WebCore/generated/JSSVGGlyphElement.cpp | 2 +- .../WebCore/generated/JSSVGGradientElement.cpp | 6 +- .../webkit/WebCore/generated/JSSVGHKernElement.cpp | 2 +- .../webkit/WebCore/generated/JSSVGImageElement.cpp | 4 +- .../webkit/WebCore/generated/JSSVGLength.cpp | 6 +- .../webkit/WebCore/generated/JSSVGLengthList.cpp | 4 +- .../webkit/WebCore/generated/JSSVGLineElement.cpp | 4 +- .../generated/JSSVGLinearGradientElement.cpp | 4 +- .../WebCore/generated/JSSVGMarkerElement.cpp | 6 +- .../webkit/WebCore/generated/JSSVGMaskElement.cpp | 4 +- .../webkit/WebCore/generated/JSSVGMatrix.cpp | 4 +- .../WebCore/generated/JSSVGMetadataElement.cpp | 2 +- .../WebCore/generated/JSSVGMissingGlyphElement.cpp | 2 +- .../webkit/WebCore/generated/JSSVGNumber.cpp | 4 +- .../webkit/WebCore/generated/JSSVGNumberList.cpp | 4 +- .../webkit/WebCore/generated/JSSVGPaint.cpp | 6 +- .../webkit/WebCore/generated/JSSVGPathElement.cpp | 4 +- .../webkit/WebCore/generated/JSSVGPathSeg.cpp | 6 +- .../WebCore/generated/JSSVGPathSegArcAbs.cpp | 4 +- .../WebCore/generated/JSSVGPathSegArcRel.cpp | 4 +- .../WebCore/generated/JSSVGPathSegClosePath.cpp | 2 +- .../generated/JSSVGPathSegCurvetoCubicAbs.cpp | 4 +- .../generated/JSSVGPathSegCurvetoCubicRel.cpp | 4 +- .../JSSVGPathSegCurvetoCubicSmoothAbs.cpp | 4 +- .../JSSVGPathSegCurvetoCubicSmoothRel.cpp | 4 +- .../generated/JSSVGPathSegCurvetoQuadraticAbs.cpp | 4 +- .../generated/JSSVGPathSegCurvetoQuadraticRel.cpp | 4 +- .../JSSVGPathSegCurvetoQuadraticSmoothAbs.cpp | 4 +- .../JSSVGPathSegCurvetoQuadraticSmoothRel.cpp | 4 +- .../WebCore/generated/JSSVGPathSegLinetoAbs.cpp | 4 +- .../generated/JSSVGPathSegLinetoHorizontalAbs.cpp | 4 +- .../generated/JSSVGPathSegLinetoHorizontalRel.cpp | 4 +- .../WebCore/generated/JSSVGPathSegLinetoRel.cpp | 4 +- .../generated/JSSVGPathSegLinetoVerticalAbs.cpp | 4 +- .../generated/JSSVGPathSegLinetoVerticalRel.cpp | 4 +- .../webkit/WebCore/generated/JSSVGPathSegList.cpp | 4 +- .../WebCore/generated/JSSVGPathSegMovetoAbs.cpp | 4 +- .../WebCore/generated/JSSVGPathSegMovetoRel.cpp | 4 +- .../WebCore/generated/JSSVGPatternElement.cpp | 4 +- .../webkit/WebCore/generated/JSSVGPoint.cpp | 4 +- .../webkit/WebCore/generated/JSSVGPointList.cpp | 4 +- .../WebCore/generated/JSSVGPolygonElement.cpp | 4 +- .../WebCore/generated/JSSVGPolylineElement.cpp | 4 +- .../WebCore/generated/JSSVGPreserveAspectRatio.cpp | 6 +- .../generated/JSSVGRadialGradientElement.cpp | 4 +- .../webkit/WebCore/generated/JSSVGRect.cpp | 4 +- .../webkit/WebCore/generated/JSSVGRectElement.cpp | 4 +- .../WebCore/generated/JSSVGRenderingIntent.cpp | 6 +- .../webkit/WebCore/generated/JSSVGSVGElement.cpp | 4 +- .../WebCore/generated/JSSVGScriptElement.cpp | 4 +- .../webkit/WebCore/generated/JSSVGSetElement.cpp | 2 +- .../webkit/WebCore/generated/JSSVGStopElement.cpp | 4 +- .../webkit/WebCore/generated/JSSVGStringList.cpp | 4 +- .../webkit/WebCore/generated/JSSVGStyleElement.cpp | 4 +- .../WebCore/generated/JSSVGSwitchElement.cpp | 4 +- .../WebCore/generated/JSSVGSymbolElement.cpp | 4 +- .../webkit/WebCore/generated/JSSVGTRefElement.cpp | 4 +- .../webkit/WebCore/generated/JSSVGTSpanElement.cpp | 2 +- .../WebCore/generated/JSSVGTextContentElement.cpp | 6 +- .../webkit/WebCore/generated/JSSVGTextElement.cpp | 4 +- .../WebCore/generated/JSSVGTextPathElement.cpp | 6 +- .../generated/JSSVGTextPositioningElement.cpp | 4 +- .../webkit/WebCore/generated/JSSVGTitleElement.cpp | 4 +- .../webkit/WebCore/generated/JSSVGTransform.cpp | 6 +- .../WebCore/generated/JSSVGTransformList.cpp | 4 +- .../webkit/WebCore/generated/JSSVGUnitTypes.cpp | 6 +- .../webkit/WebCore/generated/JSSVGUseElement.cpp | 4 +- .../webkit/WebCore/generated/JSSVGViewElement.cpp | 4 +- .../webkit/WebCore/generated/JSSVGZoomEvent.cpp | 4 +- src/3rdparty/webkit/WebCore/generated/JSScreen.cpp | 4 +- .../webkit/WebCore/generated/JSStorage.cpp | 6 +- .../webkit/WebCore/generated/JSStorageEvent.cpp | 6 +- .../webkit/WebCore/generated/JSStyleSheet.cpp | 6 +- .../webkit/WebCore/generated/JSStyleSheetList.cpp | 6 +- src/3rdparty/webkit/WebCore/generated/JSText.cpp | 6 +- .../webkit/WebCore/generated/JSTextEvent.cpp | 6 +- .../webkit/WebCore/generated/JSTextMetrics.cpp | 6 +- .../webkit/WebCore/generated/JSTimeRanges.cpp | 4 +- .../webkit/WebCore/generated/JSTreeWalker.cpp | 6 +- .../webkit/WebCore/generated/JSUIEvent.cpp | 6 +- .../webkit/WebCore/generated/JSValidityState.cpp | 172 + .../webkit/WebCore/generated/JSValidityState.h | 79 + .../webkit/WebCore/generated/JSVoidCallback.cpp | 2 +- .../WebCore/generated/JSWebKitAnimationEvent.cpp | 6 +- .../WebCore/generated/JSWebKitCSSKeyframeRule.cpp | 6 +- .../WebCore/generated/JSWebKitCSSKeyframesRule.cpp | 6 +- .../webkit/WebCore/generated/JSWebKitCSSMatrix.cpp | 4 +- .../generated/JSWebKitCSSTransformValue.cpp | 6 +- .../webkit/WebCore/generated/JSWebKitPoint.cpp | 4 +- .../WebCore/generated/JSWebKitTransitionEvent.cpp | 6 +- .../webkit/WebCore/generated/JSWheelEvent.cpp | 6 +- src/3rdparty/webkit/WebCore/generated/JSWorker.cpp | 20 +- .../webkit/WebCore/generated/JSWorkerContext.cpp | 35 +- .../webkit/WebCore/generated/JSWorkerContext.h | 3 + .../webkit/WebCore/generated/JSWorkerLocation.cpp | 6 +- .../webkit/WebCore/generated/JSWorkerNavigator.cpp | 4 +- .../webkit/WebCore/generated/JSXMLHttpRequest.cpp | 4 +- .../generated/JSXMLHttpRequestException.cpp | 6 +- .../generated/JSXMLHttpRequestProgressEvent.cpp | 6 +- .../WebCore/generated/JSXMLHttpRequestUpload.cpp | 6 +- .../webkit/WebCore/generated/JSXMLSerializer.cpp | 6 +- .../webkit/WebCore/generated/JSXPathEvaluator.cpp | 6 +- .../webkit/WebCore/generated/JSXPathException.cpp | 6 +- .../webkit/WebCore/generated/JSXPathExpression.cpp | 6 +- .../webkit/WebCore/generated/JSXPathNSResolver.cpp | 2 +- .../webkit/WebCore/generated/JSXPathResult.cpp | 6 +- src/3rdparty/webkit/WebCore/generated/Lexer.lut.h | 2 +- .../webkit/WebCore/generated/MathObject.lut.h | 2 +- .../WebCore/generated/NumberConstructor.lut.h | 2 +- .../WebCore/generated/RegExpConstructor.lut.h | 2 +- .../webkit/WebCore/generated/RegExpObject.lut.h | 2 +- .../webkit/WebCore/generated/StringPrototype.lut.h | 2 +- .../WebCore/generated/UserAgentStyleSheets.h | 4 +- .../WebCore/generated/UserAgentStyleSheetsData.cpp | 243 +- .../webkit/WebCore/generated/XPathGrammar.cpp | 418 +- .../webkit/WebCore/generated/XPathGrammar.h | 64 +- .../webkit/WebCore/history/HistoryItem.cpp | 24 +- src/3rdparty/webkit/WebCore/history/HistoryItem.h | 9 +- .../WebCore/html/CanvasRenderingContext2D.cpp | 12 +- src/3rdparty/webkit/WebCore/html/CanvasStyle.cpp | 4 +- .../webkit/WebCore/html/DOMDataGridDataSource.cpp | 44 + .../webkit/WebCore/html/DOMDataGridDataSource.h | 69 + .../webkit/WebCore/html/DataGridColumn.cpp | 11 + src/3rdparty/webkit/WebCore/html/DataGridColumn.h | 47 +- .../webkit/WebCore/html/DataGridColumn.idl | 3 +- .../webkit/WebCore/html/DataGridColumnList.cpp | 40 +- .../webkit/WebCore/html/DataGridColumnList.h | 21 +- .../webkit/WebCore/html/DataGridColumnList.idl | 3 +- .../webkit/WebCore/html/DataGridDataSource.h | 7 +- .../webkit/WebCore/html/HTMLAnchorElement.cpp | 4 +- .../webkit/WebCore/html/HTMLAppletElement.h | 3 +- .../webkit/WebCore/html/HTMLAttributeNames.in | 1 + .../webkit/WebCore/html/HTMLAudioElement.h | 3 +- src/3rdparty/webkit/WebCore/html/HTMLBRElement.h | 3 +- .../webkit/WebCore/html/HTMLBaseElement.cpp | 4 +- src/3rdparty/webkit/WebCore/html/HTMLBaseElement.h | 4 +- .../webkit/WebCore/html/HTMLBaseFontElement.h | 3 +- .../webkit/WebCore/html/HTMLButtonElement.idl | 3 + .../webkit/WebCore/html/HTMLDListElement.h | 3 +- .../WebCore/html/HTMLDataGridCellElement.cpp | 5 + .../webkit/WebCore/html/HTMLDataGridCellElement.h | 4 + .../WebCore/html/HTMLDataGridCellElement.idl | 3 +- .../webkit/WebCore/html/HTMLDataGridColElement.cpp | 75 +- .../webkit/WebCore/html/HTMLDataGridColElement.h | 23 +- .../webkit/WebCore/html/HTMLDataGridColElement.idl | 3 +- .../webkit/WebCore/html/HTMLDataGridElement.cpp | 32 +- .../webkit/WebCore/html/HTMLDataGridElement.h | 10 +- .../webkit/WebCore/html/HTMLDataGridElement.idl | 3 +- .../webkit/WebCore/html/HTMLDataGridRowElement.cpp | 5 + .../webkit/WebCore/html/HTMLDataGridRowElement.h | 4 + .../webkit/WebCore/html/HTMLDataGridRowElement.idl | 3 +- .../webkit/WebCore/html/HTMLDirectoryElement.h | 3 +- src/3rdparty/webkit/WebCore/html/HTMLElement.cpp | 9 +- .../webkit/WebCore/html/HTMLFieldSetElement.cpp | 2 +- .../webkit/WebCore/html/HTMLFieldSetElement.idl | 3 + .../webkit/WebCore/html/HTMLFormControlElement.cpp | 27 + .../webkit/WebCore/html/HTMLFormControlElement.h | 6 + .../webkit/WebCore/html/HTMLFormElement.cpp | 10 +- src/3rdparty/webkit/WebCore/html/HTMLFormElement.h | 2 +- src/3rdparty/webkit/WebCore/html/HTMLHRElement.cpp | 2 +- src/3rdparty/webkit/WebCore/html/HTMLHeadElement.h | 3 +- src/3rdparty/webkit/WebCore/html/HTMLHtmlElement.h | 3 +- .../webkit/WebCore/html/HTMLImageElement.h | 2 +- .../webkit/WebCore/html/HTMLInputElement.cpp | 4 +- .../webkit/WebCore/html/HTMLInputElement.idl | 5 +- .../webkit/WebCore/html/HTMLIsIndexElement.h | 3 +- .../webkit/WebCore/html/HTMLLinkElement.cpp | 4 +- .../webkit/WebCore/html/HTMLMarqueeElement.cpp | 2 +- .../webkit/WebCore/html/HTMLMediaElement.cpp | 37 +- .../webkit/WebCore/html/HTMLMediaElement.h | 11 +- src/3rdparty/webkit/WebCore/html/HTMLMenuElement.h | 3 +- src/3rdparty/webkit/WebCore/html/HTMLMetaElement.h | 3 +- src/3rdparty/webkit/WebCore/html/HTMLModElement.h | 3 +- .../webkit/WebCore/html/HTMLOListElement.h | 3 +- .../webkit/WebCore/html/HTMLOptionElement.cpp | 8 +- .../webkit/WebCore/html/HTMLParamElement.h | 3 +- src/3rdparty/webkit/WebCore/html/HTMLParser.cpp | 18 +- src/3rdparty/webkit/WebCore/html/HTMLParser.h | 2 + .../webkit/WebCore/html/HTMLQuoteElement.h | 3 +- .../webkit/WebCore/html/HTMLSelectElement.cpp | 8 +- .../webkit/WebCore/html/HTMLSelectElement.idl | 3 + .../webkit/WebCore/html/HTMLStyleElement.h | 3 +- .../webkit/WebCore/html/HTMLTableCaptionElement.h | 3 +- .../webkit/WebCore/html/HTMLTableCellElement.h | 3 +- .../webkit/WebCore/html/HTMLTableColElement.h | 3 +- .../WebCore/html/HTMLTableSectionElement.cpp | 2 +- src/3rdparty/webkit/WebCore/html/HTMLTagNames.in | 11 +- .../webkit/WebCore/html/HTMLTextAreaElement.idl | 3 + .../webkit/WebCore/html/HTMLTitleElement.h | 3 +- src/3rdparty/webkit/WebCore/html/HTMLTokenizer.cpp | 57 +- src/3rdparty/webkit/WebCore/html/HTMLTokenizer.h | 4 + .../webkit/WebCore/html/HTMLUListElement.h | 3 +- .../webkit/WebCore/html/HTMLVideoElement.cpp | 16 +- .../webkit/WebCore/html/HTMLVideoElement.h | 6 +- src/3rdparty/webkit/WebCore/html/ImageData.idl | 2 +- src/3rdparty/webkit/WebCore/html/TimeRanges.h | 3 +- src/3rdparty/webkit/WebCore/html/ValidityState.cpp | 43 + src/3rdparty/webkit/WebCore/html/ValidityState.h | 59 + src/3rdparty/webkit/WebCore/html/ValidityState.idl | 36 + .../webkit/WebCore/inspector/ConsoleMessage.cpp | 8 +- .../webkit/WebCore/inspector/ConsoleMessage.h | 5 +- .../WebCore/inspector/InspectorController.cpp | 24 +- .../webkit/WebCore/inspector/InspectorController.h | 4 +- .../webkit/WebCore/inspector/InspectorFrontend.cpp | 3 +- .../WebCore/inspector/JavaScriptCallFrame.cpp | 8 + .../webkit/WebCore/inspector/JavaScriptCallFrame.h | 1 + .../WebCore/inspector/JavaScriptDebugServer.cpp | 21 +- .../WebCore/inspector/JavaScriptDebugServer.h | 3 + .../inspector/front-end/CallStackSidebarPane.js | 57 + .../webkit/WebCore/inspector/front-end/Console.js | 94 +- .../inspector/front-end/KeyboardShortcut.js | 108 + .../webkit/WebCore/inspector/front-end/Resource.js | 4 +- .../WebCore/inspector/front-end/ResourcesPanel.js | 2 +- .../WebCore/inspector/front-end/ScriptsPanel.js | 61 +- .../WebCore/inspector/front-end/TextPrompt.js | 5 +- .../webkit/WebCore/inspector/front-end/WebKit.qrc | 2 + .../WebCore/inspector/front-end/inspector.css | 8 +- .../WebCore/inspector/front-end/inspector.html | 1 + .../WebCore/inspector/front-end/inspector.js | 1 + src/3rdparty/webkit/WebCore/loader/DocLoader.cpp | 2 +- src/3rdparty/webkit/WebCore/loader/EmptyClients.h | 9 +- src/3rdparty/webkit/WebCore/loader/FrameLoader.cpp | 77 +- src/3rdparty/webkit/WebCore/loader/FrameLoader.h | 8 +- .../webkit/WebCore/loader/FrameLoaderClient.h | 4 +- .../webkit/WebCore/loader/TextDocument.cpp | 2 + .../webkit/WebCore/loader/icon/IconDatabase.cpp | 4 + .../webkit/WebCore/loader/icon/IconDatabase.h | 4 +- .../WebCore/loader/icon/IconDatabaseNone.cpp | 21 + src/3rdparty/webkit/WebCore/loader/loader.cpp | 43 +- src/3rdparty/webkit/WebCore/loader/loader.h | 9 +- src/3rdparty/webkit/WebCore/page/ChromeClient.h | 5 +- src/3rdparty/webkit/WebCore/page/Console.cpp | 39 +- src/3rdparty/webkit/WebCore/page/Console.h | 19 +- src/3rdparty/webkit/WebCore/page/DOMWindow.cpp | 2 +- src/3rdparty/webkit/WebCore/page/DOMWindow.idl | 9 +- src/3rdparty/webkit/WebCore/page/EventHandler.cpp | 62 +- src/3rdparty/webkit/WebCore/page/EventHandler.h | 4 + .../webkit/WebCore/page/FocusController.cpp | 36 +- src/3rdparty/webkit/WebCore/page/FocusController.h | 4 + src/3rdparty/webkit/WebCore/page/Frame.cpp | 4 +- src/3rdparty/webkit/WebCore/page/FrameView.cpp | 223 +- src/3rdparty/webkit/WebCore/page/FrameView.h | 34 +- .../WebCore/page/MouseEventWithHitTestResults.h | 5 +- src/3rdparty/webkit/WebCore/page/Settings.cpp | 12 + src/3rdparty/webkit/WebCore/page/Settings.h | 8 + src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp | 135 +- src/3rdparty/webkit/WebCore/page/XSSAuditor.h | 24 +- .../WebCore/page/android/DragControllerAndroid.cpp | 2 +- .../WebCore/page/android/EventHandlerAndroid.cpp | 4 +- .../WebCore/page/animation/AnimationBase.cpp | 2 +- .../WebCore/page/animation/AnimationController.cpp | 18 +- .../WebCore/page/animation/CompositeAnimation.cpp | 147 +- .../WebCore/page/animation/CompositeAnimation.h | 2 - .../WebCore/page/animation/ImplicitAnimation.cpp | 4 + .../webkit/WebCore/page/qt/DragControllerQt.cpp | 3 +- .../webkit/WebCore/page/win/DragControllerWin.cpp | 3 +- src/3rdparty/webkit/WebCore/page/win/FrameWin.h | 2 +- .../webkit/WebCore/platform/CrossThreadCopier.h | 9 + src/3rdparty/webkit/WebCore/platform/DragImage.h | 4 +- src/3rdparty/webkit/WebCore/platform/FileSystem.h | 38 +- .../webkit/WebCore/platform/LocalizedStrings.h | 3 + .../webkit/WebCore/platform/ScrollView.cpp | 56 +- src/3rdparty/webkit/WebCore/platform/ScrollView.h | 16 +- src/3rdparty/webkit/WebCore/platform/Scrollbar.cpp | 31 +- src/3rdparty/webkit/WebCore/platform/Scrollbar.h | 15 +- .../webkit/WebCore/platform/ScrollbarClient.h | 26 +- src/3rdparty/webkit/WebCore/platform/Theme.h | 2 +- src/3rdparty/webkit/WebCore/platform/ThemeTypes.h | 7 +- src/3rdparty/webkit/WebCore/platform/Widget.cpp | 106 +- src/3rdparty/webkit/WebCore/platform/Widget.h | 26 +- .../WebCore/platform/graphics/BitmapImage.cpp | 4 +- .../webkit/WebCore/platform/graphics/Color.h | 1 - .../WebCore/platform/graphics/GraphicsLayer.cpp | 1 + .../WebCore/platform/graphics/GraphicsLayer.h | 9 + .../webkit/WebCore/platform/graphics/Image.h | 16 +- .../webkit/WebCore/platform/graphics/IntPoint.h | 1 + .../WebCore/platform/graphics/MediaPlayer.cpp | 20 +- .../webkit/WebCore/platform/graphics/MediaPlayer.h | 4 + .../WebCore/platform/graphics/MediaPlayerPrivate.h | 7 +- .../WebCore/platform/mac/LocalizedStringsMac.mm | 16 + .../webkit/WebCore/platform/mac/ThemeMac.mm | 13 + .../WebCore/platform/mac/WebCoreSystemInterface.h | 7 +- .../WebCore/platform/mac/WebCoreSystemInterface.mm | 7 +- .../webkit/WebCore/platform/mac/WidgetMac.mm | 74 +- .../platform/network/ResourceHandleInternal.h | 4 +- .../platform/network/ResourceResponseBase.cpp | 2 +- .../platform/network/ResourceResponseBase.h | 2 - .../webkit/WebCore/platform/qt/Localizations.cpp | 10 + .../webkit/WebCore/platform/qt/RenderThemeQt.cpp | 2 +- .../webkit/WebCore/platform/sql/SQLiteDatabase.cpp | 5 +- .../WebCore/platform/sql/SQLiteFileSystem.cpp | 123 + .../webkit/WebCore/platform/sql/SQLiteFileSystem.h | 114 + .../platform/text/TextBreakIteratorInternalICU.h | 4 +- .../text/android/TextBreakIteratorInternalICU.cpp | 7 + .../text/mac/TextBreakIteratorInternalICUMac.mm | 96 +- .../text/win/TextBreakIteratorInternalICUWin.cpp | 6 + src/3rdparty/webkit/WebCore/plugins/PluginView.cpp | 22 +- src/3rdparty/webkit/WebCore/plugins/PluginView.h | 2 +- .../plugins/win/PluginMessageThrottlerWin.cpp | 3 + .../WebCore/plugins/win/PluginPackageWin.cpp | 11 +- .../webkit/WebCore/plugins/win/PluginViewWin.cpp | 45 +- .../webkit/WebCore/rendering/AutoTableLayout.cpp | 4 +- .../webkit/WebCore/rendering/InlineBox.cpp | 38 +- src/3rdparty/webkit/WebCore/rendering/InlineBox.h | 39 +- .../webkit/WebCore/rendering/InlineFlowBox.cpp | 53 +- .../webkit/WebCore/rendering/InlineFlowBox.h | 12 +- .../webkit/WebCore/rendering/InlineTextBox.cpp | 4 +- .../WebCore/rendering/MediaControlElements.cpp | 308 +- .../WebCore/rendering/MediaControlElements.h | 97 +- .../webkit/WebCore/rendering/RenderApplet.cpp | 1 + .../webkit/WebCore/rendering/RenderArena.cpp | 2 +- .../webkit/WebCore/rendering/RenderBlock.cpp | 90 +- .../webkit/WebCore/rendering/RenderBlock.h | 21 +- .../WebCore/rendering/RenderBlockLineLayout.cpp | 2264 ++++++++ .../webkit/WebCore/rendering/RenderBox.cpp | 2 +- .../WebCore/rendering/RenderBoxModelObject.cpp | 71 +- .../webkit/WebCore/rendering/RenderDataGrid.cpp | 136 +- .../webkit/WebCore/rendering/RenderDataGrid.h | 22 +- .../webkit/WebCore/rendering/RenderFieldset.cpp | 2 +- .../webkit/WebCore/rendering/RenderFlexibleBox.cpp | 26 +- .../webkit/WebCore/rendering/RenderFrameSet.cpp | 2 +- .../webkit/WebCore/rendering/RenderFrameSet.h | 3 +- .../webkit/WebCore/rendering/RenderImage.cpp | 3 +- .../webkit/WebCore/rendering/RenderInline.cpp | 6 +- .../webkit/WebCore/rendering/RenderInline.h | 5 +- .../webkit/WebCore/rendering/RenderLayer.cpp | 152 +- .../webkit/WebCore/rendering/RenderLayer.h | 28 +- .../WebCore/rendering/RenderLayerBacking.cpp | 19 +- .../webkit/WebCore/rendering/RenderLayerBacking.h | 3 +- .../WebCore/rendering/RenderLayerCompositor.cpp | 180 +- .../WebCore/rendering/RenderLayerCompositor.h | 30 +- .../webkit/WebCore/rendering/RenderListBox.cpp | 70 +- .../webkit/WebCore/rendering/RenderListBox.h | 4 + .../webkit/WebCore/rendering/RenderMarquee.cpp | 3 +- .../webkit/WebCore/rendering/RenderMedia.cpp | 209 +- .../webkit/WebCore/rendering/RenderMedia.h | 25 +- .../webkit/WebCore/rendering/RenderMenuList.cpp | 7 + .../webkit/WebCore/rendering/RenderObject.cpp | 35 +- .../webkit/WebCore/rendering/RenderObject.h | 8 +- .../webkit/WebCore/rendering/RenderPart.cpp | 16 +- src/3rdparty/webkit/WebCore/rendering/RenderPart.h | 4 +- .../webkit/WebCore/rendering/RenderReplaced.cpp | 5 +- .../webkit/WebCore/rendering/RenderSVGImage.cpp | 14 +- .../webkit/WebCore/rendering/RenderSVGInline.cpp | 4 +- .../webkit/WebCore/rendering/RenderSVGInline.h | 2 +- .../WebCore/rendering/RenderSVGInlineText.cpp | 2 +- .../webkit/WebCore/rendering/RenderSVGText.cpp | 4 +- .../webkit/WebCore/rendering/RenderSVGText.h | 2 +- .../webkit/WebCore/rendering/RenderSlider.cpp | 90 +- .../webkit/WebCore/rendering/RenderSlider.h | 3 +- .../webkit/WebCore/rendering/RenderTable.cpp | 3 +- .../webkit/WebCore/rendering/RenderTableCol.h | 3 +- .../webkit/WebCore/rendering/RenderTextControl.cpp | 31 +- .../rendering/RenderTextControlSingleLine.cpp | 4 +- .../webkit/WebCore/rendering/RenderTheme.cpp | 23 +- .../webkit/WebCore/rendering/RenderTheme.h | 10 +- .../WebCore/rendering/RenderThemeChromiumMac.h | 2 +- .../WebCore/rendering/RenderThemeChromiumMac.mm | 30 +- .../WebCore/rendering/RenderThemeChromiumSkia.cpp | 23 +- .../WebCore/rendering/RenderThemeChromiumSkia.h | 2 +- .../WebCore/rendering/RenderThemeChromiumWin.cpp | 10 +- .../webkit/WebCore/rendering/RenderThemeMac.h | 7 +- .../webkit/WebCore/rendering/RenderThemeSafari.cpp | 6 +- .../webkit/WebCore/rendering/RenderThemeSafari.h | 2 +- .../webkit/WebCore/rendering/RenderView.cpp | 4 +- .../webkit/WebCore/rendering/RenderWidget.cpp | 31 +- .../webkit/WebCore/rendering/RenderWidget.h | 7 +- .../webkit/WebCore/rendering/RootInlineBox.cpp | 4 +- .../WebCore/rendering/SVGCharacterLayoutInfo.cpp | 4 +- .../WebCore/rendering/SVGCharacterLayoutInfo.h | 3 +- .../webkit/WebCore/rendering/SVGInlineFlowBox.h | 2 +- .../webkit/WebCore/rendering/SVGInlineTextBox.h | 2 +- .../webkit/WebCore/rendering/SVGRootInlineBox.h | 2 +- .../WebCore/rendering/TextControlInnerElements.cpp | 10 + .../WebCore/rendering/TextControlInnerElements.h | 4 +- src/3rdparty/webkit/WebCore/rendering/bidi.cpp | 2231 -------- src/3rdparty/webkit/WebCore/rendering/bidi.h | 65 - .../webkit/WebCore/rendering/style/RenderStyle.cpp | 7 + .../webkit/WebCore/rendering/style/RenderStyle.h | 9 +- .../WebCore/rendering/style/RenderStyleConstants.h | 5 +- .../WebCore/rendering/style/SVGRenderStyleDefs.h | 4 +- .../WebCore/rendering/style/StyleInheritedData.h | 2 +- src/3rdparty/webkit/WebCore/storage/Database.cpp | 24 +- src/3rdparty/webkit/WebCore/storage/Database.h | 3 + src/3rdparty/webkit/WebCore/storage/DatabaseTask.h | 15 +- .../webkit/WebCore/storage/DatabaseThread.cpp | 27 + .../webkit/WebCore/storage/DatabaseThread.h | 8 + .../webkit/WebCore/storage/DatabaseTracker.cpp | 55 +- .../webkit/WebCore/storage/OriginUsageRecord.cpp | 12 +- .../webkit/WebCore/storage/StorageArea.cpp | 221 +- src/3rdparty/webkit/WebCore/storage/StorageArea.h | 44 +- .../webkit/WebCore/storage/StorageAreaImpl.cpp | 266 + .../webkit/WebCore/storage/StorageAreaImpl.h | 80 + .../webkit/WebCore/storage/StorageAreaSync.h | 3 +- .../webkit/WebCore/storage/StorageNamespace.cpp | 96 +- .../webkit/WebCore/storage/StorageNamespace.h | 26 +- .../WebCore/storage/StorageNamespaceImpl.cpp | 129 + .../webkit/WebCore/storage/StorageNamespaceImpl.h | 66 + .../webkit/WebCore/svg/GradientAttributes.h | 3 +- .../webkit/WebCore/svg/LinearGradientAttributes.h | 3 +- .../webkit/WebCore/svg/PatternAttributes.h | 3 +- .../webkit/WebCore/svg/RadialGradientAttributes.h | 3 +- .../webkit/WebCore/svg/SVGAnimatedPathData.h | 6 +- .../webkit/WebCore/svg/SVGAnimatedPoints.h | 6 +- .../webkit/WebCore/svg/SVGAnimationElement.h | 3 +- .../webkit/WebCore/svg/SVGClipPathElement.h | 3 +- .../webkit/WebCore/svg/SVGDocumentExtensions.cpp | 4 +- .../webkit/WebCore/svg/SVGElementInstance.h | 3 +- .../webkit/WebCore/svg/SVGElementInstance.idl | 2 +- .../webkit/WebCore/svg/SVGFEBlendElement.cpp | 2 +- .../webkit/WebCore/svg/SVGFEBlendElement.h | 6 +- .../webkit/WebCore/svg/SVGFEColorMatrixElement.cpp | 2 +- .../WebCore/svg/SVGFEComponentTransferElement.cpp | 2 +- .../webkit/WebCore/svg/SVGFECompositeElement.cpp | 2 +- .../WebCore/svg/SVGFEDiffuseLightingElement.cpp | 2 +- .../WebCore/svg/SVGFEDisplacementMapElement.cpp | 2 +- .../webkit/WebCore/svg/SVGFEDistantLightElement.h | 6 +- .../webkit/WebCore/svg/SVGFEFloodElement.cpp | 2 +- .../webkit/WebCore/svg/SVGFEFloodElement.h | 6 +- .../webkit/WebCore/svg/SVGFEFuncAElement.h | 6 +- .../webkit/WebCore/svg/SVGFEFuncBElement.h | 6 +- .../webkit/WebCore/svg/SVGFEFuncGElement.h | 6 +- .../webkit/WebCore/svg/SVGFEFuncRElement.h | 6 +- .../WebCore/svg/SVGFEGaussianBlurElement.cpp | 2 +- .../webkit/WebCore/svg/SVGFEImageElement.cpp | 2 +- .../webkit/WebCore/svg/SVGFEMergeElement.cpp | 2 +- .../webkit/WebCore/svg/SVGFEOffsetElement.cpp | 2 +- .../webkit/WebCore/svg/SVGFEPointLightElement.h | 6 +- .../WebCore/svg/SVGFESpecularLightingElement.cpp | 2 +- .../webkit/WebCore/svg/SVGFESpotLightElement.h | 6 +- .../webkit/WebCore/svg/SVGFETileElement.cpp | 2 +- src/3rdparty/webkit/WebCore/svg/SVGLineElement.cpp | 3 +- src/3rdparty/webkit/WebCore/svg/SVGList.h | 3 +- src/3rdparty/webkit/WebCore/svg/SVGListTraits.h | 6 +- src/3rdparty/webkit/WebCore/svg/SVGMPathElement.h | 3 +- .../webkit/WebCore/svg/SVGMetadataElement.h | 6 +- .../webkit/WebCore/svg/SVGParserUtilities.cpp | 4 +- src/3rdparty/webkit/WebCore/svg/SVGPathElement.h | 3 +- src/3rdparty/webkit/WebCore/svg/SVGPathSeg.idl | 2 +- .../webkit/WebCore/svg/SVGPathSegClosePath.h | 6 +- src/3rdparty/webkit/WebCore/svg/SVGSVGElement.h | 6 +- src/3rdparty/webkit/WebCore/svg/SVGSetElement.h | 6 +- src/3rdparty/webkit/WebCore/svg/SVGSwitchElement.h | 6 +- .../webkit/WebCore/svg/SVGTextPathElement.cpp | 2 +- .../webkit/WebCore/svg/SVGTextPathElement.h | 6 +- src/3rdparty/webkit/WebCore/svg/SVGTitleElement.h | 6 +- .../webkit/WebCore/svg/SVGTransformDistance.cpp | 2 + .../webkit/WebCore/svg/SVGTransformList.cpp | 18 - src/3rdparty/webkit/WebCore/svg/SVGTransformList.h | 1 - .../webkit/WebCore/svg/SVGTransformable.cpp | 12 +- src/3rdparty/webkit/WebCore/svg/SVGViewSpec.cpp | 2 +- .../webkit/WebCore/svg/animation/SMILTime.cpp | 9 +- .../webkit/WebCore/svg/animation/SVGSMILElement.h | 3 +- .../webkit/WebCore/svg/graphics/SVGImage.cpp | 4 +- .../webkit/WebCore/svg/graphics/SVGResource.cpp | 3 +- src/3rdparty/webkit/WebCore/wml/WMLCardElement.cpp | 4 +- .../webkit/WebCore/wml/WMLErrorHandling.cpp | 2 +- src/3rdparty/webkit/WebCore/wml/WMLPageState.cpp | 2 +- .../webkit/WebCore/wml/WMLPostfieldElement.cpp | 2 +- .../webkit/WebCore/wml/WMLSelectElement.cpp | 336 +- src/3rdparty/webkit/WebCore/wml/WMLSelectElement.h | 23 +- .../webkit/WebCore/wml/WMLSetvarElement.cpp | 2 +- .../webkit/WebCore/workers/AbstractWorker.cpp | 125 + .../webkit/WebCore/workers/AbstractWorker.h | 86 + .../webkit/WebCore/workers/AbstractWorker.idl | 52 + .../webkit/WebCore/workers/GenericWorkerTask.h | 70 + .../webkit/WebCore/workers/SharedWorker.cpp | 52 + src/3rdparty/webkit/WebCore/workers/SharedWorker.h | 61 + .../webkit/WebCore/workers/SharedWorker.idl | 42 + src/3rdparty/webkit/WebCore/workers/Worker.cpp | 17 +- src/3rdparty/webkit/WebCore/workers/Worker.h | 5 +- src/3rdparty/webkit/WebCore/workers/Worker.idl | 3 +- .../webkit/WebCore/workers/WorkerContext.cpp | 32 +- .../webkit/WebCore/workers/WorkerContext.h | 9 +- .../webkit/WebCore/workers/WorkerContext.idl | 8 +- .../webkit/WebCore/workers/WorkerContextProxy.h | 5 +- .../webkit/WebCore/workers/WorkerLoaderProxy.h | 2 +- .../WebCore/workers/WorkerMessagingProxy.cpp | 52 +- .../webkit/WebCore/workers/WorkerMessagingProxy.h | 8 +- .../webkit/WebCore/workers/WorkerObjectProxy.h | 7 +- .../webkit/WebCore/workers/WorkerRunLoop.cpp | 3 +- src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.cpp | 36 +- src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.h | 1 + src/3rdparty/webkit/WebCore/xml/XPathFunctions.cpp | 8 +- src/3rdparty/webkit/WebCore/xml/XPathPath.h | 3 +- src/3rdparty/webkit/WebCore/xml/XSLTProcessor.cpp | 2 +- src/3rdparty/webkit/WebKit.pri | 6 +- src/3rdparty/webkit/WebKit/ChangeLog | 39 + .../webkit/WebKit/StringsNotToBeLocalized.txt | 9 +- src/3rdparty/webkit/WebKit/qt/Api/headers.pri | 4 +- src/3rdparty/webkit/WebKit/qt/Api/qwebdatabase.cpp | 14 + src/3rdparty/webkit/WebKit/qt/Api/qwebdatabase.h | 1 + src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp | 197 +- src/3rdparty/webkit/WebKit/qt/Api/qwebframe.h | 9 + src/3rdparty/webkit/WebKit/qt/Api/qwebframe_p.h | 10 +- src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp | 71 +- src/3rdparty/webkit/WebKit/qt/Api/qwebpage.h | 4 + src/3rdparty/webkit/WebKit/qt/Api/qwebpage_p.h | 3 - src/3rdparty/webkit/WebKit/qt/ChangeLog | 338 ++ .../WebKit/qt/WebCoreSupport/ChromeClientQt.cpp | 7 +- .../WebKit/qt/WebCoreSupport/ChromeClientQt.h | 2 +- .../qt/WebCoreSupport/FrameLoaderClientQt.cpp | 70 +- .../WebKit/qt/WebCoreSupport/FrameLoaderClientQt.h | 8 +- .../WebKit/qt/tests/qwebframe/tst_qwebframe.cpp | 60 + .../WebKit/qt/tests/qwebpage/frametest/iframe.html | 6 + .../qt/tests/qwebpage/frametest/iframe2.html | 7 + .../qt/tests/qwebpage/frametest/iframe3.html | 5 + .../WebKit/qt/tests/qwebpage/tst_qwebpage.cpp | 50 +- .../WebKit/qt/tests/qwebpage/tst_qwebpage.qrc | 3 + 904 files changed, 25388 insertions(+), 8713 deletions(-) create mode 100644 src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.gypi create mode 100644 src/3rdparty/webkit/WebCore/WebCore.gypi create mode 100644 src/3rdparty/webkit/WebCore/bindings/js/JSAbstractWorkerCustom.cpp create mode 100644 src/3rdparty/webkit/WebCore/bindings/js/JSSharedWorkerConstructor.cpp create mode 100644 src/3rdparty/webkit/WebCore/bindings/js/JSSharedWorkerConstructor.h create mode 100644 src/3rdparty/webkit/WebCore/bindings/js/JSSharedWorkerCustom.cpp create mode 100644 src/3rdparty/webkit/WebCore/css/html.css delete mode 100644 src/3rdparty/webkit/WebCore/css/html4.css create mode 100644 src/3rdparty/webkit/WebCore/dom/HTMLAllCollection.idl create mode 100644 src/3rdparty/webkit/WebCore/generated/JSValidityState.cpp create mode 100644 src/3rdparty/webkit/WebCore/generated/JSValidityState.h create mode 100644 src/3rdparty/webkit/WebCore/html/DOMDataGridDataSource.cpp create mode 100644 src/3rdparty/webkit/WebCore/html/DOMDataGridDataSource.h create mode 100644 src/3rdparty/webkit/WebCore/html/ValidityState.cpp create mode 100644 src/3rdparty/webkit/WebCore/html/ValidityState.h create mode 100644 src/3rdparty/webkit/WebCore/html/ValidityState.idl create mode 100644 src/3rdparty/webkit/WebCore/inspector/front-end/KeyboardShortcut.js create mode 100644 src/3rdparty/webkit/WebCore/platform/sql/SQLiteFileSystem.cpp create mode 100644 src/3rdparty/webkit/WebCore/platform/sql/SQLiteFileSystem.h create mode 100644 src/3rdparty/webkit/WebCore/rendering/RenderBlockLineLayout.cpp delete mode 100644 src/3rdparty/webkit/WebCore/rendering/bidi.cpp delete mode 100644 src/3rdparty/webkit/WebCore/rendering/bidi.h create mode 100644 src/3rdparty/webkit/WebCore/storage/StorageAreaImpl.cpp create mode 100644 src/3rdparty/webkit/WebCore/storage/StorageAreaImpl.h create mode 100644 src/3rdparty/webkit/WebCore/storage/StorageNamespaceImpl.cpp create mode 100644 src/3rdparty/webkit/WebCore/storage/StorageNamespaceImpl.h create mode 100644 src/3rdparty/webkit/WebCore/workers/AbstractWorker.cpp create mode 100644 src/3rdparty/webkit/WebCore/workers/AbstractWorker.h create mode 100644 src/3rdparty/webkit/WebCore/workers/AbstractWorker.idl create mode 100644 src/3rdparty/webkit/WebCore/workers/SharedWorker.cpp create mode 100644 src/3rdparty/webkit/WebCore/workers/SharedWorker.h create mode 100644 src/3rdparty/webkit/WebCore/workers/SharedWorker.idl create mode 100644 src/3rdparty/webkit/WebKit/qt/tests/qwebpage/frametest/iframe.html create mode 100644 src/3rdparty/webkit/WebKit/qt/tests/qwebpage/frametest/iframe2.html create mode 100644 src/3rdparty/webkit/WebKit/qt/tests/qwebpage/frametest/iframe3.html diff --git a/src/3rdparty/webkit/ChangeLog b/src/3rdparty/webkit/ChangeLog index f2cc9a2..fa8e3ff 100644 --- a/src/3rdparty/webkit/ChangeLog +++ b/src/3rdparty/webkit/ChangeLog @@ -1,3 +1,72 @@ +2009-07-13 Laszlo Gombos + + Reviewed by Tor Arne Vestbø. + + [Qt] Build fix for QtWebKit on Win + https://bugs.webkit.org/show_bug.cgi?id=27205 + + * WebKit.pri: Include the major version number in the QtWebKit + library file for Win. + +2009-07-13 Simon Hausmann + + Reviewed by Ariya Hidayat. + + Add the test netscape plugin for the Qt DRT to the build. + + * WebKit.pro: + +2009-07-13 Drew Wilson + + Reviewed by David Levin. + + Add ENABLE(SHARED_WORKERS) flag and define SharedWorker APIs + https://bugs.webkit.org/show_bug.cgi?id=26932 + + Added ENABLE(SHARED_WORKERS) flag. + + * configure.ac: + +2009-07-12 Xan Lopez + + Reviewed by Gustavo Noronha. + + Bump version in preparation for 1.1.11 release. + + * configure.ac: + +2009-07-07 Norbert Leser + + Reviewed by Simon Hausmann. + + Exclude DumpRenderTree.pro from symbian build + + * WebKit.pro: + +2009-07-09 Drew Wilson + + Reviewed by Alexey Proskuryakov. + + https://bugs.webkit.org/show_bug.cgi?id=26903 + + Turned on CHANNEL_MESSAGING by default because the MessageChannel API + can now be implemented for Web Workers and is reasonably stable. + + * configure.ac: enable CHANNEL_MESSAGING. + +2009-07-03 Jan Michael Alonzo + + Reviewed by Xan Lopez and Gustavo Noronha. + + Set user-agent from application + https://bugs.webkit.org/show_bug.cgi?id=17375 + + Define UA version macros to be used by the UA string. + Add new WebSettings unit test for the User-Agent string API. + + * GNUmakefile.am: + * configure.ac: + 2009-06-20 Gustavo Noronha Silva Reviewed by Jan Alonzo. diff --git a/src/3rdparty/webkit/JavaScriptCore/ChangeLog b/src/3rdparty/webkit/JavaScriptCore/ChangeLog index c8bba0f..cd46bf5 100644 --- a/src/3rdparty/webkit/JavaScriptCore/ChangeLog +++ b/src/3rdparty/webkit/JavaScriptCore/ChangeLog @@ -1,3 +1,464 @@ +2009-07-13 Gustavo Noronha Silva + + Unreviewed make dist build fix. + + * GNUmakefile.am: + +2009-07-13 Drew Wilson + + Reviewed by David Levin. + + Add ENABLE(SHARED_WORKERS) flag and define SharedWorker APIs + https://bugs.webkit.org/show_bug.cgi?id=26932 + + Added ENABLE(SHARED_WORKERS) flag (off by default). + + * Configurations/FeatureDefines.xcconfig: + +2009-07-07 Norbert Leser + + Reviewed by Maciej Stachoviak. + + https://bugs.webkit.org/show_bug.cgi?id=27058 + + Removed superfluous parenthesis around single expression. + Compilers on Symbian platform fail to properly parse and compile. + + * JavaScriptCore/wtf/Platform.h: + +2009-07-13 Norbert Leser + + Reviewed by Maciej Stachoviak. + + https://bugs.webkit.org/show_bug.cgi?id=27054 + + Renamed Translator to HashTranslator + + Codewarrior compiler (WINSCW) latest b482 cannot resolve typename + mismatch between template declaration and definition + (HashTranslator / Translator) + + * wtf/HashSet.h: + +2009-07-13 Norbert Leser + + Reviewed by Eric Seidel. + + https://bugs.webkit.org/show_bug.cgi?id=27053 + + Ambiguity in LabelScope initialization + + Codewarrior compiler (WINSCW) latest b482 on Symbian cannot resolve + type of "0" unambiguously. Set expression explicitly to + PassRefPtr