TableViewSelection.qml 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2016 The Qt Company Ltd.
  4. ** Contact: https://www.qt.io/licensing/
  5. **
  6. ** This file is part of the Qt Quick Controls module of the Qt Toolkit.
  7. **
  8. ** $QT_BEGIN_LICENSE:LGPL$
  9. ** Commercial License Usage
  10. ** Licensees holding valid commercial Qt licenses may use this file in
  11. ** accordance with the commercial license agreement provided with the
  12. ** Software or, alternatively, in accordance with the terms contained in
  13. ** a written agreement between you and The Qt Company. For licensing terms
  14. ** and conditions see https://www.qt.io/terms-conditions. For further
  15. ** information use the contact form at https://www.qt.io/contact-us.
  16. **
  17. ** GNU Lesser General Public License Usage
  18. ** Alternatively, this file may be used under the terms of the GNU Lesser
  19. ** General Public License version 3 as published by the Free Software
  20. ** Foundation and appearing in the file LICENSE.LGPL3 included in the
  21. ** packaging of this file. Please review the following information to
  22. ** ensure the GNU Lesser General Public License version 3 requirements
  23. ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
  24. **
  25. ** GNU General Public License Usage
  26. ** Alternatively, this file may be used under the terms of the GNU
  27. ** General Public License version 2.0 or (at your option) the GNU General
  28. ** Public license version 3 or any later version approved by the KDE Free
  29. ** Qt Foundation. The licenses are as published by the Free Software
  30. ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
  31. ** included in the packaging of this file. Please review the following
  32. ** information to ensure the GNU General Public License requirements will
  33. ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
  34. ** https://www.gnu.org/licenses/gpl-3.0.html.
  35. **
  36. ** $QT_END_LICENSE$
  37. **
  38. ****************************************************************************/
  39. import QtQuick 2.2
  40. QtObject {
  41. property int count: 0
  42. signal selectionChanged
  43. property bool __dirty: false
  44. property var __ranges: []
  45. function forEach (callback) {
  46. if (!(callback instanceof Function)) {
  47. console.warn("TableViewSelection.forEach: argument is not a function")
  48. return;
  49. }
  50. __forEach(callback, -1)
  51. }
  52. function contains(index) {
  53. for (var i = 0 ; i < __ranges.length ; ++i) {
  54. if (__ranges[i][0] <= index && index <= __ranges[i][1])
  55. return true;
  56. else if (__ranges[i][0] > index)
  57. return false;
  58. }
  59. return false;
  60. }
  61. function clear() {
  62. __ranges = []
  63. __dirty = true
  64. count = 0
  65. selectionChanged()
  66. }
  67. function selectAll() { select(0, rowCount - 1) }
  68. function select(first, last) { __select(true, first, last) }
  69. function deselect(first, last) { __select(false, first, last) }
  70. // --- private section ---
  71. function __printRanges() {
  72. var out = ""
  73. for (var i = 0 ; i < __ranges.length ; ++ i)
  74. out += ("{" + __ranges[i][0] + "," + __ranges[i][1] + "} ")
  75. print(out)
  76. }
  77. function __count() {
  78. var sum = 0
  79. for (var i = 0 ; i < __ranges.length ; ++i) {
  80. sum += (1 + __ranges[i][1] - __ranges[i][0])
  81. }
  82. return sum
  83. }
  84. function __forEach (callback, startIndex) {
  85. __dirty = false
  86. var i, j
  87. for (i = 0 ; i < __ranges.length && !__dirty ; ++i) {
  88. for (j = __ranges[i][0] ; !__dirty && j <= __ranges[i][1] ; ++j) {
  89. if (j >= startIndex)
  90. callback.call(this, j)
  91. }
  92. }
  93. // Restart iteration at last index if selection changed
  94. if (__dirty)
  95. return __forEach(callback, j)
  96. }
  97. function __selectOne(index) {
  98. __ranges = [[index, index]]
  99. __dirty = true
  100. count = 1
  101. selectionChanged();
  102. }
  103. function __select(select, first, last) {
  104. var i, range
  105. var start = first
  106. var stop = first
  107. var startRangeIndex = -1
  108. var stopRangeIndex = -1
  109. var newRangePos = 0
  110. if (first < 0 || last < 0 || first >= rowCount || last >=rowCount) {
  111. console.warn("TableViewSelection: index out of range")
  112. return
  113. }
  114. if (last !== undefined) {
  115. start = first <= last ? first : last
  116. stop = first <= last ? last : first
  117. }
  118. if (select) {
  119. // Find beginning and end ranges
  120. for (i = 0 ; i < __ranges.length; ++ i) {
  121. range = __ranges[i]
  122. if (range[0] > stop + 1) continue; // above range
  123. if (range[1] < start - 1) { // below range
  124. newRangePos = i + 1
  125. continue;
  126. }
  127. if (startRangeIndex === -1)
  128. startRangeIndex = i
  129. stopRangeIndex = i
  130. }
  131. if (startRangeIndex !== -1)
  132. start = Math.min(__ranges[startRangeIndex][0], start)
  133. if (stopRangeIndex !== -1)
  134. stop = Math.max(__ranges[stopRangeIndex][1], stop)
  135. if (startRangeIndex === -1)
  136. startRangeIndex = newRangePos
  137. __ranges.splice(Math.max(0, startRangeIndex),
  138. 1 + stopRangeIndex - startRangeIndex, [start, stop])
  139. } else {
  140. // Find beginning and end ranges
  141. for (i = 0 ; i < __ranges.length; ++ i) {
  142. range = __ranges[i]
  143. if (range[1] < start) continue; // below range
  144. if (range[0] > stop) continue; // above range
  145. if (startRangeIndex === -1)
  146. startRangeIndex = i
  147. stopRangeIndex = i
  148. }
  149. // Slice ranges accordingly
  150. if (startRangeIndex >= 0 && stopRangeIndex >= 0) {
  151. var startRange = __ranges[startRangeIndex]
  152. var stopRange = __ranges[stopRangeIndex]
  153. var length = 1 + stopRangeIndex - startRangeIndex
  154. if (start <= startRange[0] && stop >= stopRange[1]) { //remove
  155. __ranges.splice(startRangeIndex, length)
  156. } else if (start - 1 < startRange[0] && stop <= stopRange[1]) { //cut front
  157. __ranges.splice(startRangeIndex, length, [stop + 1, stopRange[1]])
  158. } else if (start - 1 < startRange[1] && stop >= stopRange[1]) { // cut back
  159. __ranges.splice(startRangeIndex, length, [startRange[0], start - 1])
  160. } else { //split
  161. __ranges.splice(startRangeIndex, length, [startRange[0], start - 1], [stop + 1, stopRange[1]])
  162. }
  163. }
  164. }
  165. __dirty = true
  166. count = __count() // forces a re-evaluation of indexes in the delegates
  167. selectionChanged()
  168. }
  169. }