libtaskmanager: add new sort mode

wilder-5.25
Yari Polla 4 years ago
parent b32638496a
commit 5098ad492f
  1. 108
      libtaskmanager/tasksmodel.cpp
  2. 10
      libtaskmanager/tasksmodel.h

@ -49,6 +49,8 @@ public:
int launcherCount = 0;
bool switchingFromActiveTask = false;
QTimer *reorderTimer = nullptr;
SortMode sortMode = SortAlpha;
bool separateLaunchers = true;
bool launchInPlace = false;
@ -78,7 +80,6 @@ public:
void updateGroupInline();
QModelIndex preFilterIndex(const QModelIndex &sourceIndex) const;
void updateActivityTaskCounts();
void forceResort();
bool lessThan(const QModelIndex &left, const QModelIndex &right, bool sortOnlyLaunchers = false) const;
private:
@ -139,6 +140,8 @@ TasksModel::Private::~Private()
virtualDesktopInfo = nullptr;
delete activityInfo;
activityInfo = nullptr;
delete reorderTimer;
reorderTimer = nullptr;
}
}
@ -165,7 +168,7 @@ void TasksModel::Private::initModels()
QObject::connect(windowTasksModel, &QAbstractItemModel::rowsRemoved, q, [this]() {
if (sortMode == SortActivity) {
updateActivityTaskCounts();
forceResort();
q->invalidate();
}
// the active task may have potentially changed, so signal that so that users
// will recompute it
@ -690,7 +693,7 @@ void TasksModel::Private::updateGroupInline()
q->setSourceModel(flattenGroupsProxyModel);
if (sortMode == SortManual) {
forceResort();
q->invalidate();
}
} else {
if (hadSourceModel && !flattenGroupsProxyModel) {
@ -707,7 +710,7 @@ void TasksModel::Private::updateGroupInline()
flattenGroupsProxyModel = nullptr;
if (hadSourceModel && sortMode == SortManual) {
forceResort();
q->invalidate();
}
}
@ -767,14 +770,6 @@ void TasksModel::Private::updateActivityTaskCounts()
}
}
void TasksModel::Private::forceResort()
{
// HACK: This causes QSortFilterProxyModel to run all rows through
// our lessThan() implementation again.
q->setDynamicSortFilter(false);
q->setDynamicSortFilter(true);
}
bool TasksModel::Private::lessThan(const QModelIndex &left, const QModelIndex &right, bool sortOnlyLaunchers) const
{
// Launcher tasks go first.
@ -827,6 +822,25 @@ bool TasksModel::Private::lessThan(const QModelIndex &left, const QModelIndex &r
// Sort other cases by sort mode.
switch (sortMode) {
case SortLastActivated: {
QTime leftSortTime = left.data(AbstractTasksModel::LastActivated).toTime();
if (!leftSortTime.isValid()) {
leftSortTime = left.data(Qt::DisplayRole).toTime();
}
QTime rightSortTime = right.data(AbstractTasksModel::LastActivated).toTime();
if (!rightSortTime.isValid()) {
rightSortTime = right.data(Qt::DisplayRole).toTime();
}
if (leftSortTime == rightSortTime) {
return left.row() < right.row();
}
return (leftSortTime < rightSortTime);
}
case SortVirtualDesktop: {
const bool leftAll = left.data(AbstractTasksModel::IsOnAllVirtualDesktops).toBool();
const bool rightAll = right.data(AbstractTasksModel::IsOnAllVirtualDesktops).toBool();
@ -872,8 +886,8 @@ bool TasksModel::Private::lessThan(const QModelIndex &left, const QModelIndex &r
return true;
}
}
Q_FALLTHROUGH();
}
// fall through
case SortActivity: {
// updateActivityTaskCounts() counts the number of window tasks on each
// activity. This will sort tasks by comparing a cumulative score made
@ -913,13 +927,12 @@ bool TasksModel::Private::lessThan(const QModelIndex &left, const QModelIndex &r
if (leftScore != rightScore) {
return (leftScore > rightScore);
}
Q_FALLTHROUGH();
}
// Fall through to source order if sorting is disabled or manual, or alphabetical by app name otherwise.
// This marker comment makes gcc/clang happy:
// fall through
default: {
if (sortMode == SortDisabled) {
return (left.row() < right.row());
return left.row() < right.row();
} else {
// The overall goal of alphabetic sorting is to sort tasks belonging to the
// same app together, while sorting the resulting sets alphabetically among
@ -953,7 +966,7 @@ bool TasksModel::Private::lessThan(const QModelIndex &left, const QModelIndex &r
// If the string are identical fall back to source model (creation/append) order.
if (sortResult == 0) {
return (left.row() < right.row());
return left.row() < right.row();
}
return (sortResult < 0);
@ -1209,10 +1222,38 @@ void TasksModel::setSortMode(SortMode mode)
d->activityTaskCounts.clear();
setSortRole(Qt::DisplayRole);
}
if (mode == SortLastActivated) {
setDynamicSortFilter(false);
if (!d->reorderTimer) {
d->reorderTimer = new QTimer(this);
}
d->reorderTimer->setSingleShot(true);
QObject::connect(this, &TasksModel::activeTaskChanged, this, [this] {
if (activeTask().data(AbstractTasksModel::AppId).isValid()
&& activeTask().data(AbstractTasksModel::AppId).toString() != "org.kde.plasmashell.desktop") {
if (!d->switchingFromActiveTask) {
d->reorderTimer->stop();
invalidate();
} else {
d->reorderTimer->start();
}
}
});
QObject::connect(d->reorderTimer, &QTimer::timeout, this, [this] {
if (d->switchingFromActiveTask) {
d->switchingFromActiveTask = false;
invalidate();
}
});
}
d->sortMode = mode;
d->forceResort();
invalidate();
Q_EMIT sortModeChanged();
}
@ -1229,7 +1270,7 @@ void TasksModel::setSeparateLaunchers(bool separate)
d->separateLaunchers = separate;
d->updateManualSortMap();
d->forceResort();
invalidate();
Q_EMIT separateLaunchersChanged();
}
@ -1245,7 +1286,7 @@ void TasksModel::setLaunchInPlace(bool launchInPlace)
if (d->launchInPlace != launchInPlace) {
d->launchInPlace = launchInPlace;
d->forceResort();
invalidate();
Q_EMIT launchInPlaceChanged();
}
@ -1365,7 +1406,7 @@ bool TasksModel::requestAddLauncher(const QUrl &url)
// their launcher position now.
if (added && d->sortMode == SortManual && (d->launchInPlace || !d->separateLaunchers)) {
d->updateManualSortMap();
d->forceResort();
invalidate();
}
return added;
@ -1381,7 +1422,7 @@ bool TasksModel::requestRemoveLauncher(const QUrl &url)
// longer backed by a launcher out of the launcher area.
if (removed && d->sortMode == SortManual && (d->launchInPlace || !d->separateLaunchers)) {
d->updateManualSortMap();
d->forceResort();
invalidate();
}
return removed;
@ -1401,7 +1442,7 @@ bool TasksModel::requestAddLauncherToActivity(const QUrl &url, const QString &ac
// their launcher position now.
if (added && d->sortMode == SortManual && (d->launchInPlace || !d->separateLaunchers)) {
d->updateManualSortMap();
d->forceResort();
invalidate();
}
return added;
@ -1417,7 +1458,7 @@ bool TasksModel::requestRemoveLauncherFromActivity(const QUrl &url, const QStrin
// longer backed by a launcher out of the launcher area.
if (removed && d->sortMode == SortManual && (d->launchInPlace || !d->separateLaunchers)) {
d->updateManualSortMap();
d->forceResort();
invalidate();
}
return removed;
@ -1549,6 +1590,21 @@ void TasksModel::requestActivities(const QModelIndex &index, const QStringList &
}
}
void TasksModel::requestLastActivatedReorderDelay(int delay)
{
if (d->sortMode == SortMode::SortLastActivated) {
if (delay > 0) {
if (d->reorderTimer->interval() != delay) {
d->reorderTimer->setInterval(delay);
}
d->switchingFromActiveTask = true;
} else {
d->switchingFromActiveTask = false;
}
}
}
void TasksModel::requestPublishDelegateGeometry(const QModelIndex &index, const QRect &geometry, QObject *delegate)
{
if (index.isValid() && index.model() == this) {
@ -1672,7 +1728,7 @@ bool TasksModel::move(int row, int newPos, const QModelIndex &parent)
}
// Resort.
d->forceResort();
invalidate();
if (!d->separateLaunchers && isLauncherMove) {
const QModelIndex &idx = d->concatProxyModel->index(d->sortedPreFilterRows.at(newPos), 0);

@ -81,6 +81,7 @@ public:
SortAlpha, /**< Tasks are sorted alphabetically, by AbstractTasksModel::AppName and Qt::DisplayRole. */
SortVirtualDesktop, /**< Tasks are sorted by the virtual desktop they are on. */
SortActivity, /**< Tasks are sorted by the number of tasks on the activities they're on. */
SortLastActivated, /**< Tasks are sorted by the last time they were active. */
};
Q_ENUM(SortMode)
@ -770,6 +771,15 @@ public:
**/
Q_INVOKABLE void requestActivities(const QModelIndex &index, const QStringList &activities) override;
/**
* Request setting or disabling a delay before the reorder phase.
*
* If the current sort mode is not SortLastActivated this function does nothing.
*
* @param delay delay interval in ms, delay disabled if 0
**/
Q_INVOKABLE void requestLastActivatedReorderDelay(int delay);
/**
* Request informing the window manager of new geometry for a visual
* delegate for the task at the given index. The geometry should be in

Loading…
Cancel
Save