GH-1404 allow deleting groups and creating instances in groups directly using context menu

This commit is contained in:
Petr Mrázek 2016-04-11 01:30:50 +02:00
parent b795ad5209
commit 432ec74174
8 changed files with 131 additions and 22 deletions

View File

@ -638,17 +638,34 @@ void MainWindow::showInstanceContextMenu(const QPoint &pos)
} }
else else
{ {
auto group = view->groupNameAt(pos);
QAction *actionVoid = new QAction("MultiMC", this); QAction *actionVoid = new QAction("MultiMC", this);
actionVoid->setEnabled(false); actionVoid->setEnabled(false);
QAction *actionCreateInstance = new QAction(tr("Create instance"), this); QAction *actionCreateInstance = new QAction(tr("Create instance"), this);
actionCreateInstance->setToolTip(ui->actionAddInstance->toolTip()); 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())); connect(actionCreateInstance, SIGNAL(triggered(bool)), SLOT(on_actionAddInstance_triggered()));
actions.prepend(actionSep); actions.prepend(actionSep);
actions.prepend(actionVoid); actions.prepend(actionVoid);
actions.append(actionCreateInstance); 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; QMenu myMenu;
myMenu.addActions(actions); myMenu.addActions(actions);
@ -1181,9 +1198,29 @@ void MainWindow::finalizeInstance(InstancePtr inst)
void MainWindow::on_actionAddInstance_triggered() void MainWindow::on_actionAddInstance_triggered()
{ {
QString groupName;
do
{
QObject* obj = sender();
if(!obj)
break;
QAction *action = qobject_cast<QAction *>(obj);
if(!action)
break;
auto map = action->data().toMap();
if(!map.contains("group"))
break;
groupName = map["group"].toString();
} while(0);
waitForMinecraftVersions(); waitForMinecraftVersions();
NewInstanceDialog newInstDlg(this); if(groupName.isEmpty())
{
groupName = MMC->settings()->get("LastUsedGroupForNewInstance").toString();
}
NewInstanceDialog newInstDlg(groupName, this);
if (!newInstDlg.exec()) if (!newInstDlg.exec())
return; return;
@ -1320,6 +1357,24 @@ void MainWindow::on_actionChangeInstGroup_triggered()
m_selectedInstance->setGroupPost(name); m_selectedInstance->setGroupPost(name);
} }
void MainWindow::on_actionDeleteGroup_triggered()
{
QObject* obj = sender();
if(!obj)
return;
QAction *action = qobject_cast<QAction *>(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() void MainWindow::on_actionViewInstanceFolder_triggered()
{ {
QString str = MMC->settings()->get("InstanceDir").toString(); QString str = MMC->settings()->get("InstanceDir").toString();

View File

@ -105,6 +105,8 @@ private slots:
void on_actionDeleteInstance_triggered(); void on_actionDeleteInstance_triggered();
void on_actionDeleteGroup_triggered();
void on_actionExportInstance_triggered(); void on_actionExportInstance_triggered();
void on_actionRenameInstance_triggered(); void on_actionRenameInstance_triggered();

View File

@ -55,7 +55,7 @@ public:
} }
}; };
NewInstanceDialog::NewInstanceDialog(QWidget *parent) NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, QWidget *parent)
: QDialog(parent), ui(new Ui::NewInstanceDialog) : QDialog(parent), ui(new Ui::NewInstanceDialog)
{ {
ui->setupUi(this); ui->setupUi(this);
@ -79,11 +79,10 @@ NewInstanceDialog::NewInstanceDialog(QWidget *parent)
auto groupList = QStringList(groups.toList()); auto groupList = QStringList(groups.toList());
groupList.sort(Qt::CaseInsensitive); groupList.sort(Qt::CaseInsensitive);
groupList.removeOne(""); groupList.removeOne("");
QString oldValue = MMC->settings()->get("LastUsedGroupForNewInstance").toString(); groupList.push_front(initialGroup);
groupList.push_front(oldValue);
groupList.push_front(""); groupList.push_front("");
ui->groupBox->addItems(groupList); ui->groupBox->addItems(groupList);
int index = groupList.indexOf(oldValue); int index = groupList.indexOf(initialGroup);
if(index == -1) if(index == -1)
{ {
index = 0; index = 0;

View File

@ -29,7 +29,7 @@ class NewInstanceDialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit NewInstanceDialog(QWidget *parent = 0); explicit NewInstanceDialog(const QString & initialGroup, QWidget *parent = 0);
~NewInstanceDialog(); ~NewInstanceDialog();
void updateDialogState(); void updateDialogState();

View File

@ -188,18 +188,31 @@ VisualGroup *GroupView::category(const QString &cat) const
return nullptr; return nullptr;
} }
VisualGroup *GroupView::categoryAt(const QPoint &pos) const VisualGroup *GroupView::categoryAt(const QPoint &pos, VisualGroup::HitResults & result) const
{ {
for (auto group : m_groups) for (auto group : m_groups)
{ {
if(group->hitScan(pos) & VisualGroup::CheckboxHit) result = group->hitScan(pos);
if(result != VisualGroup::NoHit)
{ {
return group; return group;
} }
} }
result = VisualGroup::NoHit;
return nullptr; 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 int GroupView::calculateItemsPerRow() const
{ {
return qFloor((qreal)(contentWidth()) / (qreal)(itemWidth() + m_spacing)); return qFloor((qreal)(contentWidth()) / (qreal)(itemWidth() + m_spacing));
@ -228,8 +241,9 @@ void GroupView::mousePressEvent(QMouseEvent *event)
m_pressedAlreadySelected = selectionModel()->isSelected(m_pressedIndex); m_pressedAlreadySelected = selectionModel()->isSelected(m_pressedIndex);
m_pressedPosition = geometryPos; m_pressedPosition = geometryPos;
m_pressedCategory = categoryAt(geometryPos); VisualGroup::HitResults hitresult;
if (m_pressedCategory) m_pressedCategory = categoryAt(geometryPos, hitresult);
if (m_pressedCategory && hitresult & VisualGroup::CheckboxHit)
{ {
setState(m_pressedCategory->collapsed ? ExpandingState : CollapsingState); setState(m_pressedCategory->collapsed ? ExpandingState : CollapsingState);
event->accept(); event->accept();
@ -325,8 +339,10 @@ void GroupView::mouseReleaseEvent(QMouseEvent *event)
QPoint geometryPos = event->pos() + offset(); QPoint geometryPos = event->pos() + offset();
QPersistentModelIndex index = indexAt(visualPos); QPersistentModelIndex index = indexAt(visualPos);
VisualGroup::HitResults hitresult;
bool click = (index == m_pressedIndex && index.isValid()) || bool click = (index == m_pressedIndex && index.isValid()) ||
(m_pressedCategory && m_pressedCategory == categoryAt(geometryPos)); (m_pressedCategory && m_pressedCategory == categoryAt(geometryPos, hitresult));
if (click && m_pressedCategory) if (click && m_pressedCategory)
{ {

View File

@ -4,6 +4,7 @@
#include <QLineEdit> #include <QLineEdit>
#include <QScrollBar> #include <QScrollBar>
#include <QCache> #include <QCache>
#include "VisualGroup.h"
struct GroupViewRoles struct GroupViewRoles
{ {
@ -15,8 +16,6 @@ struct GroupViewRoles
}; };
}; };
struct VisualGroup;
class GroupView : public QAbstractItemView class GroupView : public QAbstractItemView
{ {
Q_OBJECT Q_OBJECT
@ -33,6 +32,7 @@ public:
virtual QRect visualRect(const QModelIndex &index) const override; virtual QRect visualRect(const QModelIndex &index) const override;
/// get the model index at the specified visual point /// get the model index at the specified visual point
virtual QModelIndex indexAt(const QPoint &point) const override; virtual QModelIndex indexAt(const QPoint &point) const override;
QString groupNameAt(const QPoint &point);
void setSelection(const QRect &rect, void setSelection(const QRect &rect,
const QItemSelectionModel::SelectionFlags commands) override; const QItemSelectionModel::SelectionFlags commands) override;
@ -102,7 +102,7 @@ private:
VisualGroup *category(const QModelIndex &index) const; VisualGroup *category(const QModelIndex &index) const;
VisualGroup *category(const QString &cat) 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 int itemsPerRow() const
{ {

View File

@ -133,8 +133,43 @@ QStringList InstanceList::getGroups()
return m_groups.toList(); 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() void InstanceList::saveGroupList()
{ {
if(suspendedGroupSave)
{
queuedGroupSave = true;
return;
}
QString groupFileName = m_instDir + "/instgroups.json"; QString groupFileName = m_instDir + "/instgroups.json";
QMap<QString, QSet<QString>> groupMap; QMap<QString, QSet<QString>> groupMap;
for (auto instance : m_instances) for (auto instance : m_instances)

View File

@ -31,9 +31,10 @@ class MULTIMC_LOGIC_EXPORT InstanceList : public QAbstractListModel
Q_OBJECT Q_OBJECT
private: private:
void loadGroupList(QMap<QString, QString> &groupList); void loadGroupList(QMap<QString, QString> &groupList);
void suspendGroupSaving();
void resumeGroupSaving();
public public slots:
slots:
void saveGroupList(); void saveGroupList();
public: public:
@ -116,6 +117,8 @@ public:
// FIXME: instead of iterating through all instances and forming a set, keep the set around // FIXME: instead of iterating through all instances and forming a set, keep the set around
QStringList getGroups(); QStringList getGroups();
void deleteGroup(const QString & name);
/*! /*!
* \brief Creates a stub instance * \brief Creates a stub instance
* *
@ -155,8 +158,7 @@ public:
signals: signals:
void dataIsInvalid(); void dataIsInvalid();
public public slots:
slots:
void on_InstFolderChanged(const Setting &setting, QVariant value); void on_InstFolderChanged(const Setting &setting, QVariant value);
/*! /*!
@ -164,8 +166,7 @@ slots:
*/ */
InstListError loadList(); InstListError loadList();
private private slots:
slots:
void propertiesChanged(BaseInstance *inst); void propertiesChanged(BaseInstance *inst);
void instanceNuked(BaseInstance *inst); void instanceNuked(BaseInstance *inst);
void groupChanged(); void groupChanged();
@ -174,12 +175,13 @@ private:
int getInstIndex(BaseInstance *inst) const; int getInstIndex(BaseInstance *inst) const;
public: public:
static bool continueProcessInstance(InstancePtr instPtr, const int error, const QDir &dir, static bool continueProcessInstance(InstancePtr instPtr, const int error, const QDir &dir, QMap<QString, QString> &groupMap);
QMap<QString, QString> &groupMap);
protected: protected:
QString m_instDir; QString m_instDir;
QList<InstancePtr> m_instances; QList<InstancePtr> m_instances;
QSet<QString> m_groups; QSet<QString> m_groups;
SettingsObjectPtr m_globalSettings; SettingsObjectPtr m_globalSettings;
bool suspendedGroupSave = false;
bool queuedGroupSave = false;
}; };