| 196 | } |
| 197 | |
| 198 | void ProjectChangesModel::itemsAdded(const QModelIndex& parent, int start, int end) |
| 199 | { |
| 200 | ProjectModel* model=ICore::self()->projectController()->projectModel(); |
| 201 | ProjectBaseItem* item=model->itemFromIndex(parent); |
| 202 | |
| 203 | if(!item) |
| 204 | return; |
| 205 | |
| 206 | IProject* project=item->project(); |
| 207 | |
| 208 | if(!project) |
| 209 | return; |
| 210 | |
| 211 | // FIXME: this code is utterly broken. When a new file is created, the signal ProjectModel::rowsInserted() is |
| 212 | // emitted and the item has a parent. But the loop below does not process the added file, because the |
| 213 | // `start` and `end` parameters of the signal QAbstractItemModel::rowsInserted() are inclusive indices. |
| 214 | // If this bug is fixed by changing the loop's condition to `i <= end`, the urls list would remain empty |
| 215 | // because ProjectBaseItem() appends the item under construction to the model while its type is still |
| 216 | // ProjectBaseItem, so the item->type() checks below fail. Even if the checks are removed, the path |
| 217 | // of a bare ProjectBaseItem is always empty, so the changes() call below would not work anyway. |
| 218 | // |
| 219 | // Suppose one fixes all these bugs, what then? KDevelop would freeze when many files are added, |
| 220 | // e.g. while switching between distant git revisions! That's because this slot, and therefore |
| 221 | // IBasicVersionControl::status(), would be invoked separately for each added file. Each call to |
| 222 | // GitPlugin::status() would schedule an invocation of GitPlugin::parseGitStatusOutput(). |
| 223 | // parseGitStatusOutput() calls GitPlugin::getLsFiles(), which runs a |
| 224 | // `git ls-files` process synchronously. This implementation must be optimized before fixing |
| 225 | // the bugs. The UI freezes have been reported at https://bugs.kde.org/show_bug.cgi?id=486949 |
| 226 | // |
| 227 | // Another related bug is that the signal QAbstractItemModel::rowsRemoved() is not connected to for cleanup. |
| 228 | // |
| 229 | // This slot and related code have been copied almost verbatim to the class RepoStatusModel. Therefore, |
| 230 | // RepoStatusModel suffers from all these bugs as well. The extensive code duplication causes another |
| 231 | // performance bug: when both ProjectChangesModel and RepoStatusModel instances exist at the same time, each |
| 232 | // of them runs the same git processes and invokes the same slow handling of process results in GitPlugin. |
| 233 | // This work should not be duplicated and ought to be performed at most once in order to improve performance. |
| 234 | |
| 235 | QList<QUrl> urls; |
| 236 | |
| 237 | for(int i=start; i<end; i++) { |
| 238 | QModelIndex idx=parent.model()->index(i, 0, parent); |
| 239 | item=model->itemFromIndex(idx); |
| 240 | |
| 241 | if(item->type()==ProjectBaseItem::File || item->type()==ProjectBaseItem::Folder || item->type()==ProjectBaseItem::BuildFolder) |
| 242 | urls += item->path().toUrl(); |
| 243 | } |
| 244 | |
| 245 | if(!urls.isEmpty()) |
| 246 | changes(project, urls, KDevelop::IBasicVersionControl::NonRecursive); |
| 247 | } |
| 248 | |
| 249 | void ProjectChangesModel::reload(const QList<IProject*>& projects) |
| 250 | { |
nothing calls this directly
no test coverage detected