# # # patch "guitone.pro" # from [3352f5d1507c2b8457752575d3e272374316ace7] # to [e1976f62071aa2a2997a89659b4f2a6dbb529498] # # patch "src/model/Inventory.cpp" # from [ca5ce9ae95f10a662c15da323183356d64dc0212] # to [eb71059b947b91d707385bcf01aae715a6318756] # # patch "src/model/Inventory.h" # from [932f48c5ed90807b37a26c894a139f93985454be] # to [a66c6d72381d4628a70ab35445a8eedbfa6e0a99] # # patch "src/model/InventoryModel.cpp" # from [5e43bd88ca04b12866e6bf64425e47cb0525f914] # to [130c5c2d483106de0b1181f300f70078ceb3ca7c] # # patch "src/model/InventoryModel.h" # from [aa9b4be844447b426ca557ecee9a64aaf442474d] # to [b18ea84b5d13dfc7aca550e26238233a7c764b82] # # patch "src/view/InventoryView.cpp" # from [264358ef757142675513404c60332d0a881718fb] # to [c10cf69bffd6833e3fe82896fbc960efa45d1d68] # # patch "src/view/InventoryView.h" # from [43f47c2dd61433f5d526edc045cec2c8f7c26d67] # to [0593223a91095a8c0a4a149a8b85b050d1b55361] # # patch "src/view/WorkspaceWindow.cpp" # from [8f2511b6d776f68716962305e51dce09fe25bc18] # to [b95bcec3c4bb829f858da986a0d5611b749a33b0] # # patch "src/view/WorkspaceWindow.h" # from [baa9b2a1c5ccc191ca799df1b255704138795427] # to [3c181a5026143baf9e58dc86a97cf4ee5469356b] # # patch "src/view/dialogs/UnaccountedRenames.cpp" # from [3d1f44d279e9d0b244834f879d8ad80e91bfaa48] # to [fd374b3f0fcaf295cdb11587f4c9ccccd892c6a0] # ============================================================ --- guitone.pro 3352f5d1507c2b8457752575d3e272374316ace7 +++ guitone.pro e1976f62071aa2a2997a89659b4f2a6dbb529498 @@ -69,6 +69,7 @@ HEADERS = src/view/TreeView.h \ src/model/InventoryItem.h \ src/model/InventoryModel.h \ src/model/InventoryProxyModel.h \ + src/model/InventoryWatcher.h \ src/model/GetAttributes.h \ src/model/Select.h \ src/model/Certs.h \ @@ -148,6 +149,7 @@ SOURCES += src/view/TreeView.cpp \ src/model/InventoryItem.cpp \ src/model/InventoryModel.cpp \ src/model/InventoryProxyModel.cpp \ + src/model/InventoryWatcher.cpp \ src/model/GetAttributes.cpp \ src/model/Select.cpp \ src/model/Certs.cpp \ ============================================================ --- src/model/Inventory.cpp ca5ce9ae95f10a662c15da323183356d64dc0212 +++ src/model/Inventory.cpp eb71059b947b91d707385bcf01aae715a6318756 @@ -43,13 +43,8 @@ void Inventory::setWorkspacePath(const W workspacePath = ws; } -void Inventory::refresh(bool fullQuery) +void Inventory::read(const QString & path, bool fullQuery) { - readInventory(QString(), fullQuery); -} - -void Inventory::readInventory(const QString & path, bool fullQuery) -{ I(!workspacePath.isEmpty()); QStringList cmd = QStringList() << "inventory"; ============================================================ --- src/model/Inventory.h 932f48c5ed90807b37a26c894a139f93985454be +++ src/model/Inventory.h a66c6d72381d4628a70ab35445a8eedbfa6e0a99 @@ -39,11 +39,10 @@ public slots: public slots: void setWorkspacePath(const WorkspacePath &); - void refresh(bool fullQuery = false); + void read(const QString & path = QString(), bool fullQuery = false); private: void processTaskResult(const MonotoneTask &); - void readInventory(const QString &, bool fullQuery = false); void insertRowsRecursive(ModelItem *, const QMap > &); void removeRowsRecursive(ModelItem *, int, int); ============================================================ --- src/model/InventoryModel.cpp 5e43bd88ca04b12866e6bf64425e47cb0525f914 +++ src/model/InventoryModel.cpp 130c5c2d483106de0b1181f300f70078ceb3ca7c @@ -65,9 +65,9 @@ void InventoryModel::setWorkspacePath(co inventory->setWorkspacePath(ws); } -void InventoryModel::refresh() +void InventoryModel::refresh(const QString & path) { - inventory->refresh(false); + inventory->read(path, false); } bool InventoryModel::canFetchMore(const QModelIndex & parent) const @@ -130,7 +130,7 @@ void InventoryModel::fetchMore(const QMo invitem->setAboutToBeExpanded(); - inventory->readInventory(invitem->getPath()); + inventory->read(invitem->getPath()); } void InventoryModel::maybeResetModel(const QString & queriedPath) ============================================================ --- src/model/InventoryModel.h aa9b4be844447b426ca557ecee9a64aaf442474d +++ src/model/InventoryModel.h b18ea84b5d13dfc7aca550e26238233a7c764b82 @@ -43,7 +43,7 @@ public slots: public slots: //! forwards void setWorkspacePath(const WorkspacePath &); - void refresh(); + void refresh(const QString & path = QString()); private: QModelIndex indexFromItem(ModelItem *, int) const; ============================================================ --- src/view/InventoryView.cpp 264358ef757142675513404c60332d0a881718fb +++ src/view/InventoryView.cpp c10cf69bffd6833e3fe82896fbc960efa45d1d68 @@ -28,7 +28,7 @@ InventoryView::InventoryView(QWidget * p #include InventoryView::InventoryView(QWidget * parent, const QString & objectName) - : TreeView(parent, objectName), invViewDelegate(parent) + : TreeView(parent, objectName), invViewDelegate(parent), selectModel(0) { setItemDelegate(&invViewDelegate); setSelectionMode(QAbstractItemView::ExtendedSelection); @@ -180,6 +180,8 @@ InventoryView::~InventoryView() delete actIgnoreMultiple; delete actUnignoreMultiple; delete actRevertMultiple; + + if (selectModel) delete selectModel; } // ensure that we only accept sortfilterproxymodels @@ -216,6 +218,7 @@ void InventoryView::setModel(QSortFilter } TreeView::setModel(newModel); + selectModel = new QItemSelectionModel(newModel); connect( newModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), @@ -790,3 +793,57 @@ void InventoryView::setBackgroundImage() "background-repeat: no-repeat;}"); } } + +bool InventoryView::viewportEvent(QEvent * ev) +{ + switch (ev->type()) + { + case QEvent::Paint: + notifyAboutViewportChanges(); + default: + return QAbstractScrollArea::viewportEvent(ev); + } + I(false); +} + +void InventoryView::notifyAboutViewportChanges() +{ + // save the old selection model reference + QItemSelectionModel * oldSelectModel = selectionModel(); + + setSelectionModel(selectModel); + setSelection(viewport()->rect(), + QItemSelectionModel::Rows | QItemSelectionModel::ClearAndSelect); + QModelIndexList newIndexes = selectedIndexes(); + + // restore it again + setSelectionModel(oldSelectModel); + + for (int i=0; i 0) + { + newIndexes.removeAt(i); + continue; + } + i++; + } + + QSet oldIndexSet = QSet::fromList(itemsVisibleInViewport); + QSet newIndexSet = QSet::fromList(newIndexes); + + QSet removedIndexes = oldIndexSet - newIndexSet; + if (removedIndexes.size() > 0) + { + emit removedFromViewport(removedIndexes.toList()); + } + + QSet addedIndexes = newIndexSet - oldIndexSet; + if (addedIndexes.size() > 0) + { + emit addedToViewport(addedIndexes.toList()); + } + + itemsVisibleInViewport = newIndexes; +} + ============================================================ --- src/view/InventoryView.h 43f47c2dd61433f5d526edc045cec2c8f7c26d67 +++ src/view/InventoryView.h 0593223a91095a8c0a4a149a8b85b050d1b55361 @@ -48,6 +48,8 @@ signals: void diffFile(const QString &); void fileHistory(const QString &); void commitRevision(const QStringList &); + void addedToViewport(const QModelIndexList &); + void removedFromViewport(const QModelIndexList &); private: enum DefaultAction { None, Chdir, Open, FileDiff, Commit }; @@ -57,6 +59,8 @@ private: DefaultAction getDefaultAction(const QModelIndex &) const; void createAndConnectContextActions(); void closeEvent(); + bool viewportEvent(QEvent *); + void notifyAboutViewportChanges(); QAction * actChdir; QAction * actOpen; @@ -82,6 +86,9 @@ private: InventoryViewDelegate invViewDelegate; + QModelIndexList itemsVisibleInViewport; + QItemSelectionModel * selectModel; + private slots: void newNodeLoaded(const QModelIndex &, const QModelIndex &); void changeDirectory(const QModelIndex &); ============================================================ --- src/view/WorkspaceWindow.cpp 8f2511b6d776f68716962305e51dce09fe25bc18 +++ src/view/WorkspaceWindow.cpp b95bcec3c4bb829f858da986a0d5611b749a33b0 @@ -28,8 +28,8 @@ WorkspaceWindow::WorkspaceWindow() : Dat WorkspaceWindow::WorkspaceWindow() : DatabaseWindow(), mainSplitter(0), listSplitter(0), treeView(0), listView(0), attrView(0), statusBar(0), - iconHelp(0), - invModel(0), attrModel(0), proxyModelFolderTree(0), proxyModelFileList(0) + iconHelp(0), invModel(0), attrModel(0), proxyModelFolderTree(0), + proxyModelFileList(0), invWatcher(0) { setObjectName("WorkspaceWindow"); } @@ -58,6 +58,7 @@ WorkspaceWindow::~WorkspaceWindow() if (proxyModelFileList) delete proxyModelFileList; if (invModel) delete invModel; if (attrModel) delete attrModel; + if (invWatcher) delete invWatcher; } void WorkspaceWindow::init() @@ -190,6 +191,7 @@ void WorkspaceWindow::setup() // models invModel = new InventoryModel(this); + invWatcher = new InventoryWatcher(this); attrModel = new GetAttributes(this); proxyModelFolderTree = new InventoryProxyModel(this, true); @@ -199,6 +201,11 @@ void WorkspaceWindow::setup() proxyModelFileList->setSourceModel(invModel); connect( + invWatcher, SIGNAL(changedPath(const QString &)), + invModel, SLOT(refresh(const QString &)) + ); + + connect( invModel, SIGNAL(invalidWorkspaceFormat(const QString &)), this, SLOT(invalidWorkspaceFormat(const QString &)) ); @@ -239,6 +246,26 @@ void WorkspaceWindow::setup() listView->setModel(proxyModelFileList); listView->setType(InventoryView::FileList); + connect( + treeView, SIGNAL(addedToViewport(const QModelIndexList &)), + invWatcher, SLOT(watchItems(const QModelIndexList &)) + ); + + connect( + treeView, SIGNAL(removedFromViewport(const QModelIndexList &)), + invWatcher, SLOT(unwatchItems(const QModelIndexList &)) + ); + + connect( + listView, SIGNAL(addedToViewport(const QModelIndexList &)), + invWatcher, SLOT(watchItems(const QModelIndexList &)) + ); + + connect( + listView, SIGNAL(removedFromViewport(const QModelIndexList &)), + invWatcher, SLOT(unwatchItems(const QModelIndexList &)) + ); + attrView->setModel(attrModel); iconHelp = new IconHelp(this); @@ -260,9 +287,13 @@ void WorkspaceWindow::load(const QString Settings::addItemToList("RecentWorkspaceList", workspacePath, 5); reinterpret_cast(dialogManager)->init(workspacePath); + invModel->setWorkspacePath(workspacePath); + invWatcher->setWorkspacePath(workspacePath); + attrModel->setWorkspacePath(workspacePath); + + // read the inventory invModel->refresh(); - attrModel->setWorkspacePath(workspacePath); } void WorkspaceWindow::openFile(const QString & filePath) ============================================================ --- src/view/WorkspaceWindow.h baa9b2a1c5ccc191ca799df1b255704138795427 +++ src/view/WorkspaceWindow.h 3c181a5026143baf9e58dc86a97cf4ee5469356b @@ -23,6 +23,7 @@ #include "InventoryModel.h" #include "InventoryProxyModel.h" +#include "InventoryWatcher.h" #include "GetAttributes.h" #include "InventoryView.h" @@ -59,6 +60,7 @@ protected: GetAttributes * attrModel; InventoryProxyModel * proxyModelFolderTree; InventoryProxyModel * proxyModelFileList; + InventoryWatcher * invWatcher; private slots: void readAttributes(const QModelIndex &); ============================================================ --- src/view/dialogs/UnaccountedRenames.cpp 3d1f44d279e9d0b244834f879d8ad80e91bfaa48 +++ src/view/dialogs/UnaccountedRenames.cpp fd374b3f0fcaf295cdb11587f4c9ccccd892c6a0 @@ -62,7 +62,7 @@ void UnaccountedRenames::checkForUnaccou this, SLOT(findUnaccountedRenames()) ); - inventory->refresh(true); + inventory->read(QString(), true); } void UnaccountedRenames::findUnaccountedRenames()