--- /dev/null
+ -1
+ 2411
+ 1 0 0 0
+ 0.0000000000000000E+00 0.0000000000000000E+00 0.0000000000000000E+00
+ 2 0 0 0
+ 0.0000000000000000E+00 -2.3999999999999999E+00 0.0000000000000000E+00
+ 3 0 0 0
+ 0.0000000000000000E+00 -4.0000000000000000E+00 0.0000000000000000E+00
+ 4 0 0 0
+ 0.0000000000000000E+00 -5.5999999999999996E+00 0.0000000000000000E+00
+ 5 0 0 0
+ 0.0000000000000000E+00 -8.0000000000000000E+00 0.0000000000000000E+00
+ 6 0 0 0
+ 0.0000000000000000E+00 -1.0400000000000000E+01 0.0000000000000000E+00
+ 7 0 0 0
+ 0.0000000000000000E+00 -1.2000000000000000E+01 0.0000000000000000E+00
+ 8 0 0 0
+ 0.0000000000000000E+00 -1.4350000000000000E+01 0.0000000000000000E+00
+ 9 0 0 0
+ 0.0000000000000000E+00 -1.5500000000000000E+01 5.0000000000000000E-01
+ 10 0 0 0
+ 0.0000000000000000E+00 -1.6129999999999999E+01 1.7000000000000000E+00
+ 11 0 0 0
+ 0.0000000000000000E+00 -1.6129999999999999E+01 3.3500000000000001E+00
+ 12 0 0 0
+ 0.0000000000000000E+00 -1.6129999999999999E+01 4.9500000000000002E+00
+ 13 0 0 0
+ 0.0000000000000000E+00 -1.6129999999999999E+01 7.1550000000000002E+00
+ 14 0 0 0
+ 0.0000000000000000E+00 -1.6129999999999999E+01 9.3599999999999994E+00
+ 15 0 0 0
+ 0.0000000000000000E+00 -1.6129999999999999E+01 1.2359999999999999E+01
+ 16 0 0 0
+ 0.0000000000000000E+00 -1.6129999999999999E+01 1.5359999999999999E+01
+ 17 0 0 0
+ 0.0000000000000000E+00 -1.6129999999999999E+01 1.7609999999999999E+01
+ 18 0 0 0
+ 0.0000000000000000E+00 -1.6129999999999999E+01 1.8969999999999999E+01
+ 19 0 0 0
+ 0.0000000000000000E+00 -1.6129999999999999E+01 2.0800000000000001E+01
+ 20 0 0 0
+ 0.0000000000000000E+00 -2.3999999999999999E+00 2.1449999999999999E+01
+ 21 0 0 0
+ 0.0000000000000000E+00 -4.0000000000000000E+00 2.1449999999999999E+01
+ 22 0 0 0
+ 0.0000000000000000E+00 -5.5999999999999996E+00 2.1366000000000000E+01
+ 23 0 0 0
+ 0.0000000000000000E+00 -8.0000000000000000E+00 2.1239000000000001E+01
+ 24 0 0 0
+ 0.0000000000000000E+00 -1.0400000000000000E+01 2.1111999999999998E+01
+ 25 0 0 0
+ 0.0000000000000000E+00 -1.2000000000000000E+01 2.1027999999999999E+01
+ 26 0 0 0
+ 0.0000000000000000E+00 -1.4130000000000001E+01 2.0916000000000000E+01
+ 27 0 0 0
+ 0.0000000000000000E+00 0.0000000000000000E+00 2.0000000000000000E+00
+ 28 0 0 0
+ 0.0000000000000000E+00 0.0000000000000000E+00 1.8969999999999999E+01
+ 29 0 0 0
+ 0.0000000000000000E+00 -2.3999999999999999E+00 2.0000000000000000E+00
+ 30 0 0 0
+ 0.0000000000000000E+00 -4.0000000000000000E+00 2.0000000000000000E+00
+ 31 0 0 0
+ 0.0000000000000000E+00 -5.5999999999999996E+00 2.0000000000000000E+00
+ 32 0 0 0
+ 0.0000000000000000E+00 -8.0000000000000000E+00 2.0000000000000000E+00
+ 33 0 0 0
+ 0.0000000000000000E+00 -1.0400000000000000E+01 2.0000000000000000E+00
+ 34 0 0 0
+ 0.0000000000000000E+00 -1.2000000000000000E+01 2.0000000000000000E+00
+ 35 0 0 0
+ 0.0000000000000000E+00 -1.2877000000000001E+01 3.2160000000000002E+00
+ 36 0 0 0
+ 0.0000000000000000E+00 -1.4130000000000001E+01 4.9500000000000002E+00
+ 37 0 0 0
+ 0.0000000000000000E+00 -1.4130000000000001E+01 7.1550000000000002E+00
+ 38 0 0 0
+ 0.0000000000000000E+00 -1.4130000000000001E+01 9.3599999999999994E+00
+ 39 0 0 0
+ 0.0000000000000000E+00 -1.4130000000000001E+01 1.2359999999999999E+01
+ 40 0 0 0
+ 0.0000000000000000E+00 -1.4130000000000001E+01 1.5359999999999999E+01
+ 41 0 0 0
+ 0.0000000000000000E+00 -1.4130000000000001E+01 1.7609999999999999E+01
+ 42 0 0 0
+ 0.0000000000000000E+00 -1.4130000000000001E+01 1.8969999999999999E+01
+ 43 0 0 0
+ 0.0000000000000000E+00 -1.3600000000000000E+01 2.0000000000000000E+00
+ 44 0 0 0
+ 0.0000000000000000E+00 -1.5199999999999999E+01 3.8500000000000001E+00
+ 45 0 0 0
+ 0.0000000000000000E+00 -1.4500000000000000E+01 3.8500000000000001E+00
+ 46 0 0 0
+ 0.0000000000000000E+00 -1.4150000000000000E+01 3.1040000000000001E+00
+ 47 0 0 0
+ 0.0000000000000000E+00 -1.5199999999999999E+01 2.0000000000000000E+00
+ 48 0 0 0
+ 0.0000000000000000E+00 0.0000000000000000E+00 3.6600000000000001E+00
+ 49 0 0 0
+ 0.0000000000000000E+00 0.0000000000000000E+00 4.9500000000000002E+00
+ 50 0 0 0
+ 0.0000000000000000E+00 -2.3999999999999999E+00 3.0000000000000000E+00
+ 51 0 0 0
+ 0.0000000000000000E+00 -4.0000000000000000E+00 2.7999999999999998E+00
+ 52 0 0 0
+ 0.0000000000000000E+00 0.0000000000000000E+00 1.7609999999999999E+01
+ 53 0 0 0
+ 0.0000000000000000E+00 2.3999999999999999E+00 0.0000000000000000E+00
+ 54 0 0 0
+ 0.0000000000000000E+00 4.0000000000000000E+00 0.0000000000000000E+00
+ 55 0 0 0
+ 0.0000000000000000E+00 5.5999999999999996E+00 0.0000000000000000E+00
+ 56 0 0 0
+ 0.0000000000000000E+00 8.0000000000000000E+00 0.0000000000000000E+00
+ 57 0 0 0
+ 0.0000000000000000E+00 1.0400000000000000E+01 0.0000000000000000E+00
+ 58 0 0 0
+ 0.0000000000000000E+00 1.2000000000000000E+01 0.0000000000000000E+00
+ 59 0 0 0
+ 0.0000000000000000E+00 1.4350000000000000E+01 0.0000000000000000E+00
+ 60 0 0 0
+ 0.0000000000000000E+00 1.5500000000000000E+01 5.0000000000000000E-01
+ 61 0 0 0
+ 0.0000000000000000E+00 1.6129999999999999E+01 1.7000000000000000E+00
+ 62 0 0 0
+ 0.0000000000000000E+00 1.6129999999999999E+01 3.3500000000000001E+00
+ 63 0 0 0
+ 0.0000000000000000E+00 1.6129999999999999E+01 4.9500000000000002E+00
+ 64 0 0 0
+ 0.0000000000000000E+00 1.6129999999999999E+01 7.1550000000000002E+00
+ 65 0 0 0
+ 0.0000000000000000E+00 1.6129999999999999E+01 9.3599999999999994E+00
+ 66 0 0 0
+ 0.0000000000000000E+00 1.6129999999999999E+01 1.2359999999999999E+01
+ 67 0 0 0
+ 0.0000000000000000E+00 1.6129999999999999E+01 1.5359999999999999E+01
+ 68 0 0 0
+ 0.0000000000000000E+00 1.6129999999999999E+01 1.7609999999999999E+01
+ 69 0 0 0
+ 0.0000000000000000E+00 1.6129999999999999E+01 1.8969999999999999E+01
+ 70 0 0 0
+ 0.0000000000000000E+00 1.6129999999999999E+01 2.0800000000000001E+01
+ 71 0 0 0
+ 0.0000000000000000E+00 0.0000000000000000E+00 2.1449999999999999E+01
+ 72 0 0 0
+ 0.0000000000000000E+00 2.3999999999999999E+00 2.1449999999999999E+01
+ 73 0 0 0
+ 0.0000000000000000E+00 4.0000000000000000E+00 2.1449999999999999E+01
+ 74 0 0 0
+ 0.0000000000000000E+00 5.5999999999999996E+00 2.1366000000000000E+01
+ 75 0 0 0
+ 0.0000000000000000E+00 8.0000000000000000E+00 2.1239000000000001E+01
+ 76 0 0 0
+ 0.0000000000000000E+00 1.0400000000000000E+01 2.1111999999999998E+01
+ 77 0 0 0
+ 0.0000000000000000E+00 1.2000000000000000E+01 2.1027999999999999E+01
+ 78 0 0 0
+ 0.0000000000000000E+00 1.4130000000000001E+01 2.0916000000000000E+01
+ 79 0 0 0
+ 0.0000000000000000E+00 2.3999999999999999E+00 2.0000000000000000E+00
+ 80 0 0 0
+ 0.0000000000000000E+00 4.0000000000000000E+00 2.0000000000000000E+00
+ 81 0 0 0
+ 0.0000000000000000E+00 5.5999999999999996E+00 2.0000000000000000E+00
+ 82 0 0 0
+ 0.0000000000000000E+00 8.0000000000000000E+00 2.0000000000000000E+00
+ 83 0 0 0
+ 0.0000000000000000E+00 1.0400000000000000E+01 2.0000000000000000E+00
+ 84 0 0 0
+ 0.0000000000000000E+00 1.2000000000000000E+01 2.0000000000000000E+00
+ 85 0 0 0
+ 0.0000000000000000E+00 1.2877000000000001E+01 3.2160000000000002E+00
+ 86 0 0 0
+ 0.0000000000000000E+00 1.4130000000000001E+01 4.9500000000000002E+00
+ 87 0 0 0
+ 0.0000000000000000E+00 1.4130000000000001E+01 7.1550000000000002E+00
+ 88 0 0 0
+ 0.0000000000000000E+00 1.4130000000000001E+01 9.3599999999999994E+00
+ 89 0 0 0
+ 0.0000000000000000E+00 1.4130000000000001E+01 1.2359999999999999E+01
+ 90 0 0 0
+ 0.0000000000000000E+00 1.4130000000000001E+01 1.5359999999999999E+01
+ 91 0 0 0
+ 0.0000000000000000E+00 1.4130000000000001E+01 1.7609999999999999E+01
+ 92 0 0 0
+ 0.0000000000000000E+00 1.4130000000000001E+01 1.8969999999999999E+01
+ 93 0 0 0
+ 0.0000000000000000E+00 1.3600000000000000E+01 2.0000000000000000E+00
+ 94 0 0 0
+ 0.0000000000000000E+00 1.5199999999999999E+01 3.8500000000000001E+00
+ 95 0 0 0
+ 0.0000000000000000E+00 1.4500000000000000E+01 3.8500000000000001E+00
+ 96 0 0 0
+ 0.0000000000000000E+00 1.4150000000000000E+01 3.1040000000000001E+00
+ 97 0 0 0
+ 0.0000000000000000E+00 1.5199999999999999E+01 2.0000000000000000E+00
+ 98 0 0 0
+ 0.0000000000000000E+00 2.3999999999999999E+00 3.6600000000000001E+00
+ 99 0 0 0
+ 0.0000000000000000E+00 2.3999999999999999E+00 4.9500000000000002E+00
+ 100 0 0 0
+ 0.0000000000000000E+00 4.0000000000000000E+00 3.0000000000000000E+00
+ 101 0 0 0
+ 0.0000000000000000E+00 0.0000000000000000E+00 7.1550000000000002E+00
+ 102 0 0 0
+ 0.0000000000000000E+00 0.0000000000000000E+00 9.3599999999999994E+00
+ 103 0 0 0
+ 0.0000000000000000E+00 0.0000000000000000E+00 1.2359999999999999E+01
+ 104 0 0 0
+ 0.0000000000000000E+00 0.0000000000000000E+00 1.5359999999999999E+01
+ 105 0 0 0
+ 0.0000000000000000E+00 2.3999999999999999E+00 7.1550000000000002E+00
+ 106 0 0 0
+ 0.0000000000000000E+00 2.3999999999999999E+00 9.3599999999999994E+00
+ 107 0 0 0
+ 0.0000000000000000E+00 2.3999999999999999E+00 1.2359999999999999E+01
+ 108 0 0 0
+ 0.0000000000000000E+00 2.3999999999999999E+00 1.5359999999999999E+01
+ 109 0 0 0
+ 0.0000000000000000E+00 2.3999999999999999E+00 1.7609999999999999E+01
+ 110 0 0 0
+ 0.0000000000000000E+00 -1.2000000000000000E+01 3.2149999999999999E+00
+ 111 0 0 0
+ 0.0000000000000000E+00 -5.5999999999999996E+00 3.2149999999999999E+00
+ 112 0 0 0
+ 0.0000000000000000E+00 -8.0000000000000000E+00 3.2149999999999999E+00
+ 113 0 0 0
+ 0.0000000000000000E+00 -1.0400000000000000E+01 3.2149999999999999E+00
+ 114 0 0 0
+ 0.0000000000000000E+00 1.2000000000000000E+01 3.2149999999999999E+00
+ 115 0 0 0
+ 0.0000000000000000E+00 5.5999999999999996E+00 3.2149999999999999E+00
+ 116 0 0 0
+ 0.0000000000000000E+00 8.0000000000000000E+00 3.2149999999999999E+00
+ 117 0 0 0
+ 0.0000000000000000E+00 1.0400000000000000E+01 3.2149999999999999E+00
+ 118 0 0 0
+ 0.0000000000000000E+00 2.3999999999999999E+00 1.8969999999999999E+01
+ 119 0 0 0
+ 0.0000000000000000E+00 -1.2877000000000001E+01 4.9500000000000002E+00
+ 120 0 0 0
+ 0.0000000000000000E+00 -2.3999999999999999E+00 4.9500000000000002E+00
+ 121 0 0 0
+ 0.0000000000000000E+00 1.2877000000000001E+01 4.9500000000000002E+00
+ 122 0 0 0
+ 0.0000000000000000E+00 4.0000000000000000E+00 4.9500000000000002E+00
+ 123 0 0 0
+ 0.0000000000000000E+00 -1.2000000000000000E+01 4.9500000000000002E+00
+ 124 0 0 0
+ 0.0000000000000000E+00 -2.3999999999999999E+00 7.1550000000000002E+00
+ 125 0 0 0
+ 0.0000000000000000E+00 -1.2000000000000000E+01 1.7609999999999999E+01
+ 126 0 0 0
+ 0.0000000000000000E+00 -2.3999999999999999E+00 1.7609999999999999E+01
+ 127 0 0 0
+ 0.0000000000000000E+00 4.0000000000000000E+00 7.1550000000000002E+00
+ 128 0 0 0
+ 0.0000000000000000E+00 1.2000000000000000E+01 1.7609999999999999E+01
+ 129 0 0 0
+ 0.0000000000000000E+00 1.2000000000000000E+01 4.9500000000000002E+00
+ 130 0 0 0
+ 0.0000000000000000E+00 4.0000000000000000E+00 1.7609999999999999E+01
+ 131 0 0 0
+ 0.0000000000000000E+00 -1.2000000000000000E+01 7.1550000000000002E+00
+ 132 0 0 0
+ 0.0000000000000000E+00 1.2000000000000000E+01 7.1550000000000002E+00
+ 133 0 0 0
+ 0.0000000000000000E+00 -4.0000000000000000E+00 4.9500000000000002E+00
+ 134 0 0 0
+ 0.0000000000000000E+00 5.5999999999999996E+00 4.9500000000000002E+00
+ 135 0 0 0
+ 0.0000000000000000E+00 -1.0400000000000000E+01 4.9500000000000002E+00
+ 136 0 0 0
+ 0.0000000000000000E+00 -2.3999999999999999E+00 9.3599999999999994E+00
+ 137 0 0 0
+ 0.0000000000000000E+00 -2.3999999999999999E+00 1.2359999999999999E+01
+ 138 0 0 0
+ 0.0000000000000000E+00 -2.3999999999999999E+00 1.5359999999999999E+01
+ 139 0 0 0
+ 0.0000000000000000E+00 1.0400000000000000E+01 4.9500000000000002E+00
+ 140 0 0 0
+ 0.0000000000000000E+00 8.0000000000000000E+00 4.9500000000000002E+00
+ 141 0 0 0
+ 0.0000000000000000E+00 -1.2000000000000000E+01 1.5359999999999999E+01
+ 142 0 0 0
+ 0.0000000000000000E+00 -1.2000000000000000E+01 1.2359999999999999E+01
+ 143 0 0 0
+ 0.0000000000000000E+00 -1.2000000000000000E+01 9.3599999999999994E+00
+ 144 0 0 0
+ 0.0000000000000000E+00 4.0000000000000000E+00 9.3599999999999994E+00
+ 145 0 0 0
+ 0.0000000000000000E+00 4.0000000000000000E+00 1.2359999999999999E+01
+ 146 0 0 0
+ 0.0000000000000000E+00 4.0000000000000000E+00 1.5359999999999999E+01
+ 147 0 0 0
+ 0.0000000000000000E+00 1.2000000000000000E+01 1.5359999999999999E+01
+ 148 0 0 0
+ 0.0000000000000000E+00 1.2000000000000000E+01 1.2359999999999999E+01
+ 149 0 0 0
+ 0.0000000000000000E+00 1.2000000000000000E+01 9.3599999999999994E+00
+ 150 0 0 0
+ 0.0000000000000000E+00 -8.0000000000000000E+00 4.9500000000000002E+00
+ 151 0 0 0
+ 0.0000000000000000E+00 -5.5999999999999996E+00 4.9500000000000002E+00
+ 152 0 0 0
+ 0.0000000000000000E+00 4.0000000000000000E+00 1.8969999999999999E+01
+ 153 0 0 0
+ 0.0000000000000000E+00 5.5999999999999996E+00 1.8969999999999999E+01
+ 154 0 0 0
+ 0.0000000000000000E+00 8.0000000000000000E+00 1.8969999999999999E+01
+ 155 0 0 0
+ 0.0000000000000000E+00 1.0400000000000000E+01 1.8969999999999999E+01
+ 156 0 0 0
+ 0.0000000000000000E+00 1.2000000000000000E+01 1.8969999999999999E+01
+ 157 0 0 0
+ 0.0000000000000000E+00 -2.3999999999999999E+00 1.8969999999999999E+01
+ 158 0 0 0
+ 0.0000000000000000E+00 -4.0000000000000000E+00 1.8969999999999999E+01
+ 159 0 0 0
+ 0.0000000000000000E+00 -5.5999999999999996E+00 1.8969999999999999E+01
+ 160 0 0 0
+ 0.0000000000000000E+00 -8.0000000000000000E+00 1.8969999999999999E+01
+ 161 0 0 0
+ 0.0000000000000000E+00 -1.0400000000000000E+01 1.8969999999999999E+01
+ 162 0 0 0
+ 0.0000000000000000E+00 -1.2000000000000000E+01 1.8969999999999999E+01
+ 163 0 0 0
+ 3.3999999999999999E+00 -4.0000000000000000E+00 0.0000000000000000E+00
+ 164 0 0 0
+ 3.3999999999999999E+00 -2.3999999999999999E+00 0.0000000000000000E+00
+ 165 0 0 0
+ 3.3999999999999999E+00 4.0000000000000000E+00 0.0000000000000000E+00
+ 166 0 0 0
+ 3.3999999999999999E+00 2.3999999999999999E+00 0.0000000000000000E+00
+ 167 0 0 0
+ 3.3999999999999999E+00 0.0000000000000000E+00 0.0000000000000000E+00
+ 168 0 0 0
+ 3.3999999999999999E+00 0.0000000000000000E+00 3.6600000000000001E+00
+ 169 0 0 0
+ 3.3999999999999999E+00 -5.5999999999999996E+00 0.0000000000000000E+00
+ 170 0 0 0
+ 3.3999999999999999E+00 -8.0000000000000000E+00 0.0000000000000000E+00
+ 171 0 0 0
+ 3.3999999999999999E+00 -1.0400000000000000E+01 0.0000000000000000E+00
+ 172 0 0 0
+ 3.3999999999999999E+00 -4.0000000000000000E+00 2.0000000000000000E+00
+ 173 0 0 0
+ 3.3999999999999999E+00 -2.3999999999999999E+00 2.0000000000000000E+00
+ 174 0 0 0
+ 3.3999999999999999E+00 0.0000000000000000E+00 2.0000000000000000E+00
+ 175 0 0 0
+ 3.3999999999999999E+00 2.3999999999999999E+00 2.0000000000000000E+00
+ 176 0 0 0
+ 3.3999999999999999E+00 4.0000000000000000E+00 2.0000000000000000E+00
+ 177 0 0 0
+ 3.3999999999999999E+00 5.5999999999999996E+00 0.0000000000000000E+00
+ 178 0 0 0
+ 3.3999999999999999E+00 8.0000000000000000E+00 0.0000000000000000E+00
+ 179 0 0 0
+ 3.3999999999999999E+00 1.0400000000000000E+01 0.0000000000000000E+00
+ 180 0 0 0
+ 3.3999999999999999E+00 -2.3999999999999999E+00 3.0000000000000000E+00
+ 181 0 0 0
+ 0.0000000000000000E+00 -4.0000000000000000E+00 7.1550000000000002E+00
+ 182 0 0 0
+ 3.3999999999999999E+00 0.0000000000000000E+00 7.1550000000000002E+00
+ 183 0 0 0
+ 3.3999999999999999E+00 -8.0000000000000000E+00 2.0000000000000000E+00
+ 184 0 0 0
+ 3.3999999999999999E+00 -1.0400000000000000E+01 2.0000000000000000E+00
+ 185 0 0 0
+ 3.3999999999999999E+00 2.3999999999999999E+00 3.6600000000000001E+00
+ 186 0 0 0
+ 3.3999999999999999E+00 -1.2000000000000000E+01 0.0000000000000000E+00
+ 187 0 0 0
+ 3.3999999999999999E+00 -1.2000000000000000E+01 2.0000000000000000E+00
+ 188 0 0 0
+ 3.3999999999999999E+00 -1.4350000000000000E+01 0.0000000000000000E+00
+ 189 0 0 0
+ 0.0000000000000000E+00 -1.0400000000000000E+01 1.7609999999999999E+01
+ 190 0 0 0
+ 3.3999999999999999E+00 -1.2877000000000001E+01 3.2160000000000002E+00
+ 191 0 0 0
+ 3.3999999999999999E+00 -1.5500000000000000E+01 5.0000000000000000E-01
+ 192 0 0 0
+ 0.0000000000000000E+00 -4.0000000000000000E+00 1.7609999999999999E+01
+ 193 0 0 0
+ 3.3999999999999999E+00 2.3999999999999999E+00 1.9800000000000001E+01
+ 194 0 0 0
+ 3.3999999999999999E+00 -1.6129999999999999E+01 1.7000000000000000E+00
+ 195 0 0 0
+ 3.3999999999999999E+00 -1.6129999999999999E+01 3.3500000000000001E+00
+ 196 0 0 0
+ 3.3999999999999999E+00 8.0000000000000000E+00 2.0000000000000000E+00
+ 197 0 0 0
+ 0.0000000000000000E+00 5.5999999999999996E+00 7.1550000000000002E+00
+ 198 0 0 0
+ 0.0000000000000000E+00 8.0000000000000000E+00 7.1550000000000002E+00
+ 199 0 0 0
+ 0.0000000000000000E+00 1.0400000000000000E+01 7.1550000000000002E+00
+ 200 0 0 0
+ 3.3999999999999999E+00 1.2000000000000000E+01 0.0000000000000000E+00
+ 201 0 0 0
+ 3.3999999999999999E+00 1.0400000000000000E+01 2.0000000000000000E+00
+ 202 0 0 0
+ 0.0000000000000000E+00 1.0400000000000000E+01 1.7609999999999999E+01
+ 203 0 0 0
+ 0.0000000000000000E+00 8.0000000000000000E+00 1.7609999999999999E+01
+ 204 0 0 0
+ 0.0000000000000000E+00 5.5999999999999996E+00 1.7609999999999999E+01
+ 205 0 0 0
+ 3.3999999999999999E+00 1.4350000000000000E+01 0.0000000000000000E+00
+ 206 0 0 0
+ 3.3999999999999999E+00 -1.6129999999999999E+01 4.9500000000000002E+00
+ 207 0 0 0
+ 3.3999999999999999E+00 1.2000000000000000E+01 2.0000000000000000E+00
+ 208 0 0 0
+ 3.3999999999999999E+00 1.5500000000000000E+01 5.0000000000000000E-01
+ 209 0 0 0
+ 3.3999999999999999E+00 -1.6129999999999999E+01 7.1550000000000002E+00
+ 210 0 0 0
+ 3.3999999999999999E+00 0.0000000000000000E+00 1.2359999999999999E+01
+ 211 0 0 0
+ 0.0000000000000000E+00 -1.0400000000000000E+01 7.1550000000000002E+00
+ 212 0 0 0
+ 3.3999999999999999E+00 1.2877000000000001E+01 3.2160000000000002E+00
+ 213 0 0 0
+ 3.3999999999999999E+00 1.6129999999999999E+01 1.7000000000000000E+00
+ 214 0 0 0
+ 3.3999999999999999E+00 1.6129999999999999E+01 3.3500000000000001E+00
+ 215 0 0 0
+ 3.3999999999999999E+00 -1.4130000000000001E+01 7.1550000000000002E+00
+ 216 0 0 0
+ 3.3999999999999999E+00 -1.4130000000000001E+01 4.9500000000000002E+00
+ 217 0 0 0
+ 3.3999999999999999E+00 -1.6129999999999999E+01 9.3599999999999994E+00
+ 218 0 0 0
+ 3.3999999999999999E+00 -1.6129999999999999E+01 1.2359999999999999E+01
+ 219 0 0 0
+ 3.3999999999999999E+00 1.6129999999999999E+01 4.9500000000000002E+00
+ 220 0 0 0
+ 3.3999999999999999E+00 1.6129999999999999E+01 7.1550000000000002E+00
+ 221 0 0 0
+ 3.3999999999999999E+00 1.4130000000000001E+01 7.1550000000000002E+00
+ 222 0 0 0
+ 3.3999999999999999E+00 1.4130000000000001E+01 4.9500000000000002E+00
+ 223 0 0 0
+ 3.3999999999999999E+00 -1.4130000000000001E+01 1.2359999999999999E+01
+ 224 0 0 0
+ 3.3999999999999999E+00 -1.4130000000000001E+01 9.3599999999999994E+00
+ 225 0 0 0
+ 3.3999999999999999E+00 -1.6129999999999999E+01 1.5359999999999999E+01
+ 226 0 0 0
+ 3.3999999999999999E+00 -1.6129999999999999E+01 1.7609999999999999E+01
+ 227 0 0 0
+ 3.3999999999999999E+00 -1.6129999999999999E+01 1.8969999999999999E+01
+ 228 0 0 0
+ 3.3999999999999999E+00 -1.6129999999999999E+01 2.0800000000000001E+01
+ 229 0 0 0
+ 3.3999999999999999E+00 1.6129999999999999E+01 9.3599999999999994E+00
+ 230 0 0 0
+ 3.3999999999999999E+00 1.6129999999999999E+01 1.2359999999999999E+01
+ 231 0 0 0
+ 3.3999999999999999E+00 1.4130000000000001E+01 1.2359999999999999E+01
+ 232 0 0 0
+ 3.3999999999999999E+00 1.4130000000000001E+01 9.3599999999999994E+00
+ 233 0 0 0
+ 3.3999999999999999E+00 -1.4130000000000001E+01 1.5359999999999999E+01
+ 234 0 0 0
+ 3.3999999999999999E+00 1.6129999999999999E+01 1.5359999999999999E+01
+ 235 0 0 0
+ 3.3999999999999999E+00 1.6129999999999999E+01 1.7609999999999999E+01
+ 236 0 0 0
+ 3.3999999999999999E+00 1.6129999999999999E+01 1.8969999999999999E+01
+ 237 0 0 0
+ 3.3999999999999999E+00 1.6129999999999999E+01 2.0800000000000001E+01
+ 238 0 0 0
+ 3.3999999999999999E+00 -1.4130000000000001E+01 2.0916000000000000E+01
+ 239 0 0 0
+ 3.3999999999999999E+00 -1.4130000000000001E+01 1.8969999999999999E+01
+ 240 0 0 0
+ 3.3999999999999999E+00 -1.2000000000000000E+01 2.1027999999999999E+01
+ 241 0 0 0
+ 3.3999999999999999E+00 -1.0400000000000000E+01 2.1111999999999998E+01
+ 242 0 0 0
+ 3.3999999999999999E+00 -8.0000000000000000E+00 2.1239000000000001E+01
+ 243 0 0 0
+ 3.3999999999999999E+00 -5.5999999999999996E+00 2.1366000000000000E+01
+ 244 0 0 0
+ 3.3999999999999999E+00 -4.0000000000000000E+00 2.1449999999999999E+01
+ 245 0 0 0
+ 3.3999999999999999E+00 -2.3999999999999999E+00 2.1449999999999999E+01
+ 246 0 0 0
+ 3.3999999999999999E+00 0.0000000000000000E+00 2.1449999999999999E+01
+ 247 0 0 0
+ 3.3999999999999999E+00 2.3999999999999999E+00 2.1449999999999999E+01
+ 248 0 0 0
+ 0.0000000000000000E+00 -8.0000000000000000E+00 1.7609999999999999E+01
+ 249 0 0 0
+ 0.0000000000000000E+00 -5.5999999999999996E+00 1.7609999999999999E+01
+ 250 0 0 0
+ 3.3999999999999999E+00 4.0000000000000000E+00 2.1449999999999999E+01
+ 251 0 0 0
+ 3.3999999999999999E+00 5.5999999999999996E+00 2.1366000000000000E+01
+ 252 0 0 0
+ 3.3999999999999999E+00 8.0000000000000000E+00 2.1239000000000001E+01
+ 253 0 0 0
+ 3.3999999999999999E+00 1.0400000000000000E+01 2.1111999999999998E+01
+ 254 0 0 0
+ 3.3999999999999999E+00 1.2000000000000000E+01 2.1027999999999999E+01
+ 255 0 0 0
+ 3.3999999999999999E+00 1.4130000000000001E+01 2.0916000000000000E+01
+ 256 0 0 0
+ 3.3999999999999999E+00 1.4130000000000001E+01 1.8969999999999999E+01
+ 257 0 0 0
+ 0.0000000000000000E+00 -5.5999999999999996E+00 7.1550000000000002E+00
+ 258 0 0 0
+ 0.0000000000000000E+00 -8.0000000000000000E+00 7.1550000000000002E+00
+ 259 0 0 0
+ 3.3999999999999999E+00 1.4130000000000001E+01 1.5359999999999999E+01
+ 260 0 0 0
+ 2.2000000000000002E+00 2.3999999999999999E+00 4.9500000000000002E+00
+ 261 0 0 0
+ 3.3999999999999999E+00 0.0000000000000000E+00 9.3599999999999994E+00
+ 262 0 0 0
+ 2.2000000000000002E+00 2.3999999999999999E+00 9.3599999999999994E+00
+ 263 0 0 0
+ 3.3999999999999999E+00 0.0000000000000000E+00 1.5359999999999999E+01
+ 264 0 0 0
+ 2.2000000000000002E+00 2.3999999999999999E+00 1.5359999999999999E+01
+ 265 0 0 0
+ 3.3999999999999999E+00 0.0000000000000000E+00 1.7609999999999999E+01
+ 266 0 0 0
+ 3.3999999999999999E+00 -1.4130000000000001E+01 1.7609999999999999E+01
+ 267 0 0 0
+ 3.3999999999999999E+00 1.4130000000000001E+01 1.7609999999999999E+01
+ 268 0 0 0
+ 2.2000000000000002E+00 -1.2877000000000001E+01 4.9500000000000002E+00
+ 269 0 0 0
+ 2.2000000000000002E+00 -2.3999999999999999E+00 4.9500000000000002E+00
+ 270 0 0 0
+ 2.2000000000000002E+00 1.2877000000000001E+01 4.9500000000000002E+00
+ 271 0 0 0
+ 2.2000000000000002E+00 4.0000000000000000E+00 4.9500000000000002E+00
+ 272 0 0 0
+ 0.0000000000000000E+00 -4.0000000000000000E+00 9.3599999999999994E+00
+ 273 0 0 0
+ 0.0000000000000000E+00 -4.0000000000000000E+00 1.2359999999999999E+01
+ 274 0 0 0
+ 0.0000000000000000E+00 -4.0000000000000000E+00 1.5359999999999999E+01
+ 275 0 0 0
+ 0.0000000000000000E+00 -1.0400000000000000E+01 1.5359999999999999E+01
+ 276 0 0 0
+ 0.0000000000000000E+00 -1.0400000000000000E+01 1.2359999999999999E+01
+ 277 0 0 0
+ 3.3999999999999999E+00 -5.5999999999999996E+00 2.0000000000000000E+00
+ 278 0 0 0
+ 3.3999999999999999E+00 0.0000000000000000E+00 4.9500000000000002E+00
+ 279 0 0 0
+ 0.0000000000000000E+00 -1.0400000000000000E+01 9.3599999999999994E+00
+ 280 0 0 0
+ 0.0000000000000000E+00 5.5999999999999996E+00 9.3599999999999994E+00
+ 281 0 0 0
+ 0.0000000000000000E+00 5.5999999999999996E+00 1.2359999999999999E+01
+ 282 0 0 0
+ 0.0000000000000000E+00 5.5999999999999996E+00 1.5359999999999999E+01
+ 283 0 0 0
+ 0.0000000000000000E+00 1.0400000000000000E+01 1.2359999999999999E+01
+ 284 0 0 0
+ 0.0000000000000000E+00 8.0000000000000000E+00 1.2359999999999999E+01
+ 285 0 0 0
+ 0.0000000000000000E+00 1.0400000000000000E+01 1.5359999999999999E+01
+ 286 0 0 0
+ 0.0000000000000000E+00 8.0000000000000000E+00 1.5359999999999999E+01
+ 287 0 0 0
+ 0.0000000000000000E+00 1.0400000000000000E+01 9.3599999999999994E+00
+ 288 0 0 0
+ 0.0000000000000000E+00 8.0000000000000000E+00 9.3599999999999994E+00
+ 289 0 0 0
+ 3.3999999999999999E+00 5.5999999999999996E+00 2.0000000000000000E+00
+ 290 0 0 0
+ 2.2000000000000002E+00 -2.3999999999999999E+00 9.3599999999999994E+00
+ 291 0 0 0
+ 2.2000000000000002E+00 -2.3999999999999999E+00 1.5359999999999999E+01
+ 292 0 0 0
+ 2.2000000000000002E+00 -1.2000000000000000E+01 4.9500000000000002E+00
+ 293 0 0 0
+ 2.2000000000000002E+00 -1.2000000000000000E+01 1.5359999999999999E+01
+ 294 0 0 0
+ 3.3999999999999999E+00 -2.3999999999999999E+00 1.9800000000000001E+01
+ 295 0 0 0
+ 2.2000000000000002E+00 -1.2000000000000000E+01 9.3599999999999994E+00
+ 296 0 0 0
+ 2.2000000000000002E+00 4.0000000000000000E+00 9.3599999999999994E+00
+ 297 0 0 0
+ 3.3999999999999999E+00 -1.2000000000000000E+01 1.9527999999999999E+01
+ 298 0 0 0
+ 2.2000000000000002E+00 4.0000000000000000E+00 1.5359999999999999E+01
+ 299 0 0 0
+ 2.2000000000000002E+00 1.2000000000000000E+01 1.5359999999999999E+01
+ 300 0 0 0
+ 2.2000000000000002E+00 1.2000000000000000E+01 4.9500000000000002E+00
+ 301 0 0 0
+ 2.2000000000000002E+00 1.2000000000000000E+01 9.3599999999999994E+00
+ 302 0 0 0
+ 3.3999999999999999E+00 -1.3600000000000000E+01 2.0000000000000000E+00
+ 303 0 0 0
+ 3.3999999999999999E+00 1.2000000000000000E+01 1.9527999999999999E+01
+ 304 0 0 0
+ 3.3999999999999999E+00 -4.0000000000000000E+00 2.7999999999999998E+00
+ 305 0 0 0
+ 3.3999999999999999E+00 -2.3999999999999999E+00 3.6600000000000001E+00
+ 306 0 0 0
+ 2.2000000000000002E+00 -4.0000000000000000E+00 4.9500000000000002E+00
+ 307 0 0 0
+ 3.3999999999999999E+00 1.3600000000000000E+01 2.0000000000000000E+00
+ 308 0 0 0
+ 2.2000000000000002E+00 5.5999999999999996E+00 4.9500000000000002E+00
+ 309 0 0 0
+ 2.2000000000000002E+00 1.0400000000000000E+01 4.9500000000000002E+00
+ 310 0 0 0
+ 2.2000000000000002E+00 8.0000000000000000E+00 4.9500000000000002E+00
+ 311 0 0 0
+ 2.2000000000000002E+00 -1.0400000000000000E+01 4.9500000000000002E+00
+ 312 0 0 0
+ 3.3999999999999999E+00 4.0000000000000000E+00 3.0000000000000000E+00
+ 313 0 0 0
+ 2.2000000000000002E+00 -8.0000000000000000E+00 4.9500000000000002E+00
+ 314 0 0 0
+ 2.2000000000000002E+00 -5.5999999999999996E+00 4.9500000000000002E+00
+ 315 0 0 0
+ 3.3999999999999999E+00 -1.5199999999999999E+01 2.0000000000000000E+00
+ 316 0 0 0
+ 3.3999999999999999E+00 -1.4150000000000000E+01 3.1040000000000001E+00
+ 317 0 0 0
+ 3.3999999999999999E+00 -4.0000000000000000E+00 1.9949999999999999E+01
+ 318 0 0 0
+ 3.3999999999999999E+00 -1.0400000000000000E+01 1.9611999999999998E+01
+ 319 0 0 0
+ 3.3999999999999999E+00 2.3999999999999999E+00 4.9500000000000002E+00
+ 320 0 0 0
+ 3.3999999999999999E+00 2.3999999999999999E+00 1.7609999999999999E+01
+ 321 0 0 0
+ 3.3999999999999999E+00 4.0000000000000000E+00 1.9949999999999999E+01
+ 322 0 0 0
+ 3.3999999999999999E+00 1.5199999999999999E+01 2.0000000000000000E+00
+ 323 0 0 0
+ 3.3999999999999999E+00 1.4150000000000000E+01 3.1040000000000001E+00
+ 324 0 0 0
+ 3.3999999999999999E+00 1.0400000000000000E+01 1.9611999999999998E+01
+ 325 0 0 0
+ 3.3999999999999999E+00 -1.5199999999999999E+01 3.8500000000000001E+00
+ 326 0 0 0
+ 3.3999999999999999E+00 -1.4500000000000000E+01 3.8500000000000001E+00
+ 327 0 0 0
+ 3.3999999999999999E+00 -8.0000000000000000E+00 1.9739000000000001E+01
+ 328 0 0 0
+ 3.3999999999999999E+00 -5.5999999999999996E+00 1.9866000000000000E+01
+ 329 0 0 0
+ 3.3999999999999999E+00 8.0000000000000000E+00 1.9739000000000001E+01
+ 330 0 0 0
+ 3.3999999999999999E+00 5.5999999999999996E+00 1.9866000000000000E+01
+ 331 0 0 0
+ 3.3999999999999999E+00 1.5199999999999999E+01 3.8500000000000001E+00
+ 332 0 0 0
+ 3.3999999999999999E+00 1.4500000000000000E+01 3.8500000000000001E+00
+ 333 0 0 0
+ 0.0000000000000000E+00 -8.0000000000000000E+00 1.5359999999999999E+01
+ 334 0 0 0
+ 0.0000000000000000E+00 -5.5999999999999996E+00 1.5359999999999999E+01
+ 335 0 0 0
+ 0.0000000000000000E+00 -8.0000000000000000E+00 1.2359999999999999E+01
+ 336 0 0 0
+ 0.0000000000000000E+00 -5.5999999999999996E+00 1.2359999999999999E+01
+ 337 0 0 0
+ 0.0000000000000000E+00 -8.0000000000000000E+00 9.3599999999999994E+00
+ 338 0 0 0
+ 0.0000000000000000E+00 -5.5999999999999996E+00 9.3599999999999994E+00
+ 339 0 0 0
+ 3.3999999999999999E+00 0.0000000000000000E+00 1.8969999999999999E+01
+ 340 0 0 0
+ 3.3999999999999999E+00 2.3999999999999999E+00 7.1550000000000002E+00
+ 341 0 0 0
+ 3.3999999999999999E+00 2.3999999999999999E+00 1.5359999999999999E+01
+ 342 0 0 0
+ 3.3999999999999999E+00 2.3999999999999999E+00 9.3599999999999994E+00
+ 343 0 0 0
+ 3.3999999999999999E+00 2.3999999999999999E+00 1.2359999999999999E+01
+ 344 0 0 0
+ 6.7999999999999998E+00 -2.3999999999999999E+00 0.0000000000000000E+00
+ 345 0 0 0
+ 6.7999999999999998E+00 -4.0000000000000000E+00 0.0000000000000000E+00
+ 346 0 0 0
+ 6.7999999999999998E+00 0.0000000000000000E+00 0.0000000000000000E+00
+ 347 0 0 0
+ 6.7999999999999998E+00 2.3999999999999999E+00 0.0000000000000000E+00
+ 348 0 0 0
+ 6.7999999999999998E+00 4.0000000000000000E+00 0.0000000000000000E+00
+ 349 0 0 0
+ 6.7999999999999998E+00 0.0000000000000000E+00 2.0000000000000000E+00
+ 350 0 0 0
+ 6.7999999999999998E+00 -2.3999999999999999E+00 2.0000000000000000E+00
+ 351 0 0 0
+ 6.7999999999999998E+00 0.0000000000000000E+00 3.6600000000000001E+00
+ 352 0 0 0
+ 6.7999999999999998E+00 2.3999999999999999E+00 2.0000000000000000E+00
+ 353 0 0 0
+ 6.7999999999999998E+00 -5.5999999999999996E+00 0.0000000000000000E+00
+ 354 0 0 0
+ 6.7999999999999998E+00 -4.0000000000000000E+00 2.0000000000000000E+00
+ 355 0 0 0
+ 6.7999999999999998E+00 -8.0000000000000000E+00 0.0000000000000000E+00
+ 356 0 0 0
+ 6.7999999999999998E+00 -1.0400000000000000E+01 0.0000000000000000E+00
+ 357 0 0 0
+ 6.7999999999999998E+00 5.5999999999999996E+00 0.0000000000000000E+00
+ 358 0 0 0
+ 6.7999999999999998E+00 4.0000000000000000E+00 2.0000000000000000E+00
+ 359 0 0 0
+ 6.7999999999999998E+00 8.0000000000000000E+00 0.0000000000000000E+00
+ 360 0 0 0
+ 6.7999999999999998E+00 1.0400000000000000E+01 0.0000000000000000E+00
+ 361 0 0 0
+ 6.7999999999999998E+00 -1.2000000000000000E+01 0.0000000000000000E+00
+ 362 0 0 0
+ 6.7999999999999998E+00 -8.0000000000000000E+00 2.0000000000000000E+00
+ 363 0 0 0
+ 6.7999999999999998E+00 -1.0400000000000000E+01 2.0000000000000000E+00
+ 364 0 0 0
+ 6.7999999999999998E+00 0.0000000000000000E+00 7.1550000000000002E+00
+ 365 0 0 0
+ 6.7999999999999998E+00 -1.2000000000000000E+01 2.0000000000000000E+00
+ 366 0 0 0
+ 6.7999999999999998E+00 -1.4350000000000000E+01 0.0000000000000000E+00
+ 367 0 0 0
+ 6.7999999999999998E+00 -1.2877000000000001E+01 3.2160000000000002E+00
+ 368 0 0 0
+ 6.7999999999999998E+00 -1.5500000000000000E+01 5.0000000000000000E-01
+ 369 0 0 0
+ 6.7999999999999998E+00 1.2000000000000000E+01 0.0000000000000000E+00
+ 370 0 0 0
+ 6.7999999999999998E+00 -1.6129999999999999E+01 1.7000000000000000E+00
+ 371 0 0 0
+ 6.7999999999999998E+00 8.0000000000000000E+00 2.0000000000000000E+00
+ 372 0 0 0
+ 2.2000000000000002E+00 -4.0000000000000000E+00 9.3599999999999994E+00
+ 373 0 0 0
+ 6.7999999999999998E+00 1.0400000000000000E+01 2.0000000000000000E+00
+ 374 0 0 0
+ 6.7999999999999998E+00 0.0000000000000000E+00 9.3599999999999994E+00
+ 375 0 0 0
+ 2.2000000000000002E+00 -4.0000000000000000E+00 1.5359999999999999E+01
+ 376 0 0 0
+ 6.7999999999999998E+00 -1.4130000000000001E+01 4.9500000000000002E+00
+ 377 0 0 0
+ 6.7999999999999998E+00 1.4350000000000000E+01 0.0000000000000000E+00
+ 378 0 0 0
+ 6.7999999999999998E+00 -1.6129999999999999E+01 3.3500000000000001E+00
+ 379 0 0 0
+ 6.7999999999999998E+00 1.2000000000000000E+01 2.0000000000000000E+00
+ 380 0 0 0
+ 6.7999999999999998E+00 -1.6129999999999999E+01 4.9500000000000002E+00
+ 381 0 0 0
+ 2.2000000000000002E+00 -1.0400000000000000E+01 1.5359999999999999E+01
+ 382 0 0 0
+ 6.7999999999999998E+00 1.5500000000000000E+01 5.0000000000000000E-01
+ 383 0 0 0
+ 2.2000000000000002E+00 -1.0400000000000000E+01 9.3599999999999994E+00
+ 384 0 0 0
+ 6.7999999999999998E+00 -1.6129999999999999E+01 7.1550000000000002E+00
+ 385 0 0 0
+ 2.2000000000000002E+00 5.5999999999999996E+00 9.3599999999999994E+00
+ 386 0 0 0
+ 2.2000000000000002E+00 1.0400000000000000E+01 9.3599999999999994E+00
+ 387 0 0 0
+ 2.2000000000000002E+00 8.0000000000000000E+00 9.3599999999999994E+00
+ 388 0 0 0
+ 6.7999999999999998E+00 1.2877000000000001E+01 3.2160000000000002E+00
+ 389 0 0 0
+ 2.2000000000000002E+00 5.5999999999999996E+00 1.5359999999999999E+01
+ 390 0 0 0
+ 2.2000000000000002E+00 1.0400000000000000E+01 1.5359999999999999E+01
+ 391 0 0 0
+ 2.2000000000000002E+00 8.0000000000000000E+00 1.5359999999999999E+01
+ 392 0 0 0
+ 6.7999999999999998E+00 1.6129999999999999E+01 1.7000000000000000E+00
+ 393 0 0 0
+ 6.7999999999999998E+00 -1.4130000000000001E+01 7.1550000000000002E+00
+ 394 0 0 0
+ 6.7999999999999998E+00 0.0000000000000000E+00 1.2359999999999999E+01
+ 395 0 0 0
+ 6.7999999999999998E+00 -1.6129999999999999E+01 9.3599999999999994E+00
+ 396 0 0 0
+ 6.7999999999999998E+00 1.6129999999999999E+01 3.3500000000000001E+00
+ 397 0 0 0
+ 6.7999999999999998E+00 1.4130000000000001E+01 4.9500000000000002E+00
+ 398 0 0 0
+ 6.7999999999999998E+00 -1.6129999999999999E+01 1.2359999999999999E+01
+ 399 0 0 0
+ 6.7999999999999998E+00 -1.4130000000000001E+01 9.3599999999999994E+00
+ 400 0 0 0
+ 6.7999999999999998E+00 1.6129999999999999E+01 4.9500000000000002E+00
+ 401 0 0 0
+ 6.7999999999999998E+00 0.0000000000000000E+00 1.5359999999999999E+01
+ 402 0 0 0
+ 6.7999999999999998E+00 1.6129999999999999E+01 7.1550000000000002E+00
+ 403 0 0 0
+ 6.7999999999999998E+00 1.4130000000000001E+01 7.1550000000000002E+00
+ 404 0 0 0
+ 6.7999999999999998E+00 -1.4130000000000001E+01 1.2359999999999999E+01
+ 405 0 0 0
+ 6.7999999999999998E+00 -1.6129999999999999E+01 1.5359999999999999E+01
+ 406 0 0 0
+ 6.7999999999999998E+00 1.6129999999999999E+01 9.3599999999999994E+00
+ 407 0 0 0
+ 6.7999999999999998E+00 1.4130000000000001E+01 9.3599999999999994E+00
+ 408 0 0 0
+ 6.7999999999999998E+00 -1.6129999999999999E+01 1.7609999999999999E+01
+ 409 0 0 0
+ 6.7999999999999998E+00 -1.4130000000000001E+01 1.5359999999999999E+01
+ 410 0 0 0
+ 6.7999999999999998E+00 -1.6129999999999999E+01 1.8969999999999999E+01
+ 411 0 0 0
+ 6.7999999999999998E+00 -1.6129999999999999E+01 2.0800000000000001E+01
+ 412 0 0 0
+ 6.7999999999999998E+00 1.6129999999999999E+01 1.2359999999999999E+01
+ 413 0 0 0
+ 6.7999999999999998E+00 1.4130000000000001E+01 1.2359999999999999E+01
+ 414 0 0 0
+ 6.7999999999999998E+00 1.6129999999999999E+01 1.5359999999999999E+01
+ 415 0 0 0
+ 6.7999999999999998E+00 1.6129999999999999E+01 1.7609999999999999E+01
+ 416 0 0 0
+ 6.7999999999999998E+00 1.6129999999999999E+01 1.8969999999999999E+01
+ 417 0 0 0
+ 6.7999999999999998E+00 -1.4130000000000001E+01 2.0916000000000000E+01
+ 418 0 0 0
+ 6.7999999999999998E+00 -1.4130000000000001E+01 1.8969999999999999E+01
+ 419 0 0 0
+ 6.7999999999999998E+00 1.6129999999999999E+01 2.0800000000000001E+01
+ 420 0 0 0
+ 6.7999999999999998E+00 1.4130000000000001E+01 1.5359999999999999E+01
+ 421 0 0 0
+ 6.7999999999999998E+00 -1.2000000000000000E+01 2.1027999999999999E+01
+ 422 0 0 0
+ 6.7999999999999998E+00 -1.0400000000000000E+01 2.1111999999999998E+01
+ 423 0 0 0
+ 6.7999999999999998E+00 -8.0000000000000000E+00 2.1239000000000001E+01
+ 424 0 0 0
+ 6.7999999999999998E+00 -5.5999999999999996E+00 2.1366000000000000E+01
+ 425 0 0 0
+ 6.7999999999999998E+00 -4.0000000000000000E+00 2.1449999999999999E+01
+ 426 0 0 0
+ 6.7999999999999998E+00 -2.3999999999999999E+00 2.1449999999999999E+01
+ 427 0 0 0
+ 6.7999999999999998E+00 0.0000000000000000E+00 2.1449999999999999E+01
+ 428 0 0 0
+ 6.7999999999999998E+00 2.3999999999999999E+00 2.1449999999999999E+01
+ 429 0 0 0
+ 6.7999999999999998E+00 1.4130000000000001E+01 2.0916000000000000E+01
+ 430 0 0 0
+ 6.7999999999999998E+00 1.4130000000000001E+01 1.8969999999999999E+01
+ 431 0 0 0
+ 6.7999999999999998E+00 4.0000000000000000E+00 2.1449999999999999E+01
+ 432 0 0 0
+ 6.7999999999999998E+00 1.2000000000000000E+01 2.1027999999999999E+01
+ 433 0 0 0
+ 6.7999999999999998E+00 1.0400000000000000E+01 2.1111999999999998E+01
+ 434 0 0 0
+ 6.7999999999999998E+00 5.5999999999999996E+00 2.1366000000000000E+01
+ 435 0 0 0
+ 6.7999999999999998E+00 8.0000000000000000E+00 2.1239000000000001E+01
+ 436 0 0 0
+ 6.7999999999999998E+00 0.0000000000000000E+00 4.9500000000000002E+00
+ 437 0 0 0
+ 6.7999999999999998E+00 -5.5999999999999996E+00 2.0000000000000000E+00
+ 438 0 0 0
+ 6.7999999999999998E+00 -2.3999999999999999E+00 3.0000000000000000E+00
+ 439 0 0 0
+ 6.7999999999999998E+00 5.5999999999999996E+00 2.0000000000000000E+00
+ 440 0 0 0
+ 6.7999999999999998E+00 2.3999999999999999E+00 3.6600000000000001E+00
+ 441 0 0 0
+ 2.2000000000000002E+00 -8.0000000000000000E+00 1.5359999999999999E+01
+ 442 0 0 0
+ 2.2000000000000002E+00 -5.5999999999999996E+00 1.5359999999999999E+01
+ 443 0 0 0
+ 2.2000000000000002E+00 -8.0000000000000000E+00 9.3599999999999994E+00
+ 444 0 0 0
+ 2.2000000000000002E+00 -5.5999999999999996E+00 9.3599999999999994E+00
+ 445 0 0 0
+ 6.7999999999999998E+00 0.0000000000000000E+00 1.7609999999999999E+01
+ 446 0 0 0
+ 6.7999999999999998E+00 -1.4130000000000001E+01 1.7609999999999999E+01
+ 447 0 0 0
+ 6.7999999999999998E+00 1.4130000000000001E+01 1.7609999999999999E+01
+ 448 0 0 0
+ 6.7999999999999998E+00 0.0000000000000000E+00 1.8969999999999999E+01
+ 449 0 0 0
+ 6.7999999999999998E+00 -4.0000000000000000E+00 2.7999999999999998E+00
+ 450 0 0 0
+ 6.7999999999999998E+00 -2.3999999999999999E+00 3.6600000000000001E+00
+ 451 0 0 0
+ 6.7999999999999998E+00 4.0000000000000000E+00 3.0000000000000000E+00
+ 452 0 0 0
+ 6.7999999999999998E+00 -1.3600000000000000E+01 2.0000000000000000E+00
+ 453 0 0 0
+ 1.0199999999999999E+01 -2.3999999999999999E+00 0.0000000000000000E+00
+ 454 0 0 0
+ 1.0199999999999999E+01 -4.0000000000000000E+00 0.0000000000000000E+00
+ 455 0 0 0
+ 1.0199999999999999E+01 0.0000000000000000E+00 0.0000000000000000E+00
+ 456 0 0 0
+ 1.0199999999999999E+01 2.3999999999999999E+00 0.0000000000000000E+00
+ 457 0 0 0
+ 1.0199999999999999E+01 4.0000000000000000E+00 0.0000000000000000E+00
+ 458 0 0 0
+ 6.7999999999999998E+00 2.3999999999999999E+00 4.9500000000000002E+00
+ 459 0 0 0
+ 1.0199999999999999E+01 -2.3999999999999999E+00 2.0000000000000000E+00
+ 460 0 0 0
+ 1.0199999999999999E+01 0.0000000000000000E+00 2.0000000000000000E+00
+ 461 0 0 0
+ 1.0199999999999999E+01 2.3999999999999999E+00 2.0000000000000000E+00
+ 462 0 0 0
+ 1.0199999999999999E+01 0.0000000000000000E+00 3.6600000000000001E+00
+ 463 0 0 0
+ 1.0199999999999999E+01 -5.5999999999999996E+00 0.0000000000000000E+00
+ 464 0 0 0
+ 6.7999999999999998E+00 2.3999999999999999E+00 1.9800000000000001E+01
+ 465 0 0 0
+ 1.0199999999999999E+01 -4.0000000000000000E+00 2.0000000000000000E+00
+ 466 0 0 0
+ 1.0199999999999999E+01 -8.0000000000000000E+00 0.0000000000000000E+00
+ 467 0 0 0
+ 1.0199999999999999E+01 5.5999999999999996E+00 0.0000000000000000E+00
+ 468 0 0 0
+ 6.7999999999999998E+00 1.3600000000000000E+01 2.0000000000000000E+00
+ 469 0 0 0
+ 1.0199999999999999E+01 -1.0400000000000000E+01 0.0000000000000000E+00
+ 470 0 0 0
+ 1.0199999999999999E+01 4.0000000000000000E+00 2.0000000000000000E+00
+ 471 0 0 0
+ 1.0199999999999999E+01 8.0000000000000000E+00 0.0000000000000000E+00
+ 472 0 0 0
+ 1.0199999999999999E+01 1.0400000000000000E+01 0.0000000000000000E+00
+ 473 0 0 0
+ 1.0199999999999999E+01 -1.2000000000000000E+01 0.0000000000000000E+00
+ 474 0 0 0
+ 6.7999999999999998E+00 2.3999999999999999E+00 7.1550000000000002E+00
+ 475 0 0 0
+ 1.0199999999999999E+01 -8.0000000000000000E+00 2.0000000000000000E+00
+ 476 0 0 0
+ 1.0199999999999999E+01 -1.0400000000000000E+01 2.0000000000000000E+00
+ 477 0 0 0
+ 6.7999999999999998E+00 -1.4150000000000000E+01 3.1040000000000001E+00
+ 478 0 0 0
+ 1.0199999999999999E+01 -1.2000000000000000E+01 2.0000000000000000E+00
+ 479 0 0 0
+ 1.0199999999999999E+01 -1.4350000000000000E+01 0.0000000000000000E+00
+ 480 0 0 0
+ 1.0199999999999999E+01 0.0000000000000000E+00 7.1550000000000002E+00
+ 481 0 0 0
+ 6.7999999999999998E+00 -1.5199999999999999E+01 2.0000000000000000E+00
+ 482 0 0 0
+ 6.7999999999999998E+00 -1.5199999999999999E+01 3.8500000000000001E+00
+ 483 0 0 0
+ 6.7999999999999998E+00 -1.4500000000000000E+01 3.8500000000000001E+00
+ 484 0 0 0
+ 1.0199999999999999E+01 1.2000000000000000E+01 0.0000000000000000E+00
+ 485 0 0 0
+ 1.0199999999999999E+01 -1.2877000000000001E+01 3.2160000000000002E+00
+ 486 0 0 0
+ 1.0199999999999999E+01 8.0000000000000000E+00 2.0000000000000000E+00
+ 487 0 0 0
+ 1.0199999999999999E+01 -1.5500000000000000E+01 5.0000000000000000E-01
+ 488 0 0 0
+ 1.0199999999999999E+01 1.0400000000000000E+01 2.0000000000000000E+00
+ 489 0 0 0
+ 6.7999999999999998E+00 2.3999999999999999E+00 9.3599999999999994E+00
+ 490 0 0 0
+ 1.0199999999999999E+01 -1.6129999999999999E+01 1.7000000000000000E+00
+ 491 0 0 0
+ 1.0199999999999999E+01 1.4350000000000000E+01 0.0000000000000000E+00
+ 492 0 0 0
+ 1.0199999999999999E+01 0.0000000000000000E+00 9.3599999999999994E+00
+ 493 0 0 0
+ 1.0199999999999999E+01 1.2000000000000000E+01 2.0000000000000000E+00
+ 494 0 0 0
+ 6.7999999999999998E+00 1.5199999999999999E+01 2.0000000000000000E+00
+ 495 0 0 0
+ 1.0199999999999999E+01 -1.4130000000000001E+01 4.9500000000000002E+00
+ 496 0 0 0
+ 6.7999999999999998E+00 1.4150000000000000E+01 3.1040000000000001E+00
+ 497 0 0 0
+ 1.0199999999999999E+01 -1.6129999999999999E+01 3.3500000000000001E+00
+ 498 0 0 0
+ 1.0199999999999999E+01 1.5500000000000000E+01 5.0000000000000000E-01
+ 499 0 0 0
+ 1.0199999999999999E+01 -1.6129999999999999E+01 4.9500000000000002E+00
+ 500 0 0 0
+ 6.7999999999999998E+00 1.5199999999999999E+01 3.8500000000000001E+00
+ 501 0 0 0
+ 6.7999999999999998E+00 1.4500000000000000E+01 3.8500000000000001E+00
+ 502 0 0 0
+ 6.7999999999999998E+00 -1.2000000000000000E+01 1.9527999999999999E+01
+ 503 0 0 0
+ 1.0199999999999999E+01 1.2877000000000001E+01 3.2160000000000002E+00
+ 504 0 0 0
+ 1.0199999999999999E+01 -1.4130000000000001E+01 7.1550000000000002E+00
+ 505 0 0 0
+ 1.0199999999999999E+01 -1.6129999999999999E+01 7.1550000000000002E+00
+ 506 0 0 0
+ 6.7999999999999998E+00 -2.3999999999999999E+00 1.9800000000000001E+01
+ 507 0 0 0
+ 1.0199999999999999E+01 1.6129999999999999E+01 1.7000000000000000E+00
+ 508 0 0 0
+ 1.0199999999999999E+01 0.0000000000000000E+00 1.2359999999999999E+01
+ 509 0 0 0
+ 6.7999999999999998E+00 2.3999999999999999E+00 1.2359999999999999E+01
+ 510 0 0 0
+ 1.0199999999999999E+01 -1.6129999999999999E+01 9.3599999999999994E+00
+ 511 0 0 0
+ 6.7999999999999998E+00 1.2000000000000000E+01 1.9527999999999999E+01
+ 512 0 0 0
+ 1.0199999999999999E+01 -1.4130000000000001E+01 9.3599999999999994E+00
+ 513 0 0 0
+ 6.7999999999999998E+00 2.3999999999999999E+00 1.5359999999999999E+01
+ 514 0 0 0
+ 1.0199999999999999E+01 1.4130000000000001E+01 4.9500000000000002E+00
+ 515 0 0 0
+ 1.0199999999999999E+01 -1.6129999999999999E+01 1.2359999999999999E+01
+ 516 0 0 0
+ 1.0199999999999999E+01 1.6129999999999999E+01 3.3500000000000001E+00
+ 517 0 0 0
+ 1.0199999999999999E+01 1.6129999999999999E+01 4.9500000000000002E+00
+ 518 0 0 0
+ 1.0199999999999999E+01 0.0000000000000000E+00 1.5359999999999999E+01
+ 519 0 0 0
+ 1.0199999999999999E+01 1.4130000000000001E+01 7.1550000000000002E+00
+ 520 0 0 0
+ 1.0199999999999999E+01 -1.4130000000000001E+01 1.2359999999999999E+01
+ 521 0 0 0
+ 1.0199999999999999E+01 1.6129999999999999E+01 7.1550000000000002E+00
+ 522 0 0 0
+ 1.0199999999999999E+01 -1.6129999999999999E+01 1.5359999999999999E+01
+ 523 0 0 0
+ 6.7999999999999998E+00 2.3999999999999999E+00 1.7609999999999999E+01
+ 524 0 0 0
+ 1.0199999999999999E+01 1.6129999999999999E+01 9.3599999999999994E+00
+ 525 0 0 0
+ 1.0199999999999999E+01 1.4130000000000001E+01 9.3599999999999994E+00
+ 526 0 0 0
+ 1.0199999999999999E+01 -1.4130000000000001E+01 1.5359999999999999E+01
+ 527 0 0 0
+ 1.0199999999999999E+01 -1.6129999999999999E+01 1.7609999999999999E+01
+ 528 0 0 0
+ 1.0199999999999999E+01 -5.5999999999999996E+00 2.0000000000000000E+00
+ 529 0 0 0
+ 1.0199999999999999E+01 1.6129999999999999E+01 1.2359999999999999E+01
+ 530 0 0 0
+ 1.0199999999999999E+01 0.0000000000000000E+00 4.9500000000000002E+00
+ 531 0 0 0
+ 1.0199999999999999E+01 -1.6129999999999999E+01 1.8969999999999999E+01
+ 532 0 0 0
+ 1.0199999999999999E+01 1.4130000000000001E+01 1.2359999999999999E+01
+ 533 0 0 0
+ 1.0199999999999999E+01 -1.6129999999999999E+01 2.0800000000000001E+01
+ 534 0 0 0
+ 1.0199999999999999E+01 5.5999999999999996E+00 2.0000000000000000E+00
+ 536 0 0 0
+ 6.7999999999999998E+00 -1.0400000000000000E+01 1.9611999999999998E+01
+ 538 0 0 0
+ 1.0199999999999999E+01 1.6129999999999999E+01 1.5359999999999999E+01
+ 539 0 0 0
+ 1.0199999999999999E+01 1.4130000000000001E+01 1.5359999999999999E+01
+ 540 0 0 0
+ 1.0199999999999999E+01 -1.4130000000000001E+01 1.8969999999999999E+01
+ 541 0 0 0
+ 1.0199999999999999E+01 -1.4130000000000001E+01 2.0916000000000000E+01
+ 542 0 0 0
+ 1.0199999999999999E+01 1.6129999999999999E+01 1.7609999999999999E+01
+ 543 0 0 0
+ 6.7999999999999998E+00 -4.0000000000000000E+00 1.9949999999999999E+01
+ 544 0 0 0
+ 1.0199999999999999E+01 1.6129999999999999E+01 1.8969999999999999E+01
+ 545 0 0 0
+ 6.7999999999999998E+00 -8.0000000000000000E+00 1.9739000000000001E+01
+ 546 0 0 0
+ 6.7999999999999998E+00 -5.5999999999999996E+00 1.9866000000000000E+01
+ 547 0 0 0
+ 1.0199999999999999E+01 -1.2000000000000000E+01 2.1027999999999999E+01
+ 548 0 0 0
+ 1.0199999999999999E+01 1.6129999999999999E+01 2.0800000000000001E+01
+ 549 0 0 0
+ 6.7999999999999998E+00 4.0000000000000000E+00 1.9949999999999999E+01
+ 550 0 0 0
+ 1.0199999999999999E+01 -1.0400000000000000E+01 2.1111999999999998E+01
+ 551 0 0 0
+ 6.7999999999999998E+00 1.0400000000000000E+01 1.9611999999999998E+01
+ 552 0 0 0
+ 6.7999999999999998E+00 8.0000000000000000E+00 1.9739000000000001E+01
+ 553 0 0 0
+ 6.7999999999999998E+00 5.5999999999999996E+00 1.9866000000000000E+01
+ 554 0 0 0
+ 1.0199999999999999E+01 1.4130000000000001E+01 1.8969999999999999E+01
+ 555 0 0 0
+ 1.0199999999999999E+01 1.4130000000000001E+01 2.0916000000000000E+01
+ 556 0 0 0
+ 1.0199999999999999E+01 0.0000000000000000E+00 2.1449999999999999E+01
+ 557 0 0 0
+ 1.0199999999999999E+01 -8.0000000000000000E+00 2.1239000000000001E+01
+ 558 0 0 0
+ 1.0199999999999999E+01 -2.3999999999999999E+00 2.1449999999999999E+01
+ 559 0 0 0
+ 1.0199999999999999E+01 -4.0000000000000000E+00 2.1449999999999999E+01
+ 560 0 0 0
+ 1.0199999999999999E+01 -5.5999999999999996E+00 2.1366000000000000E+01
+ 561 0 0 0
+ 1.0199999999999999E+01 2.3999999999999999E+00 2.1449999999999999E+01
+ 562 0 0 0
+ 1.0199999999999999E+01 1.2000000000000000E+01 2.1027999999999999E+01
+ 563 0 0 0
+ 1.0199999999999999E+01 4.0000000000000000E+00 2.1449999999999999E+01
+ 564 0 0 0
+ 1.0199999999999999E+01 1.0400000000000000E+01 2.1111999999999998E+01
+ 565 0 0 0
+ 1.0199999999999999E+01 5.5999999999999996E+00 2.1366000000000000E+01
+ 566 0 0 0
+ 1.0199999999999999E+01 8.0000000000000000E+00 2.1239000000000001E+01
+ 569 0 0 0
+ 1.0199999999999999E+01 0.0000000000000000E+00 1.7609999999999999E+01
+ 570 0 0 0
+ 1.0199999999999999E+01 -1.4130000000000001E+01 1.7609999999999999E+01
+ 583 0 0 0
+ 1.0199999999999999E+01 1.4130000000000001E+01 1.7609999999999999E+01
+ 591 0 0 0
+ 1.0199999999999999E+01 0.0000000000000000E+00 1.8969999999999999E+01
+ 592 0 0 0
+ 1.0199999999999999E+01 -3.2556229999999999E-02 9.5263449999999992E+00
+ -1
+ -1
+ 2412
+ 1 44 2 1 7 4
+ 1 167 164 2
+ 2 44 2 1 7 4
+ 167 346 344 164
+ 3 44 2 1 7 4
+ 346 455 453 344
+ 9 44 2 1 7 4
+ 2 164 163 3
+ 10 44 2 1 7 4
+ 164 344 345 163
+ 11 44 2 1 7 4
+ 344 453 454 345
+ 17 44 2 1 7 4
+ 3 163 169 4
+ 18 44 2 1 7 4
+ 163 345 353 169
+ 19 44 2 1 7 4
+ 345 454 463 353
+ 25 44 2 1 7 4
+ 4 169 170 5
+ 26 44 2 1 7 4
+ 169 353 355 170
+ 27 44 2 1 7 4
+ 353 463 466 355
+ 33 44 2 1 7 4
+ 5 170 171 6
+ 34 44 2 1 7 4
+ 170 355 356 171
+ 35 44 2 1 7 4
+ 355 466 469 356
+ 41 44 2 1 7 4
+ 6 171 186 7
+ 42 44 2 1 7 4
+ 171 356 361 186
+ 43 44 2 1 7 4
+ 356 469 473 361
+ 49 44 2 1 7 4
+ 7 186 188 8
+ 50 44 2 1 7 4
+ 186 361 366 188
+ 51 44 2 1 7 4
+ 361 473 479 366
+ 57 44 2 1 7 4
+ 8 188 191 9
+ 58 44 2 1 7 4
+ 188 366 368 191
+ 59 44 2 1 7 4
+ 366 479 487 368
+ 65 44 2 1 7 4
+ 9 191 194 10
+ 66 44 2 1 7 4
+ 191 368 370 194
+ 67 44 2 1 7 4
+ 368 487 490 370
+ 73 44 2 1 7 4
+ 10 194 195 11
+ 74 44 2 1 7 4
+ 194 370 378 195
+ 75 44 2 1 7 4
+ 370 490 497 378
+ 81 44 2 1 7 4
+ 11 195 206 12
+ 82 44 2 1 7 4
+ 195 378 380 206
+ 83 44 2 1 7 4
+ 378 497 499 380
+ 89 44 2 1 7 4
+ 12 206 209 13
+ 90 44 2 1 7 4
+ 206 380 384 209
+ 91 44 2 1 7 4
+ 380 499 505 384
+ 97 44 2 1 7 4
+ 13 209 217 14
+ 98 44 2 1 7 4
+ 209 384 395 217
+ 99 44 2 1 7 4
+ 384 505 510 395
+ 105 44 2 1 7 4
+ 14 217 218 15
+ 106 44 2 1 7 4
+ 217 395 398 218
+ 107 44 2 1 7 4
+ 395 510 515 398
+ 113 44 2 1 7 4
+ 15 218 225 16
+ 114 44 2 1 7 4
+ 218 398 405 225
+ 115 44 2 1 7 4
+ 398 515 522 405
+ 121 44 2 1 7 4
+ 16 225 226 17
+ 122 44 2 1 7 4
+ 225 405 408 226
+ 123 44 2 1 7 4
+ 405 522 527 408
+ 129 44 2 1 7 4
+ 17 226 227 18
+ 130 44 2 1 7 4
+ 226 408 410 227
+ 131 44 2 1 7 4
+ 408 527 531 410
+ 137 44 2 1 7 4
+ 18 227 228 19
+ 138 44 2 1 7 4
+ 227 410 411 228
+ 139 44 2 1 7 4
+ 410 531 533 411
+ 145 44 2 1 7 4
+ 20 245 244 21
+ 146 44 2 1 7 4
+ 245 426 425 244
+ 147 44 2 1 7 4
+ 426 558 559 425
+ 153 44 2 1 7 4
+ 21 244 243 22
+ 154 44 2 1 7 4
+ 244 425 424 243
+ 155 44 2 1 7 4
+ 425 559 560 424
+ 161 44 2 1 7 4
+ 22 243 242 23
+ 162 44 2 1 7 4
+ 243 424 423 242
+ 163 44 2 1 7 4
+ 424 560 557 423
+ 169 44 2 1 7 4
+ 23 242 241 24
+ 170 44 2 1 7 4
+ 242 423 422 241
+ 171 44 2 1 7 4
+ 423 557 550 422
+ 177 44 2 1 7 4
+ 24 241 240 25
+ 178 44 2 1 7 4
+ 241 422 421 240
+ 179 44 2 1 7 4
+ 422 550 547 421
+ 185 44 2 1 7 4
+ 25 240 238 26
+ 186 44 2 1 7 4
+ 240 421 417 238
+ 187 44 2 1 7 4
+ 421 547 541 417
+ 193 44 2 1 7 4
+ 26 238 228 19
+ 194 44 2 1 7 4
+ 238 417 411 228
+ 195 44 2 1 7 4
+ 417 541 533 411
+ 201 44 2 1 7 4
+ 27 174 173 29
+ 202 44 2 1 7 4
+ 174 349 350 173
+ 203 44 2 1 7 4
+ 349 460 459 350
+ 209 44 2 1 7 4
+ 29 173 172 30
+ 210 44 2 1 7 4
+ 173 350 354 172
+ 211 44 2 1 7 4
+ 350 459 465 354
+ 217 44 2 1 7 4
+ 30 172 277 31
+ 218 44 2 1 7 4
+ 172 354 437 277
+ 219 44 2 1 7 4
+ 354 465 528 437
+ 225 44 2 1 7 4
+ 31 277 183 32
+ 226 44 2 1 7 4
+ 277 437 362 183
+ 227 44 2 1 7 4
+ 437 528 475 362
+ 233 44 2 1 7 4
+ 32 183 184 33
+ 234 44 2 1 7 4
+ 183 362 363 184
+ 235 44 2 1 7 4
+ 362 475 476 363
+ 241 44 2 1 7 4
+ 33 184 187 34
+ 242 44 2 1 7 4
+ 184 363 365 187
+ 243 44 2 1 7 4
+ 363 476 478 365
+ 249 44 2 1 7 4
+ 34 187 190 35
+ 250 44 2 1 7 4
+ 187 365 367 190
+ 251 44 2 1 7 4
+ 365 478 485 367
+ 257 44 2 1 7 4
+ 36 216 215 37
+ 258 44 2 1 7 4
+ 216 376 393 215
+ 259 44 2 1 7 4
+ 376 495 504 393
+ 265 44 2 1 7 4
+ 37 215 224 38
+ 266 44 2 1 7 4
+ 215 393 399 224
+ 267 44 2 1 7 4
+ 393 504 512 399
+ 273 44 2 1 7 4
+ 38 224 223 39
+ 274 44 2 1 7 4
+ 224 399 404 223
+ 275 44 2 1 7 4
+ 399 512 520 404
+ 281 44 2 1 7 4
+ 39 223 233 40
+ 282 44 2 1 7 4
+ 223 404 409 233
+ 283 44 2 1 7 4
+ 404 520 526 409
+ 289 44 2 1 7 4
+ 40 233 266 41
+ 290 44 2 1 7 4
+ 233 409 446 266
+ 291 44 2 1 7 4
+ 409 526 570 446
+ 297 44 2 1 7 4
+ 41 266 239 42
+ 298 44 2 1 7 4
+ 266 446 418 239
+ 299 44 2 1 7 4
+ 446 570 540 418
+ 305 44 2 1 7 4
+ 42 239 238 26
+ 306 44 2 1 7 4
+ 239 418 417 238
+ 307 44 2 1 7 4
+ 418 540 541 417
+ 313 44 2 1 7 4
+ 2 164 173 29
+ 314 44 2 1 7 4
+ 164 344 350 173
+ 315 44 2 1 7 4
+ 344 453 459 350
+ 321 44 2 1 7 4
+ 4 169 277 31
+ 322 44 2 1 7 4
+ 169 353 437 277
+ 323 44 2 1 7 4
+ 353 463 528 437
+ 329 44 2 1 7 4
+ 7 186 187 34
+ 330 44 2 1 7 4
+ 186 361 365 187
+ 331 44 2 1 7 4
+ 361 473 478 365
+ 337 44 2 1 7 4
+ 36 216 206 12
+ 338 44 2 1 7 4
+ 216 376 380 206
+ 339 44 2 1 7 4
+ 376 495 499 380
+ 345 44 2 1 7 4
+ 38 224 217 14
+ 346 44 2 1 7 4
+ 224 399 395 217
+ 347 44 2 1 7 4
+ 399 512 510 395
+ 353 44 2 1 7 4
+ 40 233 225 16
+ 354 44 2 1 7 4
+ 233 409 405 225
+ 355 44 2 1 7 4
+ 409 526 522 405
+ 361 44 2 1 7 4
+ 35 190 216 36
+ 362 44 2 1 7 4
+ 190 367 376 216
+ 363 44 2 1 7 4
+ 367 485 495 376
+ 369 44 2 1 7 4
+ 1 167 166 53
+ 370 44 2 1 7 4
+ 167 346 347 166
+ 371 44 2 1 7 4
+ 346 455 456 347
+ 377 44 2 1 7 4
+ 53 166 165 54
+ 378 44 2 1 7 4
+ 166 347 348 165
+ 379 44 2 1 7 4
+ 347 456 457 348
+ 385 44 2 1 7 4
+ 54 165 177 55
+ 386 44 2 1 7 4
+ 165 348 357 177
+ 387 44 2 1 7 4
+ 348 457 467 357
+ 393 44 2 1 7 4
+ 55 177 178 56
+ 394 44 2 1 7 4
+ 177 357 359 178
+ 395 44 2 1 7 4
+ 357 467 471 359
+ 401 44 2 1 7 4
+ 56 178 179 57
+ 402 44 2 1 7 4
+ 178 359 360 179
+ 403 44 2 1 7 4
+ 359 471 472 360
+ 409 44 2 1 7 4
+ 57 179 200 58
+ 410 44 2 1 7 4
+ 179 360 369 200
+ 411 44 2 1 7 4
+ 360 472 484 369
+ 417 44 2 1 7 4
+ 58 200 205 59
+ 418 44 2 1 7 4
+ 200 369 377 205
+ 419 44 2 1 7 4
+ 369 484 491 377
+ 425 44 2 1 7 4
+ 59 205 208 60
+ 426 44 2 1 7 4
+ 205 377 382 208
+ 427 44 2 1 7 4
+ 377 491 498 382
+ 433 44 2 1 7 4
+ 60 208 213 61
+ 434 44 2 1 7 4
+ 208 382 392 213
+ 435 44 2 1 7 4
+ 382 498 507 392
+ 441 44 2 1 7 4
+ 61 213 214 62
+ 442 44 2 1 7 4
+ 213 392 396 214
+ 443 44 2 1 7 4
+ 392 507 516 396
+ 449 44 2 1 7 4
+ 62 214 219 63
+ 450 44 2 1 7 4
+ 214 396 400 219
+ 451 44 2 1 7 4
+ 396 516 517 400
+ 457 44 2 1 7 4
+ 63 219 220 64
+ 458 44 2 1 7 4
+ 219 400 402 220
+ 459 44 2 1 7 4
+ 400 517 521 402
+ 465 44 2 1 7 4
+ 64 220 229 65
+ 466 44 2 1 7 4
+ 220 402 406 229
+ 467 44 2 1 7 4
+ 402 521 524 406
+ 473 44 2 1 7 4
+ 65 229 230 66
+ 474 44 2 1 7 4
+ 229 406 412 230
+ 475 44 2 1 7 4
+ 406 524 529 412
+ 481 44 2 1 7 4
+ 66 230 234 67
+ 482 44 2 1 7 4
+ 230 412 414 234
+ 483 44 2 1 7 4
+ 412 529 538 414
+ 489 44 2 1 7 4
+ 67 234 235 68
+ 490 44 2 1 7 4
+ 234 414 415 235
+ 491 44 2 1 7 4
+ 414 538 542 415
+ 497 44 2 1 7 4
+ 68 235 236 69
+ 498 44 2 1 7 4
+ 235 415 416 236
+ 499 44 2 1 7 4
+ 415 542 544 416
+ 505 44 2 1 7 4
+ 69 236 237 70
+ 506 44 2 1 7 4
+ 236 416 419 237
+ 507 44 2 1 7 4
+ 416 544 548 419
+ 513 44 2 1 7 4
+ 71 246 247 72
+ 514 44 2 1 7 4
+ 246 427 428 247
+ 515 44 2 1 7 4
+ 427 556 561 428
+ 521 44 2 1 7 4
+ 72 247 250 73
+ 522 44 2 1 7 4
+ 247 428 431 250
+ 523 44 2 1 7 4
+ 428 561 563 431
+ 529 44 2 1 7 4
+ 73 250 251 74
+ 530 44 2 1 7 4
+ 250 431 434 251
+ 531 44 2 1 7 4
+ 431 563 565 434
+ 537 44 2 1 7 4
+ 74 251 252 75
+ 538 44 2 1 7 4
+ 251 434 435 252
+ 539 44 2 1 7 4
+ 434 565 566 435
+ 545 44 2 1 7 4
+ 75 252 253 76
+ 546 44 2 1 7 4
+ 252 435 433 253
+ 547 44 2 1 7 4
+ 435 566 564 433
+ 553 44 2 1 7 4
+ 76 253 254 77
+ 554 44 2 1 7 4
+ 253 433 432 254
+ 555 44 2 1 7 4
+ 433 564 562 432
+ 561 44 2 1 7 4
+ 77 254 255 78
+ 562 44 2 1 7 4
+ 254 432 429 255
+ 563 44 2 1 7 4
+ 432 562 555 429
+ 569 44 2 1 7 4
+ 78 255 237 70
+ 570 44 2 1 7 4
+ 255 429 419 237
+ 571 44 2 1 7 4
+ 429 555 548 419
+ 577 44 2 1 7 4
+ 27 174 175 79
+ 578 44 2 1 7 4
+ 174 349 352 175
+ 579 44 2 1 7 4
+ 349 460 461 352
+ 585 44 2 1 7 4
+ 79 175 176 80
+ 586 44 2 1 7 4
+ 175 352 358 176
+ 587 44 2 1 7 4
+ 352 461 470 358
+ 593 44 2 1 7 4
+ 80 176 289 81
+ 594 44 2 1 7 4
+ 176 358 439 289
+ 595 44 2 1 7 4
+ 358 470 534 439
+ 601 44 2 1 7 4
+ 81 289 196 82
+ 602 44 2 1 7 4
+ 289 439 371 196
+ 603 44 2 1 7 4
+ 439 534 486 371
+ 609 44 2 1 7 4
+ 82 196 201 83
+ 610 44 2 1 7 4
+ 196 371 373 201
+ 611 44 2 1 7 4
+ 371 486 488 373
+ 617 44 2 1 7 4
+ 83 201 207 84
+ 618 44 2 1 7 4
+ 201 373 379 207
+ 619 44 2 1 7 4
+ 373 488 493 379
+ 625 44 2 1 7 4
+ 84 207 212 85
+ 626 44 2 1 7 4
+ 207 379 388 212
+ 627 44 2 1 7 4
+ 379 493 503 388
+ 633 44 2 1 7 4
+ 86 222 221 87
+ 634 44 2 1 7 4
+ 222 397 403 221
+ 635 44 2 1 7 4
+ 397 514 519 403
+ 641 44 2 1 7 4
+ 87 221 232 88
+ 642 44 2 1 7 4
+ 221 403 407 232
+ 643 44 2 1 7 4
+ 403 519 525 407
+ 649 44 2 1 7 4
+ 88 232 231 89
+ 650 44 2 1 7 4
+ 232 407 413 231
+ 651 44 2 1 7 4
+ 407 525 532 413
+ 657 44 2 1 7 4
+ 89 231 259 90
+ 658 44 2 1 7 4
+ 231 413 420 259
+ 659 44 2 1 7 4
+ 413 532 539 420
+ 665 44 2 1 7 4
+ 90 259 267 91
+ 666 44 2 1 7 4
+ 259 420 447 267
+ 667 44 2 1 7 4
+ 420 539 583 447
+ 673 44 2 1 7 4
+ 91 267 256 92
+ 674 44 2 1 7 4
+ 267 447 430 256
+ 675 44 2 1 7 4
+ 447 583 554 430
+ 681 44 2 1 7 4
+ 92 256 255 78
+ 682 44 2 1 7 4
+ 256 430 429 255
+ 683 44 2 1 7 4
+ 430 554 555 429
+ 689 44 2 1 7 4
+ 53 166 175 79
+ 690 44 2 1 7 4
+ 166 347 352 175
+ 691 44 2 1 7 4
+ 347 456 461 352
+ 697 44 2 1 7 4
+ 55 177 289 81
+ 698 44 2 1 7 4
+ 177 357 439 289
+ 699 44 2 1 7 4
+ 357 467 534 439
+ 705 44 2 1 7 4
+ 58 200 207 84
+ 706 44 2 1 7 4
+ 200 369 379 207
+ 707 44 2 1 7 4
+ 369 484 493 379
+ 713 44 2 1 7 4
+ 86 222 219 63
+ 714 44 2 1 7 4
+ 222 397 400 219
+ 715 44 2 1 7 4
+ 397 514 517 400
+ 721 44 2 1 7 4
+ 88 232 229 65
+ 722 44 2 1 7 4
+ 232 407 406 229
+ 723 44 2 1 7 4
+ 407 525 524 406
+ 729 44 2 1 7 4
+ 90 259 234 67
+ 730 44 2 1 7 4
+ 259 420 414 234
+ 731 44 2 1 7 4
+ 420 539 538 414
+ 737 44 2 1 7 4
+ 85 212 222 86
+ 738 44 2 1 7 4
+ 212 388 397 222
+ 739 44 2 1 7 4
+ 388 503 514 397
+ 745 44 2 1 7 4
+ 1 167 174 27
+ 746 44 2 1 7 4
+ 167 346 349 174
+ 747 44 2 1 7 4
+ 346 455 460 349
+ 753 44 2 1 7 4
+ 27 174 168 48
+ 754 44 2 1 7 4
+ 174 349 351 168
+ 755 44 2 1 7 4
+ 349 460 462 351
+ 761 44 2 1 7 4
+ 48 168 278 49
+ 762 44 2 1 7 4
+ 168 351 436 278
+ 763 44 2 1 7 4
+ 351 462 530 436
+ 769 44 2 1 7 4
+ 49 278 182 101
+ 770 44 2 1 7 4
+ 278 436 364 182
+ 771 44 2 1 7 4
+ 436 530 480 364
+ 777 44 2 1 7 4
+ 101 182 261 102
+ 778 44 2 1 7 4
+ 182 364 374 261
+ 779 44 2 1 7 4
+ 364 480 492 374
+ 785 44 2 1 7 4
+ 102 261 210 103
+ 786 44 2 1 7 4
+ 261 374 394 210
+ 787 44 2 1 7 4
+ 374 492 508 394
+ 793 44 2 1 7 4
+ 103 210 263 104
+ 794 44 2 1 7 4
+ 210 394 401 263
+ 795 44 2 1 7 4
+ 394 508 518 401
+ 801 44 2 1 7 4
+ 104 263 265 52
+ 802 44 2 1 7 4
+ 263 401 445 265
+ 803 44 2 1 7 4
+ 401 518 569 445
+ 809 44 2 1 7 4
+ 52 265 339 28
+ 810 44 2 1 7 4
+ 265 445 448 339
+ 811 44 2 1 7 4
+ 445 569 591 448
+ 817 44 2 1 7 4
+ 71 246 339 28
+ 818 44 2 1 7 4
+ 246 427 448 339
+ 819 44 2 1 7 4
+ 427 556 591 448
+ 825 44 2 1 7 4
+ 71 246 245 20
+ 826 44 2 1 7 4
+ 246 427 426 245
+ 827 44 2 1 7 4
+ 427 556 558 426
+ 838 11 2 1 7 2
+ 0 0 0
+ 450 436
+ 839 11 2 1 7 2
+ 0 0 0
+ 305 278
+ 845 11 2 1 7 2
+ 0 0 0
+ 449 450
+ 846 11 2 1 7 2
+ 0 0 0
+ 304 305
+ 852 11 2 1 7 2
+ 0 0 0
+ 437 449
+ 853 11 2 1 7 2
+ 0 0 0
+ 277 304
+ 859 11 2 1 7 2
+ 0 0 0
+ 350 349
+ 860 11 2 1 7 2
+ 0 0 0
+ 173 174
+ 861 11 2 1 7 2
+ 0 0 0
+ 29 27
+ 867 11 2 1 7 2
+ 0 0 0
+ 346 344
+ 868 11 2 1 7 2
+ 0 0 0
+ 167 164
+ 869 11 2 1 7 2
+ 0 0 0
+ 1 2
+ 875 11 2 1 7 2
+ 0 0 0
+ 477 452
+ 876 11 2 1 7 2
+ 0 0 0
+ 316 302
+ 882 11 2 1 7 2
+ 0 0 0
+ 483 477
+ 883 11 2 1 7 2
+ 0 0 0
+ 326 316
+ 889 11 2 1 7 2
+ 0 0 0
+ 482 483
+ 890 11 2 1 7 2
+ 0 0 0
+ 325 326
+ 896 11 2 1 7 2
+ 0 0 0
+ 481 482
+ 897 11 2 1 7 2
+ 0 0 0
+ 315 325
+ 903 11 2 1 7 2
+ 0 0 0
+ 452 481
+ 904 11 2 1 7 2
+ 0 0 0
+ 302 315
+ 910 11 2 1 7 2
+ 0 0 0
+ 446 502
+ 911 11 2 1 7 2
+ 0 0 0
+ 266 297
+ 917 11 2 1 7 2
+ 0 0 0
+ 502 536
+ 918 11 2 1 7 2
+ 0 0 0
+ 297 318
+ 924 11 2 1 7 2
+ 0 0 0
+ 536 545
+ 925 11 2 1 7 2
+ 0 0 0
+ 318 327
+ 931 11 2 1 7 2
+ 0 0 0
+ 545 546
+ 932 11 2 1 7 2
+ 0 0 0
+ 327 328
+ 938 11 2 1 7 2
+ 0 0 0
+ 546 543
+ 939 11 2 1 7 2
+ 0 0 0
+ 328 317
+ 945 11 2 1 7 2
+ 0 0 0
+ 543 506
+ 946 11 2 1 7 2
+ 0 0 0
+ 317 294
+ 952 11 2 1 7 2
+ 0 0 0
+ 506 445
+ 953 11 2 1 7 2
+ 0 0 0
+ 294 265
+ 954 11 2 1 7 2
+ 0 0 0
+ 216 268
+ 955 11 2 1 7 2
+ 0 0 0
+ 268 292
+ 956 11 2 1 7 2
+ 0 0 0
+ 292 311
+ 957 11 2 1 7 2
+ 0 0 0
+ 311 313
+ 958 11 2 1 7 2
+ 0 0 0
+ 313 314
+ 959 11 2 1 7 2
+ 0 0 0
+ 314 306
+ 960 11 2 1 7 2
+ 0 0 0
+ 306 269
+ 961 11 2 1 7 2
+ 0 0 0
+ 224 295
+ 962 11 2 1 7 2
+ 0 0 0
+ 295 383
+ 963 11 2 1 7 2
+ 0 0 0
+ 383 443
+ 964 11 2 1 7 2
+ 0 0 0
+ 443 444
+ 965 11 2 1 7 2
+ 0 0 0
+ 444 372
+ 966 11 2 1 7 2
+ 0 0 0
+ 372 290
+ 967 11 2 1 7 2
+ 0 0 0
+ 233 293
+ 968 11 2 1 7 2
+ 0 0 0
+ 293 381
+ 969 11 2 1 7 2
+ 0 0 0
+ 381 441
+ 970 11 2 1 7 2
+ 0 0 0
+ 441 442
+ 971 11 2 1 7 2
+ 0 0 0
+ 442 375
+ 972 11 2 1 7 2
+ 0 0 0
+ 375 291
+ 978 11 2 1 7 2
+ 0 0 0
+ 451 458
+ 979 11 2 1 7 2
+ 0 0 0
+ 312 319
+ 985 11 2 1 7 2
+ 0 0 0
+ 439 451
+ 986 11 2 1 7 2
+ 0 0 0
+ 289 312
+ 992 11 2 1 7 2
+ 0 0 0
+ 352 349
+ 993 11 2 1 7 2
+ 0 0 0
+ 175 174
+ 994 11 2 1 7 2
+ 0 0 0
+ 79 27
+ 1000 11 2 1 7 2
+ 0 0 0
+ 346 347
+ 1001 11 2 1 7 2
+ 0 0 0
+ 167 166
+ 1002 11 2 1 7 2
+ 0 0 0
+ 1 53
+ 1008 11 2 1 7 2
+ 0 0 0
+ 496 468
+ 1009 11 2 1 7 2
+ 0 0 0
+ 323 307
+ 1015 11 2 1 7 2
+ 0 0 0
+ 501 496
+ 1016 11 2 1 7 2
+ 0 0 0
+ 332 323
+ 1022 11 2 1 7 2
+ 0 0 0
+ 500 501
+ 1023 11 2 1 7 2
+ 0 0 0
+ 331 332
+ 1029 11 2 1 7 2
+ 0 0 0
+ 494 500
+ 1030 11 2 1 7 2
+ 0 0 0
+ 322 331
+ 1036 11 2 1 7 2
+ 0 0 0
+ 468 494
+ 1037 11 2 1 7 2
+ 0 0 0
+ 307 322
+ 1043 11 2 1 7 2
+ 0 0 0
+ 447 511
+ 1044 11 2 1 7 2
+ 0 0 0
+ 267 303
+ 1050 11 2 1 7 2
+ 0 0 0
+ 511 551
+ 1051 11 2 1 7 2
+ 0 0 0
+ 303 324
+ 1057 11 2 1 7 2
+ 0 0 0
+ 551 552
+ 1058 11 2 1 7 2
+ 0 0 0
+ 324 329
+ 1064 11 2 1 7 2
+ 0 0 0
+ 552 553
+ 1065 11 2 1 7 2
+ 0 0 0
+ 329 330
+ 1071 11 2 1 7 2
+ 0 0 0
+ 553 549
+ 1072 11 2 1 7 2
+ 0 0 0
+ 330 321
+ 1073 11 2 1 7 2
+ 0 0 0
+ 222 270
+ 1074 11 2 1 7 2
+ 0 0 0
+ 270 300
+ 1075 11 2 1 7 2
+ 0 0 0
+ 300 309
+ 1076 11 2 1 7 2
+ 0 0 0
+ 309 310
+ 1077 11 2 1 7 2
+ 0 0 0
+ 310 308
+ 1078 11 2 1 7 2
+ 0 0 0
+ 308 271
+ 1079 11 2 1 7 2
+ 0 0 0
+ 271 260
+ 1080 11 2 1 7 2
+ 0 0 0
+ 232 301
+ 1081 11 2 1 7 2
+ 0 0 0
+ 301 386
+ 1082 11 2 1 7 2
+ 0 0 0
+ 386 387
+ 1083 11 2 1 7 2
+ 0 0 0
+ 387 385
+ 1084 11 2 1 7 2
+ 0 0 0
+ 385 296
+ 1085 11 2 1 7 2
+ 0 0 0
+ 296 262
+ 1086 11 2 1 7 2
+ 0 0 0
+ 259 299
+ 1087 11 2 1 7 2
+ 0 0 0
+ 299 390
+ 1088 11 2 1 7 2
+ 0 0 0
+ 390 391
+ 1089 11 2 1 7 2
+ 0 0 0
+ 391 389
+ 1090 11 2 1 7 2
+ 0 0 0
+ 389 298
+ 1091 11 2 1 7 2
+ 0 0 0
+ 298 264
+ 1097 11 2 1 7 2
+ 0 0 0
+ 346 349
+ 1098 11 2 1 7 2
+ 0 0 0
+ 167 174
+ 1099 11 2 1 7 2
+ 0 0 0
+ 1 27
+ 1100 11 2 1 7 2
+ 0 0 0
+ 291 263
+ 1101 11 2 1 7 2
+ 0 0 0
+ 290 261
+ 1102 11 2 1 7 2
+ 0 0 0
+ 269 278
+ 1103 11 2 1 7 2
+ 0 0 0
+ 263 264
+ 1104 11 2 1 7 2
+ 0 0 0
+ 261 262
+ 1105 11 2 1 7 2
+ 0 0 0
+ 278 260
+ 1106 11 2 1 7 2
+ 0 0 0
+ 319 340
+ 1107 11 2 1 7 2
+ 0 0 0
+ 340 342
+ 1108 11 2 1 7 2
+ 0 0 0
+ 342 343
+ 1109 11 2 1 7 2
+ 0 0 0
+ 343 341
+ 1110 11 2 1 7 2
+ 0 0 0
+ 341 320
+ 1111 11 2 1 7 2
+ 0 0 0
+ 320 321
+ 1112 11 2 1 7 2
+ 0 0 0
+ 458 474
+ 1118 11 2 1 7 2
+ 0 0 0
+ 474 489
+ 1124 11 2 1 7 2
+ 0 0 0
+ 489 509
+ 1130 11 2 1 7 2
+ 0 0 0
+ 509 513
+ 1136 11 2 1 7 2
+ 0 0 0
+ 513 523
+ 1142 11 2 1 7 2
+ 0 0 0
+ 523 549
+ 1153 11 2 1 7 2
+ 0 0 0
+ 448 591
+ 1154 11 2 1 7 2
+ 0 0 0
+ 339 448
+ 1155 11 2 1 7 2
+ 0 0 0
+ 28 339
+ 1156 11 2 1 7 2
+ 0 0 0
+ 28 118
+ 1157 11 2 1 7 2
+ 0 0 0
+ 118 152
+ 1158 11 2 1 7 2
+ 0 0 0
+ 152 153
+ 1159 11 2 1 7 2
+ 0 0 0
+ 153 154
+ 1160 11 2 1 7 2
+ 0 0 0
+ 154 155
+ 1161 11 2 1 7 2
+ 0 0 0
+ 28 157
+ 1162 11 2 1 7 2
+ 0 0 0
+ 157 158
+ 1163 11 2 1 7 2
+ 0 0 0
+ 158 159
+ 1164 11 2 1 7 2
+ 0 0 0
+ 159 160
+ 1165 11 2 1 7 2
+ 0 0 0
+ 155 156
+ 1166 11 2 1 7 2
+ 0 0 0
+ 156 92
+ 1167 11 2 1 7 2
+ 0 0 0
+ 160 161
+ 1168 11 2 1 7 2
+ 0 0 0
+ 161 162
+ 1169 11 2 1 7 2
+ 0 0 0
+ 162 42
+ 1175 44 2 1 7 4
+ 438 351 349 350
+ 1176 44 2 1 7 4
+ 180 168 174 173
+ 1177 44 2 1 7 4
+ 50 48 27 29
+ 1183 44 2 1 7 4
+ 450 436 351 438
+ 1184 44 2 1 7 4
+ 305 278 168 180
+ 1190 44 2 1 7 4
+ 449 438 350 354
+ 1191 44 2 1 7 4
+ 304 180 173 172
+ 1197 44 2 1 7 4
+ 354 350 344 345
+ 1198 44 2 1 7 4
+ 172 173 164 163
+ 1199 44 2 1 7 4
+ 30 29 2 3
+ 1205 44 2 1 7 4
+ 437 354 345 353
+ 1206 44 2 1 7 4
+ 277 172 163 169
+ 1207 44 2 1 7 4
+ 31 30 3 4
+ 1213 44 2 1 7 4
+ 362 437 353 355
+ 1214 44 2 1 7 4
+ 183 277 169 170
+ 1215 44 2 1 7 4
+ 32 31 4 5
+ 1221 44 2 1 7 4
+ 363 362 355 356
+ 1222 44 2 1 7 4
+ 184 183 170 171
+ 1223 44 2 1 7 4
+ 33 32 5 6
+ 1229 44 2 1 7 4
+ 365 363 356 361
+ 1230 44 2 1 7 4
+ 187 184 171 186
+ 1236 44 2 1 7 4
+ 452 365 361 366
+ 1237 44 2 1 7 4
+ 302 187 186 188
+ 1238 44 2 1 7 4
+ 43 34 7 8
+ 1244 44 2 1 7 4
+ 481 452 366 368
+ 1245 44 2 1 7 4
+ 315 302 188 191
+ 1246 44 2 1 7 4
+ 47 43 8 9
+ 1252 44 2 1 7 4
+ 477 367 365 452
+ 1253 44 2 1 7 4
+ 316 190 187 302
+ 1254 44 2 1 7 4
+ 46 35 34 43
+ 1260 44 2 1 7 4
+ 483 376 367 477
+ 1261 44 2 1 7 4
+ 326 216 190 316
+ 1262 44 2 1 7 4
+ 45 36 35 46
+ 1268 44 2 1 7 4
+ 378 482 481 370
+ 1269 44 2 1 7 4
+ 195 325 315 194
+ 1270 44 2 1 7 4
+ 11 44 47 10
+ 1276 44 2 1 7 4
+ 380 376 483 482
+ 1277 44 2 1 7 4
+ 206 216 326 325
+ 1278 44 2 1 7 4
+ 12 36 45 44
+ 1284 44 2 1 7 4
+ 384 393 376 380
+ 1285 44 2 1 7 4
+ 209 215 216 206
+ 1286 44 2 1 7 4
+ 13 37 36 12
+ 1292 44 2 1 7 4
+ 395 399 393 384
+ 1293 44 2 1 7 4
+ 217 224 215 209
+ 1294 44 2 1 7 4
+ 14 38 37 13
+ 1300 44 2 1 7 4
+ 398 404 399 395
+ 1301 44 2 1 7 4
+ 218 223 224 217
+ 1302 44 2 1 7 4
+ 15 39 38 14
+ 1308 44 2 1 7 4
+ 405 409 404 398
+ 1309 44 2 1 7 4
+ 225 233 223 218
+ 1310 44 2 1 7 4
+ 16 40 39 15
+ 1316 44 2 1 7 4
+ 408 446 409 405
+ 1317 44 2 1 7 4
+ 226 266 233 225
+ 1318 44 2 1 7 4
+ 17 41 40 16
+ 1324 44 2 1 7 4
+ 410 418 446 408
+ 1325 44 2 1 7 4
+ 227 239 266 226
+ 1326 44 2 1 7 4
+ 18 42 41 17
+ 1332 44 2 1 7 4
+ 411 417 418 410
+ 1333 44 2 1 7 4
+ 228 238 239 227
+ 1334 44 2 1 7 4
+ 19 26 42 18
+ 1340 44 2 1 7 4
+ 417 421 502 418
+ 1341 44 2 1 7 4
+ 238 240 297 239
+ 1342 44 2 1 7 4
+ 26 25 162 42
+ 1348 44 2 1 7 4
+ 421 422 536 502
+ 1349 44 2 1 7 4
+ 240 241 318 297
+ 1350 44 2 1 7 4
+ 25 24 161 162
+ 1356 44 2 1 7 4
+ 422 423 545 536
+ 1357 44 2 1 7 4
+ 241 242 327 318
+ 1358 44 2 1 7 4
+ 24 23 160 161
+ 1364 44 2 1 7 4
+ 423 424 546 545
+ 1365 44 2 1 7 4
+ 242 243 328 327
+ 1366 44 2 1 7 4
+ 23 22 159 160
+ 1372 44 2 1 7 4
+ 424 425 543 546
+ 1373 44 2 1 7 4
+ 243 244 317 328
+ 1374 44 2 1 7 4
+ 22 21 158 159
+ 1380 44 2 1 7 4
+ 425 426 506 543
+ 1381 44 2 1 7 4
+ 244 245 294 317
+ 1382 44 2 1 7 4
+ 21 20 157 158
+ 1383 44 2 1 7 4
+ 44 45 46 47
+ 1384 44 2 1 7 4
+ 110 113 33 34
+ 1385 44 2 1 7 4
+ 113 112 32 33
+ 1386 44 2 1 7 4
+ 112 111 31 32
+ 1387 44 2 1 7 4
+ 111 51 30 31
+ 1388 44 2 1 7 4
+ 51 50 29 30
+ 1389 44 2 1 7 4
+ 119 123 110 35
+ 1390 44 2 1 7 4
+ 123 135 113 110
+ 1391 44 2 1 7 4
+ 135 150 112 113
+ 1392 44 2 1 7 4
+ 150 151 111 112
+ 1393 44 2 1 7 4
+ 151 133 51 111
+ 1394 44 2 1 7 4
+ 133 120 50 51
+ 1395 44 2 1 7 4
+ 120 49 48 50
+ 1396 44 2 1 7 4
+ 37 131 119 36
+ 1397 44 2 1 7 4
+ 131 211 135 123
+ 1398 44 2 1 7 4
+ 211 258 150 135
+ 1399 44 2 1 7 4
+ 258 257 151 150
+ 1400 44 2 1 7 4
+ 257 181 133 151
+ 1401 44 2 1 7 4
+ 181 124 120 133
+ 1402 44 2 1 7 4
+ 38 143 131 37
+ 1403 44 2 1 7 4
+ 143 279 211 131
+ 1404 44 2 1 7 4
+ 279 337 258 211
+ 1405 44 2 1 7 4
+ 337 338 257 258
+ 1406 44 2 1 7 4
+ 338 272 181 257
+ 1407 44 2 1 7 4
+ 272 136 124 181
+ 1408 44 2 1 7 4
+ 39 142 143 38
+ 1409 44 2 1 7 4
+ 142 276 279 143
+ 1410 44 2 1 7 4
+ 276 335 337 279
+ 1411 44 2 1 7 4
+ 335 336 338 337
+ 1412 44 2 1 7 4
+ 336 273 272 338
+ 1413 44 2 1 7 4
+ 273 137 136 272
+ 1414 44 2 1 7 4
+ 40 141 142 39
+ 1415 44 2 1 7 4
+ 141 275 276 142
+ 1416 44 2 1 7 4
+ 275 333 335 276
+ 1417 44 2 1 7 4
+ 333 334 336 335
+ 1418 44 2 1 7 4
+ 334 274 273 336
+ 1419 44 2 1 7 4
+ 274 138 137 273
+ 1420 44 2 1 7 4
+ 41 125 141 40
+ 1421 44 2 1 7 4
+ 125 189 275 141
+ 1422 44 2 1 7 4
+ 189 248 333 275
+ 1423 44 2 1 7 4
+ 248 249 334 333
+ 1424 44 2 1 7 4
+ 249 192 274 334
+ 1425 44 2 1 7 4
+ 192 126 138 274
+ 1426 44 2 1 7 4
+ 42 162 125 41
+ 1427 44 2 1 7 4
+ 162 161 189 125
+ 1428 44 2 1 7 4
+ 161 160 248 189
+ 1429 44 2 1 7 4
+ 160 159 249 248
+ 1430 44 2 1 7 4
+ 159 158 192 249
+ 1431 44 2 1 7 4
+ 158 157 126 192
+ 1432 44 2 1 7 4
+ 268 119 123 292
+ 1433 44 2 1 7 4
+ 292 123 135 311
+ 1434 44 2 1 7 4
+ 311 135 150 313
+ 1435 44 2 1 7 4
+ 313 150 151 314
+ 1436 44 2 1 7 4
+ 314 151 133 306
+ 1437 44 2 1 7 4
+ 306 133 120 269
+ 1438 44 2 1 7 4
+ 216 36 119 268
+ 1439 44 2 1 7 4
+ 224 38 143 295
+ 1440 44 2 1 7 4
+ 295 143 279 383
+ 1441 44 2 1 7 4
+ 383 279 337 443
+ 1442 44 2 1 7 4
+ 443 337 338 444
+ 1443 44 2 1 7 4
+ 444 338 272 372
+ 1444 44 2 1 7 4
+ 372 272 136 290
+ 1445 44 2 1 7 4
+ 233 40 141 293
+ 1446 44 2 1 7 4
+ 293 141 275 381
+ 1447 44 2 1 7 4
+ 381 275 333 441
+ 1448 44 2 1 7 4
+ 441 333 334 442
+ 1449 44 2 1 7 4
+ 442 334 274 375
+ 1450 44 2 1 7 4
+ 375 274 138 291
+ 1456 44 2 1 7 4
+ 440 351 349 352
+ 1457 44 2 1 7 4
+ 185 168 174 175
+ 1458 44 2 1 7 4
+ 98 48 27 79
+ 1464 44 2 1 7 4
+ 458 436 351 440
+ 1465 44 2 1 7 4
+ 319 278 168 185
+ 1471 44 2 1 7 4
+ 451 440 352 358
+ 1472 44 2 1 7 4
+ 312 185 175 176
+ 1478 44 2 1 7 4
+ 358 352 347 348
+ 1479 44 2 1 7 4
+ 176 175 166 165
+ 1480 44 2 1 7 4
+ 80 79 53 54
+ 1486 44 2 1 7 4
+ 439 358 348 357
+ 1487 44 2 1 7 4
+ 289 176 165 177
+ 1488 44 2 1 7 4
+ 81 80 54 55
+ 1494 44 2 1 7 4
+ 371 439 357 359
+ 1495 44 2 1 7 4
+ 196 289 177 178
+ 1496 44 2 1 7 4
+ 82 81 55 56
+ 1502 44 2 1 7 4
+ 373 371 359 360
+ 1503 44 2 1 7 4
+ 201 196 178 179
+ 1504 44 2 1 7 4
+ 83 82 56 57
+ 1510 44 2 1 7 4
+ 379 373 360 369
+ 1511 44 2 1 7 4
+ 207 201 179 200
+ 1512 44 2 1 7 4
+ 84 83 57 58
+ 1518 44 2 1 7 4
+ 468 379 369 377
+ 1519 44 2 1 7 4
+ 307 207 200 205
+ 1520 44 2 1 7 4
+ 93 84 58 59
+ 1526 44 2 1 7 4
+ 494 468 377 382
+ 1527 44 2 1 7 4
+ 322 307 205 208
+ 1528 44 2 1 7 4
+ 97 93 59 60
+ 1534 44 2 1 7 4
+ 496 388 379 468
+ 1535 44 2 1 7 4
+ 323 212 207 307
+ 1536 44 2 1 7 4
+ 96 85 84 93
+ 1542 44 2 1 7 4
+ 501 397 388 496
+ 1543 44 2 1 7 4
+ 332 222 212 323
+ 1544 44 2 1 7 4
+ 95 86 85 96
+ 1550 44 2 1 7 4
+ 396 500 494 392
+ 1551 44 2 1 7 4
+ 214 331 322 213
+ 1552 44 2 1 7 4
+ 62 94 97 61
+ 1558 44 2 1 7 4
+ 400 397 501 500
+ 1559 44 2 1 7 4
+ 219 222 332 331
+ 1560 44 2 1 7 4
+ 63 86 95 94
+ 1566 44 2 1 7 4
+ 402 403 397 400
+ 1567 44 2 1 7 4
+ 220 221 222 219
+ 1568 44 2 1 7 4
+ 64 87 86 63
+ 1574 44 2 1 7 4
+ 406 407 403 402
+ 1575 44 2 1 7 4
+ 229 232 221 220
+ 1576 44 2 1 7 4
+ 65 88 87 64
+ 1582 44 2 1 7 4
+ 412 413 407 406
+ 1583 44 2 1 7 4
+ 230 231 232 229
+ 1584 44 2 1 7 4
+ 66 89 88 65
+ 1590 44 2 1 7 4
+ 414 420 413 412
+ 1591 44 2 1 7 4
+ 234 259 231 230
+ 1592 44 2 1 7 4
+ 67 90 89 66
+ 1598 44 2 1 7 4
+ 415 447 420 414
+ 1599 44 2 1 7 4
+ 235 267 259 234
+ 1600 44 2 1 7 4
+ 68 91 90 67
+ 1606 44 2 1 7 4
+ 416 430 447 415
+ 1607 44 2 1 7 4
+ 236 256 267 235
+ 1608 44 2 1 7 4
+ 69 92 91 68
+ 1614 44 2 1 7 4
+ 419 429 430 416
+ 1615 44 2 1 7 4
+ 237 255 256 236
+ 1616 44 2 1 7 4
+ 70 78 92 69
+ 1622 44 2 1 7 4
+ 429 432 511 430
+ 1623 44 2 1 7 4
+ 255 254 303 256
+ 1624 44 2 1 7 4
+ 78 77 156 92
+ 1630 44 2 1 7 4
+ 432 433 551 511
+ 1631 44 2 1 7 4
+ 254 253 324 303
+ 1632 44 2 1 7 4
+ 77 76 155 156
+ 1638 44 2 1 7 4
+ 433 435 552 551
+ 1639 44 2 1 7 4
+ 253 252 329 324
+ 1640 44 2 1 7 4
+ 76 75 154 155
+ 1646 44 2 1 7 4
+ 435 434 553 552
+ 1647 44 2 1 7 4
+ 252 251 330 329
+ 1648 44 2 1 7 4
+ 75 74 153 154
+ 1654 44 2 1 7 4
+ 434 431 549 553
+ 1655 44 2 1 7 4
+ 251 250 321 330
+ 1656 44 2 1 7 4
+ 74 73 152 153
+ 1662 44 2 1 7 4
+ 431 428 464 549
+ 1663 44 2 1 7 4
+ 250 247 193 321
+ 1664 44 2 1 7 4
+ 73 72 118 152
+ 1670 44 2 1 7 4
+ 428 427 448 464
+ 1671 44 2 1 7 4
+ 247 246 339 193
+ 1672 44 2 1 7 4
+ 72 71 28 118
+ 1673 44 2 1 7 4
+ 94 95 96 97
+ 1674 44 2 1 7 4
+ 114 117 83 84
+ 1675 44 2 1 7 4
+ 117 116 82 83
+ 1676 44 2 1 7 4
+ 116 115 81 82
+ 1677 44 2 1 7 4
+ 115 100 80 81
+ 1678 44 2 1 7 4
+ 100 98 79 80
+ 1679 44 2 1 7 4
+ 121 129 114 85
+ 1680 44 2 1 7 4
+ 129 139 117 114
+ 1681 44 2 1 7 4
+ 139 140 116 117
+ 1682 44 2 1 7 4
+ 140 134 115 116
+ 1683 44 2 1 7 4
+ 134 122 100 115
+ 1684 44 2 1 7 4
+ 122 99 98 100
+ 1685 44 2 1 7 4
+ 99 49 48 98
+ 1686 44 2 1 7 4
+ 87 132 121 86
+ 1687 44 2 1 7 4
+ 132 199 139 129
+ 1688 44 2 1 7 4
+ 199 198 140 139
+ 1689 44 2 1 7 4
+ 198 197 134 140
+ 1690 44 2 1 7 4
+ 197 127 122 134
+ 1691 44 2 1 7 4
+ 88 149 132 87
+ 1692 44 2 1 7 4
+ 149 287 199 132
+ 1693 44 2 1 7 4
+ 287 288 198 199
+ 1694 44 2 1 7 4
+ 288 280 197 198
+ 1695 44 2 1 7 4
+ 280 144 127 197
+ 1696 44 2 1 7 4
+ 89 148 149 88
+ 1697 44 2 1 7 4
+ 148 283 287 149
+ 1698 44 2 1 7 4
+ 283 284 288 287
+ 1699 44 2 1 7 4
+ 284 281 280 288
+ 1700 44 2 1 7 4
+ 281 145 144 280
+ 1701 44 2 1 7 4
+ 90 147 148 89
+ 1702 44 2 1 7 4
+ 147 285 283 148
+ 1703 44 2 1 7 4
+ 285 286 284 283
+ 1704 44 2 1 7 4
+ 286 282 281 284
+ 1705 44 2 1 7 4
+ 282 146 145 281
+ 1706 44 2 1 7 4
+ 91 128 147 90
+ 1707 44 2 1 7 4
+ 128 202 285 147
+ 1708 44 2 1 7 4
+ 202 203 286 285
+ 1709 44 2 1 7 4
+ 203 204 282 286
+ 1710 44 2 1 7 4
+ 204 130 146 282
+ 1711 44 2 1 7 4
+ 92 156 128 91
+ 1712 44 2 1 7 4
+ 156 155 202 128
+ 1713 44 2 1 7 4
+ 155 154 203 202
+ 1714 44 2 1 7 4
+ 154 153 204 203
+ 1715 44 2 1 7 4
+ 153 152 130 204
+ 1716 44 2 1 7 4
+ 270 121 129 300
+ 1717 44 2 1 7 4
+ 300 129 139 309
+ 1718 44 2 1 7 4
+ 309 139 140 310
+ 1719 44 2 1 7 4
+ 310 140 134 308
+ 1720 44 2 1 7 4
+ 308 134 122 271
+ 1721 44 2 1 7 4
+ 271 122 99 260
+ 1722 44 2 1 7 4
+ 222 86 121 270
+ 1723 44 2 1 7 4
+ 232 88 149 301
+ 1724 44 2 1 7 4
+ 301 149 287 386
+ 1725 44 2 1 7 4
+ 386 287 288 387
+ 1726 44 2 1 7 4
+ 387 288 280 385
+ 1727 44 2 1 7 4
+ 385 280 144 296
+ 1728 44 2 1 7 4
+ 259 90 147 299
+ 1729 44 2 1 7 4
+ 299 147 285 390
+ 1730 44 2 1 7 4
+ 390 285 286 391
+ 1731 44 2 1 7 4
+ 391 286 282 389
+ 1732 44 2 1 7 4
+ 389 282 146 298
+ 1733 44 2 1 7 4
+ 136 102 101 124
+ 1734 44 2 1 7 4
+ 137 103 102 136
+ 1735 44 2 1 7 4
+ 138 104 103 137
+ 1736 44 2 1 7 4
+ 124 101 49 120
+ 1737 44 2 1 7 4
+ 126 52 104 138
+ 1738 44 2 1 7 4
+ 157 28 52 126
+ 1739 44 2 1 7 4
+ 269 120 49 278
+ 1740 44 2 1 7 4
+ 290 136 102 261
+ 1741 44 2 1 7 4
+ 291 138 104 263
+ 1742 44 2 1 7 4
+ 278 49 99 260
+ 1743 44 2 1 7 4
+ 127 105 99 122
+ 1744 44 2 1 7 4
+ 105 101 49 99
+ 1745 44 2 1 7 4
+ 144 106 105 127
+ 1746 44 2 1 7 4
+ 106 102 101 105
+ 1747 44 2 1 7 4
+ 145 107 106 144
+ 1748 44 2 1 7 4
+ 107 103 102 106
+ 1749 44 2 1 7 4
+ 146 108 107 145
+ 1750 44 2 1 7 4
+ 108 104 103 107
+ 1751 44 2 1 7 4
+ 296 144 106 262
+ 1752 44 2 1 7 4
+ 262 106 102 261
+ 1753 44 2 1 7 4
+ 298 146 108 264
+ 1754 44 2 1 7 4
+ 264 108 104 263
+ 1755 44 2 1 7 4
+ 130 109 108 146
+ 1756 44 2 1 7 4
+ 109 52 104 108
+ 1757 44 2 1 7 4
+ 152 118 109 130
+ 1758 44 2 1 7 4
+ 118 28 52 109
+ 1759 44 2 1 7 4
+ 340 182 278 319
+ 1760 44 2 1 7 4
+ 342 261 182 340
+ 1761 44 2 1 7 4
+ 343 210 261 342
+ 1762 44 2 1 7 4
+ 341 263 210 343
+ 1763 44 2 1 7 4
+ 320 265 263 341
+ 1764 44 2 1 7 4
+ 193 339 265 320
+ 1765 44 2 1 7 4
+ 474 364 436 458
+ 1771 44 2 1 7 4
+ 489 374 364 474
+ 1777 44 2 1 7 4
+ 509 394 374 489
+ 1783 44 2 1 7 4
+ 513 401 394 509
+ 1789 44 2 1 7 4
+ 523 445 401 513
+ 1795 44 2 1 7 4
+ 464 448 445 523
+ 1801 44 2 1 7 4
+ 71 20 157 28
+ 1802 44 2 1 7 4
+ 246 245 294 339
+ 1803 44 2 1 7 4
+ 427 426 506 448
+ 1809 44 2 1 7 4
+ 34 33 6 7
+ 1815 41 2 1 7 3
+ 506 448 445
+ 1816 41 2 1 7 3
+ 294 339 265
+ 1822 41 2 1 7 3
+ 449 450 438
+ 1823 41 2 1 7 3
+ 304 305 180
+ 1829 41 2 1 7 3
+ 437 449 354
+ 1830 41 2 1 7 3
+ 277 304 172
+ 1836 41 2 1 7 3
+ 380 482 378
+ 1837 41 2 1 7 3
+ 206 325 195
+ 1838 41 2 1 7 3
+ 12 44 11
+ 1843 41 2 1 7 3
+ 370 481 368
+ 1844 41 2 1 7 3
+ 194 315 191
+ 1845 41 2 1 7 3
+ 10 47 9
+ 1846 41 2 1 7 3
+ 43 46 47
+ 1847 41 2 1 7 3
+ 35 110 34
+ 1849 41 2 1 7 3
+ 36 119 35
+ 1850 41 2 1 7 3
+ 131 123 119
+ 1851 41 2 1 7 3
+ 239 297 266
+ 1852 41 2 1 7 3
+ 418 502 446
+ 1863 41 2 1 7 3
+ 451 458 440
+ 1864 41 2 1 7 3
+ 312 319 185
+ 1870 41 2 1 7 3
+ 439 451 358
+ 1871 41 2 1 7 3
+ 289 312 176
+ 1877 41 2 1 7 3
+ 400 500 396
+ 1878 41 2 1 7 3
+ 219 331 214
+ 1879 41 2 1 7 3
+ 63 94 62
+ 1884 41 2 1 7 3
+ 392 494 382
+ 1885 41 2 1 7 3
+ 213 322 208
+ 1886 41 2 1 7 3
+ 61 97 60
+ 1887 41 2 1 7 3
+ 93 96 97
+ 1888 41 2 1 7 3
+ 85 114 84
+ 1890 41 2 1 7 3
+ 86 121 85
+ 1891 41 2 1 7 3
+ 132 129 121
+ 1892 41 2 1 7 3
+ 256 303 267
+ 1893 41 2 1 7 3
+ 430 511 447
+ 1899 41 2 1 7 3
+ 193 321 320
+ 1900 41 2 1 7 3
+ 464 549 523
+ -1
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Module : PatchQt
+// File : qfiledialogP.cxx
+// Description : the patch for Qt's QFileDialog class (qfiledialog.cpp)
+/////////////////////////////////////////////////////////////////////////////
+
+/****************************************************************************
+** $Id$
+**
+** Implementation of QFileDialog class
+**
+** Created : 950429
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the dialogs module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qplatformdefs.h"
+
+// Solaris redefines connect -> __xnet_connect with _XOPEN_SOURCE_EXTENDED.
+#if defined(connect)
+#undef connect
+#endif
+
+#include "qfiledialogP.h"
+
+#ifndef QT_NO_FILEDIALOG
+
+#include "qlineedit.h"
+#include "qcombobox.h"
+#include "qlistview.h"
+#include "qlistbox.h"
+#include "qlabel.h"
+#include "qpushbutton.h"
+#include "qtoolbutton.h"
+#include "qmessagebox.h"
+#include "qapplication.h"
+#include "private/qapplication_p.h"
+#include "qlayout.h"
+#include "qbitmap.h"
+#include "qpopupmenu.h"
+#include "qwidgetstack.h"
+#include "qbuttongroup.h"
+#include "qptrvector.h"
+#include "qregexp.h"
+#include "qstrlist.h"
+#include "qtimer.h"
+#include "qvbox.h"
+#include "qhbox.h"
+#include "qtooltip.h"
+#include "qheader.h"
+#include "qdragobject.h"
+#include "qmime.h"
+#include "qprogressbar.h"
+#include "qfile.h"
+#include "qcstring.h"
+#include "qobjectlist.h"
+#include "qcheckbox.h"
+#include "qsplitter.h"
+#include "qmap.h"
+#include "qnetworkprotocol.h"
+#include "qsemimodal.h"
+#include "qpainter.h"
+#include "qcleanuphandler.h"
+#include "qstyle.h"
+#include "qcursor.h"
+
+#ifndef Q_OS_TEMP
+#include <time.h>
+#endif
+#include <ctype.h>
+#include <stdlib.h>
+
+#ifdef Q_WS_MAC
+#include "qt_mac.h"
+#undef check
+#endif
+
+#ifdef Q_WS_WIN
+#include "qt_windows.h"
+#endif
+
+/* XPM */
+static const char * const start_xpm[]={
+ "16 15 8 1",
+ "a c #cec6bd",
+ "# c #000000",
+ "e c #ffff00",
+ "b c #999999",
+ "f c #cccccc",
+ "d c #dcdcdc",
+ "c c #ffffff",
+ ". c None",
+ ".....######aaaaa",
+ "...bb#cccc##aaaa",
+ "..bcc#cccc#d#aaa",
+ ".bcef#cccc#dd#aa",
+ ".bcfe#cccc#####a",
+ ".bcef#ccccccccc#",
+ "bbbbbbbbbbbbccc#",
+ "bccccccccccbbcc#",
+ "bcefefefefee#bc#",
+ ".bcefefefefef#c#",
+ ".bcfefefefefe#c#",
+ "..bcfefefefeeb##",
+ "..bbbbbbbbbbbbb#",
+ "...#############",
+ "................"};
+
+/* XPM */
+static const char * const end_xpm[]={
+ "16 15 9 1",
+ "d c #a0a0a0",
+ "c c #c3c3c3",
+ "# c #cec6bd",
+ ". c #000000",
+ "f c #ffff00",
+ "e c #999999",
+ "g c #cccccc",
+ "b c #ffffff",
+ "a c None",
+ "......####aaaaaa",
+ ".bbbb..###aaaaaa",
+ ".bbbb.c.##aaaaaa",
+ ".bbbb....ddeeeea",
+ ".bbbbbbb.bbbbbe.",
+ ".bbbbbbb.bcfgfe.",
+ "eeeeeeeeeeeeefe.",
+ "ebbbbbbbbbbeege.",
+ "ebfgfgfgfgff.ee.",
+ "aebfgfgfgfgfg.e.",
+ "aebgfgfgfgfgf.e.",
+ "aaebgfgfgfgffe..",
+ "aaeeeeeeeeeeeee.",
+ "aaa.............",
+ "aaaaaaaaaaaaaaaa"};
+
+/* XPM */
+static const char* const open_xpm[]={
+ "16 16 6 1",
+ ". c None",
+ "b c #ffff00",
+ "d c #000000",
+ "* c #999999",
+ "c c #cccccc",
+ "a c #ffffff",
+ "................",
+ "................",
+ "...*****........",
+ "..*aaaaa*.......",
+ ".*abcbcba******.",
+ ".*acbcbcaaaaaa*d",
+ ".*abcbcbcbcbcb*d",
+ "*************b*d",
+ "*aaaaaaaaaa**c*d",
+ "*abcbcbcbcbbd**d",
+ ".*abcbcbcbcbcd*d",
+ ".*acbcbcbcbcbd*d",
+ "..*acbcbcbcbb*dd",
+ "..*************d",
+ "...ddddddddddddd",
+ "................"};
+
+/* XPM */
+static const char * const link_dir_xpm[]={
+ "16 16 10 1",
+ "h c #808080",
+ "g c #a0a0a0",
+ "d c #000000",
+ "b c #ffff00",
+ "f c #303030",
+ "# c #999999",
+ "a c #cccccc",
+ "e c #585858",
+ "c c #ffffff",
+ ". c None",
+ "................",
+ "................",
+ "..#####.........",
+ ".#ababa#........",
+ "#abababa######..",
+ "#cccccccccccc#d.",
+ "#cbababababab#d.",
+ "#cabababababa#d.",
+ "#cbababdddddddd.",
+ "#cababadccccccd.",
+ "#cbababdcececcd.",
+ "#cababadcefdfcd.",
+ "#cbababdccgdhcd.",
+ "#######dccchccd.",
+ ".dddddddddddddd.",
+ "................"};
+
+/* XPM */
+static const char * const link_file_xpm[]={
+ "16 16 10 1",
+ "h c #808080",
+ "g c #a0a0a0",
+ "d c #c3c3c3",
+ ". c #7f7f7f",
+ "c c #000000",
+ "b c #bfbfbf",
+ "f c #303030",
+ "e c #585858",
+ "a c #ffffff",
+ "# c None",
+ "################",
+ "..........######",
+ ".aaaaaaaab.#####",
+ ".aaaaaaaaba.####",
+ ".aaaaaaaacccc###",
+ ".aaaaaaaaaabc###",
+ ".aaaaaaaaaabc###",
+ ".aaaaaaaaaadc###",
+ ".aaaaaaaaaadc###",
+ ".aaaacccccccc###",
+ ".aaaacaaaaaac###",
+ ".aaaacaeaeaac###",
+ ".aaaacaefcfac###",
+ ".aaaacaagchac###",
+ ".ddddcaaahaac###",
+ "ccccccccccccc###"};
+
+/* XPM */
+static const char* const file_xpm[]={
+ "16 16 5 1",
+ ". c #7f7f7f",
+ "# c None",
+ "c c #000000",
+ "b c #bfbfbf",
+ "a c #ffffff",
+ "################",
+ "..........######",
+ ".aaaaaaaab.#####",
+ ".aaaaaaaaba.####",
+ ".aaaaaaaacccc###",
+ ".aaaaaaaaaabc###",
+ ".aaaaaaaaaabc###",
+ ".aaaaaaaaaabc###",
+ ".aaaaaaaaaabc###",
+ ".aaaaaaaaaabc###",
+ ".aaaaaaaaaabc###",
+ ".aaaaaaaaaabc###",
+ ".aaaaaaaaaabc###",
+ ".aaaaaaaaaabc###",
+ ".bbbbbbbbbbbc###",
+ "ccccccccccccc###"};
+
+/* XPM */
+static const char * const closed_xpm[]={
+ "16 16 6 1",
+ ". c None",
+ "b c #ffff00",
+ "d c #000000",
+ "* c #999999",
+ "a c #cccccc",
+ "c c #ffffff",
+ "................",
+ "................",
+ "..*****.........",
+ ".*ababa*........",
+ "*abababa******..",
+ "*cccccccccccc*d.",
+ "*cbababababab*d.",
+ "*cabababababa*d.",
+ "*cbababababab*d.",
+ "*cabababababa*d.",
+ "*cbababababab*d.",
+ "*cabababababa*d.",
+ "*cbababababab*d.",
+ "**************d.",
+ ".dddddddddddddd.",
+ "................"};
+
+
+/* XPM */
+static const char* const cdtoparent_xpm[]={
+ "15 13 3 1",
+ ". c None",
+ "* c #000000",
+ "a c #ffff99",
+ "..*****........",
+ ".*aaaaa*.......",
+ "***************",
+ "*aaaaaaaaaaaaa*",
+ "*aaaa*aaaaaaaa*",
+ "*aaa***aaaaaaa*",
+ "*aa*****aaaaaa*",
+ "*aaaa*aaaaaaaa*",
+ "*aaaa*aaaaaaaa*",
+ "*aaaa******aaa*",
+ "*aaaaaaaaaaaaa*",
+ "*aaaaaaaaaaaaa*",
+ "***************"};
+
+
+/* XPM */
+static const char* const newfolder_xpm[] = {
+ "15 14 4 1",
+ " c None",
+ ". c #000000",
+ "+ c #FFFF00",
+ "@ c #FFFFFF",
+ " . ",
+ " ",
+ " . ",
+ " . . ",
+ " .... . . . ",
+ " .+@+@. . . ",
+ ".......... . .",
+ ".@+@+@+@+@.. ",
+ ".+@+@+@+@+. . ",
+ ".@+@+@+@+@. . ",
+ ".+@+@+@+@+. ",
+ ".@+@+@+@+@. ",
+ ".+@+@+@+@+. ",
+ "........... "};
+
+/* XPM */
+static const char* const detailedview_xpm[]={
+ "14 11 3 1",
+ ". c None",
+ "* c #000000",
+ "a c #000099",
+ ".****.***.***.",
+ "..............",
+ "aaaaaaaaaaaaaa",
+ "..............",
+ ".****.***.***.",
+ "..............",
+ ".****.***.***.",
+ "..............",
+ ".****.***.***.",
+ "..............",
+ ".****.***.***."};
+
+/* XPM */
+static const char* const previewinfoview_xpm[]={
+ "13 13 4 1",
+ ". c #00007f",
+ "a c black",
+ "# c #cec6bd",
+ "b c #000000",
+ "..#####aaaaaa",
+ ".#.#bb#a#####",
+ "...####a#bbb#",
+ "#######a#####",
+ "#######a#bb##",
+ "..#####a#####",
+ ".#.#bb#a#bbb#",
+ "...####a#####",
+ "#######a#bb##",
+ "#######a#####",
+ "..#####a#bbb#",
+ ".#.#bb#a#####",
+ "...####aaaaaa"};
+
+/* XPM */
+static const char* const previewcontentsview_xpm[]={
+ "14 13 5 1",
+ ". c #00007f",
+ "a c black",
+ "c c #7f007f",
+ "# c #cec6bd",
+ "b c #000000",
+ "..#####aaaaaaa",
+ ".#.#bb#a#####a",
+ "...####a#ccc#a",
+ "#######a#ccc#a",
+ "#######a#####a",
+ "..#####a#bbb#a",
+ ".#.#bb#a#####a",
+ "...####a#bbb#a",
+ "#######a#####a",
+ "#######a#bbb#a",
+ "..#####a#####a",
+ ".#.#bb#a#####a",
+ "...####aaaaaaa"};
+
+/* XPM */
+static const char* const mclistview_xpm[]={
+ "15 11 4 1",
+ "* c None",
+ "b c #000000",
+ ". c #000099",
+ "a c #ffffff",
+ "...*****...****",
+ ".a.*bbb*.a.*bbb",
+ "...*****...****",
+ "***************",
+ "...*****...****",
+ ".a.*bbb*.a.*bbb",
+ "...*****...****",
+ "***************",
+ "...*****...****",
+ ".a.*bbb*.a.*bbb",
+ "...*****...****"};
+
+/* XPM */
+static const char * const back_xpm [] = {
+ "13 11 3 1",
+ "a c #00ffff",
+ "# c #000000",
+ ". c None",
+ ".....#.......",
+ "....##.......",
+ "...#a#.......",
+ "..#aa########",
+ ".#aaaaaaaaaa#",
+ "#aaaaaaaaaaa#",
+ ".#aaaaaaaaaa#",
+ "..#aa########",
+ "...#a#.......",
+ "....##.......",
+ ".....#......."};
+
+static QPixmap * openFolderIcon = 0;
+static QPixmap * closedFolderIcon = 0;
+static QPixmap * detailViewIcon = 0;
+static QPixmap * multiColumnListViewIcon = 0;
+static QPixmap * cdToParentIcon = 0;
+static QPixmap * newFolderIcon = 0;
+static QPixmap * fifteenTransparentPixels = 0;
+static QPixmap * symLinkDirIcon = 0;
+static QPixmap * symLinkFileIcon = 0;
+static QPixmap * fileIcon = 0;
+static QPixmap * startCopyIcon = 0;
+static QPixmap * endCopyIcon = 0;
+static QPixmap * previewContentsViewIcon = 0;
+static QPixmap * previewInfoViewIcon = 0;
+static QPixmap *goBackIcon = 0;
+static QFileIconProviderP * fileIconProvider = 0;
+static QSize *lastSize = 0;
+static QString * workingDirectory = 0;
+
+static bool bShowHiddenFiles = FALSE;
+static int sortFilesBy = (int)QDir::Name;
+static bool sortAscending = TRUE;
+static bool detailViewMode = FALSE;
+
+static QCleanupHandler<QPixmap> qfd_cleanup_pixmap;
+static QCleanupHandler<QSize> qfd_cleanup_size;
+static QCleanupHandler<QString> qfd_cleanup_string;
+
+static bool isDirectoryMode( int m )
+{
+ return m == QFileDialogP::Directory || m == QFileDialogP::DirectoryOnly;
+}
+
+#if defined(Q_WS_WIN)
+
+class QWindowsIconProvider : public QFileIconProviderP
+{
+public:
+ QWindowsIconProvider( QObject *parent=0, const char *name=0 );
+ ~QWindowsIconProvider();
+
+ const QPixmap * pixmap( const QFileInfo &fi );
+
+private:
+ QPixmap defaultFolder;
+ QPixmap defaultFile;
+ QPixmap defaultExe;
+ QPixmap pix;
+ int pixw, pixh;
+ QMap< QString, QPixmap > cache;
+};
+#endif
+
+static void makeVariables() {
+ if ( !openFolderIcon ) {
+ workingDirectory = new QString( QDir::currentDirPath() );
+ qfd_cleanup_string.add( &workingDirectory );
+
+ openFolderIcon = new QPixmap( (const char **)open_xpm);
+ qfd_cleanup_pixmap.add( &openFolderIcon );
+ symLinkDirIcon = new QPixmap( (const char **)link_dir_xpm);
+ qfd_cleanup_pixmap.add( &symLinkDirIcon );
+ symLinkFileIcon = new QPixmap( (const char **)link_file_xpm);
+ qfd_cleanup_pixmap.add( &symLinkFileIcon );
+ fileIcon = new QPixmap( (const char **)file_xpm);
+ qfd_cleanup_pixmap.add( &fileIcon );
+ closedFolderIcon = new QPixmap( (const char **)closed_xpm);
+ qfd_cleanup_pixmap.add( &closedFolderIcon );
+ detailViewIcon = new QPixmap( (const char **)detailedview_xpm);
+ qfd_cleanup_pixmap.add( &detailViewIcon );
+ multiColumnListViewIcon = new QPixmap( (const char **)mclistview_xpm);
+ qfd_cleanup_pixmap.add( &multiColumnListViewIcon );
+ cdToParentIcon = new QPixmap( (const char **)cdtoparent_xpm);
+ qfd_cleanup_pixmap.add( &cdToParentIcon );
+ newFolderIcon = new QPixmap( (const char **)newfolder_xpm);
+ qfd_cleanup_pixmap.add( &newFolderIcon );
+ previewInfoViewIcon
+ = new QPixmap( (const char **)previewinfoview_xpm );
+ qfd_cleanup_pixmap.add( &previewInfoViewIcon );
+ previewContentsViewIcon
+ = new QPixmap( (const char **)previewcontentsview_xpm );
+ qfd_cleanup_pixmap.add( &previewContentsViewIcon );
+ startCopyIcon = new QPixmap( (const char **)start_xpm );
+ qfd_cleanup_pixmap.add( &startCopyIcon );
+ endCopyIcon = new QPixmap( (const char **)end_xpm );
+ qfd_cleanup_pixmap.add( &endCopyIcon );
+ goBackIcon = new QPixmap( (const char **)back_xpm );
+ qfd_cleanup_pixmap.add( &goBackIcon );
+ fifteenTransparentPixels = new QPixmap( closedFolderIcon->width(), 1 );
+ qfd_cleanup_pixmap.add( &fifteenTransparentPixels );
+ QBitmap m( fifteenTransparentPixels->width(), 1 );
+ m.fill( Qt::color0 );
+ fifteenTransparentPixels->setMask( m );
+ bShowHiddenFiles = FALSE;
+ sortFilesBy = (int)QDir::Name;
+ detailViewMode = FALSE;
+#if defined(Q_WS_WIN)
+ if ( !fileIconProvider )
+ fileIconProvider = new QWindowsIconProvider( qApp );
+#endif
+ }
+}
+
+QFDProgressAnimation::QFDProgressAnimation( QWidget *parent )
+ : QWidget( parent, "qt_progressanimation" )
+{
+ setFixedSize( 300, 50 );
+ step = -1;
+ next();
+ timer = new QTimer( this );
+ connect( timer, SIGNAL( timeout() ),
+ this, SLOT( next() ) );
+}
+
+void QFDProgressAnimation::start()
+{
+ timer->start( 150, FALSE );
+}
+
+void QFDProgressAnimation::next()
+{
+ ++step;
+ if ( step > 10 )
+ step = 0;
+ repaint();
+}
+
+void QFDProgressAnimation::paintEvent( QPaintEvent * )
+{
+ erase();
+
+ QPainter p;
+ p.begin( this );
+ if ( step == 0 ) {
+ p.drawPixmap( 5, ( height() - startCopyIcon->height() ) / 2,
+ *startCopyIcon );
+ p.drawPixmap( width() - 5 - openFolderIcon->width(),
+ ( height() - openFolderIcon->height() ) / 2 , *openFolderIcon );
+ } else if ( step == 10 ) {
+ p.drawPixmap( 5, ( height() - openFolderIcon->height() ) / 2,
+ *openFolderIcon );
+ p.drawPixmap( width() - 5 - endCopyIcon->width(),
+ ( height() - endCopyIcon->height() ) / 2 , *endCopyIcon );
+ } else {
+ p.drawPixmap( 5, ( height() - openFolderIcon->height() ) / 2,
+ *openFolderIcon );
+ p.drawPixmap( width() - 5 - openFolderIcon->width(),
+ ( height() - openFolderIcon->height() ) / 2 , *openFolderIcon );
+ int x = 10 + openFolderIcon->width();
+ int w = width() - 2 * x;
+ int s = w / 9;
+ p.drawPixmap( x + s * step, ( height() - fileIcon->height() ) / 2 - fileIcon->height(),
+ *fileIcon );
+ }
+}
+
+QFDProgressDialog::QFDProgressDialog( QWidget *parent, const QString &fn, int steps )
+ : QDialog( parent, "", TRUE )
+{
+#ifndef QT_NO_WIDGET_TOPEXTRA
+ setCaption( QFileDialogP::tr( "Copy or Move a File" ) );
+#endif
+ QVBoxLayout *layout = new QVBoxLayout( this );
+ layout->setSpacing( 5 );
+ layout->setMargin( 5 );
+
+ animation = new QFDProgressAnimation( this );
+ layout->addWidget( animation );
+
+ layout->addWidget( new QLabel( QFileDialogP::tr( "Read: %1" ).arg( fn ),
+ this, "qt_read_lbl" ) );
+ readBar = new QProgressBar( steps, this, "qt_readbar" );
+ readBar->reset();
+ readBar->setProgress( 0 );
+ layout->addWidget( readBar );
+ writeLabel = new QLabel( QFileDialogP::tr( "Write: %1" ).arg( QString::null ),
+ this, "qt_write_lbl" );
+ layout->addWidget( writeLabel );
+ writeBar = new QProgressBar( steps, this, "qt_writebar" );
+ writeBar->reset();
+ writeBar->setProgress( 0 );
+ layout->addWidget( writeBar );
+
+ QPushButton *b = new QPushButton( QFileDialogP::tr( "Cancel" ), this,
+ "qt_cancel_btn" );
+ b->setFixedSize( b->sizeHint() );
+ layout->addWidget( b );
+ connect( b, SIGNAL( clicked() ),
+ this, SIGNAL( cancelled() ) );
+
+ animation->start();
+}
+
+void QFDProgressDialog::setReadProgress( int p )
+{
+ readBar->setProgress( p );
+}
+
+void QFDProgressDialog::setWriteProgress( int p )
+{
+ writeBar->setProgress( p );
+}
+
+void QFDProgressDialog::setWriteLabel( const QString &s )
+{
+ writeLabel->setText( QFileDialogP::tr( "Write: %1" ).arg( s ) );
+}
+
+/************************************************************************
+ *
+ * Private QFileDialogP members
+ *
+ ************************************************************************/
+
+class QFileDialogPrivate {
+public:
+ ~QFileDialogPrivate();
+
+ QStringList history;
+
+ bool geometryDirty;
+ QComboBox * paths;
+ QComboBox * types;
+ QLabel * pathL;
+ QLabel * fileL;
+ QLabel * typeL;
+
+ QVBoxLayout * topLevelLayout;
+ QHBoxLayout *buttonLayout, *leftLayout, *rightLayout;
+ QPtrList<QHBoxLayout> extraWidgetsLayouts;
+ QPtrList<QLabel> extraLabels;
+ QPtrList<QWidget> extraWidgets;
+ QPtrList<QWidget> extraButtons;
+ QPtrList<QButton> toolButtons;
+
+ QWidgetStack * stack;
+
+ QToolButton * cdToParent, *newFolder, * detailView, * mcView,
+ *previewInfo, *previewContents, *goBack;
+ QButtonGroup * modeButtons;
+
+ QString currentFileName;
+ QListViewItem *last;
+
+ struct File: public QListViewItem {
+ File( QFileDialogPrivate * dlgp,
+ const QUrlInfo * fi, QListViewItem * parent )
+ : QListViewItem( parent, dlgp->last ), info( *fi ), d(dlgp), i( 0 ), hasMimePixmap( FALSE )
+ { setup(); dlgp->last = this; }
+ File( QFileDialogPrivate * dlgp,
+ const QUrlInfo * fi, QListView * parent )
+ : QListViewItem( parent, dlgp->last ), info( *fi ), d(dlgp), i( 0 ), hasMimePixmap( FALSE )
+ { setup(); dlgp->last = this; }
+ File( QFileDialogPrivate * dlgp,
+ const QUrlInfo * fi, QListView * parent, QListViewItem * after )
+ : QListViewItem( parent, after ), info( *fi ), d(dlgp), i( 0 ), hasMimePixmap( FALSE )
+ { setup(); if ( !nextSibling() ) dlgp->last = this; }
+ ~File();
+
+ QString text( int column ) const;
+ const QPixmap * pixmap( int ) const;
+
+ QUrlInfo info;
+ QFileDialogPrivate * d;
+ QListBoxItem *i;
+ bool hasMimePixmap;
+ };
+
+ class MCItem: public QListBoxItem {
+ public:
+ MCItem( QListBox *, QListViewItem * item );
+ MCItem( QListBox *, QListViewItem * item, QListBoxItem *after );
+ QString text() const;
+ const QPixmap *pixmap() const;
+ int height( const QListBox * ) const;
+ int width( const QListBox * ) const;
+ void paint( QPainter * );
+ QListViewItem * i;
+ };
+
+ class UrlInfoList : public QPtrList<QUrlInfo> {
+ public:
+ UrlInfoList() { setAutoDelete( TRUE ); }
+ int compareItems( QPtrCollection::Item n1, QPtrCollection::Item n2 ) {
+ if ( !n1 || !n2 )
+ return 0;
+
+ QUrlInfo *i1 = ( QUrlInfo *)n1;
+ QUrlInfo *i2 = ( QUrlInfo *)n2;
+
+ if ( i1->isDir() && !i2->isDir() )
+ return -1;
+ if ( !i1->isDir() && i2->isDir() )
+ return 1;
+
+ if ( i1->name() == ".." )
+ return -1;
+ if ( i2->name() == ".." )
+ return 1;
+
+#if defined(Q_OS_WIN32)
+ if ( sortFilesBy == QDir::Name ) {
+ QString name1 = i1->name().lower();
+ QString name2 = i2->name().lower();
+ return name1.compare( name2 );
+ }
+#endif
+ if ( QUrlInfo::equal( *i1, *i2, sortFilesBy ) )
+ return 0;
+ else if ( QUrlInfo::greaterThan( *i1, *i2, sortFilesBy ) )
+ return 1;
+ else if ( QUrlInfo::lessThan( *i1, *i2, sortFilesBy ) )
+ return -1;
+ // can't happen...
+ return 0;
+ }
+ QUrlInfo *operator[]( int i ) {
+ return at( i );
+ }
+ };
+
+ UrlInfoList sortedList;
+ QPtrList<File> pendingItems;
+
+ QFileListBox * moreFiles;
+
+ QFileDialogP::Mode mode;
+
+ QString rw;
+ QString ro;
+ QString wo;
+ QString inaccessible;
+
+ QString symLinkToFile;
+ QString file;
+ QString symLinkToDir;
+ QString dir;
+ QString symLinkToSpecial;
+ QString special;
+ QWidgetStack *preview;
+ bool infoPreview, contentsPreview;
+ QSplitter *splitter;
+ QUrlOperator url, oldUrl;
+ QWidget *infoPreviewWidget, *contentsPreviewWidget;
+ QFilePreviewP *infoPreviewer, *contentsPreviewer;
+ bool hadDotDot;
+
+ bool ignoreNextKeyPress;
+ // ignores the next refresh operation in case the user forced a selection
+ bool ignoreNextRefresh;
+ QFDProgressDialog *progressDia;
+ bool checkForFilter;
+ bool ignoreReturn;
+ bool ignoreStop;
+
+ QTimer *mimeTypeTimer;
+ const QNetworkOperation *currListChildren;
+
+ // this is similar to QUrl::encode but does encode "*" and
+ // doesn't encode whitespaces
+ static QString encodeFileName( const QString& fName ) {
+
+ QString newStr;
+ QCString cName = fName.utf8();
+ const QCString sChars(
+#ifdef Q_WS_WIN
+ "#%"
+#else
+ "<>#@\"&%$:,;?={}|^~[]\'`\\*"
+#endif
+ );
+
+ int len = cName.length();
+ if ( !len )
+ return QString::null;
+ for ( int i = 0; i < len ;++i ) {
+ uchar inCh = (uchar)cName[ i ];
+ if ( inCh >= 128 || sChars.contains(inCh) )
+ {
+ newStr += QChar( '%' );
+ ushort c = inCh / 16;
+ c += c > 9 ? 'A' - 10 : '0';
+ newStr += c;
+ c = inCh % 16;
+ c += c > 9 ? 'A' - 10 : '0';
+ newStr += c;
+ } else {
+ newStr += inCh;
+ }
+ }
+ return newStr;
+ }
+
+};
+
+QFileDialogPrivate::~QFileDialogPrivate()
+{
+ delete modeButtons;
+}
+
+
+
+/************************************************************************
+ *
+ * Internal class QRenameEdit
+ *
+ ************************************************************************/
+
+void QRenameEdit::keyPressEvent( QKeyEvent *e )
+{
+ if ( e->key() == Key_Escape )
+ emit escapePressed();
+ else
+ QLineEdit::keyPressEvent( e );
+ e->accept();
+}
+
+void QRenameEdit::focusOutEvent( QFocusEvent * )
+{
+ emit escapePressed();
+}
+
+/************************************************************************
+ *
+ * Internal class QFileListBox
+ *
+ ************************************************************************/
+
+QFileListBox::QFileListBox( QWidget *parent, QFileDialogP *dlg )
+ : QListBox( parent, "filelistbox" ), filedialog( dlg ),
+ renaming( FALSE ), renameItem( 0 ), mousePressed( FALSE ),
+ firstMousePressEvent( TRUE )
+{
+ changeDirTimer = new QTimer( this );
+ QVBox *box = new QVBox( viewport(), "qt_vbox" );
+ box->setFrameStyle( QFrame::Box | QFrame::Plain );
+ lined = new QRenameEdit( box );
+ lined->setFixedHeight( lined->sizeHint().height() );
+ box->hide();
+ box->setBackgroundMode( PaletteBase );
+ renameTimer = new QTimer( this );
+ connect( lined, SIGNAL( returnPressed() ),
+ this, SLOT (rename() ) );
+ connect( lined, SIGNAL( escapePressed() ),
+ this, SLOT( cancelRename() ) );
+ connect( renameTimer, SIGNAL( timeout() ),
+ this, SLOT( doubleClickTimeout() ) );
+ connect( changeDirTimer, SIGNAL( timeout() ),
+ this, SLOT( changeDirDuringDrag() ) );
+ connect( this, SIGNAL( contentsMoving( int, int ) ),
+ this, SLOT( contentsMoved( int, int ) ) );
+ viewport()->setAcceptDrops( TRUE );
+ dragItem = 0;
+}
+
+void QFileListBox::show()
+{
+ setBackgroundMode( PaletteBase );
+ viewport()->setBackgroundMode( PaletteBase );
+ QListBox::show();
+}
+
+void QFileListBox::keyPressEvent( QKeyEvent *e )
+{
+ if ( ( e->key() == Key_Enter ||
+ e->key() == Key_Return ) &&
+ renaming )
+ return;
+
+ QString keyPressed = ((QKeyEvent *)e)->text().lower();
+ QChar keyChar = keyPressed[0];
+ if ( keyChar.isLetterOrNumber() ) {
+ QListBoxItem * i = 0;
+ if ( currentItem() )
+ i = item( currentItem() );
+ else
+ i = firstItem();
+ if ( i->next() )
+ i = i->next();
+ else
+ i = firstItem();
+ while ( i != item( currentItem() ) ) {
+ QString it = text( index( i ) );
+ if ( it[0].lower() == keyChar ) {
+ clearSelection();
+ setCurrentItem( i );
+ } else {
+ if ( i->next() )
+ i = i->next();
+ else
+ i = firstItem();
+ }
+ }
+ }
+ cancelRename();
+ QListBox::keyPressEvent( e );
+}
+
+void QFileListBox::viewportMousePressEvent( QMouseEvent *e )
+{
+ pressPos = e->pos();
+ mousePressed = FALSE;
+
+ bool didRename = renaming;
+
+ cancelRename();
+ if ( !hasFocus() && !viewport()->hasFocus() )
+ setFocus();
+
+ if ( e->button() != LeftButton ) {
+ QListBox::viewportMousePressEvent( e );
+ firstMousePressEvent = FALSE;
+ return;
+ }
+
+ int i = currentItem();
+ bool wasSelected = FALSE;
+ if ( i != -1 )
+ wasSelected = item( i )->isSelected();
+ QListBox::viewportMousePressEvent( e );
+
+ QFileDialogPrivate::MCItem *i1 = (QFileDialogPrivate::MCItem*)item( currentItem() );
+ if ( i1 )
+ mousePressed = !( (QFileDialogPrivate::File*)i1->i )->info.isDir();
+
+ if ( itemAt( e->pos() ) != item( i ) ) {
+ firstMousePressEvent = FALSE;
+ return;
+ }
+
+ if ( !firstMousePressEvent && !didRename && i == currentItem() && currentItem() != -1 &&
+ wasSelected && filedialog->mode() != QFileDialogP::ExistingFiles &&
+ QUrlInfo( filedialog->d->url, "." ).isWritable() && item( currentItem() )->text() != ".." ) {
+ renameTimer->start( QApplication::doubleClickInterval(), TRUE );
+ renameItem = item( i );
+ }
+
+ firstMousePressEvent = FALSE;
+}
+
+void QFileListBox::viewportMouseReleaseEvent( QMouseEvent *e )
+{
+ dragItem = 0;
+ QListBox::viewportMouseReleaseEvent( e );
+ mousePressed = FALSE;
+}
+
+void QFileListBox::viewportMouseDoubleClickEvent( QMouseEvent *e )
+{
+ renameTimer->stop();
+ QListBox::viewportMouseDoubleClickEvent( e );
+}
+
+void QFileListBox::viewportMouseMoveEvent( QMouseEvent *e )
+{
+ if ( !dragItem )
+ dragItem = itemAt( e->pos() );
+ renameTimer->stop();
+#ifndef QT_NO_DRAGANDDROP
+ if ( ( pressPos - e->pos() ).manhattanLength() > QApplication::startDragDistance() && mousePressed ) {
+ QListBoxItem *item = dragItem;
+ dragItem = 0;
+ if ( item ) {
+ if ( !itemRect( item ).contains( e->pos() ) )
+ return;
+ QUriDrag* drag = new QUriDrag( viewport() );
+ drag->setUnicodeUris( filedialog->selectedFiles() );
+
+ if ( lined->parentWidget()->isVisible() )
+ cancelRename();
+
+ connect( drag, SIGNAL( destroyed() ),
+ this, SLOT( dragObjDestroyed() ) );
+ drag->drag();
+
+ mousePressed = FALSE;
+ }
+ } else
+#endif
+ {
+ QListBox::viewportMouseMoveEvent( e );
+ }
+
+}
+
+void QFileListBox::dragObjDestroyed()
+{
+#ifndef QT_NO_DRAGANDDROP
+ //#######
+ //filedialog->rereadDir();
+#endif
+}
+
+#ifndef QT_NO_DRAGANDDROP
+void QFileListBox::viewportDragEnterEvent( QDragEnterEvent *e )
+{
+ startDragUrl = filedialog->d->url;
+ startDragDir = filedialog->dirPath();
+ currDropItem = 0;
+
+ if ( !QUriDrag::canDecode( e ) ) {
+ e->ignore();
+ return;
+ }
+
+ QStringList l;
+ QUriDrag::decodeLocalFiles( e, l );
+ urls = (int)l.count();
+
+ if ( acceptDrop( e->pos(), e->source() ) ) {
+ e->accept();
+ setCurrentDropItem( e->pos() );
+ } else {
+ e->ignore();
+ setCurrentDropItem( QPoint( -1, -1 ) );
+ }
+
+ oldDragPos = e->pos();
+}
+
+void QFileListBox::viewportDragMoveEvent( QDragMoveEvent *e )
+{
+ if ( acceptDrop( e->pos(), e->source() ) ) {
+ switch ( e->action() ) {
+ case QDropEvent::Copy:
+ e->acceptAction();
+ break;
+ case QDropEvent::Move:
+ e->acceptAction();
+ break;
+ case QDropEvent::Link:
+ break;
+ default:
+ break;
+ }
+ if ( oldDragPos != e->pos() )
+ setCurrentDropItem( e->pos() );
+ } else {
+ changeDirTimer->stop();
+ e->ignore();
+ setCurrentDropItem( QPoint( -1, -1 ) );
+ }
+
+ oldDragPos = e->pos();
+}
+
+void QFileListBox::viewportDragLeaveEvent( QDragLeaveEvent * )
+{
+ changeDirTimer->stop();
+ setCurrentDropItem( QPoint( -1, -1 ) );
+//########
+// if ( startDragDir != filedialog->d->url )
+// filedialog->setUrl( startDragUrl );
+}
+
+void QFileListBox::viewportDropEvent( QDropEvent *e )
+{
+ changeDirTimer->stop();
+
+ if ( !QUriDrag::canDecode( e ) ) {
+ e->ignore();
+ return;
+ }
+
+ QStrList l;
+ QUriDrag::decode( e, l );
+
+ bool move = e->action() == QDropEvent::Move;
+// bool supportAction = move || e->action() == QDropEvent::Copy;
+
+ QUrlOperator dest;
+ if ( currDropItem )
+ dest = QUrlOperator( filedialog->d->url, QFileDialogPrivate::encodeFileName( currDropItem->text() ) );
+ else
+ dest = filedialog->d->url;
+ QStringList lst;
+ for ( uint i = 0; i < l.count(); ++i ) {
+ lst << l.at( i );
+ }
+
+ filedialog->d->url.copy( lst, dest, move );
+
+ // ##### what is supportAction for?
+ e->acceptAction();
+ currDropItem = 0;
+}
+
+bool QFileListBox::acceptDrop( const QPoint &pnt, QWidget *source )
+{
+ QListBoxItem *item = itemAt( pnt );
+ if ( !item || item && !itemRect( item ).contains( pnt ) ) {
+ if ( source == viewport() && startDragDir == filedialog->dirPath() )
+ return FALSE;
+ return TRUE;
+ }
+
+ QUrlInfo fi( filedialog->d->url, item->text() );
+
+ if ( fi.isDir() && itemRect( item ).contains( pnt ) )
+ return TRUE;
+ return FALSE;
+}
+
+void QFileListBox::setCurrentDropItem( const QPoint &pnt )
+{
+ changeDirTimer->stop();
+
+ QListBoxItem *item = 0;
+ if ( pnt != QPoint( -1, -1 ) )
+ item = itemAt( pnt );
+ if ( item && !QUrlInfo( filedialog->d->url, item->text() ).isDir() )
+ item = 0;
+ if ( item && !itemRect( item ).contains( pnt ) )
+ item = 0;
+
+ currDropItem = item;
+ if ( currDropItem )
+ setCurrentItem( currDropItem );
+ changeDirTimer->start( 750 );
+}
+#endif // QT_NO_DRAGANDDROP
+
+void QFileListBox::changeDirDuringDrag()
+{
+#ifndef QT_NO_DRAGANDDROP
+ if ( !currDropItem )
+ return;
+ changeDirTimer->stop();
+ QUrl u( filedialog->d->url, QFileDialogPrivate::encodeFileName(currDropItem->text()) );
+ filedialog->setDir( u );
+ currDropItem = 0;
+#endif
+}
+
+void QFileListBox::doubleClickTimeout()
+{
+ startRename();
+ renameTimer->stop();
+}
+
+void QFileListBox::startRename( bool check )
+{
+ if ( check && ( !renameItem || renameItem != item( currentItem() ) ) )
+ return;
+
+ int i = currentItem();
+ setSelected( i, TRUE );
+ QRect r = itemRect( item( i ) );
+ int bdr = item( i )->pixmap() ?
+ item( i )->pixmap()->width() : 16;
+ int x = r.x() + bdr;
+ int y = r.y();
+ int w = item( i )->width( this ) - bdr;
+ int h = QMAX( lined->height() + 2, r.height() );
+ y = y + r.height() / 2 - h / 2;
+
+ lined->parentWidget()->setGeometry( x, y, w + 6, h );
+ lined->setFocus();
+ lined->setText( item( i )->text() );
+ lined->selectAll();
+ lined->setFrame( FALSE );
+ lined->parentWidget()->show();
+ viewport()->setFocusProxy( lined );
+ renaming = TRUE;
+}
+
+void QFileListBox::clear()
+{
+ cancelRename();
+ QListBox::clear();
+}
+
+void QFileListBox::rename()
+{
+ if ( !lined->text().isEmpty() ) {
+ QString file = currentText();
+
+ if ( lined->text() != file )
+ filedialog->d->url.rename( file, lined->text() );
+ }
+ cancelRename();
+}
+
+void QFileListBox::cancelRename()
+{
+ renameItem = 0;
+ lined->parentWidget()->hide();
+ viewport()->setFocusProxy( this );
+ renaming = FALSE;
+ updateItem( currentItem() );
+ if ( lined->hasFocus() )
+ viewport()->setFocus();
+}
+
+void QFileListBox::contentsMoved( int, int )
+{
+ changeDirTimer->stop();
+#ifndef QT_NO_DRAGANDDROP
+ setCurrentDropItem( QPoint( -1, -1 ) );
+#endif
+}
+
+/************************************************************************
+ *
+ * Internal class QFileListView
+ *
+ ************************************************************************/
+
+QFileDialogQFileListView::QFileDialogQFileListView( QWidget *parent, QFileDialogP *dlg )
+ : QListView( parent, "qt_filedlg_listview" ), renaming( FALSE ), renameItem( 0 ),
+ filedialog( dlg ), mousePressed( FALSE ),
+ firstMousePressEvent( TRUE )
+{
+ changeDirTimer = new QTimer( this );
+ QVBox *box = new QVBox( viewport(), "qt_vbox" );
+ box->setFrameStyle( QFrame::Box | QFrame::Plain );
+ lined = new QRenameEdit( box );
+ lined->setFixedHeight( lined->sizeHint().height() );
+ box->hide();
+ box->setBackgroundMode( PaletteBase );
+ renameTimer = new QTimer( this );
+ connect( lined, SIGNAL( returnPressed() ),
+ this, SLOT (rename() ) );
+ connect( lined, SIGNAL( escapePressed() ),
+ this, SLOT( cancelRename() ) );
+ header()->setMovingEnabled( FALSE );
+ connect( renameTimer, SIGNAL( timeout() ),
+ this, SLOT( doubleClickTimeout() ) );
+ connect( changeDirTimer, SIGNAL( timeout() ),
+ this, SLOT( changeDirDuringDrag() ) );
+ disconnect( header(), SIGNAL( sectionClicked( int ) ),
+ this, SLOT( changeSortColumn( int ) ) );
+ connect( header(), SIGNAL( sectionClicked( int ) ),
+ this, SLOT( changeSortColumn2( int ) ) );
+ connect( this, SIGNAL( contentsMoving( int, int ) ),
+ this, SLOT( contentsMoved( int, int ) ) );
+
+ viewport()->setAcceptDrops( TRUE );
+ sortcolumn = 0;
+ ascending = TRUE;
+ dragItem = 0;
+}
+
+void QFileDialogQFileListView::setSorting( int column, bool increasing )
+{
+ if ( column == -1 ) {
+ QListView::setSorting( column, increasing );
+ return;
+ }
+
+ sortAscending = ascending = increasing;
+ sortcolumn = column;
+ switch ( column ) {
+ case 0:
+ sortFilesBy = QDir::Name;
+ break;
+ case 1:
+ sortFilesBy = QDir::Size;
+ break;
+ case 3:
+ sortFilesBy = QDir::Time;
+ break;
+ default:
+ sortFilesBy = QDir::Name; // #### ???
+ break;
+ }
+
+ filedialog->resortDir();
+}
+
+void QFileDialogQFileListView::changeSortColumn2( int column )
+{
+ int lcol = header()->mapToLogical( column );
+ setSorting( lcol, sortcolumn == lcol ? !ascending : TRUE );
+}
+
+void QFileDialogQFileListView::keyPressEvent( QKeyEvent *e )
+{
+ if ( ( e->key() == Key_Enter ||
+ e->key() == Key_Return ) &&
+ renaming )
+ return;
+
+ QString keyPressed = e->text().lower();
+ QChar keyChar = keyPressed[0];
+ if ( keyChar.isLetterOrNumber() ) {
+ QListViewItem * i = 0;
+ if ( currentItem() )
+ i = currentItem();
+ else
+ i = firstChild();
+ if ( i->nextSibling() )
+ i = i->nextSibling();
+ else
+ i = firstChild();
+ while ( i != currentItem() ) {
+ QString it = i->text(0);
+ if ( it[0].lower() == keyChar ) {
+ clearSelection();
+ ensureItemVisible( i );
+ setCurrentItem( i );
+ } else {
+ if ( i->nextSibling() )
+ i = i->nextSibling();
+ else
+ i = firstChild();
+ }
+ }
+ return;
+ }
+
+ cancelRename();
+ QListView::keyPressEvent( e );
+}
+
+void QFileDialogQFileListView::viewportMousePressEvent( QMouseEvent *e )
+{
+ pressPos = e->pos();
+ mousePressed = FALSE;
+
+ bool didRename = renaming;
+ cancelRename();
+ if ( !hasFocus() && !viewport()->hasFocus() )
+ setFocus();
+
+ if ( e->button() != LeftButton ) {
+ QListView::viewportMousePressEvent( e );
+ firstMousePressEvent = FALSE;
+ return;
+ }
+
+ QListViewItem *i = currentItem();
+ QListView::viewportMousePressEvent( e );
+
+ QFileDialogPrivate::File *i1 = (QFileDialogPrivate::File*)currentItem();
+ if ( i1 )
+ mousePressed = !i1->info.isDir();
+
+ if ( itemAt( e->pos() ) != i ||
+ e->x() + contentsX() > columnWidth( 0 ) ) {
+ firstMousePressEvent = FALSE;
+ return;
+ }
+
+ if ( !firstMousePressEvent && !didRename && i == currentItem() && currentItem() &&
+ filedialog->mode() != QFileDialogP::ExistingFiles &&
+ QUrlInfo( filedialog->d->url, "." ).isWritable() && currentItem()->text( 0 ) != ".." ) {
+ renameTimer->start( QApplication::doubleClickInterval(), TRUE );
+ renameItem = currentItem();
+ }
+
+ firstMousePressEvent = FALSE;
+}
+
+void QFileDialogQFileListView::viewportMouseDoubleClickEvent( QMouseEvent *e )
+{
+ renameTimer->stop();
+ QListView::viewportMouseDoubleClickEvent( e );
+}
+
+void QFileDialogQFileListView::viewportMouseReleaseEvent( QMouseEvent *e )
+{
+ QListView::viewportMouseReleaseEvent( e );
+ mousePressed = FALSE;
+ dragItem = 0;
+}
+
+void QFileDialogQFileListView::viewportMouseMoveEvent( QMouseEvent *e )
+{
+ renameTimer->stop();
+ if ( !dragItem )
+ dragItem = itemAt( e->pos() );
+#ifndef QT_NO_DRAGANDDROP
+ if ( ( pressPos - e->pos() ).manhattanLength() > QApplication::startDragDistance() && mousePressed ) {
+ QListViewItem *item = dragItem;
+ dragItem = 0;
+ if ( item ) {
+ QUriDrag* drag = new QUriDrag( viewport() );
+ drag->setUnicodeUris( filedialog->selectedFiles() );
+
+ if ( lined->isVisible() )
+ cancelRename();
+
+ connect( drag, SIGNAL( destroyed() ),
+ this, SLOT( dragObjDestroyed() ) );
+ drag->drag();
+
+ mousePressed = FALSE;
+ }
+ }
+#endif
+}
+
+void QFileDialogQFileListView::dragObjDestroyed()
+{
+#ifndef QT_NO_DRAGANDDROP
+ //######
+ //filedialog->rereadDir();
+#endif
+}
+
+#ifndef QT_NO_DRAGANDDROP
+void QFileDialogQFileListView::viewportDragEnterEvent( QDragEnterEvent *e )
+{
+ startDragUrl = filedialog->d->url;
+ startDragDir = filedialog->dirPath();
+ currDropItem = 0;
+
+ if ( !QUriDrag::canDecode( e ) ) {
+ e->ignore();
+ return;
+ }
+
+ QStringList l;
+ QUriDrag::decodeLocalFiles( e, l );
+ urls = (int)l.count();
+
+ if ( acceptDrop( e->pos(), e->source() ) ) {
+ e->accept();
+ setCurrentDropItem( e->pos() );
+ } else {
+ e->ignore();
+ setCurrentDropItem( QPoint( -1, -1 ) );
+ }
+
+ oldDragPos = e->pos();
+}
+
+void QFileDialogQFileListView::viewportDragMoveEvent( QDragMoveEvent *e )
+{
+ if ( acceptDrop( e->pos(), e->source() ) ) {
+ if ( oldDragPos != e->pos() )
+ setCurrentDropItem( e->pos() );
+ switch ( e->action() ) {
+ case QDropEvent::Copy:
+ e->acceptAction();
+ break;
+ case QDropEvent::Move:
+ e->acceptAction();
+ break;
+ case QDropEvent::Link:
+ break;
+ default:
+ break;
+ }
+ } else {
+ changeDirTimer->stop();
+ e->ignore();
+ setCurrentDropItem( QPoint( -1, -1 ) );
+ }
+
+ oldDragPos = e->pos();
+}
+
+void QFileDialogQFileListView::viewportDragLeaveEvent( QDragLeaveEvent * )
+{
+ changeDirTimer->stop();
+ setCurrentDropItem( QPoint( -1, -1 ) );
+//########
+// if ( startDragDir != filedialog->d->url )
+// filedialog->setUrl( startDragUrl );
+}
+
+void QFileDialogQFileListView::viewportDropEvent( QDropEvent *e )
+{
+ changeDirTimer->stop();
+
+ if ( !QUriDrag::canDecode( e ) ) {
+ e->ignore();
+ return;
+ }
+
+ QStringList l;
+ QUriDrag::decodeToUnicodeUris( e, l );
+
+ bool move = e->action() == QDropEvent::Move;
+// bool supportAction = move || e->action() == QDropEvent::Copy;
+
+ QUrlOperator dest;
+ if ( currDropItem )
+ dest = QUrlOperator( filedialog->d->url, QFileDialogPrivate::encodeFileName( currDropItem->text( 0 ) ) );
+ else
+ dest = filedialog->d->url;
+ filedialog->d->url.copy( l, dest, move );
+
+ // ##### what is supportAction for?
+ e->acceptAction();
+ currDropItem = 0;
+}
+
+bool QFileDialogQFileListView::acceptDrop( const QPoint &pnt, QWidget *source )
+{
+ QListViewItem *item = itemAt( pnt );
+ if ( !item || item && !itemRect( item ).contains( pnt ) ) {
+ if ( source == viewport() && startDragDir == filedialog->dirPath() )
+ return FALSE;
+ return TRUE;
+ }
+
+ QUrlInfo fi( filedialog->d->url, item->text( 0 ) );
+
+ if ( fi.isDir() && itemRect( item ).contains( pnt ) )
+ return TRUE;
+ return FALSE;
+}
+
+void QFileDialogQFileListView::setCurrentDropItem( const QPoint &pnt )
+{
+ changeDirTimer->stop();
+
+ QListViewItem *item = itemAt( pnt );
+ if ( pnt == QPoint( -1, -1 ) )
+ item = 0;
+ if ( item && !QUrlInfo( filedialog->d->url, item->text( 0 ) ).isDir() )
+ item = 0;
+
+ if ( item && !itemRect( item ).contains( pnt ) )
+ item = 0;
+
+ currDropItem = item;
+
+ if ( currDropItem )
+ setCurrentItem( currDropItem );
+
+ changeDirTimer->start( 750 );
+}
+#endif // QT_NO_DRAGANDDROP
+
+void QFileDialogQFileListView::changeDirDuringDrag()
+{
+#ifndef QT_NO_DRAGANDDROP
+ if ( !currDropItem )
+ return;
+ changeDirTimer->stop();
+ QUrl u( filedialog->d->url, QFileDialogPrivate::encodeFileName(currDropItem->text( 0 ) ) );
+ filedialog->setDir( u );
+ currDropItem = 0;
+#endif // QT_NO_DRAGANDDROP
+}
+
+
+void QFileDialogQFileListView::doubleClickTimeout()
+{
+ startRename();
+ renameTimer->stop();
+}
+
+void QFileDialogQFileListView::startRename( bool check )
+{
+ if ( check && ( !renameItem || renameItem != currentItem() ) )
+ return;
+
+ QListViewItem *i = currentItem();
+ setSelected( i, TRUE );
+
+ QRect r = itemRect( i );
+ int bdr = i->pixmap( 0 ) ?
+ i->pixmap( 0 )->width() : 16;
+ int x = r.x() + bdr;
+ int y = r.y();
+ int w = columnWidth( 0 ) - bdr;
+ int h = QMAX( lined->height() + 2, r.height() );
+ y = y + r.height() / 2 - h / 2;
+
+ lined->parentWidget()->setGeometry( x, y, w + 6, h );
+ lined->setFocus();
+ lined->setText( i->text( 0 ) );
+ lined->selectAll();
+ lined->setFrame( FALSE );
+ lined->parentWidget()->show();
+ viewport()->setFocusProxy( lined );
+ renaming = TRUE;
+}
+
+void QFileDialogQFileListView::clear()
+{
+ cancelRename();
+ QListView::clear();
+}
+
+void QFileDialogQFileListView::rename()
+{
+ if ( !lined->text().isEmpty() ) {
+ QString file = currentItem()->text( 0 );
+
+ if ( lined->text() != file )
+ filedialog->d->url.rename( file, lined->text() );
+ }
+ cancelRename();
+}
+
+void QFileDialogQFileListView::cancelRename()
+{
+ renameItem = 0;
+ lined->parentWidget()->hide();
+ viewport()->setFocusProxy( this );
+ renaming = FALSE;
+ if ( currentItem() )
+ currentItem()->repaint();
+ if ( lined->hasFocus() )
+ viewport()->setFocus();
+}
+
+void QFileDialogQFileListView::contentsMoved( int, int )
+{
+ changeDirTimer->stop();
+#ifndef QT_NO_DRAGANDDROP
+ setCurrentDropItem( QPoint( -1, -1 ) );
+#endif
+}
+
+
+QFileDialogPrivate::File::~File()
+{
+ if ( d->pendingItems.findRef( this ) )
+ d->pendingItems.removeRef( this );
+}
+
+QString QFileDialogPrivate::File::text( int column ) const
+{
+ makeVariables();
+
+ switch( column ) {
+ case 0:
+ return info.name();
+ case 1:
+ if ( info.isFile() )
+ return QString::number(info.size());
+ else
+ return QString::fromLatin1("");
+ case 2:
+ if ( info.isFile() && info.isSymLink() ) {
+ return d->symLinkToFile;
+ } else if ( info.isFile() ) {
+ return d->file;
+ } else if ( info.isDir() && info.isSymLink() ) {
+ return d->symLinkToDir;
+ } else if ( info.isDir() ) {
+ return d->dir;
+ } else if ( info.isSymLink() ) {
+ return d->symLinkToSpecial;
+ } else {
+ return d->special;
+ }
+ case 3: {
+ return info.lastModified().toString( Qt::LocalDate );
+ }
+ case 4:
+ if ( info.isReadable() )
+ return info.isWritable() ? d->rw : d->ro;
+ else
+ return info.isWritable() ? d->wo : d->inaccessible;
+ }
+
+ return QString::fromLatin1("<--->");
+}
+
+const QPixmap * QFileDialogPrivate::File::pixmap( int column ) const
+{
+ if ( column ) {
+ return 0;
+ } else if ( QListViewItem::pixmap( column ) ) {
+ return QListViewItem::pixmap( column );
+ } else if ( info.isSymLink() ) {
+ if ( info.isFile() )
+ return symLinkFileIcon;
+ else
+ return symLinkDirIcon;
+ } else if ( info.isDir() ) {
+ return closedFolderIcon;
+ } else if ( info.isFile() ) {
+ return fileIcon;
+ } else {
+ return fifteenTransparentPixels;
+ }
+}
+
+QFileDialogPrivate::MCItem::MCItem( QListBox * lb, QListViewItem * item )
+ : QListBoxItem()
+{
+ i = item;
+ if ( lb )
+ lb->insertItem( this );
+}
+
+QFileDialogPrivate::MCItem::MCItem( QListBox * lb, QListViewItem * item, QListBoxItem *after )
+ : QListBoxItem()
+{
+ i = item;
+ if ( lb )
+ lb->insertItem( this, after );
+}
+
+QString QFileDialogPrivate::MCItem::text() const
+{
+ return i->text( 0 );
+}
+
+
+const QPixmap *QFileDialogPrivate::MCItem::pixmap() const
+{
+ return i->pixmap( 0 );
+}
+
+
+int QFileDialogPrivate::MCItem::height( const QListBox * lb ) const
+{
+ if ( pixmap() )
+ return QMAX( lb->fontMetrics().height(), pixmap()->height()) + 2;
+
+ return lb->fontMetrics().height() + 2;
+}
+
+
+int QFileDialogPrivate::MCItem::width( const QListBox * lb ) const
+{
+ QFontMetrics fm = lb->fontMetrics();
+ int w = 2;
+ if ( pixmap() )
+ w += pixmap()->width() + 4;
+ else
+ w += 18;
+ w += fm.width( text() );
+ w += -fm.minLeftBearing();
+ w += -fm.minRightBearing();
+ w += 6;
+ return w;
+}
+
+
+void QFileDialogPrivate::MCItem::paint( QPainter * ptr )
+{
+ QFontMetrics fm = ptr->fontMetrics();
+
+ int h;
+
+ if ( pixmap() )
+ h = QMAX( fm.height(), pixmap()->height()) + 2;
+ else
+ h = fm.height() + 2;
+
+ const QPixmap * pm = pixmap();
+ if ( pm )
+ ptr->drawPixmap( 2, 1, *pm );
+
+ ptr->drawText( pm ? pm->width() + 4 : 22, h - fm.descent() - 2,
+ text() );
+}
+
+static QStringList makeFiltersList( const QString &filter )
+{
+ if ( filter.isEmpty() )
+ return QStringList();
+
+ int i = filter.find( ";;", 0 );
+ QString sep( ";;" );
+ if ( i == -1 ) {
+ if ( filter.find( "\n", 0 ) != -1 ) {
+ sep = "\n";
+ i = filter.find( sep, 0 );
+ }
+ }
+
+ return QStringList::split( sep, filter );
+}
+
+/*!
+ \class QFileDialogP qfiledialog.h
+ \brief The QFileDialogP class provides dialogs that allow users to select files or directories.
+ \ingroup dialogs
+ \mainclass
+
+ The QFileDialogP class enables a user to traverse their file system in
+ order to select one or many files or a directory.
+
+ The easiest way to create a QFileDialogP is to use the static
+ functions. On Windows, these static functions will call the native
+ Windows file dialog and on Mac OS X, these static function will call
+ the native Mac OS X file dialog.
+
+ \code
+ QString s = QFileDialogP::getOpenFileName(
+ "/home",
+ "Images (*.png *.xpm *.jpg)",
+ this,
+ "open file dialog"
+ "Choose a file" );
+ \endcode
+
+ In the above example, a modal QFileDialogP is created using a static
+ function. The startup directory is set to "/home". The file filter
+ is set to "Images (*.png *.xpm *.jpg)". The parent of the file dialog
+ is set to \e this and it is given the identification name - "open file
+ dialog". The caption at the top of file dialog is set to "Choose a
+ file".
+
+ You can create your own QFileDialogP without using the static
+ functions. By calling setMode(), you can set what can be returned by
+ the QFileDialogP.
+
+ \code
+ QFileDialogP* fd = new QFileDialogP( this, "file dialog", TRUE );
+ fd->setMode( QFileDialogP::AnyFile );
+ \endcode
+
+ In the above example, the mode of the file dialog is set to \c
+ AnyFile, meaning that the user can select any file, or even specify a
+ file that doesn't exist. This mode is useful for creating a "File Save
+ As" file dialog. Use \c ExistingFile if the user must select an
+ existing file or \c Directory if only a directory may be selected.
+ (See the \l QFileDialogP::Mode enum for the complete list of modes.)
+
+ You can retrieve the dialog's mode with mode(). Use setFilter() to set
+ the dialog's file filter, e.g.
+
+ \code
+ fd->setFilter( "Images (*.png *.xpm *.jpg)" );
+ \endcode
+
+ In the above example, the filter is set to "Images (*.png *.xpm
+ *.jpg)", this means that only files with the extension \c png, \c xpm
+ or \c jpg will be shown in the QFileDialogP. You can apply
+ several filters by using setFilters() and add additional filters with
+ addFilter(). Use setSelectedFilter() to select one of the filters
+ you've given as the file dialog's default filter. Whenever the user
+ changes the filter the filterSelected() signal is emitted.
+
+ The file dialog has two view modes, QFileDialogP::List which simply
+ lists file and directory names and QFileDialogP::Detail which
+ displays additional information alongside each name, e.g. file size,
+ modification date, etc. Set the mode with setViewMode().
+
+ \code
+ fd->setViewMode( QFileDialogP::Detail );
+ \endcode
+
+ The last important function you will need to use when creating your
+ own file dialog is selectedFile().
+
+ \code
+ QString fileName;
+ if ( fd->exec() == QDialog::Accepted )
+ fileName = fd->selectedFile();
+ \endcode
+
+ In the above example, a modal file dialog is created and shown. If
+ the user clicked OK, then the file they selected is put in \c
+ fileName.
+
+ If you are using the \c ExistingFiles mode then you will need to use
+ selectedFiles() which will return the selected files in a QStringList.
+
+ The dialog's working directory can be set with setDir(). The display
+ of hidden files is controlled with setShowHiddenFiles(). The dialog
+ can be forced to re-read the directory with rereadDir() and re-sort
+ the directory with resortDir(). All the files in the current directory
+ can be selected with selectAll().
+
+ \section1 Creating and using preview widgets
+
+ There are two kinds of preview widgets that can be used with
+ QFileDialogPs: \e content preview widgets and \e information preview
+ widgets. They are created and used in the same way except that the
+ function names differ, e.g. setContentsPreview() and setInfoPreview().
+
+ A preview widget is a widget that is placed inside a QFileDialogP so
+ that the user can see either the contents of the file, or information
+ about the file.
+
+ \code
+ class Preview : public QLabel, public QFilePreviewP
+ {
+ public:
+ Preview( QWidget *parent=0 ) : QLabel( parent ) {}
+
+ void previewUrl( const QUrl &u )
+ {
+ QString path = u.path();
+ QPixmap pix( path );
+ if ( pix.isNull() )
+ setText( "This is not a pixmap" );
+ else
+ setPixmap( pix );
+ }
+ };
+ \endcode
+
+ In the above snippet, we create a preview widget which inherits from
+ QLabel and QFilePreviewP. File preview widgets \e must inherit from
+ QFilePreviewP.
+
+ Inside the class we reimplement QFilePreviewP::previewUrl(), this is
+ where we determine what happens when a file is selected. In the
+ above example we only show a preview of the file if it is a valid
+ pixmap. Here's how to make a file dialog use a preview widget:
+
+ \code
+ Preview* p = new Preview;
+
+ QFileDialogP* fd = new QFileDialogP( this );
+ fd->setContentsPreviewEnabled( TRUE );
+ fd->setContentsPreview( p, p );
+ fd->setPreviewMode( QFileDialogP::Contents );
+ fd->show();
+ \endcode
+
+ The first line creates an instance of our preview widget. We then
+ create our file dialog and call setContentsPreviewEnabled( TRUE ),
+ this tell the file dialog to preview the contents of the currently
+ selected file. We then call setContentsPreview() -- note that we pass
+ the same preview widget twice. Finally, before showing the file
+ dialog, we call setPreviewMode() setting the mode to \e Contents which
+ will show the contents preview of the file that the user has selected.
+
+ If you create another preview widget that is used for displaying
+ information about a file, create it in the same way as the contents
+ preview widget and call setInfoPreviewEnabled(), and
+ setInfoPreview(). Then the user will be able to switch between the
+ two preview modes.
+
+ For more information about creating a QFilePreviewP widget see
+ \l{QFilePreviewP}.
+
+ <img src=qfiledlg-m.png> <img src=qfiledlg-w.png>
+
+*/
+
+
+/*! \enum QFileDialogP::Mode
+
+ This enum is used to indicate what the user may select in the file
+ dialog, i.e. what the dialog will return if the user clicks OK.
+
+ \value AnyFile The name of a file, whether it exists or not.
+ \value ExistingFile The name of a single existing file.
+ \value Directory The name of a directory. Both files and directories
+ are displayed.
+ \value DirectoryOnly The name of a directory. The file dialog will only display directories.
+ \value ExistingFiles The names of zero or more existing files.
+
+ See setMode().
+*/
+
+/*!
+ \enum QFileDialogP::ViewMode
+
+ This enum describes the view mode of the file dialog, i.e. what
+ information about each file will be displayed.
+
+ \value List Display file and directory names with icons.
+ \value Detail Display file and directory names with icons plus
+ additional information, such as file size and modification date.
+
+ See setViewMode().
+*/
+
+/*!
+ \enum QFileDialogP::PreviewMode
+
+ This enum describes the preview mode of the file dialog.
+
+ \value NoPreview No preview is shown at all.
+ \value Contents Show a preview of the contents of the current file
+ using the contents preview widget.
+ \value Info Show information about the current file using the
+ info preview widget.
+
+ See setPreviewMode(), setContentsPreview() and setInfoPreview().
+*/
+
+/*!
+ \fn void QFileDialogP::detailViewSelectionChanged()
+ \internal
+*/
+
+/*!
+ \fn void QFileDialogP::listBoxSelectionChanged()
+ \internal
+*/
+
+extern const char qt_file_dialog_filter_reg_exp[] =
+ "([a-zA-Z0-9 ]*)\\(([a-zA-Z0-9_.*? +;#\\[\\]]*)\\)$";
+
+/*!
+ Constructs a file dialog called \a name, with the parent, \a parent.
+ If \a modal is TRUE then the file dialog is modal; otherwise it is
+ modeless.
+*/
+
+QFileDialogP::QFileDialogP( QWidget *parent, const char *name, bool modal )
+ : QDialog( parent, name, modal,
+ (modal ?
+ (WStyle_Customize | WStyle_DialogBorder | WStyle_Title | WStyle_SysMenu) : 0) )
+{
+ init();
+ d->mode = ExistingFile;
+ d->types->insertItem( tr( "All Files (*)" ) );
+ emit dirEntered( d->url.dirPath() );
+ rereadDir();
+}
+
+
+/*!
+ Constructs a file dialog called \a name with the parent, \a parent.
+ If \a modal is TRUE then the file dialog is modal; otherwise it is
+ modeless.
+
+ If \a dirName is specified then it will be used as the dialog's
+ working directory, i.e. it will be the directory that is shown when
+ the dialog appears. If \a filter is specified it will be used as the
+ dialog's file filter.
+
+*/
+
+QFileDialogP::QFileDialogP( const QString& dirName, const QString & filter,
+ QWidget *parent, const char *name, bool modal )
+ : QDialog( parent, name, modal,
+ (modal ?
+ (WStyle_Customize | WStyle_DialogBorder | WStyle_Title | WStyle_SysMenu) : 0) )
+{
+ init();
+ d->mode = ExistingFile;
+ rereadDir();
+ if ( !dirName.isEmpty() )
+ setSelection( dirName );
+ else if ( workingDirectory && !workingDirectory->isEmpty() )
+ setDir( *workingDirectory );
+
+ if ( !filter.isEmpty() ) {
+ setFilters( filter );
+ if ( !dirName.isEmpty() ) {
+ int dotpos = dirName.find( QChar('.'), 0, FALSE );
+ if ( dotpos != -1 ) {
+ for ( int b=0 ; b<d->types->count() ; b++ ) {
+ if ( d->types->text(b).contains( dirName.right( dirName.length() - dotpos ) ) ) {
+ d->types->setCurrentItem( b );
+ setFilter( d->types->text( b ) );
+ return;
+ }
+ }
+ }
+ }
+ } else {
+ d->types->insertItem( tr( "All Files (*)" ) );
+ }
+}
+
+
+/*!
+ \internal
+ Initializes the file dialog.
+*/
+
+void QFileDialogP::init()
+{
+ setSizeGripEnabled( TRUE );
+ d = new QFileDialogPrivate();
+ d->mode = AnyFile;
+ d->last = 0;
+ d->moreFiles = 0;
+ d->infoPreview = FALSE;
+ d->contentsPreview = FALSE;
+ d->hadDotDot = FALSE;
+ d->ignoreNextKeyPress = FALSE;
+ d->progressDia = 0;
+ d->checkForFilter = FALSE;
+ d->ignoreReturn = FALSE;
+ d->ignoreNextRefresh = FALSE;
+ d->ignoreStop = FALSE;
+ d->pendingItems.setAutoDelete( FALSE );
+ d->mimeTypeTimer = new QTimer( this );
+ connect( d->mimeTypeTimer, SIGNAL( timeout() ),
+ this, SLOT( doMimeTypeLookup() ) );
+
+ d->url = QUrlOperator( QDir::currentDirPath() );
+ d->oldUrl = d->url;
+ d->currListChildren = 0;
+
+ connect( &d->url, SIGNAL( start( QNetworkOperation * ) ),
+ this, SLOT( urlStart( QNetworkOperation * ) ) );
+ connect( &d->url, SIGNAL( finished( QNetworkOperation * ) ),
+ this, SLOT( urlFinished( QNetworkOperation * ) ) );
+ connect( &d->url, SIGNAL( newChildren( const QValueList<QUrlInfo> &, QNetworkOperation * ) ),
+ this, SLOT( insertEntry( const QValueList<QUrlInfo> &, QNetworkOperation * ) ) );
+ connect( &d->url, SIGNAL( removed( QNetworkOperation * ) ),
+ this, SLOT( removeEntry( QNetworkOperation * ) ) );
+ connect( &d->url, SIGNAL( createdDirectory( const QUrlInfo &, QNetworkOperation * ) ),
+ this, SLOT( createdDirectory( const QUrlInfo &, QNetworkOperation * ) ) );
+ connect( &d->url, SIGNAL( itemChanged( QNetworkOperation * ) ),
+ this, SLOT( itemChanged( QNetworkOperation * ) ) );
+ connect( &d->url, SIGNAL( dataTransferProgress( int, int, QNetworkOperation * ) ),
+ this, SLOT( dataTransferProgress( int, int, QNetworkOperation * ) ) );
+
+ nameEdit = new QLineEdit( this, "name/filter editor" );
+ nameEdit->setMaxLength( 255 ); //_POSIX_MAX_PATH
+ connect( nameEdit, SIGNAL(textChanged(const QString&)),
+ this, SLOT(fileNameEditDone()) );
+ nameEdit->installEventFilter( this );
+
+ d->splitter = new QSplitter( this, "qt_splitter" );
+
+ d->stack = new QWidgetStack( d->splitter, "files and more files" );
+
+ d->splitter->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
+
+ files = new QFileDialogQFileListView( d->stack, this );
+ QFontMetrics fm = fontMetrics();
+ files->addColumn( tr("Name") );
+ files->addColumn( tr("Size") );
+ files->setColumnAlignment( 1, AlignRight );
+ files->addColumn( tr("Type") );
+ files->addColumn( tr("Date") );
+ files->addColumn( tr("Attributes") );
+ files->header()->setStretchEnabled( TRUE, 0 );
+
+ files->setMinimumSize( 50, 25 + 2*fm.lineSpacing() );
+
+ connect( files, SIGNAL( selectionChanged() ),
+ this, SLOT( detailViewSelectionChanged() ) );
+ connect( files, SIGNAL(currentChanged(QListViewItem *)),
+ this, SLOT(updateFileNameEdit(QListViewItem *)) );
+ connect( files, SIGNAL(doubleClicked(QListViewItem *)),
+ this, SLOT(selectDirectoryOrFile(QListViewItem *)) );
+ connect( files, SIGNAL(returnPressed(QListViewItem *)),
+ this, SLOT(selectDirectoryOrFile(QListViewItem *)) );
+ connect( files, SIGNAL(rightButtonPressed(QListViewItem *,
+ const QPoint &, int)),
+ this, SLOT(popupContextMenu(QListViewItem *,
+ const QPoint &, int)) );
+
+ files->installEventFilter( this );
+ files->viewport()->installEventFilter( this );
+
+ d->moreFiles = new QFileListBox( d->stack, this );
+ d->moreFiles->setRowMode( QListBox::FitToHeight );
+ d->moreFiles->setVariableWidth( TRUE );
+
+ connect( d->moreFiles, SIGNAL(selected(QListBoxItem *)),
+ this, SLOT(selectDirectoryOrFile(QListBoxItem *)) );
+ connect( d->moreFiles, SIGNAL( selectionChanged() ),
+ this, SLOT( listBoxSelectionChanged() ) );
+ connect( d->moreFiles, SIGNAL(highlighted(QListBoxItem *)),
+ this, SLOT(updateFileNameEdit(QListBoxItem *)) );
+ connect( d->moreFiles, SIGNAL( rightButtonPressed( QListBoxItem *, const QPoint & ) ),
+ this, SLOT( popupContextMenu( QListBoxItem *, const QPoint & ) ) );
+
+ d->moreFiles->installEventFilter( this );
+ d->moreFiles->viewport()->installEventFilter( this );
+
+ okB = new QPushButton( tr("OK"), this, "OK" ); //### Or "Save (see other "OK")
+ okB->setDefault( TRUE );
+ okB->setEnabled( FALSE );
+ connect( okB, SIGNAL(clicked()), this, SLOT(okClicked()) );
+ cancelB = new QPushButton( tr("Cancel") , this, "Cancel" );
+ connect( cancelB, SIGNAL(clicked()), this, SLOT(cancelClicked()) );
+
+ d->paths = new QComboBox( TRUE, this, "directory history/editor" );
+ d->paths->setDuplicatesEnabled( FALSE );
+ d->paths->setInsertionPolicy( QComboBox::NoInsertion );
+ const QFileInfoList * rootDrives = QDir::drives();
+ QFileInfoListIterator it( *rootDrives );
+ QFileInfo *fi;
+ makeVariables();
+
+ while ( (fi = it.current()) != 0 ) {
+ ++it;
+ d->paths->insertItem( *openFolderIcon, fi->absFilePath() );
+ }
+
+ if ( !!QDir::homeDirPath() ) {
+ if ( !d->paths->listBox()->findItem( QDir::homeDirPath() ) )
+ d->paths->insertItem( *openFolderIcon, QDir::homeDirPath() );
+ }
+
+ connect( d->paths, SIGNAL(activated(const QString&)),
+ this, SLOT(setDir(const QString&)) );
+
+ d->paths->installEventFilter( this );
+ QObjectList *ol = d->paths->queryList( "QLineEdit" );
+ if ( ol && ol->first() )
+ ( (QLineEdit*)ol->first() )->installEventFilter( this );
+ delete ol;
+
+ d->geometryDirty = TRUE;
+ d->types = new QComboBox( TRUE, this, "file types" );
+ d->types->setDuplicatesEnabled( FALSE );
+ d->types->setEditable( FALSE );
+ connect( d->types, SIGNAL(activated(const QString&)),
+ this, SLOT(setFilter(const QString&)) );
+ connect( d->types, SIGNAL(activated(const QString&)),
+ this, SIGNAL(filterSelected(const QString&)) );
+
+ d->pathL = new QLabel( d->paths, tr("Look &in:"), this, "qt_looin_lbl" );
+ d->fileL = new QLabel( nameEdit, tr("File &name:"), this, "qt_filename_lbl" );
+ d->typeL = new QLabel( d->types, tr("File &type:"), this, "qt_filetype_lbl" );
+
+#if defined(Q_WS_WIN)
+ if ( qt_winver == Qt::WV_2000 || qt_winver == Qt::WV_XP ) {
+ d->goBack = new QToolButton( this, "go back" );
+ d->goBack->setAutoRaise( TRUE );
+ d->goBack->setEnabled( FALSE );
+ d->goBack->setFocusPolicy( TabFocus );
+ connect( d->goBack, SIGNAL( clicked() ),
+ this, SLOT( goBack() ) );
+ QToolTip::add( d->goBack, tr( "Back" ) );
+ d->goBack->setIconSet( *goBackIcon );
+ } else {
+ d->goBack = 0;
+ }
+#else
+ d->goBack = 0;
+#endif
+
+ d->cdToParent = new QToolButton( this, "cd to parent" );
+#if defined(Q_WS_WIN)
+ if ( qt_winver == Qt::WV_2000 || qt_winver == Qt::WV_XP )
+ d->cdToParent->setAutoRaise( TRUE );
+#endif
+ d->cdToParent->setFocusPolicy( TabFocus );
+#ifndef QT_NO_TOOLTIP
+ QToolTip::add( d->cdToParent, tr( "One directory up" ) );
+#endif
+ d->cdToParent->setIconSet( *cdToParentIcon );
+ connect( d->cdToParent, SIGNAL(clicked()),
+ this, SLOT(cdUpClicked()) );
+
+ d->newFolder = new QToolButton( this, "new folder" );
+#if defined(Q_WS_WIN)
+ if ( qt_winver == Qt::WV_2000 || qt_winver == Qt::WV_XP )
+ d->newFolder->setAutoRaise( TRUE );
+#endif
+ d->newFolder->setFocusPolicy( TabFocus );
+#ifndef QT_NO_TOOLTIP
+ QToolTip::add( d->newFolder, tr( "Create New Folder" ) );
+#endif
+ d->newFolder->setIconSet( *newFolderIcon );
+ connect( d->newFolder, SIGNAL(clicked()),
+ this, SLOT(newFolderClicked()) );
+
+ d->modeButtons = new QButtonGroup( 0, "invisible group" );
+ connect( d->modeButtons, SIGNAL(destroyed()),
+ this, SLOT(modeButtonsDestroyed()) );
+ d->modeButtons->setExclusive( TRUE );
+ connect( d->modeButtons, SIGNAL(clicked(int)),
+ d->stack, SLOT(raiseWidget(int)) );
+ connect( d->modeButtons, SIGNAL(clicked(int)),
+ this, SLOT(changeMode(int)) );
+
+ d->mcView = new QToolButton( this, "mclistbox view" );
+#if defined(Q_WS_WIN)
+ if ( qt_winver == Qt::WV_2000 || qt_winver == Qt::WV_XP )
+ d->mcView->setAutoRaise( TRUE );
+#endif
+ d->mcView->setFocusPolicy( TabFocus );
+#ifndef QT_NO_TOOLTIP
+ QToolTip::add( d->mcView, tr( "List View" ) );
+#endif
+ d->mcView->setIconSet( *multiColumnListViewIcon );
+ d->mcView->setToggleButton( TRUE );
+ d->stack->addWidget( d->moreFiles, d->modeButtons->insert( d->mcView ) );
+ d->detailView = new QToolButton( this, "list view" );
+#if defined(Q_WS_WIN)
+ if ( qt_winver == Qt::WV_2000 || qt_winver == Qt::WV_XP )
+ d->detailView->setAutoRaise( TRUE );
+#endif
+ d->detailView->setFocusPolicy( TabFocus );
+#ifndef QT_NO_TOOLTIP
+ QToolTip::add( d->detailView, tr( "Detail View" ) );
+#endif
+ d->detailView->setIconSet( *detailViewIcon );
+ d->detailView->setToggleButton( TRUE );
+ d->stack->addWidget( files, d->modeButtons->insert( d->detailView ) );
+
+ d->previewInfo = new QToolButton( this, "preview info view" );
+#if defined(Q_WS_WIN)
+ if ( qt_winver == Qt::WV_2000 || qt_winver == Qt::WV_XP )
+ d->previewInfo->setAutoRaise( TRUE );
+#endif
+ d->previewInfo->setFocusPolicy( TabFocus );
+#ifndef QT_NO_TOOLTIP
+ QToolTip::add( d->previewInfo, tr( "Preview File Info" ) );
+#endif
+ d->previewInfo->setIconSet( *previewInfoViewIcon );
+ d->previewInfo->setToggleButton( TRUE );
+ d->modeButtons->insert( d->previewInfo );
+
+ d->previewContents = new QToolButton( this, "preview info view" );
+#if defined(Q_WS_WIN)
+ if ( qt_winver == Qt::WV_2000 || qt_winver == Qt::WV_XP )
+ d->previewContents->setAutoRaise( TRUE );
+#endif
+ d->previewContents->setFocusPolicy( TabFocus );
+#ifndef QT_NO_TOOLTIP
+ QToolTip::add( d->previewContents, tr( "Preview File Contents" ) );
+#endif
+ d->previewContents->setIconSet( *previewContentsViewIcon );
+ d->previewContents->setToggleButton( TRUE );
+ d->modeButtons->insert( d->previewContents );
+
+ connect( d->detailView, SIGNAL( clicked() ),
+ d->moreFiles, SLOT( cancelRename() ) );
+ connect( d->detailView, SIGNAL( clicked() ),
+ files, SLOT( cancelRename() ) );
+ connect( d->mcView, SIGNAL( clicked() ),
+ d->moreFiles, SLOT( cancelRename() ) );
+ connect( d->mcView, SIGNAL( clicked() ),
+ files, SLOT( cancelRename() ) );
+
+ d->stack->raiseWidget( d->moreFiles );
+ d->mcView->setOn( TRUE );
+
+ QHBoxLayout *lay = new QHBoxLayout( this );
+ lay->setMargin( 6 );
+ d->leftLayout = new QHBoxLayout( lay, 5 );
+ d->topLevelLayout = new QVBoxLayout( (QWidget*)0, 5 );
+ lay->addLayout( d->topLevelLayout, 1 );
+ d->extraWidgetsLayouts.setAutoDelete( FALSE );
+ d->extraLabels.setAutoDelete( FALSE );
+ d->extraWidgets.setAutoDelete( FALSE );
+ d->extraButtons.setAutoDelete( FALSE );
+ d->toolButtons.setAutoDelete( FALSE );
+
+ QHBoxLayout * h;
+
+ d->preview = new QWidgetStack( d->splitter, "qt_preview" );
+
+ d->infoPreviewWidget = new QWidget( d->preview, "qt_preview_info" );
+ d->contentsPreviewWidget = new QWidget( d->preview, "qt_preview_contents" );
+ d->infoPreviewer = d->contentsPreviewer = 0;
+
+ h = new QHBoxLayout( 0 );
+ d->buttonLayout = h;
+ d->topLevelLayout->addLayout( h );
+ h->addWidget( d->pathL );
+ h->addSpacing( 8 );
+ h->addWidget( d->paths );
+ h->addSpacing( 8 );
+ if ( d->goBack )
+ h->addWidget( d->goBack );
+ h->addWidget( d->cdToParent );
+ h->addSpacing( 2 );
+ h->addWidget( d->newFolder );
+ h->addSpacing( 4 );
+ h->addWidget( d->mcView );
+ h->addWidget( d->detailView );
+ h->addWidget( d->previewInfo );
+ h->addWidget( d->previewContents );
+
+ d->topLevelLayout->addWidget( d->splitter );
+
+ h = new QHBoxLayout();
+ d->topLevelLayout->addLayout( h );
+ h->addWidget( d->fileL );
+ h->addWidget( nameEdit );
+ h->addSpacing( 15 );
+ h->addWidget( okB );
+
+ h = new QHBoxLayout();
+ d->topLevelLayout->addLayout( h );
+ h->addWidget( d->typeL );
+ h->addWidget( d->types );
+ h->addSpacing( 15 );
+ h->addWidget( cancelB );
+
+ d->rightLayout = new QHBoxLayout( lay, 5 );
+ d->topLevelLayout->setStretchFactor( d->mcView, 1 );
+ d->topLevelLayout->setStretchFactor( files, 1 );
+
+ updateGeometries();
+
+ if ( d->goBack ) {
+ setTabOrder( d->paths, d->goBack );
+ setTabOrder( d->goBack, d->cdToParent );
+ } else {
+ setTabOrder( d->paths, d->cdToParent );
+ }
+ setTabOrder( d->cdToParent, d->newFolder );
+ setTabOrder( d->newFolder, d->mcView );
+ setTabOrder( d->mcView, d->detailView );
+ setTabOrder( d->detailView, d->moreFiles );
+ setTabOrder( d->moreFiles, files );
+ setTabOrder( files, nameEdit );
+ setTabOrder( nameEdit, d->types );
+ setTabOrder( d->types, okB );
+ setTabOrder( okB, cancelB );
+
+ d->rw = tr( "Read-write" );
+ d->ro = tr( "Read-only" );
+ d->wo = tr( "Write-only" );
+ d->inaccessible = tr( "Inaccessible" );
+
+ d->symLinkToFile = tr( "Symlink to File" );
+ d->symLinkToDir = tr( "Symlink to Directory" );
+ d->symLinkToSpecial = tr( "Symlink to Special" );
+ d->file = tr( "File" );
+ d->dir = tr( "Dir" );
+ d->special = tr( "Special" );
+
+ if ( !lastSize ) {
+ QRect screen = QApplication::desktop()->screenGeometry( QApplication::desktop()->screenNumber( pos() ) );
+ if ( screen.width() < 1024 ||
+ screen.height() < 768 ) {
+ resize( QMIN(screen.width(),420),
+ QMIN(screen.height(),236) );
+ } else {
+ QSize s( files->sizeHint() );
+ s = QSize( s.width() + 300, s.height() + 82 );
+
+ if ( s.width() * 3 > screen.width() * 2 )
+ s.setWidth( screen.width() * 2 / 3 );
+
+ if ( s.height() * 3 > screen.height() * 2 )
+ s.setHeight( screen.height() * 2 / 3 );
+ else if ( s.height() * 3 < screen.height() )
+ s.setHeight( screen.height() / 3 );
+
+ resize( s );
+ }
+ lastSize = new QSize;
+ qfd_cleanup_size.add( &lastSize );
+ *lastSize = size();
+ } else
+ resize( *lastSize );
+
+ if ( detailViewMode ) {
+ d->stack->raiseWidget( files );
+ d->mcView->setOn( FALSE );
+ d->detailView->setOn( TRUE );
+ }
+
+ d->preview->hide();
+ nameEdit->setFocus();
+
+ connect( nameEdit, SIGNAL( returnPressed() ),
+ this, SLOT( fileNameEditReturnPressed() ) );
+}
+
+/*!
+ \internal
+*/
+
+void QFileDialogP::fileNameEditReturnPressed()
+{
+ d->oldUrl = d->url;
+ if ( !isDirectoryMode( d->mode ) ) {
+ okClicked();
+ } else {
+ d->currentFileName = QString::null;
+ if ( nameEdit->text().isEmpty() ) {
+ emit fileSelected( selectedFile() );
+ accept();
+ } else {
+ QUrlInfo f;
+ QFileDialogPrivate::File * c
+ = (QFileDialogPrivate::File *)files->currentItem();
+ if ( c && files->isSelected(c) )
+ f = c->info;
+ else
+ f = QUrlInfo( d->url, nameEdit->text() );
+ if ( f.isDir() ) {
+ setUrl( QUrlOperator( d->url, QFileDialogPrivate::encodeFileName(nameEdit->text() + "/" ) ) );
+ d->checkForFilter = TRUE;
+ trySetSelection( TRUE, d->url, TRUE );
+ d->checkForFilter = FALSE;
+ }
+ }
+ nameEdit->setText( QString::null );
+ d->ignoreReturn = TRUE;
+ }
+}
+
+/*!
+ \internal
+ Changes the preview mode to the mode specified at \a id.
+*/
+
+void QFileDialogP::changeMode( int id )
+{
+ if ( !d->infoPreview && !d->contentsPreview )
+ return;
+
+ QButton *btn = (QButton*)d->modeButtons->find( id );
+ if ( !btn )
+ return;
+
+ if ( btn == d->previewContents && !d->contentsPreview )
+ return;
+ if ( btn == d->previewInfo && !d->infoPreview )
+ return;
+
+ if ( btn != d->previewContents && btn != d->previewInfo ) {
+ d->preview->hide();
+ } else {
+ if ( files->currentItem() ) {
+ if ( d->infoPreviewer )
+ d->infoPreviewer->previewUrl( QUrl( d->url, files->currentItem()->text( 0 ) ) );
+ if ( d->contentsPreviewer )
+ d->contentsPreviewer->previewUrl( QUrl( d->url, files->currentItem()->text( 0 ) ) );
+ }
+ if ( btn == d->previewInfo )
+ d->preview->raiseWidget( d->infoPreviewWidget );
+ else
+ d->preview->raiseWidget( d->contentsPreviewWidget );
+ d->preview->show();
+ }
+}
+
+/*!
+ Destroys the file dialog.
+*/
+
+QFileDialogP::~QFileDialogP()
+{
+ // since clear might call setContentsPos which would emit
+ // a signal and thus cause a recompute of sizes...
+ files->blockSignals( TRUE );
+ d->moreFiles->blockSignals( TRUE );
+ files->clear();
+ d->moreFiles->clear();
+ d->moreFiles->blockSignals( FALSE );
+ files->blockSignals( FALSE );
+ if ( QApplication::overrideCursor() )
+ QApplication::restoreOverrideCursor();
+ delete d;
+ d = 0;
+}
+
+
+/*!
+ \property QFileDialogP::selectedFile
+
+ \brief the name of the selected file
+
+ If a file was selected selectedFile contains the file's name including
+ its absolute path; otherwise selectedFile is empty.
+
+ \sa QString::isEmpty(), selectedFiles, selectedFilter
+*/
+
+QString QFileDialogP::selectedFile() const
+{
+ QString s = d->currentFileName;
+ // remove the protocol because we do not want to encode it...
+ QString prot = QUrl( s ).protocol();
+ if ( !prot.isEmpty() ) {
+ prot += ":";
+ s.remove( 0, prot.length() );
+ }
+ QUrl u( prot + QFileDialogPrivate::encodeFileName( s ) );
+ if ( u.isLocalFile() ) {
+ QString s = u.toString();
+ if ( s.left( 5 ) == "file:" )
+ s.remove( 0, 5 );
+ return s;
+ }
+ return d->currentFileName;
+}
+
+/*!
+ \property QFileDialogP::selectedFilter
+
+ \brief the filter which the user has selected in the file dialog
+
+ \sa filterSelected(), selectedFiles, selectedFile
+*/
+
+QString QFileDialogP::selectedFilter() const
+{
+ return d->types->currentText();
+}
+
+/*! \overload
+
+ Sets the current filter selected in the file dialog to the
+ \a{n}-th filter in the filter list.
+
+ \sa filterSelected(), selectedFilter(), selectedFiles(), selectedFile()
+*/
+
+void QFileDialogP::setSelectedFilter( int n )
+{
+ d->types->setCurrentItem( n );
+ QString f = d->types->currentText();
+ QRegExp r( QString::fromLatin1(qt_file_dialog_filter_reg_exp) );
+ int index = r.search( f );
+ if ( index >= 0 )
+ f = r.cap( 2 );
+ d->url.setNameFilter( f );
+ rereadDir();
+}
+
+/*!
+ Sets the current filter selected in the file dialog to the first
+ one that contains the text \a mask.
+*/
+
+void QFileDialogP::setSelectedFilter( const QString& mask )
+{
+ int n;
+
+ for ( n = 0; n < d->types->count(); n++ ) {
+ if ( d->types->text( n ).contains( mask, FALSE ) ) {
+ d->types->setCurrentItem( n );
+ QString f = mask;
+ QRegExp r( QString::fromLatin1(qt_file_dialog_filter_reg_exp) );
+ int index = r.search( f );
+ if ( index >= 0 )
+ f = r.cap( 2 );
+ d->url.setNameFilter( f );
+ rereadDir();
+ return;
+ }
+ }
+}
+
+/*!
+ \property QFileDialogP::selectedFiles
+
+ \brief the list of selected files
+
+ If one or more files are selected, selectedFiles contains their
+ names including their absolute paths. If no files are selected or
+ the mode isn't ExistingFiles selectedFiles is an empty list.
+
+ It is more convenient to use selectedFile() if the mode is
+ \c ExistingFile, \c Directory or \c DirectoryOnly.
+
+ Note that if you want to iterate over the list, you should
+ iterate over a copy, e.g.
+ \code
+ QStringList list = myFileDialog.selectedFiles();
+ QStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa selectedFile, selectedFilter, QValueList::empty()
+*/
+
+QStringList QFileDialogP::selectedFiles() const
+{
+ QStringList lst;
+
+ if ( mode() == ExistingFiles ) {
+ QStringList selectedLst;
+ QString selectedFiles = nameEdit->text();
+ selectedFiles.truncate( selectedFiles.findRev( '\"' ) );
+ selectedLst = selectedLst.split( QString("\" "), selectedFiles );
+ for ( QStringList::Iterator it = selectedLst.begin(); it != selectedLst.end(); ++it ) {
+ QUrl u;
+ if ( (*it)[0] == '\"' ) {
+ u = QUrl( d->url, QFileDialogPrivate::encodeFileName( (*it).mid(1) ) );
+ } else {
+ u = QUrl( d->url, QFileDialogPrivate::encodeFileName( (*it) ) );
+ }
+ if ( u.isLocalFile() ) {
+ QString s = u.toString();
+ if ( s.left( 5 ) == "file:" )
+ s.remove( 0, 5 );
+ lst << s;
+ } else {
+ lst << u.toString();
+ }
+ }
+ }
+
+ return lst;
+}
+
+/*!
+ Sets the default selection to \a filename. If \a filename is
+ absolute, setDir() is also called to set the file dialog's working
+ directory to the filename's directory.
+
+ \omit
+ Only for external use. Not useful inside QFileDialogP.
+ \endomit
+*/
+
+void QFileDialogP::setSelection( const QString & filename )
+{
+ d->oldUrl = d->url;
+ QString nf = d->url.nameFilter();
+ if ( QUrl::isRelativeUrl( filename ) )
+ d->url = QUrlOperator( d->url, QFileDialogPrivate::encodeFileName( filename ) );
+ else
+ d->url = QUrlOperator( filename );
+ d->url.setNameFilter( nf );
+ d->checkForFilter = TRUE;
+ bool isDirOk;
+ bool isDir = d->url.isDir( &isDirOk );
+ if ( !isDirOk )
+ isDir = d->url.path().right( 1 ) == "/";
+ if ( !isDir ) {
+ QUrlOperator u( d->url );
+ d->url.setPath( d->url.dirPath() );
+ trySetSelection( FALSE, u, TRUE );
+ d->ignoreNextRefresh = TRUE;
+ nameEdit->selectAll();
+ rereadDir();
+ emit dirEntered( d->url.dirPath() );
+ } else {
+ if ( !d->url.path().isEmpty() &&
+ d->url.path().right( 1 ) != "/" ) {
+ QString p = d->url.path();
+ p += "/";
+ d->url.setPath( p );
+ }
+ trySetSelection( TRUE, d->url, FALSE );
+ rereadDir();
+ emit dirEntered( d->url.dirPath() );
+ nameEdit->setText( QString::fromLatin1("") );
+ }
+ d->checkForFilter = FALSE;
+}
+
+/*!
+ \property QFileDialogP::dirPath
+
+ \brief the file dialog's working directory
+
+ \sa dir(), setDir()
+*/
+
+QString QFileDialogP::dirPath() const
+{
+ return d->url.dirPath();
+}
+
+
+/*!
+
+ Sets the filter used in the file dialog to \a newFilter.
+
+ If \a newFilter contains a pair of parentheses containing one or more
+ of <em><b>anything*something</b></em> separated by spaces or by
+ semi-colons then only the text contained in the parentheses is used as
+ the filter. This means that these calls are all equivalent:
+
+ \code
+ fd->setFilter( "All C++ files (*.cpp *.cc *.C *.cxx *.c++)" );
+ fd->setFilter( "*.cpp *.cc *.C *.cxx *.c++" );
+ fd->setFilter( "All C++ files (*.cpp;*.cc;*.C;*.cxx;*.c++)" );
+ fd->setFilter( "*.cpp;*.cc;*.C;*.cxx;*.c++" );
+ \endcode
+
+ \sa setFilters()
+*/
+
+void QFileDialogP::setFilter( const QString & newFilter )
+{
+ if ( newFilter.isEmpty() )
+ return;
+ QString f = newFilter;
+ QRegExp r( QString::fromLatin1(qt_file_dialog_filter_reg_exp) );
+ int index = r.search( f );
+ if ( index >= 0 )
+ f = r.cap( 2 );
+ d->url.setNameFilter( f );
+ if ( d->types->count() == 1 ) {
+ d->types->clear();
+ d->types->insertItem( newFilter );
+ } else {
+ for ( int i = 0; i < d->types->count(); ++i ) {
+ if ( d->types->text( i ).left( newFilter.length() ) == newFilter ) {
+ d->types->setCurrentItem( i );
+ break;
+ }
+ }
+ }
+ rereadDir();
+}
+
+
+/*! \overload
+ Sets the file dialog's working directory to \a pathstr.
+
+ \sa dir()
+*/
+
+void QFileDialogP::setDir( const QString & pathstr )
+{
+ QString dr = pathstr;
+ if ( dr.isEmpty() )
+ return;
+
+#if defined(Q_OS_UNIX)
+ if ( dr.length() && dr[0] == '~' ) {
+ struct passwd *pw;
+ int i;
+
+ i = 0;
+ while( i < (int)dr.length() && dr[i] != '/' )
+ i++;
+ QCString user;
+ if ( i == 1 ) {
+ user = ::getlogin();
+ if ( !user )
+ user = getenv( "LOGNAME" );
+ } else
+ user = dr.mid( 1, i-1 ).local8Bit();
+ dr = dr.mid( i, dr.length() );
+ pw = ::getpwnam( user );
+ if ( pw )
+ dr.prepend( QString::fromLocal8Bit(pw->pw_dir) );
+ }
+#endif
+
+ setUrl( dr );
+}
+
+/*!
+ Returns the current directory shown in the file dialog.
+
+ The ownership of the QDir pointer is transferred to the caller, so
+ it must be deleted by the caller when no longer required.
+
+ \sa setDir()
+*/
+
+const QDir *QFileDialogP::dir() const
+{
+ if ( d->url.isLocalFile() )
+ return new QDir( d->url.path() );
+ else
+ return 0;
+}
+
+/*!
+ Sets the file dialog's working directory to \a dir.
+ \sa dir()
+*/
+
+void QFileDialogP::setDir( const QDir &dir )
+{
+ d->oldUrl = d->url;
+ QString nf( d->url.nameFilter() );
+ d->url = dir.canonicalPath();
+ d->url.setNameFilter( nf );
+ QUrlInfo i( d->url, nameEdit->text() );
+ d->checkForFilter = TRUE;
+ trySetSelection( i.isDir(), QUrlOperator( d->url, QFileDialogPrivate::encodeFileName(nameEdit->text() ) ), FALSE );
+ d->checkForFilter = FALSE;
+ rereadDir();
+ emit dirEntered( d->url.path() );
+}
+
+/*!
+ Sets the file dialog's working directory to the directory specified at \a url.
+
+ \sa url()
+*/
+
+void QFileDialogP::setUrl( const QUrlOperator &url )
+{
+ QString nf = d->url.nameFilter();
+
+ d->url = QUrl( d->url, url.toString( FALSE, FALSE ) );
+ d->url.setNameFilter( nf );
+
+ d->checkForFilter = TRUE;
+ if ( !d->url.isDir() ) {
+ QUrlOperator u = d->url;
+ d->url.setPath( d->url.dirPath() );
+ trySetSelection( FALSE, u, FALSE );
+ rereadDir();
+ emit dirEntered( d->url.dirPath() );
+ QString fn = u.fileName();
+ nameEdit->setText( fn );
+ } else {
+ trySetSelection( TRUE, d->url, FALSE );
+ rereadDir();
+ emit dirEntered( d->url.dirPath() );
+ }
+ d->checkForFilter = FALSE;
+}
+
+/*!
+ \property QFileDialogP::showHiddenFiles
+
+ \brief whether hidden files are shown in the file dialog
+
+ The default is FALSE, i.e. don't show hidden files.
+*/
+
+void QFileDialogP::setShowHiddenFiles( bool s )
+{
+ if ( s == bShowHiddenFiles )
+ return;
+
+ bShowHiddenFiles = s;
+ rereadDir();
+}
+
+bool QFileDialogP::showHiddenFiles() const
+{
+ return bShowHiddenFiles;
+}
+
+/*!
+ Rereads the current directory shown in the file dialog.
+
+ The only time you will need to call this function is if the contents of
+ the directory change and you wish to refresh the file dialog to reflect
+ the change.
+
+ \sa resortDir()
+*/
+
+void QFileDialogP::rereadDir()
+{
+ if ( !QApplication::overrideCursor() )
+ QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
+ d->pendingItems.clear();
+ if ( d->mimeTypeTimer->isActive() )
+ d->mimeTypeTimer->stop();
+ d->currListChildren = d->url.listChildren();
+}
+
+
+/*!
+ \fn void QFileDialogP::fileHighlighted( const QString& )
+
+ This signal is emitted when the user highlights a file.
+
+ \sa fileSelected(), filesSelected()
+*/
+
+/*!
+ \fn void QFileDialogP::fileSelected( const QString& )
+
+ This signal is emitted when the user selects a file.
+
+ \sa filesSelected(), fileHighlighted(), selectedFile()
+*/
+
+/*!
+ \fn void QFileDialogP::filesSelected( const QStringList& )
+
+ This signal is emitted when the user selects one or more files in \e
+ ExistingFiles mode.
+
+ \sa fileSelected(), fileHighlighted(), selectedFiles()
+*/
+
+/*!
+ \fn void QFileDialogP::dirEntered( const QString& )
+
+ This signal is emitted when the user enters a directory.
+
+ \sa dir()
+*/
+
+/*!
+ \fn void QFileDialogP::filterSelected( const QString& )
+
+ This signal is emitted when the user selects a filter.
+
+ \sa selectedFilter()
+*/
+
+extern bool qt_resolve_symlinks; // defined in qapplication.cpp
+
+/*!
+ This is a convenience static function that returns an existing file
+ selected by the user. If the user pressed Cancel, it returns a null
+ string.
+
+ \code
+ QString s = QFileDialogP::getOpenFileName(
+ "/home",
+ "Images (*.png *.xpm *.jpg)",
+ this,
+ "open file dialog",
+ "Choose a file to open" );
+ \endcode
+
+ The function creates a modal file dialog called \a name, with
+ parent, \a parent. If a parent is not 0, the dialog will be shown
+ centered over the parent.
+
+ The file dialog's working directory will be set to \a startWith. If \a
+ startWith includes a file name, the file will be selected. The filter
+ is set to \a filter so that only those files which match the filter
+ are shown. The filter selected is set to \a selectedFilter. The parameters
+ \a startWith, \a selectedFilter and \a filter may be QString::null.
+
+ The dialog's caption is set to \a caption. If \a caption is not
+ specified then a default caption will be used.
+
+ Under Windows and Mac OS X, this static function will use the native
+ file dialog and not a QFileDialogP, unless the style of the application
+ is set to something other than the native style.
+
+ Under Unix/X11, the normal behavior of the file dialog is to resolve
+ and follow symlinks. For example, if /usr/tmp is a symlink to /var/tmp,
+ the file dialog will change to /var/tmp after entering /usr/tmp.
+ If \a resolveSymlinks is FALSE, the file dialog will treat
+ symlinks as regular directories.
+
+ \sa getOpenFileNames(), getSaveFileName(), getExistingDirectory()
+*/
+
+QString QFileDialogP::getOpenFileName( const QString & startWith,
+ const QString& filter,
+ QWidget *parent, const char* name,
+ const QString& caption,
+ QString *selectedFilter,
+ bool resolveSymlinks )
+{
+ bool save_qt_resolve_symlinks = qt_resolve_symlinks;
+ qt_resolve_symlinks = resolveSymlinks;
+
+ QStringList filters;
+ if ( !filter.isEmpty() )
+ filters = makeFiltersList( filter );
+
+ makeVariables();
+ QString initialSelection;
+ //### Problem with the logic here: If a startWith is given and a file
+ // with that name exists in D->URL, the box will be opened at D->URL instead of
+ // the last directory used ('workingDirectory').
+ //
+ // hm... isn't that problem exactly the documented behaviour? the
+ // documented behaviour sounds meaningful.
+ if ( !startWith.isEmpty() ) {
+ QUrlOperator u( startWith );
+ if ( u.isLocalFile() && QFileInfo( u.path() ).isDir() ) {
+ *workingDirectory = startWith;
+ } else {
+ if ( u.isLocalFile() ) {
+ QFileInfo fi( u.dirPath() );
+ if ( fi.exists() ) {
+ *workingDirectory = u.dirPath();
+ initialSelection = u.fileName();
+ }
+ } else {
+ *workingDirectory = u.toString();
+ initialSelection = QString::null;//u.fileName();
+ }
+ }
+ }
+
+ if ( workingDirectory->isNull() )
+ *workingDirectory = QDir::currentDirPath();
+
+#if defined(Q_WS_WIN)
+ if ( qApp->style().styleHint( QStyle::SH_GUIStyle ) == WindowsStyle )
+ return winGetOpenFileName( initialSelection, filter, workingDirectory,
+ parent, name, caption, selectedFilter );
+#elif defined(Q_WS_MAC)
+ if( ( qApp->style().inherits(QMAC_DEFAULT_STYLE) ) ) {
+ QString f = macGetOpenFileNames(filter, workingDirectory,
+ parent, name, caption, FALSE).first();
+ return f;
+ }
+#endif
+
+ QFileDialogP *dlg = new QFileDialogP( *workingDirectory, QString::null, parent, name ? name : "qt_filedlg_gofn", TRUE );
+
+#ifndef QT_NO_WIDGET_TOPEXTRA
+ if ( parent && parent->icon() && !parent->icon()->isNull() )
+ dlg->setIcon( *parent->icon() );
+ else if ( qApp->mainWidget() && qApp->mainWidget()->icon() && !qApp->mainWidget()->icon()->isNull() )
+ dlg->setIcon( *qApp->mainWidget()->icon() );
+
+ if ( !caption.isNull() )
+ dlg->setCaption( caption );
+ else
+ dlg->setCaption( QFileDialogP::tr( "Open" ) );
+#endif
+
+ dlg->setFilters( filters );
+ if ( selectedFilter )
+ dlg->setFilter( *selectedFilter );
+ dlg->setMode( QFileDialogP::ExistingFile );
+ QString result;
+ if ( !initialSelection.isEmpty() )
+ dlg->setSelection( initialSelection );
+ if ( dlg->exec() == QDialog::Accepted ) {
+ result = dlg->selectedFile();
+ *workingDirectory = dlg->d->url;
+ if ( selectedFilter )
+ *selectedFilter = dlg->selectedFilter();
+ }
+ delete dlg;
+
+ qt_resolve_symlinks = save_qt_resolve_symlinks;
+
+ return result;
+}
+
+/*!
+ This is a convenience static function that will return a file name
+ selected by the user. The file does not have to exist.
+
+ It creates a modal file dialog called \a name, with parent, \a parent.
+ If a parent is not 0, the dialog will be shown centered over the
+ parent.
+
+ \code
+ QString s = QFileDialogP::getSaveFileName(
+ "/home",
+ "Images (*.png *.xpm *.jpg)",
+ this,
+ "save file dialog"
+ "Choose a filename to save under" );
+ \endcode
+
+ The file dialog's working directory will be set to \a startWith. If \a
+ startWith includes a file name, the file will be selected. The filter
+ is set to \a filter so that only those files which match the filter
+ are shown. The filter selected is set to \a selectedFilter. The parameters
+ \a startWith, \a selectedFilter and \a filter may be QString::null.
+
+ The dialog's caption is set to \a caption. If \a caption is not
+ specified then a default caption will be used.
+
+ Under Windows and Mac OS X, this static function will use the native
+ file dialog and not a QFileDialogP, unless the style of the application
+ is set to something other than the native style.
+
+ Under Unix/X11, the normal behavior of the file dialog is to resolve
+ and follow symlinks. For example, if /usr/tmp is a symlink to /var/tmp,
+ the file dialog will change to /var/tmp after entering /usr/tmp.
+ If \a resolveSymlinks is FALSE, the file dialog will treat
+ symlinks as regular directories.
+
+ \sa getOpenFileName(), getOpenFileNames(), getExistingDirectory()
+*/
+
+QString QFileDialogP::getSaveFileName( const QString & startWith,
+ const QString& filter,
+ QWidget *parent, const char* name,
+ const QString& caption,
+ QString *selectedFilter,
+ bool resolveSymlinks)
+{
+ bool save_qt_resolve_symlinks = qt_resolve_symlinks;
+ qt_resolve_symlinks = resolveSymlinks;
+
+ QStringList filters;
+ if ( !filter.isEmpty() )
+ filters = makeFiltersList( filter );
+
+ makeVariables();
+ QString initialSelection;
+ if ( !startWith.isEmpty() ) {
+ QUrlOperator u( startWith );
+ if ( u.isLocalFile() && QFileInfo( u.path() ).isDir() ) {
+ *workingDirectory = startWith;
+ } else {
+ if ( u.isLocalFile() ) {
+ QFileInfo fi( u.dirPath() );
+ if ( fi.exists() ) {
+ *workingDirectory = u.dirPath();
+ initialSelection = u.fileName();
+ }
+ } else {
+ *workingDirectory = u.toString();
+ initialSelection = QString::null;//u.fileName();
+ }
+ }
+ }
+
+ if ( workingDirectory->isNull() )
+ *workingDirectory = QDir::currentDirPath();
+
+#if defined(Q_WS_WIN)
+ if ( qApp->style().styleHint( QStyle::SH_GUIStyle ) == WindowsStyle )
+ return winGetSaveFileName( initialSelection, filter, workingDirectory,
+ parent, name, caption, selectedFilter );
+#elif defined(Q_WS_MAC)
+ if( ( qApp->style().inherits(QMAC_DEFAULT_STYLE) ) )
+ return macGetSaveFileName( initialSelection, filter, workingDirectory,
+ parent, name, caption );
+#endif
+
+ QFileDialogP *dlg = new QFileDialogP( *workingDirectory, QString::null, parent, name ? name : "qt_filedlg_gsfn", TRUE );
+
+ Q_CHECK_PTR( dlg );
+#ifndef QT_NO_WIDGET_TOPEXTRA
+ if ( parent && parent->icon() && !parent->icon()->isNull() )
+ dlg->setIcon( *parent->icon() );
+ else if ( qApp->mainWidget() && qApp->mainWidget()->icon() && !qApp->mainWidget()->icon()->isNull() )
+ dlg->setIcon( *qApp->mainWidget()->icon() );
+
+ if ( !caption.isNull() )
+ dlg->setCaption( caption );
+ else
+ dlg->setCaption( QFileDialogP::tr( "Save As" ) );
+#endif
+
+ QString result;
+ dlg->setFilters( filters );
+ if ( selectedFilter )
+ dlg->setFilter( *selectedFilter );
+ dlg->setMode( QFileDialogP::AnyFile );
+ if ( !initialSelection.isEmpty() )
+ dlg->setSelection( initialSelection );
+ if ( dlg->exec() == QDialog::Accepted ) {
+ result = dlg->selectedFile();
+ *workingDirectory = dlg->d->url;
+ if ( selectedFilter )
+ *selectedFilter = dlg->selectedFilter();
+ }
+ delete dlg;
+
+ qt_resolve_symlinks = save_qt_resolve_symlinks;
+
+ return result;
+}
+
+/*!
+ \internal
+ Activated when the "OK" button is clicked.
+*/
+
+void QFileDialogP::okClicked()
+{
+ QString fn( nameEdit->text() );
+
+#if defined(Q_WS_WIN)
+ QFileInfo fi( d->url.path() + fn );
+ if ( fi.isSymLink() ) {
+ nameEdit->setText( fi.readLink() );
+ }
+#endif
+
+ if ( fn.contains("*") ) {
+ addFilter( fn );
+ nameEdit->blockSignals( TRUE );
+ nameEdit->setText( QString::fromLatin1("") );
+ nameEdit->blockSignals( FALSE );
+ return;
+ }
+
+ *workingDirectory = d->url;
+ detailViewMode = files->isVisible();
+ *lastSize = size();
+
+ if ( isDirectoryMode( d->mode ) ) {
+ if ( d->ignoreReturn ) {
+ d->ignoreReturn = FALSE;
+ return;
+ }
+ QUrlInfo f( d->url, nameEdit->text() );
+ if ( f.isDir() ) {
+ d->currentFileName = d->url;
+ if ( d->currentFileName.right(1) != "/" )
+ d->currentFileName += '/';
+ if ( f.name() != "." )
+ d->currentFileName += f.name();
+ accept();
+ return;
+ }
+ }
+
+ // if we're in multi-selection mode and something is selected,
+ // accept it and be done.
+ if ( mode() == ExistingFiles ) {
+ if ( ! nameEdit->text().isEmpty() ) {
+ QStringList sf = selectedFiles();
+ bool isdir = FALSE;
+ if ( sf.count() == 1 ) {
+ QUrlOperator u( d->url, sf[0] );
+ bool ok;
+ isdir = u.isDir(&ok) && ok;
+ }
+ if ( !isdir ) {
+ emit filesSelected( sf );
+ accept();
+ return;
+ }
+ }
+ }
+
+ if ( mode() == AnyFile ) {
+ QUrlOperator u( d->url, QFileDialogPrivate::encodeFileName(nameEdit->text()) );
+ if ( !u.isDir() ) {
+ d->currentFileName = u;
+ emit fileSelected( selectedFile() );
+ accept();
+ return;
+ }
+ }
+
+ if ( mode() == ExistingFile ) {
+ QUrl u( d->url, QFileDialogPrivate::encodeFileName(nameEdit->text()) );
+ if ( u.isLocalFile() ) {
+ QFileInfo f( u.path() );
+ if ( !f.exists() )
+ return;
+ } else {
+ QNetworkProtocol *p = QNetworkProtocol::getNetworkProtocol( d->url.protocol() );
+ if ( p && (p->supportedOperations()&QNetworkProtocol::OpListChildren) ) {
+ QUrlInfo ui( d->url, nameEdit->text() );
+ if ( !ui.isValid() )
+ return;
+ }
+ }
+ }
+
+ // If selection is valid, return it, else try
+ // using selection as a directory to change to.
+ if ( !d->currentFileName.isNull() && !d->currentFileName.contains( "*" ) ) {
+ emit fileSelected( selectedFile() );
+ accept();
+ } else {
+ QUrlInfo f;
+ QFileDialogPrivate::File * c
+ = (QFileDialogPrivate::File *)files->currentItem();
+ QFileDialogPrivate::MCItem * m
+ = (QFileDialogPrivate::MCItem *)d->moreFiles->item( d->moreFiles->currentItem() );
+ if ( c && files->isVisible() && files->hasFocus() ||
+ m && d->moreFiles->isVisible() && d->moreFiles->hasFocus() ) {
+ if ( c && files->isVisible() )
+ f = c->info;
+ else
+ f = ( (QFileDialogPrivate::File*)m->i )->info;
+ } else {
+ f = QUrlInfo( d->url, nameEdit->text() );
+ }
+ if ( f.isDir() ) {
+ setUrl( QUrlOperator( d->url, QFileDialogPrivate::encodeFileName(f.name() + "/" ) ) );
+ d->checkForFilter = TRUE;
+ trySetSelection( TRUE, d->url, TRUE );
+ d->checkForFilter = FALSE;
+ } else {
+ if ( !nameEdit->text().contains( "/" ) &&
+ !nameEdit->text().contains( "\\" )
+#if defined(Q_OS_WIN32)
+ && nameEdit->text()[ 1 ] != ':'
+#endif
+ )
+ addFilter( nameEdit->text() );
+ else if ( nameEdit->text()[ 0 ] == '/' ||
+ nameEdit->text()[ 0 ] == '\\'
+#if defined(Q_OS_WIN32)
+ || nameEdit->text()[ 1 ] == ':'
+#endif
+ )
+ setDir( nameEdit->text() );
+ else if ( nameEdit->text().left( 3 ) == "../" || nameEdit->text().left( 3 ) == "..\\" )
+ setDir( QUrl( d->url.toString(), QFileDialogPrivate::encodeFileName(nameEdit->text() ) ).toString() );
+ }
+ nameEdit->setText( "" );
+ }
+}
+
+/*!
+ \internal
+ Activated when the "Filter" button is clicked.
+*/
+
+void QFileDialogP::filterClicked()
+{
+ // unused
+}
+
+/*!
+ \internal
+ Activated when the "Cancel" button is clicked.
+*/
+
+void QFileDialogP::cancelClicked()
+{
+ *workingDirectory = d->url;
+ detailViewMode = files->isVisible();
+ *lastSize = size();
+ reject();
+}
+
+
+/*!\reimp
+*/
+
+void QFileDialogP::resizeEvent( QResizeEvent * e )
+{
+ QDialog::resizeEvent( e );
+ updateGeometries();
+}
+
+/*
+ \internal
+ The only correct way to try to set currentFileName
+*/
+bool QFileDialogP::trySetSelection( bool isDir, const QUrlOperator &u, bool updatelined )
+{
+ if ( !isDir && !u.path().isEmpty() && u.path().right( 1 ) == "/" )
+ isDir = TRUE;
+ if ( u.fileName().contains( "*") && d->checkForFilter ) {
+ QString fn( u.fileName() );
+ if ( fn.contains( "*" ) ) {
+ addFilter( fn );
+ d->currentFileName = QString::null;
+ d->url.setFileName( QString::null );
+ nameEdit->setText( QString::fromLatin1("") );
+ return FALSE;
+ }
+ }
+
+ if ( isDir ) {
+ if ( d->preview && d->preview->isVisible() ) {
+ if ( d->infoPreviewer )
+ d->infoPreviewer->previewUrl( u );
+ if ( d->contentsPreviewer )
+ d->contentsPreviewer->previewUrl( u );
+ }
+ }
+
+ QString old = d->currentFileName;
+
+ if ( isDirectoryMode( mode() ) ) {
+ if ( isDir )
+ d->currentFileName = u;
+ else
+ d->currentFileName = QString::null;
+ } else if ( !isDir && mode() == ExistingFiles ) {
+ d->currentFileName = u;
+ } else if ( !isDir || ( mode() == AnyFile && !isDir ) ) {
+ d->currentFileName = u;
+ } else {
+ d->currentFileName = QString::null;
+ }
+ if ( updatelined && !d->currentFileName.isEmpty() ) {
+ // If the selection is valid, or if its a directory, allow OK.
+ if ( !d->currentFileName.isNull() || isDir ) {
+ if ( u.fileName() != ".." ) {
+ QString fn = u.fileName();
+ nameEdit->setText( fn );
+ } else {
+ nameEdit->setText("");
+ }
+ } else
+ nameEdit->setText( QString::fromLatin1("") );
+ }
+
+ if ( !d->currentFileName.isNull() || isDir ) {
+ okB->setEnabled( TRUE );
+ } else if ( !isDirectoryMode( d->mode ) ) {
+ okB->setEnabled( FALSE );
+ }
+
+ if ( d->currentFileName.length() && old != d->currentFileName )
+ emit fileHighlighted( selectedFile() );
+
+ return !d->currentFileName.isNull();
+}
+
+
+/*! Make sure the minimum and maximum sizes of everything are sane.
+*/
+
+void QFileDialogP::updateGeometries()
+{
+ if ( !d || !d->geometryDirty )
+ return;
+
+ d->geometryDirty = FALSE;
+
+ QSize r, t;
+
+ // we really should have a QSize::unite()
+#define RM r.setWidth( QMAX(r.width(),t.width()) ); \
+r.setHeight( QMAX(r.height(),t.height()) )
+
+ // labels first
+ r = d->pathL->sizeHint();
+ t = d->fileL->sizeHint();
+ RM;
+ t = d->typeL->sizeHint();
+ RM;
+ d->pathL->setFixedSize( d->pathL->sizeHint() );
+ d->fileL->setFixedSize( r );
+ d->typeL->setFixedSize( r );
+
+ // single-line input areas
+ r = d->paths->sizeHint();
+ t = nameEdit->sizeHint();
+ RM;
+ t = d->types->sizeHint();
+ RM;
+ r.setWidth( t.width() * 2 / 3 );
+ t.setWidth( QWIDGETSIZE_MAX );
+ t.setHeight( r.height() );
+ d->paths->setMinimumSize( r );
+ d->paths->setMaximumSize( t );
+ nameEdit->setMinimumSize( r );
+ nameEdit->setMaximumSize( t );
+ d->types->setMinimumSize( r );
+ d->types->setMaximumSize( t );
+
+ // buttons on top row
+ r = QSize( 0, d->paths->minimumSize().height() );
+ t = QSize( 21, 20 );
+ RM;
+ if ( r.height()+1 > r.width() )
+ r.setWidth( r.height()+1 );
+ if ( d->goBack )
+ d->goBack->setFixedSize( r );
+ d->cdToParent->setFixedSize( r );
+ d->newFolder->setFixedSize( r );
+ d->mcView->setFixedSize( r );
+ d->detailView->setFixedSize( r );
+
+ QButton *b = 0;
+ if ( !d->toolButtons.isEmpty() ) {
+ for ( b = d->toolButtons.first(); b; b = d->toolButtons.next() )
+ b->setFixedSize( b->sizeHint().width(), r.height() );
+ }
+
+ if ( d->infoPreview ) {
+ d->previewInfo->show();
+ d->previewInfo->setFixedSize( r );
+ } else {
+ d->previewInfo->hide();
+ d->previewInfo->setFixedSize( QSize( 0, 0 ) );
+ }
+
+ if ( d->contentsPreview ) {
+ d->previewContents->show();
+ d->previewContents->setFixedSize( r );
+ } else {
+ d->previewContents->hide();
+ d->previewContents->setFixedSize( QSize( 0, 0 ) );
+ }
+
+ // open/save, cancel
+ r = QSize( 75, 20 );
+ t = okB->sizeHint();
+ RM;
+ t = cancelB->sizeHint();
+ RM;
+
+ okB->setFixedSize( r );
+ cancelB->setFixedSize( r );
+
+ d->topLevelLayout->activate();
+
+#undef RM
+}
+
+
+/*! Updates the file name edit box to \a newItem in the file dialog
+ when the cursor moves in the listview.
+*/
+
+void QFileDialogP::updateFileNameEdit( QListViewItem * newItem )
+{
+ if ( !newItem )
+ return;
+
+ if ( mode() == ExistingFiles ) {
+ detailViewSelectionChanged();
+ QUrl u = QUrl( d->url, QFileDialogPrivate::encodeFileName( ((QFileDialogPrivate::File*)files->currentItem())->info.name() ) );
+ QFileInfo fi( u.toString( FALSE, FALSE ) );
+ if ( !fi.isDir() )
+ emit fileHighlighted( u.toString( FALSE, FALSE ) );
+ } else if ( files->isSelected( newItem ) ) {
+ QFileDialogPrivate::File * i = (QFileDialogPrivate::File *)newItem;
+ if ( i && i->i && !i->i->isSelected() ) {
+ d->moreFiles->blockSignals( TRUE );
+ d->moreFiles->setSelected( i->i, TRUE );
+ d->moreFiles->blockSignals( FALSE );
+ }
+ // Encode the filename in case it had any special characters in it
+ QString encFile = QFileDialogPrivate::encodeFileName( newItem->text( 0 ) );
+ trySetSelection( i->info.isDir(), QUrlOperator( d->url, encFile ), TRUE );
+ }
+}
+
+void QFileDialogP::detailViewSelectionChanged()
+{
+ if ( d->mode != ExistingFiles )
+ return;
+
+ nameEdit->clear();
+ QString str;
+ QListViewItem * i = files->firstChild();
+ d->moreFiles->blockSignals( TRUE );
+ while( i ) {
+ if ( d->moreFiles && isVisible() ) {
+ if ( ( (QFileDialogPrivate::File *)i )->i->isSelected() != i->isSelected() )
+ d->moreFiles->setSelected( ( (QFileDialogPrivate::File *)i )->i, i->isSelected() );
+ }
+ if ( i->isSelected() && !( (QFileDialogPrivate::File *)i )->info.isDir() )
+ str += QString( "\"%1\" " ).arg( i->text( 0 ) );
+ i = i->nextSibling();
+ }
+ d->moreFiles->blockSignals( FALSE );
+ nameEdit->setText( str );
+ nameEdit->setCursorPosition( str.length() );
+ okB->setEnabled( TRUE );
+ if ( d->preview && d->preview->isVisible() && files->currentItem() ) {
+ QUrl u = QUrl( d->url, QFileDialogPrivate::encodeFileName( ((QFileDialogPrivate::File*)files->currentItem())->info.name() ) );
+ if ( d->infoPreviewer )
+ d->infoPreviewer->previewUrl( u );
+ if ( d->contentsPreviewer )
+ d->contentsPreviewer->previewUrl( u );
+ }
+}
+
+void QFileDialogP::listBoxSelectionChanged()
+{
+ if ( d->mode != ExistingFiles )
+ return;
+
+ if ( d->ignoreNextRefresh ) {
+ d->ignoreNextRefresh = FALSE;
+ return;
+ }
+
+ nameEdit->clear();
+ QString str;
+ QListBoxItem * i = d->moreFiles->item( 0 );
+ QListBoxItem * j = 0;
+ int index = 0;
+ files->blockSignals( TRUE );
+ while( i ) {
+ if ( files && isVisible() ) {
+ if ( ( (QFileDialogPrivate::MCItem *)i )->i->isSelected() != i->isSelected() )
+ files->setSelected( ( (QFileDialogPrivate::MCItem *)i )->i, i->isSelected() );
+ }
+ if ( d->moreFiles->isSelected( i )
+ && !( (QFileDialogPrivate::File*)( (QFileDialogPrivate::MCItem *)i )->i )->info.isDir() )
+ {
+ str += QString( "\"%1\" " ).arg( i->text() );
+ if ( j == 0 )
+ j = i;
+ }
+ i = d->moreFiles->item( ++index );
+ }
+ files->blockSignals( FALSE );
+ nameEdit->setText( str );
+ nameEdit->setCursorPosition( str.length() );
+ okB->setEnabled( TRUE );
+ if ( d->preview && d->preview->isVisible() && j ) {
+ QUrl u = QUrl( d->url,
+ QFileDialogPrivate::encodeFileName( ( (QFileDialogPrivate::File*)( (QFileDialogPrivate::MCItem*)j )->i )->info.name() ) );
+ if ( d->infoPreviewer )
+ d->infoPreviewer->previewUrl( u );
+ if ( d->contentsPreviewer )
+ d->contentsPreviewer->previewUrl( u );
+ }
+}
+
+/*! \overload */
+
+void QFileDialogP::updateFileNameEdit( QListBoxItem * newItem )
+{
+ if ( !newItem )
+ return;
+ QFileDialogPrivate::MCItem * i = (QFileDialogPrivate::MCItem *)newItem;
+ if ( d->mode != ExistingFiles && i->i ) {
+ i->i->listView()->setSelected( i->i, i->isSelected() );
+ updateFileNameEdit( i->i );
+ }
+}
+
+
+/*! Updates the dialog when the file name edit changes. */
+
+void QFileDialogP::fileNameEditDone()
+{
+ QUrlInfo f( d->url, nameEdit->text() );
+ if ( mode() != QFileDialogP::ExistingFiles ) {
+ QUrlOperator u( d->url, QFileDialogPrivate::encodeFileName( nameEdit->text() ) );
+ trySetSelection( f.isDir(), u, FALSE );
+ if ( d->preview && d->preview->isVisible() ) {
+ if ( d->infoPreviewer )
+ d->infoPreviewer->previewUrl( u );
+ if ( d->contentsPreviewer )
+ d->contentsPreviewer->previewUrl( u );
+ }
+ }
+}
+
+
+
+/*! This private slot reacts to double-clicks in the list view. The item that
+was double-clicked is specified in \a newItem */
+
+void QFileDialogP::selectDirectoryOrFile( QListViewItem * newItem )
+{
+
+ *workingDirectory = d->url;
+ detailViewMode = files->isVisible();
+ *lastSize = size();
+
+ if ( !newItem )
+ return;
+
+#if defined(Q_WS_WIN)
+ QFileInfo fi( d->url.path() + newItem->text(0) );
+ if ( fi.isSymLink() ) {
+ nameEdit->setText( fi.readLink() );
+ okClicked();
+ return;
+ }
+#endif
+
+ QFileDialogPrivate::File * i = (QFileDialogPrivate::File *)newItem;
+
+ QString oldName = nameEdit->text();
+ if ( i->info.isDir() ) {
+ setUrl( QUrlOperator( d->url, QFileDialogPrivate::encodeFileName( i->info.name() ) + "/" ) );
+ if ( isDirectoryMode( mode() ) ) {
+ QUrlInfo f ( d->url, QString::fromLatin1( "." ) );
+ trySetSelection( f.isDir(), d->url, TRUE );
+ }
+ } else if ( newItem->isSelectable() &&
+ trySetSelection( i->info.isDir(), QUrlOperator( d->url, QFileDialogPrivate::encodeFileName( i->info.name() ) ), TRUE ) ) {
+ if ( !isDirectoryMode( mode() ) ) {
+ emit fileSelected( selectedFile() );
+ accept();
+ }
+ } else if ( isDirectoryMode( d->mode ) ) {
+ d->currentFileName = d->url;
+ accept();
+ }
+ if ( !oldName.isEmpty() && !isDirectoryMode( mode() ) )
+ nameEdit->setText( oldName );
+}
+
+
+void QFileDialogP::selectDirectoryOrFile( QListBoxItem * newItem )
+{
+ if ( !newItem )
+ return;
+
+ QFileDialogPrivate::MCItem * i = (QFileDialogPrivate::MCItem *)newItem;
+ if ( i->i ) {
+ i->i->listView()->setSelected( i->i, i->isSelected() );
+ selectDirectoryOrFile( i->i );
+ }
+}
+
+
+void QFileDialogP::popupContextMenu( QListViewItem *item, const QPoint &p,
+ int )
+{
+ if ( item && d->mode == ExistingFiles )
+ return;
+ if ( item ) {
+ files->setCurrentItem( item );
+ files->setSelected( item, TRUE );
+ }
+
+ PopupAction action;
+ popupContextMenu( item ? item->text( 0 ) : QString::null, TRUE, action, p );
+
+ if ( action == PA_Open )
+ selectDirectoryOrFile( item );
+ else if ( action == PA_Rename )
+ files->startRename( FALSE );
+ else if ( action == PA_Delete )
+ deleteFile( item ? item->text( 0 ) : QString::null );
+ else if ( action == PA_Reload )
+ rereadDir();
+ else if ( action == PA_Hidden ) {
+ bShowHiddenFiles = !bShowHiddenFiles;
+ rereadDir();
+ } else if ( action == PA_SortName ) {
+ sortFilesBy = (int)QDir::Name;
+ sortAscending = TRUE;
+ resortDir();
+ } else if ( action == PA_SortSize ) {
+ sortFilesBy = (int)QDir::Size;
+ sortAscending = TRUE;
+ resortDir();
+ } else if ( action == PA_SortDate ) {
+ sortFilesBy = (int)QDir::Time;
+ sortAscending = TRUE;
+ resortDir();
+ } else if ( action == PA_SortUnsorted ) {
+ sortFilesBy = (int)QDir::Unsorted;
+ sortAscending = TRUE;
+ resortDir();
+ }
+
+}
+
+void QFileDialogP::popupContextMenu( QListBoxItem *item, const QPoint & p )
+{
+ if ( item && d->mode == ExistingFiles )
+ return;
+
+ PopupAction action;
+ popupContextMenu( item ? item->text() : QString::null, FALSE, action, p );
+
+ if ( action == PA_Open )
+ selectDirectoryOrFile( item );
+ else if ( action == PA_Rename )
+ d->moreFiles->startRename( FALSE );
+ else if ( action == PA_Delete )
+ deleteFile( item->text() );
+ else if ( action == PA_Reload )
+ rereadDir();
+ else if ( action == PA_Hidden ) {
+ bShowHiddenFiles = !bShowHiddenFiles;
+ rereadDir();
+ } else if ( action == PA_SortName ) {
+ sortFilesBy = (int)QDir::Name;
+ sortAscending = TRUE;
+ resortDir();
+ } else if ( action == PA_SortSize ) {
+ sortFilesBy = (int)QDir::Size;
+ sortAscending = TRUE;
+ resortDir();
+ } else if ( action == PA_SortDate ) {
+ sortFilesBy = (int)QDir::Time;
+ sortAscending = TRUE;
+ resortDir();
+ } else if ( action == PA_SortUnsorted ) {
+ sortFilesBy = (int)QDir::Unsorted;
+ sortAscending = TRUE;
+ resortDir();
+ }
+}
+
+void QFileDialogP::popupContextMenu( const QString &filename, bool,
+ PopupAction &action, const QPoint &p )
+{
+ action = PA_Cancel;
+
+ bool glob = filename.isEmpty();
+
+ QPopupMenu m( 0, "file dialog context menu" );
+ m.setCheckable( TRUE );
+
+ if ( !glob ) {
+ QString okt;
+ if ( QUrlInfo( d->url, filename ).isDir() ) {
+ okt = tr( "&Open" );
+ } else {
+ if ( mode() == AnyFile )
+ okt = tr( "&Save" );
+ else
+ okt = tr( "&Open" );
+ }
+ int ok = m.insertItem( okt );
+
+ m.insertSeparator();
+ int rename = m.insertItem( tr( "&Rename" ) );
+ int del = m.insertItem( tr( "&Delete" ) );
+
+ if ( filename.isEmpty() || !QUrlInfo( d->url, filename ).isWritable() ||
+ filename == ".." ) {
+ if ( filename.isEmpty() || !QUrlInfo( d->url, filename ).isReadable() )
+ m.setItemEnabled( ok, FALSE );
+ m.setItemEnabled( rename, FALSE );
+ m.setItemEnabled( del, FALSE );
+ }
+
+ if ( mode() == QFileDialogP::ExistingFiles )
+ m.setItemEnabled( rename, FALSE );
+
+ m.move( p );
+ int res = m.exec();
+
+ if ( res == ok )
+ action = PA_Open;
+ else if ( res == rename )
+ action = PA_Rename;
+ else if ( res == del )
+ action = PA_Delete;
+ } else {
+ int reload = m.insertItem( tr( "R&eload" ) );
+
+ QPopupMenu m2( 0, "sort menu" );
+
+ int sname = m2.insertItem( tr( "Sort by &Name" ) );
+ //int stype = m2.insertItem( tr( "Sort by &Type" ) );
+ int ssize = m2.insertItem( tr( "Sort by &Size" ) );
+ int sdate = m2.insertItem( tr( "Sort by &Date" ) );
+ m2.insertSeparator();
+ int sunsorted = m2.insertItem( tr( "&Unsorted" ) );
+
+ //m2.setItemEnabled( stype, FALSE );
+
+ if ( sortFilesBy == (int)QDir::Name )
+ m2.setItemChecked( sname, TRUE );
+ else if ( sortFilesBy == (int)QDir::Size )
+ m2.setItemChecked( ssize, TRUE );
+// else if ( sortFilesBy == 0x16 )
+// m2.setItemChecked( stype, TRUE );
+ else if ( sortFilesBy == (int)QDir::Time )
+ m2.setItemChecked( sdate, TRUE );
+ else if ( sortFilesBy == (int)QDir::Unsorted )
+ m2.setItemChecked( sunsorted, TRUE );
+
+ m.insertItem( tr( "Sort" ), &m2 );
+
+ m.insertSeparator();
+
+ int hidden = m.insertItem( tr( "Show &hidden files" ) );
+ m.setItemChecked( hidden, bShowHiddenFiles );
+
+ m.move( p );
+ int res = m.exec();
+
+ if ( res == reload )
+ action = PA_Reload;
+ else if ( res == hidden )
+ action = PA_Hidden;
+ else if ( res == sname )
+ action = PA_SortName;
+// else if ( res == stype )
+// action = PA_SortType;
+ else if ( res == sdate )
+ action = PA_SortDate;
+ else if ( res == ssize )
+ action = PA_SortSize;
+ else if ( res == sunsorted )
+ action = PA_SortUnsorted;
+ }
+
+}
+
+void QFileDialogP::deleteFile( const QString &filename )
+{
+ if ( filename.isEmpty() )
+ return;
+
+ QUrlInfo fi( d->url, QFileDialogPrivate::encodeFileName( filename ) );
+ QString t = tr( "the file" );
+ if ( fi.isDir() )
+ t = tr( "the directory" );
+ if ( fi.isSymLink() )
+ t = tr( "the symlink" );
+
+ if ( QMessageBox::warning( this,
+ tr( "Delete %1" ).arg( t ),
+ tr( "<qt>Are you sure you wish to delete %1 \"%2\"?</qt>" )
+ .arg( t ).arg(filename),
+ tr( "&Yes" ), tr( "&No" ), QString::null, 1 ) == 0 )
+ d->url.remove( QFileDialogPrivate::encodeFileName( filename ) );
+
+}
+
+void QFileDialogP::fileSelected( int )
+{
+ // unused
+}
+
+void QFileDialogP::fileHighlighted( int )
+{
+ // unused
+}
+
+void QFileDialogP::dirSelected( int )
+{
+ // unused
+}
+
+void QFileDialogP::pathSelected( int )
+{
+ // unused
+}
+
+
+void QFileDialogP::cdUpClicked()
+{
+ QString oldName = nameEdit->text();
+ setUrl( QUrlOperator( d->url, ".." ) );
+ if ( !oldName.isEmpty() )
+ nameEdit->setText( oldName );
+}
+
+void QFileDialogP::newFolderClicked()
+{
+ QString foldername( tr( "New Folder 1" ) );
+ int i = 0;
+ QStringList lst;
+ QListViewItemIterator it( files );
+ for ( ; it.current(); ++it )
+ if ( it.current()->text( 0 ).contains( tr( "New Folder" ) ) )
+ lst.append( it.current()->text( 0 ) );
+
+ if ( !lst.count() == 0 )
+ while ( lst.contains( foldername ) )
+ foldername = tr( "New Folder %1" ).arg( ++i );
+
+ d->url.mkdir( foldername );
+}
+
+void QFileDialogP::createdDirectory( const QUrlInfo &info, QNetworkOperation * )
+{
+ resortDir();
+ if ( d->moreFiles->isVisible() ) {
+ for ( uint i = 0; i < d->moreFiles->count(); ++i ) {
+ if ( d->moreFiles->text( i ) == info.name() ) {
+ d->moreFiles->setCurrentItem( i );
+ d->moreFiles->startRename( FALSE );
+ break;
+ }
+ }
+ } else {
+ QListViewItem *item = files->firstChild();
+ while ( item ) {
+ if ( item->text( 0 ) == info.name() ) {
+ files->setSelected( item, TRUE );
+ files->setCurrentItem( item );
+ files->startRename( FALSE );
+ break;
+ }
+ item = item->nextSibling();
+ }
+ }
+}
+
+
+/*!
+ This is a convenience static function that will return an existing directory
+ selected by the user.
+
+ \code
+ QString s = QFileDialogP::getExistingDirectory(
+ "/home",
+ this,
+ "get existing directory"
+ "Choose a directory",
+ TRUE );
+ \endcode
+
+ This function creates a modal file dialog called \a name, with
+ parent, \a parent. If parent is not 0, the dialog will be shown
+ centered over the parent.
+
+ The dialog's working directory is set to \a dir, and the caption is
+ set to \a caption. Either of these may be QString::null in which case
+ the current directory and a default caption will be used respectively.
+
+ If \a dirOnly is TRUE, then only directories will be shown in
+ the file dialog; otherwise both directories and files will be shown.
+
+ Under Unix/X11, the normal behavior of the file dialog is to resolve
+ and follow symlinks. For example, if /usr/tmp is a symlink to /var/tmp,
+ the file dialog will change to /var/tmp after entering /usr/tmp.
+ If \a resolveSymlinks is FALSE, the file dialog will treat
+ symlinks as regular directories.
+
+ \sa getOpenFileName(), getOpenFileNames(), getSaveFileName()
+*/
+
+QString QFileDialogP::getExistingDirectory( const QString & dir,
+ QWidget *parent,
+ const char* name,
+ const QString& caption,
+ bool dirOnly,
+ bool resolveSymlinks)
+{
+ bool save_qt_resolve_symlinks = qt_resolve_symlinks;
+ qt_resolve_symlinks = resolveSymlinks;
+
+ makeVariables();
+ QString wd;
+ if ( workingDirectory )
+ wd = *workingDirectory;
+
+#if defined(Q_WS_WIN)
+ QString initialDir;
+ if ( !dir.isEmpty() ) {
+ QUrlOperator u( dir );
+ if ( QFileInfo( u.path() ).isDir() )
+ initialDir = dir;
+ } else
+ initialDir = QString::null;
+ if ( qApp->style().styleHint( QStyle::SH_GUIStyle ) == WindowsStyle && dirOnly )
+ return winGetExistingDirectory( initialDir, parent, name, caption );
+#endif
+#if defined(Q_WS_MAC)
+ if( ( qApp->style().inherits(QMAC_DEFAULT_STYLE) ) )
+ return macGetOpenFileNames("", 0,
+ parent, name, caption, FALSE, TRUE).first();
+#endif
+
+ QFileDialogP *dialog = new QFileDialogP( parent, name ? name : "qt_filedlg_ged", TRUE );
+#ifndef QT_NO_WIDGET_TOPEXTRA
+ if ( !caption.isNull() )
+ dialog->setCaption( caption );
+ else
+ dialog->setCaption( QFileDialogP::tr("Find Directory") );
+#endif
+
+ dialog->setMode( dirOnly ? DirectoryOnly : Directory );
+
+ dialog->d->types->clear();
+ dialog->d->types->insertItem( QFileDialogP::tr("Directories") );
+ dialog->d->types->setEnabled( FALSE );
+
+ QString dir_( dir );
+ dir_ = dir_.simplifyWhiteSpace();
+ if ( dir_.isEmpty() && !wd.isEmpty() )
+ dir_ = wd;
+ QUrlOperator u( dir_ );
+ if ( u.isLocalFile() ) {
+ if ( !dir_.isEmpty() ) {
+ QFileInfo f( u.path() );
+ if ( f.exists() )
+ if ( f.isDir() ) {
+ dialog->setDir( dir_ );
+ wd = dir_;
+ }
+ } else if ( !wd.isEmpty() ) {
+ QUrl tempUrl( wd );
+ QFileInfo f( tempUrl.path() );
+ if ( f.isDir() ) {
+ dialog->setDir( wd );
+ }
+ } else {
+ QString theDir = dir_;
+ if ( theDir.isEmpty() ) {
+ theDir = QDir::currentDirPath();
+ } if ( !theDir.isEmpty() ) {
+ QUrl tempUrl( theDir );
+ QFileInfo f( tempUrl.path() );
+ if ( f.isDir() ) {
+ wd = theDir;
+ dialog->setDir( theDir );
+ }
+ }
+ }
+ } else {
+ dialog->setUrl( dir_ );
+ }
+
+ QString result;
+ dialog->setSelection( dialog->d->url.toString() );
+
+ if ( dialog->exec() == QDialog::Accepted ) {
+ result = dialog->selectedFile();
+ wd = result;
+ }
+ delete dialog;
+
+ if ( !result.isEmpty() && result.right( 1 ) != "/" )
+ result += "/";
+
+ qt_resolve_symlinks = save_qt_resolve_symlinks;
+
+ return result;
+}
+
+
+/*!
+ \property QFileDialogP::mode
+ \brief the file dialog's mode
+
+ The default mode is \c ExistingFile.
+*/
+
+void QFileDialogP::setMode( Mode newMode )
+{
+ if ( d->mode != newMode ) {
+ d->mode = newMode;
+ QString sel = d->currentFileName;
+ if ( isDirectoryMode( newMode ) ) {
+ files->setMultiSelection( FALSE );
+ d->moreFiles->setMultiSelection( FALSE );
+ if ( sel.isNull() )
+ sel = QString::fromLatin1(".");
+ d->types->setEnabled( FALSE );
+ } else if ( newMode == ExistingFiles ) {
+ files->setSelectionMode( QListView::Extended );
+ d->moreFiles->setSelectionMode( QListBox::Extended );
+ d->types->setEnabled( TRUE );
+ } else {
+ files->setMultiSelection( FALSE );
+ d->moreFiles->setMultiSelection( FALSE );
+ d->types->setEnabled( TRUE );
+ }
+ rereadDir();
+ QUrlInfo f( d->url, "." );
+ trySetSelection( f.isDir(), d->url, FALSE );
+ }
+
+ QString okt;
+ bool changeFilters = FALSE;
+ if ( mode() == AnyFile ) {
+ okt = tr("Save");
+ d->fileL->setText( tr("File &name:") );
+ if ( d->types->count() == 1 ) {
+ d->types->setCurrentItem( 0 );
+ if ( d->types->currentText() == "Directories" ) {
+ changeFilters = TRUE;
+ }
+ }
+ }
+ else if ( mode() == Directory || mode() == DirectoryOnly ) {
+ okt = tr("OK");
+ d->fileL->setText( tr("Directory:") );
+ d->types->clear();
+ d->types->insertItem( tr("Directories") );
+ }
+ else {
+ okt = tr("Open");
+ d->fileL->setText( tr("File &name:") );
+ if ( d->types->count() == 1 ) {
+ d->types->setCurrentItem( 0 );
+ if ( d->types->currentText() == "Directories" ) {
+ changeFilters = TRUE;
+ }
+ }
+ }
+
+ if ( changeFilters ) {
+ d->types->clear();
+ d->types->insertItem( tr("All Files (*)") );
+ }
+
+ okB->setText( okt );
+}
+
+QFileDialogP::Mode QFileDialogP::mode() const
+{
+ return d->mode;
+}
+
+/*! \reimp
+*/
+
+void QFileDialogP::done( int i )
+{
+ if ( i == QDialog::Accepted && (d->mode == ExistingFile || d->mode == ExistingFiles) ) {
+ QStringList selection = selectedFiles();
+ for ( uint f = 0; f < selection.count(); f++ ) {
+ QString file = selection[f];
+ if ( file.isNull() )
+ continue;
+ if ( d->url.isLocalFile() && !QFile::exists( file ) ) {
+ QMessageBox::information( this, tr("Error"), tr("%1\nFile not found.\nCheck path and filename.").arg( file ) );
+ return;
+ }
+ }
+ }
+ QDialog::done( i );
+}
+
+/*!
+ \property QFileDialogP::viewMode
+
+ \brief the file dialog's view mode
+
+ If you set the view mode to be \e Detail (the default), then you
+ will see the file's details, such as the size of the file and the
+ date the file was last modified in addition to the file's name.
+
+ If you set the view mode to be \e List, then you will just
+ see a list of the files and folders.
+
+ See \l QFileDialogP::ViewMode
+*/
+
+
+QFileDialogP::ViewMode QFileDialogP::viewMode() const
+{
+ if ( detailViewMode )
+ return Detail;
+ else
+ return List;
+}
+
+void QFileDialogP::setViewMode( ViewMode m )
+{
+ if ( m == Detail ) {
+ detailViewMode = TRUE;
+ d->stack->raiseWidget( files );
+ d->detailView->setOn( TRUE );
+ d->mcView->setOn( FALSE );
+ } else if ( m == List ) {
+ detailViewMode = FALSE;
+ d->stack->raiseWidget( d->moreFiles );
+ d->detailView->setOn( FALSE );
+ d->mcView->setOn( TRUE );
+ }
+}
+
+
+/*!
+ \property QFileDialogP::previewMode
+
+ \brief the preview mode for the file dialog
+
+ If you set the mode to be a mode other than \e NoPreview, you must
+ use setInfoPreview() or setContentsPreview() to set the dialog's
+ preview widget to your preview widget and enable the preview
+ widget(s) with setInfoPreviewEnabled() or
+ setContentsPreviewEnabled().
+
+ \sa infoPreview, contentsPreview, viewMode
+*/
+
+void QFileDialogP::setPreviewMode( PreviewMode m )
+{
+ if ( m == NoPreview ) {
+ d->previewInfo->setOn( FALSE );
+ d->previewContents->setOn( FALSE );
+ } else if ( m == Info && d->infoPreview ) {
+ d->previewInfo->setOn( TRUE );
+ d->previewContents->setOn( FALSE );
+ changeMode( d->modeButtons->id( d->previewInfo ) );
+ } else if ( m == Contents && d->contentsPreview ) {
+ d->previewInfo->setOn( FALSE );
+ d->previewContents->setOn( TRUE );
+ changeMode( d->modeButtons->id( d->previewContents ) );
+ }
+}
+QFileDialogP::PreviewMode QFileDialogP::previewMode() const
+{
+ if ( d->infoPreview && d->previewInfo->isVisible() )
+ return Info;
+ else if ( d->contentsPreview && d->previewContents->isVisible() )
+ return Contents;
+
+ return NoPreview;
+}
+
+
+/*!
+ Adds the specified widgets to the bottom of the file dialog. The
+ label \a l is placed underneath the "file name" and the "file types"
+ labels. The widget \a w is placed underneath the file types combobox.
+ The button \a b is placed underneath the Cancel pushbutton.
+
+ \code
+ MyFileDialog::MyFileDialog( QWidget* parent, const char* name ) :
+ QFileDialogP( parent, name )
+ {
+ QLabel* label = new QLabel( "Added widgets", this );
+ QLineEdit* lineedit = new QLineEdit( this );
+ QToolButton* toolbutton = new QToolButton( this );
+
+ addWidgets( label, lineedit, toolbutton );
+ }
+ \endcode
+
+ If you don't want to have one of the widgets added, pass 0 in that
+ widget's position.
+
+ Every time you call this function, a new row of widgets will be added
+ to the bottom of the file dialog.
+
+ \sa addToolButton(), addLeftWidget(), addRightWidget()
+*/
+
+void QFileDialogP::addWidgets( QLabel * l, QWidget * w, QPushButton * b )
+{
+ if ( !l && !w && !b )
+ return;
+
+ d->geometryDirty = TRUE;
+
+ QHBoxLayout *lay = new QHBoxLayout();
+ d->extraWidgetsLayouts.append( lay );
+ d->topLevelLayout->addLayout( lay );
+
+ if ( !l )
+ l = new QLabel( this, "qt_intern_lbl" );
+ d->extraLabels.append( l );
+ lay->addWidget( l );
+
+ if ( !w )
+ w = new QWidget( this, "qt_intern_widget" );
+ d->extraWidgets.append( w );
+ lay->addWidget( w );
+ lay->addSpacing( 15 );
+
+ if ( b ) {
+ d->extraButtons.append( b );
+ lay->addWidget( b );
+ } else {
+ QWidget *wid = new QWidget( this, "qt_extrabuttons_widget" );
+ d->extraButtons.append( wid );
+ lay->addWidget( wid );
+ }
+
+ updateGeometries();
+}
+
+/*!
+ Adds the tool button \a b to the row of tool buttons at the top of the
+ file dialog. The button is appended to the right of
+ this row. If \a separator is TRUE, a small space is inserted between the
+ last button of the row and the new button \a b.
+
+ \sa addWidgets(), addLeftWidget(), addRightWidget()
+*/
+
+void QFileDialogP::addToolButton( QButton *b, bool separator )
+{
+ if ( !b || !d->buttonLayout )
+ return;
+
+ d->geometryDirty = TRUE;
+
+ d->toolButtons.append( b );
+ if ( separator )
+ d->buttonLayout->addSpacing( 8 );
+ d->buttonLayout->addWidget( b );
+
+ updateGeometries();
+}
+
+/*!
+ Adds the widget \a w to the left-hand side of the file dialog.
+
+ \sa addRightWidget(), addWidgets(), addToolButton()
+*/
+
+void QFileDialogP::addLeftWidget( QWidget *w )
+{
+ if ( !w )
+ return;
+ d->geometryDirty = TRUE;
+
+ d->leftLayout->addWidget( w );
+ d->leftLayout->addSpacing( 5 );
+
+ updateGeometries();
+}
+
+/*!
+ Adds the widget \a w to the right-hand side of the file dialog.
+
+ \sa addLeftWidget(), addWidgets(), addToolButton()
+*/
+
+void QFileDialogP::addRightWidget( QWidget *w )
+{
+ if ( !w )
+ return;
+ d->geometryDirty = TRUE;
+
+ d->rightLayout->addSpacing( 5 );
+ d->rightLayout->addWidget( w );
+
+ updateGeometries();
+}
+
+/*! \reimp */
+
+void QFileDialogP::keyPressEvent( QKeyEvent * ke )
+{
+ if ( !d->ignoreNextKeyPress &&
+ ke && ( ke->key() == Key_Enter ||
+ ke->key() == Key_Return ) ) {
+ ke->ignore();
+ if ( d->paths->hasFocus() ) {
+ ke->accept();
+ if ( d->url == QUrl(d->paths->currentText()) )
+ nameEdit->setFocus();
+ } else if ( d->types->hasFocus() ) {
+ ke->accept();
+ // ### is there a suitable condition for this? only valid
+ // wildcards?
+ nameEdit->setFocus();
+ } else if ( nameEdit->hasFocus() ) {
+ if ( d->currentFileName.isNull() ) {
+ // maybe change directory
+ QUrlInfo i( d->url, nameEdit->text() );
+ if ( i.isDir() ) {
+ nameEdit->setText( QString::fromLatin1("") );
+ setDir( QUrlOperator( d->url, QFileDialogPrivate::encodeFileName(i.name()) ) );
+ }
+ ke->accept();
+ } else if ( mode() == ExistingFiles ) {
+ QUrlInfo i( d->url, nameEdit->text() );
+ if ( i.isFile() ) {
+ QListViewItem * i = files->firstChild();
+ while ( i && nameEdit->text() != i->text( 0 ) )
+ i = i->nextSibling();
+ if ( i )
+ files->setSelected( i, TRUE );
+ else
+ ke->accept(); // strangely, means to ignore that event
+ }
+ }
+ } else if ( files->hasFocus() || d->moreFiles->hasFocus() ) {
+ ke->accept();
+ }
+ } else if ( ke->key() == Key_Escape ) {
+ ke->ignore();
+ }
+
+ d->ignoreNextKeyPress = FALSE;
+
+ if ( !ke->isAccepted() ) {
+ QDialog::keyPressEvent( ke );
+ }
+}
+
+
+/*! \class QFileIconProviderP qfiledialog.h
+
+ \brief The QFileIconProviderP class provides icons for QFileDialogP to
+ use.
+
+ \ingroup misc
+
+ By default QFileIconProviderP is not used, but any application or
+ library can subclass it, reimplement pixmap() to return a suitable
+ icon, and make all QFileDialogP objects use it by calling the static
+ function QFileDialogP::setIconProvider().
+
+ It is advisable to make all the icons that QFileIconProviderP returns be
+ the same size or at least the same width. This makes the list view
+ look much better.
+
+ \sa QFileDialogP
+*/
+
+
+/*! Constructs an empty file icon provider called \a name, with the
+ parent \a parent.
+*/
+
+QFileIconProviderP::QFileIconProviderP( QObject * parent, const char* name )
+ : QObject( parent, name )
+{
+ // nothing necessary
+}
+
+
+/*!
+ Returns a pointer to a pixmap that should be used to
+ signify the file with the information \a info.
+
+ If pixmap() returns 0, QFileDialogP draws the default pixmap.
+
+ The default implementation returns particular icons for files, directories,
+ link-files and link-directories. It returns a blank "icon" for other types.
+
+ If you return a pixmap here, it should measure 16x16 pixels.
+*/
+
+const QPixmap * QFileIconProviderP::pixmap( const QFileInfo & info )
+{
+ if ( info.isSymLink() ) {
+ if ( info.isFile() )
+ return symLinkFileIcon;
+ else
+ return symLinkDirIcon;
+ } else if ( info.isDir() ) {
+ return closedFolderIcon;
+ } else if ( info.isFile() ) {
+ return fileIcon;
+ } else {
+ return fifteenTransparentPixels;
+ }
+}
+
+/*!
+ Sets the QFileIconProviderP used by the file dialog to \a provider.
+
+ The default is that there is no QFileIconProviderP and QFileDialogP
+ just draws a folder icon next to each directory and nothing next
+ to files.
+
+ \sa QFileIconProviderP, iconProvider()
+*/
+
+void QFileDialogP::setIconProvider( QFileIconProviderP * provider )
+{
+ fileIconProvider = provider;
+}
+
+
+/*!
+ Returns a pointer to the icon provider currently set on the file dialog.
+ By default there is no icon provider, and this function returns 0.
+
+ \sa setIconProvider(), QFileIconProviderP
+*/
+
+QFileIconProviderP * QFileDialogP::iconProvider()
+{
+ return fileIconProvider;
+}
+
+
+#if defined(Q_WS_WIN)
+
+static QString getWindowsRegString( HKEY key, const char *subKey )
+{
+ QString s;
+ char buf[512];
+ DWORD bsz = sizeof(buf);
+#ifdef Q_OS_TEMP
+ int r = RegQueryValueEx( key, (LPCTSTR)qt_winTchar(subKey, TRUE), 0, 0, (LPBYTE)buf, &bsz );
+#else
+ int r = RegQueryValueExA( key, subKey, 0, 0, (LPBYTE)buf, &bsz );
+#endif
+ if ( r == ERROR_SUCCESS ) {
+ s = buf;
+ } else if ( r == ERROR_MORE_DATA ) {
+ char *ptr = new char[bsz+1];
+#ifdef Q_OS_TEMP
+ r = RegQueryValueEx( key, (LPCTSTR)qt_winTchar(subKey, TRUE), 0, 0, (LPBYTE)ptr, &bsz );
+#else
+ r = RegQueryValueExA( key, subKey, 0, 0, (LPBYTE)ptr, &bsz );
+#endif
+ if ( r == ERROR_SUCCESS )
+ s = ptr;
+ delete [] ptr;
+ }
+ return s;
+}
+
+static void initPixmap( QPixmap &pm )
+{
+ pm.fill( Qt::white );
+}
+
+QWindowsIconProvider::QWindowsIconProvider( QObject *parent, const char *name )
+ : QFileIconProviderP( parent, name )
+{
+ pixw = GetSystemMetrics( SM_CXSMICON );
+ pixh = GetSystemMetrics( SM_CYSMICON );
+
+ HKEY k;
+ HICON si;
+ int r;
+ QString s;
+ UINT res;
+
+#ifdef Q_OS_TEMP
+ // ---------- get default folder pixmap
+ r = RegOpenKeyEx( HKEY_CLASSES_ROOT,
+ L"folder\\DefaultIcon",
+ 0, KEY_READ, &k );
+#else
+ // ---------- get default folder pixmap
+ r = RegOpenKeyExA( HKEY_CLASSES_ROOT,
+ "folder\\DefaultIcon",
+ 0, KEY_READ, &k );
+#endif
+ if ( r == ERROR_SUCCESS ) {
+ s = getWindowsRegString( k, 0 );
+ RegCloseKey( k );
+
+ QStringList lst = QStringList::split( ",", s );
+
+#ifdef Q_OS_TEMP
+ res = (UINT)ExtractIconEx( (LPCTSTR)qt_winTchar( lst[ 0 ].simplifyWhiteSpace(), TRUE ),
+ lst[ 1 ].simplifyWhiteSpace().toInt(),
+ 0, &si, 1 );
+#else
+ res = ExtractIconExA( lst[ 0 ].simplifyWhiteSpace().latin1(),
+ lst[ 1 ].simplifyWhiteSpace().toInt(),
+ 0, &si, 1 );
+#endif
+
+ if ( res ) {
+ defaultFolder.resize( pixw, pixh );
+ initPixmap( defaultFolder );
+ QPainter p( &defaultFolder );
+ DrawIconEx( p.handle(), 0, 0, si, pixw, pixh, 0, NULL, DI_NORMAL );
+ p.end();
+ defaultFolder.setMask( defaultFolder.createHeuristicMask() );
+ *closedFolderIcon = defaultFolder;
+ DestroyIcon( si );
+ } else {
+ defaultFolder = *closedFolderIcon;
+ }
+ } else {
+ RegCloseKey( k );
+ }
+
+#ifdef Q_OS_TEMP
+ //------------------------------- get default file pixmap
+ res = (UINT)ExtractIconEx( L"shell32.dll",
+ 0, 0, &si, 1 );
+#else
+ //------------------------------- get default file pixmap
+ res = ExtractIconExA( "shell32.dll",
+ 0, 0, &si, 1 );
+#endif
+
+ if ( res ) {
+ defaultFile.resize( pixw, pixh );
+ initPixmap( defaultFile );
+ QPainter p( &defaultFile );
+ DrawIconEx( p.handle(), 0, 0, si, pixw, pixh, 0, NULL, DI_NORMAL );
+ p.end();
+ defaultFile.setMask( defaultFile.createHeuristicMask() );
+ *fileIcon = defaultFile;
+ DestroyIcon( si );
+ } else {
+ defaultFile = *fileIcon;
+ }
+
+#ifdef Q_OS_TEMP
+ //------------------------------- get default exe pixmap
+ res = (UINT)ExtractIconEx( L"shell32.dll",
+ 2, 0, &si, 1 );
+#else
+ //------------------------------- get default exe pixmap
+ res = ExtractIconExA( "shell32.dll",
+ 2, 0, &si, 1 );
+#endif
+
+ if ( res ) {
+ defaultExe.resize( pixw, pixh );
+ initPixmap( defaultExe );
+ QPainter p( &defaultExe );
+ DrawIconEx( p.handle(), 0, 0, si, pixw, pixh, 0, NULL, DI_NORMAL );
+ p.end();
+ defaultExe.setMask( defaultExe.createHeuristicMask() );
+ DestroyIcon( si );
+ } else {
+ defaultExe = *fileIcon;
+ }
+}
+
+QWindowsIconProvider::~QWindowsIconProvider()
+{
+ if ( this == fileIconProvider )
+ fileIconProvider = 0;
+}
+
+const QPixmap * QWindowsIconProvider::pixmap( const QFileInfo &fi )
+{
+ QString ext = fi.extension().upper();
+ QString key = ext;
+ ext.prepend( "." );
+ QMap< QString, QPixmap >::Iterator it;
+
+ if ( fi.isDir() ) {
+ return &defaultFolder;
+ } else if ( ext.lower() != ".exe" ) {
+ it = cache.find( key );
+ if ( it != cache.end() )
+ return &( *it );
+
+ HKEY k, k2;
+#ifdef Q_OS_TEMP
+ int r = RegOpenKeyEx( HKEY_CLASSES_ROOT,
+ (LPCTSTR)qt_winTchar(ext, TRUE),
+ 0, KEY_READ, &k );
+#else
+ int r = RegOpenKeyExA( HKEY_CLASSES_ROOT,
+ ext.latin1(),
+ 0, KEY_READ, &k );
+#endif
+ QString s;
+ if ( r == ERROR_SUCCESS ) {
+ s = getWindowsRegString( k, 0 );
+ } else {
+ cache[ key ] = defaultFile;
+ RegCloseKey( k );
+ return &defaultFile;
+ }
+ RegCloseKey( k );
+
+#ifdef Q_OS_TEMP
+ r = RegOpenKeyEx( HKEY_CLASSES_ROOT,
+ (LPCTSTR)qt_winTchar( s + "\\DefaultIcon", TRUE ),
+ 0, KEY_READ, &k2 );
+#else
+ r = RegOpenKeyExA( HKEY_CLASSES_ROOT,
+ QString( s + "\\DefaultIcon" ).latin1() ,
+ 0, KEY_READ, &k2 );
+#endif
+ if ( r == ERROR_SUCCESS ) {
+ s = getWindowsRegString( k2, 0 );
+ } else {
+ cache[ key ] = defaultFile;
+ RegCloseKey( k2 );
+ return &defaultFile;
+ }
+ RegCloseKey( k2 );
+
+ QStringList lst = QStringList::split( ",", s );
+
+ HICON si;
+ UINT res;
+ QString filepath = lst[ 0 ].stripWhiteSpace();
+ if ( filepath.find("%1") != -1 ) {
+ filepath = filepath.arg( fi.filePath() );
+ if ( ext.lower() == ".dll" ) {
+ pix = defaultFile;
+ return &pix;
+ }
+ }
+
+#ifdef Q_OS_TEMP
+ res = (UINT)ExtractIconEx( (LPCTSTR)qt_winTchar(filepath, TRUE),
+ lst[ 1 ].stripWhiteSpace().toInt(),
+ NULL, &si, 1 );
+#else
+ res = ExtractIconExA( filepath.latin1(),
+ lst[ 1 ].stripWhiteSpace().toInt(),
+ NULL, &si, 1 );
+#endif
+
+ if ( res ) {
+ pix.resize( pixw, pixh );
+ initPixmap( pix );
+ QPainter p( &pix );
+ DrawIconEx( p.handle(), 0, 0, si, pixw, pixh, 0, NULL, DI_NORMAL );
+ p.end();
+ pix.setMask( pix.createHeuristicMask() );
+ DestroyIcon( si );
+ } else {
+ pix = defaultFile;
+ }
+
+ cache[ key ] = pix;
+ return &pix;
+ } else {
+ HICON si;
+ UINT res;
+#ifdef Q_OS_TEMP
+ res = (UINT)ExtractIconEx( (LPCTSTR)qt_winTchar(fi.absFilePath(), TRUE),
+ -1,
+ 0, 0, 1 );
+#else
+ res = ExtractIconExA( fi.absFilePath().latin1(),
+ -1,
+ 0, 0, 1 );
+#endif
+
+ if ( res == 0 ) {
+ return &defaultExe;
+ } else {
+#ifdef Q_OS_TEMP
+ res = (UINT)ExtractIconEx( (LPCTSTR)qt_winTchar(fi.absFilePath(), TRUE),
+ res - 1,
+ 0, &si, 1 );
+#else
+ res = ExtractIconExA( fi.absFilePath().latin1(),
+ res - 1,
+ 0, &si, 1 );
+#endif
+ }
+
+ if ( res ) {
+ pix.resize( pixw, pixh );
+ initPixmap( pix );
+ QPainter p( &pix );
+ DrawIconEx( p.handle(), 0, 0, si, pixw, pixh, 0, NULL, DI_NORMAL );
+ p.end();
+ pix.setMask( pix.createHeuristicMask() );
+ DestroyIcon( si );
+ } else {
+ pix = defaultExe;
+ }
+
+ return &pix;
+ }
+
+ // can't happen!
+ return 0;
+}
+#endif
+
+
+
+/*!
+ \reimp
+*/
+bool QFileDialogP::eventFilter( QObject * o, QEvent * e )
+{
+ if ( e->type() == QEvent::KeyPress && ( (QKeyEvent*)e )->key() == Key_F5 ) {
+ rereadDir();
+ ((QKeyEvent *)e)->accept();
+ return TRUE;
+ } else if ( e->type() == QEvent::KeyPress && ( (QKeyEvent*)e )->key() == Key_F2 &&
+ ( o == files || o == files->viewport() ) ) {
+ if ( files->isVisible() && files->currentItem() ) {
+ if ( mode() != QFileDialogP::ExistingFiles &&
+ QUrlInfo( d->url, "." ).isWritable() && files->currentItem()->text( 0 ) != ".." ) {
+ files->renameItem = files->currentItem();
+ files->startRename( TRUE );
+ }
+ }
+ ((QKeyEvent *)e)->accept();
+ return TRUE;
+ } else if ( e->type() == QEvent::KeyPress && ( (QKeyEvent*)e )->key() == Key_F2 &&
+ ( o == d->moreFiles || o == d->moreFiles->viewport() ) ) {
+ if ( d->moreFiles->isVisible() && d->moreFiles->currentItem() != -1 ) {
+ if ( mode() != QFileDialogP::ExistingFiles &&
+ QUrlInfo( d->url, "." ).isWritable() &&
+ d->moreFiles->item( d->moreFiles->currentItem() )->text() != ".." ) {
+ d->moreFiles->renameItem = d->moreFiles->item( d->moreFiles->currentItem() );
+ d->moreFiles->startRename( TRUE );
+ }
+ }
+ ((QKeyEvent *)e)->accept();
+ return TRUE;
+ } else if ( e->type() == QEvent::KeyPress && d->moreFiles->renaming ) {
+ d->moreFiles->lined->setFocus();
+ QApplication::sendEvent( d->moreFiles->lined, e );
+ ((QKeyEvent *)e)->accept();
+ return TRUE;
+ } else if ( e->type() == QEvent::KeyPress && files->renaming ) {
+ files->lined->setFocus();
+ QApplication::sendEvent( files->lined, e );
+ ((QKeyEvent *)e)->accept();
+ return TRUE;
+ } else if ( e->type() == QEvent::KeyPress &&
+ ((QKeyEvent *)e)->key() == Key_Backspace &&
+ ( o == files ||
+ o == d->moreFiles ||
+ o == files->viewport() ||
+ o == d->moreFiles->viewport() ) ) {
+ cdUpClicked();
+ ((QKeyEvent *)e)->accept();
+ return TRUE;
+ } else if ( e->type() == QEvent::KeyPress &&
+ ((QKeyEvent *)e)->key() == Key_Delete &&
+ ( o == files ||
+ o == files->viewport() ) ) {
+ if ( files->currentItem() )
+ deleteFile( files->currentItem()->text( 0 ) );
+ ((QKeyEvent *)e)->accept();
+ return TRUE;
+ } else if ( e->type() == QEvent::KeyPress &&
+ ((QKeyEvent *)e)->key() == Key_Delete &&
+ ( o == d->moreFiles ||
+ o == d->moreFiles->viewport() ) ) {
+ int c = d->moreFiles->currentItem();
+ if ( c >= 0 )
+ deleteFile( d->moreFiles->item( c )->text() );
+ ((QKeyEvent *)e)->accept();
+ return TRUE;
+ } else if ( o == files && e->type() == QEvent::FocusOut &&
+ files->currentItem() && mode() != ExistingFiles ) {
+ } else if ( o == files && e->type() == QEvent::KeyPress ) {
+ QTimer::singleShot( 0, this, SLOT(fixupNameEdit()) );
+ } else if ( o == nameEdit && e->type() == QEvent::KeyPress ) {
+ if ( ( nameEdit->cursorPosition() == (int)nameEdit->text().length() || nameEdit->hasSelectedText() ) &&
+ isprint(((QKeyEvent *)e)->ascii()) ) {
+#if defined(_WS_WIN_)
+ QString nt( nameEdit->text().lower() );
+#else
+ QString nt( nameEdit->text() );
+#endif
+ nt.truncate( nameEdit->cursorPosition() );
+ nt += (char)(((QKeyEvent *)e)->ascii());
+ QListViewItem * i = files->firstChild();
+#if defined(_WS_WIN_)
+ while( i && i->text( 0 ).left(nt.length()).lower() != nt )
+#else
+ while( i && i->text( 0 ).left(nt.length()) != nt )
+#endif
+ i = i->nextSibling();
+ if ( i ) {
+ nt = i->text( 0 );
+ int cp = nameEdit->cursorPosition()+1;
+ nameEdit->validateAndSet( nt, cp, cp, nt.length() );
+ return TRUE;
+ }
+ }
+ } else if ( o == nameEdit && e->type() == QEvent::FocusIn ) {
+ fileNameEditDone();
+ } else if ( d->moreFiles->renaming && o != d->moreFiles->lined && e->type() == QEvent::FocusIn ) {
+ d->moreFiles->lined->setFocus();
+ return TRUE;
+ } else if ( files->renaming && o != files->lined && e->type() == QEvent::FocusIn ) {
+ files->lined->setFocus();
+ return TRUE;
+ } else if ( ( o == d->moreFiles || o == d->moreFiles->viewport() ) &&
+ e->type() == QEvent::FocusIn ) {
+ if ( o == d->moreFiles->viewport() && !d->moreFiles->viewport()->hasFocus() ||
+ o == d->moreFiles && !d->moreFiles->hasFocus() )
+ ((QWidget*)o)->setFocus();
+ return FALSE;
+ }
+
+ return QDialog::eventFilter( o, e );
+}
+
+/*!
+ Sets the filters used in the file dialog to \a filters. Each group
+ of filters must be separated by \c{;;} (\e two semi-colons).
+
+ \code
+ QString types("*.png;;*.xpm;;*.jpg");
+ QFileDialogP fd = new QFileDialogP( this );
+ fd->setFilters( types );
+ fd->show();
+ \endcode
+
+*/
+
+void QFileDialogP::setFilters( const QString &filters )
+{
+ QStringList lst = makeFiltersList( filters );
+ setFilters( lst );
+}
+
+/*!
+ \overload
+
+ \a types must be a null-terminated list of strings.
+
+*/
+
+void QFileDialogP::setFilters( const char ** types )
+{
+ if ( !types || !*types )
+ return;
+
+ d->types->clear();
+ while( types && *types ) {
+ d->types->insertItem( QString::fromLatin1(*types) );
+ types++;
+ }
+ d->types->setCurrentItem( 0 );
+ setFilter( d->types->text( 0 ) );
+}
+
+
+/*! \overload void QFileDialogP::setFilters( const QStringList & )
+*/
+
+void QFileDialogP::setFilters( const QStringList & types )
+{
+ if ( types.count() < 1 )
+ return;
+
+ d->types->clear();
+ for ( QStringList::ConstIterator it = types.begin(); it != types.end(); ++it )
+ d->types->insertItem( *it );
+ d->types->setCurrentItem( 0 );
+ setFilter( d->types->text( 0 ) );
+}
+
+/*!
+ Adds the filter \a filter to the list of filters and makes it the
+ current filter.
+
+ \code
+ QFileDialogP* fd = new QFileDialogP( this );
+ fd->addFilter( "Images (*.png *.jpg *.xpm)" );
+ fd->show();
+ \endcode
+
+ In the above example, a file dialog is created, and the file filter "Images
+ (*.png *.jpg *.xpm)" is added and is set as the current filter. The original
+ filter, "All Files (*)", is still available.
+
+ \sa setFilter(), setFilters()
+*/
+
+void QFileDialogP::addFilter( const QString &filter )
+{
+ if ( filter.isEmpty() )
+ return;
+ QString f = filter;
+ QRegExp r( QString::fromLatin1(qt_file_dialog_filter_reg_exp) );
+ int index = r.search( f );
+ if ( index >= 0 )
+ f = r.cap( 2 );
+ for ( int i = 0; i < d->types->count(); ++i ) {
+ QString f2( d->types->text( i ) );
+ int index = r.search( f2 );
+ if ( index >= 0 )
+ f2 = r.cap( 1 );
+ if ( f2 == f ) {
+ d->types->setCurrentItem( i );
+ setFilter( f2 );
+ return;
+ }
+ }
+
+ d->types->insertItem( filter );
+ d->types->setCurrentItem( d->types->count() - 1 );
+ setFilter( d->types->text( d->types->count() - 1 ) );
+}
+
+/*!
+ Since modeButtons is a top-level widget, it may be destroyed by the
+ kernel at application exit. Notice if this happens to
+ avoid double deletion.
+*/
+
+void QFileDialogP::modeButtonsDestroyed()
+{
+ if ( d )
+ d->modeButtons = 0;
+}
+
+
+/*!
+ This is a convenience static function that will return one or more
+ existing files selected by the user.
+
+ \code
+ QStringList files = QFileDialogP::getOpenFileNames(
+ "Images (*.png *.xpm *.jpg)",
+ "/home",
+ this,
+ "open files dialog"
+ "Select one or more files to open" );
+ \endcode
+
+ This function creates a modal file dialog called \a name, with
+ parent \a parent. If \a parent is not 0, the dialog will be shown
+ centered over the parent.
+
+ The file dialog's working directory will be set to \a dir. If \a
+ dir includes a file name, the file will be selected. The filter
+ is set to \a filter so that only those files which match the filter
+ are shown. The filter selected is set to \a selectedFilter. The parameters
+ \a dir, \a selectedFilter and \a filter may be QString::null.
+
+ The dialog's caption is set to \a caption. If \a caption is not
+ specified then a default caption will be used.
+
+ Under Windows and Mac OS X, this static function will use the native
+ file dialog and not a QFileDialogP, unless the style of the application
+ is set to something other than the native style.
+
+ Under Unix/X11, the normal behavior of the file dialog is to resolve
+ and follow symlinks. For example, if /usr/tmp is a symlink to /var/tmp,
+ the file dialog will change to /var/tmp after entering /usr/tmp.
+ If \a resolveSymlinks is FALSE, the file dialog will treat
+ symlinks as regular directories.
+
+ Note that if you want to iterate over the list of files, you should
+ iterate over a copy, e.g.
+ \code
+ QStringList list = files;
+ QStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa getOpenFileName(), getSaveFileName(), getExistingDirectory()
+*/
+
+QStringList QFileDialogP::getOpenFileNames( const QString & filter,
+ const QString& dir,
+ QWidget *parent,
+ const char* name,
+ const QString& caption,
+ QString *selectedFilter,
+ bool resolveSymlinks )
+{
+ bool save_qt_resolve_symlinks = qt_resolve_symlinks;
+ qt_resolve_symlinks = resolveSymlinks;
+
+ QStringList filters;
+ if ( !filter.isEmpty() )
+ filters = makeFiltersList( filter );
+
+ makeVariables();
+
+ if ( workingDirectory->isNull() )
+ *workingDirectory = QDir::currentDirPath();
+
+ if ( !dir.isEmpty() ) {
+ // #### works only correct for local files
+ QUrlOperator u( dir );
+ if ( u.isLocalFile() && QFileInfo( u ).isDir() ) {
+ *workingDirectory = dir;
+ } else {
+ *workingDirectory = u.toString();
+ }
+ }
+
+#if defined(Q_WS_WIN)
+ if ( qApp->style().styleHint( QStyle::SH_GUIStyle ) == WindowsStyle )
+ return winGetOpenFileNames( filter, workingDirectory, parent, name, caption, selectedFilter );
+#elif defined(Q_WS_MAC)
+ if( ( qApp->style().inherits(QMAC_DEFAULT_STYLE) ) )
+ return macGetOpenFileNames(filter, workingDirectory, parent, name, caption );
+#endif
+
+ QFileDialogP *dlg = new QFileDialogP( *workingDirectory, QString::null, parent, name ? name : "qt_filedlg_gofns", TRUE );
+
+ Q_CHECK_PTR( dlg );
+#ifndef QT_NO_WIDGET_TOPEXTRA
+ if ( parent && parent->icon() && !parent->icon()->isNull() )
+ dlg->setIcon( *parent->icon() );
+ else if ( qApp->mainWidget() && qApp->mainWidget()->icon() && !qApp->mainWidget()->icon()->isNull() )
+ dlg->setIcon( *qApp->mainWidget()->icon() );
+#endif
+
+ dlg->setFilters( filters );
+ if ( selectedFilter )
+ dlg->setFilter( *selectedFilter );
+#ifndef QT_NO_WIDGET_TOPEXTRA
+ if ( !caption.isNull() )
+ dlg->setCaption( caption );
+ else
+ dlg->setCaption( QFileDialogP::tr("Open") );
+#endif
+ dlg->setMode( QFileDialogP::ExistingFiles );
+ QString result;
+ QStringList lst;
+ if ( dlg->exec() == QDialog::Accepted ) {
+ lst = dlg->selectedFiles();
+ *workingDirectory = dlg->d->url;
+ if ( selectedFilter )
+ *selectedFilter = dlg->selectedFilter();
+ }
+ delete dlg;
+
+ qt_resolve_symlinks = save_qt_resolve_symlinks;
+
+ return lst;
+}
+
+/*! Updates the line edit to match the speed-key usage in QListView. */
+
+void QFileDialogP::fixupNameEdit()
+{
+ if ( files->currentItem() && d->mode != ExistingFiles ) {
+ if ( ( (QFileDialogPrivate::File*)files->currentItem() )->info.isFile() )
+ nameEdit->setText( files->currentItem()->text( 0 ) );
+ }
+}
+
+/*!
+ Returns the URL of the current working directory in the file dialog.
+
+ \sa setUrl()
+*/
+
+QUrl QFileDialogP::url() const
+{
+ return d->url;
+}
+
+static bool isRoot( const QUrl &u )
+{
+#if defined(Q_OS_MAC9)
+ QString p = QDir::convertSeparators(u.path());
+ if(p.contains(':') == 1)
+ return TRUE;
+#elif defined(Q_OS_UNIX)
+ if ( u.path() == "/" )
+ return TRUE;
+#elif defined(Q_OS_WIN32)
+ QString p = u.path();
+ if ( p.length() == 3 &&
+ p.right( 2 ) == ":/" )
+ return TRUE;
+ if ( p[ 0 ] == '/' && p[ 1 ] == '/' ) {
+ int slashes = p.contains( '/' );
+ if ( slashes <= 3 )
+ return TRUE;
+ if ( slashes == 4 && p[ (int)p.length() - 1 ] == '/' )
+ return TRUE;
+ }
+#else
+#if defined(Q_CC_GNU)
+#warning "case not covered.."
+#endif
+#endif
+
+ if ( !u.isLocalFile() && u.path() == "/" )
+ return TRUE;
+
+ return FALSE;
+}
+
+void QFileDialogP::urlStart( QNetworkOperation *op )
+{
+ if ( !op )
+ return;
+
+ if ( op->operation() == QNetworkProtocol::OpListChildren ) {
+ if ( isRoot( d->url ) )
+ d->cdToParent->setEnabled( FALSE );
+ else
+ d->cdToParent->setEnabled( TRUE );
+ d->mimeTypeTimer->stop();
+ d->sortedList.clear();
+ d->pendingItems.clear();
+ d->moreFiles->clearSelection();
+ files->clearSelection();
+ d->moreFiles->clear();
+ files->clear();
+ files->setSorting( -1 );
+
+ QString s = d->url.toString( FALSE, FALSE );
+ bool found = FALSE;
+ for ( int i = 0; i < d->paths->count(); ++i ) {
+#if defined(Q_WS_WIN)
+ if ( d->paths->text( i ).lower() == s.lower() ) {
+#else
+ if ( d->paths->text( i ) == s ) {
+#endif
+ found = TRUE;
+ d->paths->setCurrentItem( i );
+ break;
+ }
+ }
+ if ( !found ) {
+ d->paths->insertItem( *openFolderIcon, s, -1 );
+ d->paths->setCurrentItem( d->paths->count() - 1 );
+ }
+ d->last = 0;
+ d->hadDotDot = FALSE;
+
+ if ( d->goBack && d->history.last() != d->url.toString() ) {
+ d->history.append( d->url.toString() );
+ if ( d->history.count() > 1 )
+ d->goBack->setEnabled( TRUE );
+ }
+ }
+}
+
+void QFileDialogP::urlFinished( QNetworkOperation *op )
+{
+ if ( !op )
+ return;
+
+ if ( op->operation() == QNetworkProtocol::OpListChildren ) {
+ if ( QApplication::overrideCursor() )
+ QApplication::restoreOverrideCursor();
+ }
+ if ( op->state() == QNetworkProtocol::StFailed ) {
+ if ( d->paths->hasFocus() )
+ d->ignoreNextKeyPress = TRUE;
+
+ if ( d->progressDia ) {
+ d->ignoreStop = TRUE;
+ d->progressDia->close();
+ delete d->progressDia;
+ d->progressDia = 0;
+ }
+
+ QMessageBox::critical( this, tr( "Error" ), op->protocolDetail() );
+
+ int ecode = op->errorCode();
+ if ( ecode == QNetworkProtocol::ErrListChildren || ecode == QNetworkProtocol::ErrParse ||
+ ecode == QNetworkProtocol::ErrUnknownProtocol || ecode == QNetworkProtocol::ErrLoginIncorrect ||
+ ecode == QNetworkProtocol::ErrValid || ecode == QNetworkProtocol::ErrHostNotFound ||
+ ecode == QNetworkProtocol::ErrFileNotExisting ) {
+ if (d->url != d->oldUrl) {
+ QString nf = d->url.nameFilter();
+ d->url = d->oldUrl;
+ d->url.setNameFilter( nf );
+ rereadDir();
+ }
+ } else {
+ // another error happened, no need to go back to last dir
+ }
+ } else if ( op->operation() == QNetworkProtocol::OpListChildren &&
+ op == d->currListChildren ) {
+ if ( !d->hadDotDot && !isRoot( d->url ) ) {
+ bool ok = TRUE;
+#if defined(Q_WS_WIN)
+ if ( d->url.path().left( 2 ) == "//" )
+ ok = FALSE;
+#endif
+ if ( ok ) {
+ QUrlInfo ui( d->url, ".." );
+ ui.setName( ".." );
+ ui.setDir( TRUE );
+ ui.setFile( FALSE );
+ ui.setSymLink( FALSE );
+ ui.setSize( 0 );
+ QValueList<QUrlInfo> lst;
+ lst << ui;
+ insertEntry( lst, 0 );
+ }
+ }
+ resortDir();
+ } else if ( op->operation() == QNetworkProtocol::OpGet ) {
+ } else if ( op->operation() == QNetworkProtocol::OpPut ) {
+ rereadDir();
+ if ( d->progressDia ) {
+ d->ignoreStop = TRUE;
+ d->progressDia->close();
+ }
+ delete d->progressDia;
+ d->progressDia = 0;
+ }
+}
+
+void QFileDialogP::dataTransferProgress( int bytesDone, int bytesTotal, QNetworkOperation *op )
+{
+ if ( !op )
+ return;
+
+ QString label;
+ QUrl u( op->arg( 0 ) );
+ if ( u.isLocalFile() ) {
+ label = u.path();
+ } else {
+ label = QString( "%1 (on %2)" );
+ label = label.arg( u.path() ).arg( u.host() );
+ }
+
+ if ( !d->progressDia ) {
+ if ( bytesDone < bytesTotal) {
+ d->ignoreStop = FALSE;
+ d->progressDia = new QFDProgressDialog( this, label, bytesTotal );
+ connect( d->progressDia, SIGNAL( cancelled() ),
+ this, SLOT( stopCopy() ) );
+ d->progressDia->show();
+ } else
+ return;
+ }
+
+ if ( d->progressDia ) {
+ if ( op->operation() == QNetworkProtocol::OpGet ) {
+ if ( d->progressDia ) {
+ d->progressDia->setReadProgress( bytesDone );
+ }
+ } else if ( op->operation() == QNetworkProtocol::OpPut ) {
+ if ( d->progressDia ) {
+ d->progressDia->setWriteLabel( label );
+ d->progressDia->setWriteProgress( bytesDone );
+ }
+ } else {
+ return;
+ }
+ }
+}
+
+void QFileDialogP::insertEntry( const QValueList<QUrlInfo> &lst, QNetworkOperation *op )
+{
+ if ( op && op->operation() == QNetworkProtocol::OpListChildren &&
+ op != d->currListChildren )
+ return;
+ QValueList<QUrlInfo>::ConstIterator it = lst.begin();
+ for ( ; it != lst.end(); ++it ) {
+ const QUrlInfo &inf = *it;
+ if ( d->mode == DirectoryOnly && !inf.isDir() )
+ continue;
+ if ( inf.name() == ".." ) {
+ d->hadDotDot = TRUE;
+ if ( isRoot( d->url ) )
+ continue;
+#if defined(Q_WS_WIN)
+ if ( d->url.path().left( 2 ) == "//" )
+ continue;
+#endif
+ } else if ( inf.name() == "." )
+ continue;
+
+#if defined(Q_WS_WIN)
+ if ( !bShowHiddenFiles ) {
+ if ( d->url.isLocalFile() ) {
+ QString file = d->url.path() + inf.name();
+#if defined(UNICODE)
+ if ( qWinVersion() & Qt::WV_NT_based ) {
+ if ( GetFileAttributesW( (TCHAR*)qt_winTchar( file, TRUE ) ) & FILE_ATTRIBUTE_HIDDEN )
+ continue;
+ }
+ else
+#endif
+ {
+ if ( GetFileAttributesA( file.local8Bit() ) & FILE_ATTRIBUTE_HIDDEN )
+ continue;
+ }
+ } else {
+ if ( inf.name() != ".." && inf.name()[0] == QChar('.') )
+ continue;
+ }
+ }
+#else
+ if ( !bShowHiddenFiles && inf.name() != ".." ) {
+ if ( inf.name()[ 0 ] == QChar( '.' ) )
+ continue;
+ }
+
+#endif
+ if ( !d->url.isLocalFile() ) {
+ QFileDialogPrivate::File * i = 0;
+ QFileDialogPrivate::MCItem *i2 = 0;
+ i = new QFileDialogPrivate::File( d, &inf, files );
+ i2 = new QFileDialogPrivate::MCItem( d->moreFiles, i );
+
+ if ( d->mode == ExistingFiles && inf.isDir() ||
+ ( isDirectoryMode( d->mode ) && inf.isFile() ) ) {
+ i->setSelectable( FALSE );
+ i2->setSelectable( FALSE );
+ }
+
+ i->i = i2;
+ }
+
+ d->sortedList.append( new QUrlInfo( inf ) );
+ }
+}
+
+void QFileDialogP::removeEntry( QNetworkOperation *op )
+{
+ if ( !op )
+ return;
+
+ QUrlInfo *i = 0;
+ QListViewItemIterator it( files );
+ bool ok1 = FALSE, ok2 = FALSE;
+ for ( i = d->sortedList.first(); it.current(); ++it, i = d->sortedList.next() ) {
+ if ( ( (QFileDialogPrivate::File*)it.current() )->info.name() == op->arg( 0 ) ) {
+ d->pendingItems.removeRef( (QFileDialogPrivate::File*)it.current() );
+ delete ( (QFileDialogPrivate::File*)it.current() )->i;
+ delete it.current();
+ ok1 = TRUE;
+ }
+ if ( i && i->name() == op->arg( 0 ) ) {
+ d->sortedList.removeRef( i );
+ i = d->sortedList.prev();
+ ok2 = TRUE;
+ }
+ if ( ok1 && ok2 )
+ break;
+ }
+}
+
+void QFileDialogP::itemChanged( QNetworkOperation *op )
+{
+ if ( !op )
+ return;
+
+ QUrlInfo *i = 0;
+ QListViewItemIterator it1( files );
+ bool ok1 = FALSE, ok2 = FALSE;
+ // first check whether the new file replaces an existing file.
+ for ( i = d->sortedList.first(); it1.current(); ++it1, i = d->sortedList.next() ) {
+ if ( ( (QFileDialogPrivate::File*)it1.current() )->info.name() == op->arg( 1 ) ) {
+ delete ( (QFileDialogPrivate::File*)it1.current() )->i;
+ delete it1.current();
+ ok1 = TRUE;
+ }
+ if ( i && i->name() == op->arg( 1 ) ) {
+ d->sortedList.removeRef( i );
+ i = d->sortedList.prev();
+ ok2 = TRUE;
+ }
+ if ( ok1 && ok2 )
+ break;
+ }
+
+ i = 0;
+ QListViewItemIterator it( files );
+ ok1 = FALSE;
+ ok2 = FALSE;
+ for ( i = d->sortedList.first(); it.current(); ++it, i = d->sortedList.next() ) {
+ if ( ( (QFileDialogPrivate::File*)it.current() )->info.name() == op->arg( 0 ) ) {
+ ( (QFileDialogPrivate::File*)it.current() )->info.setName( op->arg( 1 ) );
+ ok1 = TRUE;
+ }
+ if ( i && i->name() == op->arg( 0 ) ) {
+ i->setName( op->arg( 1 ) );
+ ok2 = TRUE;
+ }
+ if ( ok1 && ok2 )
+ break;
+ }
+
+ resortDir();
+}
+
+/*!
+ \property QFileDialogP::infoPreview
+
+ \brief whether the file dialog can provide preview information about
+ the currently selected file
+
+ The default is FALSE.
+*/
+bool QFileDialogP::isInfoPreviewEnabled() const
+{
+ return d->infoPreview;
+}
+
+void QFileDialogP::setInfoPreviewEnabled( bool info )
+{
+ if ( info == d->infoPreview )
+ return;
+ d->geometryDirty = TRUE;
+ d->infoPreview = info;
+ updateGeometries();
+}
+
+
+/*!
+ \property QFileDialogP::contentsPreview
+
+ \brief whether the file dialog can provide a contents preview of the
+ currently selected file
+
+ The default is FALSE.
+
+ \sa setContentsPreview() setInfoPreviewEnabled()
+*/
+// ### improve the above documentation: how is the preview done, how can I add
+// support for customized preview, etc.
+
+bool QFileDialogP::isContentsPreviewEnabled() const
+{
+ return d->contentsPreview;
+}
+
+void QFileDialogP::setContentsPreviewEnabled( bool contents )
+{
+ if ( contents == d->contentsPreview )
+ return;
+ d->geometryDirty = TRUE;
+ d->contentsPreview = contents;
+ updateGeometries();
+}
+
+
+/*!
+ Sets the widget to be used for displaying information about the file
+ to the widget \a w and a preview of that information to the
+ QFilePreviewP \a preview.
+
+ Normally you would create a preview widget that derives from both QWidget and
+ QFilePreviewP, so you should pass the same widget twice.
+
+ \code
+ class Preview : public QLabel, public QFilePreviewP
+ {
+ public:
+ Preview( QWidget *parent=0 ) : QLabel( parent ) {}
+
+ void previewUrl( const QUrl &u )
+ {
+ QString path = u.path();
+ QPixmap pix( path );
+ if ( pix.isNull() )
+ setText( "This is not a pixmap" );
+ else
+ setText( "This is a pixmap" );
+ }
+ };
+
+ //...
+
+ int main( int argc, char** argv )
+ {
+ Preview* p = new Preview;
+
+ QFileDialogP* fd = new QFileDialogP( this );
+ fd->setInfoPreviewEnabled( TRUE );
+ fd->setInfoPreview( p, p );
+ fd->setPreviewMode( QFileDialogP::Info );
+ fd->show();
+ }
+
+ \endcode
+
+ \sa setContentsPreview(), setInfoPreviewEnabled(), setPreviewMode()
+
+*/
+
+void QFileDialogP::setInfoPreview( QWidget *w, QFilePreviewP *preview )
+{
+ if ( !w || !preview )
+ return;
+
+ if ( d->infoPreviewWidget ) {
+ d->preview->removeWidget( d->infoPreviewWidget );
+ delete d->infoPreviewWidget;
+ }
+ if ( d->infoPreviewer )
+ delete d->infoPreviewer;
+ d->infoPreviewWidget = w;
+ d->infoPreviewer = preview;
+ w->reparent( d->preview, 0, QPoint( 0, 0 ) );
+}
+
+/*!
+ Sets the widget to be used for displaying the contents of the file
+ to the widget \a w and a preview of those contents to the
+ QFilePreviewP \a preview.
+
+ Normally you would create a preview widget that derives from both QWidget and
+ QFilePreviewP, so you should pass the same widget twice.
+
+ \code
+ class Preview : public QLabel, public QFilePreviewP
+ {
+ public:
+ Preview( QWidget *parent=0 ) : QLabel( parent ) {}
+
+ void previewUrl( const QUrl &u )
+ {
+ QString path = u.path();
+ QPixmap pix( path );
+ if ( pix.isNull() )
+ setText( "This is not a pixmap" );
+ else
+ setPixmap( pix );
+ }
+ };
+
+ //...
+
+ int main( int argc, char** argv )
+ {
+ Preview* p = new Preview;
+
+ QFileDialogP* fd = new QFileDialogP( this );
+ fd->setContentsPreviewEnabled( TRUE );
+ fd->setContentsPreview( p, p );
+ fd->setPreviewMode( QFileDialogP::Contents );
+ fd->show();
+ }
+ \endcode
+
+ \sa setContentsPreviewEnabled(), setInfoPreview(), setPreviewMode()
+*/
+
+void QFileDialogP::setContentsPreview( QWidget *w, QFilePreviewP *preview )
+{
+ if ( !w || !preview )
+ return;
+
+ if ( d->contentsPreviewWidget ) {
+ d->preview->removeWidget( d->contentsPreviewWidget );
+ delete d->contentsPreviewWidget;
+ }
+ if ( d->contentsPreviewer )
+ delete d->contentsPreviewer;
+ d->contentsPreviewWidget = w;
+ d->contentsPreviewer = preview;
+ w->reparent( d->preview, 0, QPoint( 0, 0 ) );
+}
+
+/*!
+ Re-sorts the displayed directory.
+
+ \sa rereadDir()
+*/
+
+void QFileDialogP::resortDir()
+{
+ d->mimeTypeTimer->stop();
+ d->pendingItems.clear();
+
+ QFileDialogPrivate::File *item = 0;
+ QFileDialogPrivate::MCItem *item2 = 0;
+
+ d->sortedList.sort();
+
+ if ( files->childCount() > 0 || d->moreFiles->count() > 0 ) {
+ d->moreFiles->clear();
+ files->clear();
+ d->last = 0;
+ files->setSorting( -1 );
+ }
+
+ QUrlInfo *i = sortAscending ? d->sortedList.first() : d->sortedList.last();
+ for ( ; i; i = sortAscending ? d->sortedList.next() : d->sortedList.prev() ) {
+ item = new QFileDialogPrivate::File( d, i, files );
+ item2 = new QFileDialogPrivate::MCItem( d->moreFiles, item, item2 );
+ item->i = item2;
+ d->pendingItems.append( item );
+ if ( d->mode == ExistingFiles && item->info.isDir() ||
+ ( isDirectoryMode( d->mode ) && item->info.isFile() ) ) {
+ item->setSelectable( FALSE );
+ item2->setSelectable( FALSE );
+ }
+ }
+
+ // ##### As the QFileIconProviderP only support QFileInfo and no
+ // QUrlInfo it can be only used for local files at the moment. In
+ // 3.0 we have to change the API of QFileIconProviderP to work on
+ // QUrlInfo so that also remote filesystems can be show mime-type
+ // specific icons.
+ if ( d->url.isLocalFile() )
+ d->mimeTypeTimer->start( 0 );
+}
+
+/*!
+ Stops the current copy operation.
+*/
+
+void QFileDialogP::stopCopy()
+{
+ if ( d->ignoreStop )
+ return;
+
+ d->url.blockSignals( TRUE );
+ d->url.stop();
+ if ( d->progressDia ) {
+ d->ignoreStop = TRUE;
+ QTimer::singleShot( 100, this, SLOT( removeProgressDia() ) );
+ }
+ d->url.blockSignals( FALSE );
+}
+
+/*!
+ \internal
+*/
+
+void QFileDialogP::removeProgressDia()
+{
+ if ( d->progressDia )
+ delete d->progressDia;
+ d->progressDia = 0;
+}
+
+/*!
+ \internal
+*/
+
+void QFileDialogP::doMimeTypeLookup()
+{
+ if ( !iconProvider() ) {
+ d->pendingItems.clear();
+ d->mimeTypeTimer->stop();
+ return;
+ }
+
+ d->mimeTypeTimer->stop();
+ if ( d->pendingItems.count() == 0 ) {
+ return;
+ }
+
+ QRect r;
+ QFileDialogPrivate::File *item = d->pendingItems.first();
+ if ( item ) {
+ QFileInfo fi;
+ if ( d->url.isLocalFile() ) {
+ fi.setFile( QUrl( d->url.path(), QFileDialogPrivate::encodeFileName( item->info.name() ) ).path( FALSE ) );
+ } else
+ fi.setFile( item->info.name() ); // #####
+ const QPixmap *p = iconProvider()->pixmap( fi );
+ if ( p && p != item->pixmap( 0 ) &&
+ ( !item->pixmap( 0 ) || p->serialNumber() != item->pixmap( 0 )->serialNumber() ) &&
+ p != fifteenTransparentPixels ) {
+ item->hasMimePixmap = TRUE;
+
+ // evil hack to avoid much too much repaints!
+ qApp->processEvents();
+ files->setUpdatesEnabled( FALSE );
+ files->viewport()->setUpdatesEnabled( FALSE );
+ if ( item != d->pendingItems.first() )
+ return;
+ item->setPixmap( 0, *p );
+ qApp->processEvents();
+ files->setUpdatesEnabled( TRUE );
+ files->viewport()->setUpdatesEnabled( TRUE );
+
+ if ( files->isVisible() ) {
+ QRect ir( files->itemRect( item ) );
+ if ( ir != QRect( 0, 0, -1, -1 ) ) {
+ r = r.unite( ir );
+ }
+ } else {
+ QRect ir( d->moreFiles->itemRect( item->i ) );
+ if ( ir != QRect( 0, 0, -1, -1 ) ) {
+ r = r.unite( ir );
+ }
+ }
+ }
+ if ( d->pendingItems.count() )
+ d->pendingItems.removeFirst();
+ }
+
+ if ( d->moreFiles->isVisible() ) {
+ d->moreFiles->viewport()->repaint( r, FALSE );
+ } else {
+ files->viewport()->repaint( r, FALSE );
+ }
+
+ if ( d->pendingItems.count() )
+ d->mimeTypeTimer->start( 0 );
+ else if ( d->moreFiles->isVisible() )
+ d->moreFiles->triggerUpdate( TRUE );
+}
+
+/*!
+ If \a b is TRUE then all the files in the current directory are selected;
+ otherwise, they are deselected.
+*/
+
+void QFileDialogP::selectAll( bool b )
+{
+ if ( d->mode != ExistingFiles )
+ return;
+ d->moreFiles->selectAll( b );
+ files->selectAll( b );
+}
+
+void QFileDialogP::goBack()
+{
+ if ( !d->goBack || !d->goBack->isEnabled() )
+ return;
+ d->history.remove( d->history.last() );
+ if ( d->history.count() < 2 )
+ d->goBack->setEnabled( FALSE );
+ setUrl( d->history.last() );
+}
+
+// a class with wonderfully inflexible flexibility. why doesn't it
+// just subclass QWidget in the first place? 'you have to derive your
+// preview widget from QWidget and from this class' indeed.
+
+/*!
+ \class QFilePreviewP qfiledialog.h
+ \ingroup misc
+ \brief The QFilePreviewP class provides file previewing in QFileDialogP.
+
+ This class is an abstract base class which is used to implement
+ widgets that can display a preview of a file in a QFileDialogP.
+
+ You must derive the preview widget from both QWidget and from this
+ class. Then you must reimplement this class's previewUrl() function,
+ which is called by the file dialog if the preview of a file
+ (specified as a URL) should be shown.
+
+ See also QFileDialog::setPreviewMode(), QFileDialogP::setContentsPreview(),
+ QFileDialogP::setInfoPreview(), QFileDialogP::setInfoPreviewEnabled(),
+ QFileDialogP::setContentsPreviewEnabled().
+
+ For an example of a preview widget see qt/examples/qdir/qdir.cpp.
+*/
+
+/*!
+ Constructs the QFilePreviewP.
+*/
+
+QFilePreviewP::QFilePreviewP()
+{
+}
+
+/*!
+ \fn void QFilePreviewP::previewUrl( const QUrl &url )
+
+ This function is called by QFileDialogP if a preview
+ for the \a url should be shown. Reimplement this
+ function to provide file previewing.
+*/
+
+#endif