Verified Commit 7f09fb16 authored by Fushan Wen's avatar Fushan Wen
Browse files

screenmapper: Remember activity ID in screen mapping

This commit adds an extra string to screenmapper to remember the
activity ID corresponding to the screen ID. Now screenmapper can
correctly handle different activites, and desktops of different
activities can correctly show their items.

The problem

When the user sets "Files linked to the current activity" on one
activity (A) and switches to any other activity (B), though the desktop
on activity B is set to "Show Desktop folder",  there is nothing on
the desktop until the user restarts plasmashell.

The cause

In screenmapper.cpp, `removeScreen()` only checkes for the screen ID,
but two activities can share the same screen ID. Then if both the two
activities are set to "Show desktop folder", then in `setUrl()`

1. After the user changes the desktop folder option on one of the two activities,
   `removeScreen()` will remove all item records related to the screen
   ID and **the old URL (desktop:/)**.
2. But `addScreen()` will only add back item records for the current activity
   because `addScreen()` will directly return if `m_availableScreens`
   already contains the screen ID (which is added from the current activity).
3. Thus items on the desktop of the other activity incorrectly disappears.

The fix

1. When calling `addScreen()` or `removeScreen()` from FolderModel, also
   consider the activity corresponding to the FolderModel, which is the
   current activity when the FolderModel is initialized.
2. Provide a migrator for the old configuration entries because an extra
   record is added.

BUG: 447558
parent 57dae632
......@@ -32,6 +32,7 @@ target_link_libraries(folderplugin
Qt::Core
Qt::Qml
Qt::Quick
KF5::Activities
KF5::CoreAddons
KF5::KIOCore
KF5::KIOWidgets
......
......@@ -38,6 +38,7 @@ void FolderModelTest::createTestFolder(const QString &path)
void FolderModelTest::init()
{
m_currentActivity = QStringLiteral("00000000-0000-0000-0000-000000000000");
m_folderDir = new QTemporaryDir();
createTestFolder(desktop);
m_folderModel = new FolderModel(this);
......@@ -273,7 +274,7 @@ void FolderModelTest::tst_multiScreen()
const auto index = m_folderModel->index(i, 0);
const auto name = index.data(FolderModel::UrlRole).toUrl();
// all items are on the first screen by default
QCOMPARE(screenMapper->screenForItem(name), 0);
QCOMPARE(screenMapper->screenForItem(name, m_currentActivity), 0);
}
// move one file to a new screen
......@@ -289,7 +290,7 @@ void FolderModelTest::tst_multiScreen()
const auto count2 = secondFolderModel.rowCount();
QCOMPARE(count2, 0);
screenMapper->addMapping(movedItem, 1);
screenMapper->addMapping(movedItem, 1, m_currentActivity);
m_folderModel->invalidate();
secondFolderModel.invalidate();
s.wait(1000);
......@@ -298,23 +299,23 @@ void FolderModelTest::tst_multiScreen()
QCOMPARE(m_folderModel->rowCount(), count - 1);
QCOMPARE(secondFolderModel.rowCount(), 1);
QCOMPARE(secondFolderModel.index(0, 0).data(FolderModel::UrlRole).toUrl(), movedItem);
QCOMPARE(screenMapper->screenForItem(movedItem), 1);
QCOMPARE(screenMapper->screenForItem(movedItem, m_currentActivity), 1);
// remove extra screen, we have all items back
screenMapper->removeScreen(1, stringToUrl(m_folderModel->url()));
screenMapper->removeScreen(1, m_currentActivity, stringToUrl(m_folderModel->url()));
s.wait(500);
QCOMPARE(m_folderModel->rowCount(), count);
QCOMPARE(secondFolderModel.rowCount(), 0);
QCOMPARE(screenMapper->screenForItem(movedItem), 0);
QCOMPARE(screenMapper->screenForItem(movedItem, m_currentActivity), 0);
// add back extra screen, the item is moved there
screenMapper->addScreen(1, stringToUrl(m_folderModel->url()));
screenMapper->addScreen(1, m_currentActivity, stringToUrl(m_folderModel->url()));
s.wait(500);
s2.wait(500);
QCOMPARE(m_folderModel->rowCount(), count - 1);
QCOMPARE(secondFolderModel.rowCount(), 1);
QCOMPARE(secondFolderModel.index(0, 0).data(FolderModel::UrlRole).toUrl(), movedItem);
QCOMPARE(screenMapper->screenForItem(movedItem), 1);
QCOMPARE(screenMapper->screenForItem(movedItem, m_currentActivity), 1);
// create a new item, it appears on the first screen
QDir dir(m_folderDir->path());
......@@ -324,7 +325,7 @@ void FolderModelTest::tst_multiScreen()
s.wait(1000);
QCOMPARE(m_folderModel->rowCount(), count);
QCOMPARE(secondFolderModel.rowCount(), 1);
QCOMPARE(screenMapper->screenForItem(stringToUrl(QLatin1String("file://") + dir.path())), 0);
QCOMPARE(screenMapper->screenForItem(stringToUrl(QLatin1String("file://") + dir.path()), m_currentActivity), 0);
}
void FolderModelTest::tst_multiScreenDifferenPath()
......
......@@ -37,6 +37,7 @@ private Q_SLOTS:
private:
void createTestFolder(const QString &path);
QString m_currentActivity;
FolderModel *m_folderModel;
QTemporaryDir *m_folderDir;
};
......
......@@ -21,6 +21,7 @@ static const QLatin1String desktop(QLatin1String("Desktop"));
void PositionerTest::initTestCase()
{
m_currentActivity = QStringLiteral("00000000-0000-0000-0000-000000000000");
m_folderDir = new QTemporaryDir();
QDir dir(m_folderDir->path());
......@@ -249,7 +250,7 @@ void PositionerTest::tst_proxyMapping()
const auto movedItem = m_folderModel->index(1, 0).data(FolderModel::UrlRole).toUrl();
// move the item 1 from source (now in position 2) to the second screen
screenMapper->addMapping(movedItem, 1);
screenMapper->addMapping(movedItem, 1, m_currentActivity);
expectedProxy2SourceScreen1[0] = 0;
expectedSource2ProxyScreen1[0] = 0;
......@@ -268,7 +269,7 @@ void PositionerTest::tst_proxyMapping()
verifyMapping(secondPositioner.sourceToProxyMapping(), expectedSource2ProxyScreen1);
// move back the same item to the first screen
screenMapper->addMapping(movedItem, 0);
screenMapper->addMapping(movedItem, 0, m_currentActivity);
// nothing on the second screen
expectedSource2ProxyScreen1.clear();
......
......@@ -42,6 +42,7 @@ private Q_SLOTS:
private:
void checkPositions(int perStripe);
QString m_currentActivity;
Positioner *m_positioner;
FolderModel *m_folderModel;
QTemporaryDir *m_folderDir;
......
......@@ -18,6 +18,7 @@ QTEST_MAIN(ScreenMapperTest)
void ScreenMapperTest::initTestCase()
{
m_screenMapper = ScreenMapper::instance();
m_currentActivity = QStringLiteral("00000000-0000-0000-0000-000000000000");
}
void ScreenMapperTest::init()
......@@ -29,15 +30,15 @@ void ScreenMapperTest::tst_addScreens()
{
const auto path = ScreenMapper::stringToUrl(QStringLiteral("desktop:/"));
QSignalSpy s(m_screenMapper, &ScreenMapper::screensChanged);
m_screenMapper->addScreen(-1, path);
m_screenMapper->addScreen(-1, m_currentActivity, path);
QCOMPARE(s.count(), 0);
m_screenMapper->addScreen(1, path);
m_screenMapper->addScreen(1, m_currentActivity, path);
QCOMPARE(s.count(), 1);
m_screenMapper->addScreen(0, path);
m_screenMapper->addScreen(0, m_currentActivity, path);
QCOMPARE(s.count(), 2);
m_screenMapper->addScreen(1, path);
m_screenMapper->addScreen(1, m_currentActivity, path);
QCOMPARE(s.count(), 2);
QCOMPARE(m_screenMapper->firstAvailableScreen(path), 0);
QCOMPARE(m_screenMapper->firstAvailableScreen(path, m_currentActivity), 0);
}
void ScreenMapperTest::tst_removeScreens()
......@@ -45,18 +46,18 @@ void ScreenMapperTest::tst_removeScreens()
const auto path = ScreenMapper::stringToUrl(QStringLiteral("desktop:/"));
addScreens(path);
QSignalSpy s(m_screenMapper, &ScreenMapper::screensChanged);
m_screenMapper->removeScreen(-1, path);
m_screenMapper->removeScreen(-1, m_currentActivity, path);
QCOMPARE(s.count(), 0);
m_screenMapper->removeScreen(1, path);
m_screenMapper->removeScreen(1, m_currentActivity, path);
QCOMPARE(s.count(), 1);
QCOMPARE(m_screenMapper->firstAvailableScreen(path), 0);
m_screenMapper->removeScreen(1, path);
QCOMPARE(m_screenMapper->firstAvailableScreen(path, m_currentActivity), 0);
m_screenMapper->removeScreen(1, m_currentActivity, path);
QCOMPARE(s.count(), 1);
m_screenMapper->addScreen(3, path);
m_screenMapper->addScreen(3, m_currentActivity, path);
QCOMPARE(s.count(), 2);
m_screenMapper->removeScreen(0, path);
m_screenMapper->removeScreen(0, m_currentActivity, path);
QCOMPARE(s.count(), 3);
QCOMPARE(m_screenMapper->firstAvailableScreen(path), 2);
QCOMPARE(m_screenMapper->firstAvailableScreen(path, m_currentActivity), 2);
}
void ScreenMapperTest::tst_addMapping()
......@@ -68,9 +69,9 @@ void ScreenMapperTest::tst_addMapping()
for (int i = 0; i < 3; i++) {
const QUrl url = ScreenMapper::stringToUrl(file.arg(i));
m_screenMapper->addMapping(url, i);
m_screenMapper->addMapping(url, i, m_currentActivity);
QCOMPARE(s.count(), i + 1);
QCOMPARE(m_screenMapper->screenForItem(url), i);
QCOMPARE(m_screenMapper->screenForItem(url, m_currentActivity), i);
}
}
......@@ -82,63 +83,63 @@ void ScreenMapperTest::tst_addRemoveScreenWithItems()
for (int i = 0; i < 3; i++) {
const QUrl url = ScreenMapper::stringToUrl(file.arg(i));
m_screenMapper->addMapping(url, i);
m_screenMapper->addMapping(url, i, m_currentActivity);
}
// remove one screen
m_screenMapper->removeScreen(1, path);
QCOMPARE(m_screenMapper->screenForItem(ScreenMapper::stringToUrl(file.arg(0))), 0);
QCOMPARE(m_screenMapper->screenForItem(ScreenMapper::stringToUrl(file.arg(1))), -1);
QCOMPARE(m_screenMapper->screenForItem(ScreenMapper::stringToUrl(file.arg(2))), 2);
m_screenMapper->removeScreen(1, m_currentActivity, path);
QCOMPARE(m_screenMapper->screenForItem(ScreenMapper::stringToUrl(file.arg(0)), m_currentActivity), 0);
QCOMPARE(m_screenMapper->screenForItem(ScreenMapper::stringToUrl(file.arg(1)), m_currentActivity), -1);
QCOMPARE(m_screenMapper->screenForItem(ScreenMapper::stringToUrl(file.arg(2)), m_currentActivity), 2);
// add removed screen back, items screen is restored
m_screenMapper->addScreen(1, path);
QCOMPARE(m_screenMapper->screenForItem(ScreenMapper::stringToUrl(file.arg(0))), 0);
QCOMPARE(m_screenMapper->screenForItem(ScreenMapper::stringToUrl(file.arg(1))), 1);
QCOMPARE(m_screenMapper->screenForItem(ScreenMapper::stringToUrl(file.arg(2))), 2);
m_screenMapper->addScreen(1, m_currentActivity, path);
QCOMPARE(m_screenMapper->screenForItem(ScreenMapper::stringToUrl(file.arg(0)), m_currentActivity), 0);
QCOMPARE(m_screenMapper->screenForItem(ScreenMapper::stringToUrl(file.arg(1)), m_currentActivity), 1);
QCOMPARE(m_screenMapper->screenForItem(ScreenMapper::stringToUrl(file.arg(2)), m_currentActivity), 2);
// remove all screens, firstAvailableScreen changes
m_screenMapper->removeScreen(0, path);
QCOMPARE(m_screenMapper->firstAvailableScreen(path), 1);
m_screenMapper->removeScreen(1, path);
QCOMPARE(m_screenMapper->firstAvailableScreen(path), 2);
m_screenMapper->removeScreen(2, path);
QCOMPARE(m_screenMapper->firstAvailableScreen(path), -1);
m_screenMapper->removeScreen(0, m_currentActivity, path);
QCOMPARE(m_screenMapper->firstAvailableScreen(path, m_currentActivity), 1);
m_screenMapper->removeScreen(1, m_currentActivity, path);
QCOMPARE(m_screenMapper->firstAvailableScreen(path, m_currentActivity), 2);
m_screenMapper->removeScreen(2, m_currentActivity, path);
QCOMPARE(m_screenMapper->firstAvailableScreen(path, m_currentActivity), -1);
QCOMPARE(m_screenMapper->screenForItem(ScreenMapper::stringToUrl(file.arg(0))), -1);
QCOMPARE(m_screenMapper->screenForItem(ScreenMapper::stringToUrl(file.arg(1))), -1);
QCOMPARE(m_screenMapper->screenForItem(ScreenMapper::stringToUrl(file.arg(2))), -1);
QCOMPARE(m_screenMapper->screenForItem(ScreenMapper::stringToUrl(file.arg(0)), m_currentActivity), -1);
QCOMPARE(m_screenMapper->screenForItem(ScreenMapper::stringToUrl(file.arg(1)), m_currentActivity), -1);
QCOMPARE(m_screenMapper->screenForItem(ScreenMapper::stringToUrl(file.arg(2)), m_currentActivity), -1);
// add all screens back, all item's screen is restored
addScreens(path);
QCOMPARE(m_screenMapper->screenForItem(ScreenMapper::stringToUrl(file.arg(0))), 0);
QCOMPARE(m_screenMapper->screenForItem(ScreenMapper::stringToUrl(file.arg(1))), 1);
QCOMPARE(m_screenMapper->screenForItem(ScreenMapper::stringToUrl(file.arg(2))), 2);
QCOMPARE(m_screenMapper->screenForItem(ScreenMapper::stringToUrl(file.arg(0)), m_currentActivity), 0);
QCOMPARE(m_screenMapper->screenForItem(ScreenMapper::stringToUrl(file.arg(1)), m_currentActivity), 1);
QCOMPARE(m_screenMapper->screenForItem(ScreenMapper::stringToUrl(file.arg(2)), m_currentActivity), 2);
// remove one screen and move its item
const QUrl movedItem = ScreenMapper::stringToUrl(file.arg(1));
m_screenMapper->removeScreen(1, path);
QCOMPARE(m_screenMapper->screenForItem(movedItem), -1);
m_screenMapper->addMapping(movedItem, 0);
QCOMPARE(m_screenMapper->screenForItem(movedItem), 0);
m_screenMapper->removeScreen(1, m_currentActivity, path);
QCOMPARE(m_screenMapper->screenForItem(movedItem, m_currentActivity), -1);
m_screenMapper->addMapping(movedItem, 0, m_currentActivity);
QCOMPARE(m_screenMapper->screenForItem(movedItem, m_currentActivity), 0);
// add back the screen, item goes back to the original place
m_screenMapper->addScreen(1, path);
QCOMPARE(m_screenMapper->screenForItem(movedItem), 1);
m_screenMapper->addScreen(1, m_currentActivity, path);
QCOMPARE(m_screenMapper->screenForItem(movedItem, m_currentActivity), 1);
}
void ScreenMapperTest::tst_addRemoveScreenDifferentPaths()
{
const auto path = ScreenMapper::stringToUrl(QStringLiteral("desktop:/Foo"));
const auto path2 = ScreenMapper::stringToUrl(QStringLiteral("desktop:/Foo2"));
m_screenMapper->addScreen(0, path);
QCOMPARE(m_screenMapper->firstAvailableScreen(path), 0);
QCOMPARE(m_screenMapper->firstAvailableScreen(path2), -1);
m_screenMapper->addScreen(0, m_currentActivity, path);
QCOMPARE(m_screenMapper->firstAvailableScreen(path, m_currentActivity), 0);
QCOMPARE(m_screenMapper->firstAvailableScreen(path2, m_currentActivity), -1);
}
void ScreenMapperTest::addScreens(const QUrl &path)
{
m_screenMapper->addScreen(0, path);
m_screenMapper->addScreen(1, path);
m_screenMapper->addScreen(2, path);
m_screenMapper->addScreen(0, m_currentActivity, path);
m_screenMapper->addScreen(1, m_currentActivity, path);
m_screenMapper->addScreen(2, m_currentActivity, path);
}
......@@ -32,6 +32,7 @@ private:
void addScreens(const QUrl &path);
ScreenMapper *m_screenMapper;
QString m_currentActivity;
};
#endif // SCREENMAPPERTEST_H
......@@ -33,6 +33,7 @@
#include <QTimer>
#include <qplatformdefs.h>
#include <KActivities/Consumer>
#include <KAuthorized>
#include <KConfigGroup>
#include <KDirWatch>
......@@ -163,6 +164,7 @@ FolderModel::FolderModel(QObject *parent)
, m_screenUsed(false)
, m_screenMapper(ScreenMapper::instance())
, m_complete(false)
, m_currentActivity(KActivities::Consumer().currentActivity())
{
connect(DragTracker::self(), &DragTracker::dragInProgressChanged, this, &FolderModel::draggingChanged);
connect(DragTracker::self(), &DragTracker::dragInProgressChanged, this, &FolderModel::dragInProgressAnywhereChanged);
......@@ -253,7 +255,7 @@ FolderModel::~FolderModel()
// disconnect so we don't handle signals from the screen mapper when
// removeScreen is called
m_screenMapper->disconnect(this);
m_screenMapper->removeScreen(m_screen, resolvedUrl());
m_screenMapper->removeScreen(m_screen, m_currentActivity, resolvedUrl());
}
}
......@@ -327,7 +329,7 @@ void FolderModel::invalidateFilterIfComplete()
void FolderModel::newFileMenuItemCreated(const QUrl &url)
{
if (m_usedByContainment && !m_screenMapper->sharedDesktops()) {
m_screenMapper->addMapping(url, m_screen, ScreenMapper::DelayedSignal);
m_screenMapper->addMapping(url, m_screen, m_currentActivity, ScreenMapper::DelayedSignal);
m_dropTargetPositions.insert(url.fileName(), localMenuPosition());
m_menuPosition = {};
m_dropTargetPositionsCleanup->start();
......@@ -383,8 +385,8 @@ void FolderModel::setUrl(const QString &url)
Q_EMIT iconNameChanged();
if (m_usedByContainment && !m_screenMapper->sharedDesktops()) {
m_screenMapper->removeScreen(m_screen, oldUrl);
m_screenMapper->addScreen(m_screen, resolvedUrl());
m_screenMapper->removeScreen(m_screen, m_currentActivity, oldUrl);
m_screenMapper->addScreen(m_screen, m_currentActivity, resolvedUrl());
}
}
......@@ -704,7 +706,7 @@ void FolderModel::setScreen(int screen)
m_screen = screen;
if (m_usedByContainment && !m_screenMapper->sharedDesktops()) {
m_screenMapper->addScreen(screen, resolvedUrl());
m_screenMapper->addScreen(screen, m_currentActivity, resolvedUrl());
}
Q_EMIT screenChanged();
}
......@@ -1170,7 +1172,7 @@ void FolderModel::drop(QQuickItem *target, QObject *dropEvent, int row, bool sho
for (const auto &url : mimeData->urls()) {
m_dropTargetPositions.insert(url.fileName(), dropPos);
m_screenMapper->addMapping(mappableUrl(url), m_screen, ScreenMapper::DelayedSignal);
m_screenMapper->addMapping(mappableUrl(url), m_screen, m_currentActivity, ScreenMapper::DelayedSignal);
m_screenMapper->removeItemFromDisabledScreen(mappableUrl(url));
}
Q_EMIT move(x, y, mimeData->urls());
......@@ -1206,7 +1208,7 @@ void FolderModel::drop(QQuickItem *target, QObject *dropEvent, int row, bool sho
const QList<QUrl> urls = mimeData->urls();
for (const auto &url : urls) {
m_dropTargetPositions.insert(url.fileName(), dropPos);
m_screenMapper->addMapping(mappableUrl(url), m_screen, ScreenMapper::DelayedSignal);
m_screenMapper->addMapping(mappableUrl(url), m_screen, m_currentActivity, ScreenMapper::DelayedSignal);
m_screenMapper->removeItemFromDisabledScreen(mappableUrl(url));
}
m_dropTargetPositionsCleanup->start();
......@@ -1259,7 +1261,7 @@ void FolderModel::drop(QQuickItem *target, QObject *dropEvent, int row, bool sho
QUrl url = resolvedUrl();
// if the folderview's folder is a standard path, just use the targetUrl for mapping
if (targetUrl.toString().startsWith(url.toString())) {
m_screenMapper->addMapping(targetUrl, m_screen, ScreenMapper::DelayedSignal);
m_screenMapper->addMapping(targetUrl, m_screen, m_currentActivity, ScreenMapper::DelayedSignal);
} else if (targetUrl.toString().startsWith(dropTargetUrl.toString())) {
// if the folderview's folder is a special path, like desktop:// , we need to convert
// the targetUrl file:// path to a desktop:/ path for mapping
......@@ -1267,7 +1269,7 @@ void FolderModel::drop(QQuickItem *target, QObject *dropEvent, int row, bool sho
auto filePath = targetUrl.path();
if (filePath.startsWith(destPath)) {
url.setPath(filePath.remove(0, destPath.length()));
m_screenMapper->addMapping(url, m_screen, ScreenMapper::DelayedSignal);
m_screenMapper->addMapping(url, m_screen, m_currentActivity, ScreenMapper::DelayedSignal);
}
}
}
......@@ -1471,7 +1473,7 @@ void FolderModel::statResult(KJob *job)
void FolderModel::evictFromIsDirCache(const KFileItemList &items)
{
for (const KFileItem &item : items) {
m_screenMapper->removeFromMap(item.url());
m_screenMapper->removeFromMap(item.url(), m_currentActivity);
m_isDirCache.remove(item.url());
}
}
......@@ -1602,14 +1604,14 @@ bool FolderModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParen
if (m_usedByContainment && !m_screenMapper->sharedDesktops()) {
const QUrl url = item.url();
const int screen = m_screenMapper->screenForItem(url);
const int screen = m_screenMapper->screenForItem(url, m_currentActivity);
// don't do anything if the folderview is not associated with a screen
if (m_screenUsed && screen == -1) {
// The item is not associated with a screen, probably because this is the first
// time we see it or the folderview was previously used as a regular applet.
// Associated with this folderview if the view is on the first available screen
if (m_screen == m_screenMapper->firstAvailableScreen(resolvedUrl())) {
m_screenMapper->addMapping(url, m_screen, ScreenMapper::DelayedSignal);
if (m_screen == m_screenMapper->firstAvailableScreen(resolvedUrl(), m_currentActivity)) {
m_screenMapper->addMapping(url, m_screen, m_currentActivity, ScreenMapper::DelayedSignal);
} else {
return false;
}
......@@ -2041,7 +2043,7 @@ void FolderModel::setAppletInterface(QObject *appletInterface)
Plasma::Corona *corona = containment->corona();
if (corona) {
m_screenMapper->setCorona(corona);
m_screenMapper->setCorona(corona, m_currentActivity);
}
setScreen(containment->screen());
connect(containment, &Plasma::Containment::screenChanged, this, &FolderModel::setScreen);
......
......@@ -352,6 +352,11 @@ private:
QObject *m_appletInterface = nullptr;
bool m_complete;
QPoint m_menuPosition;
/**
* This property is used to save the current activity when FolderModel is initialized.
*/
QString m_currentActivity;
};
class DragTracker : public QObject
......
......@@ -6,11 +6,14 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <optional>
#include "screenmapper.h"
#include <QScreen>
#include <QTimer>
#include <KActivities/Consumer>
#include <KConfig>
#include <KConfigGroup>
#include <Plasma/Corona>
......@@ -48,9 +51,11 @@ ScreenMapper::ScreenMapper(QObject *parent)
m_screenMappingChangedTimer->setSingleShot(true);
}
void ScreenMapper::removeScreen(int screenId, const QUrl &screenUrl)
void ScreenMapper::removeScreen(int screenId, const QString &activity, const QUrl &screenUrl)
{
if (screenId < 0 || !m_availableScreens.contains(screenId))
const std::pair<int, QString> pair = std::make_pair(screenId, activity);
if (screenId < 0 || !m_availableScreens.contains(pair))
return;
const auto screenPathWithScheme = screenUrl.url();
......@@ -59,16 +64,22 @@ void ScreenMapper::removeScreen(int screenId, const QUrl &screenUrl)
QVector<QUrl> urlsToRemoveFromMapping;
while (it != m_screenItemMap.constEnd()) {
const auto name = it.key();
if (it.value() == screenId && name.url().startsWith(screenPathWithScheme)) {
if (it.value() == screenId && name.first.url().startsWith(screenPathWithScheme) && name.second == activity) {
bool found = false;
for (const auto &disabledUrls : qAsConst(m_itemsOnDisabledScreensMap)) {
found = disabledUrls.contains(name);
found = disabledUrls.contains(name.first);
if (found)
break;
}
if (!found)
m_itemsOnDisabledScreensMap[screenId].append(name);
urlsToRemoveFromMapping.append(name);
if (!found) {
auto urlVectorIt = m_itemsOnDisabledScreensMap.find(pair);
if (urlVectorIt == m_itemsOnDisabledScreensMap.end()) {
m_itemsOnDisabledScreensMap[pair] = {name.first};
} else {
urlVectorIt->append(name.first);
}
}
urlsToRemoveFromMapping.append(name.first);
}
++it;
}
......@@ -76,39 +87,41 @@ void ScreenMapper::removeScreen(int screenId, const QUrl &screenUrl)
saveDisabledScreensMap();
for (const auto &url : urlsToRemoveFromMapping)
removeFromMap(url);
removeFromMap(url, activity);
m_availableScreens.removeAll(screenId);
m_availableScreens.removeAll(pair);
auto pathIt = m_screensPerPath.find(screenUrl);
if (pathIt != m_screensPerPath.end() && pathIt.value().size() > 0) {
// remove the screen for a certain url, used when switching the URL for a screen
pathIt->removeAll(screenId);
pathIt->removeAll(pair);
} else if (screenUrl.isEmpty()) {
// the screen was indeed removed so all references to it needs to be cleaned up
for (auto &pathIt : m_screensPerPath) {
pathIt.removeAll(screenId);
pathIt.removeAll(pair);
}
}
Q_EMIT screensChanged();
}
void ScreenMapper::addScreen(int screenId, const QUrl &screenUrl)
void ScreenMapper::addScreen(int screenId, const QString &activity, const QUrl &screenUrl)
{
if (screenId < 0 || m_availableScreens.contains(screenId))
const std::pair<int, QString> pair = std::make_pair(screenId, activity);
if (screenId < 0 || m_availableScreens.contains(pair))
return;
const auto screenPathWithScheme = screenUrl.url();
// restore the stored locations
auto it = m_itemsOnDisabledScreensMap.find(screenId);
auto it = m_itemsOnDisabledScreensMap.find(pair);
if (it != m_itemsOnDisabledScreensMap.end()) {
auto items = it.value();
for (const auto &name : it.value()) {
// add the items to the new screen, if they are on a disabled screen and their
// location is below the new screen's path
if (name.url().startsWith(screenPathWithScheme)) {
addMapping(name, screenId, DelayedSignal);
addMapping(name, screenId, activity, DelayedSignal);
items.removeAll(name);
}
}
......@@ -120,24 +133,25 @@ void ScreenMapper::addScreen(int screenId, const QUrl &screenUrl)
}
saveDisabledScreensMap();
m_availableScreens.append(screenId);
m_availableScreens.append(pair);
// path is empty when a new screen appears that has no folderview base path associated with
if (!screenUrl.isEmpty()) {
auto it = m_screensPerPath.find(screenUrl);
if (it == m_screensPerPath.end()) {
m_screensPerPath[screenUrl] = {screenId};
m_screensPerPath[screenUrl] = {pair};
} else {
it->append(screenId);
it->append(pair);
}
}
Q_EMIT screensChanged();
}
void ScreenMapper::addMapping(const QUrl &url, int screen, MappingSignalBehavior behavior)
void ScreenMapper::addMapping(const QUrl &url, int screen, const QString &activity, MappingSignalBehavior behavior)
{
m_screenItemMap[url] = screen;
m_screenItemMap[std::make_pair(url, activity)] = screen;
if (behavior == DelayedSignal) {
m_screenMappingChangedTimer->start();
} else {
......@@ -145,17 +159,33 @@ void ScreenMapper::addMapping(const QUrl &url, int screen, MappingSignalBehavior
}
}
void ScreenMapper::removeFromMap(const QUrl &url)
void ScreenMapper::removeFromMap(const QUrl &url, const QString &activity)
{
m_screenItemMap.remove(url);
m_screenItemMap.remove(std::make_pair(url, activity));
m_screenMappingChangedTimer->start();
}