Commit b55420b2 authored by Valerii Malov's avatar Valerii Malov

Try to keep ContextManager in sync with viewed files in MainWindow

Summary:
ContextManager now is responsible for switching to the directory
containing requested URL and selecting it. However, if it is not
possible, URL is still kept (in case of remote URLs), while selection is
cleared (to avoid dragging in local files)

MainWindow now relies on ContextManager's selection and/or
selectedFileItemList instead of ThumbnailView selection. If selection &
currentUrl are empty, refuse to open View tab, otherwise display
selected items.

This should prevent (reduce?) the amount of mismatches between which
files user sees, and which files are being operated upon
(e.g. by FileOpsContextManagerItem)

BUG: 355493
BUG: 275807
BUG: 326190
BUG: 306835

Test Plan:
Tried playing around to make sure it doesn't break any old behaviour
Tried deleting all image files while in View mode, to make sure we back out when we run out of images
Tried opening an http url and check that operations apply to it unless we select something in browse tab
And then remote image should be unloaded from the View tab since our actions will now affect user-selected items

Tests pass but they don't seem to cover this?

Reviewers: #kde_applications, gateau, rkflx

Reviewed By: gateau, rkflx

Subscribers: ngraham, rkflx, gateau

Differential Revision: https://phabricator.kde.org/D8196
parent c980c48c
......@@ -64,17 +64,7 @@ namespace Gwenview
QList<QUrl> FileOpsContextManagerItem::urlList() const
{
QList<QUrl> urlList;
KFileItemList list = contextManager()->selectedFileItemList();
if (list.count() > 0) {
urlList = list.urlList();
} else {
QUrl url = contextManager()->currentUrl();
Q_ASSERT(url.isValid());
urlList << url;
}
return urlList;
return contextManager()->selectedFileItemList().urlList();
}
void FileOpsContextManagerItem::updateServiceList()
......
......@@ -668,13 +668,10 @@ struct MainWindow::Private
isRasterImage = mContextManager->currentUrlIsRasterImage();
canSave = isRasterImage;
isModified = DocumentFactory::instance()->load(url)->isModified();
if (mCurrentMainPageId != ViewMainPageId) {
if (mCurrentMainPageId != ViewMainPageId
&& mContextManager->selectedFileItemList().count() != 1) {
// Saving only makes sense if exactly one image is selected
QItemSelection selection = mThumbnailView->selectionModel()->selection();
QModelIndexList indexList = selection.indexes();
if (indexList.count() != 1) {
canSave = false;
}
canSave = false;
}
}
......@@ -860,9 +857,7 @@ void MainWindow::setInitialUrl(const QUrl &_url)
d->mBrowseAction->trigger();
openDirUrl(url);
} else {
d->mViewAction->trigger();
d->mViewMainPage->openUrl(url);
d->mContextManager->setUrlToSelect(url);
openUrl(url);
}
}
......@@ -884,9 +879,7 @@ void MainWindow::setActiveViewModeAction(QAction* action)
d->mCurrentMainPageId = ViewMainPageId;
// Switching to view mode
d->mViewStackedWidget->setCurrentWidget(d->mViewMainPage);
if (d->mViewMainPage->isEmpty()) {
openSelectedDocuments();
}
openSelectedDocuments();
d->mPreloadDirectionIsForward = true;
QTimer::singleShot(VIEW_PRELOAD_DELAY, this, SLOT(preloadNextUrl()));
} else {
......@@ -934,57 +927,38 @@ void MainWindow::slotThumbnailViewIndexActivated(const QModelIndex& index)
}
}
static bool indexRowLessThan(const QModelIndex& i1, const QModelIndex& i2)
{
return i1.row() < i2.row();
}
void MainWindow::openSelectedDocuments()
{
if (d->mCurrentMainPageId != ViewMainPageId) {
return;
}
QModelIndex currentIndex = d->mThumbnailView->currentIndex();
if (!currentIndex.isValid()) {
return;
}
int count = 0;
QList<QUrl> urls;
QUrl currentUrl;
QModelIndex firstDocumentIndex;
QModelIndexList list = d->mThumbnailView->selectionModel()->selectedIndexes();
// Make 'list' follow the same order as 'mThumbnailView'
qSort(list.begin(), list.end(), indexRowLessThan);
Q_FOREACH(const QModelIndex& index, list) {
KFileItem item = d->mDirModel->itemForIndex(index);
const auto list = d->mContextManager->selectedFileItemList();
for (const auto &item : list) {
if (!item.isNull() && !ArchiveUtils::fileItemIsDirOrArchive(item)) {
QUrl url = item.url();
if (!firstDocumentIndex.isValid()) {
firstDocumentIndex = index;
}
urls << url;
if (index == currentIndex) {
currentUrl = url;
}
urls << item.url();
++count;
if (count == ViewMainPage::MaxViewCount) {
break;
}
}
}
if (urls.isEmpty()) {
// No image to display
// Selection contains no fitting items
// Switch back to browsing mode
d->mBrowseAction->trigger();
d->mViewMainPage->reset();
return;
}
if (currentUrl.isEmpty()) {
// Current index is not selected, or it is not a document: set
// firstDocumentIndex as current
GV_RETURN_IF_FAIL(firstDocumentIndex.isValid());
d->mThumbnailView->selectionModel()->setCurrentIndex(firstDocumentIndex, QItemSelectionModel::Current);
QUrl currentUrl = d->mContextManager->currentUrl();
if (currentUrl.isEmpty() || !urls.contains(currentUrl)) {
// There is no current URL or it doesn't belong to selection
// This can happen when user manually selects a group of items
currentUrl = urls.first();
}
......@@ -1103,27 +1077,14 @@ void MainWindow::updateToggleSideBarAction()
void MainWindow::slotPartCompleted()
{
d->updateActions();
QUrl url = d->mViewMainPage->url();
const QUrl url = d->mContextManager->currentUrl();
if (!url.isEmpty()) {
d->mFileOpenRecentAction->addUrl(url);
d->mGvCore->addUrlToRecentFiles(url);
}
if (!KProtocolManager::supportsListing(url)) {
return;
}
QUrl dirUrl = url;
dirUrl = dirUrl.adjusted(QUrl::RemoveFilename);
dirUrl.setPath(dirUrl.path() + QString());
if (dirUrl.matches(d->mContextManager->currentDirUrl(), QUrl::StripTrailingSlash)) {
QModelIndex index = d->mDirModel->indexForUrl(url);
QItemSelectionModel* selectionModel = d->mThumbnailView->selectionModel();
if (index.isValid() && !selectionModel->isSelected(index)) {
// FIXME: QGV Reactivating this line prevents navigation to prev/next image
//selectionModel->select(index, QItemSelectionModel::SelectCurrent);
}
} else {
d->mContextManager->setCurrentDirUrl(dirUrl);
if (KProtocolManager::supportsListing(url)) {
const QUrl dirUrl = d->mContextManager->currentDirUrl();
d->mGvCore->addUrlToRecentFolders(dirUrl);
}
}
......@@ -1149,7 +1110,7 @@ void MainWindow::slotSelectionChanged()
undoGroup->addStack(doc->undoStack());
undoGroup->setActiveStack(doc->undoStack());
} else {
undoGroup->setActiveStack(0);
undoGroup->setActiveStack(nullptr);
}
}
......@@ -1174,7 +1135,7 @@ void MainWindow::slotCurrentDirUrlChanged(const QUrl &url)
void MainWindow::slotDirModelNewItems()
{
if (d->mThumbnailView->selectionModel()->hasSelection()) {
if (d->mContextManager->selectionModel()->hasSelection()) {
updatePreviousNextActions();
}
}
......@@ -1185,10 +1146,8 @@ void MainWindow::slotDirListerCompleted()
d->mStartSlideShowWhenDirListerCompleted = false;
QTimer::singleShot(0, d->mToggleSlideShowAction, SLOT(trigger()));
}
if (d->mThumbnailView->selectionModel()->hasSelection()) {
if (d->mContextManager->selectionModel()->hasSelection()) {
updatePreviousNextActions();
} else if (!d->mContextManager->urlToSelect().isValid()) {
d->goToFirstDocument();
}
d->mThumbnailView->scrollToSelectedIndex();
d->mViewMainPage->thumbnailBar()->scrollToSelectedIndex();
......@@ -1362,14 +1321,12 @@ void MainWindow::openFile()
void MainWindow::openUrl(const QUrl& url)
{
d->setActionsDisabledOnStartMainPageEnabled(true);
d->mViewAction->trigger();
d->mViewMainPage->openUrl(url);
d->mContextManager->setUrlToSelect(url);
d->mViewAction->trigger();
}
void MainWindow::showDocumentInFullScreen(const QUrl &url)
{
d->mViewMainPage->openUrl(url);
d->mContextManager->setUrlToSelect(url);
d->mFullScreenAction->trigger();
}
......@@ -1510,7 +1467,7 @@ void MainWindow::preloadNextUrl()
qDebug() << "Preloading disabled";
return;
}
QItemSelection selection = d->mThumbnailView->selectionModel()->selection();
QItemSelection selection = d->mContextManager->selectionModel()->selection();
if (selection.size() != 1) {
return;
}
......
......@@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
// KDE
#include <KDirLister>
#include <KFileItem>
#include <KProtocolManager>
// Local
#include <lib/document/documentfactory.h>
......@@ -52,6 +53,7 @@ struct ContextManagerPrivate
QSet<QByteArray> mQueuedSignals;
KFileItemList mSelectedFileItemList;
bool mDirListerFinished = false;
QTimer* mQueuedSignalsTimer;
void queueSignal(const QByteArray& signal)
......@@ -117,6 +119,8 @@ ContextManager::ContextManager(SortedDirModel* dirModel, QObject* parent)
connect(d->mDirModel->dirLister(), SIGNAL(redirection(QUrl)),
SLOT(slotDirListerRedirection(QUrl)));
connect(d->mDirModel->dirLister(), static_cast<void (KDirLister::*)()>(&KDirLister::completed), this, &ContextManager::slotDirListerCompleted);
d->mSelectionModel = new QItemSelectionModel(d->mDirModel);
connect(d->mSelectionModel, &QItemSelectionModel::selectionChanged, this, &ContextManager::slotSelectionChanged);
......@@ -149,6 +153,7 @@ void ContextManager::setCurrentUrl(const QUrl &currentUrl)
undoGroup->setActiveStack(doc->undoStack());
}
d->mSelectedFileItemListNeedsUpdate = true;
currentUrlChanged(currentUrl);
}
......@@ -163,9 +168,14 @@ void ContextManager::setCurrentDirUrl(const QUrl &url)
if (url == d->mCurrentDirUrl) {
return;
}
d->mCurrentDirUrl = url;
if (url.isValid()) {
if (url.isValid() && KProtocolManager::supportsListing(url)) {
d->mCurrentDirUrl = url;
d->mDirModel->dirLister()->openUrl(url);
d->mDirListerFinished = false;
} else {
d->mCurrentDirUrl.clear();
d->mDirModel->dirLister()->clear();
}
currentDirUrlChanged(url);
}
......@@ -276,6 +286,7 @@ void ContextManager::setUrlToSelect(const QUrl &url)
{
GV_RETURN_IF_FAIL(url.isValid());
d->mUrlToSelect = url;
setCurrentDirUrl(url.adjusted(QUrl::RemoveFilename));
setCurrentUrl(url);
selectUrlToSelect();
}
......@@ -318,6 +329,13 @@ void ContextManager::selectUrlToSelect()
if (index.isValid()) {
d->mSelectionModel->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect);
d->mUrlToSelect = QUrl();
} else if (d->mDirListerFinished) {
// Desired URL cannot be found in the directory
// Clear the selection to avoid dragging any local files into context
// and manually set current URL
d->mSelectionModel->clearSelection();
setCurrentUrl(d->mUrlToSelect);
d->mUrlToSelect.clear();
}
}
......@@ -326,5 +344,10 @@ void ContextManager::slotDirListerRedirection(const QUrl &newUrl)
setCurrentDirUrl(newUrl);
}
void ContextManager::slotDirListerCompleted()
{
d->mDirListerFinished = true;
}
} // namespace
......@@ -90,6 +90,7 @@ private Q_SLOTS:
void slotRowsInserted();
void selectUrlToSelect();
void slotDirListerRedirection(const QUrl&);
void slotDirListerCompleted();
private:
ContextManagerPrivate* const d;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment