Skip to content

Commit c291946

Browse files
committed
NOISSUE do not lose selection on mod enable/disable toggle
1 parent dfb30d9 commit c291946

File tree

7 files changed

+99
-60
lines changed

7 files changed

+99
-60
lines changed

api/logic/FileSystem.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,11 @@ bool copy::operator()(const QString &offset)
174174
bool deletePath(QString path)
175175
{
176176
bool OK = true;
177+
QFileInfo finfo(path);
178+
if(finfo.isFile()) {
179+
return QFile::remove(path);
180+
}
181+
177182
QDir dir(path);
178183

179184
if (!dir.exists())

api/logic/minecraft/mod/Mod.cpp

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "Mod.h"
2020
#include <QDebug>
21+
#include <FileSystem.h>
2122

2223
namespace {
2324

@@ -100,34 +101,15 @@ bool Mod::enable(bool value)
100101
if (!foo.rename(path))
101102
return false;
102103
}
103-
m_file = QFileInfo(path);
104+
repath(QFileInfo(path));
104105
m_enabled = value;
105106
return true;
106107
}
107108

108109
bool Mod::destroy()
109110
{
110-
if (m_type == MOD_FOLDER)
111-
{
112-
QDir d(m_file.filePath());
113-
if (d.removeRecursively())
114-
{
115-
m_type = MOD_UNKNOWN;
116-
return true;
117-
}
118-
return false;
119-
}
120-
else if (m_type == MOD_SINGLEFILE || m_type == MOD_ZIPFILE || m_type == MOD_LITEMOD)
121-
{
122-
QFile f(m_file.filePath());
123-
if (f.remove())
124-
{
125-
m_type = MOD_UNKNOWN;
126-
return true;
127-
}
128-
return false;
129-
}
130-
return true;
111+
m_type = MOD_UNKNOWN;
112+
return FS::deletePath(m_file.filePath());
131113
}
132114

133115

api/logic/minecraft/mod/ModFolderModel.cpp

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ bool ModFolderModel::installMod(const QString &filename)
303303
return false;
304304
}
305305

306-
bool ModFolderModel::enableMods(const QModelIndexList& indexes, bool enable)
306+
bool ModFolderModel::setModStatus(const QModelIndexList& indexes, ModStatusAction enable)
307307
{
308308
if(interaction_disabled) {
309309
return false;
@@ -314,27 +314,14 @@ bool ModFolderModel::enableMods(const QModelIndexList& indexes, bool enable)
314314

315315
for (auto index: indexes)
316316
{
317-
Mod &m = mods[index.row()];
318-
m.enable(enable);
319-
emit dataChanged(index, index);
317+
if(index.column() != 0) {
318+
continue;
319+
}
320+
setModStatus(index.row(), enable);
320321
}
321322
return true;
322323
}
323324

324-
void ModFolderModel::toggleEnabled(const QModelIndex& index)
325-
{
326-
if(interaction_disabled) {
327-
return;
328-
}
329-
if(!index.isValid()) {
330-
return;
331-
}
332-
333-
Mod &m = mods[index.row()];
334-
m.enable(!m.enabled());
335-
emit dataChanged(index, index);
336-
}
337-
338325
bool ModFolderModel::deleteMods(const QModelIndexList& indexes)
339326
{
340327
if(interaction_disabled) {
@@ -418,16 +405,52 @@ bool ModFolderModel::setData(const QModelIndex &index, const QVariant &value, in
418405

419406
if (role == Qt::CheckStateRole)
420407
{
421-
auto &mod = mods[index.row()];
422-
if (mod.enable(!mod.enabled()))
423-
{
424-
emit dataChanged(index, index);
425-
return true;
426-
}
408+
return setModStatus(index.row(), Toggle);
427409
}
428410
return false;
429411
}
430412

413+
bool ModFolderModel::setModStatus(int row, ModFolderModel::ModStatusAction action)
414+
{
415+
if(row < 0 || row >= mods.size()) {
416+
return false;
417+
}
418+
419+
auto &mod = mods[row];
420+
bool desiredStatus;
421+
switch(action) {
422+
case Enable:
423+
desiredStatus = true;
424+
break;
425+
case Disable:
426+
desiredStatus = false;
427+
break;
428+
case Toggle:
429+
default:
430+
desiredStatus = !mod.enabled();
431+
break;
432+
}
433+
434+
if(desiredStatus == mod.enabled()) {
435+
return true;
436+
}
437+
438+
// preserve the row, but change its ID
439+
auto oldId = mod.mmc_id();
440+
if(!mod.enable(!mod.enabled())) {
441+
return false;
442+
}
443+
auto newId = mod.mmc_id();
444+
if(modsIndex.contains(newId)) {
445+
// NOTE: this could handle a corner case, where we are overwriting a file, because the same 'mod' exists both enabled and disabled
446+
// But is it necessary?
447+
}
448+
modsIndex.remove(oldId);
449+
modsIndex[newId] = row;
450+
emit dataChanged(index(row, 0), index(row, columnCount(QModelIndex()) - 1));
451+
return true;
452+
}
453+
431454
QVariant ModFolderModel::headerData(int section, Qt::Orientation orientation, int role) const
432455
{
433456
switch (role)

api/logic/minecraft/mod/ModFolderModel.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ class MULTIMC_LOGIC_EXPORT ModFolderModel : public QAbstractListModel
4848
DateColumn,
4949
NUM_COLUMNS
5050
};
51+
enum ModStatusAction {
52+
Disable,
53+
Enable,
54+
Toggle
55+
};
5156
ModFolderModel(const QString &dir);
5257

5358
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
@@ -93,8 +98,7 @@ class MULTIMC_LOGIC_EXPORT ModFolderModel : public QAbstractListModel
9398
bool deleteMods(const QModelIndexList &indexes);
9499

95100
/// Enable or disable listed mods
96-
bool enableMods(const QModelIndexList &indexes, bool enable = true);
97-
void toggleEnabled(const QModelIndex &index);
101+
bool setModStatus(const QModelIndexList &indexes, ModStatusAction action);
98102

99103
void startWatching();
100104
void stopWatching();
@@ -125,6 +129,7 @@ private
125129

126130
private:
127131
void resolveMod(Mod& m);
132+
bool setModStatus(int index, ModStatusAction action);
128133

129134
protected:
130135
QFileSystemWatcher *m_watcher;

application/pages/instance/ModFolderPage.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -147,12 +147,13 @@ ModFolderPage::ModFolderPage(
147147
connect(m_inst, &BaseInstance::runningStatusChanged, this, &ModFolderPage::on_RunningState_changed);
148148
}
149149

150-
void ModFolderPage::modItemActivated(const QModelIndex& index)
150+
void ModFolderPage::modItemActivated(const QModelIndex&)
151151
{
152-
auto modsModelIndex = m_filterModel->mapToSource(index);
153-
if(modsModelIndex.isValid()) {
154-
m_mods->toggleEnabled(modsModelIndex);
152+
if(!m_controlsEnabled) {
153+
return;
155154
}
155+
auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
156+
m_mods->setModStatus(selection.indexes(), ModFolderModel::Toggle);
156157
}
157158

158159
QMenu * ModFolderPage::createPopupMenu()
@@ -297,7 +298,7 @@ void ModFolderPage::on_actionEnable_triggered()
297298
return;
298299
}
299300
auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
300-
m_mods->enableMods(selection.indexes(), true);
301+
m_mods->setModStatus(selection.indexes(), ModFolderModel::Enable);
301302
}
302303

303304
void ModFolderPage::on_actionDisable_triggered()
@@ -306,7 +307,7 @@ void ModFolderPage::on_actionDisable_triggered()
306307
return;
307308
}
308309
auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
309-
m_mods->enableMods(selection.indexes(), false);
310+
m_mods->setModStatus(selection.indexes(), ModFolderModel::Disable);
310311
}
311312

312313
void ModFolderPage::on_actionRemove_triggered()

application/pages/instance/ModFolderPage.ui

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
<bool>false</bool>
8888
</attribute>
8989
<addaction name="actionAdd"/>
90+
<addaction name="separator"/>
9091
<addaction name="actionRemove"/>
9192
<addaction name="actionEnable"/>
9293
<addaction name="actionDisable"/>
@@ -95,35 +96,47 @@
9596
</widget>
9697
<action name="actionAdd">
9798
<property name="text">
98-
<string>Add</string>
99+
<string>&amp;Add</string>
100+
</property>
101+
<property name="toolTip">
102+
<string>Add mods</string>
99103
</property>
100104
</action>
101105
<action name="actionRemove">
102106
<property name="text">
103-
<string>Remove</string>
107+
<string>&amp;Remove</string>
108+
</property>
109+
<property name="toolTip">
110+
<string>Remove selected mods</string>
104111
</property>
105112
</action>
106113
<action name="actionEnable">
107114
<property name="text">
108-
<string>Enable</string>
115+
<string>&amp;Enable</string>
116+
</property>
117+
<property name="toolTip">
118+
<string>Enable selected mods</string>
109119
</property>
110120
</action>
111121
<action name="actionDisable">
112122
<property name="text">
113-
<string>Disable</string>
123+
<string>&amp;Disable</string>
124+
</property>
125+
<property name="toolTip">
126+
<string>Disable selected mods</string>
114127
</property>
115128
</action>
116129
<action name="actionView_configs">
117130
<property name="text">
118-
<string>View configs</string>
131+
<string>View &amp;Configs</string>
119132
</property>
120133
<property name="toolTip">
121134
<string>Open the 'config' folder in the system file manager.</string>
122135
</property>
123136
</action>
124137
<action name="actionView_Folder">
125138
<property name="text">
126-
<string>View Folder</string>
139+
<string>View &amp;Folder</string>
127140
</property>
128141
</action>
129142
</widget>
@@ -145,6 +158,10 @@
145158
<header>widgets/WideBar.h</header>
146159
</customwidget>
147160
</customwidgets>
161+
<tabstops>
162+
<tabstop>modTreeView</tabstop>
163+
<tabstop>filterEdit</tabstop>
164+
</tabstops>
148165
<resources/>
149166
<connections/>
150167
</ui>

changelog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ There are some accessibility fixes thrown in too.
1616

1717
It now also shows disabled mods, and has prefix and suffix that shows if the mod is enabled, and if it is a folder.
1818

19+
- You can now enable and disable mods with the keyboard.
20+
21+
Toggle with enter.
22+
23+
- Enabling and disabling mods no longer makes the list forget what was selected.
24+
1925
- GH-358: Switched all the dialog pages from using buttons in layouts to toolbars.
2026

2127
Toolbar buttons are smaller, and the toolbars can overflow buttons into an overflow space. This allows requiring a lot less space for the windows.

0 commit comments

Comments
 (0)