| 134 | } |
| 135 | |
| 136 | bool FileIgnoreProxy::setFilterState(QModelIndex index, Qt::CheckState state) |
| 137 | { |
| 138 | QFileSystemModel* fsm = qobject_cast<QFileSystemModel*>(sourceModel()); |
| 139 | |
| 140 | if (!fsm) { |
| 141 | return false; |
| 142 | } |
| 143 | |
| 144 | QModelIndex sourceIndex = mapToSource(index); |
| 145 | auto blockedPath = relPath(fsm->filePath(sourceIndex)); |
| 146 | bool changed = false; |
| 147 | if (state == Qt::Unchecked) { |
| 148 | // blocking a path |
| 149 | auto& node = blocked.insert(blockedPath); |
| 150 | // get rid of all blocked nodes below |
| 151 | node.clear(); |
| 152 | changed = true; |
| 153 | } else if (state == Qt::Checked || state == Qt::PartiallyChecked) { |
| 154 | if (!blocked.remove(blockedPath)) { |
| 155 | auto cover = blocked.cover(blockedPath); |
| 156 | qDebug() << "Blocked by cover" << cover; |
| 157 | // uncover |
| 158 | blocked.remove(cover); |
| 159 | // block all contents, except for any cover |
| 160 | QModelIndex rootIndex = fsm->index(FS::PathCombine(root, cover)); |
| 161 | QModelIndex doing = rootIndex; |
| 162 | int row = 0; |
| 163 | QStack<QModelIndex> todo; |
| 164 | while (1) { |
| 165 | auto node = fsm->index(row, 0, doing); |
| 166 | if (!node.isValid()) { |
| 167 | if (!todo.size()) { |
| 168 | break; |
| 169 | } else { |
| 170 | doing = todo.pop(); |
| 171 | row = 0; |
| 172 | continue; |
| 173 | } |
| 174 | } |
| 175 | auto relpath = relPath(fsm->filePath(node)); |
| 176 | if (blockedPath.startsWith(relpath)) // cover found? |
| 177 | { |
| 178 | // continue processing cover later |
| 179 | todo.push(node); |
| 180 | } else { |
| 181 | // or just block this one. |
| 182 | blocked.insert(relpath); |
| 183 | } |
| 184 | row++; |
| 185 | } |
| 186 | } |
| 187 | changed = true; |
| 188 | } |
| 189 | if (changed) { |
| 190 | // update the thing |
| 191 | emit dataChanged(index, index, { Qt::CheckStateRole }); |
| 192 | // update everything above index |
| 193 | QModelIndex up = index.parent(); |