Merge pull request #25 from ModOrganizer2/dev/clang-formatting

Apply clang-formatting and add CI
This commit is contained in:
Mikaël Capelle
2026-05-03 09:48:55 +02:00
committed by GitHub
16 changed files with 798 additions and 651 deletions
+41
View File
@@ -0,0 +1,41 @@
---
# We'll use defaults from the LLVM style, but with 4 columns indentation.
BasedOnStyle: LLVM
IndentWidth: 2
---
Language: Cpp
DeriveLineEnding: false
UseCRLF: true
DerivePointerAlignment: false
PointerAlignment: Left
AlignConsecutiveAssignments: true
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: Empty
AlwaysBreakTemplateDeclarations: Yes
AccessModifierOffset: -2
AlignTrailingComments: true
SpacesBeforeTrailingComments: 2
NamespaceIndentation: Inner
MaxEmptyLinesToKeep: 1
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
AfterClass: true
AfterControlStatement: false
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: true
ColumnLimit: 88
ForEachMacros: ['Q_FOREACH', 'foreach']
+1
View File
@@ -0,0 +1 @@
4bc5eecd3197fbc469f05987865b38b144540aa7
+7
View File
@@ -0,0 +1,7 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
# Explicitly declare text files you want to always be normalized and converted
# to native line endings on checkout.
*.cpp text eol=crlf
*.h text eol=crlf
+22
View File
@@ -0,0 +1,22 @@
name: Build NXM Handler
on:
push:
branches: [ master ]
pull_request:
types: [ opened, synchronize, reopened ]
env:
VCPKG_BINARY_SOURCES: ${{ vars.AZ_BLOB_VCPKG_URL != '' &&
format('clear;x-azblob,{0},{1},readwrite', vars.AZ_BLOB_VCPKG_URL,
secrets.AZ_BLOB_SAS) || '' }}
jobs:
build:
runs-on: windows-2022
steps:
- name: Build NXM Handler
id: build-modorganizer
uses: ModOrganizer2/build-with-mob-action@master
with:
mo2-dependencies: uibase
+17
View File
@@ -0,0 +1,17 @@
name: Lint NXM Handler
on:
push:
pull_request:
types: [ opened, synchronize, reopened ]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Check format
uses: ModOrganizer2/check-formatting-action@master
with:
check-path: "."
exclude-regex: "third-party"
+5
View File
@@ -6,6 +6,11 @@ repos:
- id: end-of-file-fixer
- id: check-merge-conflict
- id: check-case-conflict
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: v22.1.2
hooks:
- id: clang-format
'types_or': [c++, c]
ci:
autofix_commit_msg: "[pre-commit.ci] Auto fixes from pre-commit.com hooks."
+7
View File
@@ -51,5 +51,12 @@
"name": "vs2022-windows-standalone"
}
],
"buildPresets": [
{
"name": "vs2022-windows",
"resolvePackageReferences": "on",
"configurePreset": "vs2022-windows"
}
],
"version": 4
}
+52 -53
View File
@@ -1,53 +1,52 @@
#include "addbinarydialog.h"
#include "ui_addbinarydialog.h"
#include <QFileDialog>
AddBinaryDialog::AddBinaryDialog(const std::vector<std::tuple<QString, QString, QString>> &games, QWidget *parent)
: QDialog(parent)
, ui(new Ui::AddBinaryDialog)
{
ui->setupUi(this);
for (auto iter = games.begin(); iter != games.end(); ++iter) {
addGame(std::get<0>(*iter), std::get<1>(*iter));
}
}
AddBinaryDialog::~AddBinaryDialog()
{
delete ui;
}
void AddBinaryDialog::addGame(const QString &name, const QString &id)
{
QListWidgetItem *item = new QListWidgetItem(name);
item->setData(Qt::UserRole, id);
ui->gamesList->addItem(item);
}
QStringList AddBinaryDialog::gameIDs()
{
QStringList result;
Q_FOREACH(QListWidgetItem *item, ui->gamesList->selectedItems()) {
result.append(item->data(Qt::UserRole).toString());
}
return result;
}
QString AddBinaryDialog::executable()
{
return QDir::toNativeSeparators(ui->binaryEdit->text());
}
QString AddBinaryDialog::arguments()
{
return ui->argumentsEdit->text();
}
void AddBinaryDialog::on_browseButton_clicked()
{
ui->binaryEdit->setText(QFileDialog::getOpenFileName(this, tr("Select Executable"), QString(),
tr("Executable (*.exe)")));
}
#include "addbinarydialog.h"
#include "ui_addbinarydialog.h"
#include <QFileDialog>
AddBinaryDialog::AddBinaryDialog(
const std::vector<std::tuple<QString, QString, QString>>& games, QWidget* parent)
: QDialog(parent), ui(new Ui::AddBinaryDialog)
{
ui->setupUi(this);
for (auto iter = games.begin(); iter != games.end(); ++iter) {
addGame(std::get<0>(*iter), std::get<1>(*iter));
}
}
AddBinaryDialog::~AddBinaryDialog()
{
delete ui;
}
void AddBinaryDialog::addGame(const QString& name, const QString& id)
{
QListWidgetItem* item = new QListWidgetItem(name);
item->setData(Qt::UserRole, id);
ui->gamesList->addItem(item);
}
QStringList AddBinaryDialog::gameIDs()
{
QStringList result;
Q_FOREACH (QListWidgetItem* item, ui->gamesList->selectedItems()) {
result.append(item->data(Qt::UserRole).toString());
}
return result;
}
QString AddBinaryDialog::executable()
{
return QDir::toNativeSeparators(ui->binaryEdit->text());
}
QString AddBinaryDialog::arguments()
{
return ui->argumentsEdit->text();
}
void AddBinaryDialog::on_browseButton_clicked()
{
ui->binaryEdit->setText(QFileDialog::getOpenFileName(
this, tr("Select Executable"), QString(), tr("Executable (*.exe)")));
}
+34 -29
View File
@@ -1,29 +1,34 @@
#ifndef ADDBINARYDIALOG_H
#define ADDBINARYDIALOG_H
#include <QDialog>
#include "handlerstorage.h"
namespace Ui {
class AddBinaryDialog;
}
class AddBinaryDialog : public QDialog
{
Q_OBJECT
public:
explicit AddBinaryDialog(const std::vector<std::tuple<QString, QString, QString>> &handlers, QWidget *parent = 0);
~AddBinaryDialog();
QStringList gameIDs();
QString executable();
QString arguments();
private slots:
void on_browseButton_clicked();
private:
void addGame(const QString &name, const QString &id);
private:
Ui::AddBinaryDialog *ui;
};
#endif // ADDBINARYDIALOG_H
#ifndef ADDBINARYDIALOG_H
#define ADDBINARYDIALOG_H
#include "handlerstorage.h"
#include <QDialog>
namespace Ui
{
class AddBinaryDialog;
}
class AddBinaryDialog : public QDialog
{
Q_OBJECT
public:
explicit AddBinaryDialog(
const std::vector<std::tuple<QString, QString, QString>>& handlers,
QWidget* parent = 0);
~AddBinaryDialog();
QStringList gameIDs();
QString executable();
QString arguments();
private slots:
void on_browseButton_clicked();
private:
void addGame(const QString& name, const QString& id);
private:
Ui::AddBinaryDialog* ui;
};
#endif // ADDBINARYDIALOG_H
+63 -55
View File
@@ -1,15 +1,14 @@
#include "handlerstorage.h"
#include <QCoreApplication>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QDir>
#include <QRegularExpression>
static const QRegularExpression invalid_arguments("\"?%[0-9]+\"?");
HandlerStorage::HandlerStorage(const QString &storagePath, QObject *parent)
: QObject(parent)
, m_SettingsPath(storagePath + "/nxmhandler.ini")
HandlerStorage::HandlerStorage(const QString& storagePath, QObject* parent)
: QObject(parent), m_SettingsPath(storagePath + "/nxmhandler.ini")
{
loadStore();
}
@@ -24,37 +23,43 @@ void HandlerStorage::clear()
m_Handlers.clear();
}
void HandlerStorage::registerProxy(const QString &proxyPath)
void HandlerStorage::registerProxy(const QString& proxyPath)
{
QSettings settings("HKEY_CURRENT_USER\\Software\\Classes\\nxm\\", QSettings::NativeFormat);
QString myExe = QString("\"%1\" ").arg(QDir::toNativeSeparators(proxyPath)).append("\"%1\"");
QSettings settings("HKEY_CURRENT_USER\\Software\\Classes\\nxm\\",
QSettings::NativeFormat);
QString myExe =
QString("\"%1\" ").arg(QDir::toNativeSeparators(proxyPath)).append("\"%1\"");
settings.setValue("Default", "URL:NXM Protocol");
settings.setValue("URL Protocol", "");
settings.setValue("shell/open/command/Default", myExe);
settings.sync();
}
void HandlerStorage::registerHandler(const QString &executable, const QString &arguments, bool prepend)
void HandlerStorage::registerHandler(const QString& executable,
const QString& arguments, bool prepend)
{
QStringList games;
for (const auto &game : this->knownGames()) {
for (const auto& game : this->knownGames()) {
games.append(std::get<1>(game));
}
registerHandler(games, executable, arguments, prepend, false);
}
void HandlerStorage::registerHandler(const QStringList &games, const QString &executable, const QString &arguments, bool prepend, bool rereg)
void HandlerStorage::registerHandler(const QStringList& games,
const QString& executable,
const QString& arguments, bool prepend, bool rereg)
{
QStringList gamesLower;
for (const QString &game : games) {
for (const QString& game : games) {
gamesLower.append(game.toLower());
}
for (auto iter = m_Handlers.begin(); iter != m_Handlers.end(); ++iter) {
if (iter->executable.compare(executable, Qt::CaseInsensitive) == 0) {
// executable already registered, update supported games and move it to top if requested
// executable already registered, update supported games and move it to top if
// requested
if (rereg) {
HandlerInfo info = *iter;
info.games = gamesLower;
info.games = gamesLower;
m_Handlers.erase(iter);
if (prepend) {
m_Handlers.push_front(info);
@@ -65,16 +70,17 @@ void HandlerStorage::registerHandler(const QStringList &games, const QString &ex
iter->games.append(gamesLower);
iter->games.removeDuplicates();
}
return; // important: in the rereg-case we changed the list thus screwing up the iterator
return; // important: in the rereg-case we changed the list thus screwing up the
// iterator
}
}
// executable not yet registered
HandlerInfo info;
info.ID = static_cast<int>(m_Handlers.size());
info.games = gamesLower;
info.ID = static_cast<int>(m_Handlers.size());
info.games = gamesLower;
info.executable = executable;
info.arguments = arguments;
info.arguments = arguments;
if (prepend) {
m_Handlers.push_front(info);
} else {
@@ -82,33 +88,33 @@ void HandlerStorage::registerHandler(const QStringList &games, const QString &ex
}
}
QStringList HandlerStorage::getHandler(const QString &game) const
QStringList HandlerStorage::getHandler(const QString& game) const
{
QString gameKey;
QStringList results;
auto games = knownGames();
for (auto known : games) {
if (game.compare(std::get<1>(known), Qt::CaseInsensitive) == 0 ||
game.compare(std::get<2>(known), Qt::CaseInsensitive) == 0) {
gameKey = std::get<1>(known);
}
if (game.compare(std::get<1>(known), Qt::CaseInsensitive) == 0 ||
game.compare(std::get<2>(known), Qt::CaseInsensitive) == 0) {
gameKey = std::get<1>(known);
}
}
// look for an explictly registered handler
for (const HandlerInfo &info : m_Handlers) {
for (const HandlerInfo& info : m_Handlers) {
for (auto handler : info.games) {
if (game.compare(handler, Qt::CaseInsensitive) == 0 ||
gameKey.compare(handler, Qt::CaseInsensitive) == 0) {
results << info.executable;
results << info.arguments;
return results;
}
if (game.compare(handler, Qt::CaseInsensitive) == 0 ||
gameKey.compare(handler, Qt::CaseInsensitive) == 0) {
results << info.executable;
results << info.arguments;
return results;
}
}
}
// if no registered handler, look for the first "other" entry
if (results.length() == 0) {
for (const HandlerInfo &info : m_Handlers) {
for (const HandlerInfo& info : m_Handlers) {
if (info.games.contains("other", Qt::CaseInsensitive)) {
results << info.executable;
results << info.arguments;
@@ -128,20 +134,21 @@ QStringList HandlerStorage::getHandler(const QString &game) const
std::vector<std::tuple<QString, QString, QString>> HandlerStorage::knownGames() const
{
return {
std::make_tuple<QString, QString, QString>("Morrowind", "morrowind", "morrowind"),
std::make_tuple<QString, QString, QString>("Oblivion", "oblivion", "oblivion"),
std::make_tuple<QString, QString, QString>("Fallout 3", "fallout3", "fallout3"),
std::make_tuple<QString, QString, QString>("Fallout 4", "fallout4", "fallout4"),
std::make_tuple<QString, QString, QString>("Fallout NV", "falloutnv", "newvegas"),
std::make_tuple<QString, QString, QString>("Skyrim", "skyrim", "skyrim"),
std::make_tuple<QString, QString, QString>("SkyrimSE", "skyrimse", "skyrimspecialedition"),
std::make_tuple<QString, QString, QString>("Enderal", "enderal", "enderal"),
std::make_tuple<QString, QString, QString>("EnderalSE", "enderalse", "enderalspecialedition"),
std::make_tuple<QString, QString, QString>("Other", "other", "other")
};
std::make_tuple<QString, QString, QString>("Morrowind", "morrowind", "morrowind"),
std::make_tuple<QString, QString, QString>("Oblivion", "oblivion", "oblivion"),
std::make_tuple<QString, QString, QString>("Fallout 3", "fallout3", "fallout3"),
std::make_tuple<QString, QString, QString>("Fallout 4", "fallout4", "fallout4"),
std::make_tuple<QString, QString, QString>("Fallout NV", "falloutnv", "newvegas"),
std::make_tuple<QString, QString, QString>("Skyrim", "skyrim", "skyrim"),
std::make_tuple<QString, QString, QString>("SkyrimSE", "skyrimse",
"skyrimspecialedition"),
std::make_tuple<QString, QString, QString>("Enderal", "enderal", "enderal"),
std::make_tuple<QString, QString, QString>("EnderalSE", "enderalse",
"enderalspecialedition"),
std::make_tuple<QString, QString, QString>("Other", "other", "other")};
}
QStringList HandlerStorage::stripCall(const QString &call)
QStringList HandlerStorage::stripCall(const QString& call)
{
// results[0] is binary, results[1..n] are optional arguments
// guarenteed to return at least 2 items
@@ -149,13 +156,12 @@ QStringList HandlerStorage::stripCall(const QString &call)
bool in_quote = false;
QString word;
for( QString::const_iterator iter = call.begin(); iter != call.end(); iter++ ){
for (QString::const_iterator iter = call.begin(); iter != call.end(); iter++) {
// Handle quotes
if (*iter == '"') {
if (!in_quote) {
in_quote = true;
}
else {
} else {
in_quote = false;
}
}
@@ -167,12 +173,12 @@ QStringList HandlerStorage::stripCall(const QString &call)
results << word;
}
word = "";
continue; //skip space
continue; // skip space
}
// Made it here? Add to the word
word += *iter;
}
}
// Add the last word to the results if needed
if (!word.isEmpty()) {
@@ -202,39 +208,41 @@ void HandlerStorage::loadStore()
for (int i = 0; i < size; ++i) {
settings.setArrayIndex(i);
HandlerInfo info;
info.ID = i;
info.ID = i;
QString gameList = settings.value("games").toString();
if (!gameList.isEmpty()) {
info.games = gameList.split(",");
}
info.executable = settings.value("executable").toString();
info.arguments = settings.value("arguments").toString();
info.arguments = settings.value("arguments").toString();
if (QFile::exists(info.executable)) {
m_Handlers.push_back(info);
}
}
settings.endArray();
// also register the global handler
HandlerInfo info;
QSettings handlerReg("HKEY_CLASSES_ROOT\\nxm\\", QSettings::NativeFormat);
QStringList handlerValues(stripCall(handlerReg.value("shell/open/command/Default").toString()));
QStringList handlerValues(
stripCall(handlerReg.value("shell/open/command/Default").toString()));
info.ID = static_cast<int>(m_Handlers.size());
info.ID = static_cast<int>(m_Handlers.size());
auto games = knownGames();
QStringList ids;
for (auto iter = games.begin(); iter != games.end(); ++iter) {
ids.append(std::get<1>(*iter));
}
info.games = QStringList() << ids;
info.games = QStringList() << ids;
info.executable = handlerValues.front();
handlerValues.pop_front();
info.arguments = handlerValues.join(" ");
if (!info.executable.isEmpty() && !info.executable.endsWith("nxmhandler.exe", Qt::CaseInsensitive)) {
if (!info.executable.isEmpty() &&
!info.executable.endsWith("nxmhandler.exe", Qt::CaseInsensitive)) {
bool known = false;
for (auto iter = m_Handlers.begin(); iter != m_Handlers.end(); ++iter) {
if ((iter->executable == info.executable) && (iter->arguments == info.arguments)) {
if ((iter->executable == info.executable) &&
(iter->arguments == info.arguments)) {
known = true;
}
}
+48 -45
View File
@@ -1,45 +1,48 @@
#ifndef HANDLERSTORAGE_H
#define HANDLERSTORAGE_H
#include <QSettings>
#include <list>
#include <vector>
#include <QStringList>
struct HandlerInfo
{
int ID;
QStringList games;
QString executable;
QString arguments;
};
class HandlerStorage : public QObject
{
Q_OBJECT
public:
HandlerStorage(const QString &storagePath, QObject *parent = nullptr);
~HandlerStorage();
void clear();
/// register the primary proxy handler
void registerProxy(const QString &proxyPath);
/// register handler (for all games)
void registerHandler(const QString &executable, const QString &arguments, bool prepend);
/// register handler for specified games
void registerHandler(const QStringList &games, const QString &executable, const QString &arguments, bool prepend, bool rereg);
QStringList getHandler(const QString &game) const;
std::vector<std::tuple<QString, QString, QString>> knownGames() const;
std::list<HandlerInfo> handlers() const { return m_Handlers; }
static QStringList stripCall(const QString &call);
private:
void loadStore();
void saveStore();
private:
QString m_SettingsPath;
std::list<HandlerInfo> m_Handlers;
};
#endif // HANDLERSTORAGE_H
#ifndef HANDLERSTORAGE_H
#define HANDLERSTORAGE_H
#include <QSettings>
#include <QStringList>
#include <list>
#include <vector>
struct HandlerInfo
{
int ID;
QStringList games;
QString executable;
QString arguments;
};
class HandlerStorage : public QObject
{
Q_OBJECT
public:
HandlerStorage(const QString& storagePath, QObject* parent = nullptr);
~HandlerStorage();
void clear();
/// register the primary proxy handler
void registerProxy(const QString& proxyPath);
/// register handler (for all games)
void registerHandler(const QString& executable, const QString& arguments,
bool prepend);
/// register handler for specified games
void registerHandler(const QStringList& games, const QString& executable,
const QString& arguments, bool prepend, bool rereg);
QStringList getHandler(const QString& game) const;
std::vector<std::tuple<QString, QString, QString>> knownGames() const;
std::list<HandlerInfo> handlers() const { return m_Handlers; }
static QStringList stripCall(const QString& call);
private:
void loadStore();
void saveStore();
private:
QString m_SettingsPath;
std::list<HandlerInfo> m_Handlers;
};
#endif // HANDLERSTORAGE_H
+138 -129
View File
@@ -1,129 +1,138 @@
#include "handlerwindow.h"
#include "ui_handlerwindow.h"
#include "addbinarydialog.h"
#include <QMenu>
#include <QMessageBox>
#include <QShortcut>
#include <QKeyEvent>
#include <QDir>
enum {
COL_GAMES,
COL_BINARY,
COL_ARGUMENTS
};
HandlerWindow::HandlerWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::HandlerWindow)
{
ui->setupUi(this);
connect(ui->actionAdd, SIGNAL(triggered()), this, SLOT(addBinaryDialog()));
connect(ui->actionRemove, SIGNAL(triggered()), this, SLOT(removeBinary()));
new QShortcut(QKeySequence(Qt::Key_Delete), this, SLOT(removeBinary()));
}
HandlerWindow::~HandlerWindow()
{
delete ui;
}
void HandlerWindow::setPrimaryHandler(const QString &handlerPath)
{
if (handlerPath == QCoreApplication::applicationFilePath()) {
ui->registerButton->setEnabled(false);
ui->handlerView->setText(tr("<Current>"));
} else {
ui->handlerView->setText(handlerPath);
}
}
void HandlerWindow::setHandlerStorage(HandlerStorage *storage)
{
m_Storage = storage;
ui->handlersWidget->clear();
auto list = storage->handlers();
for (auto iter = list.begin(); iter != list.end(); ++iter) {
QTreeWidgetItem *newItem = new QTreeWidgetItem(QStringList() << iter->games.join(",") << QDir::toNativeSeparators(iter->executable) << iter->arguments);
newItem->setFlags(newItem->flags() | Qt::ItemIsEditable);
ui->handlersWidget->addTopLevelItem(newItem);
}
ui->handlersWidget->resizeColumnToContents(COL_BINARY);
}
void HandlerWindow::closeEvent(QCloseEvent *event)
{
m_Storage->clear();
for (int i = 0; i < ui->handlersWidget->topLevelItemCount(); ++i) {
QTreeWidgetItem *item = ui->handlersWidget->topLevelItem(i);
m_Storage->registerHandler(item->text(0).split(","), item->text(1), item->text(2), false, false);
}
QMainWindow::closeEvent(event);
}
void HandlerWindow::addBinaryDialog()
{
AddBinaryDialog dialog(m_Storage->knownGames());
if (dialog.exec() == QDialog::Accepted) {
bool executableKnown = false;
for (int i = 0; i < ui->handlersWidget->topLevelItemCount(); ++i) {
QTreeWidgetItem *iterItem = ui->handlersWidget->topLevelItem(i);
if (QFileInfo(iterItem->text(COL_BINARY)) == QFileInfo(dialog.executable())) {
QStringList games = iterItem->text(COL_GAMES).split(",");
games.append(dialog.gameIDs());
games.removeDuplicates();
iterItem->setText(COL_GAMES, games.join(","));
if (iterItem->text(COL_ARGUMENTS).compare(dialog.arguments(), Qt::CaseInsensitive) != 0) {
iterItem->setText(COL_ARGUMENTS, dialog.arguments());
}
executableKnown = true;
}
}
if (!executableKnown) {
QTreeWidgetItem *newItem = new QTreeWidgetItem(QStringList() << dialog.gameIDs().join(",") << dialog.executable() << dialog.arguments());
newItem->setFlags(newItem->flags() | Qt::ItemIsEditable);
ui->handlersWidget->insertTopLevelItem(0, newItem);
}
ui->handlersWidget->resizeColumnToContents(COL_BINARY);
}
}
void HandlerWindow::removeBinary() {
ui->handlersWidget->takeTopLevelItem(
ui->handlersWidget->currentIndex().row());
ui->handlersWidget->resizeColumnToContents(COL_BINARY);
}
void HandlerWindow::on_handlersWidget_customContextMenuRequested(const QPoint &pos)
{
QMenu contextMenu;
QModelIndex idx = ui->handlersWidget->indexAt(pos);
if (idx.isValid()) {
contextMenu.addAction(ui->actionRemove);
} else {
contextMenu.addAction(ui->actionAdd);
}
contextMenu.move(ui->handlersWidget->mapToGlobal(pos));
contextMenu.exec();
}
void HandlerWindow::on_registerButton_clicked()
{
if (QMessageBox::question(this, tr("Change handler registration?"),
tr("This will make the nxmhandler.exe you called the primary handler registered in the system.\n"
"That has no immediate impact on how links are handled.\nUse this if you moved Mod Organizer "
"or if you uninstalled the Mod Organizer installation that was previously registered. Continue?"),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
ui->handlerView->setText(tr("<Current>"));
ui->registerButton->setEnabled(false);
m_Storage->registerProxy(QCoreApplication::applicationFilePath());
}
}
#include "handlerwindow.h"
#include "addbinarydialog.h"
#include "ui_handlerwindow.h"
#include <QDir>
#include <QKeyEvent>
#include <QMenu>
#include <QMessageBox>
#include <QShortcut>
enum
{
COL_GAMES,
COL_BINARY,
COL_ARGUMENTS
};
HandlerWindow::HandlerWindow(QWidget* parent)
: QMainWindow(parent), ui(new Ui::HandlerWindow)
{
ui->setupUi(this);
connect(ui->actionAdd, SIGNAL(triggered()), this, SLOT(addBinaryDialog()));
connect(ui->actionRemove, SIGNAL(triggered()), this, SLOT(removeBinary()));
new QShortcut(QKeySequence(Qt::Key_Delete), this, SLOT(removeBinary()));
}
HandlerWindow::~HandlerWindow()
{
delete ui;
}
void HandlerWindow::setPrimaryHandler(const QString& handlerPath)
{
if (handlerPath == QCoreApplication::applicationFilePath()) {
ui->registerButton->setEnabled(false);
ui->handlerView->setText(tr("<Current>"));
} else {
ui->handlerView->setText(handlerPath);
}
}
void HandlerWindow::setHandlerStorage(HandlerStorage* storage)
{
m_Storage = storage;
ui->handlersWidget->clear();
auto list = storage->handlers();
for (auto iter = list.begin(); iter != list.end(); ++iter) {
QTreeWidgetItem* newItem = new QTreeWidgetItem(
QStringList() << iter->games.join(",")
<< QDir::toNativeSeparators(iter->executable) << iter->arguments);
newItem->setFlags(newItem->flags() | Qt::ItemIsEditable);
ui->handlersWidget->addTopLevelItem(newItem);
}
ui->handlersWidget->resizeColumnToContents(COL_BINARY);
}
void HandlerWindow::closeEvent(QCloseEvent* event)
{
m_Storage->clear();
for (int i = 0; i < ui->handlersWidget->topLevelItemCount(); ++i) {
QTreeWidgetItem* item = ui->handlersWidget->topLevelItem(i);
m_Storage->registerHandler(item->text(0).split(","), item->text(1), item->text(2),
false, false);
}
QMainWindow::closeEvent(event);
}
void HandlerWindow::addBinaryDialog()
{
AddBinaryDialog dialog(m_Storage->knownGames());
if (dialog.exec() == QDialog::Accepted) {
bool executableKnown = false;
for (int i = 0; i < ui->handlersWidget->topLevelItemCount(); ++i) {
QTreeWidgetItem* iterItem = ui->handlersWidget->topLevelItem(i);
if (QFileInfo(iterItem->text(COL_BINARY)) == QFileInfo(dialog.executable())) {
QStringList games = iterItem->text(COL_GAMES).split(",");
games.append(dialog.gameIDs());
games.removeDuplicates();
iterItem->setText(COL_GAMES, games.join(","));
if (iterItem->text(COL_ARGUMENTS)
.compare(dialog.arguments(), Qt::CaseInsensitive) != 0) {
iterItem->setText(COL_ARGUMENTS, dialog.arguments());
}
executableKnown = true;
}
}
if (!executableKnown) {
QTreeWidgetItem* newItem = new QTreeWidgetItem(
QStringList() << dialog.gameIDs().join(",") << dialog.executable()
<< dialog.arguments());
newItem->setFlags(newItem->flags() | Qt::ItemIsEditable);
ui->handlersWidget->insertTopLevelItem(0, newItem);
}
ui->handlersWidget->resizeColumnToContents(COL_BINARY);
}
}
void HandlerWindow::removeBinary()
{
ui->handlersWidget->takeTopLevelItem(ui->handlersWidget->currentIndex().row());
ui->handlersWidget->resizeColumnToContents(COL_BINARY);
}
void HandlerWindow::on_handlersWidget_customContextMenuRequested(const QPoint& pos)
{
QMenu contextMenu;
QModelIndex idx = ui->handlersWidget->indexAt(pos);
if (idx.isValid()) {
contextMenu.addAction(ui->actionRemove);
} else {
contextMenu.addAction(ui->actionAdd);
}
contextMenu.move(ui->handlersWidget->mapToGlobal(pos));
contextMenu.exec();
}
void HandlerWindow::on_registerButton_clicked()
{
if (QMessageBox::question(this, tr("Change handler registration?"),
tr("This will make the nxmhandler.exe you called the "
"primary handler registered in the system.\n"
"That has no immediate impact on how links are "
"handled.\nUse this if you moved Mod Organizer "
"or if you uninstalled the Mod Organizer installation "
"that was previously registered. Continue?"),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
ui->handlerView->setText(tr("<Current>"));
ui->registerButton->setEnabled(false);
m_Storage->registerProxy(QCoreApplication::applicationFilePath());
}
}
+37 -38
View File
@@ -1,38 +1,37 @@
#ifndef HANDLERWINDOW_H
#define HANDLERWINDOW_H
#include <QMainWindow>
#include <QPersistentModelIndex>
#include "handlerstorage.h"
namespace Ui {
class HandlerWindow;
}
class HandlerWindow : public QMainWindow
{
Q_OBJECT
public:
explicit HandlerWindow(QWidget *parent = 0);
~HandlerWindow();
void setPrimaryHandler(const QString &handlerPath);
void setHandlerStorage(HandlerStorage *storage);
protected:
virtual void closeEvent(QCloseEvent *event);
private slots:
void on_handlersWidget_customContextMenuRequested(const QPoint &pos);
void addBinaryDialog();
void removeBinary();
void on_registerButton_clicked();
private:
Ui::HandlerWindow *ui;
HandlerStorage *m_Storage;
};
#endif // HANDLERWINDOW_H
#ifndef HANDLERWINDOW_H
#define HANDLERWINDOW_H
#include "handlerstorage.h"
#include <QMainWindow>
#include <QPersistentModelIndex>
namespace Ui
{
class HandlerWindow;
}
class HandlerWindow : public QMainWindow
{
Q_OBJECT
public:
explicit HandlerWindow(QWidget* parent = 0);
~HandlerWindow();
void setPrimaryHandler(const QString& handlerPath);
void setHandlerStorage(HandlerStorage* storage);
protected:
virtual void closeEvent(QCloseEvent* event);
private slots:
void on_handlersWidget_customContextMenuRequested(const QPoint& pos);
void addBinaryDialog();
void removeBinary();
void on_registerButton_clicked();
private:
Ui::HandlerWindow* ui;
HandlerStorage* m_Storage;
};
#endif // HANDLERWINDOW_H
+9 -5
View File
@@ -4,19 +4,23 @@
#include <QDateTime>
#include <QFile>
namespace NxmHandler {
namespace NxmHandler
{
static QFile g_File;
static void logHandler(QtMsgType type, const QMessageLogContext &context, const QString &message)
static void logHandler(QtMsgType type, const QMessageLogContext& context,
const QString& message)
{
if (!g_File.isOpen())
return;
g_File.write(qUtf8Printable(QString("[%1] %2\r\n").arg(QDateTime::currentDateTime().toString()).arg(message)));
g_File.write(qUtf8Printable(QString("[%1] %2\r\n")
.arg(QDateTime::currentDateTime().toString())
.arg(message)));
}
void LoggerInit(const QString &fileName)
void LoggerInit(const QString& fileName)
{
if (g_File.isOpen())
g_File.close();
@@ -43,4 +47,4 @@ void LoggerDeinit()
qInstallMessageHandler(NULL);
}
}; // namespace NxmHandler
}; // namespace NxmHandler
+4 -3
View File
@@ -3,11 +3,12 @@
#include <QString>
namespace NxmHandler {
namespace NxmHandler
{
void LoggerInit(const QString &fileName);
void LoggerInit(const QString& fileName);
void LoggerDeinit();
}; //namespace NxmHandler
}; // namespace NxmHandler
#endif
+313 -294
View File
File diff suppressed because it is too large Load Diff