diff --git a/libtaskmanager/launchertasksmodel.h b/libtaskmanager/launchertasksmodel.h --- a/libtaskmanager/launchertasksmodel.h +++ b/libtaskmanager/launchertasksmodel.h @@ -62,7 +62,8 @@ int rowCount(const QModelIndex &parent = QModelIndex()) const override; /** - * The list of launcher URLs serialized to strings. + * The list of launcher URLs serialized to strings along with + * the activities they belong to. * * @see setLauncherList * @returns the list of launcher URLs serialized to strings. diff --git a/libtaskmanager/launchertasksmodel.cpp b/libtaskmanager/launchertasksmodel.cpp --- a/libtaskmanager/launchertasksmodel.cpp +++ b/libtaskmanager/launchertasksmodel.cpp @@ -213,6 +213,25 @@ // Is url is not valid, ignore it if (!url.isValid()) continue; + // Filter invalid activities + if (!activities.isEmpty()) { + const auto allActivities = d->activities.activities(); + QStringList validActivities; + for (const auto& activity: activities) { + if (allActivities.contains(activity)) { + validActivities << activity; + } + } + + if (validActivities.isEmpty()) { + // If all activities that had this launcher are + // removed, we are killing the launcher as well + continue; + } + + activities = validActivities; + } + // Is the url a duplicate? const auto location = std::find_if(newLaunchersOrder.begin(), newLaunchersOrder.end(), diff --git a/libtaskmanager/launchertasksmodel_p.h b/libtaskmanager/launchertasksmodel_p.h new file mode 100644 --- /dev/null +++ b/libtaskmanager/launchertasksmodel_p.h @@ -0,0 +1,66 @@ +/******************************************************************** +Copyright 2016 Ivan Cukic + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) version 3, or any +later version accepted by the membership of KDE e.V. (or its +successor approved by the membership of KDE e.V.), which shall +act as a proxy defined in Section 6 of version 3 of the license. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library. If not, see . +*********************************************************************/ + +#ifndef LAUNCHERTASKSMODEL_P_H +#define LAUNCHERTASKSMODEL_P_H + +#include +#include +#include + +namespace TaskManager { + +#define NULL_UUID "00000000-0000-0000-0000-000000000000" + +inline static std::pair deserializeLauncher(const QString &serializedLauncher) +{ + QStringList activities; + QUrl url(serializedLauncher, QUrl::StrictMode); + + // The storage format is: [list of activity ids]\nURL + // The activity IDs list can not be empty, it at least needs + // to contain the nulluuid. + // If parsing fails, we are considering the serialized launcher + // to not have the activities array -- to have the old format + if (serializedLauncher.startsWith('[')) { + // It seems we have the activity specifier in the launcher + const auto activitiesBlockEnd = serializedLauncher.indexOf("]\n"); + + if (activitiesBlockEnd != -1) { + activities = serializedLauncher.mid(1, activitiesBlockEnd - 1).split(",", QString::SkipEmptyParts); + + if (!activities.isEmpty()) { + url = QUrl(serializedLauncher.mid(activitiesBlockEnd + 2), QUrl::StrictMode); + } + } + } + + // If the activities array is empty, this means that this launcher + // needs to be on all activities + if (activities.isEmpty()) { + activities = QStringList({ NULL_UUID }); + } + + return std::make_pair(url, activities); +} + +} // namespace TaskManager + +#endif // LAUNCHERTASKSMODEL_P_H diff --git a/libtaskmanager/taskfilterproxymodel.cpp b/libtaskmanager/taskfilterproxymodel.cpp --- a/libtaskmanager/taskfilterproxymodel.cpp +++ b/libtaskmanager/taskfilterproxymodel.cpp @@ -21,6 +21,8 @@ #include "taskfilterproxymodel.h" #include "abstracttasksmodel.h" +#include "launchertasksmodel_p.h" + namespace TaskManager { @@ -287,7 +289,7 @@ if (!activities.isNull()) { const QStringList l = activities.toStringList(); - if (!l.isEmpty() && !l.contains(d->activity)) { + if (!l.isEmpty() && !l.contains(NULL_UUID) && !l.contains(d->activity)) { return false; } } diff --git a/libtaskmanager/tasksmodel.h b/libtaskmanager/tasksmodel.h --- a/libtaskmanager/tasksmodel.h +++ b/libtaskmanager/tasksmodel.h @@ -120,7 +120,8 @@ int launcherCount() const; /** - * The list of launcher URLs serialized to strings. + * The list of launcher URLs serialized to strings along with + * the activities they belong to. * * @see setLauncherList * @returns the list of launcher URLs serialized to strings. diff --git a/libtaskmanager/tasksmodel.cpp b/libtaskmanager/tasksmodel.cpp --- a/libtaskmanager/tasksmodel.cpp +++ b/libtaskmanager/tasksmodel.cpp @@ -30,6 +30,8 @@ #include "startuptasksmodel.h" #include "windowtasksmodel.h" +#include "launchertasksmodel_p.h" + #include #include #include @@ -1435,23 +1437,27 @@ return; } - QMap sortedLaunchers; + QMap sortedShownLaunchers; foreach(const QString &launcherUrlStr, launcherList()) { int row = -1; - QUrl launcherUrl(launcherUrlStr); + QStringList activities; + QUrl launcherUrl; + + std::tie(launcherUrl, activities) = deserializeLauncher(launcherUrlStr); - for (int i = 0; i < rowCount(); ++i) { - const QUrl &rowLauncherUrl = index(i, 0).data(AbstractTasksModel::LauncherUrlWithoutIcon).toUrl(); + for (int i = 0; i < d->launcherTasksModel->rowCount(); ++i) { + const QUrl &rowLauncherUrl = + d->launcherTasksModel->index(i, 0).data(AbstractTasksModel::LauncherUrlWithoutIcon).toUrl(); if (launcherUrlsMatch(launcherUrl, rowLauncherUrl, IgnoreQueryItems)) { row = i; break; } } if (row != -1) { - sortedLaunchers.insert(row, launcherUrl); + sortedShownLaunchers.insert(row, launcherUrlStr); } } @@ -1477,7 +1483,7 @@ } } - setLauncherList(QUrl::toStringList(sortedLaunchers.values())); + setLauncherList(sortedShownLaunchers.values()); d->launcherSortingDirty = false; }