Skip to content

Commit 374eead

Browse files
authored
Add MODL schema handling (#24)
* Add MODL schema handling - Extends entries with 'schema' attribute - Adds ability to init games with an arg string - MODL URIs will parse 'name' 'modname' 'version' and 'source' parameters - Utilizes replacement strings in the launch arg - Should automigrate old entries to 'nxm' schema - Should automatically ask to register for MODL
1 parent 08e9185 commit 374eead

10 files changed

Lines changed: 310 additions & 116 deletions

src/addbinarydialog.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,19 @@
33
#include <QFileDialog>
44

55
AddBinaryDialog::AddBinaryDialog(
6-
const std::vector<std::tuple<QString, QString, QString>>& games, QWidget* parent)
6+
const std::vector<std::tuple<QString, QString, QString>>& games,
7+
const QStringList schemas, QWidget* parent)
78
: QDialog(parent), ui(new Ui::AddBinaryDialog)
89
{
910
ui->setupUi(this);
1011

1112
for (auto iter = games.begin(); iter != games.end(); ++iter) {
1213
addGame(std::get<0>(*iter), std::get<1>(*iter));
1314
}
15+
16+
for (auto schema : schemas) {
17+
this->ui->schemaSelector->addItem(schema);
18+
}
1419
}
1520

1621
AddBinaryDialog::~AddBinaryDialog()
@@ -45,6 +50,11 @@ QString AddBinaryDialog::arguments()
4550
return ui->argumentsEdit->text();
4651
}
4752

53+
QString AddBinaryDialog::schema()
54+
{
55+
return ui->schemaSelector->currentText();
56+
}
57+
4858
void AddBinaryDialog::on_browseButton_clicked()
4959
{
5060
ui->binaryEdit->setText(QFileDialog::getOpenFileName(

src/addbinarydialog.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ class AddBinaryDialog : public QDialog
1616
public:
1717
explicit AddBinaryDialog(
1818
const std::vector<std::tuple<QString, QString, QString>>& handlers,
19-
QWidget* parent = 0);
19+
const QStringList schemas, QWidget* parent = 0);
2020
~AddBinaryDialog();
2121
QStringList gameIDs();
2222
QString executable();
2323
QString arguments();
24+
QString schema();
2425
private slots:
2526
void on_browseButton_clicked();
2627

src/addbinarydialog.ui

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<x>0</x>
88
<y>0</y>
99
<width>575</width>
10-
<height>160</height>
10+
<height>219</height>
1111
</rect>
1212
</property>
1313
<property name="windowTitle">
@@ -28,7 +28,7 @@
2828
<item>
2929
<widget class="QListWidget" name="gamesList">
3030
<property name="selectionMode">
31-
<enum>QAbstractItemView::ExtendedSelection</enum>
31+
<enum>QAbstractItemView::SelectionMode::ExtendedSelection</enum>
3232
</property>
3333
</widget>
3434
</item>
@@ -37,7 +37,7 @@
3737
<item>
3838
<layout class="QVBoxLayout" name="verticalLayout_3">
3939
<item>
40-
<widget class="QLabel" name="label_2">
40+
<widget class="QLabel" name="binaryLabel">
4141
<property name="text">
4242
<string>Select Handler Binary (i.e. ModOrganizer.exe)</string>
4343
</property>
@@ -64,7 +64,17 @@
6464
</layout>
6565
</item>
6666
<item>
67-
<widget class="QLabel" name="label_3">
67+
<widget class="QLabel" name="schemaLabel">
68+
<property name="text">
69+
<string>Assigned Schema</string>
70+
</property>
71+
</widget>
72+
</item>
73+
<item>
74+
<widget class="QComboBox" name="schemaSelector"/>
75+
</item>
76+
<item>
77+
<widget class="QLabel" name="argumentsLabel">
6878
<property name="text">
6979
<string>Set Arguments (optional)</string>
7080
</property>
@@ -76,7 +86,7 @@
7686
<item>
7787
<spacer name="verticalSpacer">
7888
<property name="orientation">
79-
<enum>Qt::Vertical</enum>
89+
<enum>Qt::Orientation::Vertical</enum>
8090
</property>
8191
<property name="sizeHint" stdset="0">
8292
<size>
@@ -93,10 +103,10 @@
93103
<item>
94104
<widget class="QDialogButtonBox" name="buttonBox">
95105
<property name="orientation">
96-
<enum>Qt::Horizontal</enum>
106+
<enum>Qt::Orientation::Horizontal</enum>
97107
</property>
98108
<property name="standardButtons">
99-
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
109+
<set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set>
100110
</property>
101111
</widget>
102112
</item>

src/handlerstorage.cpp

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,29 +23,30 @@ void HandlerStorage::clear()
2323
m_Handlers.clear();
2424
}
2525

26-
void HandlerStorage::registerProxy(const QString& proxyPath)
26+
void HandlerStorage::registerSchemaProxy(const QString& proxyPath,
27+
const QString& schema)
2728
{
28-
QSettings settings("HKEY_CURRENT_USER\\Software\\Classes\\nxm\\",
29+
QSettings settings("HKEY_CURRENT_USER\\Software\\Classes\\" + schema + "\\",
2930
QSettings::NativeFormat);
3031
QString myExe =
3132
QString("\"%1\" ").arg(QDir::toNativeSeparators(proxyPath)).append("\"%1\"");
32-
settings.setValue("Default", "URL:NXM Protocol");
33+
settings.setValue("Default", "URL:" + schema.toUpper() + " Protocol");
3334
settings.setValue("URL Protocol", "");
3435
settings.setValue("shell/open/command/Default", myExe);
3536
settings.sync();
3637
}
3738

38-
void HandlerStorage::registerHandler(const QString& executable,
39+
void HandlerStorage::registerHandler(const QString& schema, const QString& executable,
3940
const QString& arguments, bool prepend)
4041
{
4142
QStringList games;
4243
for (const auto& game : this->knownGames()) {
4344
games.append(std::get<1>(game));
4445
}
45-
registerHandler(games, executable, arguments, prepend, false);
46+
registerHandler(games, schema, executable, arguments, prepend, false);
4647
}
4748

48-
void HandlerStorage::registerHandler(const QStringList& games,
49+
void HandlerStorage::registerHandler(const QStringList& games, const QString& schema,
4950
const QString& executable,
5051
const QString& arguments, bool prepend, bool rereg)
5152
{
@@ -54,12 +55,14 @@ void HandlerStorage::registerHandler(const QStringList& games,
5455
gamesLower.append(game.toLower());
5556
}
5657
for (auto iter = m_Handlers.begin(); iter != m_Handlers.end(); ++iter) {
57-
if (iter->executable.compare(executable, Qt::CaseInsensitive) == 0) {
58-
// executable already registered, update supported games and move it to top if
59-
// requested
58+
if (iter->executable.compare(executable, Qt::CaseInsensitive) == 0 &&
59+
iter->schema.compare(schema, Qt::CaseInsensitive) == 0) {
60+
// executable already registered, update supported games and move it to
61+
// top if requested
6062
if (rereg) {
6163
HandlerInfo info = *iter;
6264
info.games = gamesLower;
65+
info.arguments = arguments;
6366
m_Handlers.erase(iter);
6467
if (prepend) {
6568
m_Handlers.push_front(info);
@@ -69,6 +72,7 @@ void HandlerStorage::registerHandler(const QStringList& games,
6972
} else {
7073
iter->games.append(gamesLower);
7174
iter->games.removeDuplicates();
75+
iter->arguments = arguments;
7276
}
7377
return; // important: in the rereg-case we changed the list thus screwing up the
7478
// iterator
@@ -79,6 +83,7 @@ void HandlerStorage::registerHandler(const QStringList& games,
7983
HandlerInfo info;
8084
info.ID = static_cast<int>(m_Handlers.size());
8185
info.games = gamesLower;
86+
info.schema = schema;
8287
info.executable = executable;
8388
info.arguments = arguments;
8489
if (prepend) {
@@ -88,7 +93,7 @@ void HandlerStorage::registerHandler(const QStringList& games,
8893
}
8994
}
9095

91-
QStringList HandlerStorage::getHandler(const QString& game) const
96+
QStringList HandlerStorage::getHandler(const QString& game, const QString& schema) const
9297
{
9398
QString gameKey;
9499
QStringList results;
@@ -102,23 +107,27 @@ QStringList HandlerStorage::getHandler(const QString& game) const
102107
}
103108
// look for an explictly registered handler
104109
for (const HandlerInfo& info : m_Handlers) {
105-
for (auto handler : info.games) {
106-
if (game.compare(handler, Qt::CaseInsensitive) == 0 ||
107-
gameKey.compare(handler, Qt::CaseInsensitive) == 0) {
108-
results << info.executable;
109-
results << info.arguments;
110-
return results;
110+
if (info.schema == schema) {
111+
for (auto handler : info.games) {
112+
if (game.compare(handler, Qt::CaseInsensitive) == 0 ||
113+
gameKey.compare(handler, Qt::CaseInsensitive) == 0) {
114+
results << info.executable;
115+
results << info.arguments;
116+
return results;
117+
}
111118
}
112119
}
113120
}
114121

115122
// if no registered handler, look for the first "other" entry
116123
if (results.length() == 0) {
117124
for (const HandlerInfo& info : m_Handlers) {
118-
if (info.games.contains("other", Qt::CaseInsensitive)) {
119-
results << info.executable;
120-
results << info.arguments;
121-
return results;
125+
if (info.schema == schema) {
126+
if (info.games.contains("other", Qt::CaseInsensitive)) {
127+
results << info.executable;
128+
results << info.arguments;
129+
return results;
130+
}
122131
}
123132
}
124133
}
@@ -136,18 +145,26 @@ std::vector<std::tuple<QString, QString, QString>> HandlerStorage::knownGames()
136145
return {
137146
std::make_tuple<QString, QString, QString>("Morrowind", "morrowind", "morrowind"),
138147
std::make_tuple<QString, QString, QString>("Oblivion", "oblivion", "oblivion"),
148+
std::make_tuple<QString, QString, QString>(
149+
"Oblivion Remastered", "oblivionremastered", "oblivionremastered"),
139150
std::make_tuple<QString, QString, QString>("Fallout 3", "fallout3", "fallout3"),
140151
std::make_tuple<QString, QString, QString>("Fallout 4", "fallout4", "fallout4"),
141152
std::make_tuple<QString, QString, QString>("Fallout NV", "falloutnv", "newvegas"),
142153
std::make_tuple<QString, QString, QString>("Skyrim", "skyrim", "skyrim"),
143154
std::make_tuple<QString, QString, QString>("SkyrimSE", "skyrimse",
144155
"skyrimspecialedition"),
156+
std::make_tuple<QString, QString, QString>("Starfield", "starfield", "starfield"),
145157
std::make_tuple<QString, QString, QString>("Enderal", "enderal", "enderal"),
146158
std::make_tuple<QString, QString, QString>("EnderalSE", "enderalse",
147159
"enderalspecialedition"),
148160
std::make_tuple<QString, QString, QString>("Other", "other", "other")};
149161
}
150162

163+
QStringList HandlerStorage::availableSchemas() const
164+
{
165+
return {"nxm", "modl"};
166+
}
167+
151168
QStringList HandlerStorage::stripCall(const QString& call)
152169
{
153170
// results[0] is binary, results[1..n] are optional arguments
@@ -213,6 +230,7 @@ void HandlerStorage::loadStore()
213230
if (!gameList.isEmpty()) {
214231
info.games = gameList.split(",");
215232
}
233+
info.schema = settings.value("schema", "nxm").toString();
216234
info.executable = settings.value("executable").toString();
217235
info.arguments = settings.value("arguments").toString();
218236
if (QFile::exists(info.executable)) {
@@ -234,6 +252,7 @@ void HandlerStorage::loadStore()
234252
ids.append(std::get<1>(*iter));
235253
}
236254
info.games = QStringList() << ids;
255+
info.schema = "nxm";
237256
info.executable = handlerValues.front();
238257
handlerValues.pop_front();
239258
info.arguments = handlerValues.join(" ");
@@ -261,6 +280,7 @@ void HandlerStorage::saveStore()
261280
for (auto iter = m_Handlers.begin(); iter != m_Handlers.end(); ++iter) {
262281
settings.setArrayIndex(i++);
263282
settings.setValue("games", iter->games.join(","));
283+
settings.setValue("schema", iter->schema);
264284
settings.setValue("executable", iter->executable);
265285
settings.setValue("arguments", iter->arguments);
266286
}

src/handlerstorage.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ struct HandlerInfo
1010
{
1111
int ID;
1212
QStringList games;
13+
QString schema;
1314
QString executable;
1415
QString arguments;
1516
};
@@ -22,16 +23,18 @@ class HandlerStorage : public QObject
2223
~HandlerStorage();
2324

2425
void clear();
25-
/// register the primary proxy handler
26-
void registerProxy(const QString& proxyPath);
26+
/// register a proxy handler
27+
void registerSchemaProxy(const QString& proxyPath, const QString& schema);
2728
/// register handler (for all games)
28-
void registerHandler(const QString& executable, const QString& arguments,
29-
bool prepend);
29+
void registerHandler(const QString& schema, const QString& executable,
30+
const QString& arguments, bool prepend);
3031
/// register handler for specified games
31-
void registerHandler(const QStringList& games, const QString& executable,
32-
const QString& arguments, bool prepend, bool rereg);
33-
QStringList getHandler(const QString& game) const;
32+
void registerHandler(const QStringList& games, const QString& schema,
33+
const QString& executable, const QString& arguments,
34+
bool prepend, bool rereg);
35+
QStringList getHandler(const QString& game, const QString& schema) const;
3436
std::vector<std::tuple<QString, QString, QString>> knownGames() const;
37+
QStringList availableSchemas() const;
3538
std::list<HandlerInfo> handlers() const { return m_Handlers; }
3639

3740
static QStringList stripCall(const QString& call);

0 commit comments

Comments
 (0)