From 432ec7417499c6fa6b0c2935c96ad5f3d1d097c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Mon, 11 Apr 2016 01:30:50 +0200 Subject: [PATCH] GH-1404 allow deleting groups and creating instances in groups directly using context menu --- application/MainWindow.cpp | 57 ++++++++++++++++++++++- application/MainWindow.h | 2 + application/dialogs/NewInstanceDialog.cpp | 7 ++- application/dialogs/NewInstanceDialog.h | 2 +- application/groupview/GroupView.cpp | 26 +++++++++-- application/groupview/GroupView.h | 6 +-- logic/InstanceList.cpp | 35 ++++++++++++++ logic/InstanceList.h | 18 +++---- 8 files changed, 131 insertions(+), 22 deletions(-) diff --git a/application/MainWindow.cpp b/application/MainWindow.cpp index ef758fae..f059b275 100644 --- a/application/MainWindow.cpp +++ b/application/MainWindow.cpp @@ -638,17 +638,34 @@ void MainWindow::showInstanceContextMenu(const QPoint &pos) } else { + auto group = view->groupNameAt(pos); + QAction *actionVoid = new QAction("MultiMC", this); actionVoid->setEnabled(false); QAction *actionCreateInstance = new QAction(tr("Create instance"), this); actionCreateInstance->setToolTip(ui->actionAddInstance->toolTip()); + if(!group.isNull()) + { + QVariantMap data; + data["group"] = group; + actionCreateInstance->setData(data); + } connect(actionCreateInstance, SIGNAL(triggered(bool)), SLOT(on_actionAddInstance_triggered())); actions.prepend(actionSep); actions.prepend(actionVoid); actions.append(actionCreateInstance); + if(!group.isNull()) + { + QAction *actionDeleteGroup = new QAction(tr("Delete group '%1'").arg(group), this); + QVariantMap data; + data["group"] = group; + actionDeleteGroup->setData(data); + connect(actionDeleteGroup, SIGNAL(triggered(bool)), SLOT(on_actionDeleteGroup_triggered())); + actions.append(actionDeleteGroup); + } } QMenu myMenu; myMenu.addActions(actions); @@ -1181,9 +1198,29 @@ void MainWindow::finalizeInstance(InstancePtr inst) void MainWindow::on_actionAddInstance_triggered() { + QString groupName; + do + { + QObject* obj = sender(); + if(!obj) + break; + QAction *action = qobject_cast(obj); + if(!action) + break; + auto map = action->data().toMap(); + if(!map.contains("group")) + break; + groupName = map["group"].toString(); + } while(0); + waitForMinecraftVersions(); - NewInstanceDialog newInstDlg(this); + if(groupName.isEmpty()) + { + groupName = MMC->settings()->get("LastUsedGroupForNewInstance").toString(); + } + + NewInstanceDialog newInstDlg(groupName, this); if (!newInstDlg.exec()) return; @@ -1320,6 +1357,24 @@ void MainWindow::on_actionChangeInstGroup_triggered() m_selectedInstance->setGroupPost(name); } +void MainWindow::on_actionDeleteGroup_triggered() +{ + QObject* obj = sender(); + if(!obj) + return; + QAction *action = qobject_cast(obj); + if(!action) + return; + auto map = action->data().toMap(); + if(!map.contains("group")) + return; + QString groupName = map["group"].toString(); + if(!groupName.isEmpty()) + { + MMC->instances()->deleteGroup(groupName); + } +} + void MainWindow::on_actionViewInstanceFolder_triggered() { QString str = MMC->settings()->get("InstanceDir").toString(); diff --git a/application/MainWindow.h b/application/MainWindow.h index 363d163e..e3fb0467 100644 --- a/application/MainWindow.h +++ b/application/MainWindow.h @@ -105,6 +105,8 @@ private slots: void on_actionDeleteInstance_triggered(); + void on_actionDeleteGroup_triggered(); + void on_actionExportInstance_triggered(); void on_actionRenameInstance_triggered(); diff --git a/application/dialogs/NewInstanceDialog.cpp b/application/dialogs/NewInstanceDialog.cpp index 0d54172d..a883d1dc 100644 --- a/application/dialogs/NewInstanceDialog.cpp +++ b/application/dialogs/NewInstanceDialog.cpp @@ -55,7 +55,7 @@ public: } }; -NewInstanceDialog::NewInstanceDialog(QWidget *parent) +NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, QWidget *parent) : QDialog(parent), ui(new Ui::NewInstanceDialog) { ui->setupUi(this); @@ -79,11 +79,10 @@ NewInstanceDialog::NewInstanceDialog(QWidget *parent) auto groupList = QStringList(groups.toList()); groupList.sort(Qt::CaseInsensitive); groupList.removeOne(""); - QString oldValue = MMC->settings()->get("LastUsedGroupForNewInstance").toString(); - groupList.push_front(oldValue); + groupList.push_front(initialGroup); groupList.push_front(""); ui->groupBox->addItems(groupList); - int index = groupList.indexOf(oldValue); + int index = groupList.indexOf(initialGroup); if(index == -1) { index = 0; diff --git a/application/dialogs/NewInstanceDialog.h b/application/dialogs/NewInstanceDialog.h index 1a2be10c..578b2c45 100644 --- a/application/dialogs/NewInstanceDialog.h +++ b/application/dialogs/NewInstanceDialog.h @@ -29,7 +29,7 @@ class NewInstanceDialog : public QDialog Q_OBJECT public: - explicit NewInstanceDialog(QWidget *parent = 0); + explicit NewInstanceDialog(const QString & initialGroup, QWidget *parent = 0); ~NewInstanceDialog(); void updateDialogState(); diff --git a/application/groupview/GroupView.cpp b/application/groupview/GroupView.cpp index ab9e71cf..aa85bec7 100644 --- a/application/groupview/GroupView.cpp +++ b/application/groupview/GroupView.cpp @@ -188,18 +188,31 @@ VisualGroup *GroupView::category(const QString &cat) const return nullptr; } -VisualGroup *GroupView::categoryAt(const QPoint &pos) const +VisualGroup *GroupView::categoryAt(const QPoint &pos, VisualGroup::HitResults & result) const { for (auto group : m_groups) { - if(group->hitScan(pos) & VisualGroup::CheckboxHit) + result = group->hitScan(pos); + if(result != VisualGroup::NoHit) { return group; } } + result = VisualGroup::NoHit; return nullptr; } +QString GroupView::groupNameAt(const QPoint &point) +{ + VisualGroup::HitResults hitresult; + auto group = categoryAt(point + offset(), hitresult); + if(group && (hitresult & (VisualGroup::HeaderHit | VisualGroup::BodyHit))) + { + return group->text; + } + return QString(); +} + int GroupView::calculateItemsPerRow() const { return qFloor((qreal)(contentWidth()) / (qreal)(itemWidth() + m_spacing)); @@ -228,8 +241,9 @@ void GroupView::mousePressEvent(QMouseEvent *event) m_pressedAlreadySelected = selectionModel()->isSelected(m_pressedIndex); m_pressedPosition = geometryPos; - m_pressedCategory = categoryAt(geometryPos); - if (m_pressedCategory) + VisualGroup::HitResults hitresult; + m_pressedCategory = categoryAt(geometryPos, hitresult); + if (m_pressedCategory && hitresult & VisualGroup::CheckboxHit) { setState(m_pressedCategory->collapsed ? ExpandingState : CollapsingState); event->accept(); @@ -325,8 +339,10 @@ void GroupView::mouseReleaseEvent(QMouseEvent *event) QPoint geometryPos = event->pos() + offset(); QPersistentModelIndex index = indexAt(visualPos); + VisualGroup::HitResults hitresult; + bool click = (index == m_pressedIndex && index.isValid()) || - (m_pressedCategory && m_pressedCategory == categoryAt(geometryPos)); + (m_pressedCategory && m_pressedCategory == categoryAt(geometryPos, hitresult)); if (click && m_pressedCategory) { diff --git a/application/groupview/GroupView.h b/application/groupview/GroupView.h index b97d3a3c..a3863b6d 100644 --- a/application/groupview/GroupView.h +++ b/application/groupview/GroupView.h @@ -4,6 +4,7 @@ #include #include #include +#include "VisualGroup.h" struct GroupViewRoles { @@ -15,8 +16,6 @@ struct GroupViewRoles }; }; -struct VisualGroup; - class GroupView : public QAbstractItemView { Q_OBJECT @@ -33,6 +32,7 @@ public: virtual QRect visualRect(const QModelIndex &index) const override; /// 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; @@ -102,7 +102,7 @@ private: VisualGroup *category(const QModelIndex &index) const; VisualGroup *category(const QString &cat) const; - VisualGroup *categoryAt(const QPoint &pos) const; + VisualGroup *categoryAt(const QPoint &pos, VisualGroup::HitResults & result) const; int itemsPerRow() const { diff --git a/logic/InstanceList.cpp b/logic/InstanceList.cpp index 8197fe24..741b8611 100644 --- a/logic/InstanceList.cpp +++ b/logic/InstanceList.cpp @@ -133,8 +133,43 @@ QStringList InstanceList::getGroups() return m_groups.toList(); } +void InstanceList::suspendGroupSaving() +{ + suspendedGroupSave = true; +} + +void InstanceList::resumeGroupSaving() +{ + if(suspendedGroupSave) + { + suspendedGroupSave = false; + if(queuedGroupSave) + { + saveGroupList(); + } + } +} + +void InstanceList::deleteGroup(const QString& name) +{ + for(auto & instance: m_instances) + { + auto instGroupName = instance->group(); + if(instGroupName == name) + { + instance->setGroupPost(QString()); + } + } +} + void InstanceList::saveGroupList() { + if(suspendedGroupSave) + { + queuedGroupSave = true; + return; + } + QString groupFileName = m_instDir + "/instgroups.json"; QMap> groupMap; for (auto instance : m_instances) diff --git a/logic/InstanceList.h b/logic/InstanceList.h index 3dbfaf70..074cca7c 100644 --- a/logic/InstanceList.h +++ b/logic/InstanceList.h @@ -31,9 +31,10 @@ class MULTIMC_LOGIC_EXPORT InstanceList : public QAbstractListModel Q_OBJECT private: void loadGroupList(QMap &groupList); + void suspendGroupSaving(); + void resumeGroupSaving(); -public -slots: +public slots: void saveGroupList(); public: @@ -116,6 +117,8 @@ public: // FIXME: instead of iterating through all instances and forming a set, keep the set around QStringList getGroups(); + void deleteGroup(const QString & name); + /*! * \brief Creates a stub instance * @@ -155,8 +158,7 @@ public: signals: void dataIsInvalid(); -public -slots: +public slots: void on_InstFolderChanged(const Setting &setting, QVariant value); /*! @@ -164,8 +166,7 @@ slots: */ InstListError loadList(); -private -slots: +private slots: void propertiesChanged(BaseInstance *inst); void instanceNuked(BaseInstance *inst); void groupChanged(); @@ -174,12 +175,13 @@ private: int getInstIndex(BaseInstance *inst) const; public: - static bool continueProcessInstance(InstancePtr instPtr, const int error, const QDir &dir, - QMap &groupMap); + static bool continueProcessInstance(InstancePtr instPtr, const int error, const QDir &dir, QMap &groupMap); protected: QString m_instDir; QList m_instances; QSet m_groups; SettingsObjectPtr m_globalSettings; + bool suspendedGroupSave = false; + bool queuedGroupSave = false; };