summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2019-08-20 02:58:27 +0200
committerPetr Mrázek <peterix@gmail.com>2019-08-20 02:58:27 +0200
commit1747f413b9d9a515d8ba6f583bba5985bad5636d (patch)
tree3b964f253d0f476fe89c1ff35e6f093cedf270b5
parent6d975748c0dd9ac89815fe5043c0d89b8e684bc7 (diff)
downloadMultiMC-1747f413b9d9a515d8ba6f583bba5985bad5636d.tar
MultiMC-1747f413b9d9a515d8ba6f583bba5985bad5636d.tar.gz
MultiMC-1747f413b9d9a515d8ba6f583bba5985bad5636d.tar.lz
MultiMC-1747f413b9d9a515d8ba6f583bba5985bad5636d.tar.xz
MultiMC-1747f413b9d9a515d8ba6f583bba5985bad5636d.zip
GH-851 save, load and use group expansion status
-rw-r--r--api/logic/InstanceList.cpp66
-rw-r--r--api/logic/InstanceList.h9
-rw-r--r--application/MainWindow.cpp4
-rw-r--r--application/groupview/GroupView.cpp10
-rw-r--r--application/groupview/GroupView.h12
5 files changed, 69 insertions, 32 deletions
diff --git a/api/logic/InstanceList.cpp b/api/logic/InstanceList.cpp
index 58e2ee0c..a6dd734b 100644
--- a/api/logic/InstanceList.cpp
+++ b/api/logic/InstanceList.cpp
@@ -160,8 +160,8 @@ GroupId InstanceList::getInstanceGroup(const InstanceId& id) const
{
return GroupId();
}
- auto iter = m_groupMap.find(inst->id());
- if(iter != m_groupMap.end())
+ auto iter = m_instanceGroupIndex.find(inst->id());
+ if(iter != m_instanceGroupIndex.end())
{
return *iter;
}
@@ -178,8 +178,8 @@ void InstanceList::setInstanceGroup(const InstanceId& id, const GroupId& name)
}
bool changed = false;
- auto iter = m_groupMap.find(inst->id());
- if(iter != m_groupMap.end())
+ auto iter = m_instanceGroupIndex.find(inst->id());
+ if(iter != m_instanceGroupIndex.end())
{
if(*iter != name)
{
@@ -190,12 +190,12 @@ void InstanceList::setInstanceGroup(const InstanceId& id, const GroupId& name)
else
{
changed = true;
- m_groupMap[id] = name;
+ m_instanceGroupIndex[id] = name;
}
if(changed)
{
- m_groups.insert(name);
+ m_groupNameCache.insert(name);
auto idx = getInstIndex(inst.get());
emit dataChanged(index(idx), index(idx), {GroupRole});
saveGroupList();
@@ -204,7 +204,7 @@ void InstanceList::setInstanceGroup(const InstanceId& id, const GroupId& name)
QStringList InstanceList::getGroups()
{
- return m_groups.toList();
+ return m_groupNameCache.toList();
}
void InstanceList::deleteGroup(const QString& name)
@@ -217,7 +217,7 @@ void InstanceList::deleteGroup(const QString& name)
auto instGroupName = getInstanceGroup(instID);
if(instGroupName == name)
{
- m_groupMap.remove(instID);
+ m_instanceGroupIndex.remove(instID);
qDebug() << "Remove" << instID << "from group" << name;
removed = true;
auto idx = getInstIndex(instance.get());
@@ -233,6 +233,11 @@ void InstanceList::deleteGroup(const QString& name)
}
}
+bool InstanceList::isGroupCollapsed(const QString& group)
+{
+ return m_collapsedGroups.contains(group);
+}
+
void InstanceList::deleteInstance(const InstanceId& id)
{
auto inst = getInstanceById(id);
@@ -242,7 +247,7 @@ void InstanceList::deleteInstance(const InstanceId& id)
return;
}
- if(m_groupMap.remove(id))
+ if(m_instanceGroupIndex.remove(id))
{
saveGroupList();
}
@@ -515,7 +520,7 @@ void InstanceList::saveGroupList()
WatchLock foo(m_watcher, m_instDir);
QString groupFileName = m_instDir + "/instgroups.json";
QMap<QString, QSet<QString>> reverseGroupMap;
- for (auto iter = m_groupMap.begin(); iter != m_groupMap.end(); iter++)
+ for (auto iter = m_instanceGroupIndex.begin(); iter != m_instanceGroupIndex.end(); iter++)
{
QString id = iter.key();
QString group = iter.value();
@@ -548,7 +553,7 @@ void InstanceList::saveGroupList()
auto name = iter.key();
QJsonObject groupObj;
QJsonArray instanceArr;
- groupObj.insert("hidden", QJsonValue(QString("false")));
+ groupObj.insert("hidden", QJsonValue(m_collapsedGroups.contains(name)));
for (auto item : list)
{
instanceArr.append(QJsonValue(item));
@@ -572,7 +577,6 @@ void InstanceList::saveGroupList()
void InstanceList::loadGroupList()
{
qDebug() << "Will load group list now.";
- QSet<QString> groupSet;
QString groupFileName = m_instDir + "/instgroups.json";
@@ -623,7 +627,8 @@ void InstanceList::loadGroupList()
return;
}
- m_groupMap.clear();
+ QSet<QString> groupSet;
+ m_instanceGroupIndex.clear();
// Iterate through all the groups.
QJsonObject groupMapping = rootObj.value("groups").toObject();
@@ -634,37 +639,35 @@ void InstanceList::loadGroupList()
// If not an object, complain and skip to the next one.
if (!iter.value().isObject())
{
- qWarning() << QString("Group '%1' in the group list should "
- "be an object.")
- .arg(groupName)
- .toUtf8();
+ qWarning() << QString("Group '%1' in the group list should be an object.").arg(groupName).toUtf8();
continue;
}
QJsonObject groupObj = iter.value().toObject();
if (!groupObj.value("instances").isArray())
{
- qWarning() << QString("Group '%1' in the group list is invalid. "
- "It should contain an array "
- "called 'instances'.")
- .arg(groupName)
- .toUtf8();
+ qWarning() << QString("Group '%1' in the group list is invalid. It should contain an array called 'instances'.").arg(groupName).toUtf8();
continue;
}
// keep a list/set of groups for choosing
groupSet.insert(groupName);
+ auto hidden = groupObj.value("hidden").toBool(false);
+ if(hidden) {
+ m_collapsedGroups.insert(groupName);
+ }
+
// Iterate through the list of instances in the group.
QJsonArray instancesArray = groupObj.value("instances").toArray();
for (QJsonArray::iterator iter2 = instancesArray.begin(); iter2 != instancesArray.end(); iter2++)
{
- m_groupMap[(*iter2).toString()] = groupName;
+ m_instanceGroupIndex[(*iter2).toString()] = groupName;
}
}
m_groupsLoaded = true;
- m_groups.unite(groupSet);
+ m_groupNameCache.unite(groupSet);
qDebug() << "Group list loaded.";
}
@@ -689,6 +692,17 @@ void InstanceList::on_InstFolderChanged(const Setting &setting, QVariant value)
}
}
+void InstanceList::on_GroupStateChanged(const QString& group, bool collapsed)
+{
+ qDebug() << "Group" << group << (collapsed ? "collapsed" : "expanded");
+ if(collapsed) {
+ m_collapsedGroups.insert(group);
+ } else {
+ m_collapsedGroups.remove(group);
+ }
+ saveGroupList();
+}
+
class InstanceStaging : public Task
{
Q_OBJECT
@@ -819,9 +833,9 @@ bool InstanceList::commitStagedInstance(const QString& path, const QString& inst
qWarning() << "Failed to move" << path << "to" << destination;
return false;
}
- m_groupMap[instID] = groupName;
+ m_instanceGroupIndex[instID] = groupName;
instanceSet.insert(instID);
- m_groups.insert(groupName);
+ m_groupNameCache.insert(groupName);
emit instancesChanged();
emit instanceSelectRequest(instID);
}
diff --git a/api/logic/InstanceList.h b/api/logic/InstanceList.h
index e0abd890..005a24cd 100644
--- a/api/logic/InstanceList.h
+++ b/api/logic/InstanceList.h
@@ -99,6 +99,8 @@ public:
InstancePtr getInstanceById(QString id) const;
QModelIndex getInstanceIndexById(const QString &id) const;
QStringList getGroups();
+ bool isGroupCollapsed(const QString &groupName);
+
GroupId getInstanceGroup(const InstanceId & id) const;
void setInstanceGroup(const InstanceId & id, const GroupId& name);
@@ -134,6 +136,7 @@ signals:
public slots:
void on_InstFolderChanged(const Setting &setting, QVariant value);
+ void on_GroupStateChanged(const QString &group, bool collapsed);
private slots:
void propertiesChanged(BaseInstance *inst);
@@ -154,12 +157,14 @@ private:
int m_watchLevel = 0;
bool m_dirty = false;
QList<InstancePtr> m_instances;
- QSet<QString> m_groups;
+ QSet<QString> m_groupNameCache;
SettingsObjectPtr m_globalSettings;
QString m_instDir;
QFileSystemWatcher * m_watcher;
- QMap<InstanceId, GroupId> m_groupMap;
+ // FIXME: this is so inefficient that looking at it is almost painful.
+ QSet<QString> m_collapsedGroups;
+ QMap<InstanceId, GroupId> m_instanceGroupIndex;
QSet<InstanceId> instanceSet;
bool m_groupsLoaded = false;
bool m_instancesProbed = false;
diff --git a/application/MainWindow.cpp b/application/MainWindow.cpp
index 1db09c6c..8457cd41 100644
--- a/application/MainWindow.cpp
+++ b/application/MainWindow.cpp
@@ -682,6 +682,10 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow
connect(proxymodel, &InstanceProxyModel::dataChanged, this, &MainWindow::instanceDataChanged);
view->setModel(proxymodel);
+ view->setSourceOfGroupCollapseStatus([](const QString & groupName)->bool {
+ return MMC->instances()->isGroupCollapsed(groupName);
+ });
+ connect(view, &GroupView::groupStateChanged, MMC->instances().get(), &InstanceList::on_GroupStateChanged);
ui->horizontalLayout->addWidget(view);
}
// The cat background
diff --git a/application/groupview/GroupView.cpp b/application/groupview/GroupView.cpp
index bc7ef6c0..ff0daee4 100644
--- a/application/groupview/GroupView.cpp
+++ b/application/groupview/GroupView.cpp
@@ -175,6 +175,9 @@ void GroupView::updateGeometries()
else
{
auto cat = new VisualGroup(groupName, this);
+ if(fVisibility) {
+ cat->collapsed = fVisibility(groupName);
+ }
cats.insert(groupName, cat);
cat->update();
}
@@ -384,6 +387,8 @@ void GroupView::mouseReleaseEvent(QMouseEvent *event)
if (state() == ExpandingState)
{
m_pressedCategory->collapsed = false;
+ emit groupStateChanged(m_pressedCategory->text, false);
+
updateGeometries();
viewport()->update();
event->accept();
@@ -392,6 +397,8 @@ void GroupView::mouseReleaseEvent(QMouseEvent *event)
else if (state() == CollapsingState)
{
m_pressedCategory->collapsed = true;
+ emit groupStateChanged(m_pressedCategory->text, true);
+
updateGeometries();
viewport()->update();
event->accept();
@@ -607,8 +614,7 @@ void GroupView::dropEvent(QDropEvent *event)
const QString categoryText = category->text;
if (model()->dropMimeData(event->mimeData(), Qt::MoveAction, row, 0, QModelIndex()))
{
- model()->setData(model()->index(row, 0), categoryText,
- GroupViewRoles::GroupRole);
+ model()->setData(model()->index(row, 0), categoryText, GroupViewRoles::GroupRole);
event->setDropAction(Qt::MoveAction);
event->accept();
}
diff --git a/application/groupview/GroupView.h b/application/groupview/GroupView.h
index db29a0d4..13bfd234 100644
--- a/application/groupview/GroupView.h
+++ b/application/groupview/GroupView.h
@@ -20,6 +20,7 @@
#include <QScrollBar>
#include <QCache>
#include "VisualGroup.h"
+#include <functional>
struct GroupViewRoles
{
@@ -41,6 +42,11 @@ public:
void setModel(QAbstractItemModel *model) override;
+ using visibilityFunction = std::function<bool(const QString &)>;
+ void setSourceOfGroupCollapseStatus(visibilityFunction f) {
+ fVisibility = f;
+ }
+
/// return geometry rectangle occupied by the specified model item
QRect geometryRect(const QModelIndex &index) const;
/// return visual rectangle occupied by the specified model item
@@ -48,8 +54,7 @@ public:
/// get the model index at the specified visual point
virtual QModelIndex indexAt(const QPoint &point) const override;
QString groupNameAt(const QPoint &point);
- void setSelection(const QRect &rect,
- const QItemSelectionModel::SelectionFlags commands) override;
+ void setSelection(const QRect &rect, const QItemSelectionModel::SelectionFlags commands) override;
virtual int horizontalOffset() const override;
virtual int verticalOffset() const override;
@@ -80,6 +85,7 @@ protected slots:
signals:
void droppedURLs(QList<QUrl> urls);
+ void groupStateChanged(QString group, bool collapsed);
protected:
virtual bool isIndexHidden(const QModelIndex &index) const override;
@@ -103,6 +109,8 @@ private:
friend struct VisualGroup;
QList<VisualGroup *> m_groups;
+ visibilityFunction fVisibility;
+
// geometry
int m_leftMargin = 5;
int m_rightMargin = 5;