2021-06-10 00:52:28 +03:00
|
|
|
// SPDX-FileCopyrightText: 2021 Nheko Contributors
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <QAbstractListModel>
|
|
|
|
#include <QHash>
|
2021-12-01 02:02:41 +03:00
|
|
|
#include <QSortFilterProxyModel>
|
2021-06-10 00:52:28 +03:00
|
|
|
#include <QString>
|
|
|
|
#include <QStringList>
|
|
|
|
|
|
|
|
#include <mtx/responses/sync.hpp>
|
|
|
|
|
2021-06-16 01:09:45 +03:00
|
|
|
#include "CacheStructs.h"
|
|
|
|
|
2021-12-01 02:02:41 +03:00
|
|
|
class CommunitiesModel;
|
|
|
|
|
|
|
|
class FilteredCommunitiesModel : public QSortFilterProxyModel
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
|
|
|
FilteredCommunitiesModel(CommunitiesModel *model, QObject *parent = nullptr);
|
|
|
|
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
|
|
|
bool filterAcceptsRow(int sourceRow, const QModelIndex &) const override;
|
|
|
|
};
|
|
|
|
|
2021-06-10 00:52:28 +03:00
|
|
|
class CommunitiesModel : public QAbstractListModel
|
|
|
|
{
|
2021-09-18 01:22:33 +03:00
|
|
|
Q_OBJECT
|
|
|
|
Q_PROPERTY(QString currentTagId READ currentTagId WRITE setCurrentTagId NOTIFY
|
|
|
|
currentTagIdChanged RESET resetCurrentTagId)
|
|
|
|
Q_PROPERTY(QStringList tags READ tags NOTIFY tagsChanged)
|
|
|
|
Q_PROPERTY(QStringList tagsWithDefault READ tagsWithDefault NOTIFY tagsChanged)
|
2021-12-01 02:46:02 +03:00
|
|
|
Q_PROPERTY(bool containsSubspaces READ containsSubspaces NOTIFY containsSubspacesChanged)
|
2021-06-10 00:52:28 +03:00
|
|
|
|
|
|
|
public:
|
2021-09-18 01:22:33 +03:00
|
|
|
enum Roles
|
|
|
|
{
|
|
|
|
AvatarUrl = Qt::UserRole,
|
|
|
|
DisplayName,
|
|
|
|
Tooltip,
|
2021-12-01 02:02:41 +03:00
|
|
|
Collapsed,
|
|
|
|
Collapsible,
|
2021-09-18 01:22:33 +03:00
|
|
|
Hidden,
|
2021-12-01 02:02:41 +03:00
|
|
|
Parent,
|
|
|
|
Depth,
|
2021-09-18 01:22:33 +03:00
|
|
|
Id,
|
|
|
|
};
|
2021-06-10 00:52:28 +03:00
|
|
|
|
2021-12-01 02:02:41 +03:00
|
|
|
struct FlatTree
|
|
|
|
{
|
|
|
|
struct Elem
|
|
|
|
{
|
|
|
|
QString name;
|
|
|
|
int depth = 0;
|
|
|
|
bool collapsed = false;
|
|
|
|
};
|
|
|
|
|
|
|
|
std::vector<Elem> tree;
|
|
|
|
|
|
|
|
int size() const { return static_cast<int>(tree.size()); }
|
|
|
|
int indexOf(const QString &s) const
|
|
|
|
{
|
|
|
|
for (int i = 0; i < size(); i++)
|
|
|
|
if (tree[i].name == s)
|
|
|
|
return i;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
int lastChild(int index) const
|
|
|
|
{
|
|
|
|
if (index >= size() || index < 0)
|
|
|
|
return index;
|
|
|
|
const auto depth = tree[index].depth;
|
|
|
|
int i = index + 1;
|
|
|
|
for (; i < size(); i++)
|
2021-12-01 02:24:57 +03:00
|
|
|
if (tree[i].depth <= depth)
|
2021-12-01 02:02:41 +03:00
|
|
|
break;
|
|
|
|
return i - 1;
|
|
|
|
}
|
|
|
|
int parent(int index) const
|
|
|
|
{
|
|
|
|
if (index >= size() || index < 0)
|
|
|
|
return -1;
|
|
|
|
const auto depth = tree[index].depth;
|
|
|
|
if (depth == 0)
|
|
|
|
return -1;
|
|
|
|
int i = index - 1;
|
|
|
|
for (; i >= 0; i--)
|
|
|
|
if (tree[i].depth < depth)
|
|
|
|
break;
|
|
|
|
return i;
|
|
|
|
}
|
2021-12-01 05:46:55 +03:00
|
|
|
|
|
|
|
void storeCollapsed();
|
|
|
|
void restoreCollapsed();
|
2021-12-01 02:02:41 +03:00
|
|
|
};
|
|
|
|
|
2021-09-18 01:22:33 +03:00
|
|
|
CommunitiesModel(QObject *parent = nullptr);
|
|
|
|
QHash<int, QByteArray> roleNames() const override;
|
|
|
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override
|
|
|
|
{
|
|
|
|
(void)parent;
|
2021-11-21 00:48:04 +03:00
|
|
|
return 2 + tags_.size() + spaceOrder_.size();
|
2021-09-18 01:22:33 +03:00
|
|
|
}
|
|
|
|
QVariant data(const QModelIndex &index, int role) const override;
|
2021-12-01 02:02:41 +03:00
|
|
|
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
2021-06-10 00:52:28 +03:00
|
|
|
|
2021-12-01 02:46:02 +03:00
|
|
|
bool containsSubspaces() const
|
|
|
|
{
|
|
|
|
for (const auto &e : spaceOrder_.tree)
|
|
|
|
if (e.depth > 0)
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-06-10 00:52:28 +03:00
|
|
|
public slots:
|
2021-09-18 01:22:33 +03:00
|
|
|
void initializeSidebar();
|
2021-11-21 00:48:04 +03:00
|
|
|
void sync(const mtx::responses::Sync &sync_);
|
2021-09-18 01:22:33 +03:00
|
|
|
void clear();
|
|
|
|
QString currentTagId() const { return currentTagId_; }
|
|
|
|
void setCurrentTagId(QString tagId);
|
|
|
|
void resetCurrentTagId()
|
|
|
|
{
|
|
|
|
currentTagId_.clear();
|
|
|
|
emit currentTagIdChanged(currentTagId_);
|
|
|
|
}
|
|
|
|
QStringList tags() const { return tags_; }
|
|
|
|
QStringList tagsWithDefault() const
|
|
|
|
{
|
|
|
|
QStringList tagsWD = tags_;
|
|
|
|
tagsWD.prepend("m.lowpriority");
|
|
|
|
tagsWD.prepend("m.favourite");
|
|
|
|
tagsWD.removeOne("m.server_notice");
|
|
|
|
tagsWD.removeDuplicates();
|
|
|
|
return tagsWD;
|
|
|
|
}
|
|
|
|
void toggleTagId(QString tagId);
|
2021-12-01 02:02:41 +03:00
|
|
|
FilteredCommunitiesModel *filtered() { return new FilteredCommunitiesModel(this, this); }
|
2021-06-10 00:52:28 +03:00
|
|
|
|
|
|
|
signals:
|
2021-09-18 01:22:33 +03:00
|
|
|
void currentTagIdChanged(QString tagId);
|
|
|
|
void hiddenTagsChanged();
|
|
|
|
void tagsChanged();
|
2021-12-01 02:46:02 +03:00
|
|
|
void containsSubspacesChanged();
|
2021-06-10 00:52:28 +03:00
|
|
|
|
|
|
|
private:
|
2021-09-18 01:22:33 +03:00
|
|
|
QStringList tags_;
|
|
|
|
QString currentTagId_;
|
|
|
|
QStringList hiddentTagIds_;
|
2021-12-01 02:02:41 +03:00
|
|
|
FlatTree spaceOrder_;
|
2021-09-18 01:22:33 +03:00
|
|
|
std::map<QString, RoomInfo> spaces_;
|
2021-12-01 02:02:41 +03:00
|
|
|
|
|
|
|
friend class FilteredCommunitiesModel;
|
2021-06-10 00:52:28 +03:00
|
|
|
};
|