summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSandro Jäckel <sandro.jaeckel@gmail.com>2018-02-23 01:45:58 +0100
committerSandro Jäckel <sandro.jaeckel@gmail.com>2018-02-23 01:45:58 +0100
commitea6292168a6acd4c263913f0ccd7dd64daf4f5cf (patch)
tree312024abbd7c3c100274f3a8031d49096480b654 /src
parent5e5c9c07291f6b09623d31c92b1fb61c4ede576e (diff)
Revert "Applied clang-format on source"
This reverts commit 5e5c9c07291f6b09623d31c92b1fb61c4ede576e.
Diffstat (limited to 'src')
-rw-r--r--src/aboutdialog.cpp89
-rw-r--r--src/aboutdialog.h44
-rw-r--r--src/activatemodsdialog.cpp91
-rw-r--r--src/activatemodsdialog.h54
-rw-r--r--src/bbcode.cpp401
-rw-r--r--src/bbcode.h7
-rw-r--r--src/browserdialog.cpp364
-rw-r--r--src/browserdialog.h106
-rw-r--r--src/browserview.cpp77
-rw-r--r--src/browserview.h61
-rw-r--r--src/categories.cpp514
-rw-r--r--src/categories.h272
-rw-r--r--src/categoriesdialog.cpp306
-rw-r--r--src/categoriesdialog.h46
-rw-r--r--src/credentialsdialog.cpp32
-rw-r--r--src/credentialsdialog.h21
-rw-r--r--src/csvbuilder.cpp331
-rw-r--r--src/csvbuilder.h99
-rw-r--r--src/descriptionpage.h14
-rw-r--r--src/directoryrefresher.cpp197
-rw-r--r--src/directoryrefresher.h184
-rw-r--r--src/downloadlist.cpp123
-rw-r--r--src/downloadlist.h86
-rw-r--r--src/downloadlistsortproxy.cpp71
-rw-r--r--src/downloadlistsortproxy.h27
-rw-r--r--src/downloadlistwidget.cpp480
-rw-r--r--src/downloadlistwidget.h101
-rw-r--r--src/downloadlistwidgetcompact.cpp451
-rw-r--r--src/downloadlistwidgetcompact.h112
-rw-r--r--src/downloadmanager.cpp2205
-rw-r--r--src/downloadmanager.h751
-rw-r--r--src/editexecutablesdialog.cpp449
-rw-r--r--src/editexecutablesdialog.h85
-rw-r--r--src/eventfilter.cpp14
-rw-r--r--src/eventfilter.h16
-rw-r--r--src/executableslist.cpp251
-rw-r--r--src/executableslist.h247
-rw-r--r--src/filedialogmemory.cpp104
-rw-r--r--src/filedialogmemory.h37
-rw-r--r--src/gameinfoimpl.cpp47
-rw-r--r--src/genericicondelegate.cpp44
-rw-r--r--src/genericicondelegate.h45
-rw-r--r--src/helper.cpp90
-rw-r--r--src/helper.h13
-rw-r--r--src/icondelegate.cpp61
-rw-r--r--src/icondelegate.h22
-rw-r--r--src/ilockedwaitingforprocess.h7
-rw-r--r--src/installationmanager.cpp1256
-rw-r--r--src/installationmanager.h273
-rw-r--r--src/instancemanager.cpp400
-rw-r--r--src/instancemanager.h46
-rw-r--r--src/iuserinterface.h35
-rw-r--r--src/json.cpp799
-rw-r--r--src/json.h105
-rw-r--r--src/loadmechanism.cpp436
-rw-r--r--src/loadmechanism.h111
-rw-r--r--src/lockeddialog.cpp58
-rw-r--r--src/lockeddialog.h21
-rw-r--r--src/lockeddialogbase.cpp63
-rw-r--r--src/lockeddialogbase.h32
-rw-r--r--src/logbuffer.cpp329
-rw-r--r--src/logbuffer.h76
-rw-r--r--src/loghighlighter.cpp45
-rw-r--r--src/loghighlighter.h9
-rw-r--r--src/main.cpp1000
-rw-r--r--src/mainwindow.cpp7474
-rw-r--r--src/mainwindow.h685
-rw-r--r--src/messagedialog.cpp107
-rw-r--r--src/messagedialog.h46
-rw-r--r--src/moapplication.cpp169
-rw-r--r--src/moapplication.h19
-rw-r--r--src/modeltest.cpp494
-rw-r--r--src/modeltest.h62
-rw-r--r--src/modflagicondelegate.cpp142
-rw-r--r--src/modflagicondelegate.h17
-rw-r--r--src/modinfo.cpp498
-rw-r--r--src/modinfo.h947
-rw-r--r--src/modinfobackup.cpp22
-rw-r--r--src/modinfobackup.h47
-rw-r--r--src/modinfodialog.cpp1780
-rw-r--r--src/modinfodialog.h287
-rw-r--r--src/modinfoforeign.cpp76
-rw-r--r--src/modinfoforeign.h100
-rw-r--r--src/modinfooverwrite.cpp73
-rw-r--r--src/modinfooverwrite.h82
-rw-r--r--src/modinforegular.cpp838
-rw-r--r--src/modinforegular.h530
-rw-r--r--src/modinfowithconflictinfo.cpp176
-rw-r--r--src/modinfowithconflictinfo.h62
-rw-r--r--src/modlist.cpp1867
-rw-r--r--src/modlist.h400
-rw-r--r--src/modlistsortproxy.cpp638
-rw-r--r--src/modlistsortproxy.h134
-rw-r--r--src/modlistview.cpp65
-rw-r--r--src/modlistview.h22
-rw-r--r--src/moshortcut.cpp26
-rw-r--r--src/moshortcut.h23
-rw-r--r--src/motddialog.cpp27
-rw-r--r--src/motddialog.h19
-rw-r--r--src/nexusinterface.cpp885
-rw-r--r--src/nexusinterface.h636
-rw-r--r--src/noeditdelegate.cpp9
-rw-r--r--src/noeditdelegate.h6
-rw-r--r--src/nxmaccessmanager.cpp464
-rw-r--r--src/nxmaccessmanager.h125
-rw-r--r--src/organizercore.cpp3137
-rw-r--r--src/organizercore.h408
-rw-r--r--src/organizerproxy.cpp187
-rw-r--r--src/organizerproxy.h83
-rw-r--r--src/overwriteinfodialog.cpp328
-rw-r--r--src/overwriteinfodialog.h51
-rw-r--r--src/persistentcookiejar.cpp96
-rw-r--r--src/persistentcookiejar.h19
-rw-r--r--src/plugincontainer.cpp498
-rw-r--r--src/plugincontainer.h113
-rw-r--r--src/pluginlist.cpp1824
-rw-r--r--src/pluginlist.h459
-rw-r--r--src/pluginlistsortproxy.cpp137
-rw-r--r--src/pluginlistsortproxy.h44
-rw-r--r--src/pluginlistview.cpp64
-rw-r--r--src/pluginlistview.h22
-rw-r--r--src/previewdialog.cpp66
-rw-r--r--src/previewdialog.h24
-rw-r--r--src/previewgenerator.cpp40
-rw-r--r--src/previewgenerator.h24
-rw-r--r--src/problemsdialog.cpp104
-rw-r--r--src/problemsdialog.h30
-rw-r--r--src/profile.cpp1156
-rw-r--r--src/profile.h487
-rw-r--r--src/profileinputdialog.cpp28
-rw-r--r--src/profileinputdialog.h19
-rw-r--r--src/profilesdialog.cpp446
-rw-r--r--src/profilesdialog.h79
-rw-r--r--src/qtgroupingproxy.cpp1565
-rw-r--r--src/qtgroupingproxy.h213
-rw-r--r--src/queryoverwritedialog.cpp51
-rw-r--r--src/queryoverwritedialog.h37
-rw-r--r--src/savetextasdialog.cpp54
-rw-r--r--src/savetextasdialog.h21
-rw-r--r--src/selectiondialog.cpp105
-rw-r--r--src/selectiondialog.h54
-rw-r--r--src/selfupdater.cpp402
-rw-r--r--src/selfupdater.h130
-rw-r--r--src/serverinfo.h13
-rw-r--r--src/settings.cpp1365
-rw-r--r--src/settings.h702
-rw-r--r--src/settingsdialog.cpp309
-rw-r--r--src/settingsdialog.h53
-rw-r--r--src/shared/appconfig.cpp4
-rw-r--r--src/shared/appconfig.h4
-rw-r--r--src/shared/directoryentry.cpp1312
-rw-r--r--src/shared/directoryentry.h385
-rw-r--r--src/shared/error_report.cpp98
-rw-r--r--src/shared/leaktrace.cpp70
-rw-r--r--src/shared/leaktrace.h7
-rw-r--r--src/shared/stackdata.cpp213
-rw-r--r--src/shared/stackdata.h43
-rw-r--r--src/shared/util.cpp205
-rw-r--r--src/shared/util.h23
-rw-r--r--src/shared/windows_error.cpp35
-rw-r--r--src/shared/windows_error.h14
-rw-r--r--src/singleinstance.cpp125
-rw-r--r--src/singleinstance.h75
-rw-r--r--src/spawn.cpp226
-rw-r--r--src/spawn.h12
-rw-r--r--src/syncoverwritedialog.cpp211
-rw-r--r--src/syncoverwritedialog.h31
-rw-r--r--src/transfersavesdialog.cpp442
-rw-r--r--src/transfersavesdialog.h81
-rw-r--r--src/usvfsconnector.cpp241
-rw-r--r--src/usvfsconnector.h50
-rw-r--r--src/viewmarkingscrollbar.cpp54
-rw-r--r--src/viewmarkingscrollbar.h20
-rw-r--r--src/waitingonclosedialog.cpp57
-rw-r--r--src/waitingonclosedialog.h23
175 files changed, 28624 insertions, 24906 deletions
diff --git a/src/aboutdialog.cpp b/src/aboutdialog.cpp
index e79109ad..ed57a217 100644
--- a/src/aboutdialog.cpp
+++ b/src/aboutdialog.cpp
@@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
+
#include "aboutdialog.h"
#include "ui_aboutdialog.h"
#include <utility.h>
@@ -29,55 +30,65 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QVariant>
#include <Qt>
-AboutDialog::AboutDialog(const QString& version, QWidget* parent) : QDialog(parent), ui(new Ui::AboutDialog) {
- ui->setupUi(this);
- m_LicenseFiles[LICENSE_LGPL3] = "lgpl-3.0.txt";
- m_LicenseFiles[LICENSE_GPL3] = "gpl-3.0.txt";
- m_LicenseFiles[LICENSE_BSD3] = "bsd3.txt";
- m_LicenseFiles[LICENSE_BOOST] = "boost.txt";
- m_LicenseFiles[LICENSE_CCBY3] = "by-sa3.txt";
- m_LicenseFiles[LICENSE_ZLIB] = "zlib.txt";
- m_LicenseFiles[LICENSE_APACHE2] = "apache-license-2.0.txt";
+AboutDialog::AboutDialog(const QString &version, QWidget *parent)
+ : QDialog(parent)
+ , ui(new Ui::AboutDialog)
+{
+ ui->setupUi(this);
+
+ m_LicenseFiles[LICENSE_LGPL3] = "lgpl-3.0.txt";
+ m_LicenseFiles[LICENSE_GPL3] = "gpl-3.0.txt";
+ m_LicenseFiles[LICENSE_BSD3] = "bsd3.txt";
+ m_LicenseFiles[LICENSE_BOOST] = "boost.txt";
+ m_LicenseFiles[LICENSE_CCBY3] = "by-sa3.txt";
+ m_LicenseFiles[LICENSE_ZLIB] = "zlib.txt";
+ m_LicenseFiles[LICENSE_APACHE2] = "apache-license-2.0.txt";
- addLicense("Qt", LICENSE_LGPL3);
- addLicense("Qt Json", LICENSE_GPL3);
- addLicense("Boost Library", LICENSE_BOOST);
- addLicense("7-zip", LICENSE_LGPL3);
- addLicense("ZLib", LICENSE_ZLIB);
- addLicense("Tango Icon Theme", LICENSE_NONE);
- addLicense("RRZE Icon Set", LICENSE_CCBY3);
- addLicense("Icons by Lorc, Delapouite and sbed available on http://game-icons.net", LICENSE_CCBY3);
- addLicense("Castle Core", LICENSE_APACHE2);
- addLicense("LOOT", LICENSE_GPL3);
+ addLicense("Qt", LICENSE_LGPL3);
+ addLicense("Qt Json", LICENSE_GPL3);
+ addLicense("Boost Library", LICENSE_BOOST);
+ addLicense("7-zip", LICENSE_LGPL3);
+ addLicense("ZLib", LICENSE_ZLIB);
+ addLicense("Tango Icon Theme", LICENSE_NONE);
+ addLicense("RRZE Icon Set", LICENSE_CCBY3);
+ addLicense("Icons by Lorc, Delapouite and sbed available on http://game-icons.net", LICENSE_CCBY3);
+ addLicense("Castle Core", LICENSE_APACHE2);
+ addLicense("LOOT", LICENSE_GPL3);
- ui->nameLabel->setText(QString("<span style=\"font-size:12pt; font-weight:600;\">%1 %2</span>")
- .arg(ui->nameLabel->text())
- .arg(version));
+ ui->nameLabel->setText(QString("<span style=\"font-size:12pt; font-weight:600;\">%1 %2</span>").arg(ui->nameLabel->text()).arg(version));
#if defined(HGID)
- ui->revisionLabel->setText(ui->revisionLabel->text() + " " + HGID);
+ ui->revisionLabel->setText(ui->revisionLabel->text() + " " + HGID);
#elif defined(GITID)
- ui->revisionLabel->setText(ui->revisionLabel->text() + " " + GITID);
+ ui->revisionLabel->setText(ui->revisionLabel->text() + " " + GITID);
#else
- ui->revisionLabel->setText(ui->revisionLabel->text() + " unknown");
+ ui->revisionLabel->setText(ui->revisionLabel->text() + " unknown");
#endif
}
-AboutDialog::~AboutDialog() { delete ui; }
-void AboutDialog::addLicense(const QString& name, Licenses license) {
- QListWidgetItem* item = new QListWidgetItem(name);
- item->setData(Qt::UserRole, license);
- ui->creditsList->addItem(item);
+AboutDialog::~AboutDialog()
+{
+ delete ui;
+}
+
+
+void AboutDialog::addLicense(const QString &name, Licenses license)
+{
+ QListWidgetItem *item = new QListWidgetItem(name);
+ item->setData(Qt::UserRole, license);
+ ui->creditsList->addItem(item);
}
-void AboutDialog::on_creditsList_currentItemChanged(QListWidgetItem* current, QListWidgetItem*) {
- auto iter = m_LicenseFiles.find(current->data(Qt::UserRole).toInt());
- if (iter != m_LicenseFiles.end()) {
- QString filePath = qApp->applicationDirPath() + "/license/" + iter->second;
- QString text = MOBase::readFileText(filePath);
- ui->licenseText->setText(text);
- } else {
- ui->licenseText->setText(tr("No license"));
- }
+
+void AboutDialog::on_creditsList_currentItemChanged(QListWidgetItem *current, QListWidgetItem*)
+{
+ auto iter = m_LicenseFiles.find(current->data(Qt::UserRole).toInt());
+ if (iter != m_LicenseFiles.end()) {
+ QString filePath = qApp->applicationDirPath() + "/license/" + iter->second;
+ QString text = MOBase::readFileText(filePath);
+ ui->licenseText->setText(text);
+ } else {
+ ui->licenseText->setText(tr("No license"));
+ }
}
diff --git a/src/aboutdialog.h b/src/aboutdialog.h
index a5c93834..103a0d2f 100644
--- a/src/aboutdialog.h
+++ b/src/aboutdialog.h
@@ -18,6 +18,7 @@ You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
+
#define ABOUTDIALOG_H
#include <QDialog>
@@ -28,38 +29,43 @@ class QListWidgetItem;
#include <map>
namespace Ui {
-class AboutDialog;
+ class AboutDialog;
}
-class AboutDialog : public QDialog {
- Q_OBJECT
+class AboutDialog : public QDialog
+{
+ Q_OBJECT
public:
- explicit AboutDialog(const QString& version, QWidget* parent = 0);
- ~AboutDialog();
+ explicit AboutDialog(const QString &version, QWidget *parent = 0);
+ ~AboutDialog();
private:
- enum Licenses {
- LICENSE_NONE,
- LICENSE_LGPL3,
- LICENSE_GPL3,
- LICENSE_BSD3,
- LICENSE_BOOST,
- LICENSE_CCBY3,
- LICENSE_ZLIB,
- LICENSE_APACHE2
- };
+
+ enum Licenses {
+ LICENSE_NONE,
+ LICENSE_LGPL3,
+ LICENSE_GPL3,
+ LICENSE_BSD3,
+ LICENSE_BOOST,
+ LICENSE_CCBY3,
+ LICENSE_ZLIB,
+ LICENSE_APACHE2
+ };
private:
- void addLicense(const QString& name, Licenses license);
+
+ void addLicense(const QString &name, Licenses license);
private slots:
- void on_creditsList_currentItemChanged(QListWidgetItem* current, QListWidgetItem* previous);
+ void on_creditsList_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous);
private:
- Ui::AboutDialog* ui;
- std::map<int, QString> m_LicenseFiles;
+ Ui::AboutDialog *ui;
+
+ std::map<int, QString> m_LicenseFiles;
+
};
#endif // ABOUTDIALOG_H
diff --git a/src/activatemodsdialog.cpp b/src/activatemodsdialog.cpp
index f17bd286..c7e3dca2 100644
--- a/src/activatemodsdialog.cpp
+++ b/src/activatemodsdialog.cpp
@@ -28,60 +28,69 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QtGlobal>
-ActivateModsDialog::ActivateModsDialog(SaveGameInfo::MissingAssets const& missingAssets, QWidget* parent)
- : TutorableDialog("ActivateMods", parent), ui(new Ui::ActivateModsDialog) {
- ui->setupUi(this);
+ActivateModsDialog::ActivateModsDialog(SaveGameInfo::MissingAssets const &missingAssets, QWidget *parent)
+ : TutorableDialog("ActivateMods", parent), ui(new Ui::ActivateModsDialog)
+{
+ ui->setupUi(this);
- QTableWidget* modsTable = findChild<QTableWidget*>("modsTable");
- QHeaderView* headerView = modsTable->horizontalHeader();
- headerView->setSectionResizeMode(0, QHeaderView::Stretch);
- headerView->setSectionResizeMode(1, QHeaderView::Interactive);
+ QTableWidget *modsTable = findChild<QTableWidget*>("modsTable");
+ QHeaderView *headerView = modsTable->horizontalHeader();
+ headerView->setSectionResizeMode(0, QHeaderView::Stretch);
+ headerView->setSectionResizeMode(1, QHeaderView::Interactive);
- int row = 0;
+ int row = 0;
- modsTable->setRowCount(missingAssets.size());
+ modsTable->setRowCount(missingAssets.size());
- for (SaveGameInfo::MissingAssets::const_iterator espIter = missingAssets.begin(); espIter != missingAssets.end();
- ++espIter, ++row) {
- modsTable->setCellWidget(row, 0, new QLabel(espIter.key()));
- if (espIter->size() == 0) {
- modsTable->setCellWidget(row, 1, new QLabel(tr("not found")));
- } else {
- QComboBox* combo = new QComboBox();
- for (QString const& mod : espIter.value()) {
- combo->addItem(mod);
- }
- modsTable->setCellWidget(row, 1, combo);
- }
+ for (SaveGameInfo::MissingAssets::const_iterator espIter = missingAssets.begin();
+ espIter != missingAssets.end(); ++espIter, ++row) {
+ modsTable->setCellWidget(row, 0, new QLabel(espIter.key()));
+ if (espIter->size() == 0) {
+ modsTable->setCellWidget(row, 1, new QLabel(tr("not found")));
+ } else {
+ QComboBox* combo = new QComboBox();
+ for (QString const &mod : espIter.value()) {
+ combo->addItem(mod);
+ }
+ modsTable->setCellWidget(row, 1, combo);
}
+ }
}
-ActivateModsDialog::~ActivateModsDialog() { delete ui; }
-std::set<QString> ActivateModsDialog::getModsToActivate() {
- std::set<QString> result;
- QTableWidget* modsTable = findChild<QTableWidget*>("modsTable");
+ActivateModsDialog::~ActivateModsDialog()
+{
+ delete ui;
+}
+
- for (int row = 0; row < modsTable->rowCount(); ++row) {
- QComboBox* comboBox = dynamic_cast<QComboBox*>(modsTable->cellWidget(row, 1));
- if (comboBox != nullptr) {
- result.insert(comboBox->currentText());
- }
+std::set<QString> ActivateModsDialog::getModsToActivate()
+{
+ std::set<QString> result;
+ QTableWidget *modsTable = findChild<QTableWidget*>("modsTable");
+
+ for (int row = 0; row < modsTable->rowCount(); ++row) {
+ QComboBox *comboBox = dynamic_cast<QComboBox*>(modsTable->cellWidget(row, 1));
+ if (comboBox != nullptr) {
+ result.insert(comboBox->currentText());
}
- return result;
+ }
+ return result;
}
-std::set<QString> ActivateModsDialog::getESPsToActivate() {
- std::set<QString> result;
- QTableWidget* modsTable = findChild<QTableWidget*>("modsTable");
- for (int row = 0; row < modsTable->rowCount(); ++row) {
- QComboBox* comboBox = dynamic_cast<QComboBox*>(modsTable->cellWidget(row, 1));
- if (comboBox != nullptr) {
- QLabel* espName = dynamic_cast<QLabel*>(modsTable->cellWidget(row, 0));
+std::set<QString> ActivateModsDialog::getESPsToActivate()
+{
+ std::set<QString> result;
+ QTableWidget *modsTable = findChild<QTableWidget*>("modsTable");
+
+ for (int row = 0; row < modsTable->rowCount(); ++row) {
+ QComboBox *comboBox = dynamic_cast<QComboBox*>(modsTable->cellWidget(row, 1));
+ if (comboBox != nullptr) {
+ QLabel *espName = dynamic_cast<QLabel*>(modsTable->cellWidget(row, 0));
- result.insert(espName->text());
- }
+ result.insert(espName->text());
}
- return result;
+ }
+ return result;
}
diff --git a/src/activatemodsdialog.h b/src/activatemodsdialog.h
index b4702da3..f36b5fde 100644
--- a/src/activatemodsdialog.h
+++ b/src/activatemodsdialog.h
@@ -31,46 +31,46 @@ class QWidget;
#include <set>
namespace Ui {
-class ActivateModsDialog;
+ class ActivateModsDialog;
}
/**
* @brief Dialog that is used to batch activate/deactivate mods and plugins
**/
-class ActivateModsDialog : public MOBase::TutorableDialog {
- Q_OBJECT
+class ActivateModsDialog : public MOBase::TutorableDialog
+{
+ Q_OBJECT
public:
- /**
- * @brief constructor
- *
- * @param missingPlugins a map containing missing plugins that need to be activated
- * @param parent ... Defaults to 0.
- **/
- explicit ActivateModsDialog(SaveGameInfo::MissingAssets const& missingAssets, QWidget* parent = 0);
- ~ActivateModsDialog();
+ /**
+ * @brief constructor
+ *
+ * @param missingPlugins a map containing missing plugins that need to be activated
+ * @param parent ... Defaults to 0.
+ **/
+ explicit ActivateModsDialog(SaveGameInfo::MissingAssets const &missingAssets, QWidget *parent = 0);
+ ~ActivateModsDialog();
- /**
- * @brief get a list of mods that the user chose to activate
- *
- * @note This can of ocurse only be called after the dialog has been displayed
- *
- * @return set< QString > the mods to activate
- **/
- std::set<QString> getModsToActivate();
+ /**
+ * @brief get a list of mods that the user chose to activate
+ *
+ * @note This can of ocurse only be called after the dialog has been displayed
+ *
+ * @return set< QString > the mods to activate
+ **/
+ std::set<QString> getModsToActivate();
- /**
- * @brief get a list of plugins that should be activated
- *
- * @return set< QString > the plugins to activate. This contains only plugins that become available after enabling
- *the mods retrieved with getModsToActivate
- **/
- std::set<QString> getESPsToActivate();
+ /**
+ * @brief get a list of plugins that should be activated
+ *
+ * @return set< QString > the plugins to activate. This contains only plugins that become available after enabling the mods retrieved with getModsToActivate
+ **/
+ std::set<QString> getESPsToActivate();
private slots:
private:
- Ui::ActivateModsDialog* ui;
+ Ui::ActivateModsDialog *ui;
};
#endif // ACTIVATEMODSDIALOG_H
diff --git a/src/bbcode.cpp b/src/bbcode.cpp
index 3e709376..56369538 100644
--- a/src/bbcode.cpp
+++ b/src/bbcode.cpp
@@ -22,222 +22,251 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QRegExp>
#include <map>
+
namespace BBCode {
+
class BBCodeMap {
- typedef std::map<QString, std::pair<QRegExp, QString>> TagMap;
+ typedef std::map<QString, std::pair<QRegExp, QString> > TagMap;
public:
- static BBCodeMap& instance() {
- static BBCodeMap s_Instance;
- return s_Instance;
- }
- QString convertTag(QString input, int& length) {
- // extract the tag name
- m_TagNameExp.indexIn(input, 1, QRegExp::CaretAtOffset);
- QString tagName = m_TagNameExp.cap(0).toLower();
- TagMap::iterator tagIter = m_TagMap.find(tagName);
- if (tagIter != m_TagMap.end()) {
- // recognized tag
- if (tagName.endsWith('=')) {
- tagName.chop(1);
- }
+ static BBCodeMap &instance() {
+ static BBCodeMap s_Instance;
+ return s_Instance;
+ }
- int closeTagPos = 0;
- int closeTagLength = 0;
- if (tagName == "*") {
- // ends at the next bullet point
- closeTagPos = input.indexOf(QRegExp("(\\[\\*\\]|</ul>)", Qt::CaseInsensitive), 3);
- // leave closeTagLength at 0 because we don't want to "eat" the next bullet point
- } else if (tagName == "line") {
- // ends immediately after the tag
- closeTagPos = 6;
- // leave closeTagLength at 0 because there is no close tag to skip over
- } else {
- QString closeTag = QString("[/%1]").arg(tagName);
- closeTagPos = input.indexOf(closeTag, 0, Qt::CaseInsensitive);
- if (closeTagPos == -1) {
- // workaround to improve compatibility: add fake closing tag
- input.append(closeTag);
- closeTagPos = input.size() - closeTag.size();
- }
- closeTagLength = closeTag.size();
- }
+ QString convertTag(QString input, int &length)
+ {
+ // extract the tag name
+ m_TagNameExp.indexIn(input, 1, QRegExp::CaretAtOffset);
+ QString tagName = m_TagNameExp.cap(0).toLower();
+ TagMap::iterator tagIter = m_TagMap.find(tagName);
+ if (tagIter != m_TagMap.end()) {
+ // recognized tag
+ if (tagName.endsWith('=')) {
+ tagName.chop(1);
+ }
+
+ int closeTagPos = 0;
+ int closeTagLength = 0;
+ if (tagName == "*") {
+ // ends at the next bullet point
+ closeTagPos = input.indexOf(QRegExp("(\\[\\*\\]|</ul>)", Qt::CaseInsensitive), 3);
+ // leave closeTagLength at 0 because we don't want to "eat" the next bullet point
+ } else if (tagName == "line") {
+ // ends immediately after the tag
+ closeTagPos = 6;
+ // leave closeTagLength at 0 because there is no close tag to skip over
+ } else {
+ QString closeTag = QString("[/%1]").arg(tagName);
+ closeTagPos = input.indexOf(closeTag, 0, Qt::CaseInsensitive);
+ if (closeTagPos == -1) {
+ // workaround to improve compatibility: add fake closing tag
+ input.append(closeTag);
+ closeTagPos = input.size() - closeTag.size();
+ }
+ closeTagLength = closeTag.size();
+ }
- if (closeTagPos > -1) {
- length = closeTagPos + closeTagLength;
- QString temp = input.mid(0, length);
- if (tagIter->second.first.indexIn(temp) == 0) {
- if (tagIter->second.second.isEmpty()) {
- if (tagName == "color") {
- QString color = tagIter->second.first.cap(1);
- QString content = tagIter->second.first.cap(2);
- if (color.at(0) == '#') {
- return temp.replace(
- tagIter->second.first,
- QString("<font style=\"color: %1;\">%2</font>").arg(color, content));
- } else {
- auto colIter = m_ColorMap.find(color.toLower());
- if (colIter != m_ColorMap.end()) {
- color = colIter->second;
- }
- return temp.replace(
- tagIter->second.first,
- QString("<font style=\"color: #%1;\">%2</font>").arg(color, content));
- }
- } else {
- qWarning("don't know how to deal with tag %s", qPrintable(tagName));
- }
- } else {
- if (tagName == "*") {
- temp.remove(QRegExp("(\\[/\\*\\])?(<br/>)?$"));
- }
- return temp.replace(tagIter->second.first, tagIter->second.second);
- }
- } else {
- // expression doesn't match. either the input string is invalid
- // or the expression is
- qWarning("%s doesn't match the expression for %s", temp.toUtf8().constData(),
- tagName.toUtf8().constData());
- length = 0;
- return QString();
+ if (closeTagPos > -1) {
+ length = closeTagPos + closeTagLength;
+ QString temp = input.mid(0, length);
+ if (tagIter->second.first.indexIn(temp) == 0) {
+ if (tagIter->second.second.isEmpty()) {
+ if (tagName == "color") {
+ QString color = tagIter->second.first.cap(1);
+ QString content = tagIter->second.first.cap(2);
+ if (color.at(0) == '#') {
+ return temp.replace(tagIter->second.first, QString("<font style=\"color: %1;\">%2</font>").arg(color, content));
+ } else {
+ auto colIter = m_ColorMap.find(color.toLower());
+ if (colIter != m_ColorMap.end()) {
+ color = colIter->second;
}
+ return temp.replace(tagIter->second.first, QString("<font style=\"color: #%1;\">%2</font>").arg(color, content));
+ }
+ } else {
+ qWarning("don't know how to deal with tag %s", qPrintable(tagName));
}
+ } else {
+ if (tagName == "*") {
+ temp.remove(QRegExp("(\\[/\\*\\])?(<br/>)?$"));
+ }
+ return temp.replace(tagIter->second.first, tagIter->second.second);
+ }
+ } else {
+ // expression doesn't match. either the input string is invalid
+ // or the expression is
+ qWarning("%s doesn't match the expression for %s",
+ temp.toUtf8().constData(), tagName.toUtf8().constData());
+ length = 0;
+ return QString();
}
-
- // not a recognized tag or tag invalid
- length = 0;
- return QString();
+ }
}
-private:
- BBCodeMap() : m_TagNameExp("^[a-zA-Z*]*=?") {
- m_TagMap["b"] = std::make_pair(QRegExp("\\[b\\](.*)\\[/b\\]"), "<b>\\1</b>");
- m_TagMap["i"] = std::make_pair(QRegExp("\\[i\\](.*)\\[/i\\]"), "<i>\\1</i>");
- m_TagMap["u"] = std::make_pair(QRegExp("\\[u\\](.*)\\[/u\\]"), "<u>\\1</u>");
- m_TagMap["s"] = std::make_pair(QRegExp("\\[s\\](.*)\\[/s\\]"), "<s>\\1</s>");
- m_TagMap["sub"] = std::make_pair(QRegExp("\\[sub\\](.*)\\[/sub\\]"), "<sub>\\1</sub>");
- m_TagMap["sup"] = std::make_pair(QRegExp("\\[sup\\](.*)\\[/sup\\]"), "<sup>\\1</sup>");
- m_TagMap["size="] =
- std::make_pair(QRegExp("\\[size=([^\\]]*)\\](.*)\\[/size\\]"), "<font size=\"\\1\">\\2</font>");
- m_TagMap["color="] = std::make_pair(QRegExp("\\[color=([^\\]]*)\\](.*)\\[/color\\]"), "");
- m_TagMap["font="] = std::make_pair(QRegExp("\\[font=([^\\]]*)\\](.*)\\[/font\\]"),
- "<font style=\"font-family: \\1;\">\\2</font>");
- m_TagMap["center"] =
- std::make_pair(QRegExp("\\[center\\](.*)\\[/center\\]"), "<div align=\"center\">\\1</div>");
- m_TagMap["quote"] = std::make_pair(QRegExp("\\[quote\\](.*)\\[/quote\\]"), "<blockquote>\"\\1\"</blockquote>");
- m_TagMap["quote="] = std::make_pair(QRegExp("\\[quote=([^\\]]*)\\](.*)\\[/quote\\]"),
- "<blockquote>\"\\2\"<br/><span>--\\1</span></blockquote></p>");
- m_TagMap["code"] = std::make_pair(QRegExp("\\[code\\](.*)\\[/code\\]"), "<pre>\\1</pre>");
- m_TagMap["heading"] =
- std::make_pair(QRegExp("\\[heading\\](.*)\\[/heading\\]"), "<h2><strong>\\1</strong></h2>");
- m_TagMap["line"] = std::make_pair(QRegExp("\\[line\\]"), "<hr>");
+ // not a recognized tag or tag invalid
+ length = 0;
+ return QString();
+ }
- // lists
- m_TagMap["list"] = std::make_pair(QRegExp("\\[list\\](.*)\\[/list\\]"), "<ul>\\1</ul>");
- m_TagMap["list="] = std::make_pair(QRegExp("\\[list.*\\](.*)\\[/list\\]"), "<ol>\\1</ol>");
- m_TagMap["ul"] = std::make_pair(QRegExp("\\[ul\\](.*)\\[/ul\\]"), "<ul>\\1</ul>");
- m_TagMap["ol"] = std::make_pair(QRegExp("\\[ol\\](.*)\\[/ol\\]"), "<ol>\\1</ol>");
- m_TagMap["li"] = std::make_pair(QRegExp("\\[li\\](.*)\\[/li\\]"), "<li>\\1</li>");
+private:
+ BBCodeMap()
+ : m_TagNameExp("^[a-zA-Z*]*=?")
+ {
+ m_TagMap["b"] = std::make_pair(QRegExp("\\[b\\](.*)\\[/b\\]"),
+ "<b>\\1</b>");
+ m_TagMap["i"] = std::make_pair(QRegExp("\\[i\\](.*)\\[/i\\]"),
+ "<i>\\1</i>");
+ m_TagMap["u"] = std::make_pair(QRegExp("\\[u\\](.*)\\[/u\\]"),
+ "<u>\\1</u>");
+ m_TagMap["s"] = std::make_pair(QRegExp("\\[s\\](.*)\\[/s\\]"),
+ "<s>\\1</s>");
+ m_TagMap["sub"] = std::make_pair(QRegExp("\\[sub\\](.*)\\[/sub\\]"),
+ "<sub>\\1</sub>");
+ m_TagMap["sup"] = std::make_pair(QRegExp("\\[sup\\](.*)\\[/sup\\]"),
+ "<sup>\\1</sup>");
+ m_TagMap["size="] = std::make_pair(QRegExp("\\[size=([^\\]]*)\\](.*)\\[/size\\]"),
+ "<font size=\"\\1\">\\2</font>");
+ m_TagMap["color="] = std::make_pair(QRegExp("\\[color=([^\\]]*)\\](.*)\\[/color\\]"),
+ "");
+ m_TagMap["font="] = std::make_pair(QRegExp("\\[font=([^\\]]*)\\](.*)\\[/font\\]"),
+ "<font style=\"font-family: \\1;\">\\2</font>");
+ m_TagMap["center"] = std::make_pair(QRegExp("\\[center\\](.*)\\[/center\\]"),
+ "<div align=\"center\">\\1</div>");
+ m_TagMap["quote"] = std::make_pair(QRegExp("\\[quote\\](.*)\\[/quote\\]"),
+ "<blockquote>\"\\1\"</blockquote>");
+ m_TagMap["quote="] = std::make_pair(QRegExp("\\[quote=([^\\]]*)\\](.*)\\[/quote\\]"),
+ "<blockquote>\"\\2\"<br/><span>--\\1</span></blockquote></p>");
+ m_TagMap["code"] = std::make_pair(QRegExp("\\[code\\](.*)\\[/code\\]"),
+ "<pre>\\1</pre>");
+ m_TagMap["heading"]= std::make_pair(QRegExp("\\[heading\\](.*)\\[/heading\\]"),
+ "<h2><strong>\\1</strong></h2>");
+ m_TagMap["line"] = std::make_pair(QRegExp("\\[line\\]"),
+ "<hr>");
- // tables
- m_TagMap["table"] = std::make_pair(QRegExp("\\[table\\](.*)\\[/table\\]"), "<table>\\1</table>");
- m_TagMap["tr"] = std::make_pair(QRegExp("\\[tr\\](.*)\\[/tr\\]"), "<tr>\\1</tr>");
- m_TagMap["th"] = std::make_pair(QRegExp("\\[th\\](.*)\\[/th\\]"), "<th>\\1</th>");
- m_TagMap["td"] = std::make_pair(QRegExp("\\[td\\](.*)\\[/td\\]"), "<td>\\1</td>");
+ // lists
+ m_TagMap["list"] = std::make_pair(QRegExp("\\[list\\](.*)\\[/list\\]"),
+ "<ul>\\1</ul>");
+ m_TagMap["list="] = std::make_pair(QRegExp("\\[list.*\\](.*)\\[/list\\]"),
+ "<ol>\\1</ol>");
+ m_TagMap["ul"] = std::make_pair(QRegExp("\\[ul\\](.*)\\[/ul\\]"),
+ "<ul>\\1</ul>");
+ m_TagMap["ol"] = std::make_pair(QRegExp("\\[ol\\](.*)\\[/ol\\]"),
+ "<ol>\\1</ol>");
+ m_TagMap["li"] = std::make_pair(QRegExp("\\[li\\](.*)\\[/li\\]"),
+ "<li>\\1</li>");
- // web content
- m_TagMap["url"] = std::make_pair(QRegExp("\\[url\\](.*)\\[/url\\]"), "<a href=\"\\1\">\\1</a>");
- m_TagMap["url="] = std::make_pair(QRegExp("\\[url=([^\\]]*)\\](.*)\\[/url\\]"), "<a href=\"\\1\">\\2</a>");
- m_TagMap["img"] = std::make_pair(QRegExp("\\[img\\](.*)\\[/img\\]"), "<img src=\"\\1\">");
- m_TagMap["img="] =
- std::make_pair(QRegExp("\\[img=([^\\]]*)\\](.*)\\[/img\\]"), "<img src=\"\\2\" alt=\"\\1\">");
- m_TagMap["email="] =
- std::make_pair(QRegExp("\\[email=\"?([^\\]]*)\"?\\](.*)\\[/email\\]"), "<a href=\"mailto:\\1\">\\2</a>");
- m_TagMap["youtube"] =
- std::make_pair(QRegExp("\\[youtube\\](.*)\\[/youtube\\]"),
- "<a href=\"http://www.youtube.com/v/\\1\">http://www.youtube.com/v/\\1</a>");
+ // tables
+ m_TagMap["table"] = std::make_pair(QRegExp("\\[table\\](.*)\\[/table\\]"),
+ "<table>\\1</table>");
+ m_TagMap["tr"] = std::make_pair(QRegExp("\\[tr\\](.*)\\[/tr\\]"),
+ "<tr>\\1</tr>");
+ m_TagMap["th"] = std::make_pair(QRegExp("\\[th\\](.*)\\[/th\\]"),
+ "<th>\\1</th>");
+ m_TagMap["td"] = std::make_pair(QRegExp("\\[td\\](.*)\\[/td\\]"),
+ "<td>\\1</td>");
- // make all patterns non-greedy and case-insensitive
- for (TagMap::iterator iter = m_TagMap.begin(); iter != m_TagMap.end(); ++iter) {
- iter->second.first.setCaseSensitivity(Qt::CaseInsensitive);
- iter->second.first.setMinimal(true);
- }
+ // web content
+ m_TagMap["url"] = std::make_pair(QRegExp("\\[url\\](.*)\\[/url\\]"),
+ "<a href=\"\\1\">\\1</a>");
+ m_TagMap["url="] = std::make_pair(QRegExp("\\[url=([^\\]]*)\\](.*)\\[/url\\]"),
+ "<a href=\"\\1\">\\2</a>");
+ m_TagMap["img"] = std::make_pair(QRegExp("\\[img\\](.*)\\[/img\\]"),
+ "<img src=\"\\1\">");
+ m_TagMap["img="] = std::make_pair(QRegExp("\\[img=([^\\]]*)\\](.*)\\[/img\\]"),
+ "<img src=\"\\2\" alt=\"\\1\">");
+ m_TagMap["email="] = std::make_pair(QRegExp("\\[email=\"?([^\\]]*)\"?\\](.*)\\[/email\\]"),
+ "<a href=\"mailto:\\1\">\\2</a>");
+ m_TagMap["youtube"] = std::make_pair(QRegExp("\\[youtube\\](.*)\\[/youtube\\]"),
+ "<a href=\"http://www.youtube.com/v/\\1\">http://www.youtube.com/v/\\1</a>");
- // this tag is in fact greedy
- m_TagMap["*"] = std::make_pair(QRegExp("\\[\\*\\](.*)"), "<li>\\1</li>");
- m_ColorMap.insert(std::make_pair<QString, QString>("red", "FF0000"));
- m_ColorMap.insert(std::make_pair<QString, QString>("green", "00FF00"));
- m_ColorMap.insert(std::make_pair<QString, QString>("blue", "0000FF"));
- m_ColorMap.insert(std::make_pair<QString, QString>("black", "000000"));
- m_ColorMap.insert(std::make_pair<QString, QString>("gray", "7F7F7F"));
- m_ColorMap.insert(std::make_pair<QString, QString>("white", "FFFFFF"));
- m_ColorMap.insert(std::make_pair<QString, QString>("yellow", "FFFF00"));
- m_ColorMap.insert(std::make_pair<QString, QString>("cyan", "00FFFF"));
- m_ColorMap.insert(std::make_pair<QString, QString>("magenta", "FF00FF"));
- m_ColorMap.insert(std::make_pair<QString, QString>("brown", "A52A2A"));
- m_ColorMap.insert(std::make_pair<QString, QString>("orange", "FFA500"));
- m_ColorMap.insert(std::make_pair<QString, QString>("gold", "FFD700"));
- m_ColorMap.insert(std::make_pair<QString, QString>("deepskyblue", "00BFFF"));
- m_ColorMap.insert(std::make_pair<QString, QString>("salmon", "FA8072"));
- m_ColorMap.insert(std::make_pair<QString, QString>("dodgerblue", "1E90FF"));
- m_ColorMap.insert(std::make_pair<QString, QString>("greenyellow", "ADFF2F"));
- m_ColorMap.insert(std::make_pair<QString, QString>("peru", "CD853F"));
+ // make all patterns non-greedy and case-insensitive
+ for (TagMap::iterator iter = m_TagMap.begin(); iter != m_TagMap.end(); ++iter) {
+ iter->second.first.setCaseSensitivity(Qt::CaseInsensitive);
+ iter->second.first.setMinimal(true);
}
+ // this tag is in fact greedy
+ m_TagMap["*"] = std::make_pair(QRegExp("\\[\\*\\](.*)"),
+ "<li>\\1</li>");
+
+ m_ColorMap.insert(std::make_pair<QString, QString>("red", "FF0000"));
+ m_ColorMap.insert(std::make_pair<QString, QString>("green", "00FF00"));
+ m_ColorMap.insert(std::make_pair<QString, QString>("blue", "0000FF"));
+ m_ColorMap.insert(std::make_pair<QString, QString>("black", "000000"));
+ m_ColorMap.insert(std::make_pair<QString, QString>("gray", "7F7F7F"));
+ m_ColorMap.insert(std::make_pair<QString, QString>("white", "FFFFFF"));
+ m_ColorMap.insert(std::make_pair<QString, QString>("yellow", "FFFF00"));
+ m_ColorMap.insert(std::make_pair<QString, QString>("cyan", "00FFFF"));
+ m_ColorMap.insert(std::make_pair<QString, QString>("magenta", "FF00FF"));
+ m_ColorMap.insert(std::make_pair<QString, QString>("brown", "A52A2A"));
+ m_ColorMap.insert(std::make_pair<QString, QString>("orange", "FFA500"));
+ m_ColorMap.insert(std::make_pair<QString, QString>("gold", "FFD700"));
+ m_ColorMap.insert(std::make_pair<QString, QString>("deepskyblue", "00BFFF"));
+ m_ColorMap.insert(std::make_pair<QString, QString>("salmon", "FA8072"));
+ m_ColorMap.insert(std::make_pair<QString, QString>("dodgerblue", "1E90FF"));
+ m_ColorMap.insert(std::make_pair<QString, QString>("greenyellow", "ADFF2F"));
+ m_ColorMap.insert(std::make_pair<QString, QString>("peru", "CD853F"));
+ }
+
private:
- QRegExp m_TagNameExp;
- TagMap m_TagMap;
- std::map<QString, QString> m_ColorMap;
+
+ QRegExp m_TagNameExp;
+ TagMap m_TagMap;
+ std::map<QString, QString> m_ColorMap;
};
-QString convertToHTML(const QString& inputParam) {
- // this code goes over the input string once and replaces all bbtags
- // it encounters. This function is called recursively for every replaced
- // string to convert nested tags.
- //
- // This could be implemented simpler by applying a set of regular expressions
- // for each recognized bb-tag one after the other but that would probably be
- // very inefficient (O(n^2)).
- QString input = inputParam.mid(0).replace("\r\n", "<br/>");
- input.replace("\\\"", "\"").replace("\\'", "'");
- QString result;
- int lastBlock = 0;
- int pos = 0;
+QString convertToHTML(const QString &inputParam)
+{
+ // this code goes over the input string once and replaces all bbtags
+ // it encounters. This function is called recursively for every replaced
+ // string to convert nested tags.
+ //
+ // This could be implemented simpler by applying a set of regular expressions
+ // for each recognized bb-tag one after the other but that would probably be
+ // very inefficient (O(n^2)).
- // iterate over the input buffer
- while ((pos = input.indexOf('[', lastBlock)) != -1) {
- // append everything between the previous tag-block and the current one
- result.append(input.midRef(lastBlock, pos - lastBlock));
+ QString input = inputParam.mid(0).replace("\r\n", "<br/>");
+ input.replace("\\\"", "\"").replace("\\'", "'");
+ QString result;
+ int lastBlock = 0;
+ int pos = 0;
- if ((pos < (input.size() - 1)) && (input.at(pos + 1) == '/')) {
- // skip invalid end tag
- int tagEnd = input.indexOf(']', pos) + 1;
- pos = tagEnd;
- } else {
- // convert the tag and content if necessary
- int length = -1;
- QString replacement = BBCodeMap::instance().convertTag(input.mid(pos), length);
- if (length != 0) {
- result.append(convertToHTML(replacement));
- // length contains the number of characters in the original tag
- pos += length;
- } else {
- // nothing replaced
- result.append('[');
- ++pos;
- }
- }
- lastBlock = pos;
+ // iterate over the input buffer
+ while ((pos = input.indexOf('[', lastBlock)) != -1) {
+ // append everything between the previous tag-block and the current one
+ result.append(input.midRef(lastBlock, pos - lastBlock));
+
+ if ((pos < (input.size() - 1)) && (input.at(pos + 1) == '/')) {
+ // skip invalid end tag
+ int tagEnd = input.indexOf(']', pos) + 1;
+ pos = tagEnd;
+ } else {
+ // convert the tag and content if necessary
+ int length = -1;
+ QString replacement = BBCodeMap::instance().convertTag(input.mid(pos), length);
+ if (length != 0) {
+ result.append(convertToHTML(replacement));
+ // length contains the number of characters in the original tag
+ pos += length;
+ } else {
+ // nothing replaced
+ result.append('[');
+ ++pos;
+ }
}
+ lastBlock = pos;
+ }
- // append the remainder (everything after the last tag)
- result.append(input.midRef(lastBlock));
- return result;
+ // append the remainder (everything after the last tag)
+ result.append(input.midRef(lastBlock));
+ return result;
}
} // namespace BBCode
+
diff --git a/src/bbcode.h b/src/bbcode.h
index d8a10337..708dfe71 100644
--- a/src/bbcode.h
+++ b/src/bbcode.h
@@ -20,8 +20,10 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef BBCODE_H
#define BBCODE_H
+
#include <QString>
+
namespace BBCode {
/**
@@ -30,8 +32,9 @@ namespace BBCode {
* @param replaceOccured if not nullptr, this parameter will be set to true if any bb tags were replaced
* @return the same string in html representation
**/
-QString convertToHTML(const QString& input);
+QString convertToHTML(const QString &input);
+
+}
-} // namespace BBCode
#endif // BBCODE_H
diff --git a/src/browserdialog.cpp b/src/browserdialog.cpp
index d5a43332..c2c65acc 100644
--- a/src/browserdialog.cpp
+++ b/src/browserdialog.cpp
@@ -19,228 +19,276 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "browserdialog.h"
+#include "ui_browserdialog.h"
#include "browserview.h"
#include "messagedialog.h"
-#include "persistentcookiejar.h"
#include "report.h"
-#include "ui_browserdialog.h"
+#include "persistentcookiejar.h"
-#include "settings.h"
#include <utility.h>
+#include "settings.h"
-#include <QDesktopWidget>
-#include <QDir>
-#include <QInputDialog>
-#include <QKeyEvent>
-#include <QMenu>
-#include <QNetworkCookie>
+#include <QWebEngineSettings>
#include <QNetworkCookieJar>
+#include <QNetworkCookie>
+#include <QMenu>
+#include <QInputDialog>
#include <QWebEngineHistory>
-#include <QWebEngineSettings>
+#include <QDir>
+#include <QDesktopWidget>
+#include <QKeyEvent>
+
-BrowserDialog::BrowserDialog(QWidget* parent)
- : QDialog(parent), ui(new Ui::BrowserDialog), m_AccessManager(new QNetworkAccessManager(this)) {
- ui->setupUi(this);
- m_AccessManager->setCookieJar(
- new PersistentCookieJar(QDir::fromNativeSeparators(Settings::instance().getCacheDirectory() + "/cookies.dat")));
+BrowserDialog::BrowserDialog(QWidget *parent)
+ : QDialog(parent)
+ , ui(new Ui::BrowserDialog)
+ , m_AccessManager(new QNetworkAccessManager(this))
+{
+ ui->setupUi(this);
- Qt::WindowFlags flags = windowFlags() | Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint;
- Qt::WindowFlags helpFlag = Qt::WindowContextHelpButtonHint;
- flags = flags & (~helpFlag);
- setWindowFlags(flags);
+ m_AccessManager->setCookieJar(new PersistentCookieJar(
+ QDir::fromNativeSeparators(Settings::instance().getCacheDirectory() + "/cookies.dat")));
- m_Tabs = this->findChild<QTabWidget*>("browserTabWidget");
+ Qt::WindowFlags flags = windowFlags() | Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint;
+ Qt::WindowFlags helpFlag = Qt::WindowContextHelpButtonHint;
+ flags = flags & (~helpFlag);
+ setWindowFlags(flags);
- installEventFilter(this);
+ m_Tabs = this->findChild<QTabWidget*>("browserTabWidget");
- connect(m_Tabs, SIGNAL(tabCloseRequested(int)), this, SLOT(tabCloseRequested(int)));
+ installEventFilter(this);
- ui->urlEdit->setVisible(false);
+ connect(m_Tabs, SIGNAL(tabCloseRequested(int)), this, SLOT(tabCloseRequested(int)));
+
+ ui->urlEdit->setVisible(false);
}
-BrowserDialog::~BrowserDialog() { delete ui; }
+BrowserDialog::~BrowserDialog()
+{
+ delete ui;
+}
-void BrowserDialog::closeEvent(QCloseEvent* event) {
- // m_AccessManager->showCookies();
- QDialog::closeEvent(event);
+void BrowserDialog::closeEvent(QCloseEvent *event)
+{
+// m_AccessManager->showCookies();
+ QDialog::closeEvent(event);
}
-void BrowserDialog::initTab(BrowserView* newView) {
- // newView->page()->setNetworkAccessManager(m_AccessManager);
- // newView->page()->setForwardUnsupportedContent(true);
+void BrowserDialog::initTab(BrowserView *newView)
+{
+ //newView->page()->setNetworkAccessManager(m_AccessManager);
+ //newView->page()->setForwardUnsupportedContent(true);
+
+ connect(newView, SIGNAL(loadProgress(int)), this, SLOT(progress(int)));
+ connect(newView, SIGNAL(titleChanged(QString)), this, SLOT(titleChanged(QString)));
+ connect(newView, SIGNAL(initTab(BrowserView*)), this, SLOT(initTab(BrowserView*)));
+ connect(newView, SIGNAL(startFind()), this, SLOT(startSearch()));
+ connect(newView, SIGNAL(urlChanged(QUrl)), this, SLOT(urlChanged(QUrl)));
+ connect(newView, SIGNAL(openUrlInNewTab(QUrl)), this, SLOT(openInNewTab(QUrl)));
+ connect(newView, SIGNAL(downloadRequested(QNetworkRequest)), this, SLOT(downloadRequested(QNetworkRequest)));
+ connect(newView, SIGNAL(unsupportedContent(QNetworkReply*)), this, SLOT(unsupportedContent(QNetworkReply*)));
+
+ ui->backBtn->setEnabled(false);
+ ui->fwdBtn->setEnabled(false);
+ m_Tabs->addTab(newView, tr("new"));
+ newView->settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true);
+ newView->settings()->setAttribute(QWebEngineSettings::AutoLoadImages, true);
+}
- connect(newView, SIGNAL(loadProgress(int)), this, SLOT(progress(int)));
- connect(newView, SIGNAL(titleChanged(QString)), this, SLOT(titleChanged(QString)));
- connect(newView, SIGNAL(initTab(BrowserView*)), this, SLOT(initTab(BrowserView*)));
- connect(newView, SIGNAL(startFind()), this, SLOT(startSearch()));
- connect(newView, SIGNAL(urlChanged(QUrl)), this, SLOT(urlChanged(QUrl)));
- connect(newView, SIGNAL(openUrlInNewTab(QUrl)), this, SLOT(openInNewTab(QUrl)));
- connect(newView, SIGNAL(downloadRequested(QNetworkRequest)), this, SLOT(downloadRequested(QNetworkRequest)));
- connect(newView, SIGNAL(unsupportedContent(QNetworkReply*)), this, SLOT(unsupportedContent(QNetworkReply*)));
- ui->backBtn->setEnabled(false);
- ui->fwdBtn->setEnabled(false);
- m_Tabs->addTab(newView, tr("new"));
- newView->settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true);
- newView->settings()->setAttribute(QWebEngineSettings::AutoLoadImages, true);
+void BrowserDialog::openInNewTab(const QUrl &url)
+{
+ BrowserView *newView = new BrowserView(this);
+ initTab(newView);
+ newView->setUrl(url);
}
-void BrowserDialog::openInNewTab(const QUrl& url) {
- BrowserView* newView = new BrowserView(this);
- initTab(newView);
- newView->setUrl(url);
+
+BrowserView *BrowserDialog::getCurrentView()
+{
+ return qobject_cast<BrowserView*>(m_Tabs->currentWidget());
}
-BrowserView* BrowserDialog::getCurrentView() { return qobject_cast<BrowserView*>(m_Tabs->currentWidget()); }
-void BrowserDialog::urlChanged(const QUrl& url) {
- BrowserView* currentView = getCurrentView();
- if (currentView != nullptr) {
- ui->backBtn->setEnabled(currentView->history()->canGoBack());
- ui->fwdBtn->setEnabled(currentView->history()->canGoForward());
- }
- ui->urlEdit->setText(url.toString());
+void BrowserDialog::urlChanged(const QUrl &url)
+{
+ BrowserView *currentView = getCurrentView();
+ if (currentView != nullptr) {
+ ui->backBtn->setEnabled(currentView->history()->canGoBack());
+ ui->fwdBtn->setEnabled(currentView->history()->canGoForward());
+ }
+ ui->urlEdit->setText(url.toString());
}
-void BrowserDialog::openUrl(const QUrl& url) {
- if (isHidden()) {
- show();
- }
- openInNewTab(url);
+
+void BrowserDialog::openUrl(const QUrl &url)
+{
+ if (isHidden()) {
+ show();
+ }
+ openInNewTab(url);
}
-void BrowserDialog::maximizeWidth() {
- int viewportWidth = getCurrentView()->page()->contentsSize().width();
- int frameWidth = width() - viewportWidth;
- int contentWidth = getCurrentView()->page()->contentsSize().width();
+void BrowserDialog::maximizeWidth()
+{
+ int viewportWidth = getCurrentView()->page()->contentsSize ().width();
+ int frameWidth = width() - viewportWidth;
- QDesktopWidget screen;
- int currentScreen = screen.screenNumber(this);
- int screenWidth = screen.screenGeometry(currentScreen).size().width();
+ int contentWidth = getCurrentView()->page()->contentsSize().width();
- int targetWidth = std::min<int>(std::max<int>(viewportWidth, contentWidth) + frameWidth, screenWidth);
- this->resize(targetWidth, height());
+ QDesktopWidget screen;
+ int currentScreen = screen.screenNumber(this);
+ int screenWidth = screen.screenGeometry(currentScreen).size().width();
+
+ int targetWidth = std::min<int>(std::max<int>(viewportWidth, contentWidth) + frameWidth, screenWidth);
+ this->resize(targetWidth, height());
}
-void BrowserDialog::progress(int value) {
- ui->loadProgress->setValue(value);
- if (value == 100) {
- maximizeWidth();
- ui->loadProgress->setVisible(false);
- } else {
- ui->loadProgress->setVisible(true);
- }
+
+void BrowserDialog::progress(int value)
+{
+ ui->loadProgress->setValue(value);
+ if (value == 100) {
+ maximizeWidth();
+ ui->loadProgress->setVisible(false);
+ } else {
+ ui->loadProgress->setVisible(true);
+ }
}
-void BrowserDialog::titleChanged(const QString& title) {
- BrowserView* view = qobject_cast<BrowserView*>(sender());
- for (int i = 0; i < m_Tabs->count(); ++i) {
- if (m_Tabs->widget(i) == view) {
- m_Tabs->setTabText(i, title.mid(0, 15));
- m_Tabs->setTabToolTip(i, title);
- }
+
+void BrowserDialog::titleChanged(const QString &title)
+{
+ BrowserView *view = qobject_cast<BrowserView*>(sender());
+ for (int i = 0; i < m_Tabs->count(); ++i) {
+ if (m_Tabs->widget(i) == view) {
+ m_Tabs->setTabText(i, title.mid(0, 15));
+ m_Tabs->setTabToolTip(i, title);
}
+ }
+}
+
+
+QString BrowserDialog::guessFileName(const QString &url)
+{
+ QRegExp uploadsExp(QString("http://.+/uploads/([^/]+)$"));
+ if (uploadsExp.indexIn(url) != -1) {
+ // these seem to be premium downloads
+ return uploadsExp.cap(1);
+ }
+
+ QRegExp filesExp(QString("http://.+\\?file=([^&]+)"));
+ if (filesExp.indexIn(url) != -1) {
+ // a regular manual download?
+ return filesExp.cap(1);
+ }
+ return "unknown";
}
-QString BrowserDialog::guessFileName(const QString& url) {
- QRegExp uploadsExp(QString("http://.+/uploads/([^/]+)$"));
- if (uploadsExp.indexIn(url) != -1) {
- // these seem to be premium downloads
- return uploadsExp.cap(1);
+void BrowserDialog::unsupportedContent(QNetworkReply *reply)
+{
+ try {
+ QWebEnginePage *page = qobject_cast<QWebEnginePage*>(sender());
+ if (page == nullptr) {
+ qCritical("sender not a page");
+ return;
+ }
+ BrowserView *view = qobject_cast<BrowserView*>(page->view());
+ if (view == nullptr) {
+ qCritical("no view?");
+ return;
}
- QRegExp filesExp(QString("http://.+\\?file=([^&]+)"));
- if (filesExp.indexIn(url) != -1) {
- // a regular manual download?
- return filesExp.cap(1);
+ emit requestDownload(view->url(), reply);
+ } catch (const std::exception &e) {
+ if (isVisible()) {
+ MessageDialog::showMessage(tr("failed to start download"), this);
}
- return "unknown";
+ qCritical("exception downloading unsupported content: %s", e.what());
+ }
}
-void BrowserDialog::unsupportedContent(QNetworkReply* reply) {
- try {
- QWebEnginePage* page = qobject_cast<QWebEnginePage*>(sender());
- if (page == nullptr) {
- qCritical("sender not a page");
- return;
- }
- BrowserView* view = qobject_cast<BrowserView*>(page->view());
- if (view == nullptr) {
- qCritical("no view?");
- return;
- }
- emit requestDownload(view->url(), reply);
- } catch (const std::exception& e) {
- if (isVisible()) {
- MessageDialog::showMessage(tr("failed to start download"), this);
- }
- qCritical("exception downloading unsupported content: %s", e.what());
- }
+void BrowserDialog::downloadRequested(const QNetworkRequest &request)
+{
+ qCritical("download request %s ignored", request.url().toString().toUtf8().constData());
}
-void BrowserDialog::downloadRequested(const QNetworkRequest& request) {
- qCritical("download request %s ignored", request.url().toString().toUtf8().constData());
+
+void BrowserDialog::tabCloseRequested(int index)
+{
+ if (m_Tabs->count() == 1) {
+ this->close();
+ } else {
+ m_Tabs->widget(index)->deleteLater();
+ m_Tabs->removeTab(index);
+ }
}
-void BrowserDialog::tabCloseRequested(int index) {
- if (m_Tabs->count() == 1) {
- this->close();
- } else {
- m_Tabs->widget(index)->deleteLater();
- m_Tabs->removeTab(index);
- }
+void BrowserDialog::on_backBtn_clicked()
+{
+ BrowserView *currentView = getCurrentView();
+ if (currentView != nullptr) {
+ currentView->back();
+ }
}
-void BrowserDialog::on_backBtn_clicked() {
- BrowserView* currentView = getCurrentView();
- if (currentView != nullptr) {
- currentView->back();
- }
+void BrowserDialog::on_fwdBtn_clicked()
+{
+ BrowserView *currentView = getCurrentView();
+ if (currentView != nullptr) {
+ currentView->forward();
+ }
}
-void BrowserDialog::on_fwdBtn_clicked() {
- BrowserView* currentView = getCurrentView();
- if (currentView != nullptr) {
- currentView->forward();
- }
+
+void BrowserDialog::startSearch()
+{
+ ui->searchEdit->setFocus();
}
-void BrowserDialog::startSearch() { ui->searchEdit->setFocus(); }
-void BrowserDialog::on_searchEdit_returnPressed() {
- // BrowserView *currentView = getCurrentView();
- // if (currentView != nullptr) {
- // currentView->findText(ui->searchEdit->text(), QWebEnginePage::FindWrapsAroundDocument);
- // }
+void BrowserDialog::on_searchEdit_returnPressed()
+{
+// BrowserView *currentView = getCurrentView();
+// if (currentView != nullptr) {
+// currentView->findText(ui->searchEdit->text(), QWebEnginePage::FindWrapsAroundDocument);
+// }
}
-void BrowserDialog::on_refreshBtn_clicked() { getCurrentView()->reload(); }
+void BrowserDialog::on_refreshBtn_clicked()
+{
+ getCurrentView()->reload();
+}
-void BrowserDialog::on_browserTabWidget_currentChanged(int index) {
- BrowserView* currentView = qobject_cast<BrowserView*>(ui->browserTabWidget->widget(index));
- if (currentView != nullptr) {
- ui->backBtn->setEnabled(currentView->history()->canGoBack());
- ui->fwdBtn->setEnabled(currentView->history()->canGoForward());
- }
+void BrowserDialog::on_browserTabWidget_currentChanged(int index)
+{
+ BrowserView *currentView = qobject_cast<BrowserView*>(ui->browserTabWidget->widget(index));
+ if (currentView != nullptr) {
+ ui->backBtn->setEnabled(currentView->history()->canGoBack());
+ ui->fwdBtn->setEnabled(currentView->history()->canGoForward());
+ }
}
-void BrowserDialog::on_urlEdit_returnPressed() {
- QWebEngineView* currentView = getCurrentView();
- if (currentView != nullptr) {
- currentView->setUrl(QUrl(ui->urlEdit->text()));
- }
+void BrowserDialog::on_urlEdit_returnPressed()
+{
+ QWebEngineView *currentView = getCurrentView();
+ if (currentView != nullptr) {
+ currentView->setUrl(QUrl(ui->urlEdit->text()));
+ }
}
-bool BrowserDialog::eventFilter(QObject* object, QEvent* event) {
- if (event->type() == QEvent::KeyPress) {
- QKeyEvent* keyEvent = reinterpret_cast<QKeyEvent*>(event);
- if ((keyEvent->modifiers() & Qt::ControlModifier) && (keyEvent->key() == Qt::Key_U)) {
- ui->urlEdit->setVisible(!ui->urlEdit->isVisible());
- return true;
- }
+bool BrowserDialog::eventFilter(QObject *object, QEvent *event)
+{
+ if (event->type() == QEvent::KeyPress) {
+ QKeyEvent *keyEvent = reinterpret_cast<QKeyEvent*>(event);
+ if ((keyEvent->modifiers() & Qt::ControlModifier)
+ && (keyEvent->key() == Qt::Key_U)) {
+ ui->urlEdit->setVisible(!ui->urlEdit->isVisible());
+ return true;
}
- return QDialog::eventFilter(object, event);
+ }
+ return QDialog::eventFilter(object, event);
}
diff --git a/src/browserdialog.h b/src/browserdialog.h
index 6947cc43..354a377b 100644
--- a/src/browserdialog.h
+++ b/src/browserdialog.h
@@ -20,17 +20,18 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef BROWSERDIALOG_H
#define BROWSERDIALOG_H
-#include <QAtomicInt>
#include <QDialog>
-#include <QNetworkReply>
#include <QNetworkRequest>
-#include <QQueue>
-#include <QTabWidget>
+#include <QNetworkReply>
#include <QTimer>
#include <QWebEngineView>
+#include <QQueue>
+#include <QTabWidget>
+#include <QAtomicInt>
+
namespace Ui {
-class BrowserDialog;
+ class BrowserDialog;
}
class BrowserView;
@@ -38,81 +39,88 @@ class BrowserView;
/**
* @brief a dialog containing a webbrowser that is intended to browse the nexus network
**/
-class BrowserDialog : public QDialog {
+class BrowserDialog : public QDialog
+{
Q_OBJECT
public:
- /**
- * @brief constructor
- *
- * @param accessManager the access manager to use for network requests
- * @param parent parent widget
- **/
- explicit BrowserDialog(QWidget* parent = 0);
- ~BrowserDialog();
- /**
- * @brief set the url to open. If automatic login is enabled, the url is opened after login
- *
- * @param url the url to open
- **/
- void openUrl(const QUrl& url);
+ /**
+ * @brief constructor
+ *
+ * @param accessManager the access manager to use for network requests
+ * @param parent parent widget
+ **/
+ explicit BrowserDialog(QWidget *parent = 0);
+ ~BrowserDialog();
+
+ /**
+ * @brief set the url to open. If automatic login is enabled, the url is opened after login
+ *
+ * @param url the url to open
+ **/
+ void openUrl(const QUrl &url);
- virtual bool eventFilter(QObject* object, QEvent* event);
+ virtual bool eventFilter(QObject *object, QEvent *event);
signals:
- /**
- * @brief emitted when the user starts a download
- * @param pageUrl url of the current web site from which the download was started
- * @param reply network reply of the started download
- */
- void requestDownload(const QUrl& pageUrl, QNetworkReply* reply);
+ /**
+ * @brief emitted when the user starts a download
+ * @param pageUrl url of the current web site from which the download was started
+ * @param reply network reply of the started download
+ */
+ void requestDownload(const QUrl &pageUrl, QNetworkReply *reply);
protected:
- virtual void closeEvent(QCloseEvent*);
+
+ virtual void closeEvent(QCloseEvent *);
private slots:
- void initTab(BrowserView* newView);
- void openInNewTab(const QUrl& url);
+ void initTab(BrowserView *newView);
+ void openInNewTab(const QUrl &url);
- void progress(int value);
+ void progress(int value);
- void titleChanged(const QString& title);
- void unsupportedContent(QNetworkReply* reply);
- void downloadRequested(const QNetworkRequest& request);
+ void titleChanged(const QString &title);
+ void unsupportedContent(QNetworkReply *reply);
+ void downloadRequested(const QNetworkRequest &request);
- void tabCloseRequested(int index);
+ void tabCloseRequested(int index);
- void urlChanged(const QUrl& url);
+ void urlChanged(const QUrl &url);
- void on_backBtn_clicked();
+ void on_backBtn_clicked();
- void on_fwdBtn_clicked();
+ void on_fwdBtn_clicked();
- void on_searchEdit_returnPressed();
+ void on_searchEdit_returnPressed();
- void startSearch();
+ void startSearch();
- void on_refreshBtn_clicked();
+ void on_refreshBtn_clicked();
- void on_browserTabWidget_currentChanged(int index);
+ void on_browserTabWidget_currentChanged(int index);
- void on_urlEdit_returnPressed();
+ void on_urlEdit_returnPressed();
private:
- QString guessFileName(const QString& url);
- BrowserView* getCurrentView();
+ QString guessFileName(const QString &url);
+
+ BrowserView *getCurrentView();
- void maximizeWidth();
+ void maximizeWidth();
private:
- Ui::BrowserDialog* ui;
- QNetworkAccessManager* m_AccessManager;
+ Ui::BrowserDialog *ui;
+
+ QNetworkAccessManager *m_AccessManager;
+
+ QTabWidget *m_Tabs;
+
- QTabWidget* m_Tabs;
};
#endif // BROWSERDIALOG_H
diff --git a/src/browserview.cpp b/src/browserview.cpp
index a44792b2..0b871e23 100644
--- a/src/browserview.cpp
+++ b/src/browserview.cpp
@@ -19,53 +19,58 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "browserview.h"
-#include "utility.h"
#include <QEvent>
#include <QKeyEvent>
-#include <QMenu>
#include <QNetworkDiskCache>
#include <QWebEngineContextMenuData>
#include <QWebEngineSettings>
+#include <QMenu>
#include <Shlwapi.h>
+#include "utility.h"
+
-BrowserView::BrowserView(QWidget* parent) : QWebEngineView(parent) {
- installEventFilter(this);
+BrowserView::BrowserView(QWidget *parent)
+ : QWebEngineView(parent)
+{
+ installEventFilter(this);
- // page()->settings()->setMaximumPagesInCache(10);
+ //page()->settings()->setMaximumPagesInCache(10);
}
-QWebEngineView* BrowserView::createWindow(QWebEnginePage::WebWindowType) {
- BrowserView* newView = new BrowserView(parentWidget());
- emit initTab(newView);
- return newView;
+QWebEngineView *BrowserView::createWindow(QWebEnginePage::WebWindowType)
+{
+ BrowserView *newView = new BrowserView(parentWidget());
+ emit initTab(newView);
+ return newView;
}
-bool BrowserView::eventFilter(QObject* obj, QEvent* event) {
- if (event->type() == QEvent::ShortcutOverride) {
- QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
- if (keyEvent->matches(QKeySequence::Find)) {
- emit startFind();
- } else if (keyEvent->matches(QKeySequence::FindNext)) {
- emit findAgain();
- }
- } else if (event->type() == QEvent::MouseButtonPress) {
- QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
- if (mouseEvent->button() == Qt::MidButton) {
- mouseEvent->ignore();
- return true;
- }
- // TODO This is due to that QTWebEnginePage doesn't support QWebFrame anymore
- // } else if (event->type() == QEvent::MouseButtonRelease) {
- // QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
- // if (mouseEvent->button() == Qt::MidButton) {
- // QWebEngineContextMenuData hitTest = page()->hitTestContent(mouseEvent->pos());
- // if (hitTest.linkUrl().isValid()) {
- // emit openUrlInNewTab(hitTest.linkUrl());
- // }
- // mouseEvent->ignore();
- //
- // return true;
- // }
+bool BrowserView::eventFilter(QObject *obj, QEvent *event)
+{
+ if (event->type() == QEvent::ShortcutOverride) {
+ QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
+ if (keyEvent->matches(QKeySequence::Find)) {
+ emit startFind();
+ } else if (keyEvent->matches(QKeySequence::FindNext)) {
+ emit findAgain();
+ }
+ } else if (event->type() == QEvent::MouseButtonPress) {
+ QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
+ if (mouseEvent->button() == Qt::MidButton) {
+ mouseEvent->ignore();
+ return true;
}
- return QWebEngineView::eventFilter(obj, event);
+// TODO This is due to that QTWebEnginePage doesn't support QWebFrame anymore
+// } else if (event->type() == QEvent::MouseButtonRelease) {
+// QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
+// if (mouseEvent->button() == Qt::MidButton) {
+// QWebEngineContextMenuData hitTest = page()->hitTestContent(mouseEvent->pos());
+// if (hitTest.linkUrl().isValid()) {
+// emit openUrlInNewTab(hitTest.linkUrl());
+// }
+// mouseEvent->ignore();
+//
+// return true;
+// }
+ }
+ return QWebEngineView::eventFilter(obj, event);
}
diff --git a/src/browserview.h b/src/browserview.h
index b390ed4e..24be21c1 100644
--- a/src/browserview.h
+++ b/src/browserview.h
@@ -20,55 +20,62 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef NEXUSVIEW_H
#define NEXUSVIEW_H
+
class QEvent;
class QUrl;
class QWidget;
-#include <QWebEnginePage>
#include <QWebEngineView>
+#include <QWebEnginePage>
/**
* @brief web view used to display a nexus page
**/
-class BrowserView : public QWebEngineView {
+class BrowserView : public QWebEngineView
+{
Q_OBJECT
public:
- explicit BrowserView(QWidget* parent = 0);
+
+ explicit BrowserView(QWidget *parent = 0);
signals:
- /**
- * @brief emitted when the user opens a new window to be displayed in another tab
- *
- * @param newView the view for the newly opened window
- **/
- void initTab(BrowserView* newView);
+ /**
+ * @brief emitted when the user opens a new window to be displayed in another tab
+ *
+ * @param newView the view for the newly opened window
+ **/
+ void initTab(BrowserView *newView);
- /**
- * @brief emitted when the user requests a link to be opened in a new tab by middle-clicking
- *
- * @param url the url to open
- */
- void openUrlInNewTab(const QUrl& url);
+ /**
+ * @brief emitted when the user requests a link to be opened in a new tab by middle-clicking
+ *
+ * @param url the url to open
+ */
+ void openUrlInNewTab(const QUrl &url);
- /**
- * @brief Ctrl-f was clicked. The containing dialog should activate its find-facility
- */
- void startFind();
+ /**
+ * @brief Ctrl-f was clicked. The containing dialog should activate its find-facility
+ */
+ void startFind();
- /**
- * @brief F3 was pressed. The containing dialog should search again
- */
- void findAgain();
+ /**
+ * @brief F3 was pressed. The containing dialog should search again
+ */
+ void findAgain();
protected:
- virtual QWebEngineView* createWindow(QWebEnginePage::WebWindowType type);
- virtual bool eventFilter(QObject* obj, QEvent* event);
+ virtual QWebEngineView *createWindow(QWebEnginePage::WebWindowType type);
+
+ virtual bool eventFilter(QObject *obj, QEvent *event);
+
private:
- QString m_FindPattern;
- bool m_MiddleClick;
+
+ QString m_FindPattern;
+ bool m_MiddleClick;
+
};
#endif // NEXUSVIEW_H
diff --git a/src/categories.cpp b/src/categories.cpp
index c88227e6..d8cd49fb 100644
--- a/src/categories.cpp
+++ b/src/categories.cpp
@@ -19,302 +19,350 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "categories.h"
-#include <report.h>
#include <utility.h>
+#include <report.h>
-#include <QCoreApplication>
-#include <QDir>
+#include <QObject>
#include <QFile>
+#include <QDir>
#include <QList>
-#include <QObject>
+#include <QCoreApplication>
+
using namespace MOBase;
+
CategoryFactory* CategoryFactory::s_Instance = nullptr;
-QString CategoryFactory::categoriesFilePath() { return qApp->property("dataPath").toString() + "/categories.dat"; }
-CategoryFactory::CategoryFactory() { atexit(&cleanup); }
+QString CategoryFactory::categoriesFilePath()
+{
+ return qApp->property("dataPath").toString() + "/categories.dat";
+}
-void CategoryFactory::loadCategories() {
- reset();
- QFile categoryFile(categoriesFilePath());
+CategoryFactory::CategoryFactory()
+{
+ atexit(&cleanup);
+}
- if (!categoryFile.open(QIODevice::ReadOnly)) {
- loadDefaultCategories();
- } else {
- int lineNum = 0;
- while (!categoryFile.atEnd()) {
- QByteArray line = categoryFile.readLine();
- ++lineNum;
- QList<QByteArray> cells = line.split('|');
- if (cells.count() != 4) {
- qCritical("invalid category line %d: %s (%d cells)", lineNum, line.constData(), cells.count());
- } else {
- std::vector<int> nexusIDs;
- if (cells[2].length() > 0) {
- QList<QByteArray> nexusIDStrings = cells[2].split(',');
- for (QList<QByteArray>::iterator iter = nexusIDStrings.begin(); iter != nexusIDStrings.end();
- ++iter) {
- bool ok = false;
- int temp = iter->toInt(&ok);
- if (!ok) {
- qCritical("invalid id %s", iter->constData());
- }
- nexusIDs.push_back(temp);
- }
- }
- bool cell0Ok = true;
- bool cell3Ok = true;
- int id = cells[0].toInt(&cell0Ok);
- int parentID = cells[3].trimmed().toInt(&cell3Ok);
- if (!cell0Ok || !cell3Ok) {
- qCritical("invalid category line %d: %s", lineNum, line.constData());
- }
- addCategory(id, QString::fromUtf8(cells[1].constData()), nexusIDs, parentID);
+void CategoryFactory::loadCategories()
+{
+ reset();
+
+ QFile categoryFile(categoriesFilePath());
+
+ if (!categoryFile.open(QIODevice::ReadOnly)) {
+ loadDefaultCategories();
+ } else {
+ int lineNum = 0;
+ while (!categoryFile.atEnd()) {
+ QByteArray line = categoryFile.readLine();
+ ++lineNum;
+ QList<QByteArray> cells = line.split('|');
+ if (cells.count() != 4) {
+ qCritical("invalid category line %d: %s (%d cells)",
+ lineNum, line.constData(), cells.count());
+ } else {
+ std::vector<int> nexusIDs;
+ if (cells[2].length() > 0) {
+ QList<QByteArray> nexusIDStrings = cells[2].split(',');
+ for (QList<QByteArray>::iterator iter = nexusIDStrings.begin();
+ iter != nexusIDStrings.end(); ++iter) {
+ bool ok = false;
+ int temp = iter->toInt(&ok);
+ if (!ok) {
+ qCritical("invalid id %s", iter->constData());
}
+ nexusIDs.push_back(temp);
+ }
+ }
+ bool cell0Ok = true;
+ bool cell3Ok = true;
+ int id = cells[0].toInt(&cell0Ok);
+ int parentID = cells[3].trimmed().toInt(&cell3Ok);
+ if (!cell0Ok || !cell3Ok) {
+ qCritical("invalid category line %d: %s",
+ lineNum, line.constData());
}
- categoryFile.close();
+ addCategory(id, QString::fromUtf8(cells[1].constData()), nexusIDs, parentID);
+ }
}
- std::sort(m_Categories.begin(), m_Categories.end());
- setParents();
+ categoryFile.close();
+ }
+ std::sort(m_Categories.begin(), m_Categories.end());
+ setParents();
}
-CategoryFactory& CategoryFactory::instance() {
- if (s_Instance == nullptr) {
- s_Instance = new CategoryFactory;
- }
- return *s_Instance;
+
+CategoryFactory &CategoryFactory::instance()
+{
+ if (s_Instance == nullptr) {
+ s_Instance = new CategoryFactory;
+ }
+ return *s_Instance;
}
-void CategoryFactory::reset() {
- m_Categories.clear();
- m_IDMap.clear();
- // 28 =
- // 43 = Savegames (makes no sense to install them through MO)
- // 45 = Videos and trailers
- // 87 = Miscelanous
- addCategory(0, "None", MakeVector<int>(4, 28, 43, 45, 87), 0);
+
+void CategoryFactory::reset()
+{
+ m_Categories.clear();
+ m_IDMap.clear();
+ // 28 =
+ // 43 = Savegames (makes no sense to install them through MO)
+ // 45 = Videos and trailers
+ // 87 = Miscelanous
+ addCategory(0, "None", MakeVector<int>(4, 28, 43, 45, 87), 0);
}
-void CategoryFactory::setParents() {
- for (std::vector<Category>::iterator iter = m_Categories.begin(); iter != m_Categories.end(); ++iter) {
- iter->m_HasChildren = false;
- }
- for (std::vector<Category>::const_iterator categoryIter = m_Categories.begin(); categoryIter != m_Categories.end();
- ++categoryIter) {
- if (categoryIter->m_ParentID != 0) {
- std::map<int, unsigned int>::const_iterator iter = m_IDMap.find(categoryIter->m_ParentID);
- if (iter != m_IDMap.end()) {
- m_Categories[iter->second].m_HasChildren = true;
- }
- }
+void CategoryFactory::setParents()
+{
+ for (std::vector<Category>::iterator iter = m_Categories.begin();
+ iter != m_Categories.end(); ++iter) {
+ iter->m_HasChildren = false;
+ }
+
+ for (std::vector<Category>::const_iterator categoryIter = m_Categories.begin();
+ categoryIter != m_Categories.end(); ++categoryIter) {
+ if (categoryIter->m_ParentID != 0) {
+ std::map<int, unsigned int>::const_iterator iter = m_IDMap.find(categoryIter->m_ParentID);
+ if (iter != m_IDMap.end()) {
+ m_Categories[iter->second].m_HasChildren = true;
+ }
}
+ }
}
-void CategoryFactory::cleanup() {
- delete s_Instance;
- s_Instance = nullptr;
+void CategoryFactory::cleanup()
+{
+ delete s_Instance;
+ s_Instance = nullptr;
}
-void CategoryFactory::saveCategories() {
- QFile categoryFile(categoriesFilePath());
- if (!categoryFile.open(QIODevice::WriteOnly)) {
- reportError(QObject::tr("Failed to save custom categories"));
- return;
- }
+void CategoryFactory::saveCategories()
+{
+ QFile categoryFile(categoriesFilePath());
- categoryFile.resize(0);
- for (std::vector<Category>::const_iterator iter = m_Categories.begin(); iter != m_Categories.end(); ++iter) {
- if (iter->m_ID == 0) {
- continue;
- }
- QByteArray line;
- line.append(QByteArray::number(iter->m_ID))
- .append("|")
- .append(iter->m_Name.toUtf8())
- .append("|")
- .append(VectorJoin(iter->m_NexusIDs, ","))
- .append("|")
- .append(QByteArray::number(iter->m_ParentID))
- .append("\n");
- categoryFile.write(line);
+ if (!categoryFile.open(QIODevice::WriteOnly)) {
+ reportError(QObject::tr("Failed to save custom categories"));
+ return;
+ }
+
+ categoryFile.resize(0);
+ for (std::vector<Category>::const_iterator iter = m_Categories.begin();
+ iter != m_Categories.end(); ++iter) {
+ if (iter->m_ID == 0) {
+ continue;
}
- categoryFile.close();
+ QByteArray line;
+ line.append(QByteArray::number(iter->m_ID)).append("|")
+ .append(iter->m_Name.toUtf8()).append("|")
+ .append(VectorJoin(iter->m_NexusIDs, ",")).append("|")
+ .append(QByteArray::number(iter->m_ParentID)).append("\n");
+ categoryFile.write(line);
+ }
+ categoryFile.close();
}
-unsigned int CategoryFactory::countCategories(std::tr1::function<bool(const Category& category)> filter) {
- unsigned int result = 0;
- for (const Category& cat : m_Categories) {
- if (filter(cat)) {
- ++result;
- }
+
+unsigned int CategoryFactory::countCategories(std::tr1::function<bool (const Category &category)> filter)
+{
+ unsigned int result = 0;
+ for (const Category &cat : m_Categories) {
+ if (filter(cat)) {
+ ++result;
}
- return result;
+ }
+ return result;
}
-int CategoryFactory::addCategory(const QString& name, const std::vector<int>& nexusIDs, int parentID) {
- int id = 1;
- while (m_IDMap.find(id) != m_IDMap.end()) {
- ++id;
- }
- addCategory(id, name, nexusIDs, parentID);
+int CategoryFactory::addCategory(const QString &name, const std::vector<int> &nexusIDs, int parentID)
+{
+ int id = 1;
+ while (m_IDMap.find(id) != m_IDMap.end()) {
+ ++id;
+ }
+ addCategory(id, name, nexusIDs, parentID);
- saveCategories();
- return id;
+ saveCategories();
+ return id;
}
-void CategoryFactory::addCategory(int id, const QString& name, const std::vector<int>& nexusIDs, int parentID) {
- int index = static_cast<int>(m_Categories.size());
- m_Categories.push_back(Category(index, id, name, nexusIDs, parentID));
- for (int nexusID : nexusIDs) {
- m_NexusMap[nexusID] = index;
- }
- m_IDMap[id] = index;
+void CategoryFactory::addCategory(int id, const QString &name, const std::vector<int> &nexusIDs, int parentID)
+{
+ int index = static_cast<int>(m_Categories.size());
+ m_Categories.push_back(Category(index, id, name, nexusIDs, parentID));
+ for (int nexusID : nexusIDs) {
+ m_NexusMap[nexusID] = index;
+ }
+ m_IDMap[id] = index;
}
-void CategoryFactory::loadDefaultCategories() {
- // the order here is relevant as it defines the order in which the
- // mods appear in the combo box
- addCategory(1, "Animations", MakeVector<int>(2, 4, 51), 0);
- addCategory(52, "Poses", MakeVector<int>(1, 29), 1);
- addCategory(2, "Armour", MakeVector<int>(2, 5, 54), 0);
- addCategory(53, "Power Armor", MakeVector<int>(1, 53), 2);
- addCategory(3, "Audio", MakeVector<int>(3, 33, 35, 106), 0);
- addCategory(38, "Music", MakeVector<int>(2, 34, 61), 0);
- addCategory(39, "Voice", MakeVector<int>(2, 36, 107), 0);
- addCategory(5, "Clothing", MakeVector<int>(2, 9, 60), 0);
- addCategory(41, "Jewelry", MakeVector<int>(1, 102), 5);
- addCategory(42, "Backpacks", MakeVector<int>(1, 49), 5);
- addCategory(6, "Collectables", MakeVector<int>(2, 10, 92), 0);
- addCategory(28, "Companions", MakeVector<int>(3, 11, 66, 96), 0);
- addCategory(7, "Creatures, Mounts, & Vehicles", MakeVector<int>(4, 12, 65, 83, 101), 0);
- addCategory(8, "Factions", MakeVector<int>(2, 16, 25), 0);
- addCategory(9, "Gameplay", MakeVector<int>(2, 15, 24), 0);
- addCategory(27, "Combat", MakeVector<int>(1, 77), 9);
- addCategory(43, "Crafting", MakeVector<int>(2, 50, 100), 9);
- addCategory(48, "Overhauls", MakeVector<int>(2, 24, 79), 9);
- addCategory(49, "Perks", MakeVector<int>(1, 27), 9);
- addCategory(54, "Radio", MakeVector<int>(1, 31), 9);
- addCategory(55, "Shouts", MakeVector<int>(1, 104), 9);
- addCategory(22, "Skills & Levelling", MakeVector<int>(2, 46, 73), 9);
- addCategory(58, "Weather & Lighting", MakeVector<int>(1, 56), 9);
- addCategory(44, "Equipment", MakeVector<int>(1, 44), 43);
- addCategory(45, "Home/Settlement", MakeVector<int>(1, 45), 43);
- addCategory(10, "Body, Face, & Hair", MakeVector<int>(2, 17, 26), 0);
- addCategory(39, "Tattoos", MakeVector<int>(1, 57), 10);
- addCategory(40, "Character Presets", MakeVector<int>(1, 58), 0);
- addCategory(11, "Items", MakeVector<int>(2, 27, 85), 0);
- addCategory(32, "Mercantile", MakeVector<int>(2, 23, 69), 0);
- addCategory(37, "Ammo", MakeVector<int>(1, 3), 11);
- addCategory(19, "Weapons", MakeVector<int>(2, 41, 55), 11);
- addCategory(36, "Weapon & Armour Sets", MakeVector<int>(1, 42), 11);
- addCategory(23, "Player Homes", MakeVector<int>(2, 28, 67), 0);
- addCategory(25, "Castles & Mansions", MakeVector<int>(1, 68), 23);
- addCategory(51, "Settlements", MakeVector<int>(1, 48), 23);
- addCategory(12, "Locations", MakeVector<int>(10, 20, 21, 22, 30, 47, 70, 88, 89, 90, 91), 0);
- addCategory(4, "Cities", MakeVector<int>(1, 53), 12);
- addCategory(31, "Landscape Changes", MakeVector<int>(1, 58), 0);
- addCategory(29, "Environment", MakeVector<int>(2, 14, 74), 0);
- addCategory(30, "Immersion", MakeVector<int>(2, 51, 78), 0);
- addCategory(20, "Magic", MakeVector<int>(3, 75, 93, 94), 0);
- addCategory(21, "Models & Textures", MakeVector<int>(2, 19, 29), 0);
- addCategory(33, "Modders resources", MakeVector<int>(2, 18, 82), 0);
- addCategory(13, "NPCs", MakeVector<int>(3, 22, 33, 99), 0);
- addCategory(24, "Bugfixes", MakeVector<int>(2, 6, 95), 0);
- addCategory(14, "Patches", MakeVector<int>(2, 25, 84), 24);
- addCategory(35, "Utilities", MakeVector<int>(2, 38, 39), 0);
- addCategory(26, "Cheats", MakeVector<int>(1, 8), 0);
- addCategory(15, "Quests", MakeVector<int>(2, 30, 35), 0);
- addCategory(16, "Races & Classes", MakeVector<int>(1, 34), 0);
- addCategory(34, "Stealth", MakeVector<int>(1, 76), 0);
- addCategory(17, "UI", MakeVector<int>(2, 37, 42), 0);
- addCategory(18, "Visuals", MakeVector<int>(2, 40, 62), 0);
- addCategory(50, "Pip-Boy", MakeVector<int>(1, 52), 18);
- addCategory(46, "Shader Presets", MakeVector<int>(3, 13, 97, 105), 0);
- addCategory(47, "Miscellaneous", MakeVector<int>(2, 2, 28), 0);
+
+void CategoryFactory::loadDefaultCategories()
+{
+ // the order here is relevant as it defines the order in which the
+ // mods appear in the combo box
+ addCategory(1, "Animations", MakeVector<int>(2, 4, 51), 0);
+ addCategory(52, "Poses", MakeVector<int>(1, 29), 1);
+ addCategory(2, "Armour", MakeVector<int>(2, 5, 54), 0);
+ addCategory(53, "Power Armor", MakeVector<int>(1, 53), 2);
+ addCategory(3, "Audio", MakeVector<int>(3, 33, 35, 106), 0);
+ addCategory(38, "Music", MakeVector<int>(2, 34, 61), 0);
+ addCategory(39, "Voice", MakeVector<int>(2, 36, 107), 0);
+ addCategory(5, "Clothing", MakeVector<int>(2, 9, 60), 0);
+ addCategory(41, "Jewelry", MakeVector<int>(1, 102), 5);
+ addCategory(42, "Backpacks", MakeVector<int>(1, 49), 5);
+ addCategory(6, "Collectables", MakeVector<int>(2, 10, 92), 0);
+ addCategory(28, "Companions", MakeVector<int>(3, 11, 66, 96), 0);
+ addCategory(7, "Creatures, Mounts, & Vehicles", MakeVector<int>(4, 12, 65, 83, 101), 0);
+ addCategory(8, "Factions", MakeVector<int>(2, 16, 25), 0);
+ addCategory(9, "Gameplay", MakeVector<int>(2, 15, 24), 0);
+ addCategory(27, "Combat", MakeVector<int>(1, 77), 9);
+ addCategory(43, "Crafting", MakeVector<int>(2, 50, 100), 9);
+ addCategory(48, "Overhauls", MakeVector<int>(2, 24, 79), 9);
+ addCategory(49, "Perks", MakeVector<int>(1, 27), 9);
+ addCategory(54, "Radio", MakeVector<int>(1, 31), 9);
+ addCategory(55, "Shouts", MakeVector<int>(1, 104), 9);
+ addCategory(22, "Skills & Levelling", MakeVector<int>(2, 46, 73), 9);
+ addCategory(58, "Weather & Lighting", MakeVector<int>(1, 56), 9);
+ addCategory(44, "Equipment", MakeVector<int>(1, 44), 43);
+ addCategory(45, "Home/Settlement", MakeVector<int>(1, 45), 43);
+ addCategory(10, "Body, Face, & Hair", MakeVector<int>(2, 17, 26), 0);
+ addCategory(39, "Tattoos", MakeVector<int>(1, 57), 10);
+ addCategory(40, "Character Presets", MakeVector<int>(1, 58), 0);
+ addCategory(11, "Items", MakeVector<int>(2, 27, 85), 0);
+ addCategory(32, "Mercantile", MakeVector<int>(2, 23, 69), 0);
+ addCategory(37, "Ammo", MakeVector<int>(1, 3), 11);
+ addCategory(19, "Weapons", MakeVector<int>(2, 41, 55), 11);
+ addCategory(36, "Weapon & Armour Sets", MakeVector<int>(1, 42), 11);
+ addCategory(23, "Player Homes", MakeVector<int>(2, 28, 67), 0);
+ addCategory(25, "Castles & Mansions", MakeVector<int>(1, 68), 23);
+ addCategory(51, "Settlements", MakeVector<int>(1, 48), 23);
+ addCategory(12, "Locations", MakeVector<int>(10, 20, 21, 22, 30, 47, 70, 88, 89, 90, 91), 0);
+ addCategory(4, "Cities", MakeVector<int>(1, 53), 12);
+ addCategory(31, "Landscape Changes", MakeVector<int>(1, 58), 0);
+ addCategory(29, "Environment", MakeVector<int>(2, 14, 74), 0);
+ addCategory(30, "Immersion", MakeVector<int>(2, 51, 78), 0);
+ addCategory(20, "Magic", MakeVector<int>(3, 75, 93, 94), 0);
+ addCategory(21, "Models & Textures", MakeVector<int>(2, 19, 29), 0);
+ addCategory(33, "Modders resources", MakeVector<int>(2, 18, 82), 0);
+ addCategory(13, "NPCs", MakeVector<int>(3, 22, 33, 99), 0);
+ addCategory(24, "Bugfixes", MakeVector<int>(2, 6, 95), 0);
+ addCategory(14, "Patches", MakeVector<int>(2, 25, 84), 24);
+ addCategory(35, "Utilities", MakeVector<int>(2, 38, 39), 0);
+ addCategory(26, "Cheats", MakeVector<int>(1, 8), 0);
+ addCategory(15, "Quests", MakeVector<int>(2, 30, 35), 0);
+ addCategory(16, "Races & Classes", MakeVector<int>(1, 34), 0);
+ addCategory(34, "Stealth", MakeVector<int>(1, 76), 0);
+ addCategory(17, "UI", MakeVector<int>(2, 37, 42), 0);
+ addCategory(18, "Visuals", MakeVector<int>(2, 40, 62), 0);
+ addCategory(50, "Pip-Boy", MakeVector<int>(1, 52), 18);
+ addCategory(46, "Shader Presets", MakeVector<int>(3, 13, 97, 105), 0);
+ addCategory(47, "Miscellaneous", MakeVector<int>(2, 2, 28), 0);
}
-int CategoryFactory::getParentID(unsigned int index) const {
- if (index >= m_Categories.size()) {
- throw MyException(QObject::tr("invalid index %1").arg(index));
- }
- return m_Categories[index].m_ParentID;
+int CategoryFactory::getParentID(unsigned int index) const
+{
+ if (index >= m_Categories.size()) {
+ throw MyException(QObject::tr("invalid index %1").arg(index));
+ }
+
+ return m_Categories[index].m_ParentID;
}
-bool CategoryFactory::categoryExists(int id) const { return m_IDMap.find(id) != m_IDMap.end(); }
-bool CategoryFactory::isDecendantOf(int id, int parentID) const {
- std::map<int, unsigned int>::const_iterator iter = m_IDMap.find(id);
- if (iter != m_IDMap.end()) {
- unsigned int index = iter->second;
- if (m_Categories[index].m_ParentID == 0) {
- return false;
- } else if (m_Categories[index].m_ParentID == parentID) {
- return true;
- } else {
- return isDecendantOf(m_Categories[index].m_ParentID, parentID);
- }
+bool CategoryFactory::categoryExists(int id) const
+{
+ return m_IDMap.find(id) != m_IDMap.end();
+}
+
+
+bool CategoryFactory::isDecendantOf(int id, int parentID) const
+{
+ std::map<int, unsigned int>::const_iterator iter = m_IDMap.find(id);
+ if (iter != m_IDMap.end()) {
+ unsigned int index = iter->second;
+ if (m_Categories[index].m_ParentID == 0) {
+ return false;
+ } else if (m_Categories[index].m_ParentID == parentID) {
+ return true;
} else {
- qWarning("%d is no valid category id", id);
- return false;
+ return isDecendantOf(m_Categories[index].m_ParentID, parentID);
}
+ } else {
+ qWarning("%d is no valid category id", id);
+ return false;
+ }
}
-bool CategoryFactory::hasChildren(unsigned int index) const {
- if (index >= m_Categories.size()) {
- throw MyException(QObject::tr("invalid index %1").arg(index));
- }
- return m_Categories[index].m_HasChildren;
+bool CategoryFactory::hasChildren(unsigned int index) const
+{
+ if (index >= m_Categories.size()) {
+ throw MyException(QObject::tr("invalid index %1").arg(index));
+ }
+
+ return m_Categories[index].m_HasChildren;
}
-QString CategoryFactory::getCategoryName(unsigned int index) const {
- if (index >= m_Categories.size()) {
- throw MyException(QObject::tr("invalid index %1").arg(index));
- }
- return m_Categories[index].m_Name;
+QString CategoryFactory::getCategoryName(unsigned int index) const
+{
+ if (index >= m_Categories.size()) {
+ throw MyException(QObject::tr("invalid index %1").arg(index));
+ }
+
+ return m_Categories[index].m_Name;
}
-int CategoryFactory::getCategoryID(unsigned int index) const {
- if (index >= m_Categories.size()) {
- throw MyException(QObject::tr("invalid index %1").arg(index));
- }
- return m_Categories[index].m_ID;
+int CategoryFactory::getCategoryID(unsigned int index) const
+{
+ if (index >= m_Categories.size()) {
+ throw MyException(QObject::tr("invalid index %1").arg(index));
+ }
+
+ return m_Categories[index].m_ID;
}
-int CategoryFactory::getCategoryIndex(int ID) const {
- std::map<int, unsigned int>::const_iterator iter = m_IDMap.find(ID);
- if (iter == m_IDMap.end()) {
- throw MyException(QObject::tr("invalid category id %1").arg(ID));
- }
- return iter->second;
+
+int CategoryFactory::getCategoryIndex(int ID) const
+{
+ std::map<int, unsigned int>::const_iterator iter = m_IDMap.find(ID);
+ if (iter == m_IDMap.end()) {
+ throw MyException(QObject::tr("invalid category id %1").arg(ID));
+ }
+ return iter->second;
}
-int CategoryFactory::getCategoryID(const QString& name) const {
- auto iter = std::find_if(m_Categories.begin(), m_Categories.end(),
- [name](const Category& cat) -> bool { return cat.m_Name == name; });
- if (iter != m_Categories.end()) {
- return iter->m_ID;
- } else {
- return -1;
- }
+int CategoryFactory::getCategoryID(const QString &name) const
+{
+ auto iter = std::find_if(m_Categories.begin(), m_Categories.end(),
+ [name] (const Category &cat) -> bool {
+ return cat.m_Name == name;
+ });
+
+ if (iter != m_Categories.end()) {
+ return iter->m_ID;
+ } else {
+ return -1;
+ }
}
-unsigned int CategoryFactory::resolveNexusID(int nexusID) const {
- std::map<int, unsigned int>::const_iterator iter = m_NexusMap.find(nexusID);
- if (iter != m_NexusMap.end()) {
- qDebug("nexus category id %d maps to internal %d", nexusID, iter->second);
- return iter->second;
- } else {
- qDebug("nexus category id %d not mapped", nexusID);
- return 0U;
- }
+
+unsigned int CategoryFactory::resolveNexusID(int nexusID) const
+{
+ std::map<int, unsigned int>::const_iterator iter = m_NexusMap.find(nexusID);
+ if (iter != m_NexusMap.end()) {
+ qDebug("nexus category id %d maps to internal %d", nexusID, iter->second);
+ return iter->second;
+ } else {
+ qDebug("nexus category id %d not mapped", nexusID);
+ return 0U;
+ }
}
diff --git a/src/categories.h b/src/categories.h
index 0ed627d1..66299c30 100644
--- a/src/categories.h
+++ b/src/categories.h
@@ -20,10 +20,12 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef CATEGORIES_H
#define CATEGORIES_H
+
#include <QString>
-#include <functional>
-#include <map>
#include <vector>
+#include <map>
+#include <functional>
+
/**
* @brief Manage the available mod categories
@@ -32,170 +34,180 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
**/
class CategoryFactory {
- friend class CategoriesDialog;
+ friend class CategoriesDialog;
public:
- static const int CATEGORY_NONE = 0;
- static const int CATEGORY_SPECIAL_FIRST = 10000;
- static const int CATEGORY_SPECIAL_CHECKED = CATEGORY_SPECIAL_FIRST;
- static const int CATEGORY_SPECIAL_UNCHECKED = 10001;
- static const int CATEGORY_SPECIAL_UPDATEAVAILABLE = 10002;
- static const int CATEGORY_SPECIAL_NOCATEGORY = 10003;
- static const int CATEGORY_SPECIAL_CONFLICT = 10004;
- static const int CATEGORY_SPECIAL_NOTENDORSED = 10005;
- static const int CATEGORY_SPECIAL_MANAGED = 10006;
- static const int CATEGORY_SPECIAL_UNMANAGED = 10007;
+ static const int CATEGORY_NONE = 0;
+
+ static const int CATEGORY_SPECIAL_FIRST = 10000;
+ static const int CATEGORY_SPECIAL_CHECKED = CATEGORY_SPECIAL_FIRST;
+ static const int CATEGORY_SPECIAL_UNCHECKED = 10001;
+ static const int CATEGORY_SPECIAL_UPDATEAVAILABLE = 10002;
+ static const int CATEGORY_SPECIAL_NOCATEGORY = 10003;
+ static const int CATEGORY_SPECIAL_CONFLICT = 10004;
+ static const int CATEGORY_SPECIAL_NOTENDORSED = 10005;
+ static const int CATEGORY_SPECIAL_MANAGED = 10006;
+ static const int CATEGORY_SPECIAL_UNMANAGED = 10007;
public:
- struct Category {
- Category(int sortValue, int id, const QString& name, const std::vector<int>& nexusIDs, int parentID)
- : m_SortValue(sortValue), m_ID(id), m_Name(name), m_HasChildren(false), m_NexusIDs(nexusIDs),
- m_ParentID(parentID) {}
- int m_SortValue;
- int m_ID;
- int m_ParentID;
- bool m_HasChildren;
- QString m_Name;
- std::vector<int> m_NexusIDs;
- friend bool operator<(const Category& LHS, const Category& RHS) { return LHS.m_SortValue < RHS.m_SortValue; }
- };
+ struct Category {
+ Category(int sortValue, int id, const QString &name, const std::vector<int> &nexusIDs, int parentID)
+ : m_SortValue(sortValue), m_ID(id), m_Name(name), m_HasChildren(false),
+ m_NexusIDs(nexusIDs), m_ParentID(parentID) {}
+ int m_SortValue;
+ int m_ID;
+ int m_ParentID;
+ bool m_HasChildren;
+ QString m_Name;
+ std::vector<int> m_NexusIDs;
+
+ friend bool operator<(const Category &LHS, const Category &RHS) {
+ return LHS.m_SortValue < RHS.m_SortValue;
+ }
+ };
public:
- /**
- * @brief reset the list of categories
- **/
- void reset();
- /**
- * @brief read categories from file
- */
- void loadCategories();
+ /**
+ * @brief reset the list of categories
+ **/
+ void reset();
+
+ /**
+ * @brief read categories from file
+ */
+ void loadCategories();
- /**
- * @brief save the categories to the categories.dat file
- **/
- void saveCategories();
+ /**
+ * @brief save the categories to the categories.dat file
+ **/
+ void saveCategories();
- int addCategory(const QString& name, const std::vector<int>& nexusIDs, int parentID);
+ int addCategory(const QString &name, const std::vector<int> &nexusIDs, int parentID);
- /**
- * @brief retrieve the number of available categories
- *
- * @return unsigned int number of categories
- **/
- size_t numCategories() const { return m_Categories.size(); }
+ /**
+ * @brief retrieve the number of available categories
+ *
+ * @return unsigned int number of categories
+ **/
+ size_t numCategories() const { return m_Categories.size(); }
- /**
- * @brief count all categories that match a specified filter
- * @param filter the filter to test
- * @return number of matching categories
- */
- unsigned int countCategories(std::tr1::function<bool(const Category& category)> filter);
+ /**
+ * @brief count all categories that match a specified filter
+ * @param filter the filter to test
+ * @return number of matching categories
+ */
+ unsigned int countCategories(std::tr1::function<bool (const Category &category)> filter);
- /**
- * @brief get the id of the parent category
- *
- * @param index the index to look up
- * @return int id of the parent category
- **/
- int getParentID(unsigned int index) const;
+ /**
+ * @brief get the id of the parent category
+ *
+ * @param index the index to look up
+ * @return int id of the parent category
+ **/
+ int getParentID(unsigned int index) const;
- /**
- * @brief determine if a category exists (by id)
- *
- * @param id the id to check for existance
- * @return true if the category exists, false otherwise
- **/
- bool categoryExists(int id) const;
+ /**
+ * @brief determine if a category exists (by id)
+ *
+ * @param id the id to check for existance
+ * @return true if the category exists, false otherwise
+ **/
+ bool categoryExists(int id) const;
- /**
- * @brief test if a category is child of a second one
- * @param id the presumed child id
- * @param parentID the parent id to test for
- * @return true if id is a child of parentID
- **/
- bool isDecendantOf(int id, int parentID) const;
+ /**
+ * @brief test if a category is child of a second one
+ * @param id the presumed child id
+ * @param parentID the parent id to test for
+ * @return true if id is a child of parentID
+ **/
+ bool isDecendantOf(int id, int parentID) const;
- /**
- * @brief test if the specified category has child categories
- *
- * @param index index of the category to look up
- * @return bool true if the category has child categories
- **/
- bool hasChildren(unsigned int index) const;
+ /**
+ * @brief test if the specified category has child categories
+ *
+ * @param index index of the category to look up
+ * @return bool true if the category has child categories
+ **/
+ bool hasChildren(unsigned int index) const;
- /**
- * @brief retrieve the name of a category
- *
- * @param index index of the category to look up
- * @return QString name of the category
- **/
- QString getCategoryName(unsigned int index) const;
+ /**
+ * @brief retrieve the name of a category
+ *
+ * @param index index of the category to look up
+ * @return QString name of the category
+ **/
+ QString getCategoryName(unsigned int index) const;
- /**
- * @brief look up the id of a category by its index
- *
- * @param index index of the category to look up
- * @return int id of the category
- **/
- int getCategoryID(unsigned int index) const;
+ /**
+ * @brief look up the id of a category by its index
+ *
+ * @param index index of the category to look up
+ * @return int id of the category
+ **/
+ int getCategoryID(unsigned int index) const;
- /**
- * @brief look up the id of a category by its name
- * @note O(n)
- */
- int getCategoryID(const QString& name) const;
+ /**
+ * @brief look up the id of a category by its name
+ * @note O(n)
+ */
+ int getCategoryID(const QString &name) const;
- /**
- * @brief look up the index of a category by its id
- *
- * @param id index of the category to look up
- * @return unsigned int index of the category
- **/
- int getCategoryIndex(int ID) const;
+ /**
+ * @brief look up the index of a category by its id
+ *
+ * @param id index of the category to look up
+ * @return unsigned int index of the category
+ **/
+ int getCategoryIndex(int ID) const;
- /**
- * @brief retrieve the index of a category by its nexus id
- *
- * @param nexusID nexus id of the category to look up
- * @return unsigned int index of the category or 0 if no category matches
- **/
- unsigned int resolveNexusID(int nexusID) const;
+ /**
+ * @brief retrieve the index of a category by its nexus id
+ *
+ * @param nexusID nexus id of the category to look up
+ * @return unsigned int index of the category or 0 if no category matches
+ **/
+ unsigned int resolveNexusID(int nexusID) const;
public:
- /**
- * @brief retrieve a reference to the singleton instance
- *
- * @return the reference to the singleton
- **/
- static CategoryFactory& instance();
- /**
- * @return path to the file that contains the categories list
- */
- static QString categoriesFilePath();
+ /**
+ * @brief retrieve a reference to the singleton instance
+ *
+ * @return the reference to the singleton
+ **/
+ static CategoryFactory &instance();
+
+ /**
+ * @return path to the file that contains the categories list
+ */
+ static QString categoriesFilePath();
private:
- CategoryFactory();
- void loadDefaultCategories();
+ CategoryFactory();
+
+ void loadDefaultCategories();
- void addCategory(int id, const QString& name, const std::vector<int>& nexusID, int parentID);
+ void addCategory(int id, const QString &name, const std::vector<int> &nexusID, int parentID);
- void setParents();
+ void setParents();
- static void cleanup();
+ static void cleanup();
private:
- static CategoryFactory* s_Instance;
- std::vector<Category> m_Categories;
- std::map<int, unsigned int> m_IDMap;
- std::map<int, unsigned int> m_NexusMap;
+ static CategoryFactory *s_Instance;
+
+ std::vector<Category> m_Categories;
+ std::map<int, unsigned int> m_IDMap;
+ std::map<int, unsigned int> m_NexusMap;
private:
+
};
+
#endif // CATEGORIES_H
diff --git a/src/categoriesdialog.cpp b/src/categoriesdialog.cpp
index 1629e00d..881179a4 100644
--- a/src/categoriesdialog.cpp
+++ b/src/categoriesdialog.cpp
@@ -18,198 +18,226 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "categoriesdialog.h"
-#include "categories.h"
#include "ui_categoriesdialog.h"
+#include "categories.h"
#include "utility.h"
#include <QItemDelegate>
+#include <QRegExpValidator>
#include <QLineEdit>
#include <QMenu>
-#include <QRegExpValidator>
+
class NewIDValidator : public QIntValidator {
public:
- NewIDValidator(const std::set<int>& ids) : m_UsedIDs(ids) {}
- virtual State validate(QString& input, int& pos) const {
- State intRes = QIntValidator::validate(input, pos);
- if (intRes == Acceptable) {
- bool ok = false;
- int id = input.toInt(&ok);
- if (m_UsedIDs.find(id) != m_UsedIDs.end()) {
- return QValidator::Intermediate;
- }
- }
- return intRes;
+ NewIDValidator(const std::set<int> &ids)
+ : m_UsedIDs(ids) {}
+ virtual State validate(QString &input, int &pos) const {
+ State intRes = QIntValidator::validate(input, pos);
+ if (intRes == Acceptable) {
+ bool ok = false;
+ int id = input.toInt(&ok);
+ if (m_UsedIDs.find(id) != m_UsedIDs.end()) {
+ return QValidator::Intermediate;
+ }
}
-
+ return intRes;
+ }
private:
- const std::set<int>& m_UsedIDs;
+ const std::set<int> &m_UsedIDs;
};
+
class ExistingIDValidator : public QIntValidator {
public:
- ExistingIDValidator(const std::set<int>& ids) : m_UsedIDs(ids) {}
- virtual State validate(QString& input, int& pos) const {
- State intRes = QIntValidator::validate(input, pos);
- if (intRes == Acceptable) {
- bool ok = false;
- int id = input.toInt(&ok);
- if ((id == 0) || (m_UsedIDs.find(id) != m_UsedIDs.end())) {
- return QValidator::Acceptable;
- } else {
- return QValidator::Intermediate;
- }
- } else {
- return intRes;
- }
+ ExistingIDValidator(const std::set<int> &ids)
+ : m_UsedIDs(ids) {}
+ virtual State validate(QString &input, int &pos) const {
+ State intRes = QIntValidator::validate(input, pos);
+ if (intRes == Acceptable) {
+ bool ok = false;
+ int id = input.toInt(&ok);
+ if ((id == 0) || (m_UsedIDs.find(id) != m_UsedIDs.end())) {
+ return QValidator::Acceptable;
+ } else {
+ return QValidator::Intermediate;
+ }
+ } else {
+ return intRes;
}
-
+ }
private:
- const std::set<int>& m_UsedIDs;
+ const std::set<int> &m_UsedIDs;
};
+
class ValidatingDelegate : public QItemDelegate {
public:
- ValidatingDelegate(QObject* parent, QValidator* validator) : QItemDelegate(parent), m_Validator(validator) {}
+ ValidatingDelegate(QObject *parent, QValidator *validator)
+ : QItemDelegate(parent), m_Validator(validator) {}
- QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem&, const QModelIndex&) const {
- QLineEdit* edit = new QLineEdit(parent);
- edit->setValidator(m_Validator);
- return edit;
- }
- virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const {
- QLineEdit* edit = qobject_cast<QLineEdit*>(editor);
- int pos = 0;
- QString editText = edit->text();
- if (m_Validator->validate(editText, pos) == QValidator::Acceptable) {
- QItemDelegate::setModelData(editor, model, index);
- }
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem&, const QModelIndex&) const
+ {
+ QLineEdit *edit = new QLineEdit(parent);
+ edit->setValidator(m_Validator);
+ return edit;
+ }
+ virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
+ {
+ QLineEdit *edit = qobject_cast<QLineEdit*>(editor);
+ int pos = 0;
+ QString editText = edit->text();
+ if (m_Validator->validate(editText, pos) == QValidator::Acceptable) {
+ QItemDelegate::setModelData(editor, model, index);
}
-
+ }
private:
- QValidator* m_Validator;
+ QValidator *m_Validator;
};
-CategoriesDialog::CategoriesDialog(QWidget* parent)
- : TutorableDialog("Categories", parent), ui(new Ui::CategoriesDialog) {
- ui->setupUi(this);
- fillTable();
- connect(ui->categoriesTable, SIGNAL(cellChanged(int, int)), this, SLOT(cellChanged(int, int)));
+
+CategoriesDialog::CategoriesDialog(QWidget *parent)
+ : TutorableDialog("Categories", parent), ui(new Ui::CategoriesDialog)
+{
+ ui->setupUi(this);
+ fillTable();
+ connect(ui->categoriesTable, SIGNAL(cellChanged(int,int)), this, SLOT(cellChanged(int,int)));
}
-CategoriesDialog::~CategoriesDialog() { delete ui; }
+CategoriesDialog::~CategoriesDialog()
+{
+ delete ui;
+}
-void CategoriesDialog::cellChanged(int row, int) {
- int currentID = ui->categoriesTable->item(row, 0)->text().toInt();
- if (currentID > m_HighestID) {
- m_HighestID = currentID;
- }
+
+void CategoriesDialog::cellChanged(int row, int)
+{
+ int currentID = ui->categoriesTable->item(row, 0)->text().toInt();
+ if (currentID > m_HighestID) {
+ m_HighestID = currentID;
+ }
}
-void CategoriesDialog::commitChanges() {
- CategoryFactory& categories = CategoryFactory::instance();
- categories.reset();
- for (int i = 0; i < ui->categoriesTable->rowCount(); ++i) {
- int index = ui->categoriesTable->verticalHeader()->logicalIndex(i);
- QString nexusIDString = ui->categoriesTable->item(index, 2)->text();
- QStringList nexusIDStringList = nexusIDString.split(',', QString::SkipEmptyParts);
- std::vector<int> nexusIDs;
- for (QStringList::iterator iter = nexusIDStringList.begin(); iter != nexusIDStringList.end(); ++iter) {
- nexusIDs.push_back(iter->toInt());
- }
+void CategoriesDialog::commitChanges()
+{
+ CategoryFactory &categories = CategoryFactory::instance();
+ categories.reset();
- categories.addCategory(ui->categoriesTable->item(index, 0)->text().toInt(),
- ui->categoriesTable->item(index, 1)->text(), nexusIDs,
- ui->categoriesTable->item(index, 3)->text().toInt());
+ for (int i = 0; i < ui->categoriesTable->rowCount(); ++i) {
+ int index = ui->categoriesTable->verticalHeader()->logicalIndex(i);
+ QString nexusIDString = ui->categoriesTable->item(index, 2)->text();
+ QStringList nexusIDStringList = nexusIDString.split(',', QString::SkipEmptyParts);
+ std::vector<int> nexusIDs;
+ for (QStringList::iterator iter = nexusIDStringList.begin();
+ iter != nexusIDStringList.end(); ++iter) {
+ nexusIDs.push_back(iter->toInt());
}
- categories.setParents();
- categories.saveCategories();
+ categories.addCategory(
+ ui->categoriesTable->item(index, 0)->text().toInt(),
+ ui->categoriesTable->item(index, 1)->text(),
+ nexusIDs,
+ ui->categoriesTable->item(index, 3)->text().toInt());
+ }
+ categories.setParents();
+
+ categories.saveCategories();
}
-void CategoriesDialog::refreshIDs() {
- m_HighestID = 0;
- for (int i = 0; i < ui->categoriesTable->rowCount(); ++i) {
- int id = ui->categoriesTable->item(i, 0)->text().toInt();
- if (id > m_HighestID) {
- m_HighestID = id;
- }
- m_IDs.insert(id);
+
+void CategoriesDialog::refreshIDs()
+{
+ m_HighestID = 0;
+ for (int i = 0; i < ui->categoriesTable->rowCount(); ++i) {
+ int id = ui->categoriesTable->item(i, 0)->text().toInt();
+ if (id > m_HighestID) {
+ m_HighestID = id;
}
+ m_IDs.insert(id);
+ }
}
-void CategoriesDialog::fillTable() {
- CategoryFactory& categories = CategoryFactory::instance();
- QTableWidget* table = ui->categoriesTable;
-#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
- table->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);
- table->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
- table->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Fixed);
- table->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Fixed);
- table->verticalHeader()->setSectionsMovable(true);
- table->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
+void CategoriesDialog::fillTable()
+{
+ CategoryFactory &categories = CategoryFactory::instance();
+ QTableWidget *table = ui->categoriesTable;
+
+#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
+ table->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);
+ table->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
+ table->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Fixed);
+ table->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Fixed);
+ table->verticalHeader()->setSectionsMovable(true);
+ table->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
#else
- table->horizontalHeader()->setResizeMode(0, QHeaderView::Fixed);
- table->horizontalHeader()->setResizeMode(1, QHeaderView::Stretch);
- table->horizontalHeader()->setResizeMode(2, QHeaderView::Fixed);
- table->horizontalHeader()->setResizeMode(3, QHeaderView::Fixed);
- table->verticalHeader()->setMovable(true);
- table->verticalHeader()->setResizeMode(QHeaderView::Fixed);
+ table->horizontalHeader()->setResizeMode(0, QHeaderView::Fixed);
+ table->horizontalHeader()->setResizeMode(1, QHeaderView::Stretch);
+ table->horizontalHeader()->setResizeMode(2, QHeaderView::Fixed);
+ table->horizontalHeader()->setResizeMode(3, QHeaderView::Fixed);
+ table->verticalHeader()->setMovable(true);
+ table->verticalHeader()->setResizeMode(QHeaderView::Fixed);
#endif
- table->setItemDelegateForColumn(0, new ValidatingDelegate(this, new NewIDValidator(m_IDs)));
- table->setItemDelegateForColumn(
- 2, new ValidatingDelegate(this, new QRegExpValidator(QRegExp("([0-9]+)?(,[0-9]+)*"), this)));
- table->setItemDelegateForColumn(3, new ValidatingDelegate(this, new ExistingIDValidator(m_IDs)));
- int row = 0;
- for (std::vector<CategoryFactory::Category>::const_iterator iter = categories.m_Categories.begin();
- iter != categories.m_Categories.end(); ++iter, ++row) {
- const CategoryFactory::Category& category = *iter;
- if (category.m_ID == 0) {
- --row;
- continue;
- }
- table->insertRow(row);
- // table->setVerticalHeaderItem(row, new QTableWidgetItem(" "));
+ table->setItemDelegateForColumn(0, new ValidatingDelegate(this, new NewIDValidator(m_IDs)));
+ table->setItemDelegateForColumn(2, new ValidatingDelegate(this, new QRegExpValidator(QRegExp("([0-9]+)?(,[0-9]+)*"), this)));
+ table->setItemDelegateForColumn(3, new ValidatingDelegate(this, new ExistingIDValidator(m_IDs)));
+
+ int row = 0;
+ for (std::vector<CategoryFactory::Category>::const_iterator iter = categories.m_Categories.begin();
+ iter != categories.m_Categories.end(); ++iter, ++row) {
+ const CategoryFactory::Category &category = *iter;
+ if (category.m_ID == 0) {
+ --row;
+ continue;
+ }
+ table->insertRow(row);
+// table->setVerticalHeaderItem(row, new QTableWidgetItem(" "));
- QScopedPointer<QTableWidgetItem> idItem(new QTableWidgetItem());
- idItem->setData(Qt::DisplayRole, category.m_ID);
+ QScopedPointer<QTableWidgetItem> idItem(new QTableWidgetItem());
+ idItem->setData(Qt::DisplayRole, category.m_ID);
- QScopedPointer<QTableWidgetItem> nameItem(new QTableWidgetItem(category.m_Name));
- QScopedPointer<QTableWidgetItem> nexusIDItem(
- new QTableWidgetItem(MOBase::VectorJoin(category.m_NexusIDs, ",")));
- QScopedPointer<QTableWidgetItem> parentIDItem(new QTableWidgetItem());
- parentIDItem->setData(Qt::DisplayRole, category.m_ParentID);
+ QScopedPointer<QTableWidgetItem> nameItem(new QTableWidgetItem(category.m_Name));
+ QScopedPointer<QTableWidgetItem> nexusIDItem(new QTableWidgetItem(MOBase::VectorJoin(category.m_NexusIDs, ",")));
+ QScopedPointer<QTableWidgetItem> parentIDItem(new QTableWidgetItem());
+ parentIDItem->setData(Qt::DisplayRole, category.m_ParentID);
+
+ table->setItem(row, 0, idItem.take());
+ table->setItem(row, 1, nameItem.take());
+ table->setItem(row, 2, nexusIDItem.take());
+ table->setItem(row, 3, parentIDItem.take());
+ }
+
+ refreshIDs();
+}
- table->setItem(row, 0, idItem.take());
- table->setItem(row, 1, nameItem.take());
- table->setItem(row, 2, nexusIDItem.take());
- table->setItem(row, 3, parentIDItem.take());
- }
- refreshIDs();
+void CategoriesDialog::addCategory_clicked()
+{
+ int row = m_ContextRow >= 0 ? m_ContextRow : 0;
+ ui->categoriesTable->insertRow(row);
+ ui->categoriesTable->setVerticalHeaderItem(row, new QTableWidgetItem(" "));
+ ui->categoriesTable->setItem(row, 0, new QTableWidgetItem(QString::number(++m_HighestID)));
+ ui->categoriesTable->setItem(row, 1, new QTableWidgetItem("new"));
+ ui->categoriesTable->setItem(row, 2, new QTableWidgetItem(""));
+ ui->categoriesTable->setItem(row, 3, new QTableWidgetItem("0"));
}
-void CategoriesDialog::addCategory_clicked() {
- int row = m_ContextRow >= 0 ? m_ContextRow : 0;
- ui->categoriesTable->insertRow(row);
- ui->categoriesTable->setVerticalHeaderItem(row, new QTableWidgetItem(" "));
- ui->categoriesTable->setItem(row, 0, new QTableWidgetItem(QString::number(++m_HighestID)));
- ui->categoriesTable->setItem(row, 1, new QTableWidgetItem("new"));
- ui->categoriesTable->setItem(row, 2, new QTableWidgetItem(""));
- ui->categoriesTable->setItem(row, 3, new QTableWidgetItem("0"));
+
+void CategoriesDialog::removeCategory_clicked()
+{
+ ui->categoriesTable->removeRow(m_ContextRow);
}
-void CategoriesDialog::removeCategory_clicked() { ui->categoriesTable->removeRow(m_ContextRow); }
-void CategoriesDialog::on_categoriesTable_customContextMenuRequested(const QPoint& pos) {
- m_ContextRow = ui->categoriesTable->rowAt(pos.y());
- QMenu menu;
- menu.addAction(tr("Add"), this, SLOT(addCategory_clicked()));
- menu.addAction(tr("Remove"), this, SLOT(removeCategory_clicked()));
+void CategoriesDialog::on_categoriesTable_customContextMenuRequested(const QPoint &pos)
+{
+ m_ContextRow = ui->categoriesTable->rowAt(pos.y());
+ QMenu menu;
+ menu.addAction(tr("Add"), this, SLOT(addCategory_clicked()));
+ menu.addAction(tr("Remove"), this, SLOT(removeCategory_clicked()));
- menu.exec(ui->categoriesTable->mapToGlobal(pos));
+ menu.exec(ui->categoriesTable->mapToGlobal(pos));
}
diff --git a/src/categoriesdialog.h b/src/categoriesdialog.h
index 141eb907..72d2154d 100644
--- a/src/categoriesdialog.h
+++ b/src/categoriesdialog.h
@@ -30,36 +30,42 @@ class CategoriesDialog;
/**
* @brief Dialog that allows users to configure mod categories
**/
-class CategoriesDialog : public MOBase::TutorableDialog {
- Q_OBJECT
-
+class CategoriesDialog : public MOBase::TutorableDialog
+{
+ Q_OBJECT
+
public:
- explicit CategoriesDialog(QWidget* parent = 0);
- ~CategoriesDialog();
- /**
- * @brief store changes here to the global categories store (categories.h)
- *
- **/
- void commitChanges();
+ explicit CategoriesDialog(QWidget *parent = 0);
+ ~CategoriesDialog();
+
+ /**
+ * @brief store changes here to the global categories store (categories.h)
+ *
+ **/
+ void commitChanges();
private slots:
- void on_categoriesTable_customContextMenuRequested(const QPoint& pos);
- void addCategory_clicked();
- void removeCategory_clicked();
- void cellChanged(int row, int column);
+ void on_categoriesTable_customContextMenuRequested(const QPoint &pos);
+ void addCategory_clicked();
+ void removeCategory_clicked();
+ void cellChanged(int row, int column);
private:
- void refreshIDs();
- void fillTable();
+
+ void refreshIDs();
+ void fillTable();
private:
- Ui::CategoriesDialog* ui;
- int m_ContextRow;
- int m_HighestID;
- std::set<int> m_IDs;
+ Ui::CategoriesDialog *ui;
+ int m_ContextRow;
+
+ int m_HighestID;
+ std::set<int> m_IDs;
+
};
#endif // CATEGORIESDIALOG_H
+
diff --git a/src/credentialsdialog.cpp b/src/credentialsdialog.cpp
index fd6554ec..04774548 100644
--- a/src/credentialsdialog.cpp
+++ b/src/credentialsdialog.cpp
@@ -20,16 +20,34 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "credentialsdialog.h"
#include "ui_credentialsdialog.h"
-CredentialsDialog::CredentialsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::CredentialsDialog) {
- ui->setupUi(this);
+CredentialsDialog::CredentialsDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::CredentialsDialog)
+{
+ ui->setupUi(this);
}
-CredentialsDialog::~CredentialsDialog() { delete ui; }
+CredentialsDialog::~CredentialsDialog()
+{
+ delete ui;
+}
-QString CredentialsDialog::username() const { return ui->usernameEdit->text(); }
+QString CredentialsDialog::username() const
+{
+ return ui->usernameEdit->text();
+}
-QString CredentialsDialog::password() const { return ui->passwordEdit->text(); }
+QString CredentialsDialog::password() const
+{
+ return ui->passwordEdit->text();
+}
-bool CredentialsDialog::store() const { return ui->rememberCheck->isChecked(); }
+bool CredentialsDialog::store() const
+{
+ return ui->rememberCheck->isChecked();
+}
-bool CredentialsDialog::neverAsk() const { return ui->dontaskBox->isChecked(); }
+bool CredentialsDialog::neverAsk() const
+{
+ return ui->dontaskBox->isChecked();
+}
diff --git a/src/credentialsdialog.h b/src/credentialsdialog.h
index 79554fe7..8a68c7d8 100644
--- a/src/credentialsdialog.h
+++ b/src/credentialsdialog.h
@@ -26,21 +26,22 @@ namespace Ui {
class CredentialsDialog;
}
-class CredentialsDialog : public QDialog {
- Q_OBJECT
-
+class CredentialsDialog : public QDialog
+{
+ Q_OBJECT
+
public:
- explicit CredentialsDialog(QWidget* parent = 0);
- ~CredentialsDialog();
+ explicit CredentialsDialog(QWidget *parent = 0);
+ ~CredentialsDialog();
- QString username() const;
- QString password() const;
+ QString username() const;
+ QString password() const;
- bool store() const;
- bool neverAsk() const;
+ bool store() const;
+ bool neverAsk() const;
private:
- Ui::CredentialsDialog* ui;
+ Ui::CredentialsDialog *ui;
};
#endif // CREDENTIALSDIALOG_H
diff --git a/src/csvbuilder.cpp b/src/csvbuilder.cpp
index 495922bd..fa4218a2 100644
--- a/src/csvbuilder.cpp
+++ b/src/csvbuilder.cpp
@@ -1,200 +1,248 @@
#include "csvbuilder.h"
-CSVBuilder::CSVBuilder(QIODevice* target) : m_Out(target), m_Separator(','), m_LineBreak(BREAK_CRLF) {
- m_Out.setCodec("UTF-8");
- m_QuoteMode[TYPE_INTEGER] = QUOTE_NEVER;
- m_QuoteMode[TYPE_FLOAT] = QUOTE_NEVER;
- m_QuoteMode[TYPE_STRING] = QUOTE_ONDEMAND;
+CSVBuilder::CSVBuilder(QIODevice *target)
+ : m_Out(target), m_Separator(','), m_LineBreak(BREAK_CRLF)
+{
+ m_Out.setCodec("UTF-8");
+
+ m_QuoteMode[TYPE_INTEGER] = QUOTE_NEVER;
+ m_QuoteMode[TYPE_FLOAT] = QUOTE_NEVER;
+ m_QuoteMode[TYPE_STRING] = QUOTE_ONDEMAND;
}
-CSVBuilder::~CSVBuilder() {}
-void CSVBuilder::setFieldSeparator(char sep) {
- char oldSeparator = m_Separator;
- m_Separator = sep;
- try {
- checkFields(m_Fields);
- } catch (const CSVException&) {
- m_Separator = oldSeparator;
- throw;
- }
+CSVBuilder::~CSVBuilder()
+{
+
}
-void CSVBuilder::setLineBreak(CSVBuilder::ELineBreak lineBreak) { m_LineBreak = lineBreak; }
-void CSVBuilder::setEscapeMode(CSVBuilder::EFieldType type, CSVBuilder::EQuoteMode mode) { m_QuoteMode[type] = mode; }
+void CSVBuilder::setFieldSeparator(char sep)
+{
+ char oldSeparator = m_Separator;
+ m_Separator = sep;
+ try {
+ checkFields(m_Fields);
+ } catch (const CSVException&) {
+ m_Separator = oldSeparator;
+ throw;
+ }
+}
-void CSVBuilder::setFields(const std::vector<std::pair<QString, EFieldType>>& fields) {
- std::vector<QString> fieldNames;
- std::map<QString, EFieldType> fieldTypes;
- for (auto iter = fields.begin(); iter != fields.end(); ++iter) {
- fieldNames.push_back(iter->first);
- fieldTypes[iter->first] = iter->second;
- }
+void CSVBuilder::setLineBreak(CSVBuilder::ELineBreak lineBreak)
+{
+ m_LineBreak = lineBreak;
+}
- checkFields(fieldNames);
- m_Fields = fieldNames;
- m_FieldTypes = fieldTypes;
- m_Defaults.clear();
- m_RowBuffer.clear();
+void CSVBuilder::setEscapeMode(CSVBuilder::EFieldType type, CSVBuilder::EQuoteMode mode)
+{
+ m_QuoteMode[type] = mode;
}
-void CSVBuilder::checkValue(const QString& field, const QVariant& value) {
- auto typeIter = m_FieldTypes.find(field);
- if (typeIter == m_FieldTypes.end()) {
- throw CSVException(QObject::tr("invalid field name \"%1\"").arg(field));
- }
- switch (typeIter->second) {
+void CSVBuilder::setFields(const std::vector<std::pair<QString, EFieldType> > &fields)
+{
+ std::vector<QString> fieldNames;
+ std::map<QString, EFieldType> fieldTypes;
+
+ for (auto iter = fields.begin(); iter != fields.end(); ++iter) {
+ fieldNames.push_back(iter->first);
+ fieldTypes[iter->first] = iter->second;
+ }
+
+ checkFields(fieldNames);
+
+ m_Fields = fieldNames;
+ m_FieldTypes = fieldTypes;
+ m_Defaults.clear();
+ m_RowBuffer.clear();
+
+}
+
+
+void CSVBuilder::checkValue(const QString &field, const QVariant &value)
+{
+ auto typeIter = m_FieldTypes.find(field);
+ if (typeIter == m_FieldTypes.end()) {
+ throw CSVException(QObject::tr("invalid field name \"%1\"").arg(field));
+ }
+
+ switch (typeIter->second) {
case TYPE_INTEGER: {
- if (!value.canConvert<int>()) {
- throw CSVException(QObject::tr("invalid type for \"%1\" (should be integer)").arg(field));
- }
+ if (!value.canConvert<int>()) {
+ throw CSVException(QObject::tr("invalid type for \"%1\" (should be integer)").arg(field));
+ }
} break;
case TYPE_STRING: {
- if (!value.canConvert<QString>()) {
- throw CSVException(QObject::tr("invalid type for \"%1\" (should be string)").arg(field));
- }
+ if (!value.canConvert<QString>()) {
+ throw CSVException(QObject::tr("invalid type for \"%1\" (should be string)").arg(field));
+ }
} break;
case TYPE_FLOAT: {
- if (!value.canConvert<float>()) {
- throw CSVException(QObject::tr("invalid type for \"%1\" (should be float)").arg(field));
- }
+ if (!value.canConvert<float>()) {
+ throw CSVException(QObject::tr("invalid type for \"%1\" (should be float)").arg(field));
+ }
} break;
- }
+ }
}
-void CSVBuilder::setDefault(const QString& field, const QVariant& value) {
- checkValue(field, value);
- m_Defaults[field] = value;
+
+void CSVBuilder::setDefault(const QString &field, const QVariant &value)
+{
+ checkValue(field, value);
+ m_Defaults[field] = value;
}
-void CSVBuilder::writeHeader() {
- if (m_Fields.size() == 0) {
- throw CSVException(QObject::tr("no fields set up yet!"));
- }
- for (auto iter = m_Fields.begin(); iter != m_Fields.end(); ++iter) {
- if (iter != m_Fields.begin()) {
- m_Out << m_Separator;
- }
- m_Out << *iter;
+void CSVBuilder::writeHeader()
+{
+ if (m_Fields.size() == 0) {
+ throw CSVException(QObject::tr("no fields set up yet!"));
+ }
+
+ for (auto iter = m_Fields.begin(); iter != m_Fields.end(); ++iter) {
+ if (iter != m_Fields.begin()) {
+ m_Out << m_Separator;
}
- m_Out << lineBreak();
- m_Out.flush();
+ m_Out << *iter;
+ }
+ m_Out << lineBreak();
+ m_Out.flush();
}
-void CSVBuilder::setRowField(const QString& field, const QVariant& value) {
- checkValue(field, value);
- m_RowBuffer[field] = value;
+
+void CSVBuilder::setRowField(const QString &field, const QVariant &value)
+{
+ checkValue(field, value);
+ m_RowBuffer[field] = value;
}
-void CSVBuilder::writeData(const std::map<QString, QVariant>& data, bool check) {
- QString line;
- QTextStream temp(&line);
- for (auto iter = m_Fields.begin(); iter != m_Fields.end(); ++iter) {
- if (iter != m_Fields.begin()) {
- temp << separator();
- }
+void CSVBuilder::writeData(const std::map<QString, QVariant> &data, bool check)
+{
+ QString line;
+ QTextStream temp(&line);
- QVariant val;
+ for (auto iter = m_Fields.begin(); iter != m_Fields.end(); ++iter) {
+ if (iter != m_Fields.begin()) {
+ temp << separator();
+ }
- auto valIter = data.find(*iter);
- if (valIter == data.end()) {
- auto defaultIter = m_Defaults.find(*iter);
- if (defaultIter == m_Defaults.end()) {
- throw CSVException(QObject::tr("field not set \"%1\"").arg(*iter));
- } else {
- val = defaultIter->second;
- }
- } else {
- val = valIter->second;
- }
+ QVariant val;
- if (check) {
- checkValue(*iter, val);
- }
+ auto valIter = data.find(*iter);
+ if (valIter == data.end()) {
+ auto defaultIter = m_Defaults.find(*iter);
+ if (defaultIter == m_Defaults.end()) {
+ throw CSVException(QObject::tr("field not set \"%1\"").arg(*iter));
+ } else {
+ val = defaultIter->second;
+ }
+ } else {
+ val = valIter->second;
+ }
- switch (m_FieldTypes[*iter]) {
- case TYPE_INTEGER: {
- quoteInsert(temp, val.toInt());
- } break;
- case TYPE_FLOAT: {
- quoteInsert(temp, val.toFloat());
- } break;
- case TYPE_STRING: {
- quoteInsert(temp, val.toString());
- } break;
- }
+ if (check) {
+ checkValue(*iter, val);
}
- m_Out << line << lineBreak();
- m_Out.flush();
+
+ switch (m_FieldTypes[*iter]) {
+ case TYPE_INTEGER: {
+ quoteInsert(temp, val.toInt());
+ } break;
+ case TYPE_FLOAT: {
+ quoteInsert(temp, val.toFloat());
+ } break;
+ case TYPE_STRING: {
+ quoteInsert(temp, val.toString());
+ } break;
+ }
+ }
+ m_Out << line << lineBreak();
+ m_Out.flush();
}
-void CSVBuilder::quoteInsert(QTextStream& stream, int value) {
- switch (m_QuoteMode[TYPE_INTEGER]) {
+
+void CSVBuilder::quoteInsert(QTextStream &stream, int value)
+{
+ switch (m_QuoteMode[TYPE_INTEGER]) {
case QUOTE_NEVER:
case QUOTE_ONDEMAND: {
- stream << value;
+ stream << value;
} break;
case QUOTE_ALWAYS: {
- stream << "\"" << value << "\"";
+ stream << "\"" << value << "\"";
} break;
- }
+ }
}
-void CSVBuilder::quoteInsert(QTextStream& stream, float value) {
- switch (m_QuoteMode[TYPE_FLOAT]) {
+
+void CSVBuilder::quoteInsert(QTextStream &stream, float value)
+{
+ switch (m_QuoteMode[TYPE_FLOAT]) {
case QUOTE_NEVER:
case QUOTE_ONDEMAND: {
- stream << value;
+ stream << value;
} break;
case QUOTE_ALWAYS: {
- stream << "\"" << value << "\"";
+ stream << "\"" << value << "\"";
} break;
- }
+ }
}
-void CSVBuilder::quoteInsert(QTextStream& stream, const QString& value) {
- switch (m_QuoteMode[TYPE_STRING]) {
+
+void CSVBuilder::quoteInsert(QTextStream &stream, const QString &value)
+{
+ switch (m_QuoteMode[TYPE_STRING]) {
case QUOTE_NEVER: {
- stream << value;
+ stream << value;
} break;
case QUOTE_ONDEMAND: {
- if (value.contains("[,\r\n]")) {
- stream << "\"" << value.mid(0).replace("\"", "\"\"") << "\"";
- } else {
- stream << value;
- }
+ if (value.contains("[,\r\n]")) {
+ stream << "\"" << value.mid(0).replace("\"", "\"\"") << "\"";
+ } else {
+ stream << value;
+ }
} break;
case QUOTE_ALWAYS: {
- stream << "\"" << value.mid(0).replace("\"", "\"\"") << "\"";
+ stream << "\"" << value.mid(0).replace("\"", "\"\"") << "\"";
} break;
- }
+ }
+}
+
+
+void CSVBuilder::writeRow()
+{
+ writeData(m_RowBuffer, false); // data was tested on input
+ m_RowBuffer.clear();
}
-void CSVBuilder::writeRow() {
- writeData(m_RowBuffer, false); // data was tested on input
- m_RowBuffer.clear();
+
+void CSVBuilder::addRow(const std::map<QString, QVariant> &data)
+{
+ writeData(data, true);
}
-void CSVBuilder::addRow(const std::map<QString, QVariant>& data) { writeData(data, true); }
-void CSVBuilder::checkFields(const std::vector<QString>& fields) {
- for (auto iter = fields.begin(); iter != fields.end(); ++iter) {
- if (iter->contains(m_Separator) || iter->contains('\r') || iter->contains('\n') || iter->contains('"')) {
- throw CSVException(QObject::tr("invalid character in field \"%1\"").arg(*iter));
- }
- if (iter->length() == 0) {
- throw CSVException(QObject::tr("empty field name"));
- }
+void CSVBuilder::checkFields(const std::vector<QString> &fields)
+{
+ for (auto iter = fields.begin(); iter != fields.end(); ++iter) {
+ if (iter->contains(m_Separator) ||
+ iter->contains('\r') ||
+ iter->contains('\n') ||
+ iter->contains('"')) {
+ throw CSVException(QObject::tr("invalid character in field \"%1\"").arg(*iter));
}
+ if (iter->length() == 0) {
+ throw CSVException(QObject::tr("empty field name"));
+ }
+ }
}
+
/*
if(cell.contains(KDefaultEscapeChar) || cell.contains(KDefaultNewLine)
@@ -207,17 +255,18 @@ if(cell.contains(KDefaultEscapeChar) || cell.contains(KDefaultNewLine)
m_currentLine->append(cell);
}*/
-const char* CSVBuilder::lineBreak() {
- switch (m_LineBreak) {
- case BREAK_CR:
- return "\r";
- case BREAK_CRLF:
- return "\r\n";
- case BREAK_LF:
- return "\n";
- default:
- return "\n"; // default shouldn't be necessary
- }
+
+const char *CSVBuilder::lineBreak()
+{
+ switch (m_LineBreak) {
+ case BREAK_CR: return "\r";
+ case BREAK_CRLF: return "\r\n";
+ case BREAK_LF: return "\n";
+ default: return "\n"; // default shouldn't be necessary
+ }
}
-const char CSVBuilder::separator() { return m_Separator; }
+const char CSVBuilder::separator()
+{
+ return m_Separator;
+}
diff --git a/src/csvbuilder.h b/src/csvbuilder.h
index 70d712c4..f2e0e987 100644
--- a/src/csvbuilder.h
+++ b/src/csvbuilder.h
@@ -1,70 +1,93 @@
#ifndef CSVBUILDER_H
#define CSVBUILDER_H
+
+#include <vector>
#include <QString>
-#include <QTextStream>
#include <QVariant>
-#include <vector>
+#include <QTextStream>
+
class CSVException : public std::exception {
public:
- CSVException(const QString& text) : std::exception(), m_Message(text.toLocal8Bit()) {}
-
- virtual const char* what() const throw() { return m_Message.constData(); }
+ CSVException(const QString &text)
+ : std::exception(), m_Message(text.toLocal8Bit()) {}
+ virtual const char* what() const throw()
+ { return m_Message.constData(); }
private:
- QByteArray m_Message;
+ QByteArray m_Message;
+
};
-class CSVBuilder {
+
+class CSVBuilder
+{
public:
- enum EFieldType { TYPE_INTEGER, TYPE_STRING, TYPE_FLOAT };
- enum EQuoteMode { QUOTE_NEVER, QUOTE_ONDEMAND, QUOTE_ALWAYS };
+ enum EFieldType {
+ TYPE_INTEGER,
+ TYPE_STRING,
+ TYPE_FLOAT
+ };
- enum ELineBreak { BREAK_LF, BREAK_CRLF, BREAK_CR };
+ enum EQuoteMode {
+ QUOTE_NEVER,
+ QUOTE_ONDEMAND,
+ QUOTE_ALWAYS
+ };
+
+ enum ELineBreak {
+ BREAK_LF,
+ BREAK_CRLF,
+ BREAK_CR
+ };
public:
- CSVBuilder(QIODevice* target);
- ~CSVBuilder();
- void setFieldSeparator(char sep);
- void setLineBreak(ELineBreak lineBreak);
- void setEscapeMode(EFieldType type, EQuoteMode mode);
- void setFields(const std::vector<std::pair<QString, EFieldType>>& fields);
- void setDefault(const QString& field, const QVariant& value);
+ CSVBuilder(QIODevice *target);
+ ~CSVBuilder();
+
+ void setFieldSeparator(char sep);
+ void setLineBreak(ELineBreak lineBreak);
+ void setEscapeMode(EFieldType type, EQuoteMode mode);
+ void setFields(const std::vector<std::pair<QString, EFieldType> > &fields);
+ void setDefault(const QString &field, const QVariant &value);
- void writeHeader();
+ void writeHeader();
- void setRowField(const QString& field, const QVariant& value);
- void writeRow();
+ void setRowField(const QString &field, const QVariant &value);
+ void writeRow();
- void addRow(const std::map<QString, QVariant>& data);
+ void addRow(const std::map<QString, QVariant> &data);
private:
- const char* lineBreak();
- const char separator();
- void fieldValid();
- void checkFields(const std::vector<QString>& fields);
- void checkValue(const QString& field, const QVariant& value);
- void writeData(const std::map<QString, QVariant>& data, bool check);
+ const char *lineBreak();
+ const char separator();
- void quoteInsert(QTextStream& stream, int value);
- void quoteInsert(QTextStream& stream, float value);
- void quoteInsert(QTextStream& stream, const QString& value);
+ void fieldValid();
+ void checkFields(const std::vector<QString> &fields);
+ void checkValue(const QString &field, const QVariant &value);
+ void writeData(const std::map<QString, QVariant> &data, bool check);
+
+ void quoteInsert(QTextStream &stream, int value);
+ void quoteInsert(QTextStream &stream, float value);
+ void quoteInsert(QTextStream &stream, const QString &value);
private:
- QTextStream m_Out;
- char m_Separator;
- ELineBreak m_LineBreak;
- std::map<EFieldType, EQuoteMode> m_QuoteMode;
- std::vector<QString> m_Fields;
- std::map<QString, EFieldType> m_FieldTypes;
- std::map<QString, QVariant> m_Defaults;
- std::map<QString, QVariant> m_RowBuffer;
+
+ QTextStream m_Out;
+ char m_Separator;
+ ELineBreak m_LineBreak;
+ std::map<EFieldType, EQuoteMode> m_QuoteMode;
+ std::vector<QString> m_Fields;
+ std::map<QString, EFieldType> m_FieldTypes;
+ std::map<QString, QVariant> m_Defaults;
+ std::map<QString, QVariant> m_RowBuffer;
+
};
#endif // CSVBUILDER_H
diff --git a/src/descriptionpage.h b/src/descriptionpage.h
index 3956b7e8..f6158ee0 100644
--- a/src/descriptionpage.h
+++ b/src/descriptionpage.h
@@ -3,14 +3,17 @@
#ifndef DESCRIPTIONPAGE_H
#define DESCRIPTIONPAGE_H
-class DescriptionPage : public QWebEnginePage {
+class DescriptionPage : public QWebEnginePage
+{
Q_OBJECT
public:
- DescriptionPage(QObject* parent = 0) : QWebEnginePage(parent) {}
+ DescriptionPage(QObject* parent = 0) : QWebEnginePage(parent){}
- bool acceptNavigationRequest(const QUrl& url, QWebEnginePage::NavigationType type, bool isMainFrame) {
- if (type == QWebEnginePage::NavigationTypeLinkClicked) {
+ bool acceptNavigationRequest(const QUrl & url, QWebEnginePage::NavigationType type, bool isMainFrame)
+ {
+ if (type == QWebEnginePage::NavigationTypeLinkClicked)
+ {
emit linkClicked(url);
return false;
}
@@ -19,6 +22,7 @@ public:
signals:
void linkClicked(const QUrl&);
+
};
-#endif // DESCRIPTIONPAGE_H
+#endif //DESCRIPTIONPAGE_H
diff --git a/src/directoryrefresher.cpp b/src/directoryrefresher.cpp
index a1df5146..272b0596 100644
--- a/src/directoryrefresher.cpp
+++ b/src/directoryrefresher.cpp
@@ -20,136 +20,151 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "directoryrefresher.h"
#include "iplugingame.h"
-#include "modinfo.h"
-#include "report.h"
#include "utility.h"
+#include "report.h"
+#include "modinfo.h"
#include <QApplication>
#include <QDir>
#include <QString>
+
using namespace MOBase;
using namespace MOShared;
-DirectoryRefresher::DirectoryRefresher() : m_DirectoryStructure(nullptr) {}
-DirectoryRefresher::~DirectoryRefresher() { delete m_DirectoryStructure; }
+DirectoryRefresher::DirectoryRefresher()
+ : m_DirectoryStructure(nullptr)
+{
+}
-DirectoryEntry* DirectoryRefresher::getDirectoryStructure() {
- QMutexLocker locker(&m_RefreshLock);
- DirectoryEntry* result = m_DirectoryStructure;
- m_DirectoryStructure = nullptr;
- return result;
+DirectoryRefresher::~DirectoryRefresher()
+{
+ delete m_DirectoryStructure;
}
-void DirectoryRefresher::setMods(const std::vector<std::tuple<QString, QString, int>>& mods,
- const std::set<QString>& managedArchives) {
- QMutexLocker locker(&m_RefreshLock);
+DirectoryEntry *DirectoryRefresher::getDirectoryStructure()
+{
+ QMutexLocker locker(&m_RefreshLock);
+ DirectoryEntry *result = m_DirectoryStructure;
+ m_DirectoryStructure = nullptr;
+ return result;
+}
- m_Mods.clear();
- for (auto mod = mods.begin(); mod != mods.end(); ++mod) {
- QString name = std::get<0>(*mod);
- ModInfo::Ptr info = ModInfo::getByIndex(ModInfo::getIndex(name));
- m_Mods.push_back(EntryInfo(name, std::get<1>(*mod), info->stealFiles(), info->archives(), std::get<2>(*mod)));
- }
+void DirectoryRefresher::setMods(const std::vector<std::tuple<QString, QString, int> > &mods
+ , const std::set<QString> &managedArchives)
+{
+ QMutexLocker locker(&m_RefreshLock);
+
+ m_Mods.clear();
+ for (auto mod = mods.begin(); mod != mods.end(); ++mod) {
+ QString name = std::get<0>(*mod);
+ ModInfo::Ptr info = ModInfo::getByIndex(ModInfo::getIndex(name));
+ m_Mods.push_back(EntryInfo(name, std::get<1>(*mod), info->stealFiles(), info->archives(), std::get<2>(*mod)));
+ }
- m_EnabledArchives = managedArchives;
+ m_EnabledArchives = managedArchives;
}
-void DirectoryRefresher::cleanStructure(DirectoryEntry* structure) {
- static const wchar_t* files[] = {L"meta.ini", L"readme.txt"};
- for (int i = 0; i < sizeof(files) / sizeof(wchar_t*); ++i) {
- structure->removeFile(files[i]);
- }
+void DirectoryRefresher::cleanStructure(DirectoryEntry *structure)
+{
+ static const wchar_t *files[] = { L"meta.ini", L"readme.txt" };
+ for (int i = 0; i < sizeof(files) / sizeof(wchar_t*); ++i) {
+ structure->removeFile(files[i]);
+ }
- static const wchar_t* dirs[] = {L"fomod"};
- for (int i = 0; i < sizeof(dirs) / sizeof(wchar_t*); ++i) {
- structure->removeDir(std::wstring(dirs[i]));
- }
+ static const wchar_t *dirs[] = { L"fomod" };
+ for (int i = 0; i < sizeof(dirs) / sizeof(wchar_t*); ++i) {
+ structure->removeDir(std::wstring(dirs[i]));
+ }
}
-void DirectoryRefresher::addModBSAToStructure(DirectoryEntry* directoryStructure, const QString& modName, int priority,
- const QString& directory, const QStringList& archives) {
- std::wstring directoryW = ToWString(QDir::toNativeSeparators(directory));
+void DirectoryRefresher::addModBSAToStructure(DirectoryEntry *directoryStructure, const QString &modName,
+ int priority, const QString &directory, const QStringList &archives)
+{
+ std::wstring directoryW = ToWString(QDir::toNativeSeparators(directory));
- for (const QString& archive : archives) {
- QFileInfo fileInfo(archive);
- if (m_EnabledArchives.find(fileInfo.fileName()) != m_EnabledArchives.end()) {
- try {
- // directoryStructure->addFromBSA(ToWString(modName), directoryW,
- // ToWString(QDir::toNativeSeparators(fileInfo.absoluteFilePath())),
- // priority);
- } catch (const std::exception& e) {
- throw MyException(tr("failed to parse bsa %1: %2").arg(archive, e.what()));
- }
- }
+ for (const QString &archive : archives) {
+ QFileInfo fileInfo(archive);
+ if (m_EnabledArchives.find(fileInfo.fileName()) != m_EnabledArchives.end()) {
+ try {
+ //directoryStructure->addFromBSA(ToWString(modName), directoryW,
+ // ToWString(QDir::toNativeSeparators(fileInfo.absoluteFilePath())), priority);
+ } catch (const std::exception &e) {
+ throw MyException(tr("failed to parse bsa %1: %2").arg(archive, e.what()));
+ }
}
+ }
}
-void DirectoryRefresher::addModFilesToStructure(DirectoryEntry* directoryStructure, const QString& modName,
- int priority, const QString& directory, const QStringList& stealFiles) {
- std::wstring directoryW = ToWString(QDir::toNativeSeparators(directory));
+void DirectoryRefresher::addModFilesToStructure(DirectoryEntry *directoryStructure, const QString &modName,
+ int priority, const QString &directory, const QStringList &stealFiles)
+{
+ std::wstring directoryW = ToWString(QDir::toNativeSeparators(directory));
- if (stealFiles.length() > 0) {
- // instead of adding all the files of the target directory, we just change the root of the specified
- // files to this mod
- FilesOrigin& origin = directoryStructure->createOrigin(ToWString(modName), directoryW, priority);
- for (const QString& filename : stealFiles) {
- QFileInfo fileInfo(filename);
- FileEntry::Ptr file = directoryStructure->findFile(ToWString(fileInfo.fileName()));
- if (file.get() != nullptr) {
- if (file->getOrigin() == 0) {
- // replace data as the origin on this bsa
- file->removeOrigin(0);
- }
- origin.addFile(file->getIndex());
- file->addOrigin(origin.getID(), file->getFileTime(), L"");
- } else {
- qWarning("%s not found", qPrintable(fileInfo.fileName()));
- }
+ if (stealFiles.length() > 0) {
+ // instead of adding all the files of the target directory, we just change the root of the specified
+ // files to this mod
+ FilesOrigin &origin = directoryStructure->createOrigin(ToWString(modName), directoryW, priority);
+ for (const QString &filename : stealFiles) {
+ QFileInfo fileInfo(filename);
+ FileEntry::Ptr file = directoryStructure->findFile(ToWString(fileInfo.fileName()));
+ if (file.get() != nullptr) {
+ if (file->getOrigin() == 0) {
+ // replace data as the origin on this bsa
+ file->removeOrigin(0);
}
- } else {
- directoryStructure->addFromOrigin(ToWString(modName), directoryW, priority);
+ origin.addFile(file->getIndex());
+ file->addOrigin(origin.getID(), file->getFileTime(), L"");
+ } else {
+ qWarning("%s not found", qPrintable(fileInfo.fileName()));
+ }
}
+ } else {
+ directoryStructure->addFromOrigin(ToWString(modName), directoryW, priority);
+ }
}
-void DirectoryRefresher::addModToStructure(DirectoryEntry* directoryStructure, const QString& modName, int priority,
- const QString& directory, const QStringList& stealFiles,
- const QStringList& archives) {
- addModFilesToStructure(directoryStructure, modName, priority, directory, stealFiles);
- addModBSAToStructure(directoryStructure, modName, priority, directory, archives);
+void DirectoryRefresher::addModToStructure(DirectoryEntry *directoryStructure
+ , const QString &modName
+ , int priority
+ , const QString &directory
+ , const QStringList &stealFiles
+ , const QStringList &archives)
+{
+ addModFilesToStructure(directoryStructure, modName, priority, directory, stealFiles);
+ addModBSAToStructure(directoryStructure, modName, priority, directory, archives);
}
-void DirectoryRefresher::refresh() {
- QMutexLocker locker(&m_RefreshLock);
+void DirectoryRefresher::refresh()
+{
+ QMutexLocker locker(&m_RefreshLock);
- delete m_DirectoryStructure;
+ delete m_DirectoryStructure;
- m_DirectoryStructure = new DirectoryEntry(L"data", nullptr, 0);
+ m_DirectoryStructure = new DirectoryEntry(L"data", nullptr, 0);
- IPluginGame* game = qApp->property("managed_game").value<IPluginGame*>();
+ IPluginGame *game = qApp->property("managed_game").value<IPluginGame*>();
- std::wstring dataDirectory = QDir::toNativeSeparators(game->dataDirectory().absolutePath()).toStdWString();
- m_DirectoryStructure->addFromOrigin(L"data", dataDirectory, 0);
+ std::wstring dataDirectory = QDir::toNativeSeparators(game->dataDirectory().absolutePath()).toStdWString();
+ m_DirectoryStructure->addFromOrigin(L"data", dataDirectory, 0);
- // TODO what was the point of having the priority in this tuple? the list is already sorted by priority
- auto iter = m_Mods.begin();
+ // TODO what was the point of having the priority in this tuple? the list is already sorted by priority
+ auto iter = m_Mods.begin();
- // TODO i is the priority here, where higher = more important. the input vector is also sorted by priority but
- // inverted!
- for (int i = 1; iter != m_Mods.end(); ++iter, ++i) {
- try {
- addModToStructure(m_DirectoryStructure, iter->modName, i, iter->absolutePath, iter->stealFiles,
- iter->archives);
- } catch (const std::exception& e) {
- emit error(tr("failed to read mod (%1): %2").arg(iter->modName, e.what()));
- }
- emit progress((i * 100) / static_cast<int>(m_Mods.size()) + 1);
+ //TODO i is the priority here, where higher = more important. the input vector is also sorted by priority but inverted!
+ for (int i = 1; iter != m_Mods.end(); ++iter, ++i) {
+ try {
+ addModToStructure(m_DirectoryStructure, iter->modName, i, iter->absolutePath, iter->stealFiles, iter->archives);
+ } catch (const std::exception &e) {
+ emit error(tr("failed to read mod (%1): %2").arg(iter->modName, e.what()));
}
+ emit progress((i * 100) / static_cast<int>(m_Mods.size()) + 1);
+ }
- emit progress(100);
+ emit progress(100);
- cleanStructure(m_DirectoryStructure);
+ cleanStructure(m_DirectoryStructure);
- emit refreshed();
+ emit refreshed();
}
diff --git a/src/directoryrefresher.h b/src/directoryrefresher.h
index dbe36aa4..53709e1e 100644
--- a/src/directoryrefresher.h
+++ b/src/directoryrefresher.h
@@ -20,126 +20,128 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef DIRECTORYREFRESHER_H
#define DIRECTORYREFRESHER_H
-#include <QMutex>
+#include <directoryentry.h>
#include <QObject>
+#include <QMutex>
#include <QStringList>
-#include <directoryentry.h>
+#include <vector>
#include <set>
#include <tuple>
-#include <vector>
+
/**
* @brief used to asynchronously generate the virtual view of the combined data directory
**/
-class DirectoryRefresher : public QObject {
+class DirectoryRefresher : public QObject
+{
- Q_OBJECT
+ Q_OBJECT
public:
- /**
- * @brief constructor
- *
- **/
- DirectoryRefresher();
- ~DirectoryRefresher();
+ /**
+ * @brief constructor
+ *
+ **/
+ DirectoryRefresher();
+
+ ~DirectoryRefresher();
- /**
- * @brief retrieve the updated directory structure
- *
- * returns a pointer to the updated directory structure. DirectoryRefresher
- * deletes its own pointer and the caller takes custody of the pointer
- *
- * @return updated directory structure
- **/
- MOShared::DirectoryEntry* getDirectoryStructure();
+ /**
+ * @brief retrieve the updated directory structure
+ *
+ * returns a pointer to the updated directory structure. DirectoryRefresher
+ * deletes its own pointer and the caller takes custody of the pointer
+ *
+ * @return updated directory structure
+ **/
+ MOShared::DirectoryEntry *getDirectoryStructure();
- /**
- * @brief sets up the mods to be included in the directory structure
- *
- * @param mods list of the mods to include
- **/
- void setMods(const std::vector<std::tuple<QString, QString, int>>& mods, const std::set<QString>& managedArchives);
+ /**
+ * @brief sets up the mods to be included in the directory structure
+ *
+ * @param mods list of the mods to include
+ **/
+ void setMods(const std::vector<std::tuple<QString, QString, int> > &mods, const std::set<QString> &managedArchives);
- /**
- * @brief sets up the directory where mods are stored
- * @param modDirectory the mod directory
- * @note this function could be obsoleted easily by storing absolute paths in the parameter to setMods. This is
- * legacy
- */
- void setModDirectory(const QString& modDirectory);
+ /**
+ * @brief sets up the directory where mods are stored
+ * @param modDirectory the mod directory
+ * @note this function could be obsoleted easily by storing absolute paths in the parameter to setMods. This is legacy
+ */
+ void setModDirectory(const QString &modDirectory);
- /**
- * @brief remove files from the directory structure that are known to be irrelevant to the game
- * @param the structure to clean
- */
- static void cleanStructure(MOShared::DirectoryEntry* structure);
+ /**
+ * @brief remove files from the directory structure that are known to be irrelevant to the game
+ * @param the structure to clean
+ */
+ static void cleanStructure(MOShared::DirectoryEntry *structure);
- /**
- * @brief add files for a mod to the directory structure, including bsas
- * @param directoryStructure
- * @param modName
- * @param priority
- * @param directory
- * @param stealFiles
- * @param archives
- */
- void addModToStructure(MOShared::DirectoryEntry* directoryStructure, const QString& modName, int priority,
- const QString& directory, const QStringList& stealFiles, const QStringList& archives);
+ /**
+ * @brief add files for a mod to the directory structure, including bsas
+ * @param directoryStructure
+ * @param modName
+ * @param priority
+ * @param directory
+ * @param stealFiles
+ * @param archives
+ */
+ void addModToStructure(MOShared::DirectoryEntry *directoryStructure, const QString &modName, int priority, const QString &directory, const QStringList &stealFiles, const QStringList &archives);
- /**
- * @brief add only the bsas of a mod to the directory structure
- * @param directoryStructure
- * @param modName
- * @param priority
- * @param directory
- * @param archives
- */
- void addModBSAToStructure(MOShared::DirectoryEntry* directoryStructure, const QString& modName, int priority,
- const QString& directory, const QStringList& archives);
+ /**
+ * @brief add only the bsas of a mod to the directory structure
+ * @param directoryStructure
+ * @param modName
+ * @param priority
+ * @param directory
+ * @param archives
+ */
+ void addModBSAToStructure(MOShared::DirectoryEntry *directoryStructure, const QString &modName, int priority, const QString &directory, const QStringList &archives);
- /**
- * @brief add only regular files ofr a mod to the directory structure
- * @param directoryStructure
- * @param modName
- * @param priority
- * @param directory
- * @param stealFiles
- */
- void addModFilesToStructure(MOShared::DirectoryEntry* directoryStructure, const QString& modName, int priority,
- const QString& directory, const QStringList& stealFiles);
+ /**
+ * @brief add only regular files ofr a mod to the directory structure
+ * @param directoryStructure
+ * @param modName
+ * @param priority
+ * @param directory
+ * @param stealFiles
+ */
+ void addModFilesToStructure(MOShared::DirectoryEntry *directoryStructure, const QString &modName, int priority, const QString &directory, const QStringList &stealFiles);
public slots:
- /**
- * @brief generate a directory structure from the mods set earlier
- **/
- void refresh();
+ /**
+ * @brief generate a directory structure from the mods set earlier
+ **/
+ void refresh();
signals:
- void progress(int progress);
- void error(const QString& error);
- void refreshed();
+ void progress(int progress);
+ void error(const QString &error);
+ void refreshed();
private:
- struct EntryInfo {
- EntryInfo(const QString& modName, const QString& absolutePath, const QStringList& stealFiles,
- const QStringList& archives, int priority)
- : modName(modName), absolutePath(absolutePath), stealFiles(stealFiles), archives(archives),
- priority(priority) {}
- QString modName;
- QString absolutePath;
- QStringList stealFiles;
- QStringList archives;
- int priority;
- };
+
+ struct EntryInfo {
+ EntryInfo(const QString &modName, const QString &absolutePath,
+ const QStringList &stealFiles, const QStringList &archives, int priority)
+ : modName(modName), absolutePath(absolutePath), stealFiles(stealFiles)
+ , archives(archives), priority(priority) {}
+ QString modName;
+ QString absolutePath;
+ QStringList stealFiles;
+ QStringList archives;
+ int priority;
+ };
private:
- std::vector<EntryInfo> m_Mods;
- std::set<QString> m_EnabledArchives;
- MOShared::DirectoryEntry* m_DirectoryStructure;
- QMutex m_RefreshLock;
+
+ std::vector<EntryInfo> m_Mods;
+ std::set<QString> m_EnabledArchives;
+ MOShared::DirectoryEntry *m_DirectoryStructure;
+ QMutex m_RefreshLock;
+
};
#endif // DIRECTORYREFRESHER_H
diff --git a/src/downloadlist.cpp b/src/downloadlist.cpp
index 4feffa04..f13cdef1 100644
--- a/src/downloadlist.cpp
+++ b/src/downloadlist.cpp
@@ -23,71 +23,92 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QSortFilterProxyModel>
-DownloadList::DownloadList(DownloadManager* manager, QObject* parent)
- : QAbstractTableModel(parent), m_Manager(manager) {
- connect(m_Manager, SIGNAL(update(int)), this, SLOT(update(int)));
- connect(m_Manager, SIGNAL(aboutToUpdate()), this, SLOT(aboutToUpdate()));
+
+DownloadList::DownloadList(DownloadManager *manager, QObject *parent)
+ : QAbstractTableModel(parent), m_Manager(manager)
+{
+ connect(m_Manager, SIGNAL(update(int)), this, SLOT(update(int)));
+ connect(m_Manager, SIGNAL(aboutToUpdate()), this, SLOT(aboutToUpdate()));
}
-int DownloadList::rowCount(const QModelIndex&) const {
- return m_Manager->numTotalDownloads() + m_Manager->numPendingDownloads();
+
+int DownloadList::rowCount(const QModelIndex&) const
+{
+ return m_Manager->numTotalDownloads() + m_Manager->numPendingDownloads();
}
-int DownloadList::columnCount(const QModelIndex&) const { return 3; }
-QModelIndex DownloadList::index(int row, int column, const QModelIndex&) const { return createIndex(row, column, row); }
+int DownloadList::columnCount(const QModelIndex&) const
+{
+ return 3;
+}
-QModelIndex DownloadList::parent(const QModelIndex&) const { return QModelIndex(); }
-QVariant DownloadList::headerData(int section, Qt::Orientation orientation, int role) const {
- if ((role == Qt::DisplayRole) && (orientation == Qt::Horizontal)) {
- switch (section) {
- case COL_NAME:
- return tr("Name");
- case COL_FILETIME:
- return tr("Filetime");
- default:
- return tr("Done");
- }
- } else {
- return QAbstractItemModel::headerData(section, orientation, role);
+QModelIndex DownloadList::index(int row, int column, const QModelIndex&) const
+{
+ return createIndex(row, column, row);
+}
+
+
+QModelIndex DownloadList::parent(const QModelIndex&) const
+{
+ return QModelIndex();
+}
+
+
+QVariant DownloadList::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if ((role == Qt::DisplayRole) &&
+ (orientation == Qt::Horizontal)) {
+ switch (section) {
+ case COL_NAME: return tr("Name");
+ case COL_FILETIME: return tr("Filetime");
+ default: return tr("Done");
}
+ } else {
+ return QAbstractItemModel::headerData(section, orientation, role);
+ }
}
-QVariant DownloadList::data(const QModelIndex& index, int role) const {
- if (role == Qt::DisplayRole) {
- return index.row();
- } else if (role == Qt::ToolTipRole) {
- if (index.row() < m_Manager->numTotalDownloads()) {
- QString text = m_Manager->getFileName(index.row()) + "\n";
- if (m_Manager->isInfoIncomplete(index.row())) {
- text += tr("Information missing, please select \"Query Info\" from the context menu to re-retrieve.");
- } else {
- const MOBase::ModRepositoryFileInfo* info = m_Manager->getFileInfo(index.row());
- return QString("%1 (ID %2) %3<br><span>%4</span>")
- .arg(info->modName)
- .arg(m_Manager->getModID(index.row()))
- .arg(info->version.canonicalString())
- .arg(info->description);
- }
- return text;
- } else {
- return tr("pending download");
- }
+
+QVariant DownloadList::data(const QModelIndex &index, int role) const
+{
+ if (role == Qt::DisplayRole) {
+ return index.row();
+ } else if (role == Qt::ToolTipRole) {
+ if (index.row() < m_Manager->numTotalDownloads()) {
+ QString text = m_Manager->getFileName(index.row()) + "\n";
+ if (m_Manager->isInfoIncomplete(index.row())) {
+ text += tr("Information missing, please select \"Query Info\" from the context menu to re-retrieve.");
+ } else {
+ const MOBase::ModRepositoryFileInfo *info = m_Manager->getFileInfo(index.row());
+ return QString("%1 (ID %2) %3<br><span>%4</span>").arg(info->modName).arg(m_Manager->getModID(index.row())).arg(info->version.canonicalString()).arg(info->description);
+ }
+ return text;
} else {
- return QVariant();
+ return tr("pending download");
}
+ } else {
+ return QVariant();
+ }
+}
+
+
+void DownloadList::aboutToUpdate()
+{
+ emit beginResetModel();
}
-void DownloadList::aboutToUpdate() { emit beginResetModel(); }
-void DownloadList::update(int row) {
- if (row < 0) {
- emit endResetModel();
- } else if (row < this->rowCount()) {
+void DownloadList::update(int row)
+{
+ if (row < 0) {
+ emit endResetModel();
+ } else if (row < this->rowCount()) {
#pragma message("updating only the one column is a hack")
- emit dataChanged(this->index(row, 2, QModelIndex()), this->index(row, 2, QModelIndex()));
- } else {
- qCritical("invalid row %d in download list, update failed", row);
- }
+ emit dataChanged(this->index(row, 2, QModelIndex()), this->index(row, 2, QModelIndex()));
+ } else {
+ qCritical("invalid row %d in download list, update failed", row);
+ }
}
+
diff --git a/src/downloadlist.h b/src/downloadlist.h
index 4765a098..2316dddc 100644
--- a/src/downloadlist.h
+++ b/src/downloadlist.h
@@ -22,65 +22,75 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QAbstractTableModel>
+
class DownloadManager;
+
/**
* @brief model of the list of active and completed downloads
**/
-class DownloadList : public QAbstractTableModel {
+class DownloadList : public QAbstractTableModel
+{
- Q_OBJECT
+ Q_OBJECT
public:
- enum EColumn { COL_NAME = 0, COL_FILETIME, COL_STATUS };
+
+ enum EColumn {
+ COL_NAME = 0,
+ COL_FILETIME,
+ COL_STATUS
+ };
public:
- /**
- * @brief constructor
- *
- * @param manager the download manager processing downloads
- * @param parent parent object Defaults to 0.
- **/
- explicit DownloadList(DownloadManager* manager, QObject* parent = 0);
- /**
- * @brief retrieve the number of rows to display. Invoked by Qt
- *
- * @param parent not relevant for this implementation
- * @return number of rows to display
- **/
- virtual int rowCount(const QModelIndex& parent = QModelIndex()) const;
+ /**
+ * @brief constructor
+ *
+ * @param manager the download manager processing downloads
+ * @param parent parent object Defaults to 0.
+ **/
+ explicit DownloadList(DownloadManager *manager, QObject *parent = 0);
- virtual int columnCount(const QModelIndex& parent) const;
+ /**
+ * @brief retrieve the number of rows to display. Invoked by Qt
+ *
+ * @param parent not relevant for this implementation
+ * @return number of rows to display
+ **/
+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
- QModelIndex index(int row, int column, const QModelIndex& parent) const;
- QModelIndex parent(const QModelIndex& child) const;
+ virtual int columnCount(const QModelIndex &parent) const;
- virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
+ QModelIndex index(int row, int column, const QModelIndex &parent) const;
+ QModelIndex parent(const QModelIndex &child) const;
- /**
- * @brief retrieve the data to display in a specific row. Invoked by Qt
- *
- * @param index location to look up
- * @param role ... Defaults to Qt::DisplayRole.
- * @return this implementation only returns the row, the QItemDelegate implementation is expected to fetch its
- *information from the DownloadManager
- **/
- virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
+ virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
+
+ /**
+ * @brief retrieve the data to display in a specific row. Invoked by Qt
+ *
+ * @param index location to look up
+ * @param role ... Defaults to Qt::DisplayRole.
+ * @return this implementation only returns the row, the QItemDelegate implementation is expected to fetch its information from the DownloadManager
+ **/
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
public slots:
- /**
- * @brief used to inform the model that data has changed
- *
- * @param row the row that changed. This can be negative to update the whole view
- **/
- void update(int row);
+ /**
+ * @brief used to inform the model that data has changed
+ *
+ * @param row the row that changed. This can be negative to update the whole view
+ **/
+ void update(int row);
- void aboutToUpdate();
+ void aboutToUpdate();
private:
- DownloadManager* m_Manager;
+
+ DownloadManager *m_Manager;
+
};
#endif // DOWNLOADLIST_H
diff --git a/src/downloadlistsortproxy.cpp b/src/downloadlistsortproxy.cpp
index bef8ffc2..2780f973 100644
--- a/src/downloadlistsortproxy.cpp
+++ b/src/downloadlistsortproxy.cpp
@@ -22,43 +22,52 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "downloadmanager.h"
#include "settings.h"
-DownloadListSortProxy::DownloadListSortProxy(const DownloadManager* manager, QObject* parent)
- : QSortFilterProxyModel(parent), m_Manager(manager), m_CurrentFilter() {}
+DownloadListSortProxy::DownloadListSortProxy(const DownloadManager *manager, QObject *parent)
+ : QSortFilterProxyModel(parent), m_Manager(manager), m_CurrentFilter()
+{
+}
-void DownloadListSortProxy::updateFilter(const QString& filter) {
- m_CurrentFilter = filter;
- invalidateFilter();
+void DownloadListSortProxy::updateFilter(const QString &filter)
+{
+ m_CurrentFilter = filter;
+ invalidateFilter();
}
-bool DownloadListSortProxy::lessThan(const QModelIndex& left, const QModelIndex& right) const {
- int leftIndex = left.data().toInt();
- int rightIndex = right.data().toInt();
- if ((leftIndex < m_Manager->numTotalDownloads()) && (rightIndex < m_Manager->numTotalDownloads())) {
- if (left.column() == DownloadList::COL_NAME) {
- return m_Manager->getFileName(leftIndex).compare(m_Manager->getFileName(rightIndex), Qt::CaseInsensitive) <
- 0;
- } else if (left.column() == DownloadList::COL_FILETIME) {
- return m_Manager->getFileTime(leftIndex) < m_Manager->getFileTime(rightIndex);
- } else if (left.column() == DownloadList::COL_STATUS) {
- return m_Manager->getState(leftIndex) < m_Manager->getState(rightIndex);
- } else {
- return leftIndex < rightIndex;
- }
+
+bool DownloadListSortProxy::lessThan(const QModelIndex &left,
+ const QModelIndex &right) const
+{
+ int leftIndex = left.data().toInt();
+ int rightIndex = right.data().toInt();
+ if ((leftIndex < m_Manager->numTotalDownloads())
+ && (rightIndex < m_Manager->numTotalDownloads())) {
+ if (left.column() == DownloadList::COL_NAME) {
+ return m_Manager->getFileName(leftIndex).compare(m_Manager->getFileName(rightIndex), Qt::CaseInsensitive) < 0;
+ } else if (left.column() == DownloadList::COL_FILETIME) {
+ return m_Manager->getFileTime(leftIndex) < m_Manager->getFileTime(rightIndex);
+ } else if (left.column() == DownloadList::COL_STATUS) {
+ return m_Manager->getState(leftIndex) < m_Manager->getState(rightIndex);
} else {
- return leftIndex < rightIndex;
+ return leftIndex < rightIndex;
}
+ } else {
+ return leftIndex < rightIndex;
+ }
}
-bool DownloadListSortProxy::filterAcceptsRow(int sourceRow, const QModelIndex&) const {
- if (m_CurrentFilter.length() == 0) {
- return true;
- } else if (sourceRow < m_Manager->numTotalDownloads()) {
- int downloadIndex = sourceModel()->index(sourceRow, 0).data().toInt();
- QString displayedName = Settings::instance().metaDownloads() ? m_Manager->getDisplayName(downloadIndex)
- : m_Manager->getFileName(downloadIndex);
- return displayedName.contains(m_CurrentFilter, Qt::CaseInsensitive);
- } else {
- return false;
- }
+bool DownloadListSortProxy::filterAcceptsRow(int sourceRow, const QModelIndex&) const
+{
+ if (m_CurrentFilter.length() == 0) {
+ return true;
+ } else if (sourceRow < m_Manager->numTotalDownloads()) {
+ int downloadIndex = sourceModel()->index(sourceRow, 0).data().toInt();
+
+ QString displayedName = Settings::instance().metaDownloads()
+ ? m_Manager->getDisplayName(downloadIndex)
+ : m_Manager->getFileName(downloadIndex);
+ return displayedName.contains(m_CurrentFilter, Qt::CaseInsensitive);
+ } else {
+ return false;
+ }
}
diff --git a/src/downloadlistsortproxy.h b/src/downloadlistsortproxy.h
index 9cb16a83..59f46179 100644
--- a/src/downloadlistsortproxy.h
+++ b/src/downloadlistsortproxy.h
@@ -20,30 +20,39 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef DOWNLOADLISTSORTPROXY_H
#define DOWNLOADLISTSORTPROXY_H
+
#include <QSortFilterProxyModel>
+
class DownloadManager;
-class DownloadListSortProxy : public QSortFilterProxyModel {
- Q_OBJECT
+
+class DownloadListSortProxy : public QSortFilterProxyModel
+{
+ Q_OBJECT
public:
- explicit DownloadListSortProxy(const DownloadManager* manager, QObject* parent = 0);
+
+ explicit DownloadListSortProxy(const DownloadManager *manager, QObject *parent = 0);
public slots:
- void updateFilter(const QString& filter);
+ void updateFilter(const QString &filter);
protected:
- bool lessThan(const QModelIndex& left, const QModelIndex& right) const;
- bool filterAcceptsRow(int sourceRow, const QModelIndex& source_parent) const;
-signals:
+ bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
+ bool filterAcceptsRow(int sourceRow, const QModelIndex &source_parent) const;
+signals:
+
public slots:
private:
- const DownloadManager* m_Manager;
- QString m_CurrentFilter;
+
+ const DownloadManager *m_Manager;
+ QString m_CurrentFilter;
+
+
};
#endif // DOWNLOADLISTSORTPROXY_H
diff --git a/src/downloadlistwidget.cpp b/src/downloadlistwidget.cpp
index 29b027a4..9a8ef572 100644
--- a/src/downloadlistwidget.cpp
+++ b/src/downloadlistwidget.cpp
@@ -19,280 +19,332 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "downloadlistwidget.h"
#include "ui_downloadlistwidget.h"
+#include <QPainter>
+#include <QMouseEvent>
#include <QMenu>
#include <QMessageBox>
-#include <QMouseEvent>
-#include <QPainter>
#include <QSortFilterProxyModel>
-DownloadListWidget::DownloadListWidget(QWidget* parent) : QWidget(parent), ui(new Ui::DownloadListWidget) {
- ui->setupUi(this);
+
+DownloadListWidget::DownloadListWidget(QWidget *parent)
+ : QWidget(parent), ui(new Ui::DownloadListWidget)
+{
+ ui->setupUi(this);
}
-DownloadListWidget::~DownloadListWidget() { delete ui; }
-DownloadListWidgetDelegate::DownloadListWidgetDelegate(DownloadManager* manager, bool metaDisplay, QTreeView* view,
- QObject* parent)
- : QItemDelegate(parent), m_Manager(manager), m_MetaDisplay(metaDisplay), m_ItemWidget(new DownloadListWidget),
- m_ContextRow(0), m_View(view) {
- m_NameLabel = m_ItemWidget->findChild<QLabel*>("nameLabel");
- m_SizeLabel = m_ItemWidget->findChild<QLabel*>("sizeLabel");
- m_Progress = m_ItemWidget->findChild<QProgressBar*>("downloadProgress");
- m_InstallLabel = m_ItemWidget->findChild<QLabel*>("installLabel");
+DownloadListWidget::~DownloadListWidget()
+{
+ delete ui;
+}
+
- m_InstallLabel->setVisible(false);
+DownloadListWidgetDelegate::DownloadListWidgetDelegate(DownloadManager *manager, bool metaDisplay, QTreeView *view, QObject *parent)
+ : QItemDelegate(parent)
+ , m_Manager(manager)
+ , m_MetaDisplay(metaDisplay)
+ , m_ItemWidget(new DownloadListWidget)
+ , m_ContextRow(0)
+ , m_View(view)
+{
+ m_NameLabel = m_ItemWidget->findChild<QLabel*>("nameLabel");
+ m_SizeLabel = m_ItemWidget->findChild<QLabel*>("sizeLabel");
+ m_Progress = m_ItemWidget->findChild<QProgressBar*>("downloadProgress");
+ m_InstallLabel = m_ItemWidget->findChild<QLabel*>("installLabel");
- connect(manager, SIGNAL(stateChanged(int, DownloadManager::DownloadState)), this,
- SLOT(stateChanged(int, DownloadManager::DownloadState)));
- connect(manager, SIGNAL(downloadRemoved(int)), this, SLOT(resetCache(int)));
+ m_InstallLabel->setVisible(false);
+
+ connect(manager, SIGNAL(stateChanged(int,DownloadManager::DownloadState)), this, SLOT(stateChanged(int,DownloadManager::DownloadState)));
+ connect(manager, SIGNAL(downloadRemoved(int)), this, SLOT(resetCache(int)));
}
-DownloadListWidgetDelegate::~DownloadListWidgetDelegate() { delete m_ItemWidget; }
-void DownloadListWidgetDelegate::stateChanged(int row, DownloadManager::DownloadState) { m_Cache.remove(row); }
+DownloadListWidgetDelegate::~DownloadListWidgetDelegate()
+{
+ delete m_ItemWidget;
+}
-void DownloadListWidgetDelegate::resetCache(int) { m_Cache.clear(); }
-void DownloadListWidgetDelegate::drawCache(QPainter* painter, const QStyleOptionViewItem& option,
- const QPixmap& cache) const {
- QRect rect = option.rect;
- rect.setLeft(0);
- rect.setWidth(m_View->columnWidth(0) + m_View->columnWidth(1) + m_View->columnWidth(2));
- painter->drawPixmap(rect, cache);
+void DownloadListWidgetDelegate::stateChanged(int row,DownloadManager::DownloadState)
+{
+ m_Cache.remove(row);
}
-void DownloadListWidgetDelegate::paintPendingDownload(int downloadIndex) const {
- std::pair<int, int> nexusids = m_Manager->getPendingDownload(downloadIndex);
- m_NameLabel->setText(tr("< mod %1 file %2 >").arg(nexusids.first).arg(nexusids.second));
- m_SizeLabel->setText("???");
- m_InstallLabel->setVisible(true);
- m_InstallLabel->setText(tr("Pending"));
- m_Progress->setVisible(false);
+
+void DownloadListWidgetDelegate::resetCache(int)
+{
+ m_Cache.clear();
}
-void DownloadListWidgetDelegate::paintRegularDownload(int downloadIndex) const {
- QString name = m_MetaDisplay ? m_Manager->getDisplayName(downloadIndex) : m_Manager->getFileName(downloadIndex);
- if (name.length() > 53) {
- name.truncate(50);
- name.append("...");
- }
- m_NameLabel->setText(name);
- m_SizeLabel->setText(QString::number(m_Manager->getFileSize(downloadIndex) / 1024));
- DownloadManager::DownloadState state = m_Manager->getState(downloadIndex);
- if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
- QPalette labelPalette;
- m_InstallLabel->setVisible(true);
- m_Progress->setVisible(false);
-#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
- m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Paused - Double Click to resume", 0));
+
+void DownloadListWidgetDelegate::drawCache(QPainter *painter, const QStyleOptionViewItem &option, const QPixmap &cache) const
+{
+ QRect rect = option.rect;
+ rect.setLeft(0);
+ rect.setWidth(m_View->columnWidth(0) + m_View->columnWidth(1) + m_View->columnWidth(2));
+ painter->drawPixmap(rect, cache);
+}
+
+
+void DownloadListWidgetDelegate::paintPendingDownload(int downloadIndex) const
+{
+ std::pair<int, int> nexusids = m_Manager->getPendingDownload(downloadIndex);
+ m_NameLabel->setText(tr("< mod %1 file %2 >").arg(nexusids.first).arg(nexusids.second));
+ m_SizeLabel->setText("???");
+ m_InstallLabel->setVisible(true);
+ m_InstallLabel->setText(tr("Pending"));
+ m_Progress->setVisible(false);
+}
+
+
+void DownloadListWidgetDelegate::paintRegularDownload(int downloadIndex) const
+{
+ QString name = m_MetaDisplay ? m_Manager->getDisplayName(downloadIndex) : m_Manager->getFileName(downloadIndex);
+ if (name.length() > 53) {
+ name.truncate(50);
+ name.append("...");
+ }
+ m_NameLabel->setText(name);
+ m_SizeLabel->setText(QString::number(m_Manager->getFileSize(downloadIndex) / 1024));
+ DownloadManager::DownloadState state = m_Manager->getState(downloadIndex);
+ if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
+ QPalette labelPalette;
+ m_InstallLabel->setVisible(true);
+ m_Progress->setVisible(false);
+#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
+ m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Paused - Double Click to resume", 0));
#else
- m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Paused - Double Click to resume", 0,
- QApplication::UnicodeUTF8));
+ m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Paused - Double Click to resume", 0, QApplication::UnicodeUTF8));
#endif
- labelPalette.setColor(QPalette::WindowText, Qt::darkRed);
- m_InstallLabel->setPalette(labelPalette);
- } else if (state == DownloadManager::STATE_FETCHINGMODINFO) {
- m_InstallLabel->setText(tr("Fetching Info 1"));
- m_Progress->setVisible(false);
- } else if (state == DownloadManager::STATE_FETCHINGFILEINFO) {
- m_InstallLabel->setText(tr("Fetching Info 2"));
- m_Progress->setVisible(false);
- } else if (state >= DownloadManager::STATE_READY) {
- QPalette labelPalette;
- m_InstallLabel->setVisible(true);
- m_Progress->setVisible(false);
- if (state == DownloadManager::STATE_INSTALLED) {
- // the tr-macro doesn't work here, maybe because the translation is actually associated with DownloadListWidget
- // instead of DownloadListWidgetDelegate?
-#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
- m_InstallLabel->setText(
- QApplication::translate("DownloadListWidget", "Installed - Double Click to re-install", 0));
+ labelPalette.setColor(QPalette::WindowText, Qt::darkRed);
+ m_InstallLabel->setPalette(labelPalette);
+ } else if (state == DownloadManager::STATE_FETCHINGMODINFO) {
+ m_InstallLabel->setText(tr("Fetching Info 1"));
+ m_Progress->setVisible(false);
+ } else if (state == DownloadManager::STATE_FETCHINGFILEINFO) {
+ m_InstallLabel->setText(tr("Fetching Info 2"));
+ m_Progress->setVisible(false);
+ } else if (state >= DownloadManager::STATE_READY) {
+ QPalette labelPalette;
+ m_InstallLabel->setVisible(true);
+ m_Progress->setVisible(false);
+ if (state == DownloadManager::STATE_INSTALLED) {
+ // the tr-macro doesn't work here, maybe because the translation is actually associated with DownloadListWidget instead
+ // of DownloadListWidgetDelegate?
+#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
+ m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Installed - Double Click to re-install", 0));
#else
- m_InstallLabel->setText(QApplication::translate(
- "DownloadListWidget", "Installed - Double Click to re-install", 0, QApplication::UnicodeUTF8));
+ m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Installed - Double Click to re-install", 0, QApplication::UnicodeUTF8));
#endif
- labelPalette.setColor(QPalette::WindowText, Qt::darkGray);
- } else if (state == DownloadManager::STATE_UNINSTALLED) {
-#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
- m_InstallLabel->setText(
- QApplication::translate("DownloadListWidget", "Uninstalled - Double Click to re-install", 0));
+ labelPalette.setColor(QPalette::WindowText, Qt::darkGray);
+ } else if (state == DownloadManager::STATE_UNINSTALLED) {
+#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
+ m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Uninstalled - Double Click to re-install", 0));
#else
- m_InstallLabel->setText(QApplication::translate(
- "DownloadListWidget", "Uninstalled - Double Click to re-install", 0, QApplication::UnicodeUTF8));
+ m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Uninstalled - Double Click to re-install", 0, QApplication::UnicodeUTF8));
#endif
- labelPalette.setColor(QPalette::WindowText, Qt::lightGray);
- } else {
-#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
- m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Done - Double Click to install", 0));
+ labelPalette.setColor(QPalette::WindowText, Qt::lightGray);
+ } else {
+#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
+ m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Done - Double Click to install", 0));
#else
- m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Done - Double Click to install", 0,
- QApplication::UnicodeUTF8));
+ m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Done - Double Click to install", 0, QApplication::UnicodeUTF8));
#endif
- labelPalette.setColor(QPalette::WindowText, Qt::darkGreen);
- }
- m_InstallLabel->setPalette(labelPalette);
- if (m_Manager->isInfoIncomplete(downloadIndex)) {
- m_NameLabel->setText("<img src=\":/MO/gui/warning_16\" /> " + m_NameLabel->text());
- }
- } else {
- m_InstallLabel->setVisible(false);
- m_Progress->setVisible(true);
- m_Progress->setValue(m_Manager->getProgress(downloadIndex));
+ labelPalette.setColor(QPalette::WindowText, Qt::darkGreen);
}
+ m_InstallLabel->setPalette(labelPalette);
+ if (m_Manager->isInfoIncomplete(downloadIndex)) {
+ m_NameLabel->setText("<img src=\":/MO/gui/warning_16\" /> " + m_NameLabel->text());
+ }
+ } else {
+ m_InstallLabel->setVisible(false);
+ m_Progress->setVisible(true);
+ m_Progress->setValue(m_Manager->getProgress(downloadIndex));
+ }
}
-void DownloadListWidgetDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,
- const QModelIndex& index) const {
- try {
- auto iter = m_Cache.find(index.row());
- if (iter != m_Cache.end()) {
- drawCache(painter, option, *iter);
- return;
- }
+void DownloadListWidgetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ try {
+ auto iter = m_Cache.find(index.row());
+ if (iter != m_Cache.end()) {
+ drawCache(painter, option, *iter);
+ return;
+ }
- m_ItemWidget->resize(
- QSize(m_View->columnWidth(0) + m_View->columnWidth(1) + m_View->columnWidth(2), option.rect.height()));
+ m_ItemWidget->resize(QSize(m_View->columnWidth(0) + m_View->columnWidth(1) + m_View->columnWidth(2), option.rect.height()));
- int downloadIndex = index.data().toInt();
+ int downloadIndex = index.data().toInt();
- if (downloadIndex >= m_Manager->numTotalDownloads()) {
- paintPendingDownload(downloadIndex - m_Manager->numTotalDownloads());
- } else {
- paintRegularDownload(downloadIndex);
- }
+ if (downloadIndex >= m_Manager->numTotalDownloads()) {
+ paintPendingDownload(downloadIndex - m_Manager->numTotalDownloads());
+ } else {
+ paintRegularDownload(downloadIndex);
+ }
#pragma message("caching disabled because changes in the list (including resorting) doesn't work correctly")
- // if (state >= DownloadManager::STATE_READY) {
- if (false) {
-#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
- QPixmap cache = m_ItemWidget->grab();
+// if (state >= DownloadManager::STATE_READY) {
+ if (false) {
+#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
+ QPixmap cache = m_ItemWidget->grab();
#else
- QPixmap cache = QPixmap::grabWidget(m_ItemWidget);
+ QPixmap cache = QPixmap::grabWidget(m_ItemWidget);
#endif
- m_Cache[index.row()] = cache;
- drawCache(painter, option, cache);
- } else {
- painter->save();
- painter->translate(QPoint(0, option.rect.topLeft().y()));
+ m_Cache[index.row()] = cache;
+ drawCache(painter, option, cache);
+ } else {
+ painter->save();
+ painter->translate(QPoint(0, option.rect.topLeft().y()));
- m_ItemWidget->render(painter);
- painter->restore();
- }
- } catch (const std::exception& e) {
- qCritical("failed to paint download list: %s", e.what());
+ m_ItemWidget->render(painter);
+ painter->restore();
}
+ } catch (const std::exception &e) {
+ qCritical("failed to paint download list: %s", e.what());
+ }
}
-QSize DownloadListWidgetDelegate::sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const {
- const int width = m_ItemWidget->minimumWidth();
- const int height = m_ItemWidget->height();
- return QSize(width, height);
+QSize DownloadListWidgetDelegate::sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const
+{
+ const int width = m_ItemWidget->minimumWidth();
+ const int height = m_ItemWidget->height();
+ return QSize(width, height);
}
-void DownloadListWidgetDelegate::issueInstall() { emit installDownload(m_ContextRow); }
-
-void DownloadListWidgetDelegate::issueQueryInfo() { emit queryInfo(m_ContextRow); }
-void DownloadListWidgetDelegate::issueDelete() { emit removeDownload(m_ContextRow, true); }
+void DownloadListWidgetDelegate::issueInstall()
+{
+ emit installDownload(m_ContextRow);
+}
-void DownloadListWidgetDelegate::issueRemoveFromView() { emit removeDownload(m_ContextRow, false); }
+void DownloadListWidgetDelegate::issueQueryInfo()
+{
+ emit queryInfo(m_ContextRow);
+}
-void DownloadListWidgetDelegate::issueRestoreToView() { emit restoreDownload(m_ContextRow); }
+void DownloadListWidgetDelegate::issueDelete()
+{
+ emit removeDownload(m_ContextRow, true);
+}
-void DownloadListWidgetDelegate::issueCancel() { emit cancelDownload(m_ContextRow); }
+void DownloadListWidgetDelegate::issueRemoveFromView()
+{
+ emit removeDownload(m_ContextRow, false);
+}
-void DownloadListWidgetDelegate::issuePause() { emit pauseDownload(m_ContextRow); }
+void DownloadListWidgetDelegate::issueRestoreToView()
+{
+ emit restoreDownload(m_ContextRow);
+}
-void DownloadListWidgetDelegate::issueResume() { emit resumeDownload(m_ContextRow); }
+void DownloadListWidgetDelegate::issueCancel()
+{
+ emit cancelDownload(m_ContextRow);
+}
-void DownloadListWidgetDelegate::issueDeleteAll() {
- if (QMessageBox::question(nullptr, tr("Are you sure?"),
- tr("This will remove all finished downloads from this list and from disk."),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- emit removeDownload(-1, true);
- }
+void DownloadListWidgetDelegate::issuePause()
+{
+ emit pauseDownload(m_ContextRow);
}
-void DownloadListWidgetDelegate::issueDeleteCompleted() {
- if (QMessageBox::question(nullptr, tr("Are you sure?"),
- tr("This will remove all installed downloads from this list and from disk."),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- emit removeDownload(-2, true);
- }
+void DownloadListWidgetDelegate::issueResume()
+{
+ emit resumeDownload(m_ContextRow);
}
-void DownloadListWidgetDelegate::issueRemoveFromViewAll() {
- if (QMessageBox::question(nullptr, tr("Are you sure?"),
- tr("This will remove all finished downloads from this list (but NOT from disk)."),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- emit removeDownload(-1, false);
- }
+void DownloadListWidgetDelegate::issueDeleteAll()
+{
+ if (QMessageBox::question(nullptr, tr("Are you sure?"),
+ tr("This will remove all finished downloads from this list and from disk."),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ emit removeDownload(-1, true);
+ }
}
-void DownloadListWidgetDelegate::issueRemoveFromViewCompleted() {
- if (QMessageBox::question(nullptr, tr("Are you sure?"),
- tr("This will remove all installed downloads from this list (but NOT from disk)."),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- emit removeDownload(-2, false);
- }
+void DownloadListWidgetDelegate::issueDeleteCompleted()
+{
+ if (QMessageBox::question(nullptr, tr("Are you sure?"),
+ tr("This will remove all installed downloads from this list and from disk."),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ emit removeDownload(-2, true);
+ }
}
-bool DownloadListWidgetDelegate::editorEvent(QEvent* event, QAbstractItemModel* model,
- const QStyleOptionViewItem& option, const QModelIndex& index) {
- try {
- if (event->type() == QEvent::MouseButtonDblClick) {
- QModelIndex sourceIndex = qobject_cast<QSortFilterProxyModel*>(model)->mapToSource(index);
- if (m_Manager->getState(sourceIndex.row()) >= DownloadManager::STATE_READY) {
- emit installDownload(sourceIndex.row());
- } else if (m_Manager->getState(sourceIndex.row()) >= DownloadManager::STATE_PAUSED) {
- emit resumeDownload(sourceIndex.row());
- }
- return true;
- } else if (event->type() == QEvent::MouseButtonRelease) {
- QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
- if (mouseEvent->button() == Qt::RightButton) {
- QMenu menu(m_View);
- bool hidden = false;
- m_ContextRow = qobject_cast<QSortFilterProxyModel*>(model)->mapToSource(index).row();
- if (m_ContextRow < m_Manager->numTotalDownloads()) {
- DownloadManager::DownloadState state = m_Manager->getState(m_ContextRow);
- hidden = m_Manager->isHidden(m_ContextRow);
- if (state >= DownloadManager::STATE_READY) {
- menu.addAction(tr("Install"), this, SLOT(issueInstall()));
- if (m_Manager->isInfoIncomplete(m_ContextRow)) {
- menu.addAction(tr("Query Info"), this, SLOT(issueQueryInfo()));
- }
- menu.addAction(tr("Delete"), this, SLOT(issueDelete()));
- if (hidden) {
- menu.addAction(tr("Un-Hide"), this, SLOT(issueRestoreToView()));
- } else {
- menu.addAction(tr("Hide"), this, SLOT(issueRemoveFromView()));
- }
- } else if (state == DownloadManager::STATE_DOWNLOADING) {
- menu.addAction(tr("Cancel"), this, SLOT(issueCancel()));
- menu.addAction(tr("Pause"), this, SLOT(issuePause()));
- } else if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
- menu.addAction(tr("Remove"), this, SLOT(issueDelete()));
- menu.addAction(tr("Resume"), this, SLOT(issueResume()));
- }
+void DownloadListWidgetDelegate::issueRemoveFromViewAll()
+{
+ if (QMessageBox::question(nullptr, tr("Are you sure?"),
+ tr("This will remove all finished downloads from this list (but NOT from disk)."),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ emit removeDownload(-1, false);
+ }
+}
- menu.addSeparator();
- }
- menu.addAction(tr("Delete Installed..."), this, SLOT(issueDeleteCompleted()));
- menu.addAction(tr("Delete All..."), this, SLOT(issueDeleteAll()));
- if (!hidden) {
- menu.addSeparator();
- menu.addAction(tr("Hide Installed..."), this, SLOT(issueRemoveFromViewCompleted()));
- menu.addAction(tr("Hide All..."), this, SLOT(issueRemoveFromViewAll()));
- }
- menu.exec(mouseEvent->globalPos());
+void DownloadListWidgetDelegate::issueRemoveFromViewCompleted()
+{
+ if (QMessageBox::question(nullptr, tr("Are you sure?"),
+ tr("This will remove all installed downloads from this list (but NOT from disk)."),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ emit removeDownload(-2, false);
+ }
+}
- event->accept();
- return true;
+bool DownloadListWidgetDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
+ const QStyleOptionViewItem &option, const QModelIndex &index)
+{
+ try {
+ if (event->type() == QEvent::MouseButtonDblClick) {
+ QModelIndex sourceIndex = qobject_cast<QSortFilterProxyModel*>(model)->mapToSource(index);
+ if (m_Manager->getState(sourceIndex.row()) >= DownloadManager::STATE_READY) {
+ emit installDownload(sourceIndex.row());
+ } else if (m_Manager->getState(sourceIndex.row()) >= DownloadManager::STATE_PAUSED) {
+ emit resumeDownload(sourceIndex.row());
+ }
+ return true;
+ } else if (event->type() == QEvent::MouseButtonRelease) {
+ QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
+ if (mouseEvent->button() == Qt::RightButton) {
+ QMenu menu(m_View);
+ bool hidden = false;
+ m_ContextRow = qobject_cast<QSortFilterProxyModel*>(model)->mapToSource(index).row();
+ if (m_ContextRow < m_Manager->numTotalDownloads()) {
+ DownloadManager::DownloadState state = m_Manager->getState(m_ContextRow);
+ hidden = m_Manager->isHidden(m_ContextRow);
+ if (state >= DownloadManager::STATE_READY) {
+ menu.addAction(tr("Install"), this, SLOT(issueInstall()));
+ if (m_Manager->isInfoIncomplete(m_ContextRow)) {
+ menu.addAction(tr("Query Info"), this, SLOT(issueQueryInfo()));
+ }
+ menu.addAction(tr("Delete"), this, SLOT(issueDelete()));
+ if (hidden) {
+ menu.addAction(tr("Un-Hide"), this, SLOT(issueRestoreToView()));
+ } else {
+ menu.addAction(tr("Hide"), this, SLOT(issueRemoveFromView()));
}
+ } else if (state == DownloadManager::STATE_DOWNLOADING){
+ menu.addAction(tr("Cancel"), this, SLOT(issueCancel()));
+ menu.addAction(tr("Pause"), this, SLOT(issuePause()));
+ } else if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
+ menu.addAction(tr("Remove"), this, SLOT(issueDelete()));
+ menu.addAction(tr("Resume"), this, SLOT(issueResume()));
+ }
+
+ menu.addSeparator();
+ }
+ menu.addAction(tr("Delete Installed..."), this, SLOT(issueDeleteCompleted()));
+ menu.addAction(tr("Delete All..."), this, SLOT(issueDeleteAll()));
+ if (!hidden) {
+ menu.addSeparator();
+ menu.addAction(tr("Hide Installed..."), this, SLOT(issueRemoveFromViewCompleted()));
+ menu.addAction(tr("Hide All..."), this, SLOT(issueRemoveFromViewAll()));
}
- } catch (const std::exception& e) {
- qCritical("failed to handle editor event: %s", e.what());
+ menu.exec(mouseEvent->globalPos());
+
+ event->accept();
+ return true;
+ }
}
- return QItemDelegate::editorEvent(event, model, option, index);
+ } catch (const std::exception &e) {
+ qCritical("failed to handle editor event: %s", e.what());
+ }
+ return QItemDelegate::editorEvent(event, model, option, index);
}
diff --git a/src/downloadlistwidget.h b/src/downloadlistwidget.h
index 5f7cdc79..c1dfe4cd 100644
--- a/src/downloadlistwidget.h
+++ b/src/downloadlistwidget.h
@@ -21,93 +21,100 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#define DOWNLOADLISTWIDGET_H
#include "downloadmanager.h"
+#include <QWidget>
#include <QItemDelegate>
#include <QLabel>
#include <QProgressBar>
#include <QTreeView>
-#include <QWidget>
namespace Ui {
-class DownloadListWidget;
+ class DownloadListWidget;
}
-class DownloadListWidget : public QWidget {
+class DownloadListWidget : public QWidget
+{
Q_OBJECT
public:
- explicit DownloadListWidget(QWidget* parent = 0);
+ explicit DownloadListWidget(QWidget *parent = 0);
~DownloadListWidget();
+
private:
- Ui::DownloadListWidget* ui;
+ Ui::DownloadListWidget *ui;
};
class DownloadManager;
-class DownloadListWidgetDelegate : public QItemDelegate {
+class DownloadListWidgetDelegate : public QItemDelegate
+{
- Q_OBJECT
+ Q_OBJECT
public:
- DownloadListWidgetDelegate(DownloadManager* manager, bool metaDisplay, QTreeView* view, QObject* parent = 0);
- ~DownloadListWidgetDelegate();
- virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
- virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
+ DownloadListWidgetDelegate(DownloadManager *manager, bool metaDisplay, QTreeView *view, QObject *parent = 0);
+ ~DownloadListWidgetDelegate();
- void paintPendingDownload(int downloadIndex) const;
- void paintRegularDownload(int downloadIndex) const;
+ virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+ virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
+
+ void paintPendingDownload(int downloadIndex) const;
+ void paintRegularDownload(int downloadIndex) const;
signals:
- void installDownload(int index);
- void queryInfo(int index);
- void removeDownload(int index, bool deleteFile);
- void restoreDownload(int index);
- void cancelDownload(int index);
- void pauseDownload(int index);
- void resumeDownload(int index);
+ void installDownload(int index);
+ void queryInfo(int index);
+ void removeDownload(int index, bool deleteFile);
+ void restoreDownload(int index);
+ void cancelDownload(int index);
+ void pauseDownload(int index);
+ void resumeDownload(int index);
protected:
- bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option,
- const QModelIndex& index);
+
+ bool editorEvent(QEvent *event, QAbstractItemModel *model,
+ const QStyleOptionViewItem &option, const QModelIndex &index);
private:
- void drawCache(QPainter* painter, const QStyleOptionViewItem& option, const QPixmap& cache) const;
+
+ void drawCache(QPainter *painter, const QStyleOptionViewItem &option, const QPixmap &cache) const;
private slots:
- void issueInstall();
- void issueDelete();
- void issueRemoveFromView();
- void issueRestoreToView();
- void issueCancel();
- void issuePause();
- void issueResume();
- void issueDeleteAll();
- void issueDeleteCompleted();
- void issueRemoveFromViewAll();
- void issueRemoveFromViewCompleted();
- void issueQueryInfo();
+ void issueInstall();
+ void issueDelete();
+ void issueRemoveFromView();
+ void issueRestoreToView();
+ void issueCancel();
+ void issuePause();
+ void issueResume();
+ void issueDeleteAll();
+ void issueDeleteCompleted();
+ void issueRemoveFromViewAll();
+ void issueRemoveFromViewCompleted();
+ void issueQueryInfo();
- void stateChanged(int row, DownloadManager::DownloadState);
- void resetCache(int);
+ void stateChanged(int row, DownloadManager::DownloadState);
+ void resetCache(int);
private:
- DownloadListWidget* m_ItemWidget;
- DownloadManager* m_Manager;
- bool m_MetaDisplay;
+ DownloadListWidget *m_ItemWidget;
+ DownloadManager *m_Manager;
+
+ bool m_MetaDisplay;
- QLabel* m_NameLabel;
- QLabel* m_SizeLabel;
- QProgressBar* m_Progress;
- QLabel* m_InstallLabel;
- int m_ContextRow;
+ QLabel *m_NameLabel;
+ QLabel *m_SizeLabel;
+ QProgressBar *m_Progress;
+ QLabel *m_InstallLabel;
+ int m_ContextRow;
- QTreeView* m_View;
+ QTreeView *m_View;
- mutable QMap<int, QPixmap> m_Cache;
+ mutable QMap<int, QPixmap> m_Cache;
};
#endif // DOWNLOADLISTWIDGET_H
diff --git a/src/downloadlistwidgetcompact.cpp b/src/downloadlistwidgetcompact.cpp
index 30e3ed21..f7975150 100644
--- a/src/downloadlistwidgetcompact.cpp
+++ b/src/downloadlistwidgetcompact.cpp
@@ -19,262 +19,319 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "downloadlistwidgetcompact.h"
#include "ui_downloadlistwidgetcompact.h"
+#include <QPainter>
+#include <QMouseEvent>
#include <QMenu>
#include <QMessageBox>
-#include <QMouseEvent>
-#include <QPainter>
#include <QSortFilterProxyModel>
-DownloadListWidgetCompact::DownloadListWidgetCompact(QWidget* parent)
- : QWidget(parent), ui(new Ui::DownloadListWidgetCompact) {
- ui->setupUi(this);
+
+DownloadListWidgetCompact::DownloadListWidgetCompact(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::DownloadListWidgetCompact)
+{
+ ui->setupUi(this);
+}
+
+DownloadListWidgetCompact::~DownloadListWidgetCompact()
+{
+ delete ui;
}
-DownloadListWidgetCompact::~DownloadListWidgetCompact() { delete ui; }
-DownloadListWidgetCompactDelegate::DownloadListWidgetCompactDelegate(DownloadManager* manager, bool metaDisplay,
- QTreeView* view, QObject* parent)
- : QItemDelegate(parent), m_Manager(manager), m_MetaDisplay(metaDisplay),
- m_ItemWidget(new DownloadListWidgetCompact), m_View(view) {
- m_NameLabel = m_ItemWidget->findChild<QLabel*>("nameLabel");
- m_SizeLabel = m_ItemWidget->findChild<QLabel*>("sizeLabel");
- m_Progress = m_ItemWidget->findChild<QProgressBar*>("downloadProgress");
- m_DoneLabel = m_ItemWidget->findChild<QLabel*>("doneLabel");
+DownloadListWidgetCompactDelegate::DownloadListWidgetCompactDelegate(DownloadManager *manager, bool metaDisplay, QTreeView *view, QObject *parent)
+ : QItemDelegate(parent)
+ , m_Manager(manager)
+ , m_MetaDisplay(metaDisplay)
+ , m_ItemWidget(new DownloadListWidgetCompact)
+ , m_View(view)
+{
+ m_NameLabel = m_ItemWidget->findChild<QLabel*>("nameLabel");
+ m_SizeLabel = m_ItemWidget->findChild<QLabel*>("sizeLabel");
+ m_Progress = m_ItemWidget->findChild<QProgressBar*>("downloadProgress");
+ m_DoneLabel = m_ItemWidget->findChild<QLabel*>("doneLabel");
- m_DoneLabel->setVisible(false);
+ m_DoneLabel->setVisible(false);
- connect(manager, SIGNAL(stateChanged(int, DownloadManager::DownloadState)), this,
- SLOT(stateChanged(int, DownloadManager::DownloadState)));
- connect(manager, SIGNAL(downloadRemoved(int)), this, SLOT(resetCache(int)));
+ connect(manager, SIGNAL(stateChanged(int,DownloadManager::DownloadState)),
+ this, SLOT(stateChanged(int,DownloadManager::DownloadState)));
+ connect(manager, SIGNAL(downloadRemoved(int)), this, SLOT(resetCache(int)));
}
-DownloadListWidgetCompactDelegate::~DownloadListWidgetCompactDelegate() { delete m_ItemWidget; }
-void DownloadListWidgetCompactDelegate::stateChanged(int row, DownloadManager::DownloadState) { m_Cache.remove(row); }
+DownloadListWidgetCompactDelegate::~DownloadListWidgetCompactDelegate()
+{
+ delete m_ItemWidget;
+}
-void DownloadListWidgetCompactDelegate::resetCache(int) { m_Cache.clear(); }
-void DownloadListWidgetCompactDelegate::drawCache(QPainter* painter, const QStyleOptionViewItem& option,
- const QPixmap& cache) const {
- QRect rect = option.rect;
- rect.setLeft(0);
- rect.setWidth(m_View->columnWidth(0) + m_View->columnWidth(1) + m_View->columnWidth(2));
- painter->drawPixmap(rect, cache);
+void DownloadListWidgetCompactDelegate::stateChanged(int row,DownloadManager::DownloadState)
+{
+ m_Cache.remove(row);
}
-void DownloadListWidgetCompactDelegate::paintPendingDownload(int downloadIndex) const {
- std::pair<int, int> nexusids = m_Manager->getPendingDownload(downloadIndex);
- m_NameLabel->setText(tr("< mod %1 file %2 >").arg(nexusids.first).arg(nexusids.second));
- if (m_SizeLabel != nullptr) {
- m_SizeLabel->setText("???");
- }
- m_DoneLabel->setVisible(true);
- m_DoneLabel->setText(tr("Pending"));
- m_Progress->setVisible(false);
+
+void DownloadListWidgetCompactDelegate::resetCache(int)
+{
+ m_Cache.clear();
}
-void DownloadListWidgetCompactDelegate::paintRegularDownload(int downloadIndex) const {
- QString name = m_MetaDisplay ? m_Manager->getDisplayName(downloadIndex) : m_Manager->getFileName(downloadIndex);
- if (name.length() > 53) {
- name.truncate(50);
- name.append("...");
- }
- m_NameLabel->setText(name);
- DownloadManager::DownloadState state = m_Manager->getState(downloadIndex);
+void DownloadListWidgetCompactDelegate::drawCache(QPainter *painter, const QStyleOptionViewItem &option, const QPixmap &cache) const
+{
+ QRect rect = option.rect;
+ rect.setLeft(0);
+ rect.setWidth(m_View->columnWidth(0) + m_View->columnWidth(1) + m_View->columnWidth(2));
+ painter->drawPixmap(rect, cache);
+}
- if ((m_SizeLabel != nullptr) && (state >= DownloadManager::STATE_READY)) {
- m_SizeLabel->setText(QString::number(m_Manager->getFileSize(downloadIndex) / 1048576));
- }
- if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
- m_DoneLabel->setVisible(true);
- m_Progress->setVisible(false);
- m_DoneLabel->setText(QString("%1<img src=\":/MO/gui/inactive\">").arg(tr("Paused")));
- } else if (state == DownloadManager::STATE_FETCHINGMODINFO) {
- m_DoneLabel->setText(QString("%1").arg(tr("Fetching Info 1")));
- } else if (state == DownloadManager::STATE_FETCHINGFILEINFO) {
- m_DoneLabel->setText(QString("%1").arg(tr("Fetching Info 2")));
- } else if (state >= DownloadManager::STATE_READY) {
- m_DoneLabel->setVisible(true);
- m_Progress->setVisible(false);
- if (state == DownloadManager::STATE_INSTALLED) {
- m_DoneLabel->setText(QString("%1<img src=\":/MO/gui/check\">").arg(tr("Installed")));
- } else if (state == DownloadManager::STATE_UNINSTALLED) {
- m_DoneLabel->setText(QString("%1<img src=\":/MO/gui/awaiting\">").arg(tr("Uninstalled")));
- } else {
- m_DoneLabel->setText(QString("%1<img src=\":/MO/gui/active\">").arg(tr("Done")));
- }
- if (m_Manager->isInfoIncomplete(downloadIndex)) {
- m_NameLabel->setText("<img src=\":/MO/gui/warning_16\"/> " + m_NameLabel->text());
- }
+void DownloadListWidgetCompactDelegate::paintPendingDownload(int downloadIndex) const
+{
+ std::pair<int, int> nexusids = m_Manager->getPendingDownload(downloadIndex);
+ m_NameLabel->setText(tr("< mod %1 file %2 >").arg(nexusids.first).arg(nexusids.second));
+ if (m_SizeLabel != nullptr) {
+ m_SizeLabel->setText("???");
+ }
+ m_DoneLabel->setVisible(true);
+ m_DoneLabel->setText(tr("Pending"));
+ m_Progress->setVisible(false);
+}
+
+
+void DownloadListWidgetCompactDelegate::paintRegularDownload(int downloadIndex) const
+{
+ QString name = m_MetaDisplay ? m_Manager->getDisplayName(downloadIndex) : m_Manager->getFileName(downloadIndex);
+ if (name.length() > 53) {
+ name.truncate(50);
+ name.append("...");
+ }
+ m_NameLabel->setText(name);
+
+ DownloadManager::DownloadState state = m_Manager->getState(downloadIndex);
+
+ if ((m_SizeLabel != nullptr) && (state >= DownloadManager::STATE_READY)) {
+ m_SizeLabel->setText(QString::number(m_Manager->getFileSize(downloadIndex) / 1048576));
+ }
+
+ if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
+ m_DoneLabel->setVisible(true);
+ m_Progress->setVisible(false);
+ m_DoneLabel->setText(QString("%1<img src=\":/MO/gui/inactive\">").arg(tr("Paused")));
+ } else if (state == DownloadManager::STATE_FETCHINGMODINFO) {
+ m_DoneLabel->setText(QString("%1").arg(tr("Fetching Info 1")));
+ } else if (state == DownloadManager::STATE_FETCHINGFILEINFO) {
+ m_DoneLabel->setText(QString("%1").arg(tr("Fetching Info 2")));
+ } else if (state >= DownloadManager::STATE_READY) {
+ m_DoneLabel->setVisible(true);
+ m_Progress->setVisible(false);
+ if (state == DownloadManager::STATE_INSTALLED) {
+ m_DoneLabel->setText(QString("%1<img src=\":/MO/gui/check\">").arg(tr("Installed")));
+ } else if (state == DownloadManager::STATE_UNINSTALLED) {
+ m_DoneLabel->setText(QString("%1<img src=\":/MO/gui/awaiting\">").arg(tr("Uninstalled")));
} else {
- m_DoneLabel->setVisible(false);
- m_Progress->setVisible(true);
- m_Progress->setValue(m_Manager->getProgress(downloadIndex));
+ m_DoneLabel->setText(QString("%1<img src=\":/MO/gui/active\">").arg(tr("Done")));
+ }
+ if (m_Manager->isInfoIncomplete(downloadIndex)) {
+ m_NameLabel->setText("<img src=\":/MO/gui/warning_16\"/> " + m_NameLabel->text());
}
+ } else {
+ m_DoneLabel->setVisible(false);
+ m_Progress->setVisible(true);
+ m_Progress->setValue(m_Manager->getProgress(downloadIndex));
+ }
}
-void DownloadListWidgetCompactDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,
- const QModelIndex& index) const {
+void DownloadListWidgetCompactDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
#pragma message("This is quite costy - room for optimization?")
- try {
- auto iter = m_Cache.find(index.row());
- if (iter != m_Cache.end()) {
- drawCache(painter, option, *iter);
- return;
- }
+ try {
+ auto iter = m_Cache.find(index.row());
+ if (iter != m_Cache.end()) {
+ drawCache(painter, option, *iter);
+ return;
+ }
- m_ItemWidget->resize(
- QSize(m_View->columnWidth(0) + m_View->columnWidth(1) + m_View->columnWidth(2), option.rect.height()));
- if (index.row() % 2 == 1) {
- m_ItemWidget->setBackgroundRole(QPalette::AlternateBase);
- } else {
- m_ItemWidget->setBackgroundRole(QPalette::Base);
- }
+ m_ItemWidget->resize(QSize(m_View->columnWidth(0) + m_View->columnWidth(1) + m_View->columnWidth(2), option.rect.height()));
+ if (index.row() % 2 == 1) {
+ m_ItemWidget->setBackgroundRole(QPalette::AlternateBase);
+ } else {
+ m_ItemWidget->setBackgroundRole(QPalette::Base);
+ }
- int downloadIndex = index.data().toInt();
- if (downloadIndex >= m_Manager->numTotalDownloads()) {
- paintPendingDownload(downloadIndex - m_Manager->numTotalDownloads());
- } else {
- paintRegularDownload(downloadIndex);
- }
+ int downloadIndex = index.data().toInt();
+ if (downloadIndex >= m_Manager->numTotalDownloads()) {
+ paintPendingDownload(downloadIndex - m_Manager->numTotalDownloads());
+ } else {
+ paintRegularDownload(downloadIndex);
+ }
#pragma message("caching disabled because changes in the list (including resorting) doesn't work correctly")
- if (false) {
+ if (false) {
// if (state >= DownloadManager::STATE_READY) {
-#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
- QPixmap cache = m_ItemWidget->grab();
+#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
+ QPixmap cache = m_ItemWidget->grab();
#else
- QPixmap cache = QPixmap::grabWidget(m_ItemWidget);
+ QPixmap cache = QPixmap::grabWidget(m_ItemWidget);
#endif
- m_Cache[index.row()] = cache;
- drawCache(painter, option, cache);
- } else {
- painter->save();
- painter->translate(QPoint(0, option.rect.topLeft().y()));
+ m_Cache[index.row()] = cache;
+ drawCache(painter, option, cache);
+ } else {
+ painter->save();
+ painter->translate(QPoint(0, option.rect.topLeft().y()));
- m_ItemWidget->render(painter);
- painter->restore();
- }
- } catch (const std::exception& e) {
- qCritical("failed to paint download list item %d: %s", index.row(), e.what());
+ m_ItemWidget->render(painter);
+ painter->restore();
}
+ } catch (const std::exception &e) {
+ qCritical("failed to paint download list item %d: %s", index.row(), e.what());
+ }
}
-QSize DownloadListWidgetCompactDelegate::sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const {
- const int width = m_ItemWidget->minimumWidth();
- const int height = m_ItemWidget->height();
- return QSize(width, height);
+QSize DownloadListWidgetCompactDelegate::sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const
+{
+ const int width = m_ItemWidget->minimumWidth();
+ const int height = m_ItemWidget->height();
+ return QSize(width, height);
}
-void DownloadListWidgetCompactDelegate::issueInstall() { emit installDownload(m_ContextIndex.row()); }
-void DownloadListWidgetCompactDelegate::issueQueryInfo() { emit queryInfo(m_ContextIndex.row()); }
+void DownloadListWidgetCompactDelegate::issueInstall()
+{
+ emit installDownload(m_ContextIndex.row());
+}
-void DownloadListWidgetCompactDelegate::issueDelete() { emit removeDownload(m_ContextIndex.row(), true); }
+void DownloadListWidgetCompactDelegate::issueQueryInfo()
+{
+ emit queryInfo(m_ContextIndex.row());
+}
-void DownloadListWidgetCompactDelegate::issueRemoveFromView() { emit removeDownload(m_ContextIndex.row(), false); }
+void DownloadListWidgetCompactDelegate::issueDelete()
+{
+ emit removeDownload(m_ContextIndex.row(), true);
+}
-void DownloadListWidgetCompactDelegate::issueRestoreToView() { emit restoreDownload(m_ContextIndex.row()); }
+void DownloadListWidgetCompactDelegate::issueRemoveFromView()
+{
+ emit removeDownload(m_ContextIndex.row(), false);
+}
-void DownloadListWidgetCompactDelegate::issueCancel() { emit cancelDownload(m_ContextIndex.row()); }
+void DownloadListWidgetCompactDelegate::issueRestoreToView()
+{
+ emit restoreDownload(m_ContextIndex.row());
+}
-void DownloadListWidgetCompactDelegate::issuePause() { emit pauseDownload(m_ContextIndex.row()); }
+void DownloadListWidgetCompactDelegate::issueCancel()
+{
+ emit cancelDownload(m_ContextIndex.row());
+}
-void DownloadListWidgetCompactDelegate::issueResume() { emit resumeDownload(m_ContextIndex.row()); }
+void DownloadListWidgetCompactDelegate::issuePause()
+{
+ emit pauseDownload(m_ContextIndex.row());
+}
-void DownloadListWidgetCompactDelegate::issueDeleteAll() {
- if (QMessageBox::question(nullptr, tr("Are you sure?"),
- tr("This will remove all finished downloads from this list and from disk."),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- emit removeDownload(-1, true);
- }
+void DownloadListWidgetCompactDelegate::issueResume()
+{
+ emit resumeDownload(m_ContextIndex.row());
}
-void DownloadListWidgetCompactDelegate::issueDeleteCompleted() {
- if (QMessageBox::question(nullptr, tr("Are you sure?"),
- tr("This will remove all installed downloads from this list and from disk."),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- emit removeDownload(-2, true);
- }
+void DownloadListWidgetCompactDelegate::issueDeleteAll()
+{
+ if (QMessageBox::question(nullptr, tr("Are you sure?"),
+ tr("This will remove all finished downloads from this list and from disk."),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ emit removeDownload(-1, true);
+ }
}
-void DownloadListWidgetCompactDelegate::issueRemoveFromViewAll() {
- if (QMessageBox::question(
- nullptr, tr("Are you sure?"),
- tr("This will permanently remove all finished downloads from this list (but NOT from disk)."),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- emit removeDownload(-1, false);
- }
+void DownloadListWidgetCompactDelegate::issueDeleteCompleted()
+{
+ if (QMessageBox::question(nullptr, tr("Are you sure?"),
+ tr("This will remove all installed downloads from this list and from disk."),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ emit removeDownload(-2, true);
+ }
}
-void DownloadListWidgetCompactDelegate::issueRemoveFromViewCompleted() {
- if (QMessageBox::question(
- nullptr, tr("Are you sure?"),
- tr("This will permanently remove all installed downloads from this list (but NOT from disk)."),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- emit removeDownload(-2, false);
- }
+void DownloadListWidgetCompactDelegate::issueRemoveFromViewAll()
+{
+ if (QMessageBox::question(nullptr, tr("Are you sure?"),
+ tr("This will permanently remove all finished downloads from this list (but NOT from disk)."),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ emit removeDownload(-1, false);
+ }
}
-bool DownloadListWidgetCompactDelegate::editorEvent(QEvent* event, QAbstractItemModel* model,
- const QStyleOptionViewItem& option, const QModelIndex& index) {
- try {
- if (event->type() == QEvent::MouseButtonDblClick) {
- QModelIndex sourceIndex = qobject_cast<QSortFilterProxyModel*>(model)->mapToSource(index);
- if (m_Manager->getState(sourceIndex.row()) >= DownloadManager::STATE_READY) {
- emit installDownload(sourceIndex.row());
- } else if (m_Manager->getState(sourceIndex.row()) >= DownloadManager::STATE_PAUSED) {
- emit resumeDownload(sourceIndex.row());
- }
- return true;
- } else if (event->type() == QEvent::MouseButtonRelease) {
- QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
- if (mouseEvent->button() == Qt::RightButton) {
- QMenu menu;
- bool hidden = false;
- m_ContextIndex = qobject_cast<QSortFilterProxyModel*>(model)->mapToSource(index);
- if (m_ContextIndex.row() < m_Manager->numTotalDownloads()) {
- DownloadManager::DownloadState state = m_Manager->getState(m_ContextIndex.row());
- hidden = m_Manager->isHidden(m_ContextIndex.row());
- if (state >= DownloadManager::STATE_READY) {
- menu.addAction(tr("Install"), this, SLOT(issueInstall()));
- if (m_Manager->isInfoIncomplete(m_ContextIndex.row())) {
- menu.addAction(tr("Query Info"), this, SLOT(issueQueryInfo()));
- }
- menu.addAction(tr("Delete"), this, SLOT(issueDelete()));
- if (hidden) {
- menu.addAction(tr("Un-Hide"), this, SLOT(issueRestoreToView()));
- } else {
- menu.addAction(tr("Hide"), this, SLOT(issueRemoveFromView()));
- }
- } else if (state == DownloadManager::STATE_DOWNLOADING) {
- menu.addAction(tr("Cancel"), this, SLOT(issueCancel()));
- menu.addAction(tr("Pause"), this, SLOT(issuePause()));
- } else if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
- menu.addAction(tr("Remove"), this, SLOT(issueDelete()));
- menu.addAction(tr("Resume"), this, SLOT(issueResume()));
- }
+void DownloadListWidgetCompactDelegate::issueRemoveFromViewCompleted()
+{
+ if (QMessageBox::question(nullptr, tr("Are you sure?"),
+ tr("This will permanently remove all installed downloads from this list (but NOT from disk)."),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ emit removeDownload(-2, false);
+ }
+}
- menu.addSeparator();
- }
- menu.addAction(tr("Delete Installed..."), this, SLOT(issueDeleteCompleted()));
- menu.addAction(tr("Delete All..."), this, SLOT(issueDeleteAll()));
- if (!hidden) {
- menu.addSeparator();
- menu.addAction(tr("Hide Installed..."), this, SLOT(issueRemoveFromViewCompleted()));
- menu.addAction(tr("Hide All..."), this, SLOT(issueRemoveFromViewAll()));
- }
- menu.exec(mouseEvent->globalPos());
- event->accept();
- return false;
+bool DownloadListWidgetCompactDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
+ const QStyleOptionViewItem &option, const QModelIndex &index)
+{
+ try {
+ if (event->type() == QEvent::MouseButtonDblClick) {
+ QModelIndex sourceIndex = qobject_cast<QSortFilterProxyModel*>(model)->mapToSource(index);
+ if (m_Manager->getState(sourceIndex.row()) >= DownloadManager::STATE_READY) {
+ emit installDownload(sourceIndex.row());
+ } else if (m_Manager->getState(sourceIndex.row()) >= DownloadManager::STATE_PAUSED) {
+ emit resumeDownload(sourceIndex.row());
+ }
+ return true;
+ } else if (event->type() == QEvent::MouseButtonRelease) {
+ QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
+ if (mouseEvent->button() == Qt::RightButton) {
+ QMenu menu;
+ bool hidden = false;
+ m_ContextIndex = qobject_cast<QSortFilterProxyModel*>(model)->mapToSource(index);
+ if (m_ContextIndex.row() < m_Manager->numTotalDownloads()) {
+ DownloadManager::DownloadState state = m_Manager->getState(m_ContextIndex.row());
+ hidden = m_Manager->isHidden(m_ContextIndex.row());
+ if (state >= DownloadManager::STATE_READY) {
+ menu.addAction(tr("Install"), this, SLOT(issueInstall()));
+ if (m_Manager->isInfoIncomplete(m_ContextIndex.row())) {
+ menu.addAction(tr("Query Info"), this, SLOT(issueQueryInfo()));
}
+ menu.addAction(tr("Delete"), this, SLOT(issueDelete()));
+ if (hidden) {
+ menu.addAction(tr("Un-Hide"), this, SLOT(issueRestoreToView()));
+ } else {
+ menu.addAction(tr("Hide"), this, SLOT(issueRemoveFromView()));
+ }
+ } else if (state == DownloadManager::STATE_DOWNLOADING){
+ menu.addAction(tr("Cancel"), this, SLOT(issueCancel()));
+ menu.addAction(tr("Pause"), this, SLOT(issuePause()));
+ } else if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
+ menu.addAction(tr("Remove"), this, SLOT(issueDelete()));
+ menu.addAction(tr("Resume"), this, SLOT(issueResume()));
+ }
+
+ menu.addSeparator();
}
- } catch (const std::exception& e) {
- qCritical("failed to handle editor event: %s", e.what());
+ menu.addAction(tr("Delete Installed..."), this, SLOT(issueDeleteCompleted()));
+ menu.addAction(tr("Delete All..."), this, SLOT(issueDeleteAll()));
+ if (!hidden) {
+ menu.addSeparator();
+ menu.addAction(tr("Hide Installed..."), this, SLOT(issueRemoveFromViewCompleted()));
+ menu.addAction(tr("Hide All..."), this, SLOT(issueRemoveFromViewAll()));
+ }
+ menu.exec(mouseEvent->globalPos());
+
+ event->accept();
+ return false;
+ }
}
+ } catch (const std::exception &e) {
+ qCritical("failed to handle editor event: %s", e.what());
+ }
- return QItemDelegate::editorEvent(event, model, option, index);
+ return QItemDelegate::editorEvent(event, model, option, index);
}
+
diff --git a/src/downloadlistwidgetcompact.h b/src/downloadlistwidgetcompact.h
index 2b016cf1..bf855d5f 100644
--- a/src/downloadlistwidgetcompact.h
+++ b/src/downloadlistwidgetcompact.h
@@ -20,95 +20,103 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef DOWNLOADLISTWIDGETCOMPACT_H
#define DOWNLOADLISTWIDGETCOMPACT_H
-#include "downloadmanager.h"
+#include <QWidget>
#include <QItemDelegate>
#include <QLabel>
#include <QProgressBar>
#include <QTreeView>
-#include <QWidget>
+#include "downloadmanager.h"
+
namespace Ui {
class DownloadListWidgetCompact;
}
-class DownloadListWidgetCompact : public QWidget {
- Q_OBJECT
-
+class DownloadListWidgetCompact : public QWidget
+{
+ Q_OBJECT
+
public:
- explicit DownloadListWidgetCompact(QWidget* parent = 0);
- ~DownloadListWidgetCompact();
+ explicit DownloadListWidgetCompact(QWidget *parent = 0);
+ ~DownloadListWidgetCompact();
private:
- Ui::DownloadListWidgetCompact* ui;
- int m_ContextRow;
+ Ui::DownloadListWidgetCompact *ui;
+ int m_ContextRow;
};
class DownloadManager;
-class DownloadListWidgetCompactDelegate : public QItemDelegate {
+class DownloadListWidgetCompactDelegate : public QItemDelegate
+{
- Q_OBJECT
+ Q_OBJECT
public:
- DownloadListWidgetCompactDelegate(DownloadManager* manager, bool metaDisplay, QTreeView* view, QObject* parent = 0);
- ~DownloadListWidgetCompactDelegate();
- virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
- virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
+ DownloadListWidgetCompactDelegate(DownloadManager *manager, bool metaDisplay, QTreeView *view, QObject *parent = 0);
+ ~DownloadListWidgetCompactDelegate();
+
+ virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+ virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
signals:
- void installDownload(int index);
- void queryInfo(int index);
- void removeDownload(int index, bool deleteFile);
- void restoreDownload(int index);
- void cancelDownload(int index);
- void pauseDownload(int index);
- void resumeDownload(int index);
+ void installDownload(int index);
+ void queryInfo(int index);
+ void removeDownload(int index, bool deleteFile);
+ void restoreDownload(int index);
+ void cancelDownload(int index);
+ void pauseDownload(int index);
+ void resumeDownload(int index);
protected:
- bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option,
- const QModelIndex& index);
+
+ bool editorEvent(QEvent *event, QAbstractItemModel *model,
+ const QStyleOptionViewItem &option, const QModelIndex &index);
private:
- void drawCache(QPainter* painter, const QStyleOptionViewItem& option, const QPixmap& cache) const;
- void paintPendingDownload(int downloadIndex) const;
- void paintRegularDownload(int downloadIndex) const;
-private slots:
+ void drawCache(QPainter *painter, const QStyleOptionViewItem &option, const QPixmap &cache) const;
+ void paintPendingDownload(int downloadIndex) const;
+ void paintRegularDownload(int downloadIndex) const;
- void issueInstall();
- void issueDelete();
- void issueRemoveFromView();
- void issueRestoreToView();
- void issueCancel();
- void issuePause();
- void issueResume();
- void issueDeleteAll();
- void issueDeleteCompleted();
- void issueRemoveFromViewAll();
- void issueRemoveFromViewCompleted();
- void issueQueryInfo();
+private slots:
- void stateChanged(int row, DownloadManager::DownloadState);
- void resetCache(int);
+ void issueInstall();
+ void issueDelete();
+ void issueRemoveFromView();
+ void issueRestoreToView();
+ void issueCancel();
+ void issuePause();
+ void issueResume();
+ void issueDeleteAll();
+ void issueDeleteCompleted();
+ void issueRemoveFromViewAll();
+ void issueRemoveFromViewCompleted();
+ void issueQueryInfo();
+ void stateChanged(int row, DownloadManager::DownloadState);
+ void resetCache(int);
private:
- DownloadListWidgetCompact* m_ItemWidget;
- DownloadManager* m_Manager;
- bool m_MetaDisplay;
+ DownloadListWidgetCompact *m_ItemWidget;
+ DownloadManager *m_Manager;
- QLabel* m_NameLabel;
- QLabel* m_SizeLabel;
- QProgressBar* m_Progress;
- QLabel* m_DoneLabel;
+ bool m_MetaDisplay;
- QModelIndex m_ContextIndex;
+ QLabel *m_NameLabel;
+ QLabel *m_SizeLabel;
+ QProgressBar *m_Progress;
+ QLabel *m_DoneLabel;
- QTreeView* m_View;
+ QModelIndex m_ContextIndex;
+
+ QTreeView *m_View;
+
+ mutable QMap<int, QPixmap> m_Cache;
- mutable QMap<int, QPixmap> m_Cache;
};
#endif // DOWNLOADLISTWIDGETCOMPACT_H
+
diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp
index 5f8fc98b..a4fde093 100644
--- a/src/downloadmanager.cpp
+++ b/src/downloadmanager.cpp
@@ -19,1370 +19,1475 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "downloadmanager.h"
-#include "bbcode.h"
-#include "iplugingame.h"
+#include "nxmurl.h"
#include "nexusinterface.h"
#include "nxmaccessmanager.h"
-#include "nxmurl.h"
-#include "selectiondialog.h"
-#include "utility.h"
+#include "iplugingame.h"
#include <nxmurl.h>
-#include <report.h>
#include <taskprogressmanager.h>
+#include "utility.h"
+#include "selectiondialog.h"
+#include "bbcode.h"
#include <utility.h>
+#include <report.h>
-#include <QCoreApplication>
-#include <QDirIterator>
+#include <QTimer>
#include <QFileInfo>
+#include <QRegExp>
+#include <QDirIterator>
#include <QInputDialog>
#include <QMessageBox>
-#include <QRegExp>
+#include <QCoreApplication>
#include <QTextDocument>
-#include <QTimer>
#include <boost/bind.hpp>
#include <regex>
+
using namespace MOBase;
+
// TODO limit number of downloads, also display download during nxm requests, store modid/fileid with downloads
+
static const char UNFINISHED[] = ".unfinished";
unsigned int DownloadManager::DownloadInfo::s_NextDownloadID = 1U;
-DownloadManager::DownloadInfo* DownloadManager::DownloadInfo::createNew(const ModRepositoryFileInfo* fileInfo,
- const QStringList& URLs) {
- DownloadInfo* info = new DownloadInfo;
- info->m_DownloadID = s_NextDownloadID++;
- info->m_StartTime.start();
- info->m_PreResumeSize = 0LL;
- info->m_Progress = 0;
- info->m_ResumePos = 0;
- info->m_FileInfo = new ModRepositoryFileInfo(*fileInfo);
- info->m_Urls = URLs;
- info->m_CurrentUrl = 0;
- info->m_Tries = AUTOMATIC_RETRIES;
- info->m_State = STATE_STARTED;
- info->m_TaskProgressId = TaskProgressManager::instance().getId();
- return info;
+DownloadManager::DownloadInfo *DownloadManager::DownloadInfo::createNew(const ModRepositoryFileInfo *fileInfo, const QStringList &URLs)
+{
+ DownloadInfo *info = new DownloadInfo;
+ info->m_DownloadID = s_NextDownloadID++;
+ info->m_StartTime.start();
+ info->m_PreResumeSize = 0LL;
+ info->m_Progress = 0;
+ info->m_ResumePos = 0;
+ info->m_FileInfo = new ModRepositoryFileInfo(*fileInfo);
+ info->m_Urls = URLs;
+ info->m_CurrentUrl = 0;
+ info->m_Tries = AUTOMATIC_RETRIES;
+ info->m_State = STATE_STARTED;
+ info->m_TaskProgressId = TaskProgressManager::instance().getId();
+
+ return info;
}
-DownloadManager::DownloadInfo* DownloadManager::DownloadInfo::createFromMeta(const QString& filePath, bool showHidden) {
- DownloadInfo* info = new DownloadInfo;
+DownloadManager::DownloadInfo *DownloadManager::DownloadInfo::createFromMeta(const QString &filePath, bool showHidden)
+{
+ DownloadInfo *info = new DownloadInfo;
- QString metaFileName = filePath + ".meta";
- QSettings metaFile(metaFileName, QSettings::IniFormat);
- if (!showHidden && metaFile.value("removed", false).toBool()) {
- return nullptr;
- } else {
- info->m_Hidden = metaFile.value("removed", false).toBool();
- }
+ QString metaFileName = filePath + ".meta";
+ QSettings metaFile(metaFileName, QSettings::IniFormat);
+ if (!showHidden && metaFile.value("removed", false).toBool()) {
+ return nullptr;
+ } else {
+ info->m_Hidden = metaFile.value("removed", false).toBool();
+ }
- QString fileName = QFileInfo(filePath).fileName();
+ QString fileName = QFileInfo(filePath).fileName();
- if (fileName.endsWith(UNFINISHED)) {
- info->m_FileName = fileName.mid(0, fileName.length() - static_cast<int>(strlen(UNFINISHED)));
- info->m_State = STATE_PAUSED;
- } else {
- info->m_FileName = fileName;
+ if (fileName.endsWith(UNFINISHED)) {
+ info->m_FileName = fileName.mid(
+ 0, fileName.length() - static_cast<int>(strlen(UNFINISHED)));
+ info->m_State = STATE_PAUSED;
+ } else {
+ info->m_FileName = fileName;
- if (metaFile.value("paused", false).toBool()) {
- info->m_State = STATE_PAUSED;
- } else if (metaFile.value("uninstalled", false).toBool()) {
- info->m_State = STATE_UNINSTALLED;
- } else if (metaFile.value("installed", false).toBool()) {
- info->m_State = STATE_INSTALLED;
- } else {
- info->m_State = STATE_READY;
- }
+ if (metaFile.value("paused", false).toBool()) {
+ info->m_State = STATE_PAUSED;
+ } else if (metaFile.value("uninstalled", false).toBool()) {
+ info->m_State = STATE_UNINSTALLED;
+ } else if (metaFile.value("installed", false).toBool()) {
+ info->m_State = STATE_INSTALLED;
+ } else {
+ info->m_State = STATE_READY;
}
+ }
- info->m_DownloadID = s_NextDownloadID++;
- info->m_Output.setFileName(filePath);
- info->m_TotalSize = QFileInfo(filePath).size();
- info->m_PreResumeSize = info->m_TotalSize;
- info->m_CurrentUrl = 0;
- info->m_Urls = metaFile.value("url", "").toString().split(";");
- info->m_Tries = 0;
- info->m_TaskProgressId = TaskProgressManager::instance().getId();
- int modID = metaFile.value("modID", 0).toInt();
- int fileID = metaFile.value("fileID", 0).toInt();
- info->m_FileInfo = new ModRepositoryFileInfo(modID, fileID);
- info->m_FileInfo->name = metaFile.value("name", "").toString();
- if (info->m_FileInfo->name == "0") {
- // bug in earlier version
- info->m_FileInfo->name = "";
- }
- info->m_FileInfo->modName = metaFile.value("modName", "").toString();
- info->m_FileInfo->modID = modID;
- info->m_FileInfo->fileID = fileID;
- info->m_FileInfo->description = metaFile.value("description").toString();
- info->m_FileInfo->version.parse(metaFile.value("version", "0").toString());
- info->m_FileInfo->newestVersion.parse(metaFile.value("newestVersion", "0").toString());
- info->m_FileInfo->categoryID = metaFile.value("category", 0).toInt();
- info->m_FileInfo->fileCategory = metaFile.value("fileCategory", 0).toInt();
- info->m_FileInfo->repository = metaFile.value("repository", "Nexus").toString();
- info->m_FileInfo->userData = metaFile.value("userData").toMap();
+ info->m_DownloadID = s_NextDownloadID++;
+ info->m_Output.setFileName(filePath);
+ info->m_TotalSize = QFileInfo(filePath).size();
+ info->m_PreResumeSize = info->m_TotalSize;
+ info->m_CurrentUrl = 0;
+ info->m_Urls = metaFile.value("url", "").toString().split(";");
+ info->m_Tries = 0;
+ info->m_TaskProgressId = TaskProgressManager::instance().getId();
+ int modID = metaFile.value("modID", 0).toInt();
+ int fileID = metaFile.value("fileID", 0).toInt();
+ info->m_FileInfo = new ModRepositoryFileInfo(modID, fileID);
+ info->m_FileInfo->name = metaFile.value("name", "").toString();
+ if (info->m_FileInfo->name == "0") {
+ // bug in earlier version
+ info->m_FileInfo->name = "";
+ }
+ info->m_FileInfo->modName = metaFile.value("modName", "").toString();
+ info->m_FileInfo->modID = modID;
+ info->m_FileInfo->fileID = fileID;
+ info->m_FileInfo->description = metaFile.value("description").toString();
+ info->m_FileInfo->version.parse(metaFile.value("version", "0").toString());
+ info->m_FileInfo->newestVersion.parse(metaFile.value("newestVersion", "0").toString());
+ info->m_FileInfo->categoryID = metaFile.value("category", 0).toInt();
+ info->m_FileInfo->fileCategory = metaFile.value("fileCategory", 0).toInt();
+ info->m_FileInfo->repository = metaFile.value("repository", "Nexus").toString();
+ info->m_FileInfo->userData = metaFile.value("userData").toMap();
- return info;
+ return info;
}
-void DownloadManager::DownloadInfo::setName(QString newName, bool renameFile) {
- QString oldMetaFileName = QString("%1.meta").arg(m_FileName);
- m_FileName = QFileInfo(newName).fileName();
- if ((m_State == DownloadManager::STATE_STARTED) || (m_State == DownloadManager::STATE_DOWNLOADING)) {
- newName.append(UNFINISHED);
+void DownloadManager::DownloadInfo::setName(QString newName, bool renameFile)
+{
+ QString oldMetaFileName = QString("%1.meta").arg(m_FileName);
+ m_FileName = QFileInfo(newName).fileName();
+ if ((m_State == DownloadManager::STATE_STARTED) ||
+ (m_State == DownloadManager::STATE_DOWNLOADING)) {
+ newName.append(UNFINISHED);
+ }
+ if (renameFile) {
+ if ((newName != m_Output.fileName()) && !m_Output.rename(newName)) {
+ reportError(tr("failed to rename \"%1\" to \"%2\"").arg(m_Output.fileName()).arg(newName));
+ return;
}
- if (renameFile) {
- if ((newName != m_Output.fileName()) && !m_Output.rename(newName)) {
- reportError(tr("failed to rename \"%1\" to \"%2\"").arg(m_Output.fileName()).arg(newName));
- return;
- }
- QFile metaFile(oldMetaFileName);
- if (metaFile.exists()) {
- metaFile.rename(newName.mid(0).append(".meta"));
- }
- }
- if (!m_Output.isOpen()) {
- // can't set file name if it's open
- m_Output.setFileName(newName);
+ QFile metaFile(oldMetaFileName);
+ if (metaFile.exists()) {
+ metaFile.rename(newName.mid(0).append(".meta"));
}
+ }
+ if (!m_Output.isOpen()) {
+ // can't set file name if it's open
+ m_Output.setFileName(newName);
+ }
}
-bool DownloadManager::DownloadInfo::isPausedState() { return m_State == STATE_PAUSED || m_State == STATE_ERROR; }
+bool DownloadManager::DownloadInfo::isPausedState()
+{
+ return m_State == STATE_PAUSED || m_State == STATE_ERROR;
+}
+
+QString DownloadManager::DownloadInfo::currentURL()
+{
+ return m_Urls[m_CurrentUrl];
+}
-QString DownloadManager::DownloadInfo::currentURL() { return m_Urls[m_CurrentUrl]; }
-DownloadManager::DownloadManager(NexusInterface* nexusInterface, QObject* parent)
- : IDownloadManager(parent), m_NexusInterface(nexusInterface), m_DirWatcher(), m_ShowHidden(false),
- m_DateExpression("/Date\\((\\d+)\\)/") {
- connect(&m_DirWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(directoryChanged(QString)));
+DownloadManager::DownloadManager(NexusInterface *nexusInterface, QObject *parent)
+ : IDownloadManager(parent), m_NexusInterface(nexusInterface), m_DirWatcher(), m_ShowHidden(false),
+ m_DateExpression("/Date\\((\\d+)\\)/")
+{
+ connect(&m_DirWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(directoryChanged(QString)));
}
-DownloadManager::~DownloadManager() {
- for (QVector<DownloadInfo*>::iterator iter = m_ActiveDownloads.begin(); iter != m_ActiveDownloads.end(); ++iter) {
- delete *iter;
- }
- m_ActiveDownloads.clear();
+
+DownloadManager::~DownloadManager()
+{
+ for (QVector<DownloadInfo*>::iterator iter = m_ActiveDownloads.begin(); iter != m_ActiveDownloads.end(); ++iter) {
+ delete *iter;
+ }
+ m_ActiveDownloads.clear();
}
-bool DownloadManager::downloadsInProgress() {
- for (QVector<DownloadInfo*>::iterator iter = m_ActiveDownloads.begin(); iter != m_ActiveDownloads.end(); ++iter) {
- if ((*iter)->m_State < STATE_READY) {
- return true;
- }
+
+bool DownloadManager::downloadsInProgress()
+{
+ for (QVector<DownloadInfo*>::iterator iter = m_ActiveDownloads.begin(); iter != m_ActiveDownloads.end(); ++iter) {
+ if ((*iter)->m_State < STATE_READY) {
+ return true;
}
- return false;
+ }
+ return false;
}
-void DownloadManager::pauseAll() {
- // first loop: pause all downloads
- for (int i = 0; i < m_ActiveDownloads.count(); ++i) {
- if (m_ActiveDownloads[i]->m_State < STATE_READY) {
- pauseDownload(i);
- }
+void DownloadManager::pauseAll()
+{
+ // first loop: pause all downloads
+ for (int i = 0; i < m_ActiveDownloads.count(); ++i) {
+ if (m_ActiveDownloads[i]->m_State < STATE_READY) {
+ pauseDownload(i);
}
+ }
- ::Sleep(100);
+ ::Sleep(100);
- bool done = false;
- QTime startTime = QTime::currentTime();
- // further loops: busy waiting for all downloads to complete. This could be neater...
- while (!done && (startTime.secsTo(QTime::currentTime()) < 5)) {
- QCoreApplication::processEvents();
- done = true;
- foreach (DownloadInfo* info, m_ActiveDownloads) {
- if ((info->m_State < STATE_CANCELED) || (info->m_State == STATE_FETCHINGFILEINFO) ||
- (info->m_State == STATE_FETCHINGMODINFO)) {
- done = false;
- break;
- }
- }
- if (!done) {
- ::Sleep(100);
- }
+ bool done = false;
+ QTime startTime = QTime::currentTime();
+ // further loops: busy waiting for all downloads to complete. This could be neater...
+ while (!done && (startTime.secsTo(QTime::currentTime()) < 5)) {
+ QCoreApplication::processEvents();
+ done = true;
+ foreach (DownloadInfo *info, m_ActiveDownloads) {
+ if ((info->m_State < STATE_CANCELED) ||
+ (info->m_State == STATE_FETCHINGFILEINFO) ||
+ (info->m_State == STATE_FETCHINGMODINFO)) {
+ done = false;
+ break;
+ }
+ }
+ if (!done) {
+ ::Sleep(100);
}
+ }
}
-void DownloadManager::setOutputDirectory(const QString& outputDirectory) {
- QStringList directories = m_DirWatcher.directories();
- if (directories.length() != 0) {
- m_DirWatcher.removePaths(directories);
- }
- m_OutputDirectory = QDir::fromNativeSeparators(outputDirectory);
- refreshList();
- m_DirWatcher.addPath(m_OutputDirectory);
+
+void DownloadManager::setOutputDirectory(const QString &outputDirectory)
+{
+ QStringList directories = m_DirWatcher.directories();
+ if (directories.length() != 0) {
+ m_DirWatcher.removePaths(directories);
+ }
+ m_OutputDirectory = QDir::fromNativeSeparators(outputDirectory);
+ refreshList();
+ m_DirWatcher.addPath(m_OutputDirectory);
}
-void DownloadManager::setPreferredServers(const std::map<QString, int>& preferredServers) {
- m_PreferredServers = preferredServers;
+
+void DownloadManager::setPreferredServers(const std::map<QString, int> &preferredServers)
+{
+ m_PreferredServers = preferredServers;
}
-void DownloadManager::setSupportedExtensions(const QStringList& extensions) {
- m_SupportedExtensions = extensions;
- refreshList();
+
+void DownloadManager::setSupportedExtensions(const QStringList &extensions)
+{
+ m_SupportedExtensions = extensions;
+ refreshList();
}
-void DownloadManager::setShowHidden(bool showHidden) {
- m_ShowHidden = showHidden;
- refreshList();
+void DownloadManager::setShowHidden(bool showHidden)
+{
+ m_ShowHidden = showHidden;
+ refreshList();
}
-void DownloadManager::refreshList() {
- try {
- int downloadsBefore = m_ActiveDownloads.size();
+void DownloadManager::refreshList()
+{
+ try {
+ int downloadsBefore = m_ActiveDownloads.size();
- // remove finished downloads
- for (QVector<DownloadInfo*>::iterator iter = m_ActiveDownloads.begin(); iter != m_ActiveDownloads.end();) {
- if (((*iter)->m_State == STATE_READY) || ((*iter)->m_State == STATE_INSTALLED) ||
- ((*iter)->m_State == STATE_UNINSTALLED)) {
- delete *iter;
- iter = m_ActiveDownloads.erase(iter);
- } else {
- ++iter;
- }
- }
+ // remove finished downloads
+ for (QVector<DownloadInfo*>::iterator iter = m_ActiveDownloads.begin(); iter != m_ActiveDownloads.end();) {
+ if (((*iter)->m_State == STATE_READY) || ((*iter)->m_State == STATE_INSTALLED) || ((*iter)->m_State == STATE_UNINSTALLED)) {
+ delete *iter;
+ iter = m_ActiveDownloads.erase(iter);
+ } else {
+ ++iter;
+ }
+ }
- QStringList nameFilters(m_SupportedExtensions);
- foreach (const QString& extension, m_SupportedExtensions) { nameFilters.append("*." + extension); }
+ QStringList nameFilters(m_SupportedExtensions);
+ foreach (const QString &extension, m_SupportedExtensions) {
+ nameFilters.append("*." + extension);
+ }
- nameFilters.append(QString("*").append(UNFINISHED));
- QDir dir(QDir::fromNativeSeparators(m_OutputDirectory));
+ nameFilters.append(QString("*").append(UNFINISHED));
+ QDir dir(QDir::fromNativeSeparators(m_OutputDirectory));
- // find orphaned meta files and delete them (sounds cruel but it's better for everyone)
- QStringList orphans;
- QStringList metaFiles = dir.entryList(QStringList() << "*.meta");
- foreach (const QString& metaFile, metaFiles) {
- QString baseFile = metaFile.left(metaFile.length() - 5);
- if (!QFile::exists(dir.absoluteFilePath(baseFile))) {
- orphans.append(dir.absoluteFilePath(metaFile));
- }
- }
- if (orphans.size() > 0) {
- qDebug("%d orphaned meta files will be deleted", orphans.size());
- shellDelete(orphans, true);
- }
+ // find orphaned meta files and delete them (sounds cruel but it's better for everyone)
+ QStringList orphans;
+ QStringList metaFiles = dir.entryList(QStringList() << "*.meta");
+ foreach (const QString &metaFile, metaFiles) {
+ QString baseFile = metaFile.left(metaFile.length() - 5);
+ if (!QFile::exists(dir.absoluteFilePath(baseFile))) {
+ orphans.append(dir.absoluteFilePath(metaFile));
+ }
+ }
+ if (orphans.size() > 0) {
+ qDebug("%d orphaned meta files will be deleted", orphans.size());
+ shellDelete(orphans, true);
+ }
- // add existing downloads to list
- foreach (QString file, dir.entryList(nameFilters, QDir::Files, QDir::Time)) {
- bool Exists = false;
- for (QVector<DownloadInfo*>::const_iterator Iter = m_ActiveDownloads.begin();
- Iter != m_ActiveDownloads.end() && !Exists; ++Iter) {
- if (QString::compare((*Iter)->m_FileName, file, Qt::CaseInsensitive) == 0) {
- Exists = true;
- } else if (QString::compare(QFileInfo((*Iter)->m_Output.fileName()).fileName(), file,
- Qt::CaseInsensitive) == 0) {
- Exists = true;
- }
- }
- if (Exists) {
- continue;
- }
+ // add existing downloads to list
+ foreach (QString file, dir.entryList(nameFilters, QDir::Files, QDir::Time)) {
+ bool Exists = false;
+ for (QVector<DownloadInfo*>::const_iterator Iter = m_ActiveDownloads.begin(); Iter != m_ActiveDownloads.end() && !Exists; ++Iter) {
+ if (QString::compare((*Iter)->m_FileName, file, Qt::CaseInsensitive) == 0) {
+ Exists = true;
+ } else if (QString::compare(QFileInfo((*Iter)->m_Output.fileName()).fileName(), file, Qt::CaseInsensitive) == 0) {
+ Exists = true;
+ }
+ }
+ if (Exists) {
+ continue;
+ }
- QString fileName = QDir::fromNativeSeparators(m_OutputDirectory) + "/" + file;
+ QString fileName = QDir::fromNativeSeparators(m_OutputDirectory) + "/" + file;
- DownloadInfo* info = DownloadInfo::createFromMeta(fileName, m_ShowHidden);
- if (info != nullptr) {
- m_ActiveDownloads.push_front(info);
- }
- }
+ DownloadInfo *info = DownloadInfo::createFromMeta(fileName, m_ShowHidden);
+ if (info != nullptr) {
+ m_ActiveDownloads.push_front(info);
+ }
+ }
- if (m_ActiveDownloads.size() != downloadsBefore) {
- qDebug("downloads after refresh: %d", m_ActiveDownloads.size());
- }
- emit update(-1);
- } catch (const std::bad_alloc&) {
- reportError(tr("Memory allocation error (in refreshing directory)."));
+ if (m_ActiveDownloads.size() != downloadsBefore) {
+ qDebug("downloads after refresh: %d", m_ActiveDownloads.size());
}
+ emit update(-1);
+ } catch (const std::bad_alloc&) {
+ reportError(tr("Memory allocation error (in refreshing directory)."));
+ }
}
-bool DownloadManager::addDownload(const QStringList& URLs, int modID, int fileID,
- const ModRepositoryFileInfo* fileInfo) {
- QString fileName = QFileInfo(URLs.first()).fileName();
- if (fileName.isEmpty()) {
- fileName = "unknown";
- }
- QUrl preferredUrl = QUrl::fromEncoded(URLs.first().toLocal8Bit());
- qDebug("selected download url: %s", qPrintable(preferredUrl.toString()));
- QNetworkRequest request(preferredUrl);
- return addDownload(m_NexusInterface->getAccessManager()->get(request), URLs, fileName, modID, fileID, fileInfo);
+bool DownloadManager::addDownload(const QStringList &URLs,
+ int modID, int fileID, const ModRepositoryFileInfo *fileInfo)
+{
+ QString fileName = QFileInfo(URLs.first()).fileName();
+ if (fileName.isEmpty()) {
+ fileName = "unknown";
+ }
+
+ QUrl preferredUrl = QUrl::fromEncoded(URLs.first().toLocal8Bit());
+ qDebug("selected download url: %s", qPrintable(preferredUrl.toString()));
+ QNetworkRequest request(preferredUrl);
+ return addDownload(m_NexusInterface->getAccessManager()->get(request), URLs, fileName, modID, fileID, fileInfo);
}
-bool DownloadManager::addDownload(QNetworkReply* reply, const ModRepositoryFileInfo* fileInfo) {
- QString fileName = getFileNameFromNetworkReply(reply);
- if (fileName.isEmpty()) {
- fileName = "unknown";
- }
- return addDownload(reply, QStringList(reply->url().toString()), fileName, fileInfo->modID, fileInfo->fileID,
- fileInfo);
+bool DownloadManager::addDownload(QNetworkReply *reply, const ModRepositoryFileInfo *fileInfo)
+{
+ QString fileName = getFileNameFromNetworkReply(reply);
+ if (fileName.isEmpty()) {
+ fileName = "unknown";
+ }
+
+ return addDownload(reply, QStringList(reply->url().toString()), fileName, fileInfo->modID, fileInfo->fileID, fileInfo);
}
-bool DownloadManager::addDownload(QNetworkReply* reply, const QStringList& URLs, const QString& fileName, int modID,
- int fileID, const ModRepositoryFileInfo* fileInfo) {
- // download invoked from an already open network reply (i.e. download link in the browser)
- DownloadInfo* newDownload = DownloadInfo::createNew(fileInfo, URLs);
- QString baseName = fileName;
- if (!fileInfo->fileName.isEmpty()) {
- baseName = fileInfo->fileName;
- } else {
- QString dispoName = getFileNameFromNetworkReply(reply);
+bool DownloadManager::addDownload(QNetworkReply *reply, const QStringList &URLs, const QString &fileName,
+ int modID, int fileID, const ModRepositoryFileInfo *fileInfo)
+{
+ // download invoked from an already open network reply (i.e. download link in the browser)
+ DownloadInfo *newDownload = DownloadInfo::createNew(fileInfo, URLs);
- if (!dispoName.isEmpty()) {
- baseName = dispoName;
- }
- }
- if (QFile::exists(m_OutputDirectory + "/" + baseName) &&
- (QMessageBox::question(nullptr, tr("Download again?"),
- tr("A file with the same name has already been downloaded. "
- "Do you want to download it again? The new file will receive a different name."),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)) {
- removePending(modID, fileID);
- delete newDownload;
- return false;
+ QString baseName = fileName;
+ if (!fileInfo->fileName.isEmpty()) {
+ baseName = fileInfo->fileName;
+ } else {
+ QString dispoName = getFileNameFromNetworkReply(reply);
+
+ if (!dispoName.isEmpty()) {
+ baseName = dispoName;
}
- newDownload->setName(getDownloadFileName(baseName), false);
+ }
+ if (QFile::exists(m_OutputDirectory + "/" + baseName) &&
+ (QMessageBox::question(nullptr, tr("Download again?"), tr("A file with the same name has already been downloaded. "
+ "Do you want to download it again? The new file will receive a different name."),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)) {
+ removePending(modID, fileID);
+ delete newDownload;
+ return false;
+ }
+ newDownload->setName(getDownloadFileName(baseName), false);
- startDownload(reply, newDownload, false);
- // emit update(-1);
- return true;
+ startDownload(reply, newDownload, false);
+// emit update(-1);
+ return true;
}
-void DownloadManager::removePending(int modID, int fileID) {
- emit aboutToUpdate();
- for (auto iter = m_PendingDownloads.begin(); iter != m_PendingDownloads.end(); ++iter) {
- if ((iter->first == modID) && (iter->second == fileID)) {
- m_PendingDownloads.erase(iter);
- break;
- }
+
+void DownloadManager::removePending(int modID, int fileID)
+{
+ emit aboutToUpdate();
+ for (auto iter = m_PendingDownloads.begin(); iter != m_PendingDownloads.end(); ++iter) {
+ if ((iter->first == modID) && (iter->second == fileID)) {
+ m_PendingDownloads.erase(iter);
+ break;
}
- emit update(-1);
+ }
+ emit update(-1);
}
-void DownloadManager::startDownload(QNetworkReply* reply, DownloadInfo* newDownload, bool resume) {
- reply->setReadBufferSize(1024 * 1024); // don't read more than 1MB at once to avoid memory troubles
- newDownload->m_Reply = reply;
- setState(newDownload, STATE_DOWNLOADING);
- if (newDownload->m_Urls.count() == 0) {
- newDownload->m_Urls = QStringList(reply->url().toString());
- }
- QIODevice::OpenMode mode = QIODevice::WriteOnly;
- if (resume) {
- mode |= QIODevice::Append;
- }
+void DownloadManager::startDownload(QNetworkReply *reply, DownloadInfo *newDownload, bool resume)
+{
+ reply->setReadBufferSize(1024 * 1024); // don't read more than 1MB at once to avoid memory troubles
+ newDownload->m_Reply = reply;
+ setState(newDownload, STATE_DOWNLOADING);
+ if (newDownload->m_Urls.count() == 0) {
+ newDownload->m_Urls = QStringList(reply->url().toString());
+ }
- newDownload->m_StartTime.start();
- createMetaFile(newDownload);
+ QIODevice::OpenMode mode = QIODevice::WriteOnly;
+ if (resume) {
+ mode |= QIODevice::Append;
+ }
- if (!newDownload->m_Output.open(mode)) {
- reportError(tr("failed to download %1: could not open output file: %2")
- .arg(reply->url().toString())
- .arg(newDownload->m_Output.fileName()));
- return;
- }
+ newDownload->m_StartTime.start();
+ createMetaFile(newDownload);
- connect(newDownload->m_Reply, SIGNAL(downloadProgress(qint64, qint64)), this,
- SLOT(downloadProgress(qint64, qint64)));
- connect(newDownload->m_Reply, SIGNAL(finished()), this, SLOT(downloadFinished()));
- connect(newDownload->m_Reply, SIGNAL(error(QNetworkReply::NetworkError)), this,
- SLOT(downloadError(QNetworkReply::NetworkError)));
- connect(newDownload->m_Reply, SIGNAL(readyRead()), this, SLOT(downloadReadyRead()));
- connect(newDownload->m_Reply, SIGNAL(metaDataChanged()), this, SLOT(metaDataChanged()));
+ if (!newDownload->m_Output.open(mode)) {
+ reportError(tr("failed to download %1: could not open output file: %2")
+ .arg(reply->url().toString()).arg(newDownload->m_Output.fileName()));
+ return;
+ }
- if (!resume) {
- newDownload->m_PreResumeSize = newDownload->m_Output.size();
- removePending(newDownload->m_FileInfo->modID, newDownload->m_FileInfo->fileID);
+ connect(newDownload->m_Reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadProgress(qint64, qint64)));
+ connect(newDownload->m_Reply, SIGNAL(finished()), this, SLOT(downloadFinished()));
+ connect(newDownload->m_Reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(downloadError(QNetworkReply::NetworkError)));
+ connect(newDownload->m_Reply, SIGNAL(readyRead()), this, SLOT(downloadReadyRead()));
+ connect(newDownload->m_Reply, SIGNAL(metaDataChanged()), this, SLOT(metaDataChanged()));
- emit aboutToUpdate();
- m_ActiveDownloads.append(newDownload);
+ if (!resume) {
+ newDownload->m_PreResumeSize = newDownload->m_Output.size();
+ removePending(newDownload->m_FileInfo->modID, newDownload->m_FileInfo->fileID);
- emit update(-1);
- emit downloadAdded();
+ emit aboutToUpdate();
+ m_ActiveDownloads.append(newDownload);
- if (reply->isFinished()) {
- // it's possible the download has already finished before this function ran
- downloadFinished();
- }
+ emit update(-1);
+ emit downloadAdded();
+
+ if (reply->isFinished()) {
+ // it's possible the download has already finished before this function ran
+ downloadFinished();
}
+ }
}
-void DownloadManager::addNXMDownload(const QString& url) {
- NXMUrl nxmInfo(url);
- QString managedGame = m_ManagedGame->gameShortName();
- qDebug("add nxm download: %s", qPrintable(url));
- if (nxmInfo.game().compare(managedGame, Qt::CaseInsensitive) != 0) {
- qDebug("download requested for wrong game (game: %s, url: %s)", qPrintable(managedGame),
- qPrintable(nxmInfo.game()));
- QMessageBox::information(nullptr, tr("Wrong Game"),
- tr("The download link is for a mod for \"%1\" but this instance of MO "
- "has been set up for \"%2\".")
- .arg(nxmInfo.game())
- .arg(managedGame),
- QMessageBox::Ok);
- return;
- }
+void DownloadManager::addNXMDownload(const QString &url)
+{
+ NXMUrl nxmInfo(url);
- emit aboutToUpdate();
- m_PendingDownloads.append(std::make_pair(nxmInfo.modId(), nxmInfo.fileId()));
+ QString managedGame = m_ManagedGame->gameShortName();
+ qDebug("add nxm download: %s", qPrintable(url));
+ if (nxmInfo.game().compare(managedGame, Qt::CaseInsensitive) != 0) {
+ qDebug("download requested for wrong game (game: %s, url: %s)", qPrintable(managedGame), qPrintable(nxmInfo.game()));
+ QMessageBox::information(nullptr, tr("Wrong Game"), tr("The download link is for a mod for \"%1\" but this instance of MO "
+ "has been set up for \"%2\".").arg(nxmInfo.game()).arg(managedGame), QMessageBox::Ok);
+ return;
+ }
- emit update(-1);
- emit downloadAdded();
- m_RequestIDs.insert(
- m_NexusInterface->requestFileInfo(nxmInfo.modId(), nxmInfo.fileId(), this, nxmInfo.fileId(), ""));
+ emit aboutToUpdate();
+ m_PendingDownloads.append(std::make_pair(nxmInfo.modId(), nxmInfo.fileId()));
+
+ emit update(-1);
+ emit downloadAdded();
+ m_RequestIDs.insert(m_NexusInterface->requestFileInfo(nxmInfo.modId(), nxmInfo.fileId(), this, nxmInfo.fileId(), ""));
}
-void DownloadManager::removeFile(int index, bool deleteFile) {
- if (index >= m_ActiveDownloads.size()) {
- throw MyException(tr("remove: invalid download index %1").arg(index));
- }
- DownloadInfo* download = m_ActiveDownloads.at(index);
- QString filePath = m_OutputDirectory + "/" + download->m_FileName;
- if ((download->m_State == STATE_STARTED) || (download->m_State == STATE_DOWNLOADING)) {
- // shouldn't have been possible
- qCritical("tried to remove active download");
- return;
- }
+void DownloadManager::removeFile(int index, bool deleteFile)
+{
+ if (index >= m_ActiveDownloads.size()) {
+ throw MyException(tr("remove: invalid download index %1").arg(index));
+ }
- if ((download->m_State == STATE_PAUSED) || (download->m_State == STATE_ERROR)) {
- filePath = download->m_Output.fileName();
- }
+ DownloadInfo *download = m_ActiveDownloads.at(index);
+ QString filePath = m_OutputDirectory + "/" + download->m_FileName;
+ if ((download->m_State == STATE_STARTED) ||
+ (download->m_State == STATE_DOWNLOADING)) {
+ // shouldn't have been possible
+ qCritical("tried to remove active download");
+ return;
+ }
- if (deleteFile) {
- if (!shellDelete(QStringList(filePath), true)) {
- reportError(tr("failed to delete %1").arg(filePath));
- return;
- }
+ if ((download->m_State == STATE_PAUSED) || (download->m_State == STATE_ERROR)) {
+ filePath = download->m_Output.fileName();
+ }
- QFile metaFile(filePath.append(".meta"));
- if (metaFile.exists() && !shellDelete(QStringList(filePath), true)) {
- reportError(tr("failed to delete meta file for %1").arg(filePath));
- }
- } else {
- QSettings metaSettings(filePath.append(".meta"), QSettings::IniFormat);
- metaSettings.setValue("removed", true);
+ if (deleteFile) {
+ if (!shellDelete(QStringList(filePath), true)) {
+ reportError(tr("failed to delete %1").arg(filePath));
+ return;
+ }
+
+ QFile metaFile(filePath.append(".meta"));
+ if (metaFile.exists() && !shellDelete(QStringList(filePath), true)) {
+ reportError(tr("failed to delete meta file for %1").arg(filePath));
}
+ } else {
+ QSettings metaSettings(filePath.append(".meta"), QSettings::IniFormat);
+ metaSettings.setValue("removed", true);
+ }
}
-class LessThanWrapper {
+class LessThanWrapper
+{
public:
- LessThanWrapper(DownloadManager* manager) : m_Manager(manager) {}
- bool operator()(int LHS, int RHS) {
- return m_Manager->getFileName(LHS).compare(m_Manager->getFileName(RHS), Qt::CaseInsensitive) < 0;
- }
+ LessThanWrapper(DownloadManager *manager) : m_Manager(manager) {}
+ bool operator()(int LHS, int RHS) {
+ return m_Manager->getFileName(LHS).compare(m_Manager->getFileName(RHS), Qt::CaseInsensitive) < 0;
+
+ }
private:
- DownloadManager* m_Manager;
+ DownloadManager *m_Manager;
};
-bool DownloadManager::ByName(int LHS, int RHS) {
- return m_ActiveDownloads[LHS]->m_FileName < m_ActiveDownloads[RHS]->m_FileName;
+
+bool DownloadManager::ByName(int LHS, int RHS)
+{
+ return m_ActiveDownloads[LHS]->m_FileName < m_ActiveDownloads[RHS]->m_FileName;
}
-void DownloadManager::refreshAlphabeticalTranslation() {
- m_AlphabeticalTranslation.clear();
- int pos = 0;
- for (QVector<DownloadInfo*>::iterator iter = m_ActiveDownloads.begin(); iter != m_ActiveDownloads.end();
- ++iter, ++pos) {
- m_AlphabeticalTranslation.push_back(pos);
- }
- qSort(m_AlphabeticalTranslation.begin(), m_AlphabeticalTranslation.end(), LessThanWrapper(this));
+void DownloadManager::refreshAlphabeticalTranslation()
+{
+ m_AlphabeticalTranslation.clear();
+ int pos = 0;
+ for (QVector<DownloadInfo*>::iterator iter = m_ActiveDownloads.begin(); iter != m_ActiveDownloads.end(); ++iter, ++pos) {
+ m_AlphabeticalTranslation.push_back(pos);
+ }
+
+ qSort(m_AlphabeticalTranslation.begin(), m_AlphabeticalTranslation.end(), LessThanWrapper(this));
}
-void DownloadManager::restoreDownload(int index) {
- if ((index < 0) || (index >= m_ActiveDownloads.size())) {
- throw MyException(tr("restore: invalid download index: %1").arg(index));
- }
- DownloadInfo* download = m_ActiveDownloads.at(index);
- download->m_Hidden = false;
+void DownloadManager::restoreDownload(int index)
+{
+ if ((index < 0) || (index >= m_ActiveDownloads.size())) {
+ throw MyException(tr("restore: invalid download index: %1").arg(index));
+ }
- QString filePath = m_OutputDirectory + "/" + download->m_FileName;
+ DownloadInfo *download = m_ActiveDownloads.at(index);
+ download->m_Hidden = false;
- QSettings metaSettings(filePath.append(".meta"), QSettings::IniFormat);
- metaSettings.setValue("removed", false);
+ QString filePath = m_OutputDirectory + "/" + download->m_FileName;
+
+ QSettings metaSettings(filePath.append(".meta"), QSettings::IniFormat);
+ metaSettings.setValue("removed", false);
}
-void DownloadManager::removeDownload(int index, bool deleteFile) {
- try {
- emit aboutToUpdate();
- if (index < 0) {
- if (index == -1) {
- DownloadState minState = STATE_READY;
- index = 0;
- for (QVector<DownloadInfo*>::iterator iter = m_ActiveDownloads.begin();
- iter != m_ActiveDownloads.end();) {
- if ((*iter)->m_State >= minState) {
- removeFile(index, deleteFile);
- delete *iter;
- iter = m_ActiveDownloads.erase(iter);
- } else {
- ++iter;
- ++index;
- }
- }
- } else {
- DownloadState minState = STATE_INSTALLED;
- index = 0;
- for (QVector<DownloadInfo*>::iterator iter = m_ActiveDownloads.begin();
- iter != m_ActiveDownloads.end();) {
- if ((*iter)->m_State == minState) {
- removeFile(index, deleteFile);
- delete *iter;
- iter = m_ActiveDownloads.erase(iter);
- } else {
- ++iter;
- ++index;
- }
- }
- }
- } else {
- if (index >= m_ActiveDownloads.size()) {
- reportError(tr("remove: invalid download index %1").arg(index));
- return;
- }
+void DownloadManager::removeDownload(int index, bool deleteFile)
+{
+ try {
+ emit aboutToUpdate();
- removeFile(index, deleteFile);
- delete m_ActiveDownloads.at(index);
- m_ActiveDownloads.erase(m_ActiveDownloads.begin() + index);
- }
- emit update(-1);
- } catch (const std::exception& e) {
- qCritical("failed to remove download: %s", e.what());
+ if (index < 0) {
+ if (index == -1) {
+ DownloadState minState = STATE_READY;
+ index = 0;
+ for (QVector<DownloadInfo*>::iterator iter = m_ActiveDownloads.begin(); iter != m_ActiveDownloads.end();) {
+ if ((*iter)->m_State >= minState) {
+ removeFile(index, deleteFile);
+ delete *iter;
+ iter = m_ActiveDownloads.erase(iter);
+ }
+ else {
+ ++iter;
+ ++index;
+ }
+ }
+ }
+ else {
+ DownloadState minState = STATE_INSTALLED;
+ index = 0;
+ for (QVector<DownloadInfo*>::iterator iter = m_ActiveDownloads.begin(); iter != m_ActiveDownloads.end();) {
+ if ((*iter)->m_State == minState) {
+ removeFile(index, deleteFile);
+ delete *iter;
+ iter = m_ActiveDownloads.erase(iter);
+ }
+ else {
+ ++iter;
+ ++index;
+ }
+ }
+ }
+ } else {
+ if (index >= m_ActiveDownloads.size()) {
+ reportError(tr("remove: invalid download index %1").arg(index));
+ return;
+ }
+
+ removeFile(index, deleteFile);
+ delete m_ActiveDownloads.at(index);
+ m_ActiveDownloads.erase(m_ActiveDownloads.begin() + index);
}
+ emit update(-1);
+ } catch (const std::exception &e) {
+ qCritical("failed to remove download: %s", e.what());
+ }
}
-void DownloadManager::cancelDownload(int index) {
- if ((index < 0) || (index >= m_ActiveDownloads.size())) {
- reportError(tr("cancel: invalid download index %1").arg(index));
- return;
- }
- if (m_ActiveDownloads.at(index)->m_State == STATE_DOWNLOADING) {
- setState(m_ActiveDownloads.at(index), STATE_CANCELING);
- }
+void DownloadManager::cancelDownload(int index)
+{
+ if ((index < 0) || (index >= m_ActiveDownloads.size())) {
+ reportError(tr("cancel: invalid download index %1").arg(index));
+ return;
+ }
+
+ if (m_ActiveDownloads.at(index)->m_State == STATE_DOWNLOADING) {
+ setState(m_ActiveDownloads.at(index), STATE_CANCELING);
+ }
}
-void DownloadManager::pauseDownload(int index) {
- if ((index < 0) || (index >= m_ActiveDownloads.size())) {
- reportError(tr("pause: invalid download index %1").arg(index));
- return;
- }
- DownloadInfo* info = m_ActiveDownloads.at(index);
+void DownloadManager::pauseDownload(int index)
+{
+ if ((index < 0) || (index >= m_ActiveDownloads.size())) {
+ reportError(tr("pause: invalid download index %1").arg(index));
+ return;
+ }
- if (info->m_State == STATE_DOWNLOADING) {
- if ((info->m_Reply != nullptr) && (info->m_Reply->isRunning())) {
- setState(info, STATE_PAUSING);
- } else {
- setState(info, STATE_PAUSED);
- }
- } else if ((info->m_State == STATE_FETCHINGMODINFO) || (info->m_State == STATE_FETCHINGFILEINFO)) {
- setState(info, STATE_READY);
+ DownloadInfo *info = m_ActiveDownloads.at(index);
+
+ if (info->m_State == STATE_DOWNLOADING) {
+ if ((info->m_Reply != nullptr) && (info->m_Reply->isRunning())) {
+ setState(info, STATE_PAUSING);
+ } else {
+ setState(info, STATE_PAUSED);
}
+ } else if ((info->m_State == STATE_FETCHINGMODINFO) || (info->m_State == STATE_FETCHINGFILEINFO)) {
+ setState(info, STATE_READY);
+ }
}
-void DownloadManager::resumeDownload(int index) {
- if ((index < 0) || (index >= m_ActiveDownloads.size())) {
- reportError(tr("resume: invalid download index %1").arg(index));
- return;
- }
- DownloadInfo* info = m_ActiveDownloads[index];
- info->m_Tries = AUTOMATIC_RETRIES;
- resumeDownloadInt(index);
+void DownloadManager::resumeDownload(int index)
+{
+ if ((index < 0) || (index >= m_ActiveDownloads.size())) {
+ reportError(tr("resume: invalid download index %1").arg(index));
+ return;
+ }
+ DownloadInfo *info = m_ActiveDownloads[index];
+ info->m_Tries = AUTOMATIC_RETRIES;
+ resumeDownloadInt(index);
}
-void DownloadManager::resumeDownloadInt(int index) {
- if ((index < 0) || (index >= m_ActiveDownloads.size())) {
- reportError(tr("resume (int): invalid download index %1").arg(index));
- return;
+void DownloadManager::resumeDownloadInt(int index)
+{
+ if ((index < 0) || (index >= m_ActiveDownloads.size())) {
+ reportError(tr("resume (int): invalid download index %1").arg(index));
+ return;
+ }
+ DownloadInfo *info = m_ActiveDownloads[index];
+ if (info->isPausedState()) {
+ if ((info->m_Urls.size() == 0)
+ || ((info->m_Urls.size() == 1) && (info->m_Urls[0].size() == 0))) {
+ emit showMessage(tr("No known download urls. Sorry, this download can't be resumed."));
+ return;
}
- DownloadInfo* info = m_ActiveDownloads[index];
- if (info->isPausedState()) {
- if ((info->m_Urls.size() == 0) || ((info->m_Urls.size() == 1) && (info->m_Urls[0].size() == 0))) {
- emit showMessage(tr("No known download urls. Sorry, this download can't be resumed."));
- return;
- }
- if (info->m_State == STATE_ERROR) {
- info->m_CurrentUrl = (info->m_CurrentUrl + 1) % info->m_Urls.count();
- }
- qDebug("request resume from url %s", qPrintable(info->currentURL()));
- QNetworkRequest request(QUrl::fromEncoded(info->currentURL().toLocal8Bit()));
- info->m_ResumePos = info->m_Output.size();
- qDebug("resume at %lld bytes", info->m_ResumePos);
- QByteArray rangeHeader = "bytes=" + QByteArray::number(info->m_ResumePos) + "-";
- request.setRawHeader("Range", rangeHeader);
- startDownload(m_NexusInterface->getAccessManager()->get(request), info, true);
+ if (info->m_State == STATE_ERROR) {
+ info->m_CurrentUrl = (info->m_CurrentUrl + 1) % info->m_Urls.count();
}
- emit update(index);
+ qDebug("request resume from url %s", qPrintable(info->currentURL()));
+ QNetworkRequest request(QUrl::fromEncoded(info->currentURL().toLocal8Bit()));
+ info->m_ResumePos = info->m_Output.size();
+ qDebug("resume at %lld bytes", info->m_ResumePos);
+ QByteArray rangeHeader = "bytes=" + QByteArray::number(info->m_ResumePos) + "-";
+ request.setRawHeader("Range", rangeHeader);
+ startDownload(m_NexusInterface->getAccessManager()->get(request), info, true);
+ }
+ emit update(index);
}
-DownloadManager::DownloadInfo* DownloadManager::downloadInfoByID(unsigned int id) {
- auto iter = std::find_if(m_ActiveDownloads.begin(), m_ActiveDownloads.end(),
- [id](DownloadInfo* info) { return info->m_DownloadID == id; });
- if (iter != m_ActiveDownloads.end()) {
- return *iter;
- } else {
- return nullptr;
- }
+
+DownloadManager::DownloadInfo *DownloadManager::downloadInfoByID(unsigned int id)
+{
+ auto iter = std::find_if(m_ActiveDownloads.begin(), m_ActiveDownloads.end(),
+ [id](DownloadInfo *info) { return info->m_DownloadID == id; });
+ if (iter != m_ActiveDownloads.end()) {
+ return *iter;
+ } else {
+ return nullptr;
+ }
}
-void DownloadManager::queryInfo(int index) {
- if ((index < 0) || (index >= m_ActiveDownloads.size())) {
- reportError(tr("query: invalid download index %1").arg(index));
- return;
- }
- DownloadInfo* info = m_ActiveDownloads[index];
- if (info->m_FileInfo->repository != "Nexus") {
- qWarning("re-querying file info is currently only possible with Nexus");
- return;
- }
+void DownloadManager::queryInfo(int index)
+{
+ if ((index < 0) || (index >= m_ActiveDownloads.size())) {
+ reportError(tr("query: invalid download index %1").arg(index));
+ return;
+ }
+ DownloadInfo *info = m_ActiveDownloads[index];
- if (info->m_State < DownloadManager::STATE_READY) {
- // UI shouldn't allow this
- return;
- }
+ if (info->m_FileInfo->repository != "Nexus") {
+ qWarning("re-querying file info is currently only possible with Nexus");
+ return;
+ }
- if (info->m_FileInfo->modID <= 0) {
- QString fileName = getFileName(index);
- QString ignore;
- NexusInterface::interpretNexusFileName(fileName, ignore, info->m_FileInfo->modID, true);
- if (info->m_FileInfo->modID < 0) {
- bool ok = false;
- int modId = QInputDialog::getInt(nullptr, tr("Please enter the nexus mod id"), tr("Mod ID:"), 1, 1,
- std::numeric_limits<int>::max(), 1, &ok);
- // careful now: while the dialog was displayed, events were processed.
- // the download list might have changed and our info-ptr invalidated.
- m_ActiveDownloads[index]->m_FileInfo->modID = modId;
- return;
- }
+ if (info->m_State < DownloadManager::STATE_READY) {
+ // UI shouldn't allow this
+ return;
+ }
+
+ if (info->m_FileInfo->modID <= 0) {
+ QString fileName = getFileName(index);
+ QString ignore;
+ NexusInterface::interpretNexusFileName(fileName, ignore, info->m_FileInfo->modID, true);
+ if (info->m_FileInfo->modID < 0) {
+ bool ok = false;
+ int modId = QInputDialog::getInt(
+ nullptr, tr("Please enter the nexus mod id"), tr("Mod ID:"), 1, 1,
+ std::numeric_limits<int>::max(), 1, &ok);
+ // careful now: while the dialog was displayed, events were processed.
+ // the download list might have changed and our info-ptr invalidated.
+ m_ActiveDownloads[index]->m_FileInfo->modID = modId;
+ return;
}
- info->m_ReQueried = true;
- setState(info, STATE_FETCHINGMODINFO);
+ }
+ info->m_ReQueried = true;
+ setState(info, STATE_FETCHINGMODINFO);
}
-int DownloadManager::numTotalDownloads() const { return m_ActiveDownloads.size(); }
-int DownloadManager::numPendingDownloads() const { return m_PendingDownloads.size(); }
+int DownloadManager::numTotalDownloads() const
+{
+ return m_ActiveDownloads.size();
+}
-std::pair<int, int> DownloadManager::getPendingDownload(int index) {
- if ((index < 0) || (index >= m_PendingDownloads.size())) {
- throw MyException(tr("get pending: invalid download index %1").arg(index));
- }
+int DownloadManager::numPendingDownloads() const
+{
+ return m_PendingDownloads.size();
+}
+
+std::pair<int, int> DownloadManager::getPendingDownload(int index)
+{
+ if ((index < 0) || (index >= m_PendingDownloads.size())) {
+ throw MyException(tr("get pending: invalid download index %1").arg(index));
+ }
- return m_PendingDownloads.at(index);
+ return m_PendingDownloads.at(index);
}
-QString DownloadManager::getFilePath(int index) const {
- if ((index < 0) || (index >= m_ActiveDownloads.size())) {
- throw MyException(tr("get path: invalid download index %1").arg(index));
- }
+QString DownloadManager::getFilePath(int index) const
+{
+ if ((index < 0) || (index >= m_ActiveDownloads.size())) {
+ throw MyException(tr("get path: invalid download index %1").arg(index));
+ }
- return m_OutputDirectory + "/" + m_ActiveDownloads.at(index)->m_FileName;
+ return m_OutputDirectory + "/" + m_ActiveDownloads.at(index)->m_FileName;
}
-QString DownloadManager::getFileTypeString(int fileType) {
- switch (fileType) {
- case 1:
- return tr("Main");
- case 2:
- return tr("Update");
- case 3:
- return tr("Optional");
- case 4:
- return tr("Old");
- case 5:
- return tr("Misc");
- default:
- return tr("Unknown");
- }
+QString DownloadManager::getFileTypeString(int fileType)
+{
+ switch (fileType) {
+ case 1: return tr("Main");
+ case 2: return tr("Update");
+ case 3: return tr("Optional");
+ case 4: return tr("Old");
+ case 5: return tr("Misc");
+ default: return tr("Unknown");
+ }
}
-QString DownloadManager::getDisplayName(int index) const {
- if ((index < 0) || (index >= m_ActiveDownloads.size())) {
- throw MyException(tr("display name: invalid download index %1").arg(index));
- }
+QString DownloadManager::getDisplayName(int index) const
+{
+ if ((index < 0) || (index >= m_ActiveDownloads.size())) {
+ throw MyException(tr("display name: invalid download index %1").arg(index));
+ }
- DownloadInfo* info = m_ActiveDownloads.at(index);
+ DownloadInfo *info = m_ActiveDownloads.at(index);
- QTextDocument doc;
- if (!info->m_FileInfo->name.isEmpty()) {
- doc.setHtml(info->m_FileInfo->name);
- return QString("%1 (%2, v%3)")
- .arg(doc.toPlainText())
- .arg(getFileTypeString(info->m_FileInfo->fileCategory))
- .arg(info->m_FileInfo->version.displayString());
- } else {
- doc.setHtml(info->m_FileName);
- return doc.toPlainText();
- }
+ QTextDocument doc;
+ if (!info->m_FileInfo->name.isEmpty()) {
+ doc.setHtml(info->m_FileInfo->name);
+ return QString("%1 (%2, v%3)").arg(doc.toPlainText())
+ .arg(getFileTypeString(info->m_FileInfo->fileCategory))
+ .arg(info->m_FileInfo->version.displayString());
+ } else {
+ doc.setHtml(info->m_FileName);
+ return doc.toPlainText();
+ }
}
-QString DownloadManager::getFileName(int index) const {
- if ((index < 0) || (index >= m_ActiveDownloads.size())) {
- throw MyException(tr("file name: invalid download index %1").arg(index));
- }
+QString DownloadManager::getFileName(int index) const
+{
+ if ((index < 0) || (index >= m_ActiveDownloads.size())) {
+ throw MyException(tr("file name: invalid download index %1").arg(index));
+ }
- return m_ActiveDownloads.at(index)->m_FileName;
+ return m_ActiveDownloads.at(index)->m_FileName;
}
-QDateTime DownloadManager::getFileTime(int index) const {
- if ((index < 0) || (index >= m_ActiveDownloads.size())) {
- throw MyException(tr("file time: invalid download index %1").arg(index));
- }
+QDateTime DownloadManager::getFileTime(int index) const
+{
+ if ((index < 0) || (index >= m_ActiveDownloads.size())) {
+ throw MyException(tr("file time: invalid download index %1").arg(index));
+ }
- DownloadInfo* info = m_ActiveDownloads.at(index);
- if (!info->m_Created.isValid()) {
- info->m_Created = QFileInfo(info->m_Output).created();
- }
+ DownloadInfo *info = m_ActiveDownloads.at(index);
+ if (!info->m_Created.isValid()) {
+ info->m_Created = QFileInfo(info->m_Output).created();
+ }
- return info->m_Created;
+ return info->m_Created;
}
-qint64 DownloadManager::getFileSize(int index) const {
- if ((index < 0) || (index >= m_ActiveDownloads.size())) {
- throw MyException(tr("file size: invalid download index %1").arg(index));
- }
+qint64 DownloadManager::getFileSize(int index) const
+{
+ if ((index < 0) || (index >= m_ActiveDownloads.size())) {
+ throw MyException(tr("file size: invalid download index %1").arg(index));
+ }
- return m_ActiveDownloads.at(index)->m_TotalSize;
+ return m_ActiveDownloads.at(index)->m_TotalSize;
}
-int DownloadManager::getProgress(int index) const {
- if ((index < 0) || (index >= m_ActiveDownloads.size())) {
- throw MyException(tr("progress: invalid download index %1").arg(index));
- }
- return m_ActiveDownloads.at(index)->m_Progress;
+int DownloadManager::getProgress(int index) const
+{
+ if ((index < 0) || (index >= m_ActiveDownloads.size())) {
+ throw MyException(tr("progress: invalid download index %1").arg(index));
+ }
+
+ return m_ActiveDownloads.at(index)->m_Progress;
}
-DownloadManager::DownloadState DownloadManager::getState(int index) const {
- if ((index < 0) || (index >= m_ActiveDownloads.size())) {
- throw MyException(tr("state: invalid download index %1").arg(index));
- }
- return m_ActiveDownloads.at(index)->m_State;
+DownloadManager::DownloadState DownloadManager::getState(int index) const
+{
+ if ((index < 0) || (index >= m_ActiveDownloads.size())) {
+ throw MyException(tr("state: invalid download index %1").arg(index));
+ }
+
+ return m_ActiveDownloads.at(index)->m_State;
}
-bool DownloadManager::isInfoIncomplete(int index) const {
- if ((index < 0) || (index >= m_ActiveDownloads.size())) {
- throw MyException(tr("infocomplete: invalid download index %1").arg(index));
- }
- DownloadInfo* info = m_ActiveDownloads.at(index);
- if (info->m_FileInfo->repository != "Nexus") {
- // other repositories currently don't support re-querying info anyway
- return false;
- }
- return (info->m_FileInfo->fileID == 0) || (info->m_FileInfo->modID == 0);
+bool DownloadManager::isInfoIncomplete(int index) const
+{
+ if ((index < 0) || (index >= m_ActiveDownloads.size())) {
+ throw MyException(tr("infocomplete: invalid download index %1").arg(index));
+ }
+
+ DownloadInfo *info = m_ActiveDownloads.at(index);
+ if (info->m_FileInfo->repository != "Nexus") {
+ // other repositories currently don't support re-querying info anyway
+ return false;
+ }
+ return (info->m_FileInfo->fileID == 0) || (info->m_FileInfo->modID == 0);
}
-int DownloadManager::getModID(int index) const {
- if ((index < 0) || (index >= m_ActiveDownloads.size())) {
- throw MyException(tr("mod id: invalid download index %1").arg(index));
- }
- return m_ActiveDownloads.at(index)->m_FileInfo->modID;
+
+int DownloadManager::getModID(int index) const
+{
+ if ((index < 0) || (index >= m_ActiveDownloads.size())) {
+ throw MyException(tr("mod id: invalid download index %1").arg(index));
+ }
+ return m_ActiveDownloads.at(index)->m_FileInfo->modID;
}
-bool DownloadManager::isHidden(int index) const {
- if ((index < 0) || (index >= m_ActiveDownloads.size())) {
- throw MyException(tr("ishidden: invalid download index %1").arg(index));
- }
- return m_ActiveDownloads.at(index)->m_Hidden;
+bool DownloadManager::isHidden(int index) const
+{
+ if ((index < 0) || (index >= m_ActiveDownloads.size())) {
+ throw MyException(tr("ishidden: invalid download index %1").arg(index));
+ }
+ return m_ActiveDownloads.at(index)->m_Hidden;
}
-const ModRepositoryFileInfo* DownloadManager::getFileInfo(int index) const {
- if ((index < 0) || (index >= m_ActiveDownloads.size())) {
- throw MyException(tr("file info: invalid download index %1").arg(index));
- }
- return m_ActiveDownloads.at(index)->m_FileInfo;
+const ModRepositoryFileInfo *DownloadManager::getFileInfo(int index) const
+{
+ if ((index < 0) || (index >= m_ActiveDownloads.size())) {
+ throw MyException(tr("file info: invalid download index %1").arg(index));
+ }
+
+ return m_ActiveDownloads.at(index)->m_FileInfo;
}
-void DownloadManager::markInstalled(int index) {
- if ((index < 0) || (index >= m_ActiveDownloads.size())) {
- throw MyException(tr("mark installed: invalid download index %1").arg(index));
- }
- DownloadInfo* info = m_ActiveDownloads.at(index);
- QSettings metaFile(info->m_Output.fileName() + ".meta", QSettings::IniFormat);
- metaFile.setValue("installed", true);
- metaFile.setValue("uninstalled", false);
+void DownloadManager::markInstalled(int index)
+{
+ if ((index < 0) || (index >= m_ActiveDownloads.size())) {
+ throw MyException(tr("mark installed: invalid download index %1").arg(index));
+ }
+
+ DownloadInfo *info = m_ActiveDownloads.at(index);
+ QSettings metaFile(info->m_Output.fileName() + ".meta", QSettings::IniFormat);
+ metaFile.setValue("installed", true);
+ metaFile.setValue("uninstalled", false);
- setState(m_ActiveDownloads.at(index), STATE_INSTALLED);
+ setState(m_ActiveDownloads.at(index), STATE_INSTALLED);
}
-void DownloadManager::markUninstalled(int index) {
- if ((index < 0) || (index >= m_ActiveDownloads.size())) {
- throw MyException(tr("mark uninstalled: invalid download index %1").arg(index));
- }
- DownloadInfo* info = m_ActiveDownloads.at(index);
- QSettings metaFile(info->m_Output.fileName() + ".meta", QSettings::IniFormat);
- metaFile.setValue("uninstalled", true);
+void DownloadManager::markUninstalled(int index)
+{
+ if ((index < 0) || (index >= m_ActiveDownloads.size())) {
+ throw MyException(tr("mark uninstalled: invalid download index %1").arg(index));
+ }
+
+ DownloadInfo *info = m_ActiveDownloads.at(index);
+ QSettings metaFile(info->m_Output.fileName() + ".meta", QSettings::IniFormat);
+ metaFile.setValue("uninstalled", true);
- setState(m_ActiveDownloads.at(index), STATE_UNINSTALLED);
+ setState(m_ActiveDownloads.at(index), STATE_UNINSTALLED);
}
-QString DownloadManager::getDownloadFileName(const QString& baseName) const {
- QString fullPath = m_OutputDirectory + "/" + baseName;
- if (QFile::exists(fullPath)) {
- int i = 1;
- while (QFile::exists(QString("%1/%2_%3").arg(m_OutputDirectory).arg(i).arg(baseName))) {
- ++i;
- }
- fullPath = QString("%1/%2_%3").arg(m_OutputDirectory).arg(i).arg(baseName);
+QString DownloadManager::getDownloadFileName(const QString &baseName) const
+{
+ QString fullPath = m_OutputDirectory + "/" + baseName;
+ if (QFile::exists(fullPath)) {
+ int i = 1;
+ while (QFile::exists(QString("%1/%2_%3").arg(m_OutputDirectory).arg(i).arg(baseName))) {
+ ++i;
}
- return fullPath;
+
+ fullPath = QString("%1/%2_%3").arg(m_OutputDirectory).arg(i).arg(baseName);
+ }
+ return fullPath;
}
-QString DownloadManager::getFileNameFromNetworkReply(QNetworkReply* reply) {
- if (reply->hasRawHeader("Content-Disposition")) {
- std::regex exp("filename=\"(.*)\"");
- std::cmatch result;
- if (std::regex_search(reply->rawHeader("Content-Disposition").constData(), result, exp)) {
- return QString::fromUtf8(result.str(1).c_str());
- }
+QString DownloadManager::getFileNameFromNetworkReply(QNetworkReply *reply)
+{
+ if (reply->hasRawHeader("Content-Disposition")) {
+ std::regex exp("filename=\"(.*)\"");
+
+ std::cmatch result;
+ if (std::regex_search(reply->rawHeader("Content-Disposition").constData(), result, exp)) {
+ return QString::fromUtf8(result.str(1).c_str());
}
+ }
- return QString();
+ return QString();
}
-void DownloadManager::setState(DownloadManager::DownloadInfo* info, DownloadManager::DownloadState state) {
- int row = 0;
- for (int i = 0; i < m_ActiveDownloads.size(); ++i) {
- if (m_ActiveDownloads[i] == info) {
- row = i;
- break;
- }
+
+void DownloadManager::setState(DownloadManager::DownloadInfo *info, DownloadManager::DownloadState state)
+{
+ int row = 0;
+ for (int i = 0; i < m_ActiveDownloads.size(); ++i) {
+ if (m_ActiveDownloads[i] == info) {
+ row = i;
+ break;
}
- info->m_State = state;
- switch (state) {
+ }
+ info->m_State = state;
+ switch (state) {
case STATE_PAUSED:
case STATE_ERROR: {
- info->m_Reply->abort();
+ info->m_Reply->abort();
} break;
case STATE_CANCELED: {
- info->m_Reply->abort();
+ info->m_Reply->abort();
} break;
case STATE_FETCHINGMODINFO: {
- m_RequestIDs.insert(
- m_NexusInterface->requestDescription(info->m_FileInfo->modID, this, info->m_DownloadID, QString()));
+ m_RequestIDs.insert(m_NexusInterface->requestDescription(info->m_FileInfo->modID, this, info->m_DownloadID, QString()));
} break;
case STATE_FETCHINGFILEINFO: {
- m_RequestIDs.insert(
- m_NexusInterface->requestFiles(info->m_FileInfo->modID, this, info->m_DownloadID, QString()));
+ m_RequestIDs.insert(m_NexusInterface->requestFiles(info->m_FileInfo->modID, this, info->m_DownloadID, QString()));
} break;
case STATE_READY: {
- createMetaFile(info);
- emit downloadComplete(row);
+ createMetaFile(info);
+ emit downloadComplete(row);
} break;
- default: /* NOP */
- break;
- }
- emit stateChanged(row, state);
+ default: /* NOP */ break;
+ }
+ emit stateChanged(row, state);
}
-DownloadManager::DownloadInfo* DownloadManager::findDownload(QObject* reply, int* index) const {
- // reverse search as newer, thus more relevant, downloads are at the end
- for (int i = m_ActiveDownloads.size() - 1; i >= 0; --i) {
- if (m_ActiveDownloads[i]->m_Reply == reply) {
- if (index != nullptr) {
- *index = i;
- }
- return m_ActiveDownloads[i];
- }
+
+DownloadManager::DownloadInfo *DownloadManager::findDownload(QObject *reply, int *index) const
+{
+ // reverse search as newer, thus more relevant, downloads are at the end
+ for (int i = m_ActiveDownloads.size() - 1; i >= 0; --i) {
+ if (m_ActiveDownloads[i]->m_Reply == reply) {
+ if (index != nullptr) {
+ *index = i;
+ }
+ return m_ActiveDownloads[i];
}
- return nullptr;
+ }
+ return nullptr;
}
-void DownloadManager::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) {
- if (bytesTotal == 0) {
- return;
- }
- int index = 0;
- try {
- DownloadInfo* info = findDownload(this->sender(), &index);
- if (info != nullptr) {
- if (info->m_State == STATE_CANCELING) {
- setState(info, STATE_CANCELED);
- } else if (info->m_State == STATE_PAUSING) {
- setState(info, STATE_PAUSED);
- } else {
- if (bytesTotal > info->m_TotalSize) {
- info->m_TotalSize = bytesTotal;
- }
- int oldProgress = info->m_Progress;
- info->m_Progress = ((info->m_ResumePos + bytesReceived) * 100) / (info->m_ResumePos + bytesTotal);
- TaskProgressManager::instance().updateProgress(info->m_TaskProgressId, bytesReceived, bytesTotal);
- if (oldProgress != info->m_Progress) {
- emit update(index);
- }
- }
+
+void DownloadManager::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
+{
+ if (bytesTotal == 0) {
+ return;
+ }
+ int index = 0;
+ try {
+ DownloadInfo *info = findDownload(this->sender(), &index);
+ if (info != nullptr) {
+ if (info->m_State == STATE_CANCELING) {
+ setState(info, STATE_CANCELED);
+ } else if (info->m_State == STATE_PAUSING) {
+ setState(info, STATE_PAUSED);
+ } else {
+ if (bytesTotal > info->m_TotalSize) {
+ info->m_TotalSize = bytesTotal;
+ }
+ int oldProgress = info->m_Progress;
+ info->m_Progress = ((info->m_ResumePos + bytesReceived) * 100) / (info->m_ResumePos + bytesTotal);
+ TaskProgressManager::instance().updateProgress(info->m_TaskProgressId, bytesReceived, bytesTotal);
+ if (oldProgress != info->m_Progress) {
+ emit update(index);
}
- } catch (const std::bad_alloc&) {
- reportError(tr("Memory allocation error (in processing progress event)."));
+ }
}
+ } catch (const std::bad_alloc&) {
+ reportError(tr("Memory allocation error (in processing progress event)."));
+ }
}
-void DownloadManager::downloadReadyRead() {
- try {
- DownloadInfo* info = findDownload(this->sender());
- if (info != nullptr) {
- info->m_Output.write(info->m_Reply->readAll());
- }
- } catch (const std::bad_alloc&) {
- reportError(tr("Memory allocation error (in processing downloaded data)."));
+
+void DownloadManager::downloadReadyRead()
+{
+ try {
+ DownloadInfo *info = findDownload(this->sender());
+ if (info != nullptr) {
+ info->m_Output.write(info->m_Reply->readAll());
}
+ } catch (const std::bad_alloc&) {
+ reportError(tr("Memory allocation error (in processing downloaded data)."));
+ }
}
-void DownloadManager::createMetaFile(DownloadInfo* info) {
- QSettings metaFile(QString("%1.meta").arg(info->m_Output.fileName()), QSettings::IniFormat);
- metaFile.setValue("modID", info->m_FileInfo->modID);
- metaFile.setValue("fileID", info->m_FileInfo->fileID);
- metaFile.setValue("url", info->m_Urls.join(";"));
- metaFile.setValue("name", info->m_FileInfo->name);
- metaFile.setValue("description", info->m_FileInfo->description);
- metaFile.setValue("modName", info->m_FileInfo->modName);
- metaFile.setValue("version", info->m_FileInfo->version.canonicalString());
- metaFile.setValue("newestVersion", info->m_FileInfo->newestVersion.canonicalString());
- metaFile.setValue("fileTime", info->m_FileInfo->fileTime);
- metaFile.setValue("fileCategory", info->m_FileInfo->fileCategory);
- metaFile.setValue("category", info->m_FileInfo->categoryID);
- metaFile.setValue("repository", info->m_FileInfo->repository);
- metaFile.setValue("userData", info->m_FileInfo->userData);
- metaFile.setValue("installed", info->m_State == DownloadManager::STATE_INSTALLED);
- metaFile.setValue("uninstalled", info->m_State == DownloadManager::STATE_UNINSTALLED);
- metaFile.setValue("paused", (info->m_State == DownloadManager::STATE_PAUSED) ||
- (info->m_State == DownloadManager::STATE_ERROR));
- metaFile.setValue("removed", info->m_Hidden);
- // slightly hackish...
- for (int i = 0; i < m_ActiveDownloads.size(); ++i) {
- if (m_ActiveDownloads[i] == info) {
- emit update(i);
- }
+void DownloadManager::createMetaFile(DownloadInfo *info)
+{
+ QSettings metaFile(QString("%1.meta").arg(info->m_Output.fileName()), QSettings::IniFormat);
+ metaFile.setValue("modID", info->m_FileInfo->modID);
+ metaFile.setValue("fileID", info->m_FileInfo->fileID);
+ metaFile.setValue("url", info->m_Urls.join(";"));
+ metaFile.setValue("name", info->m_FileInfo->name);
+ metaFile.setValue("description", info->m_FileInfo->description);
+ metaFile.setValue("modName", info->m_FileInfo->modName);
+ metaFile.setValue("version", info->m_FileInfo->version.canonicalString());
+ metaFile.setValue("newestVersion", info->m_FileInfo->newestVersion.canonicalString());
+ metaFile.setValue("fileTime", info->m_FileInfo->fileTime);
+ metaFile.setValue("fileCategory", info->m_FileInfo->fileCategory);
+ metaFile.setValue("category", info->m_FileInfo->categoryID);
+ metaFile.setValue("repository", info->m_FileInfo->repository);
+ metaFile.setValue("userData", info->m_FileInfo->userData);
+ metaFile.setValue("installed", info->m_State == DownloadManager::STATE_INSTALLED);
+ metaFile.setValue("uninstalled", info->m_State == DownloadManager::STATE_UNINSTALLED);
+ metaFile.setValue("paused", (info->m_State == DownloadManager::STATE_PAUSED) ||
+ (info->m_State == DownloadManager::STATE_ERROR));
+ metaFile.setValue("removed", info->m_Hidden);
+
+ // slightly hackish...
+ for (int i = 0; i < m_ActiveDownloads.size(); ++i) {
+ if (m_ActiveDownloads[i] == info) {
+ emit update(i);
}
+ }
}
-void DownloadManager::nxmDescriptionAvailable(int, QVariant userData, QVariant resultData, int requestID) {
- std::set<int>::iterator idIter = m_RequestIDs.find(requestID);
- if (idIter == m_RequestIDs.end()) {
- return;
- } else {
- m_RequestIDs.erase(idIter);
- }
- QVariantMap result = resultData.toMap();
+void DownloadManager::nxmDescriptionAvailable(int, QVariant userData, QVariant resultData, int requestID)
+{
+ std::set<int>::iterator idIter = m_RequestIDs.find(requestID);
+ if (idIter == m_RequestIDs.end()) {
+ return;
+ } else {
+ m_RequestIDs.erase(idIter);
+ }
- DownloadInfo* info = downloadInfoByID(userData.toInt());
- if (info == nullptr)
- return;
- info->m_FileInfo->categoryID = result["category_id"].toInt();
- QTextDocument doc;
- doc.setHtml(result["name"].toString().trimmed());
- info->m_FileInfo->modName = doc.toPlainText();
- info->m_FileInfo->newestVersion.parse(result["version"].toString());
- if (info->m_FileInfo->fileID != 0) {
- setState(info, STATE_READY);
- } else {
- setState(info, STATE_FETCHINGFILEINFO);
- }
+ QVariantMap result = resultData.toMap();
+
+ DownloadInfo *info = downloadInfoByID(userData.toInt());
+ if (info == nullptr) return;
+ info->m_FileInfo->categoryID = result["category_id"].toInt();
+ QTextDocument doc;
+ doc.setHtml(result["name"].toString().trimmed());
+ info->m_FileInfo->modName = doc.toPlainText();
+ info->m_FileInfo->newestVersion.parse(result["version"].toString());
+ if (info->m_FileInfo->fileID != 0) {
+ setState(info, STATE_READY);
+ } else {
+ setState(info, STATE_FETCHINGFILEINFO);
+ }
}
-QDateTime DownloadManager::matchDate(const QString& timeString) {
- if (m_DateExpression.exactMatch(timeString)) {
- return QDateTime::fromMSecsSinceEpoch(m_DateExpression.cap(1).toLongLong());
- } else {
- qWarning("date not matched: %s", qPrintable(timeString));
- return QDateTime::currentDateTime();
- }
+
+QDateTime DownloadManager::matchDate(const QString &timeString)
+{
+ if (m_DateExpression.exactMatch(timeString)) {
+ return QDateTime::fromMSecsSinceEpoch(m_DateExpression.cap(1).toLongLong());
+ } else {
+ qWarning("date not matched: %s", qPrintable(timeString));
+ return QDateTime::currentDateTime();
+ }
}
-static EFileCategory convertFileCategory(int id) {
- // TODO: need to handle file categories in the mod page plugin
- switch (id) {
- case 0:
- return TYPE_MAIN;
- case 1:
- return TYPE_UPDATE;
- case 2:
- return TYPE_OPTION;
- default:
- return TYPE_MAIN;
- }
+
+static EFileCategory convertFileCategory(int id)
+{
+ // TODO: need to handle file categories in the mod page plugin
+ switch (id) {
+ case 0: return TYPE_MAIN;
+ case 1: return TYPE_UPDATE;
+ case 2: return TYPE_OPTION;
+ default: return TYPE_MAIN;
+ }
}
-void DownloadManager::nxmFilesAvailable(int, QVariant userData, QVariant resultData, int requestID) {
- std::set<int>::iterator idIter = m_RequestIDs.find(requestID);
- if (idIter == m_RequestIDs.end()) {
- return;
- } else {
- m_RequestIDs.erase(idIter);
- }
- DownloadInfo* info = downloadInfoByID(userData.toInt());
- if (info == nullptr)
- return;
+void DownloadManager::nxmFilesAvailable(int, QVariant userData, QVariant resultData, int requestID)
+{
+ std::set<int>::iterator idIter = m_RequestIDs.find(requestID);
+ if (idIter == m_RequestIDs.end()) {
+ return;
+ } else {
+ m_RequestIDs.erase(idIter);
+ }
- QVariantList result = resultData.toList();
+ DownloadInfo *info = downloadInfoByID(userData.toInt());
+ if (info == nullptr) return;
- // MO sometimes prepends <digit>_ to the filename in case of duplicate downloads.
- // this may muck up the file name comparison
- QString alternativeLocalName = info->m_FileName;
+ QVariantList result = resultData.toList();
- QRegExp expression("^\\d_(.*)$");
- if (expression.indexIn(alternativeLocalName) == 0) {
- alternativeLocalName = expression.cap(1);
- }
+ // MO sometimes prepends <digit>_ to the filename in case of duplicate downloads.
+ // this may muck up the file name comparison
+ QString alternativeLocalName = info->m_FileName;
- bool found = false;
+ QRegExp expression("^\\d_(.*)$");
+ if (expression.indexIn(alternativeLocalName) == 0) {
+ alternativeLocalName = expression.cap(1);
+ }
- for (QVariant file : result) {
- QVariantMap fileInfo = file.toMap();
- QString fileName = fileInfo["uri"].toString();
- QString fileNameVariant = fileName.mid(0).replace(' ', '_');
- if ((fileName == info->m_FileName) || (fileName == alternativeLocalName) ||
- (fileNameVariant == info->m_FileName) || (fileNameVariant == alternativeLocalName)) {
- info->m_FileInfo->name = fileInfo["name"].toString();
- info->m_FileInfo->version.parse(fileInfo["version"].toString());
- if (!info->m_FileInfo->version.isValid()) {
- info->m_FileInfo->version = info->m_FileInfo->newestVersion;
- }
- // we receive some names html-encoded. This is used to decode it
- QTextDocument doc;
- doc.setHtml(fileInfo["modName"].toString());
- info->m_FileInfo->modName = doc.toPlainText();
- info->m_FileInfo->fileCategory = convertFileCategory(fileInfo["category_id"].toInt());
- info->m_FileInfo->fileTime = matchDate(fileInfo["date"].toString());
- info->m_FileInfo->fileID = fileInfo["id"].toInt();
- found = true;
- break;
- }
+ bool found = false;
+
+ for (QVariant file : result) {
+ QVariantMap fileInfo = file.toMap();
+ QString fileName = fileInfo["uri"].toString();
+ QString fileNameVariant = fileName.mid(0).replace(' ', '_');
+ if ((fileName == info->m_FileName) || (fileName == alternativeLocalName) ||
+ (fileNameVariant == info->m_FileName) || (fileNameVariant == alternativeLocalName)) {
+ info->m_FileInfo->name = fileInfo["name"].toString();
+ info->m_FileInfo->version.parse(fileInfo["version"].toString());
+ if (!info->m_FileInfo->version.isValid()) {
+ info->m_FileInfo->version = info->m_FileInfo->newestVersion;
+ }
+ // we receive some names html-encoded. This is used to decode it
+ QTextDocument doc;
+ doc.setHtml(fileInfo["modName"].toString());
+ info->m_FileInfo->modName = doc.toPlainText();
+ info->m_FileInfo->fileCategory = convertFileCategory(fileInfo["category_id"].toInt());
+ info->m_FileInfo->fileTime = matchDate(fileInfo["date"].toString());
+ info->m_FileInfo->fileID = fileInfo["id"].toInt();
+ found = true;
+ break;
}
+ }
- if (info->m_ReQueried) {
- if (found) {
- emit showMessage(tr("Information updated"));
- } else if (result.count() == 0) {
- emit showMessage(
- tr("No matching file found on Nexus! Maybe this file is no longer available or it was renamed?"));
- } else {
- SelectionDialog selection(
- tr("No file on Nexus matches the selected file by name. Please manually choose the correct one."));
- for (QVariant file : result) {
- QVariantMap fileInfo = file.toMap();
- selection.addChoice(fileInfo["uri"].toString(), "", file);
- }
- if (selection.exec() == QDialog::Accepted) {
- QVariantMap fileInfo = selection.getChoiceData().toMap();
- info->m_FileInfo->name = fileInfo["name"].toString();
- info->m_FileInfo->version.parse(fileInfo["version"].toString());
- info->m_FileInfo->fileCategory = convertFileCategory(fileInfo["category_id"].toInt());
- info->m_FileInfo->fileID = fileInfo["id"].toInt();
- } else {
- emit showMessage(
- tr("No matching file found on Nexus! Maybe this file is no longer available or it was renamed?"));
- }
- }
+ if (info->m_ReQueried) {
+ if (found) {
+ emit showMessage(tr("Information updated"));
+ } else if (result.count() == 0) {
+ emit showMessage(tr("No matching file found on Nexus! Maybe this file is no longer available or it was renamed?"));
} else {
- if (info->m_FileInfo->fileID == 0) {
- qWarning("could not determine file id for %s (state %d)", info->m_FileName.toUtf8().constData(),
- info->m_State);
- }
+ SelectionDialog selection(tr("No file on Nexus matches the selected file by name. Please manually choose the correct one."));
+ for (QVariant file : result) {
+ QVariantMap fileInfo = file.toMap();
+ selection.addChoice(fileInfo["uri"].toString(), "", file);
+ }
+ if (selection.exec() == QDialog::Accepted) {
+ QVariantMap fileInfo = selection.getChoiceData().toMap();
+ info->m_FileInfo->name = fileInfo["name"].toString();
+ info->m_FileInfo->version.parse(fileInfo["version"].toString());
+ info->m_FileInfo->fileCategory = convertFileCategory(fileInfo["category_id"].toInt());
+ info->m_FileInfo->fileID = fileInfo["id"].toInt();
+ } else {
+ emit showMessage(tr("No matching file found on Nexus! Maybe this file is no longer available or it was renamed?"));
+ }
+ }
+ } else {
+ if (info->m_FileInfo->fileID == 0) {
+ qWarning("could not determine file id for %s (state %d)",
+ info->m_FileName.toUtf8().constData(), info->m_State);
}
+ }
- setState(info, STATE_READY);
+ setState(info, STATE_READY);
}
-void DownloadManager::nxmFileInfoAvailable(int modID, int fileID, QVariant userData, QVariant resultData,
- int requestID) {
- std::set<int>::iterator idIter = m_RequestIDs.find(requestID);
- if (idIter == m_RequestIDs.end()) {
- return;
- } else {
- m_RequestIDs.erase(idIter);
- }
- ModRepositoryFileInfo* info = new ModRepositoryFileInfo();
+void DownloadManager::nxmFileInfoAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID)
+{
+ std::set<int>::iterator idIter = m_RequestIDs.find(requestID);
+ if (idIter == m_RequestIDs.end()) {
+ return;
+ } else {
+ m_RequestIDs.erase(idIter);
+ }
- QVariantMap result = resultData.toMap();
- info->name = result["name"].toString();
- info->version.parse(result["version"].toString());
- if (!info->version.isValid()) {
- info->version = info->newestVersion;
- }
- info->fileName = result["uri"].toString();
- info->fileCategory = result["category_id"].toInt();
- info->fileTime = matchDate(result["date"].toString());
- info->description = BBCode::convertToHTML(result["description"].toString());
+ ModRepositoryFileInfo *info = new ModRepositoryFileInfo();
+
+ QVariantMap result = resultData.toMap();
+ info->name = result["name"].toString();
+ info->version.parse(result["version"].toString());
+ if (!info->version.isValid()) {
+ info->version = info->newestVersion;
+ }
+ info->fileName = result["uri"].toString();
+ info->fileCategory = result["category_id"].toInt();
+ info->fileTime = matchDate(result["date"].toString());
+ info->description = BBCode::convertToHTML(result["description"].toString());
- info->repository = "Nexus";
- info->modID = modID;
- info->fileID = fileID;
+ info->repository = "Nexus";
+ info->modID = modID;
+ info->fileID = fileID;
- QObject* test = info;
- m_RequestIDs.insert(m_NexusInterface->requestDownloadURL(modID, fileID, this, qVariantFromValue(test), QString()));
+ QObject *test = info;
+ m_RequestIDs.insert(m_NexusInterface->requestDownloadURL(modID, fileID, this, qVariantFromValue(test), QString()));
}
-static int evaluateFileInfoMap(const QVariantMap& map, const std::map<QString, int>& preferredServers) {
- int result = 0;
+static int evaluateFileInfoMap(const QVariantMap &map, const std::map<QString, int> &preferredServers)
+{
+ int result = 0;
- int users = map["ConnectedUsers"].toInt();
- // 0 users is probably a sign that the server is offline. Since there is currently no
- // mechanism to try a different server, we avoid those without users
- if (users == 0) {
- result -= 500;
- } else {
- result -= users;
- }
+ int users = map["ConnectedUsers"].toInt();
+ // 0 users is probably a sign that the server is offline. Since there is currently no
+ // mechanism to try a different server, we avoid those without users
+ if (users == 0) {
+ result -= 500;
+ } else {
+ result -= users;
+ }
- auto preference = preferredServers.find(map["Name"].toString());
+ auto preference = preferredServers.find(map["Name"].toString());
- if (preference != preferredServers.end()) {
- result += 100 + preference->second * 20;
- }
+ if (preference != preferredServers.end()) {
+ result += 100 + preference->second * 20;
+ }
- if (map["IsPremium"].toBool())
- result += 5;
+ if (map["IsPremium"].toBool()) result += 5;
- return result;
+ return result;
}
// sort function to sort by best download server
-bool DownloadManager::ServerByPreference(const std::map<QString, int>& preferredServers, const QVariant& LHS,
- const QVariant& RHS) {
- return evaluateFileInfoMap(LHS.toMap(), preferredServers) > evaluateFileInfoMap(RHS.toMap(), preferredServers);
+bool DownloadManager::ServerByPreference(const std::map<QString, int> &preferredServers, const QVariant &LHS, const QVariant &RHS)
+{
+ return evaluateFileInfoMap(LHS.toMap(), preferredServers) > evaluateFileInfoMap(RHS.toMap(), preferredServers);
}
-int DownloadManager::startDownloadURLs(const QStringList& urls) {
- ModRepositoryFileInfo info;
- addDownload(urls, -1, -1, &info);
- return m_ActiveDownloads.size() - 1;
+int DownloadManager::startDownloadURLs(const QStringList &urls)
+{
+ ModRepositoryFileInfo info;
+ addDownload(urls, -1, -1, &info);
+ return m_ActiveDownloads.size() - 1;
}
-int DownloadManager::startDownloadNexusFile(int modID, int fileID) {
- int newID = m_ActiveDownloads.size();
- addNXMDownload(QString("nxm://%1/mods/%2/files/%3").arg(m_ManagedGame->gameShortName()).arg(modID).arg(fileID));
- return newID;
+int DownloadManager::startDownloadNexusFile(int modID, int fileID)
+{
+ int newID = m_ActiveDownloads.size();
+ addNXMDownload(QString("nxm://%1/mods/%2/files/%3").arg(m_ManagedGame->gameShortName()).arg(modID).arg(fileID));
+ return newID;
}
-QString DownloadManager::downloadPath(int id) { return getFilePath(id); }
+QString DownloadManager::downloadPath(int id)
+{
+ return getFilePath(id);
+}
-int DownloadManager::indexByName(const QString& fileName) const {
- for (int i = 0; i < m_ActiveDownloads.size(); ++i) {
- if (m_ActiveDownloads[i]->m_FileName == fileName) {
- return i;
- }
+int DownloadManager::indexByName(const QString &fileName) const
+{
+ for (int i = 0; i < m_ActiveDownloads.size(); ++i) {
+ if (m_ActiveDownloads[i]->m_FileName == fileName) {
+ return i;
}
- return -1;
+ }
+ return -1;
}
-void DownloadManager::nxmDownloadURLsAvailable(int modID, int fileID, QVariant userData, QVariant resultData,
- int requestID) {
- std::set<int>::iterator idIter = m_RequestIDs.find(requestID);
- if (idIter == m_RequestIDs.end()) {
- return;
- } else {
- m_RequestIDs.erase(idIter);
- }
+void DownloadManager::nxmDownloadURLsAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID)
+{
+ std::set<int>::iterator idIter = m_RequestIDs.find(requestID);
+ if (idIter == m_RequestIDs.end()) {
+ return;
+ } else {
+ m_RequestIDs.erase(idIter);
+ }
- ModRepositoryFileInfo* info = qobject_cast<ModRepositoryFileInfo*>(qvariant_cast<QObject*>(userData));
- QVariantList resultList = resultData.toList();
- if (resultList.length() == 0) {
- removePending(modID, fileID);
- emit showMessage(tr("No download server available. Please try again later."));
- return;
- }
+ ModRepositoryFileInfo *info = qobject_cast<ModRepositoryFileInfo*>(qvariant_cast<QObject*>(userData));
+ QVariantList resultList = resultData.toList();
+ if (resultList.length() == 0) {
+ removePending(modID, fileID);
+ emit showMessage(tr("No download server available. Please try again later."));
+ return;
+ }
- std::sort(resultList.begin(), resultList.end(),
- boost::bind(&DownloadManager::ServerByPreference, m_PreferredServers, _1, _2));
+ std::sort(resultList.begin(), resultList.end(), boost::bind(&DownloadManager::ServerByPreference, m_PreferredServers, _1, _2));
- info->userData["downloadMap"] = resultList;
+ info->userData["downloadMap"] = resultList;
- QStringList URLs;
+ QStringList URLs;
- foreach (const QVariant& server, resultList) { URLs.append(server.toMap()["URI"].toString()); }
- addDownload(URLs, modID, fileID, info);
+ foreach (const QVariant &server, resultList) {
+ URLs.append(server.toMap()["URI"].toString());
+ }
+ addDownload(URLs, modID, fileID, info);
}
-void DownloadManager::nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID,
- const QString& errorString) {
- std::set<int>::iterator idIter = m_RequestIDs.find(requestID);
- if (idIter == m_RequestIDs.end()) {
- return;
- } else {
- m_RequestIDs.erase(idIter);
- }
- int index = 0;
+void DownloadManager::nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorString)
+{
+ std::set<int>::iterator idIter = m_RequestIDs.find(requestID);
+ if (idIter == m_RequestIDs.end()) {
+ return;
+ } else {
+ m_RequestIDs.erase(idIter);
+ }
- for (QVector<DownloadInfo*>::iterator iter = m_ActiveDownloads.begin(); iter != m_ActiveDownloads.end();
- ++iter, ++index) {
- DownloadInfo* info = *iter;
- if (info->m_FileInfo->modID == modID) {
- if (info->m_State < STATE_FETCHINGMODINFO) {
- m_ActiveDownloads.erase(iter);
- delete info;
- } else {
- setState(info, STATE_READY);
- }
- emit update(index);
- break;
- }
+ int index = 0;
+
+ for (QVector<DownloadInfo*>::iterator iter = m_ActiveDownloads.begin(); iter != m_ActiveDownloads.end(); ++iter, ++index) {
+ DownloadInfo *info = *iter;
+ if (info->m_FileInfo->modID == modID) {
+ if (info->m_State < STATE_FETCHINGMODINFO) {
+ m_ActiveDownloads.erase(iter);
+ delete info;
+ } else {
+ setState(info, STATE_READY);
+ }
+ emit update(index);
+ break;
}
+ }
- removePending(modID, fileID);
- emit showMessage(tr("Failed to request file info from nexus: %1").arg(errorString));
+ removePending(modID, fileID);
+ emit showMessage(tr("Failed to request file info from nexus: %1").arg(errorString));
}
-void DownloadManager::downloadFinished() {
- int index = 0;
- DownloadInfo* info = findDownload(this->sender(), &index);
- if (info != nullptr) {
- QNetworkReply* reply = info->m_Reply;
- QByteArray data;
- if (reply->isOpen()) {
- data = reply->readAll();
- info->m_Output.write(data);
- }
- info->m_Output.close();
- TaskProgressManager::instance().forgetMe(info->m_TaskProgressId);
+void DownloadManager::downloadFinished()
+{
+ int index = 0;
- bool error = false;
- if ((info->m_State != STATE_CANCELING) && (info->m_State != STATE_PAUSING)) {
- bool textData =
- reply->header(QNetworkRequest::ContentTypeHeader).toString().startsWith("text", Qt::CaseInsensitive);
- if ((info->m_Output.size() == 0) ||
- ((reply->error() != QNetworkReply::NoError) &&
- (reply->error() != QNetworkReply::OperationCanceledError)) ||
- textData) {
- if (info->m_Tries == 0) {
- if (textData && (reply->error() == QNetworkReply::NoError)) {
- emit showMessage(tr("Download failed. Server reported: %1").arg(QString(data)));
- } else {
- emit showMessage(tr("Download failed: %1 (%2)").arg(reply->errorString()).arg(reply->error()));
- }
- }
- error = true;
- setState(info, STATE_PAUSING);
- }
+ DownloadInfo *info = findDownload(this->sender(), &index);
+ if (info != nullptr) {
+ QNetworkReply *reply = info->m_Reply;
+ QByteArray data;
+ if (reply->isOpen()) {
+ data = reply->readAll();
+ info->m_Output.write(data);
+ }
+ info->m_Output.close();
+ TaskProgressManager::instance().forgetMe(info->m_TaskProgressId);
+
+ bool error = false;
+ if ((info->m_State != STATE_CANCELING) &&
+ (info->m_State != STATE_PAUSING)) {
+ bool textData = reply->header(QNetworkRequest::ContentTypeHeader).toString().startsWith("text", Qt::CaseInsensitive);
+ if ((info->m_Output.size() == 0) ||
+ ((reply->error() != QNetworkReply::NoError) && (reply->error() != QNetworkReply::OperationCanceledError)) ||
+ textData) {
+ if (info->m_Tries == 0) {
+ if (textData && (reply->error() == QNetworkReply::NoError)) {
+ emit showMessage(tr("Download failed. Server reported: %1").arg(QString(data)));
+ } else {
+ emit showMessage(tr("Download failed: %1 (%2)").arg(reply->errorString()).arg(reply->error()));
+ }
}
+ error = true;
+ setState(info, STATE_PAUSING);
+ }
+ }
- if (info->m_State == STATE_CANCELING) {
- setState(info, STATE_CANCELED);
- } else if (info->m_State == STATE_PAUSING) {
- if (info->m_Output.isOpen()) {
- info->m_Output.write(info->m_Reply->readAll());
- }
+ if (info->m_State == STATE_CANCELING) {
+ setState(info, STATE_CANCELED);
+ } else if (info->m_State == STATE_PAUSING) {
+ if (info->m_Output.isOpen()) {
+ info->m_Output.write(info->m_Reply->readAll());
+ }
- if (error) {
- setState(info, STATE_ERROR);
- } else {
- setState(info, STATE_PAUSED);
- }
- }
+ if (error) {
+ setState(info, STATE_ERROR);
+ } else {
+ setState(info, STATE_PAUSED);
+ }
+ }
- if (info->m_State == STATE_CANCELED) {
- emit aboutToUpdate();
- info->m_Output.remove();
- delete info;
- m_ActiveDownloads.erase(m_ActiveDownloads.begin() + index);
- emit update(-1);
- } else if (info->isPausedState()) {
- info->m_Output.close();
- createMetaFile(info);
- emit update(index);
- } else {
- QString url = info->m_Urls[info->m_CurrentUrl];
- if (info->m_FileInfo->userData.contains("downloadMap")) {
- foreach (const QVariant& server, info->m_FileInfo->userData["downloadMap"].toList()) {
- QVariantMap serverMap = server.toMap();
- if (serverMap["URI"].toString() == url) {
- int deltaTime = info->m_StartTime.secsTo(QTime::currentTime());
- if (deltaTime > 5) {
- emit downloadSpeed(serverMap["Name"].toString(),
- (info->m_TotalSize - info->m_PreResumeSize) / deltaTime);
- } // no division by zero please! Also, if the download is shorter than a few seconds, the result
- // is way to inprecise
- break;
- }
- }
- }
+ if (info->m_State == STATE_CANCELED) {
+ emit aboutToUpdate();
+ info->m_Output.remove();
+ delete info;
+ m_ActiveDownloads.erase(m_ActiveDownloads.begin() + index);
+ emit update(-1);
+ } else if (info->isPausedState()) {
+ info->m_Output.close();
+ createMetaFile(info);
+ emit update(index);
+ } else {
+ QString url = info->m_Urls[info->m_CurrentUrl];
+ if (info->m_FileInfo->userData.contains("downloadMap")) {
+ foreach (const QVariant &server, info->m_FileInfo->userData["downloadMap"].toList()) {
+ QVariantMap serverMap = server.toMap();
+ if (serverMap["URI"].toString() == url) {
+ int deltaTime = info->m_StartTime.secsTo(QTime::currentTime());
+ if (deltaTime > 5) {
+ emit downloadSpeed(serverMap["Name"].toString(), (info->m_TotalSize - info->m_PreResumeSize) / deltaTime);
+ } // no division by zero please! Also, if the download is shorter than a few seconds, the result is way to inprecise
+ break;
+ }
+ }
+ }
- bool isNexus = info->m_FileInfo->repository == "Nexus";
- // need to change state before changing the file name, otherwise .unfinished is appended
- if (isNexus) {
- setState(info, STATE_FETCHINGMODINFO);
- } else {
- setState(info, STATE_NOFETCH);
- }
+ bool isNexus = info->m_FileInfo->repository == "Nexus";
+ // need to change state before changing the file name, otherwise .unfinished is appended
+ if (isNexus) {
+ setState(info, STATE_FETCHINGMODINFO);
+ } else {
+ setState(info, STATE_NOFETCH);
+ }
- QString newName = getFileNameFromNetworkReply(reply);
- QString oldName = QFileInfo(info->m_Output).fileName();
- if (!newName.isEmpty() && (newName != oldName)) {
- info->setName(getDownloadFileName(newName), true);
- } else {
- info->setName(m_OutputDirectory + "/" + info->m_FileName,
- true); // don't rename but remove the ".unfinished" extension
- }
+ QString newName = getFileNameFromNetworkReply(reply);
+ QString oldName = QFileInfo(info->m_Output).fileName();
+ if (!newName.isEmpty() && (newName != oldName)) {
+ info->setName(getDownloadFileName(newName), true);
+ } else {
+ info->setName(m_OutputDirectory + "/" + info->m_FileName, true); // don't rename but remove the ".unfinished" extension
+ }
- if (!isNexus) {
- setState(info, STATE_READY);
- }
+ if (!isNexus) {
+ setState(info, STATE_READY);
+ }
- emit update(index);
- }
- reply->close();
- reply->deleteLater();
+ emit update(index);
+ }
+ reply->close();
+ reply->deleteLater();
- if ((info->m_Tries > 0) && error) {
- --info->m_Tries;
- resumeDownloadInt(index);
- }
- } else {
- qWarning("no download index %d", index);
+ if ((info->m_Tries > 0) && error) {
+ --info->m_Tries;
+ resumeDownloadInt(index);
}
+ } else {
+ qWarning("no download index %d", index);
+ }
}
-void DownloadManager::downloadError(QNetworkReply::NetworkError error) {
- if (error != QNetworkReply::OperationCanceledError) {
- QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
- qWarning("%s (%d)", reply != nullptr ? qPrintable(reply->errorString()) : "Download error occured", error);
- }
+
+void DownloadManager::downloadError(QNetworkReply::NetworkError error)
+{
+ if (error != QNetworkReply::OperationCanceledError) {
+ QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
+ qWarning("%s (%d)", reply != nullptr ? qPrintable(reply->errorString())
+ : "Download error occured",
+ error);
+ }
}
-void DownloadManager::metaDataChanged() {
- int index = 0;
- DownloadInfo* info = findDownload(this->sender(), &index);
- if (info != nullptr) {
- QString newName = getFileNameFromNetworkReply(info->m_Reply);
- if (!newName.isEmpty() && (newName != info->m_FileName)) {
- info->setName(getDownloadFileName(newName), true);
- refreshAlphabeticalTranslation();
- if (!info->m_Output.isOpen() && !info->m_Output.open(QIODevice::WriteOnly | QIODevice::Append)) {
- reportError(tr("failed to re-open %1").arg(info->m_FileName));
- setState(info, STATE_CANCELING);
- }
- }
- } else {
- qWarning("meta data event for unknown download");
+void DownloadManager::metaDataChanged()
+{
+ int index = 0;
+
+ DownloadInfo *info = findDownload(this->sender(), &index);
+ if (info != nullptr) {
+ QString newName = getFileNameFromNetworkReply(info->m_Reply);
+ if (!newName.isEmpty() && (newName != info->m_FileName)) {
+ info->setName(getDownloadFileName(newName), true);
+ refreshAlphabeticalTranslation();
+ if (!info->m_Output.isOpen() && !info->m_Output.open(QIODevice::WriteOnly | QIODevice::Append)) {
+ reportError(tr("failed to re-open %1").arg(info->m_FileName));
+ setState(info, STATE_CANCELING);
+ }
}
+ } else {
+ qWarning("meta data event for unknown download");
+ }
}
-void DownloadManager::directoryChanged(const QString&) { refreshList(); }
+void DownloadManager::directoryChanged(const QString&)
+{
+ refreshList();
+}
-void DownloadManager::managedGameChanged(MOBase::IPluginGame const* managedGame) { m_ManagedGame = managedGame; }
+void DownloadManager::managedGameChanged(MOBase::IPluginGame const *managedGame)
+{
+ m_ManagedGame = managedGame;
+}
diff --git a/src/downloadmanager.h b/src/downloadmanager.h
index 39dc56f4..e63a0113 100644
--- a/src/downloadmanager.h
+++ b/src/downloadmanager.h
@@ -20,496 +20,495 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef DOWNLOADMANAGER_H
#define DOWNLOADMANAGER_H
-#include <QFile>
-#include <QFileSystemWatcher>
-#include <QMap>
-#include <QNetworkReply>
+#include <idownloadmanager.h>
+#include <modrepositoryfileinfo.h>
+#include <set>
#include <QObject>
+#include <QUrl>
#include <QQueue>
-#include <QSettings>
-#include <QStringList>
+#include <QFile>
+#include <QNetworkReply>
#include <QTime>
-#include <QUrl>
#include <QVector>
-#include <idownloadmanager.h>
-#include <modrepositoryfileinfo.h>
-#include <set>
+#include <QMap>
+#include <QStringList>
+#include <QFileSystemWatcher>
+#include <QSettings>
-namespace MOBase {
-class IPluginGame;
-}
+namespace MOBase { class IPluginGame; }
class NexusInterface;
/*!
* \brief manages downloading of files and provides progress information for gui elements
**/
-class DownloadManager : public MOBase::IDownloadManager {
- Q_OBJECT
+class DownloadManager : public MOBase::IDownloadManager
+{
+ Q_OBJECT
public:
- enum DownloadState {
- STATE_STARTED = 0,
- STATE_DOWNLOADING,
- STATE_CANCELING,
- STATE_PAUSING,
- STATE_CANCELED,
- STATE_PAUSED,
- STATE_ERROR,
- STATE_FETCHINGMODINFO,
- STATE_FETCHINGFILEINFO,
- STATE_NOFETCH,
- STATE_READY,
- STATE_INSTALLED,
- STATE_UNINSTALLED
- };
-private:
- struct DownloadInfo {
- ~DownloadInfo() { delete m_FileInfo; }
- unsigned int m_DownloadID;
- QString m_FileName;
- QFile m_Output;
- QNetworkReply* m_Reply;
- QTime m_StartTime;
- qint64 m_PreResumeSize;
- int m_Progress;
- DownloadState m_State;
- int m_CurrentUrl;
- QStringList m_Urls;
- qint64 m_ResumePos;
- qint64 m_TotalSize;
- QDateTime m_Created; // used as a cache in DownloadManager::getFileTime, may not be valid elsewhere
+ enum DownloadState {
+ STATE_STARTED = 0,
+ STATE_DOWNLOADING,
+ STATE_CANCELING,
+ STATE_PAUSING,
+ STATE_CANCELED,
+ STATE_PAUSED,
+ STATE_ERROR,
+ STATE_FETCHINGMODINFO,
+ STATE_FETCHINGFILEINFO,
+ STATE_NOFETCH,
+ STATE_READY,
+ STATE_INSTALLED,
+ STATE_UNINSTALLED
+ };
- int m_Tries;
- bool m_ReQueried;
+private:
- quint32 m_TaskProgressId;
+ struct DownloadInfo {
+ ~DownloadInfo() { delete m_FileInfo; }
+ unsigned int m_DownloadID;
+ QString m_FileName;
+ QFile m_Output;
+ QNetworkReply *m_Reply;
+ QTime m_StartTime;
+ qint64 m_PreResumeSize;
+ int m_Progress;
+ DownloadState m_State;
+ int m_CurrentUrl;
+ QStringList m_Urls;
+ qint64 m_ResumePos;
+ qint64 m_TotalSize;
+ QDateTime m_Created; // used as a cache in DownloadManager::getFileTime, may not be valid elsewhere
- MOBase::ModRepositoryFileInfo* m_FileInfo{nullptr};
+ int m_Tries;
+ bool m_ReQueried;
- bool m_Hidden;
+ quint32 m_TaskProgressId;
- static DownloadInfo* createNew(const MOBase::ModRepositoryFileInfo* fileInfo, const QStringList& URLs);
- static DownloadInfo* createFromMeta(const QString& filePath, bool showHidden);
+ MOBase::ModRepositoryFileInfo *m_FileInfo { nullptr };
- /**
- * @brief rename the file
- * this will change the file name as well as the display name. It will automatically
- * append .unfinished to the name if this file is still being downloaded
- * @param newName the new name to setName
- * @param renameFile if true, the file is assumed to exist and renamed. If the file does not
- * yet exist, set this to false
- **/
- void setName(QString newName, bool renameFile);
+ bool m_Hidden;
- unsigned int downloadID() { return m_DownloadID; }
+ static DownloadInfo *createNew(const MOBase::ModRepositoryFileInfo *fileInfo, const QStringList &URLs);
+ static DownloadInfo *createFromMeta(const QString &filePath, bool showHidden);
- bool isPausedState();
+ /**
+ * @brief rename the file
+ * this will change the file name as well as the display name. It will automatically
+ * append .unfinished to the name if this file is still being downloaded
+ * @param newName the new name to setName
+ * @param renameFile if true, the file is assumed to exist and renamed. If the file does not
+ * yet exist, set this to false
+ **/
+ void setName(QString newName, bool renameFile);
- QString currentURL();
+ unsigned int downloadID() { return m_DownloadID; }
- private:
- static unsigned int s_NextDownloadID;
+ bool isPausedState();
- private:
- DownloadInfo() : m_TotalSize(0), m_ReQueried(false), m_Hidden(false) {}
- };
+ QString currentURL();
+ private:
+ static unsigned int s_NextDownloadID;
+ private:
+ DownloadInfo() : m_TotalSize(0), m_ReQueried(false), m_Hidden(false) {}
+ };
public:
- /**
- * @brief constructor
- *
- * @param nexusInterface interface to use to retrieve information from the relevant nexus page
- * @param parent parent object
- **/
- explicit DownloadManager(NexusInterface* nexusInterface, QObject* parent);
- ~DownloadManager();
+ /**
+ * @brief constructor
+ *
+ * @param nexusInterface interface to use to retrieve information from the relevant nexus page
+ * @param parent parent object
+ **/
+ explicit DownloadManager(NexusInterface *nexusInterface, QObject *parent);
- /**
- * @brief determine if a download is currently in progress
- *
- * @return true if there is currently a download in progress
- **/
- bool downloadsInProgress();
+ ~DownloadManager();
- /**
- * @brief set the output directory to write to
- *
- * @param outputDirectory the new output directory
- **/
- void setOutputDirectory(const QString& outputDirectory);
+ /**
+ * @brief determine if a download is currently in progress
+ *
+ * @return true if there is currently a download in progress
+ **/
+ bool downloadsInProgress();
- /**
- * @return current download directory
- **/
- QString getOutputDirectory() const { return m_OutputDirectory; }
+ /**
+ * @brief set the output directory to write to
+ *
+ * @param outputDirectory the new output directory
+ **/
+ void setOutputDirectory(const QString &outputDirectory);
- /**
- * @brief setPreferredServers set the list of preferred servers
- */
- void setPreferredServers(const std::map<QString, int>& preferredServers);
+ /**
+ * @return current download directory
+ **/
+ QString getOutputDirectory() const { return m_OutputDirectory; }
- /**
- * @brief set the list of supported extensions
- * @param extensions list of supported extensions
- */
- void setSupportedExtensions(const QStringList& extensions);
+ /**
+ * @brief setPreferredServers set the list of preferred servers
+ */
+ void setPreferredServers(const std::map<QString, int> &preferredServers);
- /**
- * @brief sets whether hidden files are to be shown after all
- */
- void setShowHidden(bool showHidden);
+ /**
+ * @brief set the list of supported extensions
+ * @param extensions list of supported extensions
+ */
+ void setSupportedExtensions(const QStringList &extensions);
- /**
- * @brief download from an already open network connection
- *
- * @param reply the network reply to download from
- * @param fileInfo information about the file, like mod id, file id, version, ...
- * @return true if the download was started, false if it wasn't. The latter currently only happens if there is a
- *duplicate and the user decides not to download again
- **/
- bool addDownload(QNetworkReply* reply, const MOBase::ModRepositoryFileInfo* fileInfo);
+ /**
+ * @brief sets whether hidden files are to be shown after all
+ */
+ void setShowHidden(bool showHidden);
- /**
- * @brief download from an already open network connection
- *
- * @param reply the network reply to download from
- * @param fileName the name to use for the file. This may be overridden by the name in the fileInfo-structure or if
- *the http stream specifies a name
- * @param fileInfo information previously retrieved from the nexus network
- * @return true if the download was started, false if it wasn't. The latter currently only happens if there is a
- *duplicate and the user decides not to download again
- **/
- bool addDownload(QNetworkReply* reply, const QStringList& URLs, const QString& fileName, int modID, int fileID = 0,
- const MOBase::ModRepositoryFileInfo* fileInfo = new MOBase::ModRepositoryFileInfo());
+ /**
+ * @brief download from an already open network connection
+ *
+ * @param reply the network reply to download from
+ * @param fileInfo information about the file, like mod id, file id, version, ...
+ * @return true if the download was started, false if it wasn't. The latter currently only happens if there is a duplicate and the user decides not to download again
+ **/
+ bool addDownload(QNetworkReply *reply, const MOBase::ModRepositoryFileInfo *fileInfo);
- /**
- * @brief start a download using a nxm-link
- *
- * starts a download using a nxm-link. The download manager will first query the nexus
- * page for file information.
- * @param url a nxm link looking like this: nxm://skyrim/mods/1234/files/4711
- * @todo the game name encoded into the link is currently ignored, all downloads are incorrectly assumed to be for
- *the identified game
- **/
- void addNXMDownload(const QString& url);
+ /**
+ * @brief download from an already open network connection
+ *
+ * @param reply the network reply to download from
+ * @param fileName the name to use for the file. This may be overridden by the name in the fileInfo-structure or if the http stream specifies a name
+ * @param fileInfo information previously retrieved from the nexus network
+ * @return true if the download was started, false if it wasn't. The latter currently only happens if there is a duplicate and the user decides not to download again
+ **/
+ bool addDownload(QNetworkReply *reply, const QStringList &URLs, const QString &fileName, int modID, int fileID = 0, const MOBase::ModRepositoryFileInfo *fileInfo = new MOBase::ModRepositoryFileInfo());
- /**
- * @brief retrieve the total number of downloads, both finished and unfinished including downloads from previous
- *sessions
- *
- * @return total number of downloads
- **/
- int numTotalDownloads() const;
+ /**
+ * @brief start a download using a nxm-link
+ *
+ * starts a download using a nxm-link. The download manager will first query the nexus
+ * page for file information.
+ * @param url a nxm link looking like this: nxm://skyrim/mods/1234/files/4711
+ * @todo the game name encoded into the link is currently ignored, all downloads are incorrectly assumed to be for the identified game
+ **/
+ void addNXMDownload(const QString &url);
- /**
- * @brief retrieve number of pending downloads (nexus downloads for which we don't know the name and url yet)
- * @return number of pending downloads
- */
- int numPendingDownloads() const;
+ /**
+ * @brief retrieve the total number of downloads, both finished and unfinished including downloads from previous sessions
+ *
+ * @return total number of downloads
+ **/
+ int numTotalDownloads() const;
- /**
- * @brief retrieve the info of a pending download
- * @param index index of the pending download (index in the range [0, numPendingDownloads()[)
- * @return pair of modid, fileid
- */
- std::pair<int, int> getPendingDownload(int index);
+ /**
+ * @brief retrieve number of pending downloads (nexus downloads for which we don't know the name and url yet)
+ * @return number of pending downloads
+ */
+ int numPendingDownloads() const;
- /**
- * @brief retrieve the full path to the download specified by index
- *
- * @param index the index to look up
- * @return absolute path of the file
- **/
- QString getFilePath(int index) const;
+ /**
+ * @brief retrieve the info of a pending download
+ * @param index index of the pending download (index in the range [0, numPendingDownloads()[)
+ * @return pair of modid, fileid
+ */
+ std::pair<int, int> getPendingDownload(int index);
- /**
- * @brief retrieve a descriptive name of the download specified by index
- *
- * @param index index of the file to look up
- * @return display name of the file
- **/
- QString getDisplayName(int index) const;
+ /**
+ * @brief retrieve the full path to the download specified by index
+ *
+ * @param index the index to look up
+ * @return absolute path of the file
+ **/
+ QString getFilePath(int index) const;
- /**
- * @brief retrieve the filename of the download specified by index
- *
- * @param index index of the file to look up
- * @return name of the file
- **/
- QString getFileName(int index) const;
+ /**
+ * @brief retrieve a descriptive name of the download specified by index
+ *
+ * @param index index of the file to look up
+ * @return display name of the file
+ **/
+ QString getDisplayName(int index) const;
- /**
- * @brief retrieve the file size of the download specified by index
- *
- * @param index index of the file to look up
- * @return size of the file (total size during download)
- */
- qint64 getFileSize(int index) const;
+ /**
+ * @brief retrieve the filename of the download specified by index
+ *
+ * @param index index of the file to look up
+ * @return name of the file
+ **/
+ QString getFileName(int index) const;
- /**
- * @brief retrieve the creation time of the download specified by index
- * @param index index of the file to look up
- * @return size of the file (total size during download)
- */
- QDateTime getFileTime(int index) const;
+ /**
+ * @brief retrieve the file size of the download specified by index
+ *
+ * @param index index of the file to look up
+ * @return size of the file (total size during download)
+ */
+ qint64 getFileSize(int index) const;
- /**
- * @brief retrieve the current progress of the download specified by index
- *
- * @param index index of the file to look up
- * @return progress of the download in percent (integer)
- **/
- int getProgress(int index) const;
+ /**
+ * @brief retrieve the creation time of the download specified by index
+ * @param index index of the file to look up
+ * @return size of the file (total size during download)
+ */
+ QDateTime getFileTime(int index) const;
- /**
- * @brief retrieve the current state of the download
- *
- * retrieve the current state of the download. A download usually goes through
- * the following states:
- * started -> downloading -> fetching mod info -> fetching file info -> done
- * in case of downloads started via nxm-link, file information is fetched first
- *
- * @param index index of the file to look up
- * @return the download state
- **/
- DownloadState getState(int index) const;
+ /**
+ * @brief retrieve the current progress of the download specified by index
+ *
+ * @param index index of the file to look up
+ * @return progress of the download in percent (integer)
+ **/
+ int getProgress(int index) const;
- /**
- * @param index index of the file to look up
- * @return true if the nexus information for this download is not complete
- **/
- bool isInfoIncomplete(int index) const;
+ /**
+ * @brief retrieve the current state of the download
+ *
+ * retrieve the current state of the download. A download usually goes through
+ * the following states:
+ * started -> downloading -> fetching mod info -> fetching file info -> done
+ * in case of downloads started via nxm-link, file information is fetched first
+ *
+ * @param index index of the file to look up
+ * @return the download state
+ **/
+ DownloadState getState(int index) const;
- /**
- * @brief retrieve the nexus mod id of the download specified by index
- *
- * @param index index of the file to look up
- * @return the nexus mod id
- **/
- int getModID(int index) const;
+ /**
+ * @param index index of the file to look up
+ * @return true if the nexus information for this download is not complete
+ **/
+ bool isInfoIncomplete(int index) const;
- /**
- * @brief determine if the specified file is supposed to be hidden
- * @param index index of the file to look up
- * @return true if the specified file is supposed to be hidden
- */
- bool isHidden(int index) const;
+ /**
+ * @brief retrieve the nexus mod id of the download specified by index
+ *
+ * @param index index of the file to look up
+ * @return the nexus mod id
+ **/
+ int getModID(int index) const;
- /**
- * @brief retrieve all nexus info of the download specified by index
- *
- * @param index index of the file to look up
- * @return the nexus mod information
- **/
- const MOBase::ModRepositoryFileInfo* getFileInfo(int index) const;
+ /**
+ * @brief determine if the specified file is supposed to be hidden
+ * @param index index of the file to look up
+ * @return true if the specified file is supposed to be hidden
+ */
+ bool isHidden(int index) const;
- /**
- * @brief mark a download as installed
- *
- * @param index index of the file to mark installed
- */
- void markInstalled(int index);
+ /**
+ * @brief retrieve all nexus info of the download specified by index
+ *
+ * @param index index of the file to look up
+ * @return the nexus mod information
+ **/
+ const MOBase::ModRepositoryFileInfo *getFileInfo(int index) const;
- /**
- * @brief mark a download as uninstalled
- *
- * @param index index of the file to mark uninstalled
- */
- void markUninstalled(int index);
+ /**
+ * @brief mark a download as installed
+ *
+ * @param index index of the file to mark installed
+ */
+ void markInstalled(int index);
- /**
- * @brief refreshes the list of downloads
- */
- void refreshList();
+ /**
+ * @brief mark a download as uninstalled
+ *
+ * @param index index of the file to mark uninstalled
+ */
+ void markUninstalled(int index);
- /**
- * @brief Sort function for download servers
- * @param LHS
- * @param RHS
- * @return
- */
- static bool ServerByPreference(const std::map<QString, int>& preferredServers, const QVariant& LHS,
- const QVariant& RHS);
+ /**
+ * @brief refreshes the list of downloads
+ */
+ void refreshList();
- virtual int startDownloadURLs(const QStringList& urls);
+ /**
+ * @brief Sort function for download servers
+ * @param LHS
+ * @param RHS
+ * @return
+ */
+ static bool ServerByPreference(const std::map<QString, int> &preferredServers, const QVariant &LHS, const QVariant &RHS);
- virtual int startDownloadNexusFile(int modID, int fileID);
- virtual QString downloadPath(int id);
+ virtual int startDownloadURLs(const QStringList &urls);
- /**
- * @brief retrieve a download index from the filename
- * @param fileName file to look up
- * @return index of that download or -1 if it wasn't found
- */
- int indexByName(const QString& fileName) const;
+ virtual int startDownloadNexusFile(int modID, int fileID);
- void pauseAll();
+ virtual QString downloadPath(int id);
+
+ /**
+ * @brief retrieve a download index from the filename
+ * @param fileName file to look up
+ * @return index of that download or -1 if it wasn't found
+ */
+ int indexByName(const QString &fileName) const;
+
+ void pauseAll();
signals:
- void aboutToUpdate();
+ void aboutToUpdate();
- /**
- * @brief signals that the specified download has changed
- *
- * @param row the row that changed. This corresponds to the download index
- **/
- void update(int row);
+ /**
+ * @brief signals that the specified download has changed
+ *
+ * @param row the row that changed. This corresponds to the download index
+ **/
+ void update(int row);
- /**
- * @brief signals the ui that a message should be displayed
- *
- * @param message the message to display
- **/
- void showMessage(const QString& message);
+ /**
+ * @brief signals the ui that a message should be displayed
+ *
+ * @param message the message to display
+ **/
+ void showMessage(const QString &message);
- /**
- * @brief emitted whenever the state of a download changes
- * @param row the row that changed
- * @param state the new state
- */
- void stateChanged(int row, DownloadManager::DownloadState state);
+ /**
+ * @brief emitted whenever the state of a download changes
+ * @param row the row that changed
+ * @param state the new state
+ */
+ void stateChanged(int row, DownloadManager::DownloadState state);
- /**
- * @brief emitted whenever a download completes successfully, reporting the download speed for the server used
- */
- void downloadSpeed(const QString& serverName, int bytesPerSecond);
+ /**
+ * @brief emitted whenever a download completes successfully, reporting the download speed for the server used
+ */
+ void downloadSpeed(const QString &serverName, int bytesPerSecond);
- /**
- * @brief emitted whenever a new download is added to the list
- */
- void downloadAdded();
+ /**
+ * @brief emitted whenever a new download is added to the list
+ */
+ void downloadAdded();
public slots:
- /**
- * @brief removes the specified download
- *
- * @param index index of the download to remove
- * @param deleteFile if true, the file will also be deleted from disc, otherwise it is only marked as hidden.
- **/
- void removeDownload(int index, bool deleteFile);
+ /**
+ * @brief removes the specified download
+ *
+ * @param index index of the download to remove
+ * @param deleteFile if true, the file will also be deleted from disc, otherwise it is only marked as hidden.
+ **/
+ void removeDownload(int index, bool deleteFile);
- /**
- * @brief restores the specified download to view (which was previously hidden
- * @param index index of the download to restore
- */
- void restoreDownload(int index);
+ /**
+ * @brief restores the specified download to view (which was previously hidden
+ * @param index index of the download to restore
+ */
+ void restoreDownload(int index);
- /**
- * @brief cancel the specified download. This will lead to the corresponding file to be deleted
- *
- * @param index index of the download to cancel
- **/
- void cancelDownload(int index);
+ /**
+ * @brief cancel the specified download. This will lead to the corresponding file to be deleted
+ *
+ * @param index index of the download to cancel
+ **/
+ void cancelDownload(int index);
- void pauseDownload(int index);
+ void pauseDownload(int index);
- void resumeDownload(int index);
+ void resumeDownload(int index);
- void queryInfo(int index);
+ void queryInfo(int index);
- void nxmDescriptionAvailable(int modID, QVariant userData, QVariant resultData, int requestID);
+ void nxmDescriptionAvailable(int modID, QVariant userData, QVariant resultData, int requestID);
- void nxmFilesAvailable(int modID, QVariant userData, QVariant resultData, int requestID);
+ void nxmFilesAvailable(int modID, QVariant userData, QVariant resultData, int requestID);
- void nxmFileInfoAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
+ void nxmFileInfoAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
- void nxmDownloadURLsAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
+ void nxmDownloadURLsAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
- void nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString& errorString);
+ void nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorString);
- void managedGameChanged(MOBase::IPluginGame const* gamePlugin);
+ void managedGameChanged(MOBase::IPluginGame const *gamePlugin);
private slots:
- void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
- void downloadReadyRead();
- void downloadFinished();
- void downloadError(QNetworkReply::NetworkError error);
- void metaDataChanged();
- void directoryChanged(const QString& dirctory);
+ void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
+ void downloadReadyRead();
+ void downloadFinished();
+ void downloadError(QNetworkReply::NetworkError error);
+ void metaDataChanged();
+ void directoryChanged(const QString &dirctory);
private:
- void createMetaFile(DownloadInfo* info);
+
+ void createMetaFile(DownloadInfo *info);
public:
- /** Get a unique filename for a download.
- *
- * This allows you multiple versions of download files, useful if the file
- * comes from a web site with no version control
- *
- * @param basename: Name of the file
- *
- * @return Unique(ish) name
- */
- QString getDownloadFileName(const QString& baseName) const;
+
+ /** Get a unique filename for a download.
+ *
+ * This allows you multiple versions of download files, useful if the file
+ * comes from a web site with no version control
+ *
+ * @param basename: Name of the file
+ *
+ * @return Unique(ish) name
+ */
+ QString getDownloadFileName(const QString &baseName) const;
private:
- void startDownload(QNetworkReply* reply, DownloadInfo* newDownload, bool resume);
- void resumeDownloadInt(int index);
- /**
- * @brief start a download from a url
- *
- * @param url the url to download from
- * @param fileInfo information previously retrieved from the mod page
- * @return true if the download was started, false if it wasn't. The latter currently only happens if there is a
- *duplicate and the user decides not to download again
- **/
- bool addDownload(const QStringList& URLs, int modID, int fileID, const MOBase::ModRepositoryFileInfo* fileInfo);
+ void startDownload(QNetworkReply *reply, DownloadInfo *newDownload, bool resume);
+ void resumeDownloadInt(int index);
- // important: the caller has to lock the list-mutex, otherwise the DownloadInfo-pointer might get invalidated at any
- // time
- DownloadInfo* findDownload(QObject* reply, int* index = nullptr) const;
+ /**
+ * @brief start a download from a url
+ *
+ * @param url the url to download from
+ * @param fileInfo information previously retrieved from the mod page
+ * @return true if the download was started, false if it wasn't. The latter currently only happens if there is a duplicate and the user decides not to download again
+ **/
+ bool addDownload(const QStringList &URLs, int modID, int fileID, const MOBase::ModRepositoryFileInfo *fileInfo);
- void removeFile(int index, bool deleteFile);
+ // important: the caller has to lock the list-mutex, otherwise the DownloadInfo-pointer might get invalidated at any time
+ DownloadInfo *findDownload(QObject *reply, int *index = nullptr) const;
- void refreshAlphabeticalTranslation();
+ void removeFile(int index, bool deleteFile);
- bool ByName(int LHS, int RHS);
+ void refreshAlphabeticalTranslation();
- QString getFileNameFromNetworkReply(QNetworkReply* reply);
+ bool ByName(int LHS, int RHS);
- void setState(DownloadInfo* info, DownloadManager::DownloadState state);
+ QString getFileNameFromNetworkReply(QNetworkReply *reply);
- DownloadInfo* downloadInfoByID(unsigned int id);
+ void setState(DownloadInfo *info, DownloadManager::DownloadState state);
- QDateTime matchDate(const QString& timeString);
+ DownloadInfo *downloadInfoByID(unsigned int id);
- void removePending(int modID, int fileID);
+ QDateTime matchDate(const QString &timeString);
- static QString getFileTypeString(int fileType);
+ void removePending(int modID, int fileID);
+
+ static QString getFileTypeString(int fileType);
private:
- static const int AUTOMATIC_RETRIES = 3;
+
+ static const int AUTOMATIC_RETRIES = 3;
private:
- NexusInterface* m_NexusInterface;
- QVector<std::pair<int, int>> m_PendingDownloads;
+ NexusInterface *m_NexusInterface;
+
+ QVector<std::pair<int, int> > m_PendingDownloads;
- QVector<DownloadInfo*> m_ActiveDownloads;
+ QVector<DownloadInfo*> m_ActiveDownloads;
- QString m_OutputDirectory;
- std::map<QString, int> m_PreferredServers;
- QStringList m_SupportedExtensions;
- std::set<int> m_RequestIDs;
- QVector<int> m_AlphabeticalTranslation;
+ QString m_OutputDirectory;
+ std::map<QString, int> m_PreferredServers;
+ QStringList m_SupportedExtensions;
+ std::set<int> m_RequestIDs;
+ QVector<int> m_AlphabeticalTranslation;
- QFileSystemWatcher m_DirWatcher;
+ QFileSystemWatcher m_DirWatcher;
- std::map<QString, int> m_DownloadFails;
+ std::map<QString, int> m_DownloadFails;
- bool m_ShowHidden;
+ bool m_ShowHidden;
- QRegExp m_DateExpression;
+ QRegExp m_DateExpression;
- MOBase::IPluginGame const* m_ManagedGame;
+ MOBase::IPluginGame const *m_ManagedGame;
};
+
+
#endif // DOWNLOADMANAGER_H
diff --git a/src/editexecutablesdialog.cpp b/src/editexecutablesdialog.cpp
index 1c01545a..fde6b397 100644
--- a/src/editexecutablesdialog.cpp
+++ b/src/editexecutablesdialog.cpp
@@ -18,282 +18,323 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "editexecutablesdialog.h"
+#include "ui_editexecutablesdialog.h"
#include "filedialogmemory.h"
-#include "modlist.h"
#include "stackdata.h"
-#include "ui_editexecutablesdialog.h"
+#include "modlist.h"
#include <QMessageBox>
#include <Shellapi.h>
#include <utility.h>
+
using namespace MOBase;
using namespace MOShared;
-EditExecutablesDialog::EditExecutablesDialog(const ExecutablesList& executablesList, const ModList& modList,
- Profile* profile, QWidget* parent)
- : TutorableDialog("EditExecutables", parent), ui(new Ui::EditExecutablesDialog), m_CurrentItem(nullptr),
- m_ExecutablesList(executablesList), m_Profile(profile) {
- ui->setupUi(this);
+EditExecutablesDialog::EditExecutablesDialog(
+ const ExecutablesList &executablesList, const ModList &modList,
+ Profile *profile, QWidget *parent)
+ : TutorableDialog("EditExecutables", parent)
+ , ui(new Ui::EditExecutablesDialog)
+ , m_CurrentItem(nullptr)
+ , m_ExecutablesList(executablesList)
+ , m_Profile(profile)
+{
+ ui->setupUi(this);
- refreshExecutablesWidget();
+ refreshExecutablesWidget();
- ui->newFilesModBox->addItems(modList.allMods());
+ ui->newFilesModBox->addItems(modList.allMods());
}
-EditExecutablesDialog::~EditExecutablesDialog() { delete ui; }
+EditExecutablesDialog::~EditExecutablesDialog()
+{
+ delete ui;
+}
-ExecutablesList EditExecutablesDialog::getExecutablesList() const {
- ExecutablesList newList;
- for (int i = 0; i < ui->executablesListBox->count(); ++i) {
- newList.addExecutable(m_ExecutablesList.find(ui->executablesListBox->item(i)->text()));
- }
- return newList;
+ExecutablesList EditExecutablesDialog::getExecutablesList() const
+{
+ ExecutablesList newList;
+ for (int i = 0; i < ui->executablesListBox->count(); ++i) {
+ newList.addExecutable(m_ExecutablesList.find(ui->executablesListBox->item(i)->text()));
+ }
+ return newList;
}
-void EditExecutablesDialog::refreshExecutablesWidget() {
- ui->executablesListBox->clear();
- std::vector<Executable>::const_iterator current, end;
- m_ExecutablesList.getExecutables(current, end);
+void EditExecutablesDialog::refreshExecutablesWidget()
+{
+ ui->executablesListBox->clear();
+ std::vector<Executable>::const_iterator current, end;
+ m_ExecutablesList.getExecutables(current, end);
- for (; current != end; ++current) {
- QListWidgetItem* newItem = new QListWidgetItem(current->m_Title);
- newItem->setTextColor(current->isCustom() ? QColor(Qt::black) : QColor(Qt::darkGray));
- ui->executablesListBox->addItem(newItem);
- }
+ for(; current != end; ++current) {
+ QListWidgetItem *newItem = new QListWidgetItem(current->m_Title);
+ newItem->setTextColor(current->isCustom() ? QColor(Qt::black) : QColor(Qt::darkGray));
+ ui->executablesListBox->addItem(newItem);
+ }
- ui->addButton->setEnabled(false);
- ui->removeButton->setEnabled(false);
+ ui->addButton->setEnabled(false);
+ ui->removeButton->setEnabled(false);
}
-void EditExecutablesDialog::on_binaryEdit_textChanged(const QString& name) {
- QFileInfo fileInfo(name);
- ui->addButton->setEnabled(fileInfo.exists() && fileInfo.isFile());
+
+void EditExecutablesDialog::on_binaryEdit_textChanged(const QString &name)
+{
+ QFileInfo fileInfo(name);
+ ui->addButton->setEnabled(fileInfo.exists() && fileInfo.isFile());
}
-void EditExecutablesDialog::resetInput() {
- ui->binaryEdit->setText("");
- ui->titleEdit->setText("");
- ui->workingDirEdit->clear();
- ui->argumentsEdit->setText("");
- ui->appIDOverwriteEdit->clear();
- ui->overwriteAppIDBox->setChecked(false);
- ui->useAppIconCheckBox->setChecked(false);
- ui->newFilesModCheckBox->setChecked(false);
- m_CurrentItem = nullptr;
+void EditExecutablesDialog::resetInput()
+{
+ ui->binaryEdit->setText("");
+ ui->titleEdit->setText("");
+ ui->workingDirEdit->clear();
+ ui->argumentsEdit->setText("");
+ ui->appIDOverwriteEdit->clear();
+ ui->overwriteAppIDBox->setChecked(false);
+ ui->useAppIconCheckBox->setChecked(false);
+ ui->newFilesModCheckBox->setChecked(false);
+ m_CurrentItem = nullptr;
}
-void EditExecutablesDialog::saveExecutable() {
- m_ExecutablesList.updateExecutable(
- ui->titleEdit->text(), QDir::fromNativeSeparators(ui->binaryEdit->text()), ui->argumentsEdit->text(),
+
+void EditExecutablesDialog::saveExecutable()
+{
+ m_ExecutablesList.updateExecutable(
+ ui->titleEdit->text(),
+ QDir::fromNativeSeparators(ui->binaryEdit->text()),
+ ui->argumentsEdit->text(),
QDir::fromNativeSeparators(ui->workingDirEdit->text()),
- ui->overwriteAppIDBox->isChecked() ? ui->appIDOverwriteEdit->text() : "",
+ ui->overwriteAppIDBox->isChecked() ?
+ ui->appIDOverwriteEdit->text() : "",
Executable::UseApplicationIcon | Executable::CustomExecutable,
- (ui->useAppIconCheckBox->isChecked() ? Executable::UseApplicationIcon : Executable::Flags()) |
- Executable::CustomExecutable);
+ (ui->useAppIconCheckBox->isChecked() ?
+ Executable::UseApplicationIcon : Executable::Flags())
+ | Executable::CustomExecutable);
- if (ui->newFilesModCheckBox->isChecked()) {
- m_Profile->storeSetting("custom_overwrites", ui->titleEdit->text(), ui->newFilesModBox->currentText());
- } else {
- m_Profile->removeSetting("custom_overwrites", ui->titleEdit->text());
- }
+ if (ui->newFilesModCheckBox->isChecked()) {
+ m_Profile->storeSetting("custom_overwrites", ui->titleEdit->text(),
+ ui->newFilesModBox->currentText());
+ }
+ else {
+ m_Profile->removeSetting("custom_overwrites", ui->titleEdit->text());
+ }
}
-void EditExecutablesDialog::delayedRefresh() {
- QModelIndex index = ui->executablesListBox->currentIndex();
- resetInput();
- refreshExecutablesWidget();
- on_executablesListBox_clicked(index);
+
+void EditExecutablesDialog::delayedRefresh()
+{
+ QModelIndex index = ui->executablesListBox->currentIndex();
+ resetInput();
+ refreshExecutablesWidget();
+ on_executablesListBox_clicked(index);
}
-void EditExecutablesDialog::on_addButton_clicked() {
- if (executableChanged()) {
- saveExecutable();
- }
- resetInput();
- refreshExecutablesWidget();
+void EditExecutablesDialog::on_addButton_clicked()
+{
+ if (executableChanged()) {
+ saveExecutable();
+ }
+
+ resetInput();
+ refreshExecutablesWidget();
}
-void EditExecutablesDialog::on_browseButton_clicked() {
- QString binaryName = FileDialogMemory::getOpenFileName("editExecutableBinary", this, tr("Select a binary"),
- QString(), tr("Executable (%1)").arg("*.exe *.bat *.jar"));
+void EditExecutablesDialog::on_browseButton_clicked()
+{
+ QString binaryName = FileDialogMemory::getOpenFileName(
+ "editExecutableBinary", this, tr("Select a binary"), QString(),
+ tr("Executable (%1)").arg("*.exe *.bat *.jar"));
- if (binaryName.endsWith(".jar", Qt::CaseInsensitive)) {
- QString binaryPath;
- { // try to find java automatically
- std::wstring binaryNameW = ToWString(binaryName);
- WCHAR buffer[MAX_PATH];
- if (::FindExecutableW(binaryNameW.c_str(), nullptr, buffer) > reinterpret_cast<HINSTANCE>(32)) {
- DWORD binaryType = 0UL;
- if (!::GetBinaryTypeW(binaryNameW.c_str(), &binaryType)) {
- qDebug("failed to determine binary type of \"%ls\": %lu", binaryNameW.c_str(), ::GetLastError());
- } else if (binaryType == SCS_32BIT_BINARY) {
- binaryPath = ToQString(buffer);
- }
- }
+ if (binaryName.endsWith(".jar", Qt::CaseInsensitive)) {
+ QString binaryPath;
+ { // try to find java automatically
+ std::wstring binaryNameW = ToWString(binaryName);
+ WCHAR buffer[MAX_PATH];
+ if (::FindExecutableW(binaryNameW.c_str(), nullptr, buffer)
+ > reinterpret_cast<HINSTANCE>(32)) {
+ DWORD binaryType = 0UL;
+ if (!::GetBinaryTypeW(binaryNameW.c_str(), &binaryType)) {
+ qDebug("failed to determine binary type of \"%ls\": %lu", binaryNameW.c_str(), ::GetLastError());
+ } else if (binaryType == SCS_32BIT_BINARY) {
+ binaryPath = ToQString(buffer);
}
- if (binaryPath.isEmpty()) {
- QSettings javaReg("HKEY_LOCAL_MACHINE\\Software\\JavaSoft\\Java Runtime Environment",
- QSettings::NativeFormat);
- if (javaReg.contains("CurrentVersion")) {
- QString currentVersion = javaReg.value("CurrentVersion").toString();
- binaryPath =
- javaReg.value(QString("%1/JavaHome").arg(currentVersion)).toString().append("\\bin\\javaw.exe");
- }
- }
- if (binaryPath.isEmpty()) {
- QMessageBox::information(this, tr("Java (32-bit) required"),
- tr("MO requires 32-bit java to run this application. If you already have it "
- "installed, select javaw.exe "
- "from that installation as the binary."));
- } else {
- ui->binaryEdit->setText(binaryPath);
- }
-
- ui->workingDirEdit->setText(QDir::toNativeSeparators(QFileInfo(binaryName).absolutePath()));
- ui->argumentsEdit->setText("-jar \"" + QDir::toNativeSeparators(binaryName) + "\"");
+ }
+ }
+ if (binaryPath.isEmpty()) {
+ QSettings javaReg("HKEY_LOCAL_MACHINE\\Software\\JavaSoft\\Java Runtime Environment", QSettings::NativeFormat);
+ if (javaReg.contains("CurrentVersion")) {
+ QString currentVersion = javaReg.value("CurrentVersion").toString();
+ binaryPath = javaReg.value(QString("%1/JavaHome").arg(currentVersion)).toString().append("\\bin\\javaw.exe");
+ }
+ }
+ if (binaryPath.isEmpty()) {
+ QMessageBox::information(this, tr("Java (32-bit) required"),
+ tr("MO requires 32-bit java to run this application. If you already have it installed, select javaw.exe "
+ "from that installation as the binary."));
} else {
- ui->binaryEdit->setText(QDir::toNativeSeparators(binaryName));
+ ui->binaryEdit->setText(binaryPath);
}
+
+ ui->workingDirEdit->setText(QDir::toNativeSeparators(QFileInfo(binaryName).absolutePath()));
+ ui->argumentsEdit->setText("-jar \"" + QDir::toNativeSeparators(binaryName) + "\"");
+ } else {
+ ui->binaryEdit->setText(QDir::toNativeSeparators(binaryName));
+ }
}
-void EditExecutablesDialog::on_browseDirButton_clicked() {
- QString dirName = FileDialogMemory::getExistingDirectory("editExecutableDirectory", this, tr("Select a directory"));
+void EditExecutablesDialog::on_browseDirButton_clicked()
+{
+ QString dirName = FileDialogMemory::getExistingDirectory("editExecutableDirectory", this,
+ tr("Select a directory"));
- ui->workingDirEdit->setText(dirName);
+ ui->workingDirEdit->setText(dirName);
}
-void EditExecutablesDialog::on_removeButton_clicked() {
- if (QMessageBox::question(this, tr("Confirm"),
- tr("Really remove \"%1\" from executables?").arg(ui->titleEdit->text()),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- m_ExecutablesList.remove(ui->titleEdit->text());
- }
+void EditExecutablesDialog::on_removeButton_clicked()
+{
+ if (QMessageBox::question(this, tr("Confirm"), tr("Really remove \"%1\" from executables?").arg(ui->titleEdit->text()),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ m_ExecutablesList.remove(ui->titleEdit->text());
+ }
- resetInput();
- refreshExecutablesWidget();
+ resetInput();
+ refreshExecutablesWidget();
}
-void EditExecutablesDialog::on_titleEdit_textChanged(const QString& arg1) {
- QPushButton* addButton = findChild<QPushButton*>("addButton");
- QPushButton* removeButton = findChild<QPushButton*>("removeButton");
+void EditExecutablesDialog::on_titleEdit_textChanged(const QString &arg1)
+{
+ QPushButton *addButton = findChild<QPushButton*>("addButton");
+ QPushButton *removeButton = findChild<QPushButton*>("removeButton");
- QListWidget* executablesWidget = findChild<QListWidget*>("executablesListBox");
+ QListWidget *executablesWidget = findChild<QListWidget*>("executablesListBox");
- QList<QListWidgetItem*> existingItems = executablesWidget->findItems(arg1, Qt::MatchFixedString);
+ QList<QListWidgetItem*> existingItems = executablesWidget->findItems(arg1, Qt::MatchFixedString);
- addButton->setEnabled(arg1.length() != 0);
+ addButton->setEnabled(arg1.length() != 0);
- if (existingItems.count() == 0) {
- addButton->setText(tr("Add"));
- removeButton->setEnabled(false);
- } else {
- // existing item. is it a custom one?
- addButton->setText(tr("Modify"));
- removeButton->setEnabled(true);
- }
+ if (existingItems.count() == 0) {
+ addButton->setText(tr("Add"));
+ removeButton->setEnabled(false);
+ } else {
+ // existing item. is it a custom one?
+ addButton->setText(tr("Modify"));
+ removeButton->setEnabled(true);
+ }
}
-bool EditExecutablesDialog::executableChanged() {
- if (m_CurrentItem != nullptr) {
- Executable const& selectedExecutable(m_ExecutablesList.find(m_CurrentItem->text()));
- QString storedCustomOverwrite = m_Profile->setting("custom_overwrites", selectedExecutable.m_Title).toString();
+bool EditExecutablesDialog::executableChanged()
+{
+ if (m_CurrentItem != nullptr) {
+ Executable const &selectedExecutable(m_ExecutablesList.find(m_CurrentItem->text()));
- return selectedExecutable.m_Title != ui->titleEdit->text() ||
- selectedExecutable.m_Arguments != ui->argumentsEdit->text() ||
- selectedExecutable.m_SteamAppID != ui->appIDOverwriteEdit->text() ||
- !storedCustomOverwrite.isEmpty() != ui->newFilesModCheckBox->isChecked() ||
- !storedCustomOverwrite.isEmpty() && (storedCustomOverwrite != ui->newFilesModBox->currentText()) ||
- selectedExecutable.m_WorkingDirectory != QDir::fromNativeSeparators(ui->workingDirEdit->text()) ||
- selectedExecutable.m_BinaryInfo.absoluteFilePath() !=
- QDir::fromNativeSeparators(ui->binaryEdit->text()) ||
- selectedExecutable.usesOwnIcon() != ui->useAppIconCheckBox->isChecked();
- } else {
- QFileInfo fileInfo(ui->binaryEdit->text());
- return !ui->binaryEdit->text().isEmpty() && !ui->titleEdit->text().isEmpty() && fileInfo.exists() &&
- fileInfo.isFile();
- }
+ QString storedCustomOverwrite = m_Profile->setting("custom_overwrites", selectedExecutable.m_Title).toString();
+
+ return selectedExecutable.m_Title != ui->titleEdit->text()
+ || selectedExecutable.m_Arguments != ui->argumentsEdit->text()
+ || selectedExecutable.m_SteamAppID != ui->appIDOverwriteEdit->text()
+ || !storedCustomOverwrite.isEmpty() != ui->newFilesModCheckBox->isChecked()
+ || !storedCustomOverwrite.isEmpty() && (storedCustomOverwrite != ui->newFilesModBox->currentText())
+ || selectedExecutable.m_WorkingDirectory != QDir::fromNativeSeparators(ui->workingDirEdit->text())
+ || selectedExecutable.m_BinaryInfo.absoluteFilePath() != QDir::fromNativeSeparators(ui->binaryEdit->text())
+ || selectedExecutable.usesOwnIcon() != ui->useAppIconCheckBox->isChecked();
+ } else {
+ QFileInfo fileInfo(ui->binaryEdit->text());
+ return !ui->binaryEdit->text().isEmpty()
+ && !ui->titleEdit->text().isEmpty()
+ && fileInfo.exists()
+ && fileInfo.isFile();
+ }
}
-void EditExecutablesDialog::on_executablesListBox_itemSelectionChanged() {
- if (ui->executablesListBox->selectedItems().size() == 0) {
- // deselected
- resetInput();
- }
+void EditExecutablesDialog::on_executablesListBox_itemSelectionChanged()
+{
+ if (ui->executablesListBox->selectedItems().size() == 0) {
+ // deselected
+ resetInput();
+ }
}
-void EditExecutablesDialog::on_overwriteAppIDBox_toggled(bool checked) { ui->appIDOverwriteEdit->setEnabled(checked); }
+void EditExecutablesDialog::on_overwriteAppIDBox_toggled(bool checked)
+{
+ ui->appIDOverwriteEdit->setEnabled(checked);
+}
-void EditExecutablesDialog::on_closeButton_clicked() {
- if (executableChanged()) {
- QMessageBox::StandardButton res = QMessageBox::question(
- this, tr("Save Changes?"), tr("You made changes to the current executable, do you want to save them?"),
- QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
- if (res == QMessageBox::Cancel) {
- return;
- } else if (res == QMessageBox::Yes) {
- saveExecutable();
- // the executable list returned to callers is generated from the user data in the widgets,
- // NOT the list we just saved
- refreshExecutablesWidget();
- }
+void EditExecutablesDialog::on_closeButton_clicked()
+{
+ if (executableChanged()) {
+ QMessageBox::StandardButton res = QMessageBox::question(this, tr("Save Changes?"),
+ tr("You made changes to the current executable, do you want to save them?"),
+ QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
+ if (res == QMessageBox::Cancel) {
+ return;
+ } else if (res == QMessageBox::Yes) {
+ saveExecutable();
+ // the executable list returned to callers is generated from the user data in the widgets,
+ // NOT the list we just saved
+ refreshExecutablesWidget();
}
- this->accept();
+ }
+ this->accept();
}
-void EditExecutablesDialog::on_executablesListBox_clicked(const QModelIndex& current) {
- if (current.isValid()) {
-
- if (executableChanged()) {
- QMessageBox::StandardButton res = QMessageBox::question(
- this, tr("Save Changes?"), tr("You made changes to the current executable, do you want to save them?"),
- QMessageBox::Yes | QMessageBox::No);
- if (res == QMessageBox::Yes) {
- saveExecutable();
+void EditExecutablesDialog::on_executablesListBox_clicked(const QModelIndex &current)
+{
+ if (current.isValid()) {
- // This is necessary if we're adding a new item, but it doesn't look very nice.
- // Ideally we'd end up with the correct row displayed
- ui->executablesListBox->selectionModel()->clearSelection();
- ui->executablesListBox->selectionModel()->select(current, QItemSelectionModel::SelectCurrent);
- QTimer::singleShot(50, this, SLOT(delayedRefresh()));
- return;
- }
- }
+ if (executableChanged()) {
+ QMessageBox::StandardButton res = QMessageBox::question(this, tr("Save Changes?"),
+ tr("You made changes to the current executable, do you want to save them?"),
+ QMessageBox::Yes | QMessageBox::No);
+ if (res == QMessageBox::Yes) {
+ saveExecutable();
+ //This is necessary if we're adding a new item, but it doesn't look very nice.
+ //Ideally we'd end up with the correct row displayed
ui->executablesListBox->selectionModel()->clearSelection();
ui->executablesListBox->selectionModel()->select(current, QItemSelectionModel::SelectCurrent);
+ QTimer::singleShot(50, this, SLOT(delayedRefresh()));
+ return;
+ }
+ }
- m_CurrentItem = ui->executablesListBox->item(current.row());
+ ui->executablesListBox->selectionModel()->clearSelection();
+ ui->executablesListBox->selectionModel()->select(current, QItemSelectionModel::SelectCurrent);
- Executable const& selectedExecutable(m_ExecutablesList.find(m_CurrentItem->text()));
+ m_CurrentItem = ui->executablesListBox->item(current.row());
- ui->titleEdit->setText(selectedExecutable.m_Title);
- ui->binaryEdit->setText(QDir::toNativeSeparators(selectedExecutable.m_BinaryInfo.absoluteFilePath()));
- ui->argumentsEdit->setText(selectedExecutable.m_Arguments);
- ui->workingDirEdit->setText(QDir::toNativeSeparators(selectedExecutable.m_WorkingDirectory));
- ui->removeButton->setEnabled(selectedExecutable.isCustom());
- ui->overwriteAppIDBox->setChecked(!selectedExecutable.m_SteamAppID.isEmpty());
- if (!selectedExecutable.m_SteamAppID.isEmpty()) {
- ui->appIDOverwriteEdit->setText(selectedExecutable.m_SteamAppID);
- } else {
- ui->appIDOverwriteEdit->clear();
- }
- ui->useAppIconCheckBox->setChecked(selectedExecutable.usesOwnIcon());
+ Executable const &selectedExecutable(m_ExecutablesList.find(m_CurrentItem->text()));
+
+ ui->titleEdit->setText(selectedExecutable.m_Title);
+ ui->binaryEdit->setText(QDir::toNativeSeparators(selectedExecutable.m_BinaryInfo.absoluteFilePath()));
+ ui->argumentsEdit->setText(selectedExecutable.m_Arguments);
+ ui->workingDirEdit->setText(QDir::toNativeSeparators(selectedExecutable.m_WorkingDirectory));
+ ui->removeButton->setEnabled(selectedExecutable.isCustom());
+ ui->overwriteAppIDBox->setChecked(!selectedExecutable.m_SteamAppID.isEmpty());
+ if (!selectedExecutable.m_SteamAppID.isEmpty()) {
+ ui->appIDOverwriteEdit->setText(selectedExecutable.m_SteamAppID);
+ } else {
+ ui->appIDOverwriteEdit->clear();
+ }
+ ui->useAppIconCheckBox->setChecked(selectedExecutable.usesOwnIcon());
- int index = -1;
+ int index = -1;
- QString customOverwrite = m_Profile->setting("custom_overwrites", selectedExecutable.m_Title).toString();
- if (!customOverwrite.isEmpty()) {
- index = ui->newFilesModBox->findText(customOverwrite);
- qDebug("find %s -> %d", qPrintable(customOverwrite), index);
- }
+ QString customOverwrite = m_Profile->setting("custom_overwrites", selectedExecutable.m_Title).toString();
+ if (!customOverwrite.isEmpty()) {
+ index = ui->newFilesModBox->findText(customOverwrite);
+ qDebug("find %s -> %d", qPrintable(customOverwrite), index);
+ }
- ui->newFilesModCheckBox->setChecked(index != -1);
- if (index != -1) {
- ui->newFilesModBox->setCurrentIndex(index);
- }
+ ui->newFilesModCheckBox->setChecked(index != -1);
+ if (index != -1) {
+ ui->newFilesModBox->setCurrentIndex(index);
}
+ }
}
-void EditExecutablesDialog::on_newFilesModCheckBox_toggled(bool checked) { ui->newFilesModBox->setEnabled(checked); }
+void EditExecutablesDialog::on_newFilesModCheckBox_toggled(bool checked)
+{
+ ui->newFilesModBox->setEnabled(checked);
+}
diff --git a/src/editexecutablesdialog.h b/src/editexecutablesdialog.h
index 8241ba51..0f3dbaff 100644
--- a/src/editexecutablesdialog.h
+++ b/src/editexecutablesdialog.h
@@ -20,87 +20,94 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef EDITEXECUTABLESDIALOG_H
#define EDITEXECUTABLESDIALOG_H
-#include "executableslist.h"
-#include "profile.h"
#include "tutorabledialog.h"
#include <QListWidgetItem>
#include <QTimer>
+#include "executableslist.h"
+#include "profile.h"
namespace Ui {
-class EditExecutablesDialog;
+ class EditExecutablesDialog;
}
+
class ModList;
+
/**
* @brief Dialog to manage the list of executables
**/
-class EditExecutablesDialog : public MOBase::TutorableDialog {
+class EditExecutablesDialog : public MOBase::TutorableDialog
+{
Q_OBJECT
public:
- /**
- * @brief constructor
- *
- * @param executablesList current list of executables
- * @param parent parent widget
- **/
- explicit EditExecutablesDialog(const ExecutablesList& executablesList, const ModList& modList, Profile* profile,
- QWidget* parent = 0);
- ~EditExecutablesDialog();
+ /**
+ * @brief constructor
+ *
+ * @param executablesList current list of executables
+ * @param parent parent widget
+ **/
+ explicit EditExecutablesDialog(const ExecutablesList &executablesList,
+ const ModList &modList,
+ Profile *profile,
+ QWidget *parent = 0);
- /**
- * @brief retrieve the updated list of executables
- *
- * @return updated list of executables
- **/
- ExecutablesList getExecutablesList() const;
+ ~EditExecutablesDialog();
- void saveExecutable();
+ /**
+ * @brief retrieve the updated list of executables
+ *
+ * @return updated list of executables
+ **/
+ ExecutablesList getExecutablesList() const;
+
+ void saveExecutable();
private slots:
- void on_newFilesModCheckBox_toggled(bool checked);
+ void on_newFilesModCheckBox_toggled(bool checked);
private slots:
- void on_binaryEdit_textChanged(const QString& arg1);
+ void on_binaryEdit_textChanged(const QString &arg1);
- void on_addButton_clicked();
+ void on_addButton_clicked();
- void on_browseButton_clicked();
+ void on_browseButton_clicked();
- void on_removeButton_clicked();
+ void on_removeButton_clicked();
- void on_titleEdit_textChanged(const QString& arg1);
+ void on_titleEdit_textChanged(const QString &arg1);
- void on_overwriteAppIDBox_toggled(bool checked);
+ void on_overwriteAppIDBox_toggled(bool checked);
- void on_browseDirButton_clicked();
+ void on_browseDirButton_clicked();
- void on_closeButton_clicked();
+ void on_closeButton_clicked();
- void delayedRefresh();
+ void delayedRefresh();
- void on_executablesListBox_itemSelectionChanged();
+ void on_executablesListBox_itemSelectionChanged();
- void on_executablesListBox_clicked(const QModelIndex& index);
+ void on_executablesListBox_clicked(const QModelIndex &index);
private:
- void resetInput();
- void refreshExecutablesWidget();
+ void resetInput();
+
+ void refreshExecutablesWidget();
- bool executableChanged();
+ bool executableChanged();
private:
- Ui::EditExecutablesDialog* ui;
+ Ui::EditExecutablesDialog *ui;
- QListWidgetItem* m_CurrentItem;
+ QListWidgetItem *m_CurrentItem;
- ExecutablesList m_ExecutablesList;
+ ExecutablesList m_ExecutablesList;
- Profile* m_Profile;
+ Profile *m_Profile;
};
#endif // EDITEXECUTABLESDIALOG_H
diff --git a/src/eventfilter.cpp b/src/eventfilter.cpp
index e3195249..69327f79 100644
--- a/src/eventfilter.cpp
+++ b/src/eventfilter.cpp
@@ -17,9 +17,17 @@ You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
+
#include "eventfilter.h"
-EventFilter::EventFilter(QObject* parent, const EventFilter::HandlerFunc& handler)
- : QObject(parent), m_Handler(handler) {}
+EventFilter::EventFilter(QObject *parent,
+ const EventFilter::HandlerFunc &handler)
+ : QObject(parent)
+ , m_Handler(handler)
+{
+}
-bool EventFilter::eventFilter(QObject* obj, QEvent* event) { return m_Handler(obj, event); }
+bool EventFilter::eventFilter(QObject *obj, QEvent *event)
+{
+ return m_Handler(obj, event);
+}
diff --git a/src/eventfilter.h b/src/eventfilter.h
index f2f406db..2400a853 100644
--- a/src/eventfilter.h
+++ b/src/eventfilter.h
@@ -19,20 +19,26 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#pragma once
+
#include <QObject>
#include <functional>
+
class EventFilter : public QObject {
- Q_OBJECT
+ Q_OBJECT
- typedef std::function<bool(QObject*, QEvent*)> HandlerFunc;
+ typedef std::function<bool (QObject*, QEvent*)> HandlerFunc;
public:
- EventFilter(QObject* parent, const HandlerFunc& handler);
- virtual bool eventFilter(QObject* obj, QEvent* event) override;
+ EventFilter(QObject *parent, const HandlerFunc &handler);
+
+ virtual bool eventFilter(QObject *obj , QEvent *event) override;
private:
- HandlerFunc m_Handler;
+
+ HandlerFunc m_Handler;
+
};
+
diff --git a/src/executableslist.cpp b/src/executableslist.cpp
index cde487be..21cb6ed4 100644
--- a/src/executableslist.cpp
+++ b/src/executableslist.cpp
@@ -22,152 +22,187 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "iplugingame.h"
#include "utility.h"
-#include <QDebug>
-#include <QDir>
#include <QFileInfo>
+#include <QDir>
+#include <QDebug>
#include <algorithm>
+
using namespace MOBase;
-ExecutablesList::ExecutablesList() {}
-ExecutablesList::~ExecutablesList() {}
+ExecutablesList::ExecutablesList()
+{
+}
+
+ExecutablesList::~ExecutablesList()
+{
+}
-void ExecutablesList::init(IPluginGame const* game) {
- Q_ASSERT(game != nullptr);
- m_Executables.clear();
- for (const ExecutableInfo& info : game->executables()) {
- if (info.isValid()) {
- addExecutableInternal(info.title(), info.binary().absoluteFilePath(), info.arguments().join(" "),
- info.workingDirectory().absolutePath(), info.steamAppID());
- }
+void ExecutablesList::init(IPluginGame const *game)
+{
+ Q_ASSERT(game != nullptr);
+ m_Executables.clear();
+ for (const ExecutableInfo &info : game->executables()) {
+ if (info.isValid()) {
+ addExecutableInternal(info.title(),
+ info.binary().absoluteFilePath(),
+ info.arguments().join(" "),
+ info.workingDirectory().absolutePath(),
+ info.steamAppID());
}
+ }
}
-void ExecutablesList::getExecutables(std::vector<Executable>::iterator& begin, std::vector<Executable>::iterator& end) {
- begin = m_Executables.begin();
- end = m_Executables.end();
+void ExecutablesList::getExecutables(std::vector<Executable>::iterator &begin, std::vector<Executable>::iterator &end)
+{
+ begin = m_Executables.begin();
+ end = m_Executables.end();
}
-void ExecutablesList::getExecutables(std::vector<Executable>::const_iterator& begin,
- std::vector<Executable>::const_iterator& end) const {
- begin = m_Executables.begin();
- end = m_Executables.end();
+void ExecutablesList::getExecutables(std::vector<Executable>::const_iterator &begin,
+ std::vector<Executable>::const_iterator &end) const
+{
+ begin = m_Executables.begin();
+ end = m_Executables.end();
}
-const Executable& ExecutablesList::find(const QString& title) const {
- for (Executable const& exe : m_Executables) {
- if (exe.m_Title == title) {
- return exe;
- }
+const Executable &ExecutablesList::find(const QString &title) const
+{
+ for (Executable const &exe : m_Executables) {
+ if (exe.m_Title == title) {
+ return exe;
}
- throw std::runtime_error(QString("invalid name %1").arg(title).toLocal8Bit().constData());
+ }
+ throw std::runtime_error(QString("invalid name %1").arg(title).toLocal8Bit().constData());
}
-Executable& ExecutablesList::find(const QString& title) {
- for (Executable& exe : m_Executables) {
- if (exe.m_Title == title) {
- return exe;
- }
+
+Executable &ExecutablesList::find(const QString &title)
+{
+ for (Executable &exe : m_Executables) {
+ if (exe.m_Title == title) {
+ return exe;
}
- throw std::runtime_error(QString("invalid executable name %1").arg(title).toLocal8Bit().constData());
+ }
+ throw std::runtime_error(QString("invalid executable name %1").arg(title).toLocal8Bit().constData());
}
-Executable& ExecutablesList::findByBinary(const QFileInfo& info) {
- for (Executable& exe : m_Executables) {
- if (info == exe.m_BinaryInfo) {
- return exe;
- }
+
+Executable &ExecutablesList::findByBinary(const QFileInfo &info)
+{
+ for (Executable &exe : m_Executables) {
+ if (info == exe.m_BinaryInfo) {
+ return exe;
}
- throw std::runtime_error("invalid info");
+ }
+ throw std::runtime_error("invalid info");
}
-std::vector<Executable>::iterator ExecutablesList::findExe(const QString& title) {
- for (std::vector<Executable>::iterator iter = m_Executables.begin(); iter != m_Executables.end(); ++iter) {
- if (iter->m_Title == title) {
- return iter;
- }
+
+std::vector<Executable>::iterator ExecutablesList::findExe(const QString &title)
+{
+ for (std::vector<Executable>::iterator iter = m_Executables.begin(); iter != m_Executables.end(); ++iter) {
+ if (iter->m_Title == title) {
+ return iter;
}
- return m_Executables.end();
+ }
+ return m_Executables.end();
}
-bool ExecutablesList::titleExists(const QString& title) const {
- auto test = [&](const Executable& exe) { return exe.m_Title == title; };
- return std::find_if(m_Executables.begin(), m_Executables.end(), test) != m_Executables.end();
+
+bool ExecutablesList::titleExists(const QString &title) const
+{
+ auto test = [&] (const Executable &exe) { return exe.m_Title == title; };
+ return std::find_if(m_Executables.begin(), m_Executables.end(), test) != m_Executables.end();
}
-void ExecutablesList::addExecutable(const Executable& executable) {
- auto existingExe = findExe(executable.m_Title);
- if (existingExe != m_Executables.end()) {
- *existingExe = executable;
- } else {
- m_Executables.push_back(executable);
- }
+
+void ExecutablesList::addExecutable(const Executable &executable)
+{
+ auto existingExe = findExe(executable.m_Title);
+ if (existingExe != m_Executables.end()) {
+ *existingExe = executable;
+ } else {
+ m_Executables.push_back(executable);
+ }
}
-void ExecutablesList::updateExecutable(const QString& title, const QString& executableName, const QString& arguments,
- const QString& workingDirectory, const QString& steamAppID,
- Executable::Flags mask, Executable::Flags flags) {
- QFileInfo file(executableName);
- auto existingExe = findExe(title);
- flags &= mask;
- if (existingExe != m_Executables.end()) {
- existingExe->m_Title = title;
- existingExe->m_Flags &= ~mask;
- existingExe->m_Flags |= flags;
- // for pre-configured executables don't overwrite settings we didn't store
- if (flags & Executable::CustomExecutable) {
- if (file.exists()) {
- // don't overwrite a valid binary with an invalid one
- existingExe->m_BinaryInfo = file;
- }
- existingExe->m_Arguments = arguments;
- existingExe->m_WorkingDirectory = workingDirectory;
- existingExe->m_SteamAppID = steamAppID;
- }
- } else {
- Executable newExe;
- newExe.m_Title = title;
- newExe.m_BinaryInfo = file;
- newExe.m_Arguments = arguments;
- newExe.m_WorkingDirectory = workingDirectory;
- newExe.m_SteamAppID = steamAppID;
- newExe.m_Flags = Executable::CustomExecutable | flags;
- m_Executables.push_back(newExe);
+void ExecutablesList::updateExecutable(const QString &title,
+ const QString &executableName,
+ const QString &arguments,
+ const QString &workingDirectory,
+ const QString &steamAppID,
+ Executable::Flags mask,
+ Executable::Flags flags)
+{
+ QFileInfo file(executableName);
+ auto existingExe = findExe(title);
+ flags &= mask;
+
+ if (existingExe != m_Executables.end()) {
+ existingExe->m_Title = title;
+ existingExe->m_Flags &= ~mask;
+ existingExe->m_Flags |= flags;
+ // for pre-configured executables don't overwrite settings we didn't store
+ if (flags & Executable::CustomExecutable) {
+ if (file.exists()) {
+ // don't overwrite a valid binary with an invalid one
+ existingExe->m_BinaryInfo = file;
+ }
+ existingExe->m_Arguments = arguments;
+ existingExe->m_WorkingDirectory = workingDirectory;
+ existingExe->m_SteamAppID = steamAppID;
}
+ } else {
+ Executable newExe;
+ newExe.m_Title = title;
+ newExe.m_BinaryInfo = file;
+ newExe.m_Arguments = arguments;
+ newExe.m_WorkingDirectory = workingDirectory;
+ newExe.m_SteamAppID = steamAppID;
+ newExe.m_Flags = Executable::CustomExecutable | flags;
+ m_Executables.push_back(newExe);
+ }
}
-void ExecutablesList::remove(const QString& title) {
- for (std::vector<Executable>::iterator iter = m_Executables.begin(); iter != m_Executables.end(); ++iter) {
- if (iter->isCustom() && (iter->m_Title == title)) {
- m_Executables.erase(iter);
- break;
- }
+
+void ExecutablesList::remove(const QString &title)
+{
+ for (std::vector<Executable>::iterator iter = m_Executables.begin(); iter != m_Executables.end(); ++iter) {
+ if (iter->isCustom() && (iter->m_Title == title)) {
+ m_Executables.erase(iter);
+ break;
}
+ }
}
-void ExecutablesList::addExecutableInternal(const QString& title, const QString& executableName,
- const QString& arguments, const QString& workingDirectory,
- const QString& steamAppID) {
- QFileInfo file(executableName);
- if (file.exists()) {
- Executable newExe;
- newExe.m_BinaryInfo = file;
- newExe.m_Title = title;
- newExe.m_Arguments = arguments;
- newExe.m_WorkingDirectory = workingDirectory;
- newExe.m_SteamAppID = steamAppID;
- newExe.m_Flags = Executable::UseApplicationIcon;
- m_Executables.push_back(newExe);
- }
+
+void ExecutablesList::addExecutableInternal(const QString &title, const QString &executableName,
+ const QString &arguments, const QString &workingDirectory,
+ const QString &steamAppID)
+{
+ QFileInfo file(executableName);
+ if (file.exists()) {
+ Executable newExe;
+ newExe.m_BinaryInfo = file;
+ newExe.m_Title = title;
+ newExe.m_Arguments = arguments;
+ newExe.m_WorkingDirectory = workingDirectory;
+ newExe.m_SteamAppID = steamAppID;
+ newExe.m_Flags = Executable::UseApplicationIcon;
+ m_Executables.push_back(newExe);
+ }
}
-void Executable::showOnToolbar(bool state) {
- if (state) {
- m_Flags |= ShowInToolbar;
- } else {
- m_Flags &= ~ShowInToolbar;
- }
+
+void Executable::showOnToolbar(bool state)
+{
+ if (state) {
+ m_Flags |= ShowInToolbar;
+ } else {
+ m_Flags &= ~ShowInToolbar;
+ }
}
diff --git a/src/executableslist.h b/src/executableslist.h
index cb1b1913..0534c09e 100644
--- a/src/executableslist.h
+++ b/src/executableslist.h
@@ -27,160 +27,175 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QFileInfo>
#include <QMetaType>
-namespace MOBase {
-class IPluginGame;
-}
+namespace MOBase { class IPluginGame; }
/*!
* @brief Information about an executable
**/
struct Executable {
- QString m_Title;
- QFileInfo m_BinaryInfo;
- QString m_Arguments;
- QString m_SteamAppID;
- QString m_WorkingDirectory;
+ QString m_Title;
+ QFileInfo m_BinaryInfo;
+ QString m_Arguments;
+ QString m_SteamAppID;
+ QString m_WorkingDirectory;
- enum Flag {
- CustomExecutable = 0x01,
- ShowInToolbar = 0x02,
- UseApplicationIcon = 0x04,
+ enum Flag {
+ CustomExecutable = 0x01,
+ ShowInToolbar = 0x02,
+ UseApplicationIcon = 0x04,
- AllFlags = 0xff // I know, I know
- };
+ AllFlags = 0xff //I know, I know
+ };
- Q_DECLARE_FLAGS(Flags, Flag)
+ Q_DECLARE_FLAGS(Flags, Flag)
- Flags m_Flags;
+ Flags m_Flags;
- bool isCustom() const { return m_Flags.testFlag(CustomExecutable); }
+ bool isCustom() const { return m_Flags.testFlag(CustomExecutable); }
- bool isShownOnToolbar() const { return m_Flags.testFlag(ShowInToolbar); }
+ bool isShownOnToolbar() const { return m_Flags.testFlag(ShowInToolbar); }
- void showOnToolbar(bool state);
+ void showOnToolbar(bool state);
- bool usesOwnIcon() const { return m_Flags.testFlag(UseApplicationIcon); }
+ bool usesOwnIcon() const { return m_Flags.testFlag(UseApplicationIcon); }
};
+
/*!
* @brief List of executables configured to by started from MO
**/
class ExecutablesList {
public:
- /**
- * @brief constructor
- *
- **/
- ExecutablesList();
- ~ExecutablesList();
+ /**
+ * @brief constructor
+ *
+ **/
+ ExecutablesList();
+
+ ~ExecutablesList();
- /**
- * @brief initialise the list with the executables preconfigured for this game
- **/
- void init(MOBase::IPluginGame const* game);
+ /**
+ * @brief initialise the list with the executables preconfigured for this game
+ **/
+ void init(MOBase::IPluginGame const *game);
- /**
- * @brief find an executable by its name
- *
- * @param title the title of the executable to look up
- * @return the executable
- * @exception runtime_error will throw an exception if the name is not correct
- **/
- const Executable& find(const QString& title) const;
+ /**
+ * @brief find an executable by its name
+ *
+ * @param title the title of the executable to look up
+ * @return the executable
+ * @exception runtime_error will throw an exception if the name is not correct
+ **/
+ const Executable &find(const QString &title) const;
- /**
- * @brief find an executable by its name
- *
- * @param title the title of the executable to look up
- * @return the executable
- * @exception runtime_error will throw an exception if the name is not correct
- **/
- Executable& find(const QString& title);
+ /**
+ * @brief find an executable by its name
+ *
+ * @param title the title of the executable to look up
+ * @return the executable
+ * @exception runtime_error will throw an exception if the name is not correct
+ **/
+ Executable &find(const QString &title);
- /**
- * @brief find an executable by a fileinfo structure
- * @param info the info object to search for
- * @return the executable
- * @exception runtime_error will throw an exception if the name is not correct
- */
- Executable& findByBinary(const QFileInfo& info);
+ /**
+ * @brief find an executable by a fileinfo structure
+ * @param info the info object to search for
+ * @return the executable
+ * @exception runtime_error will throw an exception if the name is not correct
+ */
+ Executable &findByBinary(const QFileInfo &info);
- /**
- * @brief determine if an executable exists
- * @param title the title of the executable to look up
- * @return true if the executable exists, false otherwise
- **/
- bool titleExists(const QString& title) const;
+ /**
+ * @brief determine if an executable exists
+ * @param title the title of the executable to look up
+ * @return true if the executable exists, false otherwise
+ **/
+ bool titleExists(const QString &title) const;
- /**
- * @brief add a new executable to the list
- * @param executable
- */
- void addExecutable(const Executable& executable);
+ /**
+ * @brief add a new executable to the list
+ * @param executable
+ */
+ void addExecutable(const Executable &executable);
- /**
- * @brief add a new executable to the list
- *
- * @param title name displayed in the UI
- * @param executableName the actual filename to execute
- * @param arguments arguments to pass to the executable
- **/
- void addExecutable(const QString& title, const QString& executableName, const QString& arguments,
- const QString& workingDirectory, const QString& steamAppID, Executable::Flags flags) {
- updateExecutable(title, executableName, arguments, workingDirectory, steamAppID, Executable::AllFlags, flags);
- }
+ /**
+ * @brief add a new executable to the list
+ *
+ * @param title name displayed in the UI
+ * @param executableName the actual filename to execute
+ * @param arguments arguments to pass to the executable
+ **/
+ void addExecutable(const QString &title,
+ const QString &executableName,
+ const QString &arguments,
+ const QString &workingDirectory,
+ const QString &steamAppID,
+ Executable::Flags flags)
+ {
+ updateExecutable(title, executableName, arguments, workingDirectory,
+ steamAppID, Executable::AllFlags, flags);
+ }
- /**
- * @brief Update an executable to the list
- *
- * @param title name displayed in the UI
- * @param executableName the actual filename to execute
- * @param arguments arguments to pass to the executable
- * @param closeMO if true, MO will be closed when the binary is started
- **/
- void updateExecutable(const QString& title, const QString& executableName, const QString& arguments,
- const QString& workingDirectory, const QString& steamAppID, Executable::Flags mask,
- Executable::Flags flags);
+ /**
+ * @brief Update an executable to the list
+ *
+ * @param title name displayed in the UI
+ * @param executableName the actual filename to execute
+ * @param arguments arguments to pass to the executable
+ * @param closeMO if true, MO will be closed when the binary is started
+ **/
+ void updateExecutable(const QString &title,
+ const QString &executableName,
+ const QString &arguments,
+ const QString &workingDirectory,
+ const QString &steamAppID,
+ Executable::Flags mask,
+ Executable::Flags flags);
- /**
- * @brief remove the executable with the specified file name. This needs to be an absolute file path
- *
- * @param title title of the executable to remove
- * @note if the executable name is invalid, nothing happens. There is no way to determine if this was successful
- **/
- void remove(const QString& title);
+ /**
+ * @brief remove the executable with the specified file name. This needs to be an absolute file path
+ *
+ * @param title title of the executable to remove
+ * @note if the executable name is invalid, nothing happens. There is no way to determine if this was successful
+ **/
+ void remove(const QString &title);
- /**
- * @brief retrieve begin and end iterators of the configured executables
- *
- * @param begin iterator to the first executable
- * @param end iterator one past the last executable
- **/
- void getExecutables(std::vector<Executable>::const_iterator& begin,
- std::vector<Executable>::const_iterator& end) const;
+ /**
+ * @brief retrieve begin and end iterators of the configured executables
+ *
+ * @param begin iterator to the first executable
+ * @param end iterator one past the last executable
+ **/
+ void getExecutables(std::vector<Executable>::const_iterator &begin, std::vector<Executable>::const_iterator &end) const;
- /**
- * @brief retrieve begin and end iterators of the configured executables
- *
- * @param begin iterator to the first executable
- * @param end iterator one past the last executable
- **/
- void getExecutables(std::vector<Executable>::iterator& begin, std::vector<Executable>::iterator& end);
+ /**
+ * @brief retrieve begin and end iterators of the configured executables
+ *
+ * @param begin iterator to the first executable
+ * @param end iterator one past the last executable
+ **/
+ void getExecutables(std::vector<Executable>::iterator &begin, std::vector<Executable>::iterator &end);
- /**
- * @brief get the number of executables (custom or otherwise)
- **/
- size_t size() const { return m_Executables.size(); }
+ /**
+ * @brief get the number of executables (custom or otherwise)
+ **/
+ size_t size() const {
+ return m_Executables.size();
+ }
private:
- std::vector<Executable>::iterator findExe(const QString& title);
- void addExecutableInternal(const QString& title, const QString& executableName, const QString& arguments,
- const QString& workingDirectory, const QString& steamAppID);
+ std::vector<Executable>::iterator findExe(const QString &title);
+
+ void addExecutableInternal(const QString &title, const QString &executableName, const QString &arguments,
+ const QString &workingDirectory,
+ const QString &steamAppID);
private:
- std::vector<Executable> m_Executables;
+
+ std::vector<Executable> m_Executables;
+
};
Q_DECLARE_OPERATORS_FOR_FLAGS(Executable::Flags)
diff --git a/src/filedialogmemory.cpp b/src/filedialogmemory.cpp
index d5ce5f24..6b440d0f 100644
--- a/src/filedialogmemory.cpp
+++ b/src/filedialogmemory.cpp
@@ -20,61 +20,75 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "filedialogmemory.h"
#include <QFileDialog>
-FileDialogMemory::FileDialogMemory() {}
-void FileDialogMemory::save(QSettings& settings) {
- settings.remove("recentDirectories");
- settings.beginWriteArray("recentDirectories");
- int index = 0;
- for (std::map<QString, QString>::const_iterator iter = instance().m_Cache.begin(); iter != instance().m_Cache.end();
- ++iter) {
- settings.setArrayIndex(index++);
- settings.setValue("name", iter->first);
- settings.setValue("directory", iter->second);
- }
- settings.endArray();
+FileDialogMemory::FileDialogMemory()
+{
}
-void FileDialogMemory::restore(QSettings& settings) {
- int size = settings.beginReadArray("recentDirectories");
- for (int i = 0; i < size; ++i) {
- settings.setArrayIndex(i);
- QVariant name = settings.value("name");
- QVariant dir = settings.value("directory");
- if (name.isValid() && dir.isValid()) {
- instance().m_Cache.insert(std::make_pair(name.toString(), dir.toString()));
- }
- }
- settings.endArray();
+
+void FileDialogMemory::save(QSettings &settings)
+{
+ settings.remove("recentDirectories");
+ settings.beginWriteArray("recentDirectories");
+ int index = 0;
+ for (std::map<QString, QString>::const_iterator iter = instance().m_Cache.begin();
+ iter != instance().m_Cache.end(); ++iter) {
+ settings.setArrayIndex(index++);
+ settings.setValue("name", iter->first);
+ settings.setValue("directory", iter->second);
+ }
+ settings.endArray();
}
-QString FileDialogMemory::getOpenFileName(const QString& dirID, QWidget* parent, const QString& caption,
- const QString& dir, const QString& filter, QString* selectedFilter,
- QFileDialog::Options options) {
- std::pair<std::map<QString, QString>::iterator, bool> currentDir =
- instance().m_Cache.insert(std::make_pair(dirID, dir));
- QString result =
- QFileDialog::getOpenFileName(parent, caption, currentDir.first->second, filter, selectedFilter, options);
- if (!result.isNull()) {
- instance().m_Cache[dirID] = QFileInfo(result).path();
+void FileDialogMemory::restore(QSettings &settings)
+{
+ int size = settings.beginReadArray("recentDirectories");
+ for (int i = 0; i < size; ++i) {
+ settings.setArrayIndex(i);
+ QVariant name = settings.value("name");
+ QVariant dir = settings.value("directory");
+ if (name.isValid() && dir.isValid()) {
+ instance().m_Cache.insert(std::make_pair(name.toString(), dir.toString()));
}
- return result;
+ }
+ settings.endArray();
}
-QString FileDialogMemory::getExistingDirectory(const QString& dirID, QWidget* parent, const QString& caption,
- const QString& dir, QFileDialog::Options options) {
- std::pair<std::map<QString, QString>::iterator, bool> currentDir =
- instance().m_Cache.insert(std::make_pair(dirID, dir));
- QString result = QFileDialog::getExistingDirectory(parent, caption, currentDir.first->second, options);
- if (!result.isNull()) {
- instance().m_Cache[dirID] = QFileInfo(result).path();
- }
- return result;
+QString FileDialogMemory::getOpenFileName(const QString &dirID, QWidget *parent,
+ const QString &caption, const QString &dir,
+ const QString &filter, QString *selectedFilter,
+ QFileDialog::Options options)
+{
+ std::pair<std::map<QString, QString>::iterator, bool> currentDir =
+ instance().m_Cache.insert(std::make_pair(dirID, dir));
+
+ QString result = QFileDialog::getOpenFileName(parent, caption, currentDir.first->second,
+ filter, selectedFilter, options);
+ if (!result.isNull()) {
+ instance().m_Cache[dirID] = QFileInfo(result).path();
+ }
+ return result;
}
-FileDialogMemory& FileDialogMemory::instance() {
- static FileDialogMemory instance;
- return instance;
+
+QString FileDialogMemory::getExistingDirectory(const QString &dirID, QWidget *parent,
+ const QString &caption, const QString &dir, QFileDialog::Options options)
+{
+ std::pair<std::map<QString, QString>::iterator, bool> currentDir =
+ instance().m_Cache.insert(std::make_pair(dirID, dir));
+
+ QString result = QFileDialog::getExistingDirectory(parent, caption, currentDir.first->second, options);
+ if (!result.isNull()) {
+ instance().m_Cache[dirID] = QFileInfo(result).path();
+ }
+ return result;
+}
+
+
+FileDialogMemory &FileDialogMemory::instance()
+{
+ static FileDialogMemory instance;
+ return instance;
}
diff --git a/src/filedialogmemory.h b/src/filedialogmemory.h
index d853bd51..b2bfdb53 100644
--- a/src/filedialogmemory.h
+++ b/src/filedialogmemory.h
@@ -20,32 +20,39 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef FILEDIALOGMEMORY_H
#define FILEDIALOGMEMORY_H
-#include <QFileDialog>
-#include <QSettings>
-#include <QString>
+
#include <map>
+#include <QString>
+#include <QSettings>
+#include <QFileDialog>
+
-class FileDialogMemory {
+class FileDialogMemory
+{
public:
- static void save(QSettings& settings);
- static void restore(QSettings& settings);
- static QString getOpenFileName(const QString& dirID, QWidget* parent = 0, const QString& caption = QString(),
- const QString& dir = QString(), const QString& filter = QString(),
- QString* selectedFilter = 0, QFileDialog::Options options = 0);
+ static void save(QSettings &settings);
+ static void restore(QSettings &settings);
+
+ static QString getOpenFileName(const QString &dirID, QWidget *parent = 0, const QString &caption = QString(),
+ const QString &dir = QString(), const QString &filter = QString(),
+ QString *selectedFilter = 0, QFileDialog::Options options = 0);
- static QString getExistingDirectory(const QString& dirID, QWidget* parent = 0, const QString& caption = QString(),
- const QString& dir = QString(),
- QFileDialog::Options options = QFileDialog::ShowDirsOnly);
+ static QString getExistingDirectory(const QString &dirID, QWidget *parent = 0, const QString &caption = QString(),
+ const QString &dir = QString(),
+ QFileDialog::Options options = QFileDialog::ShowDirsOnly);
private:
- FileDialogMemory();
- static FileDialogMemory& instance();
+ FileDialogMemory();
+
+ static FileDialogMemory &instance();
private:
- std::map<QString, QString> m_Cache;
+
+ std::map<QString, QString> m_Cache;
+
};
#endif // FILEDIALOGMEMORY_H
diff --git a/src/gameinfoimpl.cpp b/src/gameinfoimpl.cpp
index 56f4749c..61a4c523 100644
--- a/src/gameinfoimpl.cpp
+++ b/src/gameinfoimpl.cpp
@@ -18,36 +18,39 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "gameinfoimpl.h"
-#include <QDir>
#include <gameinfo.h>
#include <utility.h>
+#include <QDir>
+
using namespace MOBase;
using namespace MOShared;
-GameInfoImpl::GameInfoImpl() {}
-IGameInfo::Type GameInfoImpl::type() const {
- switch (GameInfo::instance().getType()) {
- case GameInfo::TYPE_OBLIVION:
- return IGameInfo::TYPE_OBLIVION;
- case GameInfo::TYPE_FALLOUT3:
- return IGameInfo::TYPE_FALLOUT3;
- case GameInfo::TYPE_FALLOUT4:
- return IGameInfo::TYPE_FALLOUT4;
- case GameInfo::TYPE_FALLOUTNV:
- return IGameInfo::TYPE_FALLOUTNV;
- case GameInfo::TYPE_SKYRIM:
- return IGameInfo::TYPE_SKYRIM;
- case GameInfo::TYPE_SKYRIMSE:
- return IGameInfo::TYPE_SKYRIMSE;
- default:
- throw MyException(QObject::tr("invalid game type %1").arg(GameInfo::instance().getType()));
- }
+GameInfoImpl::GameInfoImpl()
+{
}
-QString GameInfoImpl::path() const {
- return QDir::fromNativeSeparators(ToQString(GameInfo::instance().getGameDirectory()));
+IGameInfo::Type GameInfoImpl::type() const
+{
+ switch (GameInfo::instance().getType()) {
+ case GameInfo::TYPE_OBLIVION: return IGameInfo::TYPE_OBLIVION;
+ case GameInfo::TYPE_FALLOUT3: return IGameInfo::TYPE_FALLOUT3;
+ case GameInfo::TYPE_FALLOUT4: return IGameInfo::TYPE_FALLOUT4;
+ case GameInfo::TYPE_FALLOUTNV: return IGameInfo::TYPE_FALLOUTNV;
+ case GameInfo::TYPE_SKYRIM: return IGameInfo::TYPE_SKYRIM;
+ case GameInfo::TYPE_SKYRIMSE: return IGameInfo::TYPE_SKYRIMSE;
+ default: throw MyException(QObject::tr("invalid game type %1").arg(GameInfo::instance().getType()));
+ }
}
-QString GameInfoImpl::binaryName() const { return ToQString(GameInfo::instance().getBinaryName()); }
+
+QString GameInfoImpl::path() const
+{
+ return QDir::fromNativeSeparators(ToQString(GameInfo::instance().getGameDirectory()));
+}
+
+QString GameInfoImpl::binaryName() const
+{
+ return ToQString(GameInfo::instance().getBinaryName());
+}
diff --git a/src/genericicondelegate.cpp b/src/genericicondelegate.cpp
index 98917c33..1e00f0e9 100644
--- a/src/genericicondelegate.cpp
+++ b/src/genericicondelegate.cpp
@@ -3,25 +3,37 @@
#include <QList>
#include <QPixmapCache>
-GenericIconDelegate::GenericIconDelegate(QObject* parent, int role, int logicalIndex, int compactSize)
- : IconDelegate(parent), m_Role(role), m_LogicalIndex(logicalIndex), m_CompactSize(compactSize), m_Compact(false) {}
-void GenericIconDelegate::columnResized(int logicalIndex, int, int newSize) {
- if (logicalIndex == m_LogicalIndex) {
- m_Compact = newSize < m_CompactSize;
- }
+GenericIconDelegate::GenericIconDelegate(QObject *parent, int role, int logicalIndex, int compactSize)
+ : IconDelegate(parent)
+ , m_Role(role)
+ , m_LogicalIndex(logicalIndex)
+ , m_CompactSize(compactSize)
+ , m_Compact(false)
+{
+}
+
+void GenericIconDelegate::columnResized(int logicalIndex, int, int newSize)
+{
+ if (logicalIndex == m_LogicalIndex) {
+ m_Compact = newSize < m_CompactSize;
+ }
}
-QList<QString> GenericIconDelegate::getIcons(const QModelIndex& index) const {
- QList<QString> result;
- if (index.isValid()) {
- for (const QVariant& var : index.data(m_Role).toList()) {
- if (!m_Compact || !var.toString().isEmpty()) {
- result.append(var.toString());
- }
- }
+QList<QString> GenericIconDelegate::getIcons(const QModelIndex &index) const
+{
+ QList<QString> result;
+ if (index.isValid()) {
+ for (const QVariant &var : index.data(m_Role).toList()) {
+ if (!m_Compact || !var.toString().isEmpty()) {
+ result.append(var.toString());
+ }
}
- return result;
+ }
+ return result;
}
-size_t GenericIconDelegate::getNumIcons(const QModelIndex& index) const { return index.data(m_Role).toList().count(); }
+size_t GenericIconDelegate::getNumIcons(const QModelIndex &index) const
+{
+ return index.data(m_Role).toList().count();
+}
diff --git a/src/genericicondelegate.h b/src/genericicondelegate.h
index e6ddddc3..98605250 100644
--- a/src/genericicondelegate.h
+++ b/src/genericicondelegate.h
@@ -6,34 +6,31 @@
/**
* @brief an icon delegate that takes the list of icons from a user-defines data role
*/
-class GenericIconDelegate : public IconDelegate {
- Q_OBJECT
+class GenericIconDelegate : public IconDelegate
+{
+Q_OBJECT
public:
- /**
- * @brief constructor
- * @param parent parent object
- * @param role role of the itemmodel from which the icon list can be queried (as a QVariantList)
- * @param logicalIndex logical index within the model. This is part of a "hack". Normally "empty" icons will be
- * allocated the same space as a regular icon. This way the model can use empty icons as spacers and thus align same
- * icons horizontally. Now, if you set the logical Index to a valid column and connect the
- * columnResized slot to the sectionResized signal of the view, the delegate will turn off this
- * behaviour if the column is smaller than "compactSize"
- * @param compactSize see explanation of logicalIndex
- */
- GenericIconDelegate(QObject* parent = nullptr, int role = Qt::UserRole + 1, int logicalIndex = -1,
- int compactSize = 150);
+ /**
+ * @brief constructor
+ * @param parent parent object
+ * @param role role of the itemmodel from which the icon list can be queried (as a QVariantList)
+ * @param logicalIndex logical index within the model. This is part of a "hack". Normally "empty" icons will be allocated the same
+ * space as a regular icon. This way the model can use empty icons as spacers and thus align same icons horizontally.
+ * Now, if you set the logical Index to a valid column and connect the columnResized slot to the sectionResized signal
+ * of the view, the delegate will turn off this behaviour if the column is smaller than "compactSize"
+ * @param compactSize see explanation of logicalIndex
+ */
+ GenericIconDelegate(QObject *parent = nullptr, int role = Qt::UserRole + 1, int logicalIndex = -1, int compactSize = 150);
public slots:
- void columnResized(int logicalIndex, int oldSize, int newSize);
-
+ void columnResized(int logicalIndex, int oldSize, int newSize);
private:
- virtual QList<QString> getIcons(const QModelIndex& index) const;
- virtual size_t getNumIcons(const QModelIndex& index) const;
-
+ virtual QList<QString> getIcons(const QModelIndex &index) const;
+ virtual size_t getNumIcons(const QModelIndex &index) const;
private:
- int m_Role;
- int m_LogicalIndex;
- int m_CompactSize;
- bool m_Compact;
+ int m_Role;
+ int m_LogicalIndex;
+ int m_CompactSize;
+ bool m_Compact;
};
#endif // GENERICICONDELEGATE_H
diff --git a/src/helper.cpp b/src/helper.cpp
index 172cf2a2..b7fc866c 100644
--- a/src/helper.cpp
+++ b/src/helper.cpp
@@ -19,8 +19,8 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "helper.h"
#include "utility.h"
-#include <LMCons.h>
#include <report.h>
+#include <LMCons.h>
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
@@ -29,61 +29,71 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
using MOBase::reportError;
+
namespace Helper {
-static bool helperExec(LPCWSTR moDirectory, LPCWSTR commandLine) {
- wchar_t fileName[MAX_PATH];
- _snwprintf(fileName, MAX_PATH, L"%ls\\helper.exe", moDirectory);
- SHELLEXECUTEINFOW execInfo = {0};
+static bool helperExec(LPCWSTR moDirectory, LPCWSTR commandLine)
+{
+ wchar_t fileName[MAX_PATH];
+ _snwprintf(fileName, MAX_PATH, L"%ls\\helper.exe", moDirectory);
+
+ SHELLEXECUTEINFOW execInfo = {0};
- execInfo.cbSize = sizeof(SHELLEXECUTEINFOW);
- execInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
- execInfo.hwnd = nullptr;
- execInfo.lpVerb = L"runas";
- execInfo.lpFile = fileName;
- execInfo.lpParameters = commandLine;
- execInfo.lpDirectory = moDirectory;
- execInfo.nShow = SW_SHOW;
+ execInfo.cbSize = sizeof(SHELLEXECUTEINFOW);
+ execInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
+ execInfo.hwnd = nullptr;
+ execInfo.lpVerb = L"runas";
+ execInfo.lpFile = fileName;
+ execInfo.lpParameters = commandLine;
+ execInfo.lpDirectory = moDirectory;
+ execInfo.nShow = SW_SHOW;
- ::ShellExecuteExW(&execInfo);
+ ::ShellExecuteExW(&execInfo);
- if ((execInfo.hProcess == 0) || (::WaitForSingleObject(execInfo.hProcess, INFINITE) != WAIT_OBJECT_0)) {
- reportError(QObject::tr("helper failed"));
- return false;
- }
+ if ((execInfo.hProcess == 0) || (::WaitForSingleObject(execInfo.hProcess, INFINITE) != WAIT_OBJECT_0)) {
+ reportError(QObject::tr("helper failed"));
+ return false;
+ }
- DWORD exitCode;
- GetExitCodeProcess(execInfo.hProcess, &exitCode);
- return exitCode == NOERROR;
+ DWORD exitCode;
+ GetExitCodeProcess(execInfo.hProcess, &exitCode);
+ return exitCode == NOERROR;
}
-bool init(const std::wstring& moPath, const std::wstring& dataPath) {
- DWORD userNameLen = UNLEN + 1;
- wchar_t userName[UNLEN + 1];
- if (!GetUserName(userName, &userNameLen)) {
- reportError(QObject::tr("failed to determine account name"));
- return false;
- }
- wchar_t* commandLine = new wchar_t[32768];
+bool init(const std::wstring &moPath, const std::wstring &dataPath)
+{
+ DWORD userNameLen = UNLEN + 1;
+ wchar_t userName[UNLEN + 1];
- _snwprintf(commandLine, 32768, L"init \"%ls\" \"%ls\"", dataPath.c_str(), userName);
+ if (!GetUserName(userName, &userNameLen)) {
+ reportError(QObject::tr("failed to determine account name"));
+ return false;
+ }
+ wchar_t *commandLine = new wchar_t[32768];
- bool res = helperExec(moPath.c_str(), commandLine);
- delete[] commandLine;
+ _snwprintf(commandLine, 32768, L"init \"%ls\" \"%ls\"",
+ dataPath.c_str(), userName);
- return res;
+ bool res = helperExec(moPath.c_str(), commandLine);
+ delete [] commandLine;
+
+ return res;
}
-bool backdateBSAs(const std::wstring& moPath, const std::wstring& dataPath) {
- wchar_t* commandLine = new wchar_t[32768];
- _snwprintf(commandLine, 32768, L"backdateBSA \"%ls\"", dataPath.c_str());
- bool res = helperExec(moPath.c_str(), commandLine);
- delete[] commandLine;
+bool backdateBSAs(const std::wstring &moPath, const std::wstring &dataPath)
+{
+ wchar_t *commandLine = new wchar_t[32768];
+ _snwprintf(commandLine, 32768, L"backdateBSA \"%ls\"",
+ dataPath.c_str());
+
+ bool res = helperExec(moPath.c_str(), commandLine);
+ delete [] commandLine;
- return res;
+ return res;
}
-} // namespace Helper
+
+} // namespace
diff --git a/src/helper.h b/src/helper.h
index 738950a2..cd4b7883 100644
--- a/src/helper.h
+++ b/src/helper.h
@@ -20,11 +20,13 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef HELPER_H
#define HELPER_H
+
#include <string>
+
/**
* @brief Convenience functions to work with the external helper program.
- *
+ *
* The mo_helper program is used to make changes on the system that require administrative
* rights, so that ModOrganizer itself can run without special privileges
**/
@@ -32,22 +34,23 @@ namespace Helper {
/**
* @brief initialise the specified directory for use with mod organizer.
- *
+ *
* This will create all required sub-directories and give the user running ModOrganizer
* write-access
*
* @param moPath absolute path to the ModOrganizer base directory
* @return true on success
**/
-bool init(const std::wstring& moPath, const std::wstring& dataPath);
+bool init(const std::wstring &moPath, const std::wstring &dataPath);
/**
* @brief sets the last modified time for all .bsa-files in the target directory well into the past
* @param moPath absolute path to the modOrganizer base directory
* @param dataPath the path taht contains the .bsa-files, usually the data directory of the game
**/
-bool backdateBSAs(const std::wstring& moPath, const std::wstring& dataPath);
+bool backdateBSAs(const std::wstring &moPath, const std::wstring &dataPath);
+
+}
-} // namespace Helper
#endif // HELPER_H
diff --git a/src/icondelegate.cpp b/src/icondelegate.cpp
index 4125210a..e502dc69 100644
--- a/src/icondelegate.cpp
+++ b/src/icondelegate.cpp
@@ -18,43 +18,50 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "icondelegate.h"
-#include <QDebug>
#include <QHBoxLayout>
#include <QLabel>
#include <QPainter>
+#include <QDebug>
#include <QPixmapCache>
-IconDelegate::IconDelegate(QObject* parent) : QStyledItemDelegate(parent) {}
-void IconDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
- QStyledItemDelegate::paint(painter, option, index);
+IconDelegate::IconDelegate(QObject *parent)
+ : QStyledItemDelegate(parent)
+{
+}
+
- QList<QString> icons = getIcons(index);
+void IconDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ QStyledItemDelegate::paint(painter, option, index);
- int x = 4;
- painter->save();
+ QList<QString> icons = getIcons(index);
- int iconWidth = icons.size() > 0 ? ((option.rect.width() / icons.size()) - 4) : 16;
- iconWidth = std::min(16, iconWidth);
+ int x = 4;
+ painter->save();
- painter->translate(option.rect.topLeft());
- for (const QString& iconId : icons) {
- if (iconId.isEmpty()) {
- x += iconWidth + 4;
- continue;
- }
- QPixmap icon;
- QString fullIconId = QString("%1_%2").arg(iconId).arg(iconWidth);
- if (!QPixmapCache::find(fullIconId, &icon)) {
- icon = QIcon(iconId).pixmap(iconWidth, iconWidth);
- if (icon.isNull()) {
- qWarning("failed to load icon %s", qPrintable(iconId));
- }
- QPixmapCache::insert(fullIconId, icon);
- }
- painter->drawPixmap(x, 2, iconWidth, iconWidth, icon);
- x += iconWidth + 4;
+ int iconWidth = icons.size() > 0 ? ((option.rect.width() / icons.size()) - 4) : 16;
+ iconWidth = std::min(16, iconWidth);
+
+ painter->translate(option.rect.topLeft());
+ for (const QString &iconId : icons) {
+ if (iconId.isEmpty()) {
+ x += iconWidth + 4;
+ continue;
+ }
+ QPixmap icon;
+ QString fullIconId = QString("%1_%2").arg(iconId).arg(iconWidth);
+ if (!QPixmapCache::find(fullIconId, &icon)) {
+ icon = QIcon(iconId).pixmap(iconWidth, iconWidth);
+ if (icon.isNull()) {
+ qWarning("failed to load icon %s", qPrintable(iconId));
+ }
+ QPixmapCache::insert(fullIconId, icon);
}
+ painter->drawPixmap(x, 2, iconWidth, iconWidth, icon);
+ x += iconWidth + 4;
+ }
- painter->restore();
+ painter->restore();
}
+
diff --git a/src/icondelegate.h b/src/icondelegate.h
index c0c28388..39694481 100644
--- a/src/icondelegate.h
+++ b/src/icondelegate.h
@@ -21,25 +21,31 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#define ICONDELEGATE_H
#include "modinfo.h"
-#include <QAbstractProxyModel>
#include <QStyledItemDelegate>
+#include <QAbstractProxyModel>
-class IconDelegate : public QStyledItemDelegate {
- Q_OBJECT
+
+class IconDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
public:
- explicit IconDelegate(QObject* parent = 0);
- virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
+ explicit IconDelegate(QObject *parent = 0);
-signals:
+ virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+signals:
+
public slots:
private:
- virtual QList<QString> getIcons(const QModelIndex& index) const = 0;
- virtual size_t getNumIcons(const QModelIndex& index) const = 0;
+
+ virtual QList<QString> getIcons(const QModelIndex &index) const = 0;
+ virtual size_t getNumIcons(const QModelIndex &index) const = 0;
+
private:
+
};
#endif // ICONDELEGATE_H
diff --git a/src/ilockedwaitingforprocess.h b/src/ilockedwaitingforprocess.h
index 5f933417..9475ddb9 100644
--- a/src/ilockedwaitingforprocess.h
+++ b/src/ilockedwaitingforprocess.h
@@ -3,10 +3,11 @@
class QString;
-class ILockedWaitingForProcess {
+class ILockedWaitingForProcess
+{
public:
- virtual bool unlockForced() const = 0;
- virtual void setProcessName(QString const&) = 0;
+ virtual bool unlockForced() const = 0;
+ virtual void setProcessName(QString const &) = 0;
};
#endif // ILOCKEDWAITINGFORPROCESS_H
diff --git a/src/installationmanager.cpp b/src/installationmanager.cpp
index 48faecc1..9a70f8bd 100644
--- a/src/installationmanager.cpp
+++ b/src/installationmanager.cpp
@@ -19,34 +19,35 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "installationmanager.h"
+#include "utility.h"
+#include "report.h"
#include "categories.h"
-#include "iplugininstallercustom.h"
-#include "iplugininstallersimple.h"
+#include "questionboxmemory.h"
+#include "settings.h"
+#include "queryoverwritedialog.h"
#include "messagedialog.h"
-#include "modinfo.h"
+#include "iplugininstallersimple.h"
+#include "iplugininstallercustom.h"
#include "nexusinterface.h"
-#include "queryoverwritedialog.h"
-#include "questionboxmemory.h"
-#include "report.h"
#include "selectiondialog.h"
-#include "settings.h"
-#include "utility.h"
-#include <installationtester.h>
+#include "modinfo.h"
#include <scopeguard.h>
+#include <installationtester.h>
#include <utility.h>
+#include <scopeguard.h>
-#include <QApplication>
-#include <QDateTime>
-#include <QDebug>
-#include <QDir>
-#include <QDirIterator>
#include <QFileInfo>
-#include <QInputDialog>
#include <QLibrary>
-#include <QMessageBox>
-#include <QPushButton>
+#include <QInputDialog>
#include <QRegExp>
+#include <QDir>
+#include <QMessageBox>
#include <QSettings>
+#include <QPushButton>
+#include <QApplication>
+#include <QDateTime>
+#include <QDirIterator>
+#include <QDebug>
#include <QTextDocument>
#include <Shellapi.h>
@@ -54,743 +55,822 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <boost/assign.hpp>
#include <boost/scoped_ptr.hpp>
+
using namespace MOBase;
using namespace MOShared;
+
typedef Archive* (*CreateArchiveType)();
+
+
template <typename T>
-static T resolveFunction(QLibrary& lib, const char* name) {
- T temp = reinterpret_cast<T>(lib.resolve(name));
- if (temp == nullptr) {
- throw std::runtime_error(QObject::tr("invalid 7-zip32.dll: %1").arg(lib.errorString()).toLatin1().constData());
- }
- return temp;
+static T resolveFunction(QLibrary &lib, const char *name)
+{
+ T temp = reinterpret_cast<T>(lib.resolve(name));
+ if (temp == nullptr) {
+ throw std::runtime_error(QObject::tr("invalid 7-zip32.dll: %1")
+ .arg(lib.errorString())
+ .toLatin1()
+ .constData());
+ }
+ return temp;
}
InstallationManager::InstallationManager()
- : m_ParentWidget(nullptr), m_SupportedExtensions({"zip", "rar", "7z", "fomod", "001"}) {
- QLibrary archiveLib(QCoreApplication::applicationDirPath() + "\\dlls\\archive.dll");
- if (!archiveLib.load()) {
- throw MyException(QObject::tr("archive.dll not loaded: \"%1\"").arg(archiveLib.errorString()));
- }
+ : m_ParentWidget(nullptr),
+ m_SupportedExtensions({"zip", "rar", "7z", "fomod", "001"}) {
+ QLibrary archiveLib(QCoreApplication::applicationDirPath() +
+ "\\dlls\\archive.dll");
+ if (!archiveLib.load()) {
+ throw MyException(QObject::tr("archive.dll not loaded: \"%1\"")
+ .arg(archiveLib.errorString()));
+ }
- CreateArchiveType CreateArchiveFunc = resolveFunction<CreateArchiveType>(archiveLib, "CreateArchive");
+ CreateArchiveType CreateArchiveFunc
+ = resolveFunction<CreateArchiveType>(archiveLib, "CreateArchive");
- m_ArchiveHandler = CreateArchiveFunc();
- if (!m_ArchiveHandler->isValid()) {
- throw MyException(getErrorString(m_ArchiveHandler->getLastError()));
- }
+ m_ArchiveHandler = CreateArchiveFunc();
+ if (!m_ArchiveHandler->isValid()) {
+ throw MyException(getErrorString(m_ArchiveHandler->getLastError()));
+ }
}
-InstallationManager::~InstallationManager() { delete m_ArchiveHandler; }
+InstallationManager::~InstallationManager()
+{
+ delete m_ArchiveHandler;
+}
-void InstallationManager::setParentWidget(QWidget* widget) {
- for (IPluginInstaller* installer : m_Installers) {
- installer->setParentWidget(widget);
- }
+void InstallationManager::setParentWidget(QWidget *widget)
+{
+ for (IPluginInstaller *installer : m_Installers) {
+ installer->setParentWidget(widget);
+ }
}
-void InstallationManager::setURL(QString const& url) { m_URL = url; }
+void InstallationManager::setURL(QString const &url)
+{
+ m_URL = url;
+}
-void InstallationManager::queryPassword(QString* password) {
- *password = QInputDialog::getText(nullptr, tr("Password required"), tr("Password"), QLineEdit::Password);
+void InstallationManager::queryPassword(QString *password)
+{
+ *password = QInputDialog::getText(nullptr, tr("Password required"),
+ tr("Password"), QLineEdit::Password);
}
-void InstallationManager::mapToArchive(const DirectoryTree::Node* node, QString path, FileData* const* data) {
- if (path.length() > 0) {
- // when using a long windows path (starting with \\?\) we apparently can have redundant
- // . components in the path. This wasn't a problem with "regular" path names.
- if (path == ".") {
- path.clear();
- } else {
- path.append("\\");
- }
+void InstallationManager::mapToArchive(const DirectoryTree::Node *node, QString path, FileData * const *data)
+{
+ if (path.length() > 0) {
+ // when using a long windows path (starting with \\?\) we apparently can have redundant
+ // . components in the path. This wasn't a problem with "regular" path names.
+ if (path == ".") {
+ path.clear();
+ } else {
+ path.append("\\");
}
+ }
- for (DirectoryTree::const_leaf_iterator iter = node->leafsBegin(); iter != node->leafsEnd(); ++iter) {
- data[iter->getIndex()]->addOutputFileName(path + iter->getName().toQString());
- }
+ for (DirectoryTree::const_leaf_iterator iter = node->leafsBegin(); iter != node->leafsEnd(); ++iter) {
+ data[iter->getIndex()]->addOutputFileName(path + iter->getName().toQString());
+ }
- for (DirectoryTree::const_node_iterator iter = node->nodesBegin(); iter != node->nodesEnd(); ++iter) {
- QString temp = path + (*iter)->getData().name.toQString();
- if ((*iter)->getData().index != -1) {
- data[(*iter)->getData().index]->addOutputFileName(temp);
- }
- mapToArchive(*iter, temp, data);
+ for (DirectoryTree::const_node_iterator iter = node->nodesBegin(); iter != node->nodesEnd(); ++iter) {
+ QString temp = path + (*iter)->getData().name.toQString();
+ if ((*iter)->getData().index != -1) {
+ data[(*iter)->getData().index]->addOutputFileName(temp);
}
+ mapToArchive(*iter, temp, data);
+ }
}
-void InstallationManager::mapToArchive(const DirectoryTree::Node* baseNode) {
- FileData* const* data;
- size_t size;
- m_ArchiveHandler->getFileList(data, size);
- mapToArchive(baseNode, "", data);
+void InstallationManager::mapToArchive(const DirectoryTree::Node *baseNode)
+{
+ FileData* const *data;
+ size_t size;
+ m_ArchiveHandler->getFileList(data, size);
+
+ mapToArchive(baseNode, "", data);
}
-bool InstallationManager::unpackSingleFile(const QString& fileName) {
- FileData* const* data;
- size_t size;
- m_ArchiveHandler->getFileList(data, size);
- QString baseName = QFileInfo(fileName).fileName();
+bool InstallationManager::unpackSingleFile(const QString &fileName)
+{
+ FileData* const *data;
+ size_t size;
+ m_ArchiveHandler->getFileList(data, size);
- bool available = false;
- for (size_t i = 0; i < size; ++i) {
- if (data[i]->getFileName().compare(fileName, Qt::CaseInsensitive) == 0) {
- available = true;
- data[i]->addOutputFileName(baseName);
- m_TempFilesToDelete.insert(baseName);
- }
- }
+ QString baseName = QFileInfo(fileName).fileName();
- if (!available) {
- return false;
+ bool available = false;
+ for (size_t i = 0; i < size; ++i) {
+ if (data[i]->getFileName().compare(fileName, Qt::CaseInsensitive) == 0) {
+ available = true;
+ data[i]->addOutputFileName(baseName);
+ m_TempFilesToDelete.insert(baseName);
}
+ }
- m_InstallationProgress = new QProgressDialog(m_ParentWidget);
- ON_BLOCK_EXIT([this]() {
- m_InstallationProgress->hide();
- m_InstallationProgress->deleteLater();
- m_InstallationProgress = nullptr;
- });
- m_InstallationProgress->setWindowFlags(m_InstallationProgress->windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ if (!available) {
+ return false;
+ }
- m_InstallationProgress->setWindowTitle(tr("Extracting files"));
- m_InstallationProgress->setWindowModality(Qt::WindowModal);
- m_InstallationProgress->setFixedSize(600, 100);
- m_InstallationProgress->show();
+ m_InstallationProgress = new QProgressDialog(m_ParentWidget);
+ ON_BLOCK_EXIT([this] () {
+ m_InstallationProgress->hide();
+ m_InstallationProgress->deleteLater();
+ m_InstallationProgress = nullptr;
+ });
+ m_InstallationProgress->setWindowFlags(
+ m_InstallationProgress->windowFlags() & ~Qt::WindowContextHelpButtonHint);
- bool res = m_ArchiveHandler->extract(
- QDir::tempPath(),
- new MethodCallback<InstallationManager, void, float>(this, &InstallationManager::updateProgress), nullptr,
- new MethodCallback<InstallationManager, void, QString const&>(this, &InstallationManager::report7ZipError));
+ m_InstallationProgress->setWindowTitle(tr("Extracting files"));
+ m_InstallationProgress->setWindowModality(Qt::WindowModal);
+ m_InstallationProgress->setFixedSize(600, 100);
+ m_InstallationProgress->show();
- return res;
-}
+ bool res = m_ArchiveHandler->extract(QDir::tempPath(),
+ new MethodCallback<InstallationManager, void, float>(this, &InstallationManager::updateProgress),
+ nullptr,
+ new MethodCallback<InstallationManager, void, QString const &>(this, &InstallationManager::report7ZipError));
-QString InstallationManager::extractFile(const QString& fileName) {
- if (unpackSingleFile(fileName)) {
- return QDir::tempPath() + "/" + QFileInfo(fileName).fileName();
- } else {
- return QString();
- }
+ return res;
}
-static QString canonicalize(const QString& name) {
- QString result(name);
- if ((result.startsWith('/')) || (result.startsWith('\\'))) {
- result.remove(0, 1);
- }
- result.replace('/', '\\');
- return result;
+QString InstallationManager::extractFile(const QString &fileName)
+{
+ if (unpackSingleFile(fileName)) {
+ return QDir::tempPath() + "/" + QFileInfo(fileName).fileName();
+ } else {
+ return QString();
+ }
}
-QStringList InstallationManager::extractFiles(const QStringList& filesOrig, bool flatten) {
- QStringList files;
- for (const QString& file : filesOrig) {
- files.append(canonicalize(file));
- }
+static QString canonicalize(const QString &name)
+{
+ QString result(name);
+ if ((result.startsWith('/')) ||
+ (result.startsWith('\\'))) {
+ result.remove(0, 1);
+ }
+ result.replace('/', '\\');
- QStringList result;
+ return result;
+}
- FileData* const* data;
- size_t size;
- m_ArchiveHandler->getFileList(data, size);
- for (size_t i = 0; i < size; ++i) {
- // FIXME Use qstring all the way through
- if (files.contains(data[i]->getFileName(), Qt::CaseInsensitive)) {
- std::wstring temp = data[i]->getFileName().toStdWString();
- wchar_t const* const origFile = temp.c_str();
- const wchar_t* targetFile = origFile;
- // Note: I don't think 'flatten' is ever set to true. so this code
- // might never be executed
- if (flatten) {
- targetFile = wcsrchr(origFile /*data[i]->getFileName()*/, '\\');
- if (targetFile == nullptr) {
- targetFile = wcsrchr(origFile /*data[i]->getFileName()*/, '/');
- }
- if (targetFile == nullptr) {
- qCritical() << "Failed to find backslash in " << data[i]->getFileName();
- continue;
- } else {
- // skip the slash
- ++targetFile;
- }
- }
- data[i]->addOutputFileName(ToQString(targetFile));
+QStringList InstallationManager::extractFiles(const QStringList &filesOrig, bool flatten)
+{
+ QStringList files;
- result.append(QDir::tempPath().append("/").append(ToQString(targetFile)));
+ for (const QString &file : filesOrig) {
+ files.append(canonicalize(file));
+ }
- m_TempFilesToDelete.insert(ToQString(targetFile));
+ QStringList result;
+
+ FileData* const *data;
+ size_t size;
+ m_ArchiveHandler->getFileList(data, size);
+
+ for (size_t i = 0; i < size; ++i) {
+ //FIXME Use qstring all the way through
+ if (files.contains(data[i]->getFileName(), Qt::CaseInsensitive)) {
+ std::wstring temp = data[i]->getFileName().toStdWString();
+ wchar_t const * const origFile = temp.c_str();
+ const wchar_t *targetFile = origFile;
+ //Note: I don't think 'flatten' is ever set to true. so this code
+ //might never be executed
+ if (flatten) {
+ targetFile = wcsrchr(origFile/*data[i]->getFileName()*/, '\\');
+ if (targetFile == nullptr) {
+ targetFile = wcsrchr(origFile/*data[i]->getFileName()*/, '/');
}
- }
+ if (targetFile == nullptr) {
+ qCritical() << "Failed to find backslash in " << data[i]->getFileName();
+ continue;
+ } else {
+ // skip the slash
+ ++targetFile;
+ }
+ }
+ data[i]->addOutputFileName(ToQString(targetFile));
- m_InstallationProgress = new QProgressDialog(m_ParentWidget);
- ON_BLOCK_EXIT([this]() {
- m_InstallationProgress->hide();
- m_InstallationProgress->deleteLater();
- m_InstallationProgress = nullptr;
- });
- m_InstallationProgress->setWindowFlags(m_InstallationProgress->windowFlags() & (~Qt::WindowContextHelpButtonHint));
- m_InstallationProgress->setWindowTitle(tr("Extracting files"));
- m_InstallationProgress->setWindowModality(Qt::WindowModal);
- m_InstallationProgress->setFixedSize(600, 100);
- m_InstallationProgress->show();
+ result.append(QDir::tempPath().append("/").append(ToQString(targetFile)));
- // unpack only the files we need for the installer
- if (!m_ArchiveHandler->extract(
- QDir::tempPath(),
- new MethodCallback<InstallationManager, void, float>(this, &InstallationManager::updateProgress), nullptr,
- new MethodCallback<InstallationManager, void, QString const&>(this,
- &InstallationManager::report7ZipError))) {
- throw MyException(QString("extracting failed (%1)").arg(m_ArchiveHandler->getLastError()));
+ m_TempFilesToDelete.insert(ToQString(targetFile));
}
+ }
+
+ m_InstallationProgress = new QProgressDialog(m_ParentWidget);
+ ON_BLOCK_EXIT([this] () {
+ m_InstallationProgress->hide();
+ m_InstallationProgress->deleteLater();
+ m_InstallationProgress = nullptr;
+ });
+ m_InstallationProgress->setWindowFlags(
+ m_InstallationProgress->windowFlags() & (~Qt::WindowContextHelpButtonHint));
+ m_InstallationProgress->setWindowTitle(tr("Extracting files"));
+ m_InstallationProgress->setWindowModality(Qt::WindowModal);
+ m_InstallationProgress->setFixedSize(600, 100);
+ m_InstallationProgress->show();
+
+ // unpack only the files we need for the installer
+ if (!m_ArchiveHandler->extract(QDir::tempPath(),
+ new MethodCallback<InstallationManager, void, float>(this, &InstallationManager::updateProgress),
+ nullptr,
+ new MethodCallback<InstallationManager, void, QString const &>(this, &InstallationManager::report7ZipError))) {
+ throw MyException(QString("extracting failed (%1)").arg(m_ArchiveHandler->getLastError()));
+ }
- return result;
+ return result;
}
-IPluginInstaller::EInstallResult InstallationManager::installArchive(GuessedValue<QString>& modName,
- const QString& archiveName) {
- // in earlier versions the modName was copied here and the copy passed to install. I don't know why I did this and
- // it causes a problem if this is called by the bundle installer and the bundled installer adds additional names
- // that then end up being used, because the caller will then not have the right name.
- bool iniTweaks;
- if (install(archiveName, modName, iniTweaks)) {
- return IPluginInstaller::RESULT_SUCCESS;
- } else {
- return IPluginInstaller::RESULT_FAILED;
- }
+IPluginInstaller::EInstallResult InstallationManager::installArchive(GuessedValue<QString> &modName, const QString &archiveName)
+{
+ // in earlier versions the modName was copied here and the copy passed to install. I don't know why I did this and it causes
+ // a problem if this is called by the bundle installer and the bundled installer adds additional names that then end up being used,
+ // because the caller will then not have the right name.
+ bool iniTweaks;
+ if (install(archiveName, modName, iniTweaks)) {
+ return IPluginInstaller::RESULT_SUCCESS;
+ } else {
+ return IPluginInstaller::RESULT_FAILED;
+ }
}
-DirectoryTree* InstallationManager::createFilesTree() {
- FileData* const* data;
- size_t size;
- m_ArchiveHandler->getFileList(data, size);
- QScopedPointer<DirectoryTree> result(new DirectoryTree);
+DirectoryTree *InstallationManager::createFilesTree()
+{
+ FileData* const *data;
+ size_t size;
+ m_ArchiveHandler->getFileList(data, size);
- for (size_t i = 0; i < size; ++i) {
- // the files are in a flat list where each file has a a full path relative to the archive root
- // to create a tree, we have to iterate over each path component of each. This could be sped up by
- // grouping the filenames first, but so far there doesn't seem to be an actual performance problem
- DirectoryTree::Node* currentNode = result.data();
+ QScopedPointer<DirectoryTree> result(new DirectoryTree);
- QString fileName = data[i]->getFileName();
- QStringList components = fileName.split("\\");
+ for (size_t i = 0; i < size; ++i) {
+ // the files are in a flat list where each file has a a full path relative to the archive root
+ // to create a tree, we have to iterate over each path component of each. This could be sped up by
+ // grouping the filenames first, but so far there doesn't seem to be an actual performance problem
+ DirectoryTree::Node *currentNode = result.data();
- // iterate over all path-components of this filename (including the filename itself)
- for (QStringList::iterator componentIter = components.begin(); componentIter != components.end();
- ++componentIter) {
- if (componentIter->size() == 0) {
- // empty string indicates fileName is actually only a directory name and we have
- // completely processed it already.
- break;
- }
+ QString fileName = data[i]->getFileName();
+ QStringList components = fileName.split("\\");
- bool exists = false;
- // test if this path is already in the tree
- for (DirectoryTree::node_iterator nodeIter = currentNode->nodesBegin(); nodeIter != currentNode->nodesEnd();
- ++nodeIter) {
- if ((*nodeIter)->getData().name == *componentIter) {
- currentNode = *nodeIter;
- exists = true;
- break;
- }
- }
+ // iterate over all path-components of this filename (including the filename itself)
+ for (QStringList::iterator componentIter = components.begin(); componentIter != components.end(); ++componentIter) {
+ if (componentIter->size() == 0) {
+ // empty string indicates fileName is actually only a directory name and we have
+ // completely processed it already.
+ break;
+ }
- if (!exists) {
- if (componentIter + 1 == components.end()) {
- // last path component. directory or file?
- if (data[i]->isDirectory()) {
- // this is a bit problematic. archives will often only list directories if they are empty,
- // otherwise the dir only appears in the path of a file. In the UI however we allow the user
- // to uncheck all files in a directory while keeping the dir checked. Those directories are
- // currently not installed.
- DirectoryTree::Node* newNode = new DirectoryTree::Node;
- newNode->setData(DirectoryTreeInformation(*componentIter, static_cast<int>(i)));
- currentNode->addNode(newNode, false);
- currentNode = newNode;
- } else {
- currentNode->addLeaf(FileTreeInformation(*componentIter, i));
- }
- } else {
- DirectoryTree::Node* newNode = new DirectoryTree::Node;
- newNode->setData(DirectoryTreeInformation(*componentIter, -1));
- currentNode->addNode(newNode, false);
- currentNode = newNode;
- }
- }
+ bool exists = false;
+ // test if this path is already in the tree
+ for (DirectoryTree::node_iterator nodeIter = currentNode->nodesBegin(); nodeIter != currentNode->nodesEnd(); ++nodeIter) {
+ if ((*nodeIter)->getData().name == *componentIter) {
+ currentNode = *nodeIter;
+ exists = true;
+ break;
+ }
+ }
+
+ if (!exists) {
+ if (componentIter + 1 == components.end()) {
+ // last path component. directory or file?
+ if (data[i]->isDirectory()) {
+ // this is a bit problematic. archives will often only list directories if they are empty,
+ // otherwise the dir only appears in the path of a file. In the UI however we allow the user
+ // to uncheck all files in a directory while keeping the dir checked. Those directories are
+ // currently not installed.
+ DirectoryTree::Node *newNode = new DirectoryTree::Node;
+ newNode->setData(
+ DirectoryTreeInformation(*componentIter, static_cast<int>(i)));
+ currentNode->addNode(newNode, false);
+ currentNode = newNode;
+ } else {
+ currentNode->addLeaf(FileTreeInformation(*componentIter, i));
+ }
+ } else {
+ DirectoryTree::Node *newNode = new DirectoryTree::Node;
+ newNode->setData(DirectoryTreeInformation(*componentIter, -1));
+ currentNode->addNode(newNode, false);
+ currentNode = newNode;
}
+ }
}
+ }
- return result.take();
+ return result.take();
}
-bool InstallationManager::isSimpleArchiveTopLayer(const DirectoryTree::Node* node, bool bainStyle) {
- // see if there is at least one directory that makes sense on the top level
- for (DirectoryTree::const_node_iterator iter = node->nodesBegin(); iter != node->nodesEnd(); ++iter) {
- if ((bainStyle && InstallationTester::isTopLevelDirectoryBain((*iter)->getData().name)) ||
- (!bainStyle && InstallationTester::isTopLevelDirectory((*iter)->getData().name))) {
- qDebug("%s on the top level", (*iter)->getData().name.toUtf8().constData());
- return true;
- }
+
+bool InstallationManager::isSimpleArchiveTopLayer(const DirectoryTree::Node *node, bool bainStyle)
+{
+ // see if there is at least one directory that makes sense on the top level
+ for (DirectoryTree::const_node_iterator iter = node->nodesBegin(); iter != node->nodesEnd(); ++iter) {
+ if ((bainStyle && InstallationTester::isTopLevelDirectoryBain((*iter)->getData().name)) ||
+ (!bainStyle && InstallationTester::isTopLevelDirectory((*iter)->getData().name))) {
+ qDebug("%s on the top level", (*iter)->getData().name.toUtf8().constData());
+ return true;
}
+ }
- // see if there is a file that makes sense on the top level
- for (DirectoryTree::const_leaf_iterator iter = node->leafsBegin(); iter != node->leafsEnd(); ++iter) {
- if (InstallationTester::isTopLevelSuffix(iter->getName())) {
- return true;
- }
+ // see if there is a file that makes sense on the top level
+ for (DirectoryTree::const_leaf_iterator iter = node->leafsBegin(); iter != node->leafsEnd(); ++iter) {
+ if (InstallationTester::isTopLevelSuffix(iter->getName())) {
+ return true;
}
- return false;
+ }
+ return false;
}
-DirectoryTree::Node* InstallationManager::getSimpleArchiveBase(DirectoryTree* dataTree) {
- DirectoryTree::Node* currentNode = dataTree;
- while (true) {
- if (isSimpleArchiveTopLayer(currentNode, false)) {
- return currentNode;
- } else if ((currentNode->numLeafs() == 0) && (currentNode->numNodes() == 1)) {
- currentNode = *currentNode->nodesBegin();
- } else {
- qDebug("not a simple archive");
- return nullptr;
- }
+DirectoryTree::Node *InstallationManager::getSimpleArchiveBase(DirectoryTree *dataTree)
+{
+ DirectoryTree::Node *currentNode = dataTree;
+
+ while (true) {
+ if (isSimpleArchiveTopLayer(currentNode, false)) {
+ return currentNode;
+ } else if ((currentNode->numLeafs() == 0) &&
+ (currentNode->numNodes() == 1)) {
+ currentNode = *currentNode->nodesBegin();
+ } else {
+ qDebug("not a simple archive");
+ return nullptr;
}
+ }
}
-void InstallationManager::updateProgress(float percentage) {
- if (m_InstallationProgress != nullptr) {
- m_InstallationProgress->setValue(static_cast<int>(percentage * 100.0));
- if (m_InstallationProgress->wasCanceled()) {
- m_ArchiveHandler->cancel();
- m_InstallationProgress->reset();
- }
+
+void InstallationManager::updateProgress(float percentage)
+{
+ if (m_InstallationProgress != nullptr) {
+ m_InstallationProgress->setValue(static_cast<int>(percentage * 100.0));
+ if (m_InstallationProgress->wasCanceled()) {
+ m_ArchiveHandler->cancel();
+ m_InstallationProgress->reset();
}
+ }
}
-void InstallationManager::updateProgressFile(QString const& fileName) {
- if (m_InstallationProgress != nullptr) {
- m_InstallationProgress->setLabelText(fileName);
- QCoreApplication::processEvents();
- }
+
+void InstallationManager::updateProgressFile(QString const &fileName)
+{
+ if (m_InstallationProgress != nullptr) {
+ m_InstallationProgress->setLabelText(fileName);
+ QCoreApplication::processEvents();
+ }
}
-void InstallationManager::report7ZipError(QString const& errorMessage) {
- reportError(errorMessage);
- m_ArchiveHandler->cancel();
+
+void InstallationManager::report7ZipError(QString const &errorMessage)
+{
+ reportError(errorMessage);
+ m_ArchiveHandler->cancel();
}
-QString InstallationManager::generateBackupName(const QString& directoryName) const {
- QString backupName = directoryName + "_backup";
- if (QDir(backupName).exists()) {
- int idx = 2;
- QString temp = backupName + QString::number(idx);
- while (QDir(temp).exists()) {
- ++idx;
- temp = backupName + QString::number(idx);
- }
- backupName = temp;
+
+QString InstallationManager::generateBackupName(const QString &directoryName) const
+{
+ QString backupName = directoryName + "_backup";
+ if (QDir(backupName).exists()) {
+ int idx = 2;
+ QString temp = backupName + QString::number(idx);
+ while (QDir(temp).exists()) {
+ ++idx;
+ temp = backupName + QString::number(idx);
}
- return backupName;
+ backupName = temp;
+ }
+ return backupName;
}
-bool InstallationManager::testOverwrite(GuessedValue<QString>& modName, bool* merge) const {
- QString targetDirectory = QDir::fromNativeSeparators(m_ModsDirectory + "\\" + modName);
- while (QDir(targetDirectory).exists()) {
- Settings& settings(Settings::instance());
- bool backup = settings.directInterface().value("backup_install", false).toBool();
- QueryOverwriteDialog overwriteDialog(m_ParentWidget, backup ? QueryOverwriteDialog::BACKUP_YES
- : QueryOverwriteDialog::BACKUP_NO);
- if (overwriteDialog.exec()) {
- settings.directInterface().setValue("backup_install", overwriteDialog.backup());
- if (overwriteDialog.backup()) {
- QString backupDirectory = generateBackupName(targetDirectory);
- if (!copyDir(targetDirectory, backupDirectory, false)) {
- reportError(tr("failed to create backup"));
- return false;
- }
- }
- if (merge != nullptr) {
- *merge = (overwriteDialog.action() == QueryOverwriteDialog::ACT_MERGE);
- }
- if (overwriteDialog.action() == QueryOverwriteDialog::ACT_RENAME) {
- bool ok = false;
- QString name =
- QInputDialog::getText(m_ParentWidget, tr("Mod Name"), tr("Name"), QLineEdit::Normal, modName, &ok);
- if (ok && !name.isEmpty()) {
- modName.update(name, GUESS_USER);
- if (!ensureValidModName(modName)) {
- return false;
- }
- targetDirectory = QDir::fromNativeSeparators(m_ModsDirectory) + "/" + modName;
- }
- } else if (overwriteDialog.action() == QueryOverwriteDialog::ACT_REPLACE) {
- // save original settings like categories. Because it makes sense
- QString metaFilename = targetDirectory + "/meta.ini";
- QFile settingsFile(metaFilename);
- QByteArray originalSettings;
- if (settingsFile.open(QIODevice::ReadOnly)) {
- originalSettings = settingsFile.readAll();
- settingsFile.close();
- }
- // remove the directory with all content, then recreate it empty
- shellDelete(QStringList(targetDirectory));
- if (!QDir().mkdir(targetDirectory)) {
- // windows may keep the directory around for a moment, preventing its re-creation. Not sure
- // if this still happens with shellDelete
- Sleep(100);
- QDir().mkdir(targetDirectory);
- }
- // restore the saved settings
- if (settingsFile.open(QIODevice::WriteOnly)) {
- settingsFile.write(originalSettings);
- settingsFile.close();
- } else {
- qCritical("failed to restore original settings: %s", metaFilename.toUtf8().constData());
- }
- return true;
- } else if (overwriteDialog.action() == QueryOverwriteDialog::ACT_MERGE) {
- return true;
- }
- } else {
+bool InstallationManager::testOverwrite(GuessedValue<QString> &modName, bool *merge) const
+{
+ QString targetDirectory = QDir::fromNativeSeparators(m_ModsDirectory + "\\" + modName);
+ while (QDir(targetDirectory).exists()) {
+ Settings &settings(Settings::instance());
+ bool backup = settings.directInterface().value("backup_install", false).toBool();
+ QueryOverwriteDialog overwriteDialog(m_ParentWidget,
+ backup ? QueryOverwriteDialog::BACKUP_YES : QueryOverwriteDialog::BACKUP_NO);
+ if (overwriteDialog.exec()) {
+ settings.directInterface().setValue("backup_install", overwriteDialog.backup());
+ if (overwriteDialog.backup()) {
+ QString backupDirectory = generateBackupName(targetDirectory);
+ if (!copyDir(targetDirectory, backupDirectory, false)) {
+ reportError(tr("failed to create backup"));
+ return false;
+ }
+ }
+ if (merge != nullptr) {
+ *merge = (overwriteDialog.action() == QueryOverwriteDialog::ACT_MERGE);
+ }
+ if (overwriteDialog.action() == QueryOverwriteDialog::ACT_RENAME) {
+ bool ok = false;
+ QString name = QInputDialog::getText(m_ParentWidget, tr("Mod Name"), tr("Name"),
+ QLineEdit::Normal, modName, &ok);
+ if (ok && !name.isEmpty()) {
+ modName.update(name, GUESS_USER);
+ if (!ensureValidModName(modName)) {
return false;
+ }
+ targetDirectory = QDir::fromNativeSeparators(m_ModsDirectory) + "/" + modName;
+ }
+ } else if (overwriteDialog.action() == QueryOverwriteDialog::ACT_REPLACE) {
+ // save original settings like categories. Because it makes sense
+ QString metaFilename = targetDirectory + "/meta.ini";
+ QFile settingsFile(metaFilename);
+ QByteArray originalSettings;
+ if (settingsFile.open(QIODevice::ReadOnly)) {
+ originalSettings = settingsFile.readAll();
+ settingsFile.close();
+ }
+
+ // remove the directory with all content, then recreate it empty
+ shellDelete(QStringList(targetDirectory));
+ if (!QDir().mkdir(targetDirectory)) {
+ // windows may keep the directory around for a moment, preventing its re-creation. Not sure
+ // if this still happens with shellDelete
+ Sleep(100);
+ QDir().mkdir(targetDirectory);
+ }
+ // restore the saved settings
+ if (settingsFile.open(QIODevice::WriteOnly)) {
+ settingsFile.write(originalSettings);
+ settingsFile.close();
+ } else {
+ qCritical("failed to restore original settings: %s", metaFilename.toUtf8().constData());
}
+ return true;
+ } else if (overwriteDialog.action() == QueryOverwriteDialog::ACT_MERGE) {
+ return true;
+ }
+ } else {
+ return false;
}
+ }
- QDir().mkdir(targetDirectory);
+ QDir().mkdir(targetDirectory);
- return true;
+ return true;
}
-bool InstallationManager::ensureValidModName(GuessedValue<QString>& name) const {
- while (name->isEmpty()) {
- bool ok;
- name.update(QInputDialog::getText(m_ParentWidget, tr("Invalid name"),
- tr("The name you entered is invalid, please enter a different one."),
- QLineEdit::Normal, "", &ok),
- GUESS_USER);
- if (!ok) {
- return false;
- }
+
+bool InstallationManager::ensureValidModName(GuessedValue<QString> &name) const
+{
+ while (name->isEmpty()) {
+ bool ok;
+ name.update(QInputDialog::getText(m_ParentWidget, tr("Invalid name"),
+ tr("The name you entered is invalid, please enter a different one."),
+ QLineEdit::Normal, "", &ok),
+ GUESS_USER);
+ if (!ok) {
+ return false;
}
- return true;
+ }
+ return true;
}
-bool InstallationManager::doInstall(GuessedValue<QString>& modName, int modID, const QString& version,
- const QString& newestVersion, int categoryID, const QString& repository) {
- if (!ensureValidModName(modName)) {
- return false;
- }
+bool InstallationManager::doInstall(GuessedValue<QString> &modName, int modID,
+ const QString &version, const QString &newestVersion,
+ int categoryID, const QString &repository)
+{
+ if (!ensureValidModName(modName)) {
+ return false;
+ }
- bool merge = false;
- // determine target directory
- if (!testOverwrite(modName, &merge)) {
- return false;
- }
+ bool merge = false;
+ // determine target directory
+ if (!testOverwrite(modName, &merge)) {
+ return false;
+ }
- QString targetDirectory = QDir(m_ModsDirectory + "/" + modName).canonicalPath();
- QString targetDirectoryNative = QDir::toNativeSeparators(targetDirectory);
+ QString targetDirectory = QDir(m_ModsDirectory + "/" + modName).canonicalPath();
+ QString targetDirectoryNative = QDir::toNativeSeparators(targetDirectory);
- qDebug("installing to \"%s\"", targetDirectoryNative.toUtf8().constData());
+ qDebug("installing to \"%s\"", targetDirectoryNative.toUtf8().constData());
- m_InstallationProgress = new QProgressDialog(m_ParentWidget);
- ON_BLOCK_EXIT([this]() {
- m_InstallationProgress->hide();
- m_InstallationProgress->deleteLater();
- m_InstallationProgress = nullptr;
- });
+ m_InstallationProgress = new QProgressDialog(m_ParentWidget);
+ ON_BLOCK_EXIT([this] () {
+ m_InstallationProgress->hide();
+ m_InstallationProgress->deleteLater();
+ m_InstallationProgress = nullptr;
+ });
- m_InstallationProgress->setWindowFlags(m_InstallationProgress->windowFlags() & (~Qt::WindowContextHelpButtonHint));
- m_InstallationProgress->setWindowModality(Qt::WindowModal);
- m_InstallationProgress->setFixedSize(600, 100);
- m_InstallationProgress->show();
- if (!m_ArchiveHandler->extract(
- targetDirectory,
- new MethodCallback<InstallationManager, void, float>(this, &InstallationManager::updateProgress),
- new MethodCallback<InstallationManager, void, QString const&>(this,
- &InstallationManager::updateProgressFile),
- new MethodCallback<InstallationManager, void, QString const&>(this,
- &InstallationManager::report7ZipError))) {
- if (m_ArchiveHandler->getLastError() == Archive::ERROR_EXTRACT_CANCELLED) {
- return false;
- } else {
- throw MyException(QString("extracting failed (%1)").arg(m_ArchiveHandler->getLastError()));
- }
+ m_InstallationProgress->setWindowFlags(
+ m_InstallationProgress->windowFlags() & (~Qt::WindowContextHelpButtonHint));
+ m_InstallationProgress->setWindowModality(Qt::WindowModal);
+ m_InstallationProgress->setFixedSize(600, 100);
+ m_InstallationProgress->show();
+ if (!m_ArchiveHandler->extract(targetDirectory,
+ new MethodCallback<InstallationManager, void, float>(this, &InstallationManager::updateProgress),
+ new MethodCallback<InstallationManager, void, QString const &>(this, &InstallationManager::updateProgressFile),
+ new MethodCallback<InstallationManager, void, QString const &>(this, &InstallationManager::report7ZipError))) {
+ if (m_ArchiveHandler->getLastError() == Archive::ERROR_EXTRACT_CANCELLED) {
+ return false;
+ } else {
+ throw MyException(QString("extracting failed (%1)").arg(m_ArchiveHandler->getLastError()));
}
+ }
- QSettings settingsFile(targetDirectory + "/meta.ini", QSettings::IniFormat);
+ QSettings settingsFile(targetDirectory + "/meta.ini", QSettings::IniFormat);
- // overwrite settings only if they are actually are available or haven't been set before
- if ((modID != 0) || !settingsFile.contains("modid")) {
- settingsFile.setValue("modid", modID);
- }
- if (!settingsFile.contains("version") ||
- (!version.isEmpty() &&
- (!merge || (VersionInfo(version) >= VersionInfo(settingsFile.value("version").toString()))))) {
- settingsFile.setValue("version", version);
- }
- if (!newestVersion.isEmpty() || !settingsFile.contains("newestVersion")) {
- settingsFile.setValue("newestVersion", newestVersion);
- }
- // issue #51 used to overwrite the manually set categories
- if (!settingsFile.contains("category")) {
- settingsFile.setValue("category", QString::number(categoryID));
- }
- settingsFile.setValue("installationFile", m_CurrentFile);
- settingsFile.setValue("repository", repository);
- settingsFile.setValue("url", m_URL);
+ // overwrite settings only if they are actually are available or haven't been set before
+ if ((modID != 0) || !settingsFile.contains("modid")) {
+ settingsFile.setValue("modid", modID);
+ }
+ if (!settingsFile.contains("version") ||
+ (!version.isEmpty() &&
+ (!merge || (VersionInfo(version) >= VersionInfo(settingsFile.value("version").toString()))))) {
+ settingsFile.setValue("version", version);
+ }
+ if (!newestVersion.isEmpty() || !settingsFile.contains("newestVersion")) {
+ settingsFile.setValue("newestVersion", newestVersion);
+ }
+ // issue #51 used to overwrite the manually set categories
+ if (!settingsFile.contains("category")) {
+ settingsFile.setValue("category", QString::number(categoryID));
+ }
+ settingsFile.setValue("installationFile", m_CurrentFile);
+ settingsFile.setValue("repository", repository);
+ settingsFile.setValue("url", m_URL);
- if (!merge) {
- // this does not clear the list we have in memory but the mod is going to have to be re-read anyway
- // btw.: installedFiles were written with beginWriteArray but we can still clear it with beginGroup. nice
- settingsFile.beginGroup("installedFiles");
- settingsFile.remove("");
- settingsFile.endGroup();
- }
+ if (!merge) {
+ // this does not clear the list we have in memory but the mod is going to have to be re-read anyway
+ // btw.: installedFiles were written with beginWriteArray but we can still clear it with beginGroup. nice
+ settingsFile.beginGroup("installedFiles");
+ settingsFile.remove("");
+ settingsFile.endGroup();
+ }
- return true;
+ return true;
}
-bool InstallationManager::wasCancelled() {
- return m_ArchiveHandler->getLastError() == Archive::ERROR_EXTRACT_CANCELLED;
+
+bool InstallationManager::wasCancelled()
+{
+ return m_ArchiveHandler->getLastError() == Archive::ERROR_EXTRACT_CANCELLED;
}
-void InstallationManager::postInstallCleanup() {
- m_ArchiveHandler->close();
- // directories we may want to remove. sorted from longest to shortest to ensure we remove subdirectories first.
- auto longestFirst = [](const QString& LHS, const QString& RHS) -> bool {
- if (LHS.size() != RHS.size())
- return LHS.size() > RHS.size();
- else
- return LHS < RHS;
- };
+void InstallationManager::postInstallCleanup()
+{
+ m_ArchiveHandler->close();
- std::set<QString, std::function<bool(const QString&, const QString&)>> directoriesToRemove(longestFirst);
+ // directories we may want to remove. sorted from longest to shortest to ensure we remove subdirectories first.
+ auto longestFirst = [](const QString &LHS, const QString &RHS) -> bool {
+ if (LHS.size() != RHS.size()) return LHS.size() > RHS.size();
+ else return LHS < RHS;
+ };
- // clean up temp files
- // TODO: this doesn't yet remove directories. Also, the files may be left there if this point isn't reached
- for (const QString& tempFile : m_TempFilesToDelete) {
- QFileInfo fileInfo(QDir::tempPath() + "/" + tempFile);
- QFile::remove(fileInfo.absoluteFilePath());
- directoriesToRemove.insert(fileInfo.absolutePath());
- }
+ std::set<QString, std::function<bool(const QString&, const QString&)>> directoriesToRemove(longestFirst);
- m_TempFilesToDelete.clear();
+ // clean up temp files
+ // TODO: this doesn't yet remove directories. Also, the files may be left there if this point isn't reached
+ for (const QString &tempFile : m_TempFilesToDelete) {
+ QFileInfo fileInfo(QDir::tempPath() + "/" + tempFile);
+ QFile::remove(fileInfo.absoluteFilePath());
+ directoriesToRemove.insert(fileInfo.absolutePath());
+ }
- // try to delete each directory we had temporary files in. the call fails for non-empty directories which is ok
- for (const QString& dir : directoriesToRemove) {
- QDir().rmdir(dir);
- }
+ m_TempFilesToDelete.clear();
+
+ // try to delete each directory we had temporary files in. the call fails for non-empty directories which is ok
+ for (const QString &dir : directoriesToRemove) {
+ QDir().rmdir(dir);
+ }
}
-bool InstallationManager::install(const QString& fileName, GuessedValue<QString>& modName, bool& hasIniTweaks) {
- QFileInfo fileInfo(fileName);
- if (m_SupportedExtensions.find(fileInfo.suffix()) == m_SupportedExtensions.end()) {
- reportError(tr("File format \"%1\" not supported").arg(fileInfo.suffix()));
- return false;
- }
+bool InstallationManager::install(const QString &fileName,
+ GuessedValue<QString> &modName,
+ bool &hasIniTweaks)
+{
+ QFileInfo fileInfo(fileName);
+ if (m_SupportedExtensions.find(fileInfo.suffix()) == m_SupportedExtensions.end()) {
+ reportError(tr("File format \"%1\" not supported").arg(fileInfo.suffix()));
+ return false;
+ }
- modName.setFilter(&fixDirectoryName);
+ modName.setFilter(&fixDirectoryName);
- modName.update(QFileInfo(fileName).completeBaseName(), GUESS_FALLBACK);
+ modName.update(QFileInfo(fileName).completeBaseName(), GUESS_FALLBACK);
- // read out meta information from the download if available
- int modID = 0;
- QString version = "";
- QString newestVersion = "";
- int categoryID = 0;
- QString repository = "Nexus";
+ // read out meta information from the download if available
+ int modID = 0;
+ QString version = "";
+ QString newestVersion = "";
+ int categoryID = 0;
+ QString repository = "Nexus";
- QString metaName = fileName + ".meta";
- if (QFile(metaName).exists()) {
- QSettings metaFile(metaName, QSettings::IniFormat);
- modID = metaFile.value("modID", 0).toInt();
- QTextDocument doc;
- doc.setHtml(metaFile.value("name", "").toString());
- modName.update(doc.toPlainText(), GUESS_FALLBACK);
- modName.update(metaFile.value("modName", "").toString(), GUESS_META);
+ QString metaName = fileName + ".meta";
+ if (QFile(metaName).exists()) {
+ QSettings metaFile(metaName, QSettings::IniFormat);
+ modID = metaFile.value("modID", 0).toInt();
+ QTextDocument doc;
+ doc.setHtml(metaFile.value("name", "").toString());
+ modName.update(doc.toPlainText(), GUESS_FALLBACK);
+ modName.update(metaFile.value("modName", "").toString(), GUESS_META);
- version = metaFile.value("version", "").toString();
- newestVersion = metaFile.value("newestVersion", "").toString();
- unsigned int categoryIndex = CategoryFactory::instance().resolveNexusID(metaFile.value("category", 0).toInt());
- categoryID = CategoryFactory::instance().getCategoryID(categoryIndex);
- repository = metaFile.value("repository", "").toString();
- }
+ version = metaFile.value("version", "").toString();
+ newestVersion = metaFile.value("newestVersion", "").toString();
+ unsigned int categoryIndex = CategoryFactory::instance().resolveNexusID(
+ metaFile.value("category", 0).toInt());
+ categoryID = CategoryFactory::instance().getCategoryID(categoryIndex);
+ repository = metaFile.value("repository", "").toString();
+ }
+
+ if (version.isEmpty()) {
+ QDateTime lastMod = fileInfo.lastModified();
+ version = "d" + lastMod.toString("yyyy.M.d");
+ }
- if (version.isEmpty()) {
- QDateTime lastMod = fileInfo.lastModified();
- version = "d" + lastMod.toString("yyyy.M.d");
+ { // guess the mod name and mod if from the file name if there was no meta information
+ QString guessedModName;
+ int guessedModID = modID;
+ NexusInterface::interpretNexusFileName(QFileInfo(fileName).fileName(), guessedModName, guessedModID, false);
+ if ((modID == 0) && (guessedModID != -1)) {
+ modID = guessedModID;
+ } else if (modID != guessedModID) {
+ qDebug("passed mod id: %d, guessed id: %d", modID, guessedModID);
}
- { // guess the mod name and mod if from the file name if there was no meta information
- QString guessedModName;
- int guessedModID = modID;
- NexusInterface::interpretNexusFileName(QFileInfo(fileName).fileName(), guessedModName, guessedModID, false);
- if ((modID == 0) && (guessedModID != -1)) {
- modID = guessedModID;
- } else if (modID != guessedModID) {
- qDebug("passed mod id: %d, guessed id: %d", modID, guessedModID);
- }
+ modName.update(guessedModName, GUESS_GOOD);
+ }
- modName.update(guessedModName, GUESS_GOOD);
- }
+ m_CurrentFile = fileInfo.absoluteFilePath();
+ if (fileInfo.dir() == QDir(m_DownloadsDirectory)) {
+ m_CurrentFile = fileInfo.fileName();
+ }
+ qDebug("using mod name \"%s\" (id %d) -> %s", modName->toUtf8().constData(), modID, qPrintable(m_CurrentFile));
- m_CurrentFile = fileInfo.absoluteFilePath();
- if (fileInfo.dir() == QDir(m_DownloadsDirectory)) {
- m_CurrentFile = fileInfo.fileName();
- }
- qDebug("using mod name \"%s\" (id %d) -> %s", modName->toUtf8().constData(), modID, qPrintable(m_CurrentFile));
+ //If there's an archive already open, close it. This happens with the bundle
+ //installer when it uncompresses a split archive, then finds it has a real archive
+ //to deal with.
+ m_ArchiveHandler->close();
- // If there's an archive already open, close it. This happens with the bundle
- // installer when it uncompresses a split archive, then finds it has a real archive
- // to deal with.
- m_ArchiveHandler->close();
+ // open the archive and construct the directory tree the installers work on
+ bool archiveOpen = m_ArchiveHandler->open(fileName,
+ new MethodCallback<InstallationManager, void, QString *>(this, &InstallationManager::queryPassword));
+ if (!archiveOpen) {
+ qDebug("integrated archiver can't open %s: %s (%d)",
+ qPrintable(fileName),
+ qPrintable(getErrorString(m_ArchiveHandler->getLastError())),
+ m_ArchiveHandler->getLastError());
+ }
+ ON_BLOCK_EXIT(std::bind(&InstallationManager::postInstallCleanup, this));
- // open the archive and construct the directory tree the installers work on
- bool archiveOpen = m_ArchiveHandler->open(
- fileName, new MethodCallback<InstallationManager, void, QString*>(this, &InstallationManager::queryPassword));
- if (!archiveOpen) {
- qDebug("integrated archiver can't open %s: %s (%d)", qPrintable(fileName),
- qPrintable(getErrorString(m_ArchiveHandler->getLastError())), m_ArchiveHandler->getLastError());
- }
- ON_BLOCK_EXIT(std::bind(&InstallationManager::postInstallCleanup, this));
+ QScopedPointer<DirectoryTree> filesTree(archiveOpen ? createFilesTree() : nullptr);
+ IPluginInstaller::EInstallResult installResult = IPluginInstaller::RESULT_NOTATTEMPTED;
- QScopedPointer<DirectoryTree> filesTree(archiveOpen ? createFilesTree() : nullptr);
- IPluginInstaller::EInstallResult installResult = IPluginInstaller::RESULT_NOTATTEMPTED;
+ std::sort(m_Installers.begin(), m_Installers.end(), [] (IPluginInstaller *LHS, IPluginInstaller *RHS) {
+ return LHS->priority() > RHS->priority();
+ });
- std::sort(m_Installers.begin(), m_Installers.end(),
- [](IPluginInstaller* LHS, IPluginInstaller* RHS) { return LHS->priority() > RHS->priority(); });
+ for (IPluginInstaller *installer : m_Installers) {
+ // don't use inactive installers (installer can't be null here but vc static code analysis thinks it could)
+ if ((installer == nullptr) || !installer->isActive()) {
+ continue;
+ }
- for (IPluginInstaller* installer : m_Installers) {
- // don't use inactive installers (installer can't be null here but vc static code analysis thinks it could)
- if ((installer == nullptr) || !installer->isActive()) {
- continue;
- }
+ // try only manual installers if that was requested
+ if (installResult == IPluginInstaller::RESULT_MANUALREQUESTED) {
+ if (!installer->isManualInstaller()) {
+ continue;
+ }
+ } else if (installResult != IPluginInstaller::RESULT_NOTATTEMPTED) {
+ break;
+ }
- // try only manual installers if that was requested
- if (installResult == IPluginInstaller::RESULT_MANUALREQUESTED) {
- if (!installer->isManualInstaller()) {
- continue;
+ try {
+ { // simple case
+ IPluginInstallerSimple *installerSimple
+ = dynamic_cast<IPluginInstallerSimple *>(installer);
+ if ((installerSimple != nullptr) && (filesTree != nullptr)
+ && (installer->isArchiveSupported(*filesTree))) {
+ installResult
+ = installerSimple->install(modName, *filesTree, version, modID);
+ if (installResult == IPluginInstaller::RESULT_SUCCESS) {
+ mapToArchive(filesTree.data());
+ // the simple installer only prepares the installation, the rest
+ // works the same for all installers
+ if (!doInstall(modName, modID, version, newestVersion, categoryID,
+ repository)) {
+ installResult = IPluginInstaller::RESULT_FAILED;
}
- } else if (installResult != IPluginInstaller::RESULT_NOTATTEMPTED) {
- break;
+ }
}
+ }
- try {
- { // simple case
- IPluginInstallerSimple* installerSimple = dynamic_cast<IPluginInstallerSimple*>(installer);
- if ((installerSimple != nullptr) && (filesTree != nullptr) &&
- (installer->isArchiveSupported(*filesTree))) {
- installResult = installerSimple->install(modName, *filesTree, version, modID);
- if (installResult == IPluginInstaller::RESULT_SUCCESS) {
- mapToArchive(filesTree.data());
- // the simple installer only prepares the installation, the rest
- // works the same for all installers
- if (!doInstall(modName, modID, version, newestVersion, categoryID, repository)) {
- installResult = IPluginInstaller::RESULT_FAILED;
- }
- }
- }
+ { // custom case
+ IPluginInstallerCustom *installerCustom
+ = dynamic_cast<IPluginInstallerCustom *>(installer);
+ if ((installerCustom != nullptr)
+ && (((filesTree != nullptr)
+ && installer->isArchiveSupported(*filesTree))
+ || ((filesTree == nullptr)
+ && installerCustom->isArchiveSupported(fileName)))) {
+ std::set<QString> installerExt
+ = installerCustom->supportedExtensions();
+ if (installerExt.find(fileInfo.suffix()) != installerExt.end()) {
+ installResult
+ = installerCustom->install(modName, fileName, version, modID);
+ unsigned int idx = ModInfo::getIndex(modName);
+ if (idx != UINT_MAX) {
+ ModInfo::Ptr info = ModInfo::getByIndex(idx);
+ info->setRepository(repository);
}
-
- { // custom case
- IPluginInstallerCustom* installerCustom = dynamic_cast<IPluginInstallerCustom*>(installer);
- if ((installerCustom != nullptr) &&
- (((filesTree != nullptr) && installer->isArchiveSupported(*filesTree)) ||
- ((filesTree == nullptr) && installerCustom->isArchiveSupported(fileName)))) {
- std::set<QString> installerExt = installerCustom->supportedExtensions();
- if (installerExt.find(fileInfo.suffix()) != installerExt.end()) {
- installResult = installerCustom->install(modName, fileName, version, modID);
- unsigned int idx = ModInfo::getIndex(modName);
- if (idx != UINT_MAX) {
- ModInfo::Ptr info = ModInfo::getByIndex(idx);
- info->setRepository(repository);
- }
- }
- }
- }
- } catch (const IncompatibilityException& e) {
- qCritical("plugin \"%s\" incompatible: %s", qPrintable(installer->name()), e.what());
+ }
}
+ }
+ } catch (const IncompatibilityException &e) {
+ qCritical("plugin \"%s\" incompatible: %s",
+ qPrintable(installer->name()), e.what());
+ }
- // act upon the installation result. at this point the files have already been
- // extracted to the correct location
- switch (installResult) {
- case IPluginInstaller::RESULT_CANCELED:
- case IPluginInstaller::RESULT_FAILED: {
- return false;
- } break;
- case IPluginInstaller::RESULT_SUCCESS:
- case IPluginInstaller::RESULT_SUCCESSCANCEL: {
- if (filesTree != nullptr) {
- DirectoryTree::node_iterator iniTweakNode = filesTree->nodeFind(DirectoryTreeInformation("INI Tweaks"));
- hasIniTweaks = (iniTweakNode != filesTree->nodesEnd()) && ((*iniTweakNode)->numLeafs() != 0);
- return true;
- } else {
- return false;
- }
- } break;
+ // act upon the installation result. at this point the files have already been
+ // extracted to the correct location
+ switch (installResult) {
+ case IPluginInstaller::RESULT_CANCELED:
+ case IPluginInstaller::RESULT_FAILED: {
+ return false;
+ } break;
+ case IPluginInstaller::RESULT_SUCCESS:
+ case IPluginInstaller::RESULT_SUCCESSCANCEL: {
+ if (filesTree != nullptr) {
+ DirectoryTree::node_iterator iniTweakNode = filesTree->nodeFind(DirectoryTreeInformation("INI Tweaks"));
+ hasIniTweaks = (iniTweakNode != filesTree->nodesEnd()) &&
+ ((*iniTweakNode)->numLeafs() != 0);
+ return true;
+ } else {
+ return false;
}
+ } break;
}
+ }
- reportError(tr("None of the available installer plugins were able to handle that archive"));
- return false;
+ reportError(tr("None of the available installer plugins were able to handle that archive"));
+ return false;
}
-QString InstallationManager::getErrorString(Archive::Error errorCode) {
- switch (errorCode) {
+
+
+QString InstallationManager::getErrorString(Archive::Error errorCode)
+{
+ switch (errorCode) {
case Archive::ERROR_NONE: {
- return tr("no error");
+ return tr("no error");
} break;
case Archive::ERROR_LIBRARY_NOT_FOUND: {
- return tr("7z.dll not found");
+ return tr("7z.dll not found");
} break;
case Archive::ERROR_LIBRARY_INVALID: {
- return tr("7z.dll isn't valid");
+ return tr("7z.dll isn't valid");
} break;
case Archive::ERROR_ARCHIVE_NOT_FOUND: {
- return tr("archive not found");
+ return tr("archive not found");
} break;
case Archive::ERROR_FAILED_TO_OPEN_ARCHIVE: {
- return tr("failed to open archive");
+ return tr("failed to open archive");
} break;
case Archive::ERROR_INVALID_ARCHIVE_FORMAT: {
- return tr("unsupported archive type");
+ return tr("unsupported archive type");
} break;
case Archive::ERROR_LIBRARY_ERROR: {
- return tr("internal library error");
+ return tr("internal library error");
} break;
case Archive::ERROR_ARCHIVE_INVALID: {
- return tr("archive invalid");
+ return tr("archive invalid");
} break;
default: {
- // this probably means the archiver.dll is newer than this
- return tr("unknown archive error");
+ // this probably means the archiver.dll is newer than this
+ return tr("unknown archive error");
} break;
- }
+ }
}
-void InstallationManager::registerInstaller(IPluginInstaller* installer) {
- m_Installers.push_back(installer);
- installer->setInstallationManager(this);
- IPluginInstallerCustom* installerCustom = dynamic_cast<IPluginInstallerCustom*>(installer);
- if (installerCustom != nullptr) {
- std::set<QString> extensions = installerCustom->supportedExtensions();
- m_SupportedExtensions.insert(extensions.begin(), extensions.end());
- }
+
+void InstallationManager::registerInstaller(IPluginInstaller *installer)
+{
+ m_Installers.push_back(installer);
+ installer->setInstallationManager(this);
+ IPluginInstallerCustom *installerCustom = dynamic_cast<IPluginInstallerCustom*>(installer);
+ if (installerCustom != nullptr) {
+ std::set<QString> extensions = installerCustom->supportedExtensions();
+ m_SupportedExtensions.insert(extensions.begin(), extensions.end());
+ }
}
-QStringList InstallationManager::getSupportedExtensions() const {
- QStringList result;
- foreach (const QString& extension, m_SupportedExtensions) { result.append(extension); }
- return result;
+QStringList InstallationManager::getSupportedExtensions() const
+{
+ QStringList result;
+ foreach (const QString &extension, m_SupportedExtensions) {
+ result.append(extension);
+ }
+ return result;
}
diff --git a/src/installationmanager.h b/src/installationmanager.h
index fdb056fa..e1ebb519 100644
--- a/src/installationmanager.h
+++ b/src/installationmanager.h
@@ -20,193 +20,198 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef INSTALLATIONMANAGER_H
#define INSTALLATIONMANAGER_H
-#include <guessedvalue.h>
+
#include <iinstallationmanager.h>
#include <iplugininstaller.h>
+#include <guessedvalue.h>
#include <QObject>
#define WIN32_LEAN_AND_MEAN
-#include <QProgressDialog>
#include <Windows.h>
#include <archive.h>
-#include <errorcodes.h>
+#include <QProgressDialog>
#include <set>
+#include <errorcodes.h>
+
/**
* @brief manages the installation of mod archives
* This currently supports two special kind of archives:
- * - "simple" archives: properly packaged archives without options, so they can be extracted to the (virtual) data
- *directory directly
+ * - "simple" archives: properly packaged archives without options, so they can be extracted to the (virtual) data directory directly
* - "complex" bain archives: archives with options for the bain system.
* All other archives are managed through the manual "InstallDialog"
* @todo this may be a good place to support plugins
**/
-class InstallationManager : public QObject, public MOBase::IInstallationManager {
- Q_OBJECT
+class InstallationManager : public QObject, public MOBase::IInstallationManager
+{
+ Q_OBJECT
public:
- /**
- * @brief constructor
- *
- * @param parent parent object.
- **/
- explicit InstallationManager();
- virtual ~InstallationManager();
+ /**
+ * @brief constructor
+ *
+ * @param parent parent object.
+ **/
+ explicit InstallationManager();
+
+ virtual ~InstallationManager();
- void setParentWidget(QWidget* widget);
+ void setParentWidget(QWidget *widget);
- void setURL(const QString& url);
+ void setURL(const QString &url);
- /**
- * @brief update the directory where mods are to be installed
- * @param modsDirectory the mod directory
- * @note this is called a lot, probably redundantly
- */
- void setModsDirectory(const QString& modsDirectory) { m_ModsDirectory = modsDirectory; }
+ /**
+ * @brief update the directory where mods are to be installed
+ * @param modsDirectory the mod directory
+ * @note this is called a lot, probably redundantly
+ */
+ void setModsDirectory(const QString &modsDirectory) { m_ModsDirectory = modsDirectory; }
- /**
- * @brief update the directory where downloads are stored
- * @param downloadDirectory the download directory
- */
- void setDownloadDirectory(const QString& downloadDirectory) { m_DownloadsDirectory = downloadDirectory; }
+ /**
+ * @brief update the directory where downloads are stored
+ * @param downloadDirectory the download directory
+ */
+ void setDownloadDirectory(const QString &downloadDirectory) { m_DownloadsDirectory = downloadDirectory; }
- /**
- * @brief install a mod from an archive
- *
- * @param fileName absolute file name of the archive to install
- * @param modName suggested name of the mod. If this is empty (the default), a name will be guessed based on the
- *filename. The user will always have a chance to rename the mod
- * @return true if the archive was installed, false if installation failed or was refused
- * @exception std::exception an exception may be thrown if the archive can't be opened (maybe the format is invalid
- *or the file is damaged)
- **/
- bool install(const QString& fileName, MOBase::GuessedValue<QString>& modName, bool& hasIniTweaks);
+ /**
+ * @brief install a mod from an archive
+ *
+ * @param fileName absolute file name of the archive to install
+ * @param modName suggested name of the mod. If this is empty (the default), a name will be guessed based on the filename. The user will always have a chance to rename the mod
+ * @return true if the archive was installed, false if installation failed or was refused
+ * @exception std::exception an exception may be thrown if the archive can't be opened (maybe the format is invalid or the file is damaged)
+ **/
+ bool install(const QString &fileName, MOBase::GuessedValue<QString> &modName, bool &hasIniTweaks);
- /**
- * @return true if the installation was canceled
- **/
- bool wasCancelled();
+ /**
+ * @return true if the installation was canceled
+ **/
+ bool wasCancelled();
- /**
- * @brief retrieve a string describing the specified error code
- *
- * @param errorCode an error code as returned by the archiving function
- * @return the error string
- * @todo This function doesn't belong here, it is only public because the SelfUpdater class also uses "Archive" to
- *get to the package.txt file
- **/
- static QString getErrorString(Archive::Error errorCode);
+ /**
+ * @brief retrieve a string describing the specified error code
+ *
+ * @param errorCode an error code as returned by the archiving function
+ * @return the error string
+ * @todo This function doesn't belong here, it is only public because the SelfUpdater class also uses "Archive" to get to the package.txt file
+ **/
+ static QString getErrorString(Archive::Error errorCode);
- /**
- * @brief register an installer-plugin
- * @param the installer to register
- */
- void registerInstaller(MOBase::IPluginInstaller* installer);
+ /**
+ * @brief register an installer-plugin
+ * @param the installer to register
+ */
+ void registerInstaller(MOBase::IPluginInstaller *installer);
- /**
- * @return list of file extensions we can install
- */
- QStringList getSupportedExtensions() const;
+ /**
+ * @return list of file extensions we can install
+ */
+ QStringList getSupportedExtensions() const;
- /**
- * @brief extract the specified file from the currently open archive to a temporary location
- * @param (relative) name of the file within the archive
- * @return the absolute name of the temporary file
- * @note the call will fail with an exception if no archive is open (plugins deriving
- * from IPluginInstallerSimple can rely on that, custom installers shouldn't)
- * @note the temporary file is automatically cleaned up after the installation
- * @note This call can be very slow if the archive is large and "solid"
- */
- virtual QString extractFile(const QString& fileName);
+ /**
+ * @brief extract the specified file from the currently open archive to a temporary location
+ * @param (relative) name of the file within the archive
+ * @return the absolute name of the temporary file
+ * @note the call will fail with an exception if no archive is open (plugins deriving
+ * from IPluginInstallerSimple can rely on that, custom installers shouldn't)
+ * @note the temporary file is automatically cleaned up after the installation
+ * @note This call can be very slow if the archive is large and "solid"
+ */
+ virtual QString extractFile(const QString &fileName);
- /**
- * @brief extract the specified files from the currently open archive to a temporary location
- * @param (relative) names of files within the archive
- * @return the absolute names of the temporary files
- * @note the call will fail with an exception if no archive is open (plugins deriving
- * from IPluginInstallerSimple can rely on that, custom installers shouldn't)
- * @note the temporary file is automatically cleaned up after the installation
- * @note This call can be very slow if the archive is large and "solid"
- */
- virtual QStringList extractFiles(const QStringList& files, bool flatten);
+ /**
+ * @brief extract the specified files from the currently open archive to a temporary location
+ * @param (relative) names of files within the archive
+ * @return the absolute names of the temporary files
+ * @note the call will fail with an exception if no archive is open (plugins deriving
+ * from IPluginInstallerSimple can rely on that, custom installers shouldn't)
+ * @note the temporary file is automatically cleaned up after the installation
+ * @note This call can be very slow if the archive is large and "solid"
+ */
+ virtual QStringList extractFiles(const QStringList &files, bool flatten);
- /**
- * @brief installs an archive
- * @param modName suggested name of the mod
- * @param archiveFile path to the archive to install
- * @return the installation result
- */
- virtual MOBase::IPluginInstaller::EInstallResult installArchive(MOBase::GuessedValue<QString>& modName,
- const QString& archiveName);
+ /**
+ * @brief installs an archive
+ * @param modName suggested name of the mod
+ * @param archiveFile path to the archive to install
+ * @return the installation result
+ */
+ virtual MOBase::IPluginInstaller::EInstallResult installArchive(MOBase::GuessedValue<QString> &modName, const QString &archiveName);
- /**
- * @brief test if the specified mod name is free. If not, query the user how to proceed
- * @param modName current possible names for the mod
- * @param merge if this value is not null, the value will be set to whether the use chose to merge or replace
- * @return true if we can proceed with the installation, false if the user canceled or in case of an unrecoverable
- * error
- */
- virtual bool testOverwrite(MOBase::GuessedValue<QString>& modName, bool* merge = nullptr) const;
+ /**
+ * @brief test if the specified mod name is free. If not, query the user how to proceed
+ * @param modName current possible names for the mod
+ * @param merge if this value is not null, the value will be set to whether the use chose to merge or replace
+ * @return true if we can proceed with the installation, false if the user canceled or in case of an unrecoverable error
+ */
+ virtual bool testOverwrite(MOBase::GuessedValue<QString> &modName, bool *merge = nullptr) const;
private:
- void queryPassword(QString* password);
- void updateProgress(float percentage);
- void updateProgressFile(const QString& fileName);
- void report7ZipError(const QString& errorMessage);
- MOBase::DirectoryTree* createFilesTree();
+ void queryPassword(QString *password);
+ void updateProgress(float percentage);
+ void updateProgressFile(const QString &fileName);
+ void report7ZipError(const QString &errorMessage);
+
+ MOBase::DirectoryTree *createFilesTree();
+
+ // remap all files in the archive to the directory structure represented by baseNode
+ // files not present in baseNode are disabled
+ void mapToArchive(const MOBase::DirectoryTree::Node *baseNode);
- // remap all files in the archive to the directory structure represented by baseNode
- // files not present in baseNode are disabled
- void mapToArchive(const MOBase::DirectoryTree::Node* baseNode);
+ // recursive worker function for mapToArchive
+ void mapToArchive(const MOBase::DirectoryTree::Node *node, QString path, FileData * const *data);
+ bool unpackSingleFile(const QString &fileName);
- // recursive worker function for mapToArchive
- void mapToArchive(const MOBase::DirectoryTree::Node* node, QString path, FileData* const* data);
- bool unpackSingleFile(const QString& fileName);
- bool isSimpleArchiveTopLayer(const MOBase::DirectoryTree::Node* node, bool bainStyle);
- MOBase::DirectoryTree::Node* getSimpleArchiveBase(MOBase::DirectoryTree* dataTree);
+ bool isSimpleArchiveTopLayer(const MOBase::DirectoryTree::Node *node, bool bainStyle);
+ MOBase::DirectoryTree::Node *getSimpleArchiveBase(MOBase::DirectoryTree *dataTree);
- bool doInstall(MOBase::GuessedValue<QString>& modName, int modID, const QString& version,
- const QString& newestVersion, int categoryID, const QString& repository);
+ bool doInstall(MOBase::GuessedValue<QString> &modName,
+ int modID, const QString &version, const QString &newestVersion, int categoryID, const QString &repository);
- QString generateBackupName(const QString& directoryName) const;
+ QString generateBackupName(const QString &directoryName) const;
- bool ensureValidModName(MOBase::GuessedValue<QString>& name) const;
+ bool ensureValidModName(MOBase::GuessedValue<QString> &name) const;
- void postInstallCleanup();
+ void postInstallCleanup();
private:
- struct ByPriority {
- bool operator()(MOBase::IPluginInstaller* LHS, MOBase::IPluginInstaller* RHS) const {
- return LHS->priority() > RHS->priority();
- }
- };
- struct CaseInsensitive {
- bool operator()(const QString& LHS, const QString& RHS) const {
- return QString::compare(LHS, RHS, Qt::CaseInsensitive) < 0;
- }
- };
+ struct ByPriority {
+ bool operator()(MOBase::IPluginInstaller *LHS, MOBase::IPluginInstaller *RHS) const
+ {
+ return LHS->priority() > RHS->priority();
+ }
+ };
+
+ struct CaseInsensitive {
+ bool operator() (const QString &LHS, const QString &RHS) const
+ {
+ return QString::compare(LHS, RHS, Qt::CaseInsensitive) < 0;
+ }
+ };
private:
- QWidget* m_ParentWidget;
- QString m_ModsDirectory;
- QString m_DownloadsDirectory;
+ QWidget *m_ParentWidget;
+
+ QString m_ModsDirectory;
+ QString m_DownloadsDirectory;
- std::vector<MOBase::IPluginInstaller*> m_Installers;
- std::set<QString, CaseInsensitive> m_SupportedExtensions;
+ std::vector<MOBase::IPluginInstaller*> m_Installers;
+ std::set<QString, CaseInsensitive> m_SupportedExtensions;
- Archive* m_ArchiveHandler;
- QString m_CurrentFile;
+ Archive *m_ArchiveHandler;
+ QString m_CurrentFile;
- QProgressDialog* m_InstallationProgress{nullptr};
+ QProgressDialog *m_InstallationProgress { nullptr };
- std::set<QString> m_TempFilesToDelete;
+ std::set<QString> m_TempFilesToDelete;
- QString m_URL;
+ QString m_URL;
};
+
#endif // INSTALLATIONMANAGER_H
diff --git a/src/instancemanager.cpp b/src/instancemanager.cpp
index d1232809..29068c5b 100644
--- a/src/instancemanager.cpp
+++ b/src/instancemanager.cpp
@@ -17,244 +17,282 @@ You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
+
#include "instancemanager.h"
#include "selectiondialog.h"
+#include <utility.h>
+#include <appconfig.h>
#include <QCoreApplication>
#include <QDir>
+#include <QStandardPaths>
#include <QInputDialog>
#include <QMessageBox>
-#include <QStandardPaths>
-#include <appconfig.h>
#include <cstdint>
-#include <utility.h>
-static const char COMPANY_NAME[] = "Tannin";
+
+static const char COMPANY_NAME[] = "Tannin";
static const char APPLICATION_NAME[] = "Mod Organizer";
-static const char INSTANCE_KEY[] = "CurrentInstance";
+static const char INSTANCE_KEY[] = "CurrentInstance";
-InstanceManager::InstanceManager() : m_AppSettings(COMPANY_NAME, APPLICATION_NAME) {}
-InstanceManager& InstanceManager::instance() {
- static InstanceManager s_Instance;
- return s_Instance;
-}
-void InstanceManager::overrideInstance(const QString& instanceName) {
- m_overrideInstanceName = instanceName;
- m_overrideInstance = true;
+InstanceManager::InstanceManager()
+ : m_AppSettings(COMPANY_NAME, APPLICATION_NAME)
+{
}
-QString InstanceManager::currentInstance() const {
- if (m_overrideInstance)
- return m_overrideInstanceName;
- else
- return m_AppSettings.value(INSTANCE_KEY, "").toString();
+InstanceManager &InstanceManager::instance()
+{
+ static InstanceManager s_Instance;
+ return s_Instance;
}
-void InstanceManager::clearCurrentInstance() {
- setCurrentInstance("");
- m_Reset = true;
+void InstanceManager::overrideInstance(const QString& instanceName)
+{
+ m_overrideInstanceName = instanceName;
+ m_overrideInstance = true;
}
-void InstanceManager::setCurrentInstance(const QString& name) { m_AppSettings.setValue(INSTANCE_KEY, name); }
-
-bool InstanceManager::deleteLocalInstance(const QString& instanceId) const {
- bool result = true;
- QString instancePath =
- QDir::fromNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + instanceId);
- if (QMessageBox::warning(
- nullptr, QObject::tr("Deleting folder"),
- QObject::tr("I'm about to delete the following folder: \"%1\". Proceed?").arg(instancePath),
- QMessageBox::No | QMessageBox::Yes, QMessageBox::No) == QMessageBox::No) {
- return false;
- }
+QString InstanceManager::currentInstance() const
+{
+ if (m_overrideInstance)
+ return m_overrideInstanceName;
+ else
+ return m_AppSettings.value(INSTANCE_KEY, "").toString();
+}
- if (!MOBase::shellDelete(QStringList(instancePath), true)) {
- qWarning("Failed to shell-delete \"%s\" (errorcode %lu), trying regular delete", qPrintable(instancePath),
- ::GetLastError());
- if (!MOBase::removeDir(instancePath)) {
- qWarning("regular delete failed too");
- result = false;
- }
- }
+void InstanceManager::clearCurrentInstance()
+{
+ setCurrentInstance("");
+ m_Reset = true;
+}
- return result;
+void InstanceManager::setCurrentInstance(const QString &name)
+{
+ m_AppSettings.setValue(INSTANCE_KEY, name);
}
-QString InstanceManager::manageInstances(const QStringList& instanceList) const {
- SelectionDialog selection(
- QString("<h3>%1</h3><br>%2")
- .arg(QObject::tr("Choose Instance to Delete"))
- .arg(QObject::tr("Be Carefull! Deleting an Instance will remove all your files for that Instance (mods, "
- "downloads, profiles, configuration, ...). Custom paths outside of the instance folder "
- "for downloads, mods, etc. will be left untoched.")),
- nullptr);
- for (const QString& instance : instanceList) {
- selection.addChoice(instance, "", instance);
- }
+bool InstanceManager::deleteLocalInstance(const QString &instanceId) const
+{
+ bool result = true;
+ QString instancePath = QDir::fromNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + instanceId);
- if (selection.exec() == QDialog::Rejected) {
- return (chooseInstance(instances()));
- } else {
- QString choice = selection.getChoiceData().toString();
- {
- if (QMessageBox::warning(
- nullptr, QObject::tr("Are you sure?"),
- QObject::tr("Are you really sure you want to delete the Instance \"%1\" with all its files?")
- .arg(choice),
- QMessageBox::No | QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
- if (!deleteLocalInstance(choice)) {
- QMessageBox::warning(nullptr, QObject::tr("Failed to delete Instance"),
- QObject::tr("Could not delete Instance \"%1\"").arg(choice), QMessageBox::Ok);
- }
- }
- }
+ if (QMessageBox::warning(nullptr, QObject::tr("Deleting folder"),
+ QObject::tr("I'm about to delete the following folder: \"%1\". Proceed?").arg(instancePath), QMessageBox::No | QMessageBox::Yes, QMessageBox::No) == QMessageBox::No ){
+ return false;
+ }
+
+ if (!MOBase::shellDelete(QStringList(instancePath),true))
+ {
+ qWarning("Failed to shell-delete \"%s\" (errorcode %lu), trying regular delete", qPrintable(instancePath), ::GetLastError());
+ if (!MOBase::removeDir(instancePath))
+ {
+ qWarning("regular delete failed too");
+ result = false;
}
- return (manageInstances(instances()));
+ }
+
+ return result;
}
-QString InstanceManager::queryInstanceName(const QStringList& instanceList) const {
- QString instanceId;
- while (instanceId.isEmpty()) {
- QInputDialog dialog;
+QString InstanceManager::manageInstances(const QStringList &instanceList) const
+{
+ SelectionDialog selection(
+ QString("<h3>%1</h3><br>%2")
+ .arg(QObject::tr("Choose Instance to Delete"))
+ .arg(QObject::tr("Be Carefull! Deleting an Instance will remove all your files for that Instance (mods, downloads, profiles, configuration, ...). Custom paths outside of the instance folder for downloads, mods, etc. will be left untoched.")),
+ nullptr);
+ for (const QString &instance : instanceList)
+ {
+ selection.addChoice(instance, "", instance);
+ }
- dialog.setWindowTitle(QObject::tr("Enter a Name for the new Instance"));
- dialog.setLabelText(
- QObject::tr("Enter a new name or select one from the sugested list (only letters and numbers allowed):"));
- // would be neat if we could take the names from the game plugins but
- // the required initialization order requires the ini file to be
- // available *before* we load plugins
- dialog.setComboBoxItems(
- {"NewName", "Fallout 4", "SkyrimSE", "Skyrim", "Fallout 3", "Fallout NV", "FO4VR", "Oblivion"});
- dialog.setComboBoxEditable(true);
+ if (selection.exec() == QDialog::Rejected) {
+ return(chooseInstance(instances()));
+ }
+ else {
+ QString choice = selection.getChoiceData().toString();
+ {
+ if (QMessageBox::warning(nullptr, QObject::tr("Are you sure?"),
+ QObject::tr("Are you really sure you want to delete the Instance \"%1\" with all its files?").arg(choice), QMessageBox::No | QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
+ {
+ if (!deleteLocalInstance(choice))
+ {
+ QMessageBox::warning(nullptr, QObject::tr("Failed to delete Instance"),
+ QObject::tr("Could not delete Instance \"%1\"").arg(choice), QMessageBox::Ok);
+ }
+ }
+ }
+ }
+ return(manageInstances(instances()));
+}
- if (dialog.exec() == QDialog::Rejected) {
- throw MOBase::MyException(QObject::tr("Canceled"));
- }
- instanceId = dialog.textValue().replace(QRegExp("[^0-9a-zA-Z ]"), "");
+QString InstanceManager::queryInstanceName(const QStringList &instanceList) const
+{
+ QString instanceId;
+ while (instanceId.isEmpty()) {
+ QInputDialog dialog;
+
+ dialog.setWindowTitle(QObject::tr("Enter a Name for the new Instance"));
+ dialog.setLabelText(QObject::tr("Enter a new name or select one from the sugested list (only letters and numbers allowed):"));
+ // would be neat if we could take the names from the game plugins but
+ // the required initialization order requires the ini file to be
+ // available *before* we load plugins
+ dialog.setComboBoxItems({ "NewName", "Fallout 4", "SkyrimSE", "Skyrim", "Fallout 3",
+ "Fallout NV", "FO4VR", "Oblivion" });
+ dialog.setComboBoxEditable(true);
+
+ if (dialog.exec() == QDialog::Rejected) {
+ throw MOBase::MyException(QObject::tr("Canceled"));
+ }
+ instanceId = dialog.textValue().replace(QRegExp("[^0-9a-zA-Z ]"), "");
- bool alreadyExists = false;
- for (const QString& instance : instanceList) {
- if (instanceId == instance)
- alreadyExists = true;
- }
- if (alreadyExists) {
- QMessageBox msgBox;
- msgBox.setText(QObject::tr("The instance \"%1\" already exists.").arg(instanceId));
- msgBox.setInformativeText(
- QObject::tr("Please choose a different instance name, like: \"%1 1\" .").arg(instanceId));
- msgBox.exec();
- instanceId = "";
- }
+ bool alreadyExists=false;
+ for (const QString &instance : instanceList) {
+ if(instanceId==instance)
+ alreadyExists=true;
+ }
+ if(alreadyExists)
+ {
+ QMessageBox msgBox;
+ msgBox.setText( QObject::tr("The instance \"%1\" already exists.").arg(instanceId) );
+ msgBox.setInformativeText(QObject::tr("Please choose a different instance name, like: \"%1 1\" .").arg(instanceId));
+ msgBox.exec();
+ instanceId="";
}
- return instanceId;
+ }
+ return instanceId;
}
-QString InstanceManager::chooseInstance(const QStringList& instanceList) const {
- enum class Special : uint8_t { NewInstance, Portable, Manage };
- SelectionDialog selection(
- QString("<h3>%1</h3><br>%2")
- .arg(QObject::tr("Choose Instance"))
- .arg(QObject::tr("Each Instance is a full set of MO data files (mods, "
- "downloads, profiles, configuration, ...). You can use multiple "
- "instances for different games. Instances are stored in Appdata and can be accessed by "
- "all MO installations. "
- "If your MO folder is writable, you can also store a single instance locally (called "
- "a Portable install, and all the MO data files will be inside the installation folder).")),
- nullptr);
- selection.disableCancel();
- for (const QString& instance : instanceList) {
- selection.addChoice(instance, "", instance);
- }
+QString InstanceManager::chooseInstance(const QStringList &instanceList) const
+{
+ enum class Special : uint8_t {
+ NewInstance,
+ Portable,
+ Manage
+ };
- selection.addChoice(QIcon(":/MO/gui/add"), QObject::tr("New"), QObject::tr("Create a new instance."),
- static_cast<uint8_t>(Special::NewInstance));
+ SelectionDialog selection(
+ QString("<h3>%1</h3><br>%2")
+ .arg(QObject::tr("Choose Instance"))
+ .arg(QObject::tr(
+ "Each Instance is a full set of MO data files (mods, "
+ "downloads, profiles, configuration, ...). You can use multiple "
+ "instances for different games. Instances are stored in Appdata and can be accessed by all MO installations. "
+ "If your MO folder is writable, you can also store a single instance locally (called "
+ "a Portable install, and all the MO data files will be inside the installation folder).")),
+ nullptr);
+ selection.disableCancel();
+ for (const QString &instance : instanceList) {
+ selection.addChoice(instance, "", instance);
+ }
- if (QFileInfo(qApp->applicationDirPath()).isWritable()) {
- selection.addChoice(QIcon(":/MO/gui/package"), QObject::tr("Portable"), QObject::tr("Use MO folder for data."),
- static_cast<uint8_t>(Special::Portable));
- }
+ selection.addChoice(QIcon(":/MO/gui/add"), QObject::tr("New"),
+ QObject::tr("Create a new instance."),
+ static_cast<uint8_t>(Special::NewInstance));
+
+ if (QFileInfo(qApp->applicationDirPath()).isWritable()) {
+ selection.addChoice(QIcon(":/MO/gui/package"), QObject::tr("Portable"),
+ QObject::tr("Use MO folder for data."),
+ static_cast<uint8_t>(Special::Portable));
+ }
- selection.addChoice(QIcon(":/MO/gui/remove"), QObject::tr("Manage Instances"), QObject::tr("Delete an Instance."),
+ selection.addChoice(QIcon(":/MO/gui/remove"), QObject::tr("Manage Instances"),
+ QObject::tr("Delete an Instance."),
static_cast<uint8_t>(Special::Manage));
- if (selection.exec() == QDialog::Rejected) {
- qDebug("rejected");
- throw MOBase::MyException(QObject::tr("Canceled"));
- }
+ if (selection.exec() == QDialog::Rejected) {
+ qDebug("rejected");
+ throw MOBase::MyException(QObject::tr("Canceled"));
+ }
- QVariant choice = selection.getChoiceData();
+ QVariant choice = selection.getChoiceData();
- if (choice.type() == QVariant::String) {
- return choice.toString();
- } else {
- switch (choice.value<uint8_t>()) {
- case Special::NewInstance:
- return queryInstanceName(instanceList);
- case Special::Portable:
- return QString();
- case Special::Manage: {
+ if (choice.type() == QVariant::String) {
+ return choice.toString();
+ } else {
+ switch (choice.value<uint8_t>()) {
+ case Special::NewInstance: return queryInstanceName(instanceList);
+ case Special::Portable: return QString();
+ case Special::Manage: {
- return (manageInstances(instances()));
- }
- default:
- throw std::runtime_error("invalid selection");
- }
+ return(manageInstances(instances()));
+ }
+ default: throw std::runtime_error("invalid selection");
}
+ }
}
-QString InstanceManager::instancePath() const {
- return QDir::fromNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::DataLocation));
+
+QString InstanceManager::instancePath() const
+{
+ return QDir::fromNativeSeparators(
+ QStandardPaths::writableLocation(QStandardPaths::DataLocation));
}
-QStringList InstanceManager::instances() const {
- return QDir(instancePath()).entryList(QDir::Dirs | QDir::NoDotAndDotDot);
+
+QStringList InstanceManager::instances() const
+{
+ return QDir(instancePath()).entryList(QDir::Dirs | QDir::NoDotAndDotDot);
}
-bool InstanceManager::portableInstall() const {
- return QFile::exists(qApp->applicationDirPath() + "/" + QString::fromStdWString(AppConfig::iniFileName()));
+
+bool InstanceManager::portableInstall() const
+{
+ return QFile::exists(qApp->applicationDirPath() + "/" +
+ QString::fromStdWString(AppConfig::iniFileName()));
}
-void InstanceManager::createDataPath(const QString& dataPath) const {
- if (!QDir(dataPath).exists()) {
- if (!QDir().mkpath(dataPath)) {
- throw MOBase::MyException(QObject::tr("failed to create %1").arg(dataPath));
- } else {
- QMessageBox::information(nullptr, QObject::tr("Data directory created"),
- QObject::tr("New data directory created at %1. If you don't want to "
- "store a lot of data there, reconfigure the storage "
- "directories via settings.")
- .arg(dataPath));
- }
+
+void InstanceManager::createDataPath(const QString &dataPath) const
+{
+ if (!QDir(dataPath).exists()) {
+ if (!QDir().mkpath(dataPath)) {
+ throw MOBase::MyException(
+ QObject::tr("failed to create %1").arg(dataPath));
+ } else {
+ QMessageBox::information(
+ nullptr, QObject::tr("Data directory created"),
+ QObject::tr("New data directory created at %1. If you don't want to "
+ "store a lot of data there, reconfigure the storage "
+ "directories via settings.").arg(dataPath));
}
+ }
}
-QString InstanceManager::determineDataPath() {
- QString instanceId = currentInstance();
- if (instanceId.isEmpty() && !m_Reset && (m_overrideInstance || portableInstall())) {
- // startup, apparently using portable mode before
- return qApp->applicationDirPath();
- }
- QString dataPath =
- QDir::fromNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + instanceId);
+QString InstanceManager::determineDataPath()
+{
+ QString instanceId = currentInstance();
+ if (instanceId.isEmpty() && !m_Reset && (m_overrideInstance || portableInstall()))
+ {
+ // startup, apparently using portable mode before
+ return qApp->applicationDirPath();
+ }
- if (!m_overrideInstance && (instanceId.isEmpty() || !QFileInfo::exists(dataPath))) {
- instanceId = chooseInstance(instances());
- setCurrentInstance(instanceId);
- if (!instanceId.isEmpty()) {
- dataPath = QDir::fromNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" +
- instanceId);
- }
- }
+ QString dataPath = QDir::fromNativeSeparators(
+ QStandardPaths::writableLocation(QStandardPaths::DataLocation)
+ + "/" + instanceId);
- if (instanceId.isEmpty()) {
- return qApp->applicationDirPath();
- } else {
- createDataPath(dataPath);
- return dataPath;
+ if (!m_overrideInstance && (instanceId.isEmpty() || !QFileInfo::exists(dataPath))) {
+ instanceId = chooseInstance(instances());
+ setCurrentInstance(instanceId);
+ if (!instanceId.isEmpty()) {
+ dataPath = QDir::fromNativeSeparators(
+ QStandardPaths::writableLocation(QStandardPaths::DataLocation)
+ + "/" + instanceId);
}
+ }
+
+ if (instanceId.isEmpty()) {
+ return qApp->applicationDirPath();
+ } else {
+ createDataPath(dataPath);
+
+ return dataPath;
+ }
}
+
diff --git a/src/instancemanager.h b/src/instancemanager.h
index 9222872f..adedd78f 100644
--- a/src/instancemanager.h
+++ b/src/instancemanager.h
@@ -17,45 +17,51 @@ You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
+
#pragma once
-#include <QSettings>
+
#include <QString>
+#include <QSettings>
+
class InstanceManager {
public:
- static InstanceManager& instance();
- QString determineDataPath();
- void clearCurrentInstance();
+ static InstanceManager &instance();
+
+ QString determineDataPath();
+ void clearCurrentInstance();
- void overrideInstance(const QString& instanceName);
+ void overrideInstance(const QString& instanceName);
- QString currentInstance() const;
+ QString currentInstance() const;
private:
- InstanceManager();
- QString instancePath() const;
+ InstanceManager();
- QStringList instances() const;
+ QString instancePath() const;
- bool deleteLocalInstance(const QString& instanceId) const;
+ QStringList instances() const;
- QString manageInstances(const QStringList& instanceList) const;
+ bool deleteLocalInstance(const QString &instanceId) const;
- void setCurrentInstance(const QString& name);
+ QString manageInstances(const QStringList &instanceList) const;
- QString queryInstanceName(const QStringList& instanceList) const;
- QString chooseInstance(const QStringList& instanceList) const;
+ void setCurrentInstance(const QString &name);
- void createDataPath(const QString& dataPath) const;
- bool portableInstall() const;
+ QString queryInstanceName(const QStringList &instanceList) const;
+ QString chooseInstance(const QStringList &instanceList) const;
+
+ void createDataPath(const QString &dataPath) const;
+ bool portableInstall() const;
private:
- QSettings m_AppSettings;
- bool m_Reset{false};
- bool m_overrideInstance{false};
- QString m_overrideInstanceName;
+
+ QSettings m_AppSettings;
+ bool m_Reset {false};
+ bool m_overrideInstance{false};
+ QString m_overrideInstanceName;
};
diff --git a/src/iuserinterface.h b/src/iuserinterface.h
index 800d8b10..7ce71c24 100644
--- a/src/iuserinterface.h
+++ b/src/iuserinterface.h
@@ -1,36 +1,39 @@
#ifndef IUSERINTERFACE_H
#define IUSERINTERFACE_H
-#include "ilockedwaitingforprocess.h"
+
#include "modinfo.h"
-#include <delayedfilewriter.h>
-#include <ipluginmodpage.h>
+#include "ilockedwaitingforprocess.h"
#include <iplugintool.h>
+#include <ipluginmodpage.h>
+#include <delayedfilewriter.h>
class QSettings;
-class IUserInterface {
+class IUserInterface
+{
public:
- virtual void storeSettings(QSettings& settings) = 0;
- virtual void registerPluginTool(MOBase::IPluginTool* tool) = 0;
- virtual void registerModPage(MOBase::IPluginModPage* modPage) = 0;
+ virtual void storeSettings(QSettings &settings) = 0;
+
+ virtual void registerPluginTool(MOBase::IPluginTool *tool) = 0;
+ virtual void registerModPage(MOBase::IPluginModPage *modPage) = 0;
- virtual void installTranslator(const QString& name) = 0;
+ virtual void installTranslator(const QString &name) = 0;
- virtual void disconnectPlugins() = 0;
+ virtual void disconnectPlugins() = 0;
- virtual bool closeWindow() = 0;
- virtual void setWindowEnabled(bool enabled) = 0;
+ virtual bool closeWindow() = 0;
+ virtual void setWindowEnabled(bool enabled) = 0;
- virtual void displayModInformation(ModInfo::Ptr modInfo, unsigned int index, int tab) = 0;
+ virtual void displayModInformation(ModInfo::Ptr modInfo, unsigned int index, int tab) = 0;
- virtual void updateBSAList(const QStringList& defaultArchives, const QStringList& activeArchives) = 0;
+ virtual void updateBSAList(const QStringList &defaultArchives, const QStringList &activeArchives) = 0;
- virtual MOBase::DelayedFileWriterBase& archivesWriter() = 0;
+ virtual MOBase::DelayedFileWriterBase &archivesWriter() = 0;
- virtual ILockedWaitingForProcess* lock() = 0;
- virtual void unlock() = 0;
+ virtual ILockedWaitingForProcess* lock() = 0;
+ virtual void unlock() = 0;
};
#endif // IUSERINTERFACE_H
diff --git a/src/json.cpp b/src/json.cpp
index 704b60d8..05a2665a 100644
--- a/src/json.cpp
+++ b/src/json.cpp
@@ -23,319 +23,317 @@
#include "json.h"
namespace QtJson {
-static QString sanitizeString(QString str);
-static QByteArray join(const QList<QByteArray>& list, const QByteArray& sep);
-static QVariant parseValue(const QString& json, int& index, bool& success);
-static QVariant parseObject(const QString& json, int& index, bool& success);
-static QVariant parseArray(const QString& json, int& index, bool& success);
-static QVariant parseString(const QString& json, int& index, bool& success);
-static QVariant parseNumber(const QString& json, int& index);
-static int lastIndexOfNumber(const QString& json, int index);
-static void eatWhitespace(const QString& json, int& index);
-static int lookAhead(const QString& json, int index);
-static int nextToken(const QString& json, int& index);
+ static QString sanitizeString(QString str);
+ static QByteArray join(const QList<QByteArray> &list, const QByteArray &sep);
+ static QVariant parseValue(const QString &json, int &index, bool &success);
+ static QVariant parseObject(const QString &json, int &index, bool &success);
+ static QVariant parseArray(const QString &json, int &index, bool &success);
+ static QVariant parseString(const QString &json, int &index, bool &success);
+ static QVariant parseNumber(const QString &json, int &index);
+ static int lastIndexOfNumber(const QString &json, int index);
+ static void eatWhitespace(const QString &json, int &index);
+ static int lookAhead(const QString &json, int index);
+ static int nextToken(const QString &json, int &index);
-template <typename T>
-QByteArray serializeMap(const T& map, bool& success) {
- QByteArray str = "{ ";
- QList<QByteArray> pairs;
- for (typename T::const_iterator it = map.begin(), itend = map.end(); it != itend; ++it) {
- QByteArray serializedValue = serialize(it.value());
- if (serializedValue.isNull()) {
- success = false;
- break;
+ template<typename T>
+ QByteArray serializeMap(const T &map, bool &success) {
+ QByteArray str = "{ ";
+ QList<QByteArray> pairs;
+ for (typename T::const_iterator it = map.begin(), itend = map.end(); it != itend; ++it) {
+ QByteArray serializedValue = serialize(it.value());
+ if (serializedValue.isNull()) {
+ success = false;
+ break;
+ }
+ pairs << sanitizeString(it.key()).toUtf8() + " : " + serializedValue;
}
- pairs << sanitizeString(it.key()).toUtf8() + " : " + serializedValue;
+
+ str += join(pairs, ", ");
+ str += " }";
+ return str;
}
- str += join(pairs, ", ");
- str += " }";
- return str;
-}
-/**
- * parse
- */
-QVariant parse(const QString& json) {
- bool success = true;
- return parse(json, success);
-}
+ /**
+ * parse
+ */
+ QVariant parse(const QString &json) {
+ bool success = true;
+ return parse(json, success);
+ }
-/**
- * parse
- */
-QVariant parse(const QString& json, bool& success) {
- success = true;
+ /**
+ * parse
+ */
+ QVariant parse(const QString &json, bool &success) {
+ success = true;
- // Return an empty QVariant if the JSON data is either null or empty
- if (!json.isNull() || !json.isEmpty()) {
- QString data = json;
- // We'll start from index 0
- int index = 0;
+ // Return an empty QVariant if the JSON data is either null or empty
+ if (!json.isNull() || !json.isEmpty()) {
+ QString data = json;
+ // We'll start from index 0
+ int index = 0;
- // Parse the first value
- QVariant value = parseValue(data, index, success);
+ // Parse the first value
+ QVariant value = parseValue(data, index, success);
- // Return the parsed value
- return value;
- } else {
- // Return the empty QVariant
- return QVariant();
+ // Return the parsed value
+ return value;
+ } else {
+ // Return the empty QVariant
+ return QVariant();
+ }
+ }
+
+ QByteArray serialize(const QVariant &data) {
+ bool success = true;
+ return serialize(data, success);
}
-}
-QByteArray serialize(const QVariant& data) {
- bool success = true;
- return serialize(data, success);
-}
+ QByteArray serialize(const QVariant &data, bool &success) {
+ QByteArray str;
+ success = true;
-QByteArray serialize(const QVariant& data, bool& success) {
- QByteArray str;
- success = true;
+ if (!data.isValid()) { // invalid or null?
+ str = "null";
+ } else if ((data.type() == QVariant::List) ||
+ (data.type() == QVariant::StringList)) { // variant is a list?
+ QList<QByteArray> values;
+ const QVariantList list = data.toList();
+ Q_FOREACH(const QVariant& v, list) {
+ QByteArray serializedValue = serialize(v);
+ if (serializedValue.isNull()) {
+ success = false;
+ break;
+ }
+ values << serializedValue;
+ }
- if (!data.isValid()) { // invalid or null?
- str = "null";
- } else if ((data.type() == QVariant::List) || (data.type() == QVariant::StringList)) { // variant is a list?
- QList<QByteArray> values;
- const QVariantList list = data.toList();
- Q_FOREACH (const QVariant& v, list) {
- QByteArray serializedValue = serialize(v);
- if (serializedValue.isNull()) {
+ str = "[ " + join( values, ", " ) + " ]";
+ } else if (data.type() == QVariant::Hash) { // variant is a hash?
+ str = serializeMap<>(data.toHash(), success);
+ } else if (data.type() == QVariant::Map) { // variant is a map?
+ str = serializeMap<>(data.toMap(), success);
+ } else if ((data.type() == QVariant::String) ||
+ (data.type() == QVariant::ByteArray)) {// a string or a byte array?
+ str = sanitizeString(data.toString()).toUtf8();
+ } else if (data.type() == QVariant::Double) { // double?
+ double value = data.toDouble();
+ if ((value - value) == 0.0) {
+ str = QByteArray::number(value, 'g');
+ if (!str.contains(".") && ! str.contains("e")) {
+ str += ".0";
+ }
+ } else {
success = false;
- break;
}
- values << serializedValue;
+ } else if (data.type() == QVariant::Bool) { // boolean value?
+ str = data.toBool() ? "true" : "false";
+ } else if (data.type() == QVariant::ULongLong) { // large unsigned number?
+ str = QByteArray::number(data.value<qulonglong>());
+ } else if (data.canConvert<qlonglong>()) { // any signed number?
+ str = QByteArray::number(data.value<qlonglong>());
+ } else if (data.canConvert<long>()) { //TODO: this code is never executed
+ str = QString::number(data.value<long>()).toUtf8();
+ } else if (data.canConvert<QString>()) { // can value be converted to string?
+ // this will catch QDate, QDateTime, QUrl, ...
+ str = sanitizeString(data.toString()).toUtf8();
+ } else {
+ success = false;
}
- str = "[ " + join(values, ", ") + " ]";
- } else if (data.type() == QVariant::Hash) { // variant is a hash?
- str = serializeMap<>(data.toHash(), success);
- } else if (data.type() == QVariant::Map) { // variant is a map?
- str = serializeMap<>(data.toMap(), success);
- } else if ((data.type() == QVariant::String) || (data.type() == QVariant::ByteArray)) { // a string or a byte array?
- str = sanitizeString(data.toString()).toUtf8();
- } else if (data.type() == QVariant::Double) { // double?
- double value = data.toDouble();
- if ((value - value) == 0.0) {
- str = QByteArray::number(value, 'g');
- if (!str.contains(".") && !str.contains("e")) {
- str += ".0";
- }
+ if (success) {
+ return str;
} else {
- success = false;
+ return QByteArray();
}
- } else if (data.type() == QVariant::Bool) { // boolean value?
- str = data.toBool() ? "true" : "false";
- } else if (data.type() == QVariant::ULongLong) { // large unsigned number?
- str = QByteArray::number(data.value<qulonglong>());
- } else if (data.canConvert<qlonglong>()) { // any signed number?
- str = QByteArray::number(data.value<qlonglong>());
- } else if (data.canConvert<long>()) { // TODO: this code is never executed
- str = QString::number(data.value<long>()).toUtf8();
- } else if (data.canConvert<QString>()) { // can value be converted to string?
- // this will catch QDate, QDateTime, QUrl, ...
- str = sanitizeString(data.toString()).toUtf8();
- } else {
- success = false;
}
- if (success) {
- return str;
- } else {
- return QByteArray();
+ QString serializeStr(const QVariant &data) {
+ return QString::fromUtf8(serialize(data));
}
-}
-QString serializeStr(const QVariant& data) { return QString::fromUtf8(serialize(data)); }
+ QString serializeStr(const QVariant &data, bool &success) {
+ return QString::fromUtf8(serialize(data, success));
+ }
-QString serializeStr(const QVariant& data, bool& success) { return QString::fromUtf8(serialize(data, success)); }
-/**
- * \enum JsonToken
- */
-enum JsonToken {
- JsonTokenNone = 0,
- JsonTokenCurlyOpen = 1,
- JsonTokenCurlyClose = 2,
- JsonTokenSquaredOpen = 3,
- JsonTokenSquaredClose = 4,
- JsonTokenColon = 5,
- JsonTokenComma = 6,
- JsonTokenString = 7,
- JsonTokenNumber = 8,
- JsonTokenTrue = 9,
- JsonTokenFalse = 10,
- JsonTokenNull = 11
-};
+ /**
+ * \enum JsonToken
+ */
+ enum JsonToken {
+ JsonTokenNone = 0,
+ JsonTokenCurlyOpen = 1,
+ JsonTokenCurlyClose = 2,
+ JsonTokenSquaredOpen = 3,
+ JsonTokenSquaredClose = 4,
+ JsonTokenColon = 5,
+ JsonTokenComma = 6,
+ JsonTokenString = 7,
+ JsonTokenNumber = 8,
+ JsonTokenTrue = 9,
+ JsonTokenFalse = 10,
+ JsonTokenNull = 11
+ };
-static QString sanitizeString(QString str) {
- str.replace(QLatin1String("\\"), QLatin1String("\\\\"));
- str.replace(QLatin1String("\""), QLatin1String("\\\""));
- str.replace(QLatin1String("\b"), QLatin1String("\\b"));
- str.replace(QLatin1String("\f"), QLatin1String("\\f"));
- str.replace(QLatin1String("\n"), QLatin1String("\\n"));
- str.replace(QLatin1String("\r"), QLatin1String("\\r"));
- str.replace(QLatin1String("\t"), QLatin1String("\\t"));
- return QString(QLatin1String("\"%1\"")).arg(str);
-}
+ static QString sanitizeString(QString str) {
+ str.replace(QLatin1String("\\"), QLatin1String("\\\\"));
+ str.replace(QLatin1String("\""), QLatin1String("\\\""));
+ str.replace(QLatin1String("\b"), QLatin1String("\\b"));
+ str.replace(QLatin1String("\f"), QLatin1String("\\f"));
+ str.replace(QLatin1String("\n"), QLatin1String("\\n"));
+ str.replace(QLatin1String("\r"), QLatin1String("\\r"));
+ str.replace(QLatin1String("\t"), QLatin1String("\\t"));
+ return QString(QLatin1String("\"%1\"")).arg(str);
+ }
-static QByteArray join(const QList<QByteArray>& list, const QByteArray& sep) {
- QByteArray res;
- Q_FOREACH (const QByteArray& i, list) {
- if (!res.isEmpty()) {
- res += sep;
+ static QByteArray join(const QList<QByteArray> &list, const QByteArray &sep) {
+ QByteArray res;
+ Q_FOREACH(const QByteArray &i, list) {
+ if (!res.isEmpty()) {
+ res += sep;
+ }
+ res += i;
}
- res += i;
+ return res;
}
- return res;
-}
-/**
- * parseValue
- */
-static QVariant parseValue(const QString& json, int& index, bool& success) {
- // Determine what kind of data we should parse by
- // checking out the upcoming token
- switch (lookAhead(json, index)) {
- case JsonTokenString:
- return parseString(json, index, success);
- case JsonTokenNumber:
- return parseNumber(json, index);
- case JsonTokenCurlyOpen:
- return parseObject(json, index, success);
- case JsonTokenSquaredOpen:
- return parseArray(json, index, success);
- case JsonTokenTrue:
- nextToken(json, index);
- return QVariant(true);
- case JsonTokenFalse:
- nextToken(json, index);
- return QVariant(false);
- case JsonTokenNull:
- nextToken(json, index);
+ /**
+ * parseValue
+ */
+ static QVariant parseValue(const QString &json, int &index, bool &success) {
+ // Determine what kind of data we should parse by
+ // checking out the upcoming token
+ switch(lookAhead(json, index)) {
+ case JsonTokenString:
+ return parseString(json, index, success);
+ case JsonTokenNumber:
+ return parseNumber(json, index);
+ case JsonTokenCurlyOpen:
+ return parseObject(json, index, success);
+ case JsonTokenSquaredOpen:
+ return parseArray(json, index, success);
+ case JsonTokenTrue:
+ nextToken(json, index);
+ return QVariant(true);
+ case JsonTokenFalse:
+ nextToken(json, index);
+ return QVariant(false);
+ case JsonTokenNull:
+ nextToken(json, index);
+ return QVariant();
+ case JsonTokenNone:
+ break;
+ }
+
+ // If there were no tokens, flag the failure and return an empty QVariant
+ success = false;
return QVariant();
- case JsonTokenNone:
- break;
}
- // If there were no tokens, flag the failure and return an empty QVariant
- success = false;
- return QVariant();
-}
+ /**
+ * parseObject
+ */
+ static QVariant parseObject(const QString &json, int &index, bool &success) {
+ QVariantMap map;
+ int token;
-/**
- * parseObject
- */
-static QVariant parseObject(const QString& json, int& index, bool& success) {
- QVariantMap map;
- int token;
+ // Get rid of the whitespace and increment index
+ nextToken(json, index);
- // Get rid of the whitespace and increment index
- nextToken(json, index);
+ // Loop through all of the key/value pairs of the object
+ bool done = false;
+ while (!done) {
+ // Get the upcoming token
+ token = lookAhead(json, index);
- // Loop through all of the key/value pairs of the object
- bool done = false;
- while (!done) {
- // Get the upcoming token
- token = lookAhead(json, index);
+ if (token == JsonTokenNone) {
+ success = false;
+ return QVariantMap();
+ } else if (token == JsonTokenComma) {
+ nextToken(json, index);
+ } else if (token == JsonTokenCurlyClose) {
+ nextToken(json, index);
+ return map;
+ } else {
+ // Parse the key/value pair's name
+ QString name = parseString(json, index, success).toString();
- if (token == JsonTokenNone) {
- success = false;
- return QVariantMap();
- } else if (token == JsonTokenComma) {
- nextToken(json, index);
- } else if (token == JsonTokenCurlyClose) {
- nextToken(json, index);
- return map;
- } else {
- // Parse the key/value pair's name
- QString name = parseString(json, index, success).toString();
+ if (!success) {
+ return QVariantMap();
+ }
- if (!success) {
- return QVariantMap();
- }
+ // Get the next token
+ token = nextToken(json, index);
- // Get the next token
- token = nextToken(json, index);
+ // If the next token is not a colon, flag the failure
+ // return an empty QVariant
+ if (token != JsonTokenColon) {
+ success = false;
+ return QVariant(QVariantMap());
+ }
- // If the next token is not a colon, flag the failure
- // return an empty QVariant
- if (token != JsonTokenColon) {
- success = false;
- return QVariant(QVariantMap());
- }
+ // Parse the key/value pair's value
+ QVariant value = parseValue(json, index, success);
- // Parse the key/value pair's value
- QVariant value = parseValue(json, index, success);
+ if (!success) {
+ return QVariantMap();
+ }
- if (!success) {
- return QVariantMap();
+ // Assign the value to the key in the map
+ map[name] = value;
}
-
- // Assign the value to the key in the map
- map[name] = value;
}
- }
- // Return the map successfully
- return QVariant(map);
-}
+ // Return the map successfully
+ return QVariant(map);
+ }
-/**
- * parseArray
- */
-static QVariant parseArray(const QString& json, int& index, bool& success) {
- QVariantList list;
+ /**
+ * parseArray
+ */
+ static QVariant parseArray(const QString &json, int &index, bool &success) {
+ QVariantList list;
- nextToken(json, index);
+ nextToken(json, index);
- bool done = false;
- while (!done) {
- int token = lookAhead(json, index);
+ bool done = false;
+ while(!done) {
+ int token = lookAhead(json, index);
- if (token == JsonTokenNone) {
- success = false;
- return QVariantList();
- } else if (token == JsonTokenComma) {
- nextToken(json, index);
- } else if (token == JsonTokenSquaredClose) {
- nextToken(json, index);
- break;
- } else {
- QVariant value = parseValue(json, index, success);
- if (!success) {
+ if (token == JsonTokenNone) {
+ success = false;
return QVariantList();
+ } else if (token == JsonTokenComma) {
+ nextToken(json, index);
+ } else if (token == JsonTokenSquaredClose) {
+ nextToken(json, index);
+ break;
+ } else {
+ QVariant value = parseValue(json, index, success);
+ if (!success) {
+ return QVariantList();
+ }
+ list.push_back(value);
}
- list.push_back(value);
}
- }
-
- return QVariant(list);
-}
-/**
- * parseString
- */
-static QVariant parseString(const QString& json, int& index, bool& success) {
- QString s;
- QChar c;
-
- eatWhitespace(json, index);
+ return QVariant(list);
+ }
- c = json[index++];
+ /**
+ * parseString
+ */
+ static QVariant parseString(const QString &json, int &index, bool &success) {
+ QString s;
+ QChar c;
- bool complete = false;
- while (!complete) {
- if (index == json.size()) {
- break;
- }
+ eatWhitespace(json, index);
c = json[index++];
- if (c == '\"') {
- complete = true;
- break;
- } else if (c == '\\') {
+ bool complete = false;
+ while(!complete) {
if (index == json.size()) {
break;
}
@@ -343,185 +341,182 @@ static QVariant parseString(const QString& json, int& index, bool& success) {
c = json[index++];
if (c == '\"') {
- s.append('\"');
+ complete = true;
+ break;
} else if (c == '\\') {
- s.append('\\');
- } else if (c == '/') {
- s.append('/');
- } else if (c == 'b') {
- s.append('\b');
- } else if (c == 'f') {
- s.append('\f');
- } else if (c == 'n') {
- s.append('\n');
- } else if (c == 'r') {
- s.append('\r');
- } else if (c == 't') {
- s.append('\t');
- } else if (c == 'u') {
- int remainingLength = json.size() - index;
- if (remainingLength >= 4) {
- QString unicodeStr = json.mid(index, 4);
+ if (index == json.size()) {
+ break;
+ }
- int symbol = unicodeStr.toInt(0, 16);
+ c = json[index++];
- s.append(QChar(symbol));
+ if (c == '\"') {
+ s.append('\"');
+ } else if (c == '\\') {
+ s.append('\\');
+ } else if (c == '/') {
+ s.append('/');
+ } else if (c == 'b') {
+ s.append('\b');
+ } else if (c == 'f') {
+ s.append('\f');
+ } else if (c == 'n') {
+ s.append('\n');
+ } else if (c == 'r') {
+ s.append('\r');
+ } else if (c == 't') {
+ s.append('\t');
+ } else if (c == 'u') {
+ int remainingLength = json.size() - index;
+ if (remainingLength >= 4) {
+ QString unicodeStr = json.mid(index, 4);
- index += 4;
- } else {
- break;
+ int symbol = unicodeStr.toInt(0, 16);
+
+ s.append(QChar(symbol));
+
+ index += 4;
+ } else {
+ break;
+ }
}
+ } else {
+ s.append(c);
}
- } else {
- s.append(c);
}
- }
- if (!complete) {
- success = false;
- return QVariant();
- }
+ if (!complete) {
+ success = false;
+ return QVariant();
+ }
- return QVariant(s);
-}
+ return QVariant(s);
+ }
-/**
- * parseNumber
- */
-static QVariant parseNumber(const QString& json, int& index) {
- eatWhitespace(json, index);
+ /**
+ * parseNumber
+ */
+ static QVariant parseNumber(const QString &json, int &index) {
+ eatWhitespace(json, index);
- int lastIndex = lastIndexOfNumber(json, index);
- int charLength = (lastIndex - index) + 1;
- QString numberStr;
+ int lastIndex = lastIndexOfNumber(json, index);
+ int charLength = (lastIndex - index) + 1;
+ QString numberStr;
- numberStr = json.mid(index, charLength);
+ numberStr = json.mid(index, charLength);
- index = lastIndex + 1;
- bool ok;
+ index = lastIndex + 1;
+ bool ok;
- if (numberStr.contains('.')) {
- return QVariant(numberStr.toDouble(nullptr));
- } else if (numberStr.startsWith('-')) {
- int i = numberStr.toInt(&ok);
- if (!ok) {
- qlonglong ll = numberStr.toLongLong(&ok);
- return ok ? ll : QVariant(numberStr);
- }
- return i;
- } else {
- uint u = numberStr.toUInt(&ok);
- if (!ok) {
- qulonglong ull = numberStr.toULongLong(&ok);
- return ok ? ull : QVariant(numberStr);
+ if (numberStr.contains('.')) {
+ return QVariant(numberStr.toDouble(nullptr));
+ } else if (numberStr.startsWith('-')) {
+ int i = numberStr.toInt(&ok);
+ if (!ok) {
+ qlonglong ll = numberStr.toLongLong(&ok);
+ return ok ? ll : QVariant(numberStr);
+ }
+ return i;
+ } else {
+ uint u = numberStr.toUInt(&ok);
+ if (!ok) {
+ qulonglong ull = numberStr.toULongLong(&ok);
+ return ok ? ull : QVariant(numberStr);
+ }
+ return u;
}
- return u;
}
-}
-/**
- * lastIndexOfNumber
- */
-static int lastIndexOfNumber(const QString& json, int index) {
- int lastIndex;
+ /**
+ * lastIndexOfNumber
+ */
+ static int lastIndexOfNumber(const QString &json, int index) {
+ int lastIndex;
- for (lastIndex = index; lastIndex < json.size(); lastIndex++) {
- if (QString("0123456789+-.eE").indexOf(json[lastIndex]) == -1) {
- break;
+ for(lastIndex = index; lastIndex < json.size(); lastIndex++) {
+ if (QString("0123456789+-.eE").indexOf(json[lastIndex]) == -1) {
+ break;
+ }
}
- }
- return lastIndex - 1;
-}
+ return lastIndex -1;
+ }
-/**
- * eatWhitespace
- */
-static void eatWhitespace(const QString& json, int& index) {
- for (; index < json.size(); index++) {
- if (QString(" \t\n\r").indexOf(json[index]) == -1) {
- break;
+ /**
+ * eatWhitespace
+ */
+ static void eatWhitespace(const QString &json, int &index) {
+ for(; index < json.size(); index++) {
+ if (QString(" \t\n\r").indexOf(json[index]) == -1) {
+ break;
+ }
}
}
-}
-/**
- * lookAhead
- */
-static int lookAhead(const QString& json, int index) {
- int saveIndex = index;
- return nextToken(json, saveIndex);
-}
+ /**
+ * lookAhead
+ */
+ static int lookAhead(const QString &json, int index) {
+ int saveIndex = index;
+ return nextToken(json, saveIndex);
+ }
-/**
- * nextToken
- */
-static int nextToken(const QString& json, int& index) {
- eatWhitespace(json, index);
+ /**
+ * nextToken
+ */
+ static int nextToken(const QString &json, int &index) {
+ eatWhitespace(json, index);
- if (index == json.size()) {
- return JsonTokenNone;
- }
+ if (index == json.size()) {
+ return JsonTokenNone;
+ }
- QChar c = json[index];
- index++;
- switch (c.toLatin1()) {
- case '{':
- return JsonTokenCurlyOpen;
- case '}':
- return JsonTokenCurlyClose;
- case '[':
- return JsonTokenSquaredOpen;
- case ']':
- return JsonTokenSquaredClose;
- case ',':
- return JsonTokenComma;
- case '"':
- return JsonTokenString;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case '-':
- return JsonTokenNumber;
- case ':':
- return JsonTokenColon;
- }
- index--; // ^ WTF?
+ QChar c = json[index];
+ index++;
+ switch(c.toLatin1()) {
+ case '{': return JsonTokenCurlyOpen;
+ case '}': return JsonTokenCurlyClose;
+ case '[': return JsonTokenSquaredOpen;
+ case ']': return JsonTokenSquaredClose;
+ case ',': return JsonTokenComma;
+ case '"': return JsonTokenString;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ case '-': return JsonTokenNumber;
+ case ':': return JsonTokenColon;
+ }
+ index--; // ^ WTF?
- int remainingLength = json.size() - index;
+ int remainingLength = json.size() - index;
- // True
- if (remainingLength >= 4) {
- if (json[index] == 't' && json[index + 1] == 'r' && json[index + 2] == 'u' && json[index + 3] == 'e') {
- index += 4;
- return JsonTokenTrue;
+ // True
+ if (remainingLength >= 4) {
+ if (json[index] == 't' && json[index + 1] == 'r' &&
+ json[index + 2] == 'u' && json[index + 3] == 'e') {
+ index += 4;
+ return JsonTokenTrue;
+ }
}
- }
- // False
- if (remainingLength >= 5) {
- if (json[index] == 'f' && json[index + 1] == 'a' && json[index + 2] == 'l' && json[index + 3] == 's' &&
- json[index + 4] == 'e') {
- index += 5;
- return JsonTokenFalse;
+ // False
+ if (remainingLength >= 5) {
+ if (json[index] == 'f' && json[index + 1] == 'a' &&
+ json[index + 2] == 'l' && json[index + 3] == 's' &&
+ json[index + 4] == 'e') {
+ index += 5;
+ return JsonTokenFalse;
+ }
}
- }
- // Null
- if (remainingLength >= 4) {
- if (json[index] == 'n' && json[index + 1] == 'u' && json[index + 2] == 'l' && json[index + 3] == 'l') {
- index += 4;
- return JsonTokenNull;
+ // Null
+ if (remainingLength >= 4) {
+ if (json[index] == 'n' && json[index + 1] == 'u' &&
+ json[index + 2] == 'l' && json[index + 3] == 'l') {
+ index += 4;
+ return JsonTokenNull;
+ }
}
- }
- return JsonTokenNone;
-}
-} // namespace QtJson
+ return JsonTokenNone;
+ }
+} //end namespace
diff --git a/src/json.h b/src/json.h
index 2247bd53..57842e37 100644
--- a/src/json.h
+++ b/src/json.h
@@ -23,8 +23,9 @@
#ifndef JSON_H
#define JSON_H
-#include <QString>
#include <QVariant>
+#include <QString>
+
/**
* \namespace QtJson
@@ -33,61 +34,61 @@
* Json parses a JSON data into a QVariant hierarchy.
*/
namespace QtJson {
-typedef QVariantMap JsonObject;
-typedef QVariantList JsonArray;
+ typedef QVariantMap JsonObject;
+ typedef QVariantList JsonArray;
-/**
- * Parse a JSON string
- *
- * \param json The JSON data
- */
-QVariant parse(const QString& json);
+ /**
+ * Parse a JSON string
+ *
+ * \param json The JSON data
+ */
+ QVariant parse(const QString &json);
-/**
- * Parse a JSON string
- *
- * \param json The JSON data
- * \param success The success of the parsing
- */
-QVariant parse(const QString& json, bool& success);
+ /**
+ * Parse a JSON string
+ *
+ * \param json The JSON data
+ * \param success The success of the parsing
+ */
+ QVariant parse(const QString &json, bool &success);
-/**
- * This method generates a textual JSON representation
- *
- * \param data The JSON data generated by the parser.
- *
- * \return QByteArray Textual JSON representation in UTF-8
- */
-QByteArray serialize(const QVariant& data);
+ /**
+ * This method generates a textual JSON representation
+ *
+ * \param data The JSON data generated by the parser.
+ *
+ * \return QByteArray Textual JSON representation in UTF-8
+ */
+ QByteArray serialize(const QVariant &data);
-/**
- * This method generates a textual JSON representation
- *
- * \param data The JSON data generated by the parser.
- * \param success The success of the serialization
- *
- * \return QByteArray Textual JSON representation in UTF-8
- */
-QByteArray serialize(const QVariant& data, bool& success);
+ /**
+ * This method generates a textual JSON representation
+ *
+ * \param data The JSON data generated by the parser.
+ * \param success The success of the serialization
+ *
+ * \return QByteArray Textual JSON representation in UTF-8
+ */
+ QByteArray serialize(const QVariant &data, bool &success);
-/**
- * This method generates a textual JSON representation
- *
- * \param data The JSON data generated by the parser.
- *
- * \return QString Textual JSON representation
- */
-QString serializeStr(const QVariant& data);
+ /**
+ * This method generates a textual JSON representation
+ *
+ * \param data The JSON data generated by the parser.
+ *
+ * \return QString Textual JSON representation
+ */
+ QString serializeStr(const QVariant &data);
-/**
- * This method generates a textual JSON representation
- *
- * \param data The JSON data generated by the parser.
- * \param success The success of the serialization
- *
- * \return QString Textual JSON representation
- */
-QString serializeStr(const QVariant& data, bool& success);
-} // namespace QtJson
+ /**
+ * This method generates a textual JSON representation
+ *
+ * \param data The JSON data generated by the parser.
+ * \param success The success of the serialization
+ *
+ * \return QString Textual JSON representation
+ */
+ QString serializeStr(const QVariant &data, bool &success);
+}
-#endif // JSON_H
+#endif //JSON_H
diff --git a/src/loadmechanism.cpp b/src/loadmechanism.cpp
index 1aef11dd..7ad36ac7 100644
--- a/src/loadmechanism.cpp
+++ b/src/loadmechanism.cpp
@@ -18,273 +18,299 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "loadmechanism.h"
-#include "util.h"
#include "utility.h"
-#include <QCoreApplication>
-#include <QCryptographicHash>
-#include <QDir>
+#include "util.h"
+#include <iplugingame.h>
+#include <scriptextender.h>
+#include <appconfig.h>
#include <QFile>
#include <QFileInfo>
-#include <QMessageBox>
+#include <QDir>
#include <QString>
-#include <appconfig.h>
-#include <iplugingame.h>
-#include <scriptextender.h>
+#include <QMessageBox>
+#include <QCryptographicHash>
+#include <QCoreApplication>
+
using namespace MOBase;
using namespace MOShared;
-LoadMechanism::LoadMechanism() : m_SelectedMechanism(LOAD_MODORGANIZER) {}
-void LoadMechanism::writeHintFile(const QDir& targetDirectory) {
- QString hintFilePath = targetDirectory.absoluteFilePath("mo_path.txt");
- QFile hintFile(hintFilePath);
- if (hintFile.exists()) {
- hintFile.remove();
- }
- if (!hintFile.open(QIODevice::WriteOnly)) {
- throw MyException(QObject::tr("failed to open %1: %2").arg(hintFilePath).arg(hintFile.errorString()));
- }
- hintFile.write(qApp->applicationDirPath().toUtf8().constData());
- hintFile.close();
+LoadMechanism::LoadMechanism()
+ : m_SelectedMechanism(LOAD_MODORGANIZER)
+{
}
-void LoadMechanism::removeHintFile(QDir targetDirectory) { targetDirectory.remove("mo_path.txt"); }
+void LoadMechanism::writeHintFile(const QDir &targetDirectory)
+{
+ QString hintFilePath = targetDirectory.absoluteFilePath("mo_path.txt");
+ QFile hintFile(hintFilePath);
+ if (hintFile.exists()) {
+ hintFile.remove();
+ }
+ if (!hintFile.open(QIODevice::WriteOnly)) {
+ throw MyException(QObject::tr("failed to open %1: %2").arg(hintFilePath).arg(hintFile.errorString()));
+ }
+ hintFile.write(qApp->applicationDirPath().toUtf8().constData());
+ hintFile.close();
+}
-bool LoadMechanism::isDirectLoadingSupported() {
- // FIXME: Seriously? isn't there a 'do i need steam' thing?
- IPluginGame const* game = qApp->property("managed_game").value<IPluginGame*>();
- if (game->gameName().compare("oblivion", Qt::CaseInsensitive) == 0) {
- // oblivion can be loaded directly if it's not the steam variant
- return !game->gameDirectory().exists("steam_api.dll");
- } else {
- // all other games work afaik
- return true;
- }
+
+void LoadMechanism::removeHintFile(QDir targetDirectory)
+{
+ targetDirectory.remove("mo_path.txt");
}
-bool LoadMechanism::isScriptExtenderSupported() {
- IPluginGame const* game = qApp->property("managed_game").value<IPluginGame*>();
- ScriptExtender* extender = game->feature<ScriptExtender>();
- // test if there even is an extender for the managed game and if so whether it's installed
- return extender != nullptr && extender->isInstalled();
+bool LoadMechanism::isDirectLoadingSupported()
+{
+ //FIXME: Seriously? isn't there a 'do i need steam' thing?
+ IPluginGame const *game = qApp->property("managed_game").value<IPluginGame*>();
+ if (game->gameName().compare("oblivion", Qt::CaseInsensitive) == 0) {
+ // oblivion can be loaded directly if it's not the steam variant
+ return !game->gameDirectory().exists("steam_api.dll");
+ } else {
+ // all other games work afaik
+ return true;
+ }
}
-bool LoadMechanism::isProxyDLLSupported() {
- // using steam_api.dll as the proxy is way too game specific as many games will have different
- // versions of that dll.
- // plus: the proxy dll hasn't been working for at least the whole 1.12.x versions of MO and
- // noone reported it so why maintain an unused feature?
- return false;
- /* IPluginGame const *game = qApp->property("managed_game").value<IPluginGame*>();
- return game->gameDirectory().exists(QString::fromStdWString(AppConfig::proxyDLLTarget()));*/
+bool LoadMechanism::isScriptExtenderSupported()
+{
+ IPluginGame const *game = qApp->property("managed_game").value<IPluginGame*>();
+ ScriptExtender *extender = game->feature<ScriptExtender>();
+
+ // test if there even is an extender for the managed game and if so whether it's installed
+ return extender != nullptr && extender->isInstalled();
}
-bool LoadMechanism::hashIdentical(const QString& fileNameLHS, const QString& fileNameRHS) {
- QFile fileLHS(fileNameLHS);
- if (!fileLHS.open(QIODevice::ReadOnly)) {
- throw MyException(QObject::tr("%1 not found").arg(fileNameLHS));
- }
- QByteArray dataLHS = fileLHS.readAll();
- QByteArray hashLHS = QCryptographicHash::hash(dataLHS, QCryptographicHash::Md5);
+bool LoadMechanism::isProxyDLLSupported()
+{
+ // using steam_api.dll as the proxy is way too game specific as many games will have different
+ // versions of that dll.
+ // plus: the proxy dll hasn't been working for at least the whole 1.12.x versions of MO and
+ // noone reported it so why maintain an unused feature?
+ return false;
+/* IPluginGame const *game = qApp->property("managed_game").value<IPluginGame*>();
+ return game->gameDirectory().exists(QString::fromStdWString(AppConfig::proxyDLLTarget()));*/
+}
- fileLHS.close();
- QFile fileRHS(fileNameRHS);
- if (!fileRHS.open(QIODevice::ReadOnly)) {
- throw MyException(QObject::tr("%1 not found").arg(fileNameRHS));
- }
- QByteArray dataRHS = fileRHS.readAll();
- QByteArray hashRHS = QCryptographicHash::hash(dataRHS, QCryptographicHash::Md5);
+bool LoadMechanism::hashIdentical(const QString &fileNameLHS, const QString &fileNameRHS)
+{
+ QFile fileLHS(fileNameLHS);
+ if (!fileLHS.open(QIODevice::ReadOnly)) {
+ throw MyException(QObject::tr("%1 not found").arg(fileNameLHS));
+ }
+ QByteArray dataLHS = fileLHS.readAll();
+ QByteArray hashLHS = QCryptographicHash::hash(dataLHS, QCryptographicHash::Md5);
+
+ fileLHS.close();
- fileRHS.close();
+ QFile fileRHS(fileNameRHS);
+ if (!fileRHS.open(QIODevice::ReadOnly)) {
+ throw MyException(QObject::tr("%1 not found").arg(fileNameRHS));
+ }
+ QByteArray dataRHS = fileRHS.readAll();
+ QByteArray hashRHS = QCryptographicHash::hash(dataRHS, QCryptographicHash::Md5);
- return hashLHS == hashRHS;
+ fileRHS.close();
+
+ return hashLHS == hashRHS;
}
-void LoadMechanism::deactivateScriptExtender() {
- try {
- IPluginGame const* game = qApp->property("managed_game").value<IPluginGame*>();
- ScriptExtender* extender = game->feature<ScriptExtender>();
- if (extender == nullptr) {
- throw MyException(QObject::tr("game doesn't support a script extender"));
- }
- QDir pluginsDir(game->gameDirectory().absolutePath() + "/data/" + extender->PluginPath());
+void LoadMechanism::deactivateScriptExtender()
+{
+ try {
+ IPluginGame const *game = qApp->property("managed_game").value<IPluginGame*>();
+ ScriptExtender *extender = game->feature<ScriptExtender>();
+ if (extender == nullptr) {
+ throw MyException(QObject::tr("game doesn't support a script extender"));
+ }
+
+ QDir pluginsDir(game->gameDirectory().absolutePath() + "/data/" + extender->PluginPath());
#pragma message("implement this for usvfs")
- QString vfsDLLName = "";
- if (extender->getArch() == IMAGE_FILE_MACHINE_I386) {
- vfsDLLName = ToQString(AppConfig::vfs32DLLName());
- } else if (extender->getArch() == IMAGE_FILE_MACHINE_AMD64) {
- vfsDLLName = ToQString(AppConfig::vfs64DLLName());
- }
- qDebug("USVFS DLL Name: " + vfsDLLName.toLatin1());
- if (vfsDLLName != "") {
- if (QFile(pluginsDir.absoluteFilePath(vfsDLLName)).exists()) {
- // remove dll from SE plugins directory
- if (!pluginsDir.remove(vfsDLLName)) {
- throw MyException(QObject::tr("Failed to delete %1").arg(pluginsDir.absoluteFilePath(vfsDLLName)));
- }
- }
- }
+ QString vfsDLLName = "";
+ if (extender->getArch() == IMAGE_FILE_MACHINE_I386) {
+ vfsDLLName = ToQString(AppConfig::vfs32DLLName());
+ }
+ else if (extender->getArch() == IMAGE_FILE_MACHINE_AMD64)
+ {
+ vfsDLLName = ToQString(AppConfig::vfs64DLLName());
+ }
+ qDebug("USVFS DLL Name: " + vfsDLLName.toLatin1());
+ if (vfsDLLName != "") {
+ if (QFile(pluginsDir.absoluteFilePath(vfsDLLName)).exists()) {
+ // remove dll from SE plugins directory
+ if (!pluginsDir.remove(vfsDLLName)) {
+ throw MyException(QObject::tr("Failed to delete %1").arg(pluginsDir.absoluteFilePath(vfsDLLName)));
+ }
+ }
+ }
- removeHintFile(pluginsDir);
- } catch (const std::exception& e) {
- QMessageBox::critical(nullptr, QObject::tr("Failed to deactivate script extender loading"), e.what());
- }
+ removeHintFile(pluginsDir);
+ } catch (const std::exception &e) {
+ QMessageBox::critical(nullptr, QObject::tr("Failed to deactivate script extender loading"), e.what());
+ }
}
-void LoadMechanism::deactivateProxyDLL() {
- try {
- IPluginGame const* game = qApp->property("managed_game").value<IPluginGame*>();
- QString targetPath =
- game->gameDirectory().absoluteFilePath(QString::fromStdWString(AppConfig::proxyDLLTarget()));
+void LoadMechanism::deactivateProxyDLL()
+{
+ try {
+ IPluginGame const *game = qApp->property("managed_game").value<IPluginGame *>();
- QFile targetDLL(targetPath);
- if (targetDLL.exists()) {
- QString origFile =
- game->gameDirectory().absoluteFilePath(QString::fromStdWString(AppConfig::proxyDLLOrig()));
- // determine if a proxy-dll is installed
- // this is a very crude way of making this decision but it should be good enough
- if ((targetDLL.size() < 24576) && (QFile(origFile).exists())) {
- // remove proxy-dll
- if (!targetDLL.remove()) {
- throw MyException(
- QObject::tr("Failed to remove %1: %2").arg(targetPath).arg(targetDLL.errorString()));
- } else if (!QFile::rename(origFile, targetPath)) {
- throw MyException(QObject::tr("Failed to rename %1 to %2").arg(origFile, targetPath));
- }
- }
- }
+ QString targetPath = game->gameDirectory().absoluteFilePath(QString::fromStdWString(AppConfig::proxyDLLTarget()));
- removeHintFile(game->gameDirectory());
- } catch (const std::exception& e) {
- QMessageBox::critical(nullptr, QObject::tr("Failed to deactivate proxy-dll loading"), e.what());
+ QFile targetDLL(targetPath);
+ if (targetDLL.exists()) {
+ QString origFile = game->gameDirectory().absoluteFilePath(QString::fromStdWString(AppConfig::proxyDLLOrig()));
+ // determine if a proxy-dll is installed
+ // this is a very crude way of making this decision but it should be good enough
+ if ((targetDLL.size() < 24576) && (QFile(origFile).exists())) {
+ // remove proxy-dll
+ if (!targetDLL.remove()) {
+ throw MyException(QObject::tr("Failed to remove %1: %2").arg(targetPath).arg(targetDLL.errorString()));
+ } else if (!QFile::rename(origFile, targetPath)) {
+ throw MyException(QObject::tr("Failed to rename %1 to %2").arg(origFile, targetPath));
+ }
+ }
}
+
+ removeHintFile(game->gameDirectory());
+ } catch (const std::exception &e) {
+ QMessageBox::critical(nullptr, QObject::tr("Failed to deactivate proxy-dll loading"), e.what());
+ }
}
-void LoadMechanism::activateScriptExtender() {
- try {
- IPluginGame const* game = qApp->property("managed_game").value<IPluginGame*>();
- ScriptExtender* extender = game->feature<ScriptExtender>();
- if (extender == nullptr) {
- throw MyException(QObject::tr("game doesn't support a script extender"));
- }
- QDir pluginsDir(game->gameDirectory().absolutePath() + "/data/" + extender->PluginPath());
+void LoadMechanism::activateScriptExtender()
+{
+ try {
+ IPluginGame const *game = qApp->property("managed_game").value<IPluginGame *>();
+ ScriptExtender *extender = game->feature<ScriptExtender>();
+ if (extender == nullptr) {
+ throw MyException(QObject::tr("game doesn't support a script extender"));
+ }
- if (!pluginsDir.exists()) {
- pluginsDir.mkpath(".");
- }
+ QDir pluginsDir(game->gameDirectory().absolutePath() + "/data/" + extender->PluginPath());
+
+ if (!pluginsDir.exists()) {
+ pluginsDir.mkpath(".");
+ }
#pragma message("implement this for usvfs")
- std::wstring vfsDLL = L"";
- if (extender->getArch() == IMAGE_FILE_MACHINE_I386) {
- vfsDLL = AppConfig::vfs32DLLName();
- } else if (extender->getArch() == IMAGE_FILE_MACHINE_AMD64) {
- vfsDLL = AppConfig::vfs64DLLName();
- }
- if (vfsDLL != L"") {
- QString targetPath = pluginsDir.absoluteFilePath(ToQString(vfsDLL));
- QString vfsDLLPath = qApp->applicationDirPath() + "/" + QString::fromStdWString(vfsDLL);
+ std::wstring vfsDLL = L"";
+ if (extender->getArch() == IMAGE_FILE_MACHINE_I386) {
+ vfsDLL = AppConfig::vfs32DLLName();
+ }
+ else if (extender->getArch() == IMAGE_FILE_MACHINE_AMD64)
+ {
+ vfsDLL = AppConfig::vfs64DLLName();
+ }
+ if (vfsDLL != L"") {
+ QString targetPath = pluginsDir.absoluteFilePath(ToQString(vfsDLL));
+ QString vfsDLLPath = qApp->applicationDirPath() + "/" + QString::fromStdWString(vfsDLL);
- qDebug("DLL USVFS Target Path: " + targetPath.toLatin1());
- qDebug("DLL USVFS VFS DLL Path: " + vfsDLLPath.toLatin1());
+ qDebug("DLL USVFS Target Path: " + targetPath.toLatin1());
+ qDebug("DLL USVFS VFS DLL Path: " + vfsDLLPath.toLatin1());
- QFile dllFile(targetPath);
+ QFile dllFile(targetPath);
- if (dllFile.exists()) {
- // may be outdated
- if (!hashIdentical(targetPath, vfsDLLPath)) {
- dllFile.remove();
- }
- }
+ if (dllFile.exists()) {
+ // may be outdated
+ if (!hashIdentical(targetPath, vfsDLLPath)) {
+ dllFile.remove();
+ }
+ }
- if (!dllFile.exists()) {
- // install dll to SE plugins
- if (!QFile::copy(vfsDLLPath, targetPath)) {
- throw MyException(QObject::tr("Failed to copy %1 to %2").arg(vfsDLLPath, targetPath));
- }
- }
- }
- writeHintFile(pluginsDir);
- } catch (const std::exception& e) {
- QMessageBox::critical(nullptr, QObject::tr("Failed to set up script extender loading"), e.what());
- }
+ if (!dllFile.exists()) {
+ // install dll to SE plugins
+ if (!QFile::copy(vfsDLLPath, targetPath)) {
+ throw MyException(QObject::tr("Failed to copy %1 to %2").arg(vfsDLLPath, targetPath));
+ }
+ }
+ }
+ writeHintFile(pluginsDir);
+ } catch (const std::exception &e) {
+ QMessageBox::critical(nullptr, QObject::tr("Failed to set up script extender loading"), e.what());
+ }
}
-void LoadMechanism::activateProxyDLL() {
- try {
- IPluginGame const* game = qApp->property("managed_game").value<IPluginGame*>();
- QString targetPath =
- game->gameDirectory().absoluteFilePath(QString::fromStdWString(AppConfig::proxyDLLTarget()));
+void LoadMechanism::activateProxyDLL()
+{
+ try {
+ IPluginGame const *game = qApp->property("managed_game").value<IPluginGame *>();
- QFile targetDLL(targetPath);
- if (!targetDLL.exists()) {
- return;
- }
+ QString targetPath = game->gameDirectory().absoluteFilePath(QString::fromStdWString(AppConfig::proxyDLLTarget()));
- QString sourcePath = qApp->applicationDirPath() + "/" + ToQString(AppConfig::proxyDLLSource());
+ QFile targetDLL(targetPath);
+ if (!targetDLL.exists()) {
+ return;
+ }
- // this is a very crude way of making this decision but it should be good enough
- if (targetDLL.size() < 24576) {
- // determine if a proxy-dll is already installed and if so, if it's the right one
- if (!hashIdentical(targetPath, sourcePath)) {
- // wrong proxy dll, probably outdated. delete and install the new one
- if (!QFile::remove(targetPath)) {
- throw MyException(QObject::tr("Failed to delete old proxy-dll %1").arg(targetPath));
- }
- if (!QFile::copy(sourcePath, targetPath)) {
- throw MyException(QObject::tr("Failed to copy %1 to %2").arg(sourcePath).arg(targetPath));
- }
- } // otherwise the proxy-dll is already the right one
- } else {
- // no proxy dll installed yet. move the original and insert proxy-dll
+ QString sourcePath = qApp->applicationDirPath() + "/" + ToQString(AppConfig::proxyDLLSource());
- QString origFile =
- game->gameDirectory().absoluteFilePath(QString::fromStdWString(AppConfig::proxyDLLOrig()));
+ // this is a very crude way of making this decision but it should be good enough
+ if (targetDLL.size() < 24576) {
+ // determine if a proxy-dll is already installed and if so, if it's the right one
+ if (!hashIdentical(targetPath, sourcePath)) {
+ // wrong proxy dll, probably outdated. delete and install the new one
+ if (!QFile::remove(targetPath)) {
+ throw MyException(QObject::tr("Failed to delete old proxy-dll %1").arg(targetPath));
+ }
+ if (!QFile::copy(sourcePath, targetPath)) {
+ throw MyException(QObject::tr("Failed to copy %1 to %2").arg(sourcePath).arg(targetPath));
+ }
+ } // otherwise the proxy-dll is already the right one
+ } else {
+ // no proxy dll installed yet. move the original and insert proxy-dll
+
+ QString origFile = game->gameDirectory().absoluteFilePath(QString::fromStdWString(AppConfig::proxyDLLOrig()));
- if (QFile(origFile).exists()) {
- // orig-file exists. this may happen if the steam-api was updated or the user messed with the
- // dlls.
- if (!QFile::remove(origFile)) {
- throw MyException(QObject::tr("Failed to overwrite %1").arg(origFile));
- }
- }
- if (!QFile::rename(targetPath, origFile)) {
- throw MyException(QObject::tr("Failed to rename %1 to %2").arg(targetPath).arg(origFile));
- }
- if (!QFile::copy(sourcePath, targetPath)) {
- throw MyException(QObject::tr("Failed to copy %1 to %2").arg(sourcePath).arg(targetPath));
- }
+ if (QFile(origFile).exists()) {
+ // orig-file exists. this may happen if the steam-api was updated or the user messed with the
+ // dlls.
+ if (!QFile::remove(origFile)) {
+ throw MyException(QObject::tr("Failed to overwrite %1").arg(origFile));
}
- writeHintFile(game->gameDirectory());
- } catch (const std::exception& e) {
- QMessageBox::critical(nullptr, QObject::tr("Failed to set up proxy-dll loading"), e.what());
+ }
+ if (!QFile::rename(targetPath, origFile)) {
+ throw MyException(QObject::tr("Failed to rename %1 to %2").arg(targetPath).arg(origFile));
+ }
+ if (!QFile::copy(sourcePath, targetPath)) {
+ throw MyException(QObject::tr("Failed to copy %1 to %2").arg(sourcePath).arg(targetPath));
+ }
}
+ writeHintFile(game->gameDirectory());
+ } catch (const std::exception &e) {
+ QMessageBox::critical(nullptr, QObject::tr("Failed to set up proxy-dll loading"), e.what());
+ }
}
-void LoadMechanism::activate(EMechanism mechanism) {
- switch (mechanism) {
+
+void LoadMechanism::activate(EMechanism mechanism)
+{
+ switch (mechanism) {
case LOAD_MODORGANIZER: {
- qDebug("Load Mechanism: Mod Organizer");
- deactivateProxyDLL();
- deactivateScriptExtender();
+ qDebug("Load Mechanism: Mod Organizer");
+ deactivateProxyDLL();
+ deactivateScriptExtender();
} break;
case LOAD_SCRIPTEXTENDER: {
- qDebug("Load Mechanism: ScriptExtender");
- deactivateProxyDLL();
- activateScriptExtender();
+ qDebug("Load Mechanism: ScriptExtender");
+ deactivateProxyDLL();
+ activateScriptExtender();
} break;
case LOAD_PROXYDLL: {
- qDebug("Load Mechanism: Proxy DLL");
- deactivateScriptExtender();
- activateProxyDLL();
+ qDebug("Load Mechanism: Proxy DLL");
+ deactivateScriptExtender();
+ activateProxyDLL();
} break;
- }
+ }
}
+
diff --git a/src/loadmechanism.h b/src/loadmechanism.h
index dfa43d85..c04473ab 100644
--- a/src/loadmechanism.h
+++ b/src/loadmechanism.h
@@ -20,9 +20,11 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef LOADMECHANISM_H
#define LOADMECHANISM_H
+
#include <QDir>
#include <QString>
+
/**
* @brief manages the various load mechanisms supported by Mod Organizer
* the load mechanisms is the means by which the mo-dll is injected into the target
@@ -36,72 +38,83 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
* chain-load the original dll. This currently only works with steam-versions of games and
* is intended as a last resort solution.
**/
-class LoadMechanism {
+class LoadMechanism
+{
public:
- enum EMechanism { LOAD_MODORGANIZER = 0, LOAD_SCRIPTEXTENDER, LOAD_PROXYDLL };
+
+ enum EMechanism {
+ LOAD_MODORGANIZER = 0,
+ LOAD_SCRIPTEXTENDER,
+ LOAD_PROXYDLL
+ };
public:
- /**
- * @brief constructor
- *
- **/
- LoadMechanism();
- /**
- * activate the specified mechanism. This automatically disables any other mechanism active
- *
- * @param mechanism the mechanism to activate
- **/
- void activate(EMechanism mechanism);
+ /**
+ * @brief constructor
+ *
+ **/
+ LoadMechanism();
+
+ /**
+ * activate the specified mechanism. This automatically disables any other mechanism active
+ *
+ * @param mechanism the mechanism to activate
+ **/
+ void activate(EMechanism mechanism);
- /**
- * @brief test whether the "Mod Organizer" load mechanism is supported for the current game
- *
- * @return true if the load mechanism is supported
- **/
- bool isDirectLoadingSupported();
+ /**
+ * @brief test whether the "Mod Organizer" load mechanism is supported for the current game
+ *
+ * @return true if the load mechanism is supported
+ **/
+ bool isDirectLoadingSupported();
- /**
- * @brief test whether the "Script Extender" load mechanism is supported for the current game
- *
- * @return true if the load mechanism is supported
- **/
- bool isScriptExtenderSupported();
+ /**
+ * @brief test whether the "Script Extender" load mechanism is supported for the current game
+ *
+ * @return true if the load mechanism is supported
+ **/
+ bool isScriptExtenderSupported();
- /**
- * @brief test whether the "Proxy DLL" load mechanism is supported for the current game
- *
- * @return true if the load mechanism is supported
- **/
- bool isProxyDLLSupported();
+ /**
+ * @brief test whether the "Proxy DLL" load mechanism is supported for the current game
+ *
+ * @return true if the load mechanism is supported
+ **/
+ bool isProxyDLLSupported();
private:
- // write a hint file that is required for certain loading mechanisms for the dll to find
- // the mod organizer installation
- void writeHintFile(const QDir& targetDirectory);
- // remove the hint file if it exists. does nothing if the file doesn't exist
- void removeHintFile(QDir targetDirectory);
+ // write a hint file that is required for certain loading mechanisms for the dll to find
+ // the mod organizer installation
+ void writeHintFile(const QDir &targetDirectory);
- // compare the two files by md5-hash, returns true if they are identical
- bool hashIdentical(const QString& fileNameLHS, const QString& fileNameRHS);
+ // remove the hint file if it exists. does nothing if the file doesn't exist
+ void removeHintFile(QDir targetDirectory);
- // deactivate loading through script extender. does nothing if se-loading wasn't active
- void deactivateScriptExtender();
+ // compare the two files by md5-hash, returns true if they are identical
+ bool hashIdentical(const QString &fileNameLHS, const QString &fileNameRHS);
- // deactivate loading through proxy-dll. does nothing if se-loading wasn't active
- void deactivateProxyDLL();
+ // deactivate loading through script extender. does nothing if se-loading wasn't active
+ void deactivateScriptExtender();
- // activate loading through script extender. does nothing if already active. updates
- // the dll if necessary
- void activateScriptExtender();
+ // deactivate loading through proxy-dll. does nothing if se-loading wasn't active
+ void deactivateProxyDLL();
- // activate loading through proxy-dll. does nothing if already active. updates
- // the dll if necessary
- void activateProxyDLL();
+ // activate loading through script extender. does nothing if already active. updates
+ // the dll if necessary
+ void activateScriptExtender();
+
+ // activate loading through proxy-dll. does nothing if already active. updates
+ // the dll if necessary
+ void activateProxyDLL();
private:
- EMechanism m_SelectedMechanism;
+
+ EMechanism m_SelectedMechanism;
+
};
+
#endif // LOADMECHANISM_H
diff --git a/src/lockeddialog.cpp b/src/lockeddialog.cpp
index 8883cd56..143d5838 100644
--- a/src/lockeddialog.cpp
+++ b/src/lockeddialog.cpp
@@ -23,35 +23,49 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QPoint>
#include <QResizeEvent>
#include <QWidget>
-#include <Qt> // for Qt::FramelessWindowHint, etc
+#include <Qt> // for Qt::FramelessWindowHint, etc
-LockedDialog::LockedDialog(QWidget* parent, bool unlockByButton)
- : LockedDialogBase(parent, !unlockByButton), ui(new Ui::LockedDialog) {
- ui->setupUi(this);
+LockedDialog::LockedDialog(QWidget *parent, bool unlockByButton)
+ : LockedDialogBase(parent, !unlockByButton)
+ , ui(new Ui::LockedDialog)
+{
+ ui->setupUi(this);
- // Supposedly the Qt::CustomizeWindowHint should use a customized window
- // allowing us to select if there is a close button. In practice this doesn't
- // seem to work. We will ignore pressing the close button if unlockByButton == true
- Qt::WindowFlags flags =
- this->windowFlags() | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowMinimizeButtonHint;
- if (m_allowClose)
- flags |= Qt::WindowCloseButtonHint;
- this->setWindowFlags(flags);
+ // Supposedly the Qt::CustomizeWindowHint should use a customized window
+ // allowing us to select if there is a close button. In practice this doesn't
+ // seem to work. We will ignore pressing the close button if unlockByButton == true
+ Qt::WindowFlags flags =
+ this->windowFlags() | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowMinimizeButtonHint;
+ if (m_allowClose)
+ flags |= Qt::WindowCloseButtonHint;
+ this->setWindowFlags(flags);
- if (!unlockByButton) {
- ui->unlockButton->hide();
- ui->verticalLayout->addItem(new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding));
- }
+ if (!unlockByButton)
+ {
+ ui->unlockButton->hide();
+ ui->verticalLayout->addItem(
+ new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding));
+ }
+}
+
+LockedDialog::~LockedDialog()
+{
+ delete ui;
}
-LockedDialog::~LockedDialog() { delete ui; }
-void LockedDialog::setProcessName(const QString& name) { ui->processLabel->setText(name); }
+void LockedDialog::setProcessName(const QString &name)
+{
+ ui->processLabel->setText(name);
+}
-void LockedDialog::on_unlockButton_clicked() { unlock(); }
+void LockedDialog::on_unlockButton_clicked()
+{
+ unlock();
+}
void LockedDialog::unlock() {
- LockedDialogBase::unlock();
- ui->label->setText("unlocking may take a few seconds");
- ui->unlockButton->setEnabled(false);
+ LockedDialogBase::unlock();
+ ui->label->setText("unlocking may take a few seconds");
+ ui->unlockButton->setEnabled(false);
}
diff --git a/src/lockeddialog.h b/src/lockeddialog.h
index fae01600..36c16429 100644
--- a/src/lockeddialog.h
+++ b/src/lockeddialog.h
@@ -22,33 +22,36 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "lockeddialogbase.h"
namespace Ui {
-class LockedDialog;
+ class LockedDialog;
}
/**
* a small borderless dialog displayed while the Mod Organizer UI is locked
* The dialog contains only a label and a button to force the UI to be unlocked
- *
+ *
* The UI gets locked while running external applications since they may modify the
* data on which Mod Organizer works. After the UI is unlocked (manually or after the
* external application closed) MO will refresh all of its data sources
**/
-class LockedDialog : public LockedDialogBase {
+class LockedDialog : public LockedDialogBase
+{
Q_OBJECT
public:
- explicit LockedDialog(QWidget* parent = 0, bool unlockByButton = false);
- ~LockedDialog();
+ explicit LockedDialog(QWidget *parent = 0, bool unlockByButton = false);
+ ~LockedDialog();
- void setProcessName(const QString& name) override;
+ void setProcessName(const QString &name) override;
protected:
- void unlock() override;
+
+ void unlock() override;
private slots:
- void on_unlockButton_clicked();
+ void on_unlockButton_clicked();
private:
- Ui::LockedDialog* ui;
+
+ Ui::LockedDialog *ui;
};
diff --git a/src/lockeddialogbase.cpp b/src/lockeddialogbase.cpp
index 4cf158ea..b18f7429 100644
--- a/src/lockeddialogbase.cpp
+++ b/src/lockeddialogbase.cpp
@@ -22,37 +22,52 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QPoint>
#include <QResizeEvent>
#include <QWidget>
-#include <Qt> // for Qt::FramelessWindowHint, etc
+#include <Qt> // for Qt::FramelessWindowHint, etc
-LockedDialogBase::LockedDialogBase(QWidget* parent, bool allowClose)
- : QDialog(parent), m_Unlocked(false), m_Canceled(false), m_allowClose(allowClose) {
- if (parent != nullptr) {
- QPoint position = parent->mapToGlobal(QPoint(parent->width() / 2, parent->height() / 2));
- position.rx() -= this->width() / 2;
- position.ry() -= this->height() / 2;
- move(position);
- }
+LockedDialogBase::LockedDialogBase(QWidget *parent, bool allowClose)
+ : QDialog(parent)
+ , m_Unlocked(false)
+ , m_Canceled(false)
+ , m_allowClose(allowClose)
+{
+ if (parent != nullptr) {
+ QPoint position = parent->mapToGlobal(QPoint(parent->width() / 2, parent->height() / 2));
+ position.rx() -= this->width() / 2;
+ position.ry() -= this->height() / 2;
+ move(position);
+ }
}
-void LockedDialogBase::resizeEvent(QResizeEvent* event) {
- QWidget* par = parentWidget();
- if (par != nullptr) {
- QPoint position = par->mapToGlobal(QPoint(par->width() / 2, par->height() / 2));
- position.rx() -= event->size().width() / 2;
- position.ry() -= event->size().height() / 2;
- move(position);
- }
+void LockedDialogBase::resizeEvent(QResizeEvent *event)
+{
+ QWidget *par = parentWidget();
+ if (par != nullptr) {
+ QPoint position = par->mapToGlobal(QPoint(par->width() / 2, par->height() / 2));
+ position.rx() -= event->size().width() / 2;
+ position.ry() -= event->size().height() / 2;
+ move(position);
+ }
}
-void LockedDialogBase::reject() {
- if (m_allowClose)
- unlock();
+void LockedDialogBase::reject()
+{
+ if (m_allowClose)
+ unlock();
}
-bool LockedDialogBase::unlockForced() const { return m_Unlocked; }
+bool LockedDialogBase::unlockForced() const {
+ return m_Unlocked;
+}
-bool LockedDialogBase::canceled() const { return m_Canceled; }
+bool LockedDialogBase::canceled() const {
+ return m_Canceled;
+}
-void LockedDialogBase::unlock() { m_Unlocked = true; }
+void LockedDialogBase::unlock() {
+ m_Unlocked = true;
+}
+
+void LockedDialogBase::cancel() {
+ m_Canceled = true;
+}
-void LockedDialogBase::cancel() { m_Canceled = true; }
diff --git a/src/lockeddialogbase.h b/src/lockeddialogbase.h
index 43f5d1ad..3c974a38 100644
--- a/src/lockeddialogbase.h
+++ b/src/lockeddialogbase.h
@@ -20,9 +20,9 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#pragma once
#include "ilockedwaitingforprocess.h"
-#include <QDialog> // for QDialog
-#include <QObject> // for Q_OBJECT, slots
-#include <QString> // for QString
+#include <QDialog> // for QDialog
+#include <QObject> // for Q_OBJECT, slots
+#include <QString> // for QString
class QResizeEvent;
class QWidget;
@@ -30,31 +30,33 @@ class QWidget;
/**
* a small borderless dialog displayed while the Mod Organizer UI is locked
* The dialog contains only a label and a button to force the UI to be unlocked
- *
+ *
* The UI gets locked while running external applications since they may modify the
* data on which Mod Organizer works. After the UI is unlocked (manually or after the
* external application closed) MO will refresh all of its data sources
**/
-class LockedDialogBase : public QDialog, public ILockedWaitingForProcess {
+class LockedDialogBase : public QDialog, public ILockedWaitingForProcess
+{
Q_OBJECT
public:
- explicit LockedDialogBase(QWidget* parent, bool allowClose);
+ explicit LockedDialogBase(QWidget *parent, bool allowClose);
- bool unlockForced() const override;
+ bool unlockForced() const override;
- virtual bool canceled() const;
+ virtual bool canceled() const;
protected:
- virtual void resizeEvent(QResizeEvent* event);
- virtual void reject();
+ virtual void resizeEvent(QResizeEvent *event);
- virtual void unlock();
+ virtual void reject();
- virtual void cancel();
+ virtual void unlock();
- bool m_Unlocked;
- bool m_Canceled;
- bool m_allowClose;
+ virtual void cancel();
+
+ bool m_Unlocked;
+ bool m_Canceled;
+ bool m_allowClose;
};
diff --git a/src/logbuffer.cpp b/src/logbuffer.cpp
index 5a74d5f5..522ce3c8 100644
--- a/src/logbuffer.cpp
+++ b/src/logbuffer.cpp
@@ -18,212 +18,253 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "logbuffer.h"
-#include <QDateTime>
+#include <scopeguard.h>
+#include <report.h>
+#include <QMutexLocker>
#include <QFile>
#include <QIcon>
-#include <QMutexLocker>
+#include <QDateTime>
#include <Windows.h>
-#include <report.h>
-#include <scopeguard.h>
using MOBase::reportError;
QScopedPointer<LogBuffer> LogBuffer::s_Instance;
QMutex LogBuffer::s_Mutex;
-LogBuffer::LogBuffer(int messageCount, QtMsgType minMsgType, const QString& outputFileName)
- : QAbstractItemModel(nullptr), m_OutFileName(outputFileName), m_ShutDown(false), m_MinMsgType(minMsgType),
- m_NumMessages(0) {
- m_Messages.resize(messageCount);
+LogBuffer::LogBuffer(int messageCount, QtMsgType minMsgType,
+ const QString &outputFileName)
+ : QAbstractItemModel(nullptr)
+ , m_OutFileName(outputFileName)
+ , m_ShutDown(false)
+ , m_MinMsgType(minMsgType)
+ , m_NumMessages(0)
+{
+ m_Messages.resize(messageCount);
}
-LogBuffer::~LogBuffer() {
- qInstallMessageHandler(0);
- write();
+LogBuffer::~LogBuffer()
+{
+ qInstallMessageHandler(0);
+ write();
}
-void LogBuffer::logMessage(QtMsgType type, const QString& message) {
- if (type >= m_MinMsgType) {
- Message msg = {type, QTime::currentTime(), message};
- if (m_NumMessages < m_Messages.size()) {
- beginInsertRows(QModelIndex(), static_cast<int>(m_NumMessages), static_cast<int>(m_NumMessages) + 1);
- }
- m_Messages.at(m_NumMessages % m_Messages.size()) = msg;
- if (m_NumMessages < m_Messages.size()) {
- endInsertRows();
- } else {
- emit dataChanged(createIndex(0, 0), createIndex(static_cast<int>(m_Messages.size()), 0));
- }
- ++m_NumMessages;
- if (type >= QtCriticalMsg) {
- write();
- }
+void LogBuffer::logMessage(QtMsgType type, const QString &message)
+{
+ if (type >= m_MinMsgType) {
+ Message msg = {type, QTime::currentTime(), message};
+ if (m_NumMessages < m_Messages.size()) {
+ beginInsertRows(QModelIndex(), static_cast<int>(m_NumMessages),
+ static_cast<int>(m_NumMessages) + 1);
+ }
+ m_Messages.at(m_NumMessages % m_Messages.size()) = msg;
+ if (m_NumMessages < m_Messages.size()) {
+ endInsertRows();
+ } else {
+ emit dataChanged(createIndex(0, 0),
+ createIndex(static_cast<int>(m_Messages.size()), 0));
+ }
+ ++m_NumMessages;
+ if (type >= QtCriticalMsg) {
+ write();
}
+ }
}
-void LogBuffer::write() const {
- if (m_NumMessages == 0) {
- return;
- }
+void LogBuffer::write() const
+{
+ if (m_NumMessages == 0) {
+ return;
+ }
- DWORD lastError = ::GetLastError();
+ DWORD lastError = ::GetLastError();
- QFile file(m_OutFileName);
- if (!file.open(QIODevice::WriteOnly)) {
- reportError(tr("failed to write log to %1: %2").arg(m_OutFileName).arg(file.errorString()));
- return;
- }
+ QFile file(m_OutFileName);
+ if (!file.open(QIODevice::WriteOnly)) {
+ reportError(tr("failed to write log to %1: %2")
+ .arg(m_OutFileName)
+ .arg(file.errorString()));
+ return;
+ }
- unsigned int i =
- (m_NumMessages > m_Messages.size()) ? static_cast<unsigned int>(m_NumMessages - m_Messages.size()) : 0U;
- for (; i < m_NumMessages; ++i) {
- file.write(m_Messages.at(i % m_Messages.size()).toString().toUtf8());
- file.write("\r\n");
- }
- ::SetLastError(lastError);
+ unsigned int i
+ = (m_NumMessages > m_Messages.size())
+ ? static_cast<unsigned int>(m_NumMessages - m_Messages.size())
+ : 0U;
+ for (; i < m_NumMessages; ++i) {
+ file.write(m_Messages.at(i % m_Messages.size()).toString().toUtf8());
+ file.write("\r\n");
+ }
+ ::SetLastError(lastError);
}
-void LogBuffer::init(int messageCount, QtMsgType minMsgType, const QString& outputFileName) {
- QMutexLocker guard(&s_Mutex);
+void LogBuffer::init(int messageCount, QtMsgType minMsgType,
+ const QString &outputFileName)
+{
+ QMutexLocker guard(&s_Mutex);
- s_Instance.reset(new LogBuffer(messageCount, minMsgType, outputFileName));
- qInstallMessageHandler(LogBuffer::log);
+ s_Instance.reset(new LogBuffer(messageCount, minMsgType, outputFileName));
+ qInstallMessageHandler(LogBuffer::log);
}
-char LogBuffer::msgTypeID(QtMsgType type) {
- switch (type) {
+char LogBuffer::msgTypeID(QtMsgType type)
+{
+ switch (type) {
case QtDebugMsg:
- return 'D';
+ return 'D';
case QtWarningMsg:
- return 'W';
+ return 'W';
case QtCriticalMsg:
- return 'C';
+ return 'C';
case QtFatalMsg:
- return 'F';
+ return 'F';
default:
- return '?';
- }
+ return '?';
+ }
}
-void LogBuffer::log(QtMsgType type, const QMessageLogContext& context, const QString& message) {
- // QMutexLocker doesn't support timeout...
- if (!s_Mutex.tryLock(100)) {
- fprintf(stderr, "failed to log: %s", qPrintable(message));
- return;
- }
- ON_BLOCK_EXIT([]() { s_Mutex.unlock(); });
+void LogBuffer::log(QtMsgType type, const QMessageLogContext &context,
+ const QString &message)
+{
+ // QMutexLocker doesn't support timeout...
+ if (!s_Mutex.tryLock(100)) {
+ fprintf(stderr, "failed to log: %s", qPrintable(message));
+ return;
+ }
+ ON_BLOCK_EXIT([]() { s_Mutex.unlock(); });
- if (!s_Instance.isNull()) {
- s_Instance->logMessage(type, message);
- }
+ if (!s_Instance.isNull()) {
+ s_Instance->logMessage(type, message);
+ }
- if (type == QtDebugMsg) {
- fprintf(stdout, "%s [%c] %s\n", qPrintable(QTime::currentTime().toString()), msgTypeID(type),
- qPrintable(message));
+ if (type == QtDebugMsg) {
+ fprintf(stdout, "%s [%c] %s\n", qPrintable(QTime::currentTime().toString()),
+ msgTypeID(type), qPrintable(message));
+ } else {
+ if (context.line != 0) {
+ fprintf(stdout, "%s [%c] (%s:%u) %s\n",
+ qPrintable(QTime::currentTime().toString()), msgTypeID(type),
+ context.file, context.line, qPrintable(message));
} else {
- if (context.line != 0) {
- fprintf(stdout, "%s [%c] (%s:%u) %s\n", qPrintable(QTime::currentTime().toString()), msgTypeID(type),
- context.file, context.line, qPrintable(message));
- } else {
- fprintf(stdout, "%s [%c] %s\n", qPrintable(QTime::currentTime().toString()), msgTypeID(type),
- qPrintable(message));
- }
+ fprintf(stdout, "%s [%c] %s\n",
+ qPrintable(QTime::currentTime().toString()), msgTypeID(type),
+ qPrintable(message));
}
- fflush(stdout);
+ }
+ fflush(stdout);
}
-QModelIndex LogBuffer::index(int row, int column, const QModelIndex&) const { return createIndex(row, column, row); }
+QModelIndex LogBuffer::index(int row, int column, const QModelIndex &) const
+{
+ return createIndex(row, column, row);
+}
-QModelIndex LogBuffer::parent(const QModelIndex&) const { return QModelIndex(); }
+QModelIndex LogBuffer::parent(const QModelIndex &) const
+{
+ return QModelIndex();
+}
-int LogBuffer::rowCount(const QModelIndex& parent) const {
- if (parent.isValid())
- return 0;
- else
- return static_cast<int>(std::min(m_NumMessages, m_Messages.size()));
+int LogBuffer::rowCount(const QModelIndex &parent) const
+{
+ if (parent.isValid())
+ return 0;
+ else
+ return static_cast<int>(std::min(m_NumMessages, m_Messages.size()));
}
-int LogBuffer::columnCount(const QModelIndex&) const { return 2; }
+int LogBuffer::columnCount(const QModelIndex &) const
+{
+ return 2;
+}
-QVariant LogBuffer::data(const QModelIndex& index, int role) const {
- unsigned int offset =
- m_NumMessages < m_Messages.size() ? 0 : static_cast<unsigned int>(m_NumMessages - m_Messages.size());
- unsigned int msgIndex = (offset + index.row() + 1) % m_Messages.size();
- switch (role) {
+QVariant LogBuffer::data(const QModelIndex &index, int role) const
+{
+ unsigned int offset
+ = m_NumMessages < m_Messages.size()
+ ? 0
+ : static_cast<unsigned int>(m_NumMessages - m_Messages.size());
+ unsigned int msgIndex = (offset + index.row() + 1) % m_Messages.size();
+ switch (role) {
case Qt::DisplayRole: {
- if (index.column() == 0) {
- return m_Messages[msgIndex].time;
- } else if (index.column() == 1) {
- const QString& msg = m_Messages[msgIndex].message;
- if (msg.length() < 200) {
- return msg;
- } else {
- return msg.mid(0, 200) + "...";
- }
+ if (index.column() == 0) {
+ return m_Messages[msgIndex].time;
+ } else if (index.column() == 1) {
+ const QString &msg = m_Messages[msgIndex].message;
+ if (msg.length() < 200) {
+ return msg;
+ } else {
+ return msg.mid(0, 200) + "...";
}
+ }
} break;
case Qt::DecorationRole: {
- if (index.column() == 1) {
- switch (m_Messages[msgIndex].type) {
- case QtDebugMsg:
- return QIcon(":/MO/gui/information");
- case QtWarningMsg:
- return QIcon(":/MO/gui/warning");
- case QtCriticalMsg:
- return QIcon(":/MO/gui/important");
- case QtFatalMsg:
- return QIcon(":/MO/gui/problem");
- }
+ if (index.column() == 1) {
+ switch (m_Messages[msgIndex].type) {
+ case QtDebugMsg:
+ return QIcon(":/MO/gui/information");
+ case QtWarningMsg:
+ return QIcon(":/MO/gui/warning");
+ case QtCriticalMsg:
+ return QIcon(":/MO/gui/important");
+ case QtFatalMsg:
+ return QIcon(":/MO/gui/problem");
}
+ }
} break;
case Qt::UserRole: {
- if (index.column() == 1) {
- switch (m_Messages[msgIndex].type) {
- case QtDebugMsg:
- return "D";
- case QtWarningMsg:
- return "W";
- case QtCriticalMsg:
- return "C";
- case QtFatalMsg:
- return "F";
- }
+ if (index.column() == 1) {
+ switch (m_Messages[msgIndex].type) {
+ case QtDebugMsg:
+ return "D";
+ case QtWarningMsg:
+ return "W";
+ case QtCriticalMsg:
+ return "C";
+ case QtFatalMsg:
+ return "F";
}
+ }
} break;
- }
- return QVariant();
+ }
+ return QVariant();
}
-void LogBuffer::writeNow() {
- QMutexLocker guard(&s_Mutex);
- if (!s_Instance.isNull()) {
- s_Instance->write();
- }
+void LogBuffer::writeNow()
+{
+ QMutexLocker guard(&s_Mutex);
+ if (!s_Instance.isNull()) {
+ s_Instance->write();
+ }
}
-void LogBuffer::cleanQuit() {
- QMutexLocker guard(&s_Mutex);
- if (!s_Instance.isNull()) {
- s_Instance->m_ShutDown = true;
- }
+void LogBuffer::cleanQuit()
+{
+ QMutexLocker guard(&s_Mutex);
+ if (!s_Instance.isNull()) {
+ s_Instance->m_ShutDown = true;
+ }
}
-void log(const char* format, ...) {
- va_list argList;
- va_start(argList, format);
+void log(const char *format, ...)
+{
+ va_list argList;
+ va_start(argList, format);
- static const int BUFFERSIZE = 1000;
+ static const int BUFFERSIZE = 1000;
- char buffer[BUFFERSIZE + 1];
- buffer[BUFFERSIZE] = '\0';
+ char buffer[BUFFERSIZE + 1];
+ buffer[BUFFERSIZE] = '\0';
- vsnprintf(buffer, BUFFERSIZE, format, argList);
+ vsnprintf(buffer, BUFFERSIZE, format, argList);
- qCritical("%s", buffer);
+ qCritical("%s", buffer);
- va_end(argList);
+ va_end(argList);
}
-QString LogBuffer::Message::toString() const {
- return QString("%1 [%2] %3").arg(time.toString()).arg(msgTypeID(type)).arg(message);
+QString LogBuffer::Message::toString() const
+{
+ return QString("%1 [%2] %3")
+ .arg(time.toString())
+ .arg(msgTypeID(type))
+ .arg(message);
}
diff --git a/src/logbuffer.h b/src/logbuffer.h
index 0a35e91a..0cfecfa2 100644
--- a/src/logbuffer.h
+++ b/src/logbuffer.h
@@ -20,68 +20,76 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef LOGBUFFER_H
#define LOGBUFFER_H
-#include <QMutex>
#include <QObject>
+#include <QMutex>
#include <QScopedPointer>
#include <QStringListModel>
#include <QTime>
#include <vector>
-class LogBuffer : public QAbstractItemModel {
- Q_OBJECT
+
+class LogBuffer : public QAbstractItemModel
+{
+ Q_OBJECT
public:
- static void init(int messageCount, QtMsgType minMsgType, const QString& outputFileName);
- static void log(QtMsgType type, const QMessageLogContext& context, const QString& message);
- static void writeNow();
- static void cleanQuit();
+ static void init(int messageCount, QtMsgType minMsgType, const QString &outputFileName);
+ static void log(QtMsgType type, const QMessageLogContext &context, const QString &message);
+
+ static void writeNow();
+ static void cleanQuit();
- static LogBuffer* instance() { return s_Instance.data(); }
+ static LogBuffer *instance() { return s_Instance.data(); }
public:
- virtual ~LogBuffer();
- void logMessage(QtMsgType type, const QString& message);
+ virtual ~LogBuffer();
- // QAbstractItemModel interface
+ void logMessage(QtMsgType type, const QString &message);
+
+ // QAbstractItemModel interface
public:
- QModelIndex index(int row, int column, const QModelIndex& parent) const;
- QModelIndex parent(const QModelIndex& child) const;
- int rowCount(const QModelIndex& parent) const;
- int columnCount(const QModelIndex& parent) const;
- QVariant data(const QModelIndex& index, int role) const;
+ QModelIndex index(int row, int column, const QModelIndex &parent) const;
+ QModelIndex parent(const QModelIndex &child) const;
+ int rowCount(const QModelIndex &parent) const;
+ int columnCount(const QModelIndex &parent) const;
+ QVariant data(const QModelIndex &index, int role) const;
signals:
public slots:
private:
- explicit LogBuffer(int messageCount, QtMsgType minMsgType, const QString& outputFileName);
- LogBuffer(const LogBuffer& reference); // not implemented
- LogBuffer& operator=(const LogBuffer& reference); // not implemented
- void write() const;
+ explicit LogBuffer(int messageCount, QtMsgType minMsgType, const QString &outputFileName);
+ LogBuffer(const LogBuffer &reference); // not implemented
+ LogBuffer &operator=(const LogBuffer &reference); // not implemented
+
+ void write() const;
- static char msgTypeID(QtMsgType type);
+ static char msgTypeID(QtMsgType type);
private:
- struct Message {
- QtMsgType type;
- QTime time;
- QString message;
- QString toString() const;
- };
+
+ struct Message {
+ QtMsgType type;
+ QTime time;
+ QString message;
+ QString toString() const;
+ };
private:
- static QScopedPointer<LogBuffer> s_Instance;
- static QMutex s_Mutex;
- QString m_OutFileName;
- bool m_ShutDown;
- QtMsgType m_MinMsgType;
- size_t m_NumMessages;
- std::vector<Message> m_Messages;
+ static QScopedPointer<LogBuffer> s_Instance;
+ static QMutex s_Mutex;
+
+ QString m_OutFileName;
+ bool m_ShutDown;
+ QtMsgType m_MinMsgType;
+ size_t m_NumMessages;
+ std::vector<Message> m_Messages;
+
};
#endif // LOGBUFFER_H
diff --git a/src/loghighlighter.cpp b/src/loghighlighter.cpp
index 414c3020..f43e5662 100644
--- a/src/loghighlighter.cpp
+++ b/src/loghighlighter.cpp
@@ -20,28 +20,33 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "loghighlighter.h"
#include <QRegExp>
-LogHighlighter::LogHighlighter(QObject* parent) : QSyntaxHighlighter(parent) {}
+LogHighlighter::LogHighlighter(QObject *parent) :
+ QSyntaxHighlighter(parent)
+{
+}
-void LogHighlighter::highlightBlock(const QString& text) {
- int spacePos = text.indexOf(" ");
- if (spacePos != -1) {
- QString type = text.mid(0, spacePos);
- if (type == "DEBUG") {
- setFormat(0, text.length(), Qt::gray);
- } else if (type == "INFO") {
- setFormat(0, text.length(), Qt::darkGreen);
- } else if (type == "ERROR") {
- setFormat(0, text.length(), Qt::red);
- }
- }
- int markPos = text.indexOf("injecting to");
- if (markPos != -1) {
- setFormat(markPos + 12, text.length(), Qt::blue);
+void LogHighlighter::highlightBlock(const QString &text)
+{
+ int spacePos = text.indexOf(" ");
+ if (spacePos != -1) {
+ QString type = text.mid(0, spacePos);
+ if (type == "DEBUG") {
+ setFormat(0, text.length(), Qt::gray);
+ } else if (type == "INFO") {
+ setFormat(0, text.length(), Qt::darkGreen);
+ } else if (type == "ERROR") {
+ setFormat(0, text.length(), Qt::red);
}
+ }
- markPos = text.indexOf("using profile");
- if (markPos != -1) {
- setFormat(markPos + 13, text.length(), Qt::blue);
- }
+ int markPos = text.indexOf("injecting to");
+ if (markPos != -1) {
+ setFormat(markPos + 12, text.length(), Qt::blue);
+ }
+
+ markPos = text.indexOf("using profile");
+ if (markPos != -1) {
+ setFormat(markPos + 13, text.length(), Qt::blue);
+ }
}
diff --git a/src/loghighlighter.h b/src/loghighlighter.h
index d542259e..55c15142 100644
--- a/src/loghighlighter.h
+++ b/src/loghighlighter.h
@@ -26,17 +26,20 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
* @brief Syntax highlighter to make log files from mo.dll more readable.
* @note this is currently not used!
**/
-class LogHighlighter : public QSyntaxHighlighter {
+class LogHighlighter : public QSyntaxHighlighter
+{
Q_OBJECT
public:
- explicit LogHighlighter(QObject* parent = 0);
+ explicit LogHighlighter(QObject *parent = 0);
signals:
public slots:
protected:
- virtual void highlightBlock(const QString& text);
+
+ virtual void highlightBlock(const QString &text);
+
};
#endif // LOGHIGHLIGHTER_H
diff --git a/src/main.cpp b/src/main.cpp
index bc1b4bc5..935b7404 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -17,58 +17,60 @@ You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
+
#ifdef LEAK_CHECK_WITH_VLD
-#include <vld.h>
#include <wchar.h>
+#include <vld.h>
#endif // LEAK_CHECK_WITH_VLD
#define WIN32_LEAN_AND_MEAN
-#include <DbgHelp.h>
#include <windows.h>
+#include <DbgHelp.h>
-#include "executableslist.h"
-#include "helper.h"
-#include "instancemanager.h"
-#include "logbuffer.h"
+#include <appconfig.h>
+#include <utility.h>
+#include <scopeguard.h>
#include "mainwindow.h"
-#include "moapplication.h"
+#include <report.h>
#include "modlist.h"
-#include "moshortcut.h"
-#include "nxmaccessmanager.h"
#include "profile.h"
-#include "selectiondialog.h"
-#include "singleinstance.h"
#include "spawn.h"
-#include "tutorialmanager.h"
+#include "executableslist.h"
+#include "singleinstance.h"
#include "utility.h"
-#include <appconfig.h>
-#include <report.h>
-#include <scopeguard.h>
-#include <utility.h>
+#include "helper.h"
+#include "logbuffer.h"
+#include "selectiondialog.h"
+#include "moapplication.h"
+#include "tutorialmanager.h"
+#include "nxmaccessmanager.h"
+#include "instancemanager.h"
+#include "moshortcut.h"
#include <eh.h>
-#include <usvfs.h>
#include <windows_error.h>
+#include <usvfs.h>
#include <QApplication>
-#include <QBuffer>
-#include <QCheckBox>
+#include <QPushButton>
+#include <QListWidget>
#include <QComboBox>
-#include <QDesktopServices>
+#include <QCheckBox>
#include <QDir>
-#include <QDirIterator>
-#include <QFileDialog>
#include <QFileInfo>
-#include <QLibraryInfo>
-#include <QListWidget>
-#include <QMessageBox>
-#include <QPushButton>
#include <QSettings>
+#include <QWhatsThis>
+#include <QToolBar>
+#include <QFileDialog>
+#include <QDesktopServices>
+#include <QMessageBox>
#include <QSharedMemory>
+#include <QBuffer>
#include <QSplashScreen>
+#include <QDirIterator>
+#include <QDesktopServices>
+#include <QLibraryInfo>
#include <QSslSocket>
-#include <QToolBar>
-#include <QWhatsThis>
#include <boost/scoped_array.hpp>
@@ -79,591 +81,629 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <sstream>
#include <stdexcept>
-#pragma comment(linker, \
- "/manifestDependency:\"name='dlls' processorArchitecture='x86' version='1.0.0.0' type='win32' \"")
+
+#pragma comment(linker, "/manifestDependency:\"name='dlls' processorArchitecture='x86' version='1.0.0.0' type='win32' \"")
+
using namespace MOBase;
using namespace MOShared;
-bool createAndMakeWritable(const std::wstring& subPath) {
- QString const dataPath = qApp->property("dataPath").toString();
- QString fullPath = dataPath + "/" + QString::fromStdWString(subPath);
+bool createAndMakeWritable(const std::wstring &subPath) {
+ QString const dataPath = qApp->property("dataPath").toString();
+ QString fullPath = dataPath + "/" + QString::fromStdWString(subPath);
- if (!QDir(fullPath).exists() && !QDir().mkdir(fullPath)) {
- QMessageBox::critical(nullptr, QObject::tr("Error"),
- QObject::tr("Failed to create \"%1\". Your user "
- "account probably lacks permission.")
- .arg(fullPath));
- return false;
- } else {
- return true;
- }
+ if (!QDir(fullPath).exists() && !QDir().mkdir(fullPath)) {
+ QMessageBox::critical(nullptr, QObject::tr("Error"),
+ QObject::tr("Failed to create \"%1\". Your user "
+ "account probably lacks permission.")
+ .arg(fullPath));
+ return false;
+ } else {
+ return true;
+ }
}
-bool bootstrap() {
- // remove the temporary backup directory in case we're restarting after an update
- QString backupDirectory = qApp->applicationDirPath() + "/update_backup";
- if (QDir(backupDirectory).exists()) {
- shellDelete(QStringList(backupDirectory));
- }
+bool bootstrap()
+{
+ // remove the temporary backup directory in case we're restarting after an update
+ QString backupDirectory = qApp->applicationDirPath() + "/update_backup";
+ if (QDir(backupDirectory).exists()) {
+ shellDelete(QStringList(backupDirectory));
+ }
- // cycle logfile
- removeOldFiles(qApp->property("dataPath").toString() + "/" + QString::fromStdWString(AppConfig::logPath()),
- "usvfs*.log", 5, QDir::Name);
+ // cycle logfile
+ removeOldFiles(qApp->property("dataPath").toString() + "/" + QString::fromStdWString(AppConfig::logPath()),
+ "usvfs*.log", 5, QDir::Name);
- if (!createAndMakeWritable(AppConfig::logPath())) {
- return false;
- }
+ if (!createAndMakeWritable(AppConfig::logPath())) {
+ return false;
+ }
- return true;
+ return true;
}
LPTOP_LEVEL_EXCEPTION_FILTER prevUnhandledExceptionFilter = nullptr;
-static LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS* exceptionPtrs) {
- const std::wstring& dumpPath = OrganizerCore::crashDumpsPath();
- int dumpRes = CreateMiniDump(exceptionPtrs, OrganizerCore::getGlobalCrashDumpsType(), dumpPath.c_str());
- if (!dumpRes)
- qCritical("ModOrganizer has crashed, crash dump created.");
- else
- qCritical("ModOrganizer has crashed, CreateMiniDump failed (%d, error %lu).", dumpRes, GetLastError());
+static LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *exceptionPtrs)
+{
+ const std::wstring& dumpPath = OrganizerCore::crashDumpsPath();
+ int dumpRes =
+ CreateMiniDump(exceptionPtrs, OrganizerCore::getGlobalCrashDumpsType(), dumpPath.c_str());
+ if (!dumpRes)
+ qCritical("ModOrganizer has crashed, crash dump created.");
+ else
+ qCritical("ModOrganizer has crashed, CreateMiniDump failed (%d, error %lu).", dumpRes, GetLastError());
- if (prevUnhandledExceptionFilter)
- return prevUnhandledExceptionFilter(exceptionPtrs);
- else
- return EXCEPTION_CONTINUE_SEARCH;
+ if (prevUnhandledExceptionFilter)
+ return prevUnhandledExceptionFilter(exceptionPtrs);
+ else
+ return EXCEPTION_CONTINUE_SEARCH;
}
// Parses the first parseArgCount arguments of the current process command line and returns
// them in parsedArgs, the rest of the command line is returned untouched.
-LPCWSTR UntouchedCommandLineArguments(int parseArgCount, std::vector<std::wstring>& parsedArgs) {
- LPCWSTR cmd = GetCommandLineW();
- LPCWSTR arg = nullptr; // to skip executable name
- for (; parseArgCount >= 0 && *cmd; ++cmd) {
- if (*cmd == '"') {
- int escaped = 0;
- for (++cmd; *cmd && (*cmd != '"' || escaped % 2 != 0); ++cmd)
- escaped = *cmd == '\\' ? escaped + 1 : 0;
- }
- if (*cmd == ' ') {
- if (arg)
- if (cmd - 1 > arg && *arg == '"' && *(cmd - 1) == '"')
- parsedArgs.push_back(std::wstring(arg + 1, cmd - 1));
- else
- parsedArgs.push_back(std::wstring(arg, cmd));
- arg = cmd + 1;
- --parseArgCount;
- }
+LPCWSTR UntouchedCommandLineArguments(int parseArgCount, std::vector<std::wstring>& parsedArgs)
+{
+ LPCWSTR cmd = GetCommandLineW();
+ LPCWSTR arg = nullptr; // to skip executable name
+ for (; parseArgCount >= 0 && *cmd; ++cmd)
+ {
+ if (*cmd == '"') {
+ int escaped = 0;
+ for (++cmd; *cmd && (*cmd != '"' || escaped % 2 != 0); ++cmd)
+ escaped = *cmd == '\\' ? escaped + 1 : 0;
}
- return cmd;
+ if (*cmd == ' ') {
+ if (arg)
+ if (cmd-1 > arg && *arg == '"' && *(cmd-1) == '"')
+ parsedArgs.push_back(std::wstring(arg+1, cmd-1));
+ else
+ parsedArgs.push_back(std::wstring(arg, cmd));
+ arg = cmd + 1;
+ --parseArgCount;
+ }
+ }
+ return cmd;
}
static int SpawnWaitProcess(LPCWSTR workingDirectory, LPCWSTR commandLine) {
- PROCESS_INFORMATION pi{0};
- STARTUPINFO si{0};
- si.cb = sizeof(si);
- std::wstring commandLineCopy = commandLine;
+ PROCESS_INFORMATION pi{ 0 };
+ STARTUPINFO si{ 0 };
+ si.cb = sizeof(si);
+ std::wstring commandLineCopy = commandLine;
- if (!CreateProcessW(NULL, &commandLineCopy[0], NULL, NULL, FALSE, 0, NULL, workingDirectory, &si, &pi)) {
- // A bit of a problem where to log the error message here, at least this way you can get the message
- // using a either DebugView or a live debugger:
- std::wostringstream ost;
- ost << L"CreateProcess failed: " << commandLine << ", " << GetLastError();
- OutputDebugStringW(ost.str().c_str());
- return -1;
- }
+ if (!CreateProcessW(NULL, &commandLineCopy[0], NULL, NULL, FALSE, 0, NULL, workingDirectory, &si, &pi)) {
+ // A bit of a problem where to log the error message here, at least this way you can get the message
+ // using a either DebugView or a live debugger:
+ std::wostringstream ost;
+ ost << L"CreateProcess failed: " << commandLine << ", " << GetLastError();
+ OutputDebugStringW(ost.str().c_str());
+ return -1;
+ }
- WaitForSingleObject(pi.hProcess, INFINITE);
+ WaitForSingleObject(pi.hProcess, INFINITE);
- DWORD exitCode = (DWORD)-1;
- ::GetExitCodeProcess(pi.hProcess, &exitCode);
- CloseHandle(pi.hThread);
- CloseHandle(pi.hProcess);
- return static_cast<int>(exitCode);
+ DWORD exitCode = (DWORD)-1;
+ ::GetExitCodeProcess(pi.hProcess, &exitCode);
+ CloseHandle(pi.hThread);
+ CloseHandle(pi.hProcess);
+ return static_cast<int>(exitCode);
}
-static DWORD WaitForProcess() {}
+static DWORD WaitForProcess() {
-static bool HaveWriteAccess(const std::wstring& path) {
- bool writable = false;
+}
- const static SECURITY_INFORMATION requestedFileInformation =
- OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
+static bool HaveWriteAccess(const std::wstring &path)
+{
+ bool writable = false;
- DWORD length = 0;
- if (!::GetFileSecurityW(path.c_str(), requestedFileInformation, nullptr, 0UL, &length) &&
- (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
- std::string tempBuffer;
- tempBuffer.reserve(length);
- PSECURITY_DESCRIPTOR security = (PSECURITY_DESCRIPTOR)tempBuffer.data();
- if (security && ::GetFileSecurity(path.c_str(), requestedFileInformation, security, length, &length)) {
- HANDLE token = nullptr;
- const static DWORD tokenDesiredAccess =
- TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE | STANDARD_RIGHTS_READ;
- if (!::OpenThreadToken(::GetCurrentThread(), tokenDesiredAccess, TRUE, &token)) {
- if (!::OpenProcessToken(::GetCurrentProcess(), tokenDesiredAccess, &token)) {
- throw std::runtime_error("Unable to get any thread or process token");
- }
- }
+ const static SECURITY_INFORMATION requestedFileInformation = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
- HANDLE impersonatedToken = nullptr;
- if (::DuplicateToken(token, SecurityImpersonation, &impersonatedToken)) {
- GENERIC_MAPPING mapping = {0xFFFFFFFF};
- mapping.GenericRead = FILE_GENERIC_READ;
- mapping.GenericWrite = FILE_GENERIC_WRITE;
- mapping.GenericExecute = FILE_GENERIC_EXECUTE;
- mapping.GenericAll = FILE_ALL_ACCESS;
+ DWORD length = 0;
+ if (!::GetFileSecurityW(path.c_str(), requestedFileInformation, nullptr, 0UL, &length)
+ && (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
+ std::string tempBuffer;
+ tempBuffer.reserve(length);
+ PSECURITY_DESCRIPTOR security = (PSECURITY_DESCRIPTOR)tempBuffer.data();
+ if (security
+ && ::GetFileSecurity(path.c_str(), requestedFileInformation, security, length, &length)) {
+ HANDLE token = nullptr;
+ const static DWORD tokenDesiredAccess = TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE | STANDARD_RIGHTS_READ;
+ if (!::OpenThreadToken(::GetCurrentThread(), tokenDesiredAccess, TRUE, &token)) {
+ if (!::OpenProcessToken(::GetCurrentProcess(), tokenDesiredAccess, &token)) {
+ throw std::runtime_error("Unable to get any thread or process token");
+ }
+ }
- DWORD genericAccessRights = FILE_GENERIC_WRITE;
- ::MapGenericMask(&genericAccessRights, &mapping);
+ HANDLE impersonatedToken = nullptr;
+ if (::DuplicateToken(token, SecurityImpersonation, &impersonatedToken)) {
+ GENERIC_MAPPING mapping = { 0xFFFFFFFF };
+ mapping.GenericRead = FILE_GENERIC_READ;
+ mapping.GenericWrite = FILE_GENERIC_WRITE;
+ mapping.GenericExecute = FILE_GENERIC_EXECUTE;
+ mapping.GenericAll = FILE_ALL_ACCESS;
- PRIVILEGE_SET privileges = {0};
- DWORD grantedAccess = 0;
- DWORD privilegesLength = sizeof(privileges);
- BOOL result = 0;
- if (::AccessCheck(security, impersonatedToken, genericAccessRights, &mapping, &privileges,
- &privilegesLength, &grantedAccess, &result)) {
- writable = result != 0;
- }
- ::CloseHandle(impersonatedToken);
- }
+ DWORD genericAccessRights = FILE_GENERIC_WRITE;
+ ::MapGenericMask(&genericAccessRights, &mapping);
- ::CloseHandle(token);
+ PRIVILEGE_SET privileges = { 0 };
+ DWORD grantedAccess = 0;
+ DWORD privilegesLength = sizeof(privileges);
+ BOOL result = 0;
+ if (::AccessCheck(security, impersonatedToken, genericAccessRights, &mapping, &privileges, &privilegesLength, &grantedAccess, &result)) {
+ writable = result != 0;
}
+ ::CloseHandle(impersonatedToken);
+ }
+
+ ::CloseHandle(token);
}
- return writable;
+ }
+ return writable;
}
-QString determineProfile(QStringList& arguments, const QSettings& settings) {
- QString selectedProfileName = QString::fromUtf8(settings.value("selected_profile", "").toByteArray());
- { // see if there is a profile on the command line
- int profileIndex = arguments.indexOf("-p", 1);
- if ((profileIndex != -1) && (profileIndex < arguments.size() - 1)) {
- qDebug("profile overwritten on command line");
- selectedProfileName = arguments.at(profileIndex + 1);
- }
- arguments.removeAt(profileIndex);
- arguments.removeAt(profileIndex);
- }
- if (selectedProfileName.isEmpty()) {
- qDebug("no configured profile");
- selectedProfileName = "Default";
- } else {
- qDebug("configured profile: %s", qPrintable(selectedProfileName));
+
+QString determineProfile(QStringList &arguments, const QSettings &settings)
+{
+ QString selectedProfileName = QString::fromUtf8(settings.value("selected_profile", "").toByteArray());
+ { // see if there is a profile on the command line
+ int profileIndex = arguments.indexOf("-p", 1);
+ if ((profileIndex != -1) && (profileIndex < arguments.size() - 1)) {
+ qDebug("profile overwritten on command line");
+ selectedProfileName = arguments.at(profileIndex + 1);
}
+ arguments.removeAt(profileIndex);
+ arguments.removeAt(profileIndex);
+ }
+ if (selectedProfileName.isEmpty()) {
+ qDebug("no configured profile");
+ selectedProfileName = "Default";
+ } else {
+ qDebug("configured profile: %s", qPrintable(selectedProfileName));
+ }
- return selectedProfileName;
+ return selectedProfileName;
}
-MOBase::IPluginGame* selectGame(QSettings& settings, QDir const& gamePath, MOBase::IPluginGame* game) {
- settings.setValue("gameName", game->gameName());
- // Sadly, hookdll needs gamePath in order to run. So following code block is
- // commented out
- /*if (gamePath == game->gameDirectory()) {
+MOBase::IPluginGame *selectGame(QSettings &settings, QDir const &gamePath, MOBase::IPluginGame *game)
+{
+ settings.setValue("gameName", game->gameName());
+ //Sadly, hookdll needs gamePath in order to run. So following code block is
+ //commented out
+ /*if (gamePath == game->gameDirectory()) {
settings.remove("gamePath");
} else*/ {
- QString gameDir = gamePath.absolutePath();
- game->setGamePath(gameDir);
- settings.setValue("gamePath", QDir::toNativeSeparators(gameDir).toUtf8().constData());
- }
- return game; // Woot
+ QString gameDir = gamePath.absolutePath();
+ game->setGamePath(gameDir);
+ settings.setValue("gamePath", QDir::toNativeSeparators(gameDir).toUtf8().constData());
+ }
+ return game; //Woot
}
-MOBase::IPluginGame* determineCurrentGame(QString const& moPath, QSettings& settings, PluginContainer const& plugins) {
- // Determine what game we are running where. Be very paranoid in case the
- // user has done something odd.
- // If the game name has been set up, use that.
- QString gameName = settings.value("gameName", "").toString();
- if (!gameName.isEmpty()) {
- MOBase::IPluginGame* game = plugins.managedGame(gameName);
- if (game == nullptr) {
- reportError(QObject::tr("Plugin to handle %1 no longer installed").arg(gameName));
- return nullptr;
- }
- QString gamePath = QString::fromUtf8(settings.value("gamePath", "").toByteArray());
- if (gamePath == "") {
- gamePath = game->gameDirectory().absolutePath();
- }
- QDir gameDir(gamePath);
- if (game->looksValid(gameDir)) {
- return selectGame(settings, gameDir, game);
- }
- }
- // gameName wasn't set, or otherwise can't be found. Try looking through all
- // the plugins using the gamePath
+MOBase::IPluginGame *determineCurrentGame(QString const &moPath, QSettings &settings, PluginContainer const &plugins)
+{
+ //Determine what game we are running where. Be very paranoid in case the
+ //user has done something odd.
+ //If the game name has been set up, use that.
+ QString gameName = settings.value("gameName", "").toString();
+ if (!gameName.isEmpty()) {
+ MOBase::IPluginGame *game = plugins.managedGame(gameName);
+ if (game == nullptr) {
+ reportError(QObject::tr("Plugin to handle %1 no longer installed").arg(gameName));
+ return nullptr;
+ }
QString gamePath = QString::fromUtf8(settings.value("gamePath", "").toByteArray());
- if (!gamePath.isEmpty()) {
- QDir gameDir(gamePath);
- // Look to see if one of the installed games binary file exists in the current
- // game directory.
- for (IPluginGame* const game : plugins.plugins<IPluginGame>()) {
- if (game->looksValid(gameDir)) {
- return selectGame(settings, gameDir, game);
- }
- }
+ if (gamePath == "") {
+ gamePath = game->gameDirectory().absolutePath();
+ }
+ QDir gameDir(gamePath);
+ if (game->looksValid(gameDir)) {
+ return selectGame(settings, gameDir, game);
}
+ }
- // The following code would try to determine the right game to mange but it would usually find the wrong one
- // so it was commented out.
- /*
- //OK, we are in a new setup or existing info is useless.
- //See if MO has been installed inside a game directory
+ //gameName wasn't set, or otherwise can't be found. Try looking through all
+ //the plugins using the gamePath
+ QString gamePath = QString::fromUtf8(settings.value("gamePath", "").toByteArray());
+ if (!gamePath.isEmpty()) {
+ QDir gameDir(gamePath);
+ //Look to see if one of the installed games binary file exists in the current
+ //game directory.
for (IPluginGame * const game : plugins.plugins<IPluginGame>()) {
- if (game->isInstalled() && moPath.startsWith(game->gameDirectory().absolutePath())) {
- //Found it.
- return selectGame(settings, game->gameDirectory(), game);
+ if (game->looksValid(gameDir)) {
+ return selectGame(settings, gameDir, game);
}
}
+ }
- //Try walking up the directory tree to see if MO has been installed inside a game
- {
- QDir gameDir(moPath);
- do {
- //Look to see if one of the installed games binary file exists in the current
- //directory.
- for (IPluginGame * const game : plugins.plugins<IPluginGame>()) {
- if (game->looksValid(gameDir)) {
- return selectGame(settings, gameDir, game);
- }
- }
- //OK, chop off the last directory and try again
- } while (gameDir.cdUp());
+ //The following code would try to determine the right game to mange but it would usually find the wrong one
+ //so it was commented out.
+ /*
+ //OK, we are in a new setup or existing info is useless.
+ //See if MO has been installed inside a game directory
+ for (IPluginGame * const game : plugins.plugins<IPluginGame>()) {
+ if (game->isInstalled() && moPath.startsWith(game->gameDirectory().absolutePath())) {
+ //Found it.
+ return selectGame(settings, game->gameDirectory(), game);
}
- */
+ }
- // Then try a selection dialogue.
- if (!gamePath.isEmpty() || !gameName.isEmpty()) {
- reportError(QObject::tr("Could not use configuration settings for game \"%1\", path \"%2\".")
- .arg(gameName)
- .arg(gamePath));
- }
+ //Try walking up the directory tree to see if MO has been installed inside a game
+ {
+ QDir gameDir(moPath);
+ do {
+ //Look to see if one of the installed games binary file exists in the current
+ //directory.
+ for (IPluginGame * const game : plugins.plugins<IPluginGame>()) {
+ if (game->looksValid(gameDir)) {
+ return selectGame(settings, gameDir, game);
+ }
+ }
+ //OK, chop off the last directory and try again
+ } while (gameDir.cdUp());
+ }
+ */
- SelectionDialog selection(QObject::tr("Please select the game to manage"), nullptr, QSize(32, 32));
+ //Then try a selection dialogue.
+ if (!gamePath.isEmpty() || !gameName.isEmpty()) {
+ reportError(QObject::tr("Could not use configuration settings for game \"%1\", path \"%2\".").
+ arg(gameName).arg(gamePath));
+ }
- for (IPluginGame* game : plugins.plugins<IPluginGame>()) {
- if (game->isInstalled()) {
- QString path = game->gameDirectory().absolutePath();
- selection.addChoice(game->gameIcon(), game->gameName(), path, QVariant::fromValue(game));
- }
+ SelectionDialog selection(QObject::tr("Please select the game to manage"), nullptr, QSize(32, 32));
+
+ for (IPluginGame *game : plugins.plugins<IPluginGame>()) {
+ if (game->isInstalled()) {
+ QString path = game->gameDirectory().absolutePath();
+ selection.addChoice(game->gameIcon(), game->gameName(), path, QVariant::fromValue(game));
}
+ }
- selection.addChoice(QString("Browse..."), QString(), QVariant::fromValue(static_cast<IPluginGame*>(nullptr)));
+ selection.addChoice(QString("Browse..."), QString(), QVariant::fromValue(static_cast<IPluginGame *>(nullptr)));
- while (selection.exec() != QDialog::Rejected) {
- IPluginGame* game = selection.getChoiceData().value<IPluginGame*>();
- if (game != nullptr) {
- return selectGame(settings, game->gameDirectory(), game);
- }
+ while (selection.exec() != QDialog::Rejected) {
+ IPluginGame * game = selection.getChoiceData().value<IPluginGame *>();
+ if (game != nullptr) {
+ return selectGame(settings, game->gameDirectory(), game);
+ }
- gamePath = QFileDialog::getExistingDirectory(nullptr, QObject::tr("Please select the game to manage"),
- QString(), QFileDialog::ShowDirsOnly);
+ gamePath = QFileDialog::getExistingDirectory(
+ nullptr, QObject::tr("Please select the game to manage"), QString(),
+ QFileDialog::ShowDirsOnly);
- if (!gamePath.isEmpty()) {
- QDir gameDir(gamePath);
- for (IPluginGame* const game : plugins.plugins<IPluginGame>()) {
- if (game->looksValid(gameDir)) {
- return selectGame(settings, gameDir, game);
- }
- }
- reportError(QObject::tr("No game identified in \"%1\". The directory is required to contain "
- "the game binary and its launcher.")
- .arg(gamePath));
+ if (!gamePath.isEmpty()) {
+ QDir gameDir(gamePath);
+ for (IPluginGame * const game : plugins.plugins<IPluginGame>()) {
+ if (game->looksValid(gameDir)) {
+ return selectGame(settings, gameDir, game);
}
+ }
+ reportError(QObject::tr("No game identified in \"%1\". The directory is required to contain "
+ "the game binary and its launcher.").arg(gamePath));
}
+ }
- return nullptr;
+ return nullptr;
}
+
// extend path to include dll directory so plugins don't need a manifest
// (using AddDllDirectory would be an alternative to this but it seems fairly
// complicated esp.
// since it isn't easily accessible on Windows < 8
// SetDllDirectory replaces other search directories and this seems to
// propagate to child processes)
-void setupPath() {
- static const int BUFSIZE = 4096;
+void setupPath()
+{
+ static const int BUFSIZE = 4096;
- qDebug("MO at: %s", qPrintable(QDir::toNativeSeparators(QCoreApplication::applicationDirPath())));
+ qDebug("MO at: %s", qPrintable(QDir::toNativeSeparators(
+ QCoreApplication::applicationDirPath())));
- boost::scoped_array<TCHAR> oldPath(new TCHAR[BUFSIZE]);
- DWORD offset = ::GetEnvironmentVariable(TEXT("PATH"), oldPath.get(), BUFSIZE);
- if (offset > BUFSIZE) {
- oldPath.reset(new TCHAR[offset]);
- ::GetEnvironmentVariable(TEXT("PATH"), oldPath.get(), offset);
- }
+ boost::scoped_array<TCHAR> oldPath(new TCHAR[BUFSIZE]);
+ DWORD offset = ::GetEnvironmentVariable(TEXT("PATH"), oldPath.get(), BUFSIZE);
+ if (offset > BUFSIZE) {
+ oldPath.reset(new TCHAR[offset]);
+ ::GetEnvironmentVariable(TEXT("PATH"), oldPath.get(), offset);
+ }
- std::wstring newPath(oldPath.get());
- newPath += L";";
- newPath += ToWString(QDir::toNativeSeparators(QCoreApplication::applicationDirPath())).c_str();
- newPath += L"\\dlls";
+ std::wstring newPath(oldPath.get());
+ newPath += L";";
+ newPath += ToWString(QDir::toNativeSeparators(
+ QCoreApplication::applicationDirPath()))
+ .c_str();
+ newPath += L"\\dlls";
- ::SetEnvironmentVariableW(L"PATH", newPath.c_str());
+ ::SetEnvironmentVariableW(L"PATH", newPath.c_str());
}
-static void preloadSsl() {
- QString appPath = QDir::toNativeSeparators(QCoreApplication::applicationDirPath());
- if (GetModuleHandleA("libeay32.dll"))
- qWarning("libeay32.dll already loaded?!");
- else {
- QString libeay32 = appPath + "\\libeay32.dll";
- if (!QFile::exists(libeay32))
- qWarning("libeay32.dll not found: %s", qPrintable(libeay32));
- else if (!LoadLibraryW(libeay32.toStdWString().c_str()))
- qWarning("failed to load: %s, %d", qPrintable(libeay32), GetLastError());
- }
- if (GetModuleHandleA("ssleay32.dll"))
- qWarning("ssleay32.dll already loaded?!");
- else {
- QString ssleay32 = appPath + "\\ssleay32.dll";
- if (!QFile::exists(ssleay32))
- qWarning("ssleay32.dll not found: %s", qPrintable(ssleay32));
- else if (!LoadLibraryW(ssleay32.toStdWString().c_str()))
- qWarning("failed to load: %s, %d", qPrintable(ssleay32), GetLastError());
- }
+static void preloadSsl()
+{
+ QString appPath = QDir::toNativeSeparators(QCoreApplication::applicationDirPath());
+ if (GetModuleHandleA("libeay32.dll"))
+ qWarning("libeay32.dll already loaded?!");
+ else {
+ QString libeay32 = appPath + "\\libeay32.dll";
+ if (!QFile::exists(libeay32))
+ qWarning("libeay32.dll not found: %s", qPrintable(libeay32));
+ else if (!LoadLibraryW(libeay32.toStdWString().c_str()))
+ qWarning("failed to load: %s, %d", qPrintable(libeay32), GetLastError());
+ }
+ if (GetModuleHandleA("ssleay32.dll"))
+ qWarning("ssleay32.dll already loaded?!");
+ else {
+ QString ssleay32 = appPath + "\\ssleay32.dll";
+ if (!QFile::exists(ssleay32))
+ qWarning("ssleay32.dll not found: %s", qPrintable(ssleay32));
+ else if (!LoadLibraryW(ssleay32.toStdWString().c_str()))
+ qWarning("failed to load: %s, %d", qPrintable(ssleay32), GetLastError());
+ }
}
-static QString getVersionDisplayString() {
- VS_FIXEDFILEINFO version = GetFileVersion(ToWString(QApplication::applicationFilePath()));
- return VersionInfo(version.dwFileVersionMS >> 16, version.dwFileVersionMS & 0xFFFF, version.dwFileVersionLS >> 16,
- version.dwFileVersionLS & 0xFFFF)
- .displayString();
+static QString getVersionDisplayString()
+{
+ VS_FIXEDFILEINFO version = GetFileVersion(ToWString(QApplication::applicationFilePath()));
+ return VersionInfo(version.dwFileVersionMS >> 16,
+ version.dwFileVersionMS & 0xFFFF,
+ version.dwFileVersionLS >> 16,
+ version.dwFileVersionLS & 0xFFFF).displayString();
}
-int runApplication(MOApplication& application, SingleInstance& instance, const QString& splashPath) {
+int runApplication(MOApplication &application, SingleInstance &instance,
+ const QString &splashPath)
+{
- qDebug("Starting Mod Organizer version %s revision %s", qPrintable(getVersionDisplayString()),
+ qDebug("Starting Mod Organizer version %s revision %s", qPrintable(getVersionDisplayString()),
#if defined(HGID)
- HGID
+ HGID
#elif defined(GITID)
- GITID
+ GITID
#else
- "unknown"
+ "unknown"
#endif
- );
+ );
#if !defined(QT_NO_SSL)
- preloadSsl();
- qDebug("ssl support: %d", QSslSocket::supportsSsl());
+ preloadSsl();
+ qDebug("ssl support: %d", QSslSocket::supportsSsl());
#else
- qDebug("non-ssl build");
+ qDebug("non-ssl build");
#endif
- QString dataPath = application.property("dataPath").toString();
- qDebug("data path: %s", qPrintable(dataPath));
+ QString dataPath = application.property("dataPath").toString();
+ qDebug("data path: %s", qPrintable(dataPath));
- if (!bootstrap()) {
- reportError("failed to set up data paths");
- return 1;
- }
+ if (!bootstrap()) {
+ reportError("failed to set up data paths");
+ return 1;
+ }
- QStringList arguments = application.arguments();
+ QStringList arguments = application.arguments();
- try {
- qDebug("Working directory: %s", qPrintable(QDir::toNativeSeparators(QDir::currentPath())));
+ try {
+ qDebug("Working directory: %s", qPrintable(QDir::toNativeSeparators(QDir::currentPath())));
- QSettings settings(dataPath + "/" + QString::fromStdWString(AppConfig::iniFileName()), QSettings::IniFormat);
+ QSettings settings(dataPath + "/"
+ + QString::fromStdWString(AppConfig::iniFileName()),
+ QSettings::IniFormat);
- // global crashDumpType sits in OrganizerCore to make a bit less ugly to update it when the settings are changed
- // during runtime
- OrganizerCore::setGlobalCrashDumpsType(
- settings.value("Settings/crash_dumps_type", static_cast<int>(CrashDumpsType::Mini)).toInt());
+ // global crashDumpType sits in OrganizerCore to make a bit less ugly to update it when the settings are changed during runtime
+ OrganizerCore::setGlobalCrashDumpsType(settings.value("Settings/crash_dumps_type", static_cast<int>(CrashDumpsType::Mini)).toInt());
- qDebug("Loaded settings:");
- settings.beginGroup("Settings");
- for (auto k : settings.allKeys())
- if (!k.contains("username") && !k.contains("password"))
- qDebug(" %s=%s", k.toUtf8().data(), settings.value(k).toString().toUtf8().data());
- settings.endGroup();
+ qDebug("Loaded settings:");
+ settings.beginGroup("Settings");
+ for (auto k : settings.allKeys())
+ if (!k.contains("username") && !k.contains("password"))
+ qDebug(" %s=%s", k.toUtf8().data(), settings.value(k).toString().toUtf8().data());
+ settings.endGroup();
- qDebug("initializing core");
- OrganizerCore organizer(settings);
- if (!organizer.bootstrap()) {
- reportError("failed to set up data paths");
- return 1;
- }
- qDebug("initialize plugins");
- PluginContainer pluginContainer(&organizer);
- pluginContainer.loadPlugins();
- MOBase::IPluginGame* game = determineCurrentGame(application.applicationDirPath(), settings, pluginContainer);
- if (game == nullptr) {
- return 1;
- }
- if (splashPath.startsWith(':')) {
- // currently using MO splash, see if the plugin contains one
- QString pluginSplash = QString(":/%1/splash").arg(game->gameShortName());
- QImage image(pluginSplash);
- if (!image.isNull()) {
- image.save(dataPath + "/splash.png");
- } else {
- qDebug("no plugin splash");
- }
- }
+ qDebug("initializing core");
+ OrganizerCore organizer(settings);
+ if (!organizer.bootstrap()) {
+ reportError("failed to set up data paths");
+ return 1;
+ }
+ qDebug("initialize plugins");
+ PluginContainer pluginContainer(&organizer);
+ pluginContainer.loadPlugins();
+
+ MOBase::IPluginGame *game = determineCurrentGame(
+ application.applicationDirPath(), settings, pluginContainer);
+ if (game == nullptr) {
+ return 1;
+ }
+ if (splashPath.startsWith(':')) {
+ // currently using MO splash, see if the plugin contains one
+ QString pluginSplash
+ = QString(":/%1/splash").arg(game->gameShortName());
+ QImage image(pluginSplash);
+ if (!image.isNull()) {
+ image.save(dataPath + "/splash.png");
+ } else {
+ qDebug("no plugin splash");
+ }
+ }
- organizer.setManagedGame(game);
- organizer.createDefaultProfile();
+ organizer.setManagedGame(game);
+ organizer.createDefaultProfile();
- if (!settings.contains("game_edition")) {
- QStringList editions = game->gameVariants();
- if (editions.size() > 1) {
- SelectionDialog selection(QObject::tr("Please select the game edition you have (MO can't "
- "start the game correctly if this is set "
- "incorrectly!)"),
- nullptr);
- int index = 0;
- for (const QString& edition : editions) {
- selection.addChoice(edition, "", index++);
- }
- if (selection.exec() == QDialog::Rejected) {
- return 1;
- } else {
- settings.setValue("game_edition", selection.getChoiceString());
- }
- }
+ if (!settings.contains("game_edition")) {
+ QStringList editions = game->gameVariants();
+ if (editions.size() > 1) {
+ SelectionDialog selection(
+ QObject::tr("Please select the game edition you have (MO can't "
+ "start the game correctly if this is set "
+ "incorrectly!)"),
+ nullptr);
+ int index = 0;
+ for (const QString &edition : editions) {
+ selection.addChoice(edition, "", index++);
}
- game->setGameVariant(settings.value("game_edition").toString());
+ if (selection.exec() == QDialog::Rejected) {
+ return 1;
+ } else {
+ settings.setValue("game_edition", selection.getChoiceString());
+ }
+ }
+ }
+ game->setGameVariant(settings.value("game_edition").toString());
- qDebug("managing game at %s", qPrintable(QDir::toNativeSeparators(game->gameDirectory().absolutePath())));
+ qDebug("managing game at %s", qPrintable(QDir::toNativeSeparators(
+ game->gameDirectory().absolutePath())));
- organizer.updateExecutablesList(settings);
+ organizer.updateExecutablesList(settings);
- QString selectedProfileName = determineProfile(arguments, settings);
- organizer.setCurrentProfile(selectedProfileName);
+ QString selectedProfileName = determineProfile(arguments, settings);
+ organizer.setCurrentProfile(selectedProfileName);
- // if we have a command line parameter, it is either a nxm link or
- // a binary to start
- if (arguments.size() > 1) {
- if (MOShortcut shortcut{arguments.at(1)}) {
- try {
- organizer.runShortcut(shortcut);
- return 0;
- } catch (const std::exception& e) {
- reportError(QObject::tr("failed to start shortcut: %1").arg(e.what()));
- return 1;
- }
- } else if (OrganizerCore::isNxmLink(arguments.at(1))) {
- qDebug("starting download from command line: %s", qPrintable(arguments.at(1)));
- organizer.externalMessage(arguments.at(1));
- } else {
- QString exeName = arguments.at(1);
- qDebug("starting %s from command line", qPrintable(exeName));
- arguments.removeFirst(); // remove application name (ModOrganizer.exe)
- arguments.removeFirst(); // remove binary name
- // pass the remaining parameters to the binary
- try {
- organizer.startApplication(exeName, arguments, QString(), QString());
- return 0;
- } catch (const std::exception& e) {
- reportError(QObject::tr("failed to start application: %1").arg(e.what()));
- return 1;
- }
- }
+ // if we have a command line parameter, it is either a nxm link or
+ // a binary to start
+ if (arguments.size() > 1) {
+ if (MOShortcut shortcut{ arguments.at(1) }) {
+ try {
+ organizer.runShortcut(shortcut);
+ return 0;
+ } catch (const std::exception &e) {
+ reportError(
+ QObject::tr("failed to start shortcut: %1").arg(e.what()));
+ return 1;
}
+ } else if (OrganizerCore::isNxmLink(arguments.at(1))) {
+ qDebug("starting download from command line: %s",
+ qPrintable(arguments.at(1)));
+ organizer.externalMessage(arguments.at(1));
+ } else {
+ QString exeName = arguments.at(1);
+ qDebug("starting %s from command line", qPrintable(exeName));
+ arguments.removeFirst(); // remove application name (ModOrganizer.exe)
+ arguments.removeFirst(); // remove binary name
+ // pass the remaining parameters to the binary
+ try {
+ organizer.startApplication(exeName, arguments, QString(), QString());
+ return 0;
+ } catch (const std::exception &e) {
+ reportError(
+ QObject::tr("failed to start application: %1").arg(e.what()));
+ return 1;
+ }
+ }
+ }
- QPixmap pixmap(splashPath);
- QSplashScreen splash(pixmap);
- splash.show();
+ QPixmap pixmap(splashPath);
+ QSplashScreen splash(pixmap);
+ splash.show();
- NexusInterface::instance()->getAccessManager()->startLoginCheck();
+ NexusInterface::instance()->getAccessManager()->startLoginCheck();
- qDebug("initializing tutorials");
- TutorialManager::init(
- qApp->applicationDirPath() + "/" + QString::fromStdWString(AppConfig::tutorialsPath()) + "/", &organizer);
+ qDebug("initializing tutorials");
+ TutorialManager::init(
+ qApp->applicationDirPath() + "/"
+ + QString::fromStdWString(AppConfig::tutorialsPath()) + "/",
+ &organizer);
- if (!application.setStyleFile(settings.value("Settings/style", "").toString())) {
- // disable invalid stylesheet
- settings.setValue("Settings/style", "");
- }
+ if (!application.setStyleFile(settings.value("Settings/style", "").toString())) {
+ // disable invalid stylesheet
+ settings.setValue("Settings/style", "");
+ }
- int res = 1;
- { // scope to control lifetime of mainwindow
- // set up main window and its data structures
- MainWindow mainWindow(settings, organizer, pluginContainer);
+ int res = 1;
+ { // scope to control lifetime of mainwindow
+ // set up main window and its data structures
+ MainWindow mainWindow(settings, organizer, pluginContainer);
- QObject::connect(&mainWindow, SIGNAL(styleChanged(QString)), &application, SLOT(setStyleFile(QString)));
- QObject::connect(&instance, SIGNAL(messageSent(QString)), &organizer, SLOT(externalMessage(QString)));
+ QObject::connect(&mainWindow, SIGNAL(styleChanged(QString)), &application,
+ SLOT(setStyleFile(QString)));
+ QObject::connect(&instance, SIGNAL(messageSent(QString)), &organizer,
+ SLOT(externalMessage(QString)));
- mainWindow.readSettings();
+ mainWindow.readSettings();
- qDebug("displaying main window");
- mainWindow.show();
+ qDebug("displaying main window");
+ mainWindow.show();
- splash.finish(&mainWindow);
- return application.exec();
- }
- } catch (const std::exception& e) {
- reportError(e.what());
- return 1;
+ splash.finish(&mainWindow);
+ return application.exec();
}
+ } catch (const std::exception &e) {
+ reportError(e.what());
+ return 1;
+ }
}
-int main(int argc, char* argv[]) {
- // Should allow for better scaling of ui with higher resolution displays
- QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
- if (argc >= 4) {
- std::vector<std::wstring> arg;
- auto args = UntouchedCommandLineArguments(2, arg);
- if (arg[0] == L"launch")
- return SpawnWaitProcess(arg[1].c_str(), args);
- }
+int main(int argc, char *argv[])
+{
+ //Should allow for better scaling of ui with higher resolution displays
+ QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
- MOApplication application(argc, argv);
- QStringList arguments = application.arguments();
+ if (argc >= 4) {
+ std::vector<std::wstring> arg;
+ auto args = UntouchedCommandLineArguments(2, arg);
+ if (arg[0] == L"launch")
+ return SpawnWaitProcess(arg[1].c_str(), args);
+ }
- setupPath();
+ MOApplication application(argc, argv);
+ QStringList arguments = application.arguments();
- bool forcePrimary = false;
- if (arguments.contains("update")) {
- arguments.removeAll("update");
- forcePrimary = true;
- }
+ setupPath();
- MOShortcut moshortcut{arguments.size() > 1 ? arguments.at(1) : ""};
+ bool forcePrimary = false;
+ if (arguments.contains("update")) {
+ arguments.removeAll("update");
+ forcePrimary = true;
+ }
- SingleInstance instance(forcePrimary);
- if (!instance.primaryInstance()) {
- if (moshortcut || arguments.size() > 1 && OrganizerCore::isNxmLink(arguments.at(1))) {
- qDebug("not primary instance, sending shortcut/download message");
- instance.sendMessage(arguments.at(1));
- return 0;
- } else if (arguments.size() == 1) {
- QMessageBox::information(nullptr, QObject::tr("Mod Organizer"),
- QObject::tr("An instance of Mod Organizer is already running"));
- return 0;
- }
- } // we continue for the primary instance OR if MO was called with parameters
+ MOShortcut moshortcut{ arguments.size() > 1 ? arguments.at(1) : "" };
- do {
- QString dataPath;
+ SingleInstance instance(forcePrimary);
+ if (!instance.primaryInstance()) {
+ if (moshortcut ||
+ arguments.size() > 1 && OrganizerCore::isNxmLink(arguments.at(1)))
+ {
+ qDebug("not primary instance, sending shortcut/download message");
+ instance.sendMessage(arguments.at(1));
+ return 0;
+ } else if (arguments.size() == 1) {
+ QMessageBox::information(
+ nullptr, QObject::tr("Mod Organizer"),
+ QObject::tr("An instance of Mod Organizer is already running"));
+ return 0;
+ }
+ } // we continue for the primary instance OR if MO was called with parameters
- try {
- InstanceManager& instanceManager = InstanceManager::instance();
- if (moshortcut && moshortcut.hasInstance())
- instanceManager.overrideInstance(moshortcut.instance());
- dataPath = instanceManager.determineDataPath();
- } catch (const std::exception& e) {
- if (strcmp(e.what(), "Canceled"))
- QMessageBox::critical(nullptr, QObject::tr("Failed to set up instance"), e.what());
- return 1;
- }
- application.setProperty("dataPath", dataPath);
+ do {
+ QString dataPath;
- // initialize dump collection only after "dataPath" since the crashes are stored under it
- prevUnhandledExceptionFilter = SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
+ try {
+ InstanceManager& instanceManager = InstanceManager::instance();
+ if (moshortcut && moshortcut.hasInstance())
+ instanceManager.overrideInstance(moshortcut.instance());
+ dataPath = instanceManager.determineDataPath();
+ } catch (const std::exception &e) {
+ if (strcmp(e.what(),"Canceled"))
+ QMessageBox::critical(nullptr, QObject::tr("Failed to set up instance"), e.what());
+ return 1;
+ }
+ application.setProperty("dataPath", dataPath);
- LogBuffer::init(1000, QtDebugMsg, qApp->property("dataPath").toString() + "/logs/mo_interface.log");
+ // initialize dump collection only after "dataPath" since the crashes are stored under it
+ prevUnhandledExceptionFilter = SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
- QString splash = dataPath + "/splash.png";
- if (!QFile::exists(dataPath + "/splash.png")) {
- splash = ":/MO/gui/splash";
- }
+ LogBuffer::init(1000, QtDebugMsg, qApp->property("dataPath").toString() + "/logs/mo_interface.log");
- int result = runApplication(application, instance, splash);
- if (result != INT_MAX) {
- return result;
- }
- argc = 1;
- } while (true);
+ QString splash = dataPath + "/splash.png";
+ if (!QFile::exists(dataPath + "/splash.png")) {
+ splash = ":/MO/gui/splash";
+ }
+
+ int result = runApplication(application, instance, splash);
+ if (result != INT_MAX) {
+ return result;
+ }
+ argc = 1;
+ } while (true);
}
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 31fe43ed..abac9317 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -26,64 +26,64 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "executableslist.h"
#include "guessedvalue.h"
#include "imodinterface.h"
-#include "instancemanager.h"
-#include "iplugindiagnose.h"
#include "iplugingame.h"
+#include "iplugindiagnose.h"
#include "isavegame.h"
#include "isavegameinfowidget.h"
#include "nexusinterface.h"
#include "organizercore.h"
#include "pluginlistsortproxy.h"
#include "previewgenerator.h"
-#include "savegameinfo.h"
#include "serverinfo.h"
+#include "savegameinfo.h"
#include "spawn.h"
#include "versioninfo.h"
+#include "instancemanager.h"
-#include "aboutdialog.h"
-#include "activatemodsdialog.h"
-#include "appconfig.h"
-#include "browserdialog.h"
+#include "report.h"
+#include "modlist.h"
+#include "modlistsortproxy.h"
+#include "qtgroupingproxy.h"
+#include "profile.h"
+#include "pluginlist.h"
+#include "profilesdialog.h"
+#include "editexecutablesdialog.h"
#include "categories.h"
#include "categoriesdialog.h"
-#include "csvbuilder.h"
+#include "modinfodialog.h"
+#include "overwriteinfodialog.h"
+#include "activatemodsdialog.h"
#include "downloadlist.h"
-#include "downloadlistsortproxy.h"
#include "downloadlistwidget.h"
#include "downloadlistwidgetcompact.h"
-#include "editexecutablesdialog.h"
-#include "eventfilter.h"
-#include "filedialogmemory.h"
-#include "genericicondelegate.h"
+#include "messagedialog.h"
#include "installationmanager.h"
#include "lockeddialog.h"
+#include "waitingonclosedialog.h"
#include "logbuffer.h"
-#include "messagedialog.h"
-#include "modflagicondelegate.h"
-#include "modinfodialog.h"
-#include "modlist.h"
-#include "modlistsortproxy.h"
+#include "downloadlistsortproxy.h"
#include "motddialog.h"
-#include "nxmaccessmanager.h"
-#include "overwriteinfodialog.h"
-#include "pluginlist.h"
-#include "previewdialog.h"
-#include "problemsdialog.h"
-#include "profile.h"
-#include "profilesdialog.h"
-#include "qtgroupingproxy.h"
-#include "report.h"
-#include "savetextasdialog.h"
-#include "selectiondialog.h"
+#include "filedialogmemory.h"
#include "tutorialmanager.h"
-#include "waitingonclosedialog.h"
-#include <bsainvalidation.h>
-#include <dataarchives.h>
+#include "modflagicondelegate.h"
+#include "genericicondelegate.h"
+#include "selectiondialog.h"
+#include "csvbuilder.h"
+#include "savetextasdialog.h"
+#include "problemsdialog.h"
+#include "previewdialog.h"
+#include "browserdialog.h"
+#include "aboutdialog.h"
#include <safewritefile.h>
-#include <scopeguard.h>
+#include "nxmaccessmanager.h"
+#include "appconfig.h"
+#include "eventfilter.h"
+#include <utility.h>
+#include <dataarchives.h>
+#include <bsainvalidation.h>
#include <taskprogressmanager.h>
+#include <scopeguard.h>
#include <usvfs.h>
-#include <utility.h>
#include <QAbstractItemDelegate>
#include <QAbstractProxyModel>
@@ -98,7 +98,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QDebug>
#include <QDesktopWidget>
#include <QDialog>
-#include <QDialogButtonBox>
#include <QDirIterator>
#include <QDragEnterEvent>
#include <QDropEvent>
@@ -128,15 +127,16 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QPoint>
#include <QProcess>
#include <QProgressDialog>
+#include <QDialogButtonBox>
#include <QPushButton>
#include <QRadioButton>
#include <QRect>
#include <QRegExp>
#include <QResizeEvent>
-#include <QScopedPointer>
#include <QSettings>
-#include <QSize>
+#include <QScopedPointer>
#include <QSizePolicy>
+#include <QSize>
#include <QTime>
#include <QTimer>
#include <QToolButton>
@@ -146,9 +146,9 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QTreeWidgetItemIterator>
#include <QUrl>
#include <QVariantList>
-#include <QWebEngineProfile>
#include <QWhatsThis>
#include <QWidgetAction>
+#include <QWebEngineProfile>
#include <QDebug>
#include <QtGlobal>
@@ -156,4551 +156,4877 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QtConcurrent/QtConcurrentRun>
#ifndef Q_MOC_RUN
+#include <boost/thread.hpp>
#include <boost/algorithm/string.hpp>
-#include <boost/assign.hpp>
#include <boost/bind.hpp>
-#include <boost/thread.hpp>
+#include <boost/assign.hpp>
#endif
#include <shlobj.h>
+#include <limits.h>
#include <exception>
#include <functional>
-#include <limits.h>
#include <map>
#include <regex>
-#include <sstream>
#include <stdexcept>
+#include <sstream>
#include <utility>
#ifdef TEST_MODELS
#include "modeltest.h"
#endif // TEST_MODELS
-#pragma warning(disable : 4428)
+#pragma warning( disable : 4428 )
using namespace MOBase;
using namespace MOShared;
-MainWindow::MainWindow(QSettings& initSettings, OrganizerCore& organizerCore, PluginContainer& pluginContainer,
- QWidget* parent)
- : QMainWindow(parent), ui(new Ui::MainWindow), m_WasVisible(false), m_Tutorial(this, "MainWindow"),
- m_OldProfileIndex(-1), m_ModListGroupingProxy(nullptr), m_ModListSortProxy(nullptr), m_OldExecutableIndex(-1),
- m_CategoryFactory(CategoryFactory::instance()), m_ContextItem(nullptr), m_ContextAction(nullptr),
- m_CurrentSaveView(nullptr), m_OrganizerCore(organizerCore), m_PluginContainer(pluginContainer),
- m_DidUpdateMasterList(false), m_ArchiveListWriter(std::bind(&MainWindow::saveArchiveList, this)) {
- QWebEngineProfile::defaultProfile()->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies);
- QWebEngineProfile::defaultProfile()->setHttpCacheMaximumSize(52428800);
- QWebEngineProfile::defaultProfile()->setCachePath(m_OrganizerCore.settings().getCacheDirectory());
- QWebEngineProfile::defaultProfile()->setPersistentStoragePath(m_OrganizerCore.settings().getCacheDirectory());
- ui->setupUi(this);
- updateWindowTitle(QString(), false);
- languageChange(m_OrganizerCore.settings().language());
+MainWindow::MainWindow(QSettings &initSettings
+ , OrganizerCore &organizerCore
+ , PluginContainer &pluginContainer
+ , QWidget *parent)
+ : QMainWindow(parent)
+ , ui(new Ui::MainWindow)
+ , m_WasVisible(false)
+ , m_Tutorial(this, "MainWindow")
+ , m_OldProfileIndex(-1)
+ , m_ModListGroupingProxy(nullptr)
+ , m_ModListSortProxy(nullptr)
+ , m_OldExecutableIndex(-1)
+ , m_CategoryFactory(CategoryFactory::instance())
+ , m_ContextItem(nullptr)
+ , m_ContextAction(nullptr)
+ , m_CurrentSaveView(nullptr)
+ , m_OrganizerCore(organizerCore)
+ , m_PluginContainer(pluginContainer)
+ , m_DidUpdateMasterList(false)
+ , m_ArchiveListWriter(std::bind(&MainWindow::saveArchiveList, this))
+{
+ QWebEngineProfile::defaultProfile()->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies);
+ QWebEngineProfile::defaultProfile()->setHttpCacheMaximumSize(52428800);
+ QWebEngineProfile::defaultProfile()->setCachePath(m_OrganizerCore.settings().getCacheDirectory());
+ QWebEngineProfile::defaultProfile()->setPersistentStoragePath(m_OrganizerCore.settings().getCacheDirectory());
+ ui->setupUi(this);
+ updateWindowTitle(QString(), false);
- m_CategoryFactory.loadCategories();
+ languageChange(m_OrganizerCore.settings().language());
- ui->logList->setModel(LogBuffer::instance());
- ui->logList->setColumnWidth(0, 100);
- ui->logList->setAutoScroll(true);
- ui->logList->scrollToBottom();
- ui->logList->addAction(ui->actionCopy_Log_to_Clipboard);
- int splitterSize =
- this->size().height(); // actually total window size, but the splitter doesn't seem to return the true value
- ui->topLevelSplitter->setSizes(QList<int>() << splitterSize - 100 << 100);
- connect(ui->logList->model(), SIGNAL(rowsInserted(const QModelIndex&, int, int)), ui->logList,
- SLOT(scrollToBottom()));
- connect(ui->logList->model(), SIGNAL(dataChanged(QModelIndex, QModelIndex)), ui->logList, SLOT(scrollToBottom()));
+ m_CategoryFactory.loadCategories();
- m_RefreshProgress = new QProgressBar(statusBar());
- m_RefreshProgress->setTextVisible(true);
- m_RefreshProgress->setRange(0, 100);
- m_RefreshProgress->setValue(0);
- m_RefreshProgress->setVisible(false);
- statusBar()->addWidget(m_RefreshProgress, 1000);
- statusBar()->clearMessage();
- statusBar()->hide();
+ ui->logList->setModel(LogBuffer::instance());
+ ui->logList->setColumnWidth(0, 100);
+ ui->logList->setAutoScroll(true);
+ ui->logList->scrollToBottom();
+ ui->logList->addAction(ui->actionCopy_Log_to_Clipboard);
+ int splitterSize = this->size().height(); // actually total window size, but the splitter doesn't seem to return the true value
+ ui->topLevelSplitter->setSizes(QList<int>() << splitterSize - 100 << 100);
+ connect(ui->logList->model(), SIGNAL(rowsInserted(const QModelIndex &, int, int)),
+ ui->logList, SLOT(scrollToBottom()));
+ connect(ui->logList->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
+ ui->logList, SLOT(scrollToBottom()));
- ui->actionEndorseMO->setVisible(false);
+ m_RefreshProgress = new QProgressBar(statusBar());
+ m_RefreshProgress->setTextVisible(true);
+ m_RefreshProgress->setRange(0, 100);
+ m_RefreshProgress->setValue(0);
+ m_RefreshProgress->setVisible(false);
+ statusBar()->addWidget(m_RefreshProgress, 1000);
+ statusBar()->clearMessage();
+ statusBar()->hide();
- updateProblemsButton();
+ ui->actionEndorseMO->setVisible(false);
- updateToolBar();
+ updateProblemsButton();
- TaskProgressManager::instance().tryCreateTaskbar();
+ updateToolBar();
- // set up mod list
- m_ModListSortProxy = m_OrganizerCore.createModListProxyModel();
+ TaskProgressManager::instance().tryCreateTaskbar();
- ui->modList->setModel(m_ModListSortProxy);
+ // set up mod list
+ m_ModListSortProxy = m_OrganizerCore.createModListProxyModel();
- GenericIconDelegate* contentDelegate =
- new GenericIconDelegate(ui->modList, Qt::UserRole + 3, ModList::COL_CONTENT, 150);
- connect(ui->modList->header(), SIGNAL(sectionResized(int, int, int)), contentDelegate,
- SLOT(columnResized(int, int, int)));
- ui->modList->sortByColumn(ModList::COL_PRIORITY, Qt::AscendingOrder);
- ui->modList->setItemDelegateForColumn(ModList::COL_FLAGS, new ModFlagIconDelegate(ui->modList));
- ui->modList->setItemDelegateForColumn(ModList::COL_CONTENT, contentDelegate);
- ui->modList->header()->installEventFilter(m_OrganizerCore.modList());
+ ui->modList->setModel(m_ModListSortProxy);
- bool modListAdjusted = registerWidgetState(ui->modList->objectName(), ui->modList->header(), "mod_list_state");
+ GenericIconDelegate *contentDelegate = new GenericIconDelegate(ui->modList, Qt::UserRole + 3, ModList::COL_CONTENT, 150);
+ connect(ui->modList->header(), SIGNAL(sectionResized(int,int,int)), contentDelegate, SLOT(columnResized(int,int,int)));
+ ui->modList->sortByColumn(ModList::COL_PRIORITY, Qt::AscendingOrder);
+ ui->modList->setItemDelegateForColumn(ModList::COL_FLAGS, new ModFlagIconDelegate(ui->modList));
+ ui->modList->setItemDelegateForColumn(ModList::COL_CONTENT, contentDelegate);
+ ui->modList->header()->installEventFilter(m_OrganizerCore.modList());
- if (modListAdjusted) {
- // hack: force the resize-signal to be triggered because restoreState doesn't seem to do that
- int sectionSize = ui->modList->header()->sectionSize(ModList::COL_CONTENT);
- ui->modList->header()->resizeSection(ModList::COL_CONTENT, sectionSize + 1);
- ui->modList->header()->resizeSection(ModList::COL_CONTENT, sectionSize);
- } else {
- // hide these columns by default
- ui->modList->header()->setSectionHidden(ModList::COL_CONTENT, true);
- ui->modList->header()->setSectionHidden(ModList::COL_MODID, true);
- ui->modList->header()->setSectionHidden(ModList::COL_INSTALLTIME, true);
- }
+ bool modListAdjusted = registerWidgetState(ui->modList->objectName(), ui->modList->header(), "mod_list_state");
- ui->modList->header()->setSectionHidden(ModList::COL_NAME, false); // prevent the name-column from being hidden
- ui->modList->installEventFilter(m_OrganizerCore.modList());
+ if (modListAdjusted) {
+ // hack: force the resize-signal to be triggered because restoreState doesn't seem to do that
+ int sectionSize = ui->modList->header()->sectionSize(ModList::COL_CONTENT);
+ ui->modList->header()->resizeSection(ModList::COL_CONTENT, sectionSize + 1);
+ ui->modList->header()->resizeSection(ModList::COL_CONTENT, sectionSize);
+ } else {
+ // hide these columns by default
+ ui->modList->header()->setSectionHidden(ModList::COL_CONTENT, true);
+ ui->modList->header()->setSectionHidden(ModList::COL_MODID, true);
+ ui->modList->header()->setSectionHidden(ModList::COL_INSTALLTIME, true);
+ }
- // set up plugin list
- m_PluginListSortProxy = m_OrganizerCore.createPluginListProxyModel();
+ ui->modList->header()->setSectionHidden(ModList::COL_NAME, false); // prevent the name-column from being hidden
+ ui->modList->installEventFilter(m_OrganizerCore.modList());
- ui->espList->setModel(m_PluginListSortProxy);
- ui->espList->sortByColumn(PluginList::COL_PRIORITY, Qt::AscendingOrder);
- ui->espList->setItemDelegateForColumn(PluginList::COL_FLAGS, new GenericIconDelegate(ui->espList));
- ui->espList->installEventFilter(m_OrganizerCore.pluginList());
+ // set up plugin list
+ m_PluginListSortProxy = m_OrganizerCore.createPluginListProxyModel();
- ui->bsaList->setLocalMoveOnly(true);
+ ui->espList->setModel(m_PluginListSortProxy);
+ ui->espList->sortByColumn(PluginList::COL_PRIORITY, Qt::AscendingOrder);
+ ui->espList->setItemDelegateForColumn(PluginList::COL_FLAGS, new GenericIconDelegate(ui->espList));
+ ui->espList->installEventFilter(m_OrganizerCore.pluginList());
- bool pluginListAdjusted =
- registerWidgetState(ui->espList->objectName(), ui->espList->header(), "plugin_list_state");
- registerWidgetState(ui->dataTree->objectName(), ui->dataTree->header());
- registerWidgetState(ui->downloadView->objectName(), ui->downloadView->header());
+ ui->bsaList->setLocalMoveOnly(true);
- ui->splitter->setStretchFactor(0, 3);
- ui->splitter->setStretchFactor(1, 2);
+ bool pluginListAdjusted = registerWidgetState(ui->espList->objectName(), ui->espList->header(), "plugin_list_state");
+ registerWidgetState(ui->dataTree->objectName(), ui->dataTree->header());
+ registerWidgetState(ui->downloadView->objectName(),
+ ui->downloadView->header());
- resizeLists(modListAdjusted, pluginListAdjusted);
+ ui->splitter->setStretchFactor(0, 3);
+ ui->splitter->setStretchFactor(1, 2);
- QMenu* linkMenu = new QMenu(this);
- linkMenu->addAction(QIcon(":/MO/gui/link"), tr("Toolbar"), this, SLOT(linkToolbar()));
- linkMenu->addAction(QIcon(":/MO/gui/link"), tr("Desktop"), this, SLOT(linkDesktop()));
- linkMenu->addAction(QIcon(":/MO/gui/link"), tr("Start Menu"), this, SLOT(linkMenu()));
- ui->linkButton->setMenu(linkMenu);
+ resizeLists(modListAdjusted, pluginListAdjusted);
- ui->listOptionsBtn->setMenu(modListContextMenu());
+ QMenu *linkMenu = new QMenu(this);
+ linkMenu->addAction(QIcon(":/MO/gui/link"), tr("Toolbar"), this, SLOT(linkToolbar()));
+ linkMenu->addAction(QIcon(":/MO/gui/link"), tr("Desktop"), this, SLOT(linkDesktop()));
+ linkMenu->addAction(QIcon(":/MO/gui/link"), tr("Start Menu"), this, SLOT(linkMenu()));
+ ui->linkButton->setMenu(linkMenu);
- updateDownloadListDelegate();
+ ui->listOptionsBtn->setMenu(modListContextMenu());
- ui->savegameList->installEventFilter(this);
- ui->savegameList->setMouseTracking(true);
+ updateDownloadListDelegate();
- // don't allow mouse wheel to switch grouping, too many people accidentally
- // turn on grouping and then don't understand what happened
- EventFilter* noWheel =
- new EventFilter(this, [](QObject*, QEvent* event) -> bool { return event->type() == QEvent::Wheel; });
+ ui->savegameList->installEventFilter(this);
+ ui->savegameList->setMouseTracking(true);
- ui->groupCombo->installEventFilter(noWheel);
- ui->profileBox->installEventFilter(noWheel);
+ // don't allow mouse wheel to switch grouping, too many people accidentally
+ // turn on grouping and then don't understand what happened
+ EventFilter *noWheel
+ = new EventFilter(this, [](QObject *, QEvent *event) -> bool {
+ return event->type() == QEvent::Wheel;
+ });
- connect(ui->savegameList, SIGNAL(itemEntered(QListWidgetItem*)), this,
- SLOT(saveSelectionChanged(QListWidgetItem*)));
+ ui->groupCombo->installEventFilter(noWheel);
+ ui->profileBox->installEventFilter(noWheel);
- connect(ui->modList, SIGNAL(dropModeUpdate(bool)), m_OrganizerCore.modList(), SLOT(dropModeUpdate(bool)));
+ connect(ui->savegameList, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(saveSelectionChanged(QListWidgetItem*)));
- connect(ui->modList->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this,
- SLOT(modlistSelectionChanged(QModelIndex, QModelIndex)));
- connect(m_ModListSortProxy, SIGNAL(filterActive(bool)), this, SLOT(modFilterActive(bool)));
- connect(ui->modFilterEdit, SIGNAL(textChanged(QString)), m_ModListSortProxy, SLOT(updateFilter(QString)));
+ connect(ui->modList, SIGNAL(dropModeUpdate(bool)), m_OrganizerCore.modList(), SLOT(dropModeUpdate(bool)));
- connect(ui->espFilterEdit, SIGNAL(textChanged(QString)), m_PluginListSortProxy, SLOT(updateFilter(QString)));
- connect(ui->espFilterEdit, SIGNAL(textChanged(QString)), this, SLOT(espFilterChanged(QString)));
+ connect(ui->modList->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(modlistSelectionChanged(QModelIndex,QModelIndex)));
+ connect(m_ModListSortProxy, SIGNAL(filterActive(bool)), this, SLOT(modFilterActive(bool)));
+ connect(ui->modFilterEdit, SIGNAL(textChanged(QString)), m_ModListSortProxy, SLOT(updateFilter(QString)));
- connect(ui->dataTree, SIGNAL(itemExpanded(QTreeWidgetItem*)), this, SLOT(expandDataTreeItem(QTreeWidgetItem*)));
+ connect(ui->espFilterEdit, SIGNAL(textChanged(QString)), m_PluginListSortProxy, SLOT(updateFilter(QString)));
+ connect(ui->espFilterEdit, SIGNAL(textChanged(QString)), this, SLOT(espFilterChanged(QString)));
- connect(m_OrganizerCore.directoryRefresher(), SIGNAL(refreshed()), this, SLOT(directory_refreshed()));
- connect(m_OrganizerCore.directoryRefresher(), SIGNAL(progress(int)), this, SLOT(refresher_progress(int)));
- connect(m_OrganizerCore.directoryRefresher(), SIGNAL(error(QString)), this, SLOT(showError(QString)));
+ connect(ui->dataTree, SIGNAL(itemExpanded(QTreeWidgetItem*)), this, SLOT(expandDataTreeItem(QTreeWidgetItem*)));
- connect(&m_SavesWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(refreshSavesIfOpen()));
+ connect(m_OrganizerCore.directoryRefresher(), SIGNAL(refreshed()), this, SLOT(directory_refreshed()));
+ connect(m_OrganizerCore.directoryRefresher(), SIGNAL(progress(int)), this, SLOT(refresher_progress(int)));
+ connect(m_OrganizerCore.directoryRefresher(), SIGNAL(error(QString)), this, SLOT(showError(QString)));
- connect(&m_OrganizerCore.settings(), SIGNAL(languageChanged(QString)), this, SLOT(languageChange(QString)));
- connect(&m_OrganizerCore.settings(), SIGNAL(styleChanged(QString)), this, SIGNAL(styleChanged(QString)));
+ connect(&m_SavesWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(refreshSavesIfOpen()));
- connect(m_OrganizerCore.updater(), SIGNAL(restart()), this, SLOT(close()));
- connect(m_OrganizerCore.updater(), SIGNAL(updateAvailable()), this, SLOT(updateAvailable()));
- connect(m_OrganizerCore.updater(), SIGNAL(motdAvailable(QString)), this, SLOT(motdReceived(QString)));
+ connect(&m_OrganizerCore.settings(), SIGNAL(languageChanged(QString)), this, SLOT(languageChange(QString)));
+ connect(&m_OrganizerCore.settings(), SIGNAL(styleChanged(QString)), this, SIGNAL(styleChanged(QString)));
- connect(NexusInterface::instance(), SIGNAL(requestNXMDownload(QString)), &m_OrganizerCore,
- SLOT(downloadRequestedNXM(QString)));
- connect(NexusInterface::instance(), SIGNAL(nxmDownloadURLsAvailable(int, int, QVariant, QVariant, int)), this,
- SLOT(nxmDownloadURLs(int, int, QVariant, QVariant, int)));
- connect(NexusInterface::instance(), SIGNAL(needLogin()), &m_OrganizerCore, SLOT(nexusLogin()));
- connect(NexusInterface::instance()->getAccessManager(), SIGNAL(loginFailed(QString)), this,
- SLOT(loginFailed(QString)));
- connect(NexusInterface::instance()->getAccessManager(), SIGNAL(credentialsReceived(const QString&, bool)), this,
- SLOT(updateWindowTitle(const QString&, bool)));
+ connect(m_OrganizerCore.updater(), SIGNAL(restart()), this, SLOT(close()));
+ connect(m_OrganizerCore.updater(), SIGNAL(updateAvailable()), this, SLOT(updateAvailable()));
+ connect(m_OrganizerCore.updater(), SIGNAL(motdAvailable(QString)), this, SLOT(motdReceived(QString)));
- connect(&TutorialManager::instance(), SIGNAL(windowTutorialFinished(QString)), this,
- SLOT(windowTutorialFinished(QString)));
- connect(ui->tabWidget, SIGNAL(currentChanged(int)), &TutorialManager::instance(), SIGNAL(tabChanged(int)));
- connect(ui->modList->header(), SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), this,
- SLOT(modListSortIndicatorChanged(int, Qt::SortOrder)));
- connect(ui->toolBar, SIGNAL(customContextMenuRequested(QPoint)), this,
- SLOT(toolBar_customContextMenuRequested(QPoint)));
+ connect(NexusInterface::instance(), SIGNAL(requestNXMDownload(QString)), &m_OrganizerCore, SLOT(downloadRequestedNXM(QString)));
+ connect(NexusInterface::instance(), SIGNAL(nxmDownloadURLsAvailable(int,int,QVariant,QVariant,int)), this, SLOT(nxmDownloadURLs(int,int,QVariant,QVariant,int)));
+ connect(NexusInterface::instance(), SIGNAL(needLogin()), &m_OrganizerCore, SLOT(nexusLogin()));
+ connect(NexusInterface::instance()->getAccessManager(), SIGNAL(loginFailed(QString)), this, SLOT(loginFailed(QString)));
+ connect(NexusInterface::instance()->getAccessManager(), SIGNAL(credentialsReceived(const QString&, bool)),
+ this, SLOT(updateWindowTitle(const QString&, bool)));
- connect(&m_OrganizerCore, &OrganizerCore::modInstalled, this, &MainWindow::modInstalled);
- connect(&m_OrganizerCore, &OrganizerCore::close, this, &QMainWindow::close);
+ connect(&TutorialManager::instance(), SIGNAL(windowTutorialFinished(QString)), this, SLOT(windowTutorialFinished(QString)));
+ connect(ui->tabWidget, SIGNAL(currentChanged(int)), &TutorialManager::instance(), SIGNAL(tabChanged(int)));
+ connect(ui->modList->header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(modListSortIndicatorChanged(int,Qt::SortOrder)));
+ connect(ui->toolBar, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(toolBar_customContextMenuRequested(QPoint)));
- connect(&m_IntegratedBrowser, SIGNAL(requestDownload(QUrl, QNetworkReply*)), &m_OrganizerCore,
- SLOT(requestDownload(QUrl, QNetworkReply*)));
+ connect(&m_OrganizerCore, &OrganizerCore::modInstalled, this, &MainWindow::modInstalled);
+ connect(&m_OrganizerCore, &OrganizerCore::close, this, &QMainWindow::close);
- connect(this, SIGNAL(styleChanged(QString)), this, SLOT(updateStyle(QString)));
+ connect(&m_IntegratedBrowser, SIGNAL(requestDownload(QUrl,QNetworkReply*)), &m_OrganizerCore, SLOT(requestDownload(QUrl,QNetworkReply*)));
- m_CheckBSATimer.setSingleShot(true);
- connect(&m_CheckBSATimer, SIGNAL(timeout()), this, SLOT(checkBSAList()));
+ connect(this, SIGNAL(styleChanged(QString)), this, SLOT(updateStyle(QString)));
- connect(ui->espList->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this,
- SLOT(esplistSelectionsChanged(QItemSelection)));
- connect(ui->modList->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this,
- SLOT(modlistSelectionsChanged(QItemSelection)));
+ m_CheckBSATimer.setSingleShot(true);
+ connect(&m_CheckBSATimer, SIGNAL(timeout()), this, SLOT(checkBSAList()));
- m_UpdateProblemsTimer.setSingleShot(true);
- connect(&m_UpdateProblemsTimer, SIGNAL(timeout()), this, SLOT(updateProblemsButton()));
+ connect(ui->espList->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(esplistSelectionsChanged(QItemSelection)));
+ connect(ui->modList->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(modlistSelectionsChanged(QItemSelection)));
- m_SaveMetaTimer.setSingleShot(false);
- connect(&m_SaveMetaTimer, SIGNAL(timeout()), this, SLOT(saveModMetas()));
- m_SaveMetaTimer.start(5000);
+ m_UpdateProblemsTimer.setSingleShot(true);
+ connect(&m_UpdateProblemsTimer, SIGNAL(timeout()), this, SLOT(updateProblemsButton()));
- setCategoryListVisible(initSettings.value("categorylist_visible", true).toBool());
- FileDialogMemory::restore(initSettings);
+ m_SaveMetaTimer.setSingleShot(false);
+ connect(&m_SaveMetaTimer, SIGNAL(timeout()), this, SLOT(saveModMetas()));
+ m_SaveMetaTimer.start(5000);
- fixCategories();
+ setCategoryListVisible(initSettings.value("categorylist_visible", true).toBool());
+ FileDialogMemory::restore(initSettings);
- m_StartTime = QTime::currentTime();
+ fixCategories();
- m_Tutorial.expose("modList", m_OrganizerCore.modList());
- m_Tutorial.expose("espList", m_OrganizerCore.pluginList());
+ m_StartTime = QTime::currentTime();
- m_OrganizerCore.setUserInterface(this, this);
- for (const QString& fileName : m_PluginContainer.pluginFileNames()) {
- installTranslator(QFileInfo(fileName).baseName());
- }
- for (IPluginTool* toolPlugin : m_PluginContainer.plugins<IPluginTool>()) {
- registerPluginTool(toolPlugin);
- }
+ m_Tutorial.expose("modList", m_OrganizerCore.modList());
+ m_Tutorial.expose("espList", m_OrganizerCore.pluginList());
- for (IPluginModPage* modPagePlugin : m_PluginContainer.plugins<IPluginModPage>()) {
- registerModPage(modPagePlugin);
- }
+ m_OrganizerCore.setUserInterface(this, this);
+ for (const QString &fileName : m_PluginContainer.pluginFileNames()) {
+ installTranslator(QFileInfo(fileName).baseName());
+ }
+ for (IPluginTool *toolPlugin : m_PluginContainer.plugins<IPluginTool>()) {
+ registerPluginTool(toolPlugin);
+ }
- // refresh profiles so the current profile can be activated
- refreshProfiles(false);
+ for (IPluginModPage *modPagePlugin : m_PluginContainer.plugins<IPluginModPage>()) {
+ registerModPage(modPagePlugin);
+ }
- ui->profileBox->setCurrentText(m_OrganizerCore.currentProfile()->name());
+ // refresh profiles so the current profile can be activated
+ refreshProfiles(false);
- refreshExecutablesList();
- updateToolBar();
+ ui->profileBox->setCurrentText(m_OrganizerCore.currentProfile()->name());
+
+ refreshExecutablesList();
+ updateToolBar();
}
-MainWindow::~MainWindow() {
- cleanup();
- m_PluginContainer.setUserInterface(nullptr, nullptr);
- m_OrganizerCore.setUserInterface(nullptr, nullptr);
- m_IntegratedBrowser.close();
- delete ui;
+MainWindow::~MainWindow()
+{
+ cleanup();
+
+ m_PluginContainer.setUserInterface(nullptr, nullptr);
+ m_OrganizerCore.setUserInterface(nullptr, nullptr);
+ m_IntegratedBrowser.close();
+ delete ui;
}
-void MainWindow::updateWindowTitle(const QString& accountName, bool premium) {
- QString title = QString("%1 Mod Organizer v%2")
- .arg(m_OrganizerCore.managedGame()->gameName(), m_OrganizerCore.getVersion().displayString());
- if (!accountName.isEmpty()) {
- title.append(QString(" (%1%2)").arg(accountName, premium ? "*" : ""));
- }
+void MainWindow::updateWindowTitle(const QString &accountName, bool premium)
+{
+ QString title = QString("%1 Mod Organizer v%2").arg(
+ m_OrganizerCore.managedGame()->gameName(),
+ m_OrganizerCore.getVersion().displayString());
- this->setWindowTitle(title);
+ if (!accountName.isEmpty()) {
+ title.append(QString(" (%1%2)").arg(accountName, premium ? "*" : ""));
+ }
+
+ this->setWindowTitle(title);
}
-void MainWindow::disconnectPlugins() {
- if (ui->actionTool->menu() != nullptr) {
- ui->actionTool->menu()->clear();
- }
+
+void MainWindow::disconnectPlugins()
+{
+ if (ui->actionTool->menu() != nullptr) {
+ ui->actionTool->menu()->clear();
+ }
}
-void MainWindow::resizeLists(bool modListCustom, bool pluginListCustom) {
- if (!modListCustom) {
- // resize mod list to fit content
- for (int i = 0; i < ui->modList->header()->count(); ++i) {
- ui->modList->header()->setSectionResizeMode(i, QHeaderView::ResizeToContents);
- }
- ui->modList->header()->setSectionResizeMode(ModList::COL_NAME, QHeaderView::Stretch);
- }
- // ensure the columns aren't so small you can't see them any more
+void MainWindow::resizeLists(bool modListCustom, bool pluginListCustom)
+{
+ if (!modListCustom) {
+ // resize mod list to fit content
for (int i = 0; i < ui->modList->header()->count(); ++i) {
- if (ui->modList->header()->sectionSize(i) < 10) {
- ui->modList->header()->resizeSection(i, 10);
- }
+ ui->modList->header()->setSectionResizeMode(i, QHeaderView::ResizeToContents);
}
+ ui->modList->header()->setSectionResizeMode(ModList::COL_NAME, QHeaderView::Stretch);
+ }
- if (!pluginListCustom) {
- // resize plugin list to fit content
- for (int i = 0; i < ui->espList->header()->count(); ++i) {
- ui->espList->header()->setSectionResizeMode(i, QHeaderView::ResizeToContents);
- }
- ui->espList->header()->setSectionResizeMode(0, QHeaderView::Stretch);
+ // ensure the columns aren't so small you can't see them any more
+ for (int i = 0; i < ui->modList->header()->count(); ++i) {
+ if (ui->modList->header()->sectionSize(i) < 10) {
+ ui->modList->header()->resizeSection(i, 10);
}
-}
+ }
-void MainWindow::allowListResize() {
- // allow resize on mod list
- for (int i = 0; i < ui->modList->header()->count(); ++i) {
- ui->modList->header()->setSectionResizeMode(i, QHeaderView::Interactive);
- }
- // ui->modList->header()->setSectionResizeMode(ui->modList->header()->count() - 1, QHeaderView::Stretch);
- ui->modList->header()->setStretchLastSection(true);
-
- // allow resize on plugin list
+ if (!pluginListCustom) {
+ // resize plugin list to fit content
for (int i = 0; i < ui->espList->header()->count(); ++i) {
- ui->espList->header()->setSectionResizeMode(i, QHeaderView::Interactive);
+ ui->espList->header()->setSectionResizeMode(i, QHeaderView::ResizeToContents);
}
- // ui->espList->header()->setSectionResizeMode(ui->espList->header()->count() - 1, QHeaderView::Stretch);
- ui->espList->header()->setStretchLastSection(true);
+ ui->espList->header()->setSectionResizeMode(0, QHeaderView::Stretch);
+ }
+}
+
+
+void MainWindow::allowListResize()
+{
+ // allow resize on mod list
+ for (int i = 0; i < ui->modList->header()->count(); ++i) {
+ ui->modList->header()->setSectionResizeMode(i, QHeaderView::Interactive);
+ }
+ //ui->modList->header()->setSectionResizeMode(ui->modList->header()->count() - 1, QHeaderView::Stretch);
+ ui->modList->header()->setStretchLastSection(true);
+
+
+ // allow resize on plugin list
+ for (int i = 0; i < ui->espList->header()->count(); ++i) {
+ ui->espList->header()->setSectionResizeMode(i, QHeaderView::Interactive);
+ }
+ //ui->espList->header()->setSectionResizeMode(ui->espList->header()->count() - 1, QHeaderView::Stretch);
+ ui->espList->header()->setStretchLastSection(true);
}
-void MainWindow::updateStyle(const QString&) {
- // no effect?
- ensurePolished();
+void MainWindow::updateStyle(const QString&)
+{
+ // no effect?
+ ensurePolished();
}
-void MainWindow::resizeEvent(QResizeEvent* event) {
- m_Tutorial.resize(event->size());
- QMainWindow::resizeEvent(event);
+void MainWindow::resizeEvent(QResizeEvent *event)
+{
+ m_Tutorial.resize(event->size());
+ QMainWindow::resizeEvent(event);
}
-static QModelIndex mapToModel(const QAbstractItemModel* targetModel, QModelIndex idx) {
- QModelIndex result = idx;
- const QAbstractItemModel* model = idx.model();
- while (model != targetModel) {
- if (model == nullptr) {
- return QModelIndex();
- }
- const QAbstractProxyModel* proxyModel = qobject_cast<const QAbstractProxyModel*>(model);
- if (proxyModel == nullptr) {
- return QModelIndex();
- }
- result = proxyModel->mapToSource(result);
- model = proxyModel->sourceModel();
+
+static QModelIndex mapToModel(const QAbstractItemModel *targetModel, QModelIndex idx)
+{
+ QModelIndex result = idx;
+ const QAbstractItemModel *model = idx.model();
+ while (model != targetModel) {
+ if (model == nullptr) {
+ return QModelIndex();
}
- return result;
+ const QAbstractProxyModel *proxyModel = qobject_cast<const QAbstractProxyModel*>(model);
+ if (proxyModel == nullptr) {
+ return QModelIndex();
+ }
+ result = proxyModel->mapToSource(result);
+ model = proxyModel->sourceModel();
+ }
+ return result;
}
-void MainWindow::actionToToolButton(QAction*& sourceAction) {
- QToolButton* button = new QToolButton(ui->toolBar);
- button->setObjectName(sourceAction->objectName());
- button->setIcon(sourceAction->icon());
- button->setText(sourceAction->text());
- button->setPopupMode(QToolButton::InstantPopup);
- button->setToolButtonStyle(ui->toolBar->toolButtonStyle());
- button->setToolTip(sourceAction->toolTip());
- button->setShortcut(sourceAction->shortcut());
- QMenu* buttonMenu = new QMenu(sourceAction->text(), button);
- button->setMenu(buttonMenu);
- QAction* newAction = ui->toolBar->insertWidget(sourceAction, button);
- newAction->setObjectName(sourceAction->objectName());
- newAction->setIcon(sourceAction->icon());
- newAction->setText(sourceAction->text());
- newAction->setToolTip(sourceAction->toolTip());
- newAction->setShortcut(sourceAction->shortcut());
- ui->toolBar->removeAction(sourceAction);
- sourceAction->deleteLater();
- sourceAction = newAction;
+
+void MainWindow::actionToToolButton(QAction *&sourceAction)
+{
+ QToolButton *button = new QToolButton(ui->toolBar);
+ button->setObjectName(sourceAction->objectName());
+ button->setIcon(sourceAction->icon());
+ button->setText(sourceAction->text());
+ button->setPopupMode(QToolButton::InstantPopup);
+ button->setToolButtonStyle(ui->toolBar->toolButtonStyle());
+ button->setToolTip(sourceAction->toolTip());
+ button->setShortcut(sourceAction->shortcut());
+ QMenu *buttonMenu = new QMenu(sourceAction->text(), button);
+ button->setMenu(buttonMenu);
+ QAction *newAction = ui->toolBar->insertWidget(sourceAction, button);
+ newAction->setObjectName(sourceAction->objectName());
+ newAction->setIcon(sourceAction->icon());
+ newAction->setText(sourceAction->text());
+ newAction->setToolTip(sourceAction->toolTip());
+ newAction->setShortcut(sourceAction->shortcut());
+ ui->toolBar->removeAction(sourceAction);
+ sourceAction->deleteLater();
+ sourceAction = newAction;
}
-void MainWindow::updateToolBar() {
- for (QAction* action : ui->toolBar->actions()) {
- if (action->objectName().startsWith("custom__")) {
- ui->toolBar->removeAction(action);
- }
+void MainWindow::updateToolBar()
+{
+ for (QAction *action : ui->toolBar->actions()) {
+ if (action->objectName().startsWith("custom__")) {
+ ui->toolBar->removeAction(action);
}
+ }
- QWidget* spacer = new QWidget(ui->toolBar);
- spacer->setObjectName("custom__spacer");
- spacer->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
- QWidget* widget = ui->toolBar->widgetForAction(ui->actionTool);
- QToolButton* toolBtn = qobject_cast<QToolButton*>(widget);
+ QWidget *spacer = new QWidget(ui->toolBar);
+ spacer->setObjectName("custom__spacer");
+ spacer->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
+ QWidget *widget = ui->toolBar->widgetForAction(ui->actionTool);
+ QToolButton *toolBtn = qobject_cast<QToolButton*>(widget);
- if (toolBtn->menu() == nullptr) {
- actionToToolButton(ui->actionTool);
- }
+ if (toolBtn->menu() == nullptr) {
+ actionToToolButton(ui->actionTool);
+ }
- actionToToolButton(ui->actionHelp);
- createHelpWidget();
+ actionToToolButton(ui->actionHelp);
+ createHelpWidget();
- for (QAction* action : ui->toolBar->actions()) {
- if (action->isSeparator()) {
- // insert spacers
- ui->toolBar->insertWidget(action, spacer);
+ for (QAction *action : ui->toolBar->actions()) {
+ if (action->isSeparator()) {
+ // insert spacers
+ ui->toolBar->insertWidget(action, spacer);
- std::vector<Executable>::iterator begin, end;
- m_OrganizerCore.executablesList()->getExecutables(begin, end);
- for (auto iter = begin; iter != end; ++iter) {
- if (iter->isShownOnToolbar()) {
- QAction* exeAction =
- new QAction(iconForExecutable(iter->m_BinaryInfo.filePath()), iter->m_Title, ui->toolBar);
- exeAction->setObjectName(QString("custom__") + iter->m_Title);
- if (!connect(exeAction, SIGNAL(triggered()), this, SLOT(startExeAction()))) {
- qDebug("failed to connect trigger?");
- }
- ui->toolBar->insertAction(action, exeAction);
- }
- }
+ std::vector<Executable>::iterator begin, end;
+ m_OrganizerCore.executablesList()->getExecutables(begin, end);
+ for (auto iter = begin; iter != end; ++iter) {
+ if (iter->isShownOnToolbar()) {
+ QAction *exeAction = new QAction(iconForExecutable(iter->m_BinaryInfo.filePath()),
+ iter->m_Title,
+ ui->toolBar);
+ exeAction->setObjectName(QString("custom__") + iter->m_Title);
+ if (!connect(exeAction, SIGNAL(triggered()), this, SLOT(startExeAction()))) {
+ qDebug("failed to connect trigger?");
+ }
+ ui->toolBar->insertAction(action, exeAction);
}
+ }
}
+ }
}
-void MainWindow::scheduleUpdateButton() {
- if (!m_UpdateProblemsTimer.isActive()) {
- m_UpdateProblemsTimer.start(1000);
- }
+
+void MainWindow::scheduleUpdateButton()
+{
+ if (!m_UpdateProblemsTimer.isActive()) {
+ m_UpdateProblemsTimer.start(1000);
+ }
}
-void MainWindow::updateProblemsButton() {
- size_t numProblems = checkForProblems();
- if (numProblems > 0) {
- ui->actionProblems->setEnabled(true);
- ui->actionProblems->setIconText(tr("Problems"));
- ui->actionProblems->setToolTip(tr("There are potential problems with your setup"));
- QPixmap mergedIcon = QPixmap(":/MO/gui/warning").scaled(64, 64);
- {
- QPainter painter(&mergedIcon);
- std::string badgeName = std::string(":/MO/gui/badge_") +
- (numProblems < 10 ? std::to_string(static_cast<long long>(numProblems)) : "more");
- painter.drawPixmap(32, 32, 32, 32, QPixmap(badgeName.c_str()));
- }
- ui->actionProblems->setIcon(QIcon(mergedIcon));
- } else {
- ui->actionProblems->setEnabled(false);
- ui->actionProblems->setIconText(tr("No Problems"));
- ui->actionProblems->setToolTip(tr("Everything seems to be in order"));
- ui->actionProblems->setIcon(QIcon(":/MO/gui/warning"));
+void MainWindow::updateProblemsButton()
+{
+ size_t numProblems = checkForProblems();
+ if (numProblems > 0) {
+ ui->actionProblems->setEnabled(true);
+ ui->actionProblems->setIconText(tr("Problems"));
+ ui->actionProblems->setToolTip(tr("There are potential problems with your setup"));
+
+ QPixmap mergedIcon = QPixmap(":/MO/gui/warning").scaled(64, 64);
+ {
+ QPainter painter(&mergedIcon);
+ std::string badgeName = std::string(":/MO/gui/badge_") + (numProblems < 10 ? std::to_string(static_cast<long long>(numProblems)) : "more");
+ painter.drawPixmap(32, 32, 32, 32, QPixmap(badgeName.c_str()));
}
+ ui->actionProblems->setIcon(QIcon(mergedIcon));
+ } else {
+ ui->actionProblems->setEnabled(false);
+ ui->actionProblems->setIconText(tr("No Problems"));
+ ui->actionProblems->setToolTip(tr("Everything seems to be in order"));
+ ui->actionProblems->setIcon(QIcon(":/MO/gui/warning"));
+ }
}
-bool MainWindow::errorReported(QString& logFile) {
- QDir dir(qApp->property("dataPath").toString() + "/" + QString::fromStdWString(AppConfig::logPath()));
- QFileInfoList files =
- dir.entryInfoList(QStringList("ModOrganizer_??_??_??_??_??.log"), QDir::Files, QDir::Name | QDir::Reversed);
- if (files.count() > 0) {
- logFile = files.at(0).absoluteFilePath();
- QFile file(logFile);
- if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- char buffer[1024];
- int line = 0;
- while (!file.atEnd()) {
- file.readLine(buffer, 1024);
- if (strncmp(buffer, "ERROR", 5) == 0) {
- return true;
- }
+bool MainWindow::errorReported(QString &logFile)
+{
+ QDir dir(qApp->property("dataPath").toString() + "/" + QString::fromStdWString(AppConfig::logPath()));
+ QFileInfoList files = dir.entryInfoList(QStringList("ModOrganizer_??_??_??_??_??.log"),
+ QDir::Files, QDir::Name | QDir::Reversed);
- // prevent this function from taking forever
- if (line++ >= 50000) {
- break;
- }
- }
+ if (files.count() > 0) {
+ logFile = files.at(0).absoluteFilePath();
+ QFile file(logFile);
+ if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ char buffer[1024];
+ int line = 0;
+ while (!file.atEnd()) {
+ file.readLine(buffer, 1024);
+ if (strncmp(buffer, "ERROR", 5) == 0) {
+ return true;
+ }
+
+ // prevent this function from taking forever
+ if (line++ >= 50000) {
+ break;
}
+ }
}
+ }
- return false;
+ return false;
}
-size_t MainWindow::checkForProblems() {
- size_t numProblems = 0;
- for (IPluginDiagnose* diagnose : m_PluginContainer.plugins<IPluginDiagnose>()) {
- numProblems += diagnose->activeProblems().size();
- }
- return numProblems;
+
+size_t MainWindow::checkForProblems()
+{
+ size_t numProblems = 0;
+ for (IPluginDiagnose *diagnose : m_PluginContainer.plugins<IPluginDiagnose>()) {
+ numProblems += diagnose->activeProblems().size();
+ }
+ return numProblems;
}
-void MainWindow::about() {
- AboutDialog dialog(m_OrganizerCore.getVersion().displayString(), this);
- dialog.exec();
+void MainWindow::about()
+{
+ AboutDialog dialog(m_OrganizerCore.getVersion().displayString(), this);
+ dialog.exec();
}
-void MainWindow::createHelpWidget() {
- QToolButton* toolBtn = qobject_cast<QToolButton*>(ui->toolBar->widgetForAction(ui->actionHelp));
- QMenu* buttonMenu = toolBtn->menu();
- if (buttonMenu == nullptr) {
- return;
- }
- buttonMenu->clear();
- QAction* helpAction = new QAction(tr("Help on UI"), buttonMenu);
- connect(helpAction, SIGNAL(triggered()), this, SLOT(helpTriggered()));
- buttonMenu->addAction(helpAction);
+void MainWindow::createHelpWidget()
+{
+ QToolButton *toolBtn = qobject_cast<QToolButton*>(ui->toolBar->widgetForAction(ui->actionHelp));
+ QMenu *buttonMenu = toolBtn->menu();
+ if (buttonMenu == nullptr) {
+ return;
+ }
+ buttonMenu->clear();
- QAction* wikiAction = new QAction(tr("Documentation Wiki"), buttonMenu);
- connect(wikiAction, SIGNAL(triggered()), this, SLOT(wikiTriggered()));
- buttonMenu->addAction(wikiAction);
+ QAction *helpAction = new QAction(tr("Help on UI"), buttonMenu);
+ connect(helpAction, SIGNAL(triggered()), this, SLOT(helpTriggered()));
+ buttonMenu->addAction(helpAction);
- QAction* issueAction = new QAction(tr("Report Issue"), buttonMenu);
- connect(issueAction, SIGNAL(triggered()), this, SLOT(issueTriggered()));
- buttonMenu->addAction(issueAction);
+ QAction *wikiAction = new QAction(tr("Documentation Wiki"), buttonMenu);
+ connect(wikiAction, SIGNAL(triggered()), this, SLOT(wikiTriggered()));
+ buttonMenu->addAction(wikiAction);
- QMenu* tutorialMenu = new QMenu(tr("Tutorials"), buttonMenu);
+ QAction *issueAction = new QAction(tr("Report Issue"), buttonMenu);
+ connect(issueAction, SIGNAL(triggered()), this, SLOT(issueTriggered()));
+ buttonMenu->addAction(issueAction);
- typedef std::vector<std::pair<int, QAction*>> ActionList;
+ QMenu *tutorialMenu = new QMenu(tr("Tutorials"), buttonMenu);
- ActionList tutorials;
+ typedef std::vector<std::pair<int, QAction*> > ActionList;
- QDirIterator dirIter(QApplication::applicationDirPath() + "/tutorials", QStringList("*.js"), QDir::Files);
- while (dirIter.hasNext()) {
- dirIter.next();
- QString fileName = dirIter.fileName();
+ ActionList tutorials;
- QFile file(dirIter.filePath());
- if (!file.open(QIODevice::ReadOnly)) {
- qCritical() << "Failed to open " << fileName;
- continue;
- }
- QString firstLine = QString::fromUtf8(file.readLine());
- if (firstLine.startsWith("//TL")) {
- QStringList params = firstLine.mid(4).trimmed().split('#');
- if (params.size() != 2) {
- qCritical() << "invalid header line for tutorial " << fileName << " expected 2 parameters";
- continue;
- }
- QAction* tutAction = new QAction(params.at(0), tutorialMenu);
- tutAction->setData(fileName);
- tutorials.push_back(std::make_pair(params.at(1).toInt(), tutAction));
- }
+ QDirIterator dirIter(QApplication::applicationDirPath() + "/tutorials", QStringList("*.js"), QDir::Files);
+ while (dirIter.hasNext()) {
+ dirIter.next();
+ QString fileName = dirIter.fileName();
+
+ QFile file(dirIter.filePath());
+ if (!file.open(QIODevice::ReadOnly)) {
+ qCritical() << "Failed to open " << fileName;
+ continue;
+ }
+ QString firstLine = QString::fromUtf8(file.readLine());
+ if (firstLine.startsWith("//TL")) {
+ QStringList params = firstLine.mid(4).trimmed().split('#');
+ if (params.size() != 2) {
+ qCritical() << "invalid header line for tutorial " << fileName << " expected 2 parameters";
+ continue;
+ }
+ QAction *tutAction = new QAction(params.at(0), tutorialMenu);
+ tutAction->setData(fileName);
+ tutorials.push_back(std::make_pair(params.at(1).toInt(), tutAction));
}
+ }
- std::sort(
- tutorials.begin(), tutorials.end(),
- [](const ActionList::value_type& LHS, const ActionList::value_type& RHS) { return LHS.first < RHS.first; });
+ std::sort(tutorials.begin(), tutorials.end(),
+ [] (const ActionList::value_type &LHS, const ActionList::value_type &RHS) {
+ return LHS.first < RHS.first; } );
- for (auto iter = tutorials.begin(); iter != tutorials.end(); ++iter) {
- connect(iter->second, SIGNAL(triggered()), this, SLOT(tutorialTriggered()));
- tutorialMenu->addAction(iter->second);
- }
+ for (auto iter = tutorials.begin(); iter != tutorials.end(); ++iter) {
+ connect(iter->second, SIGNAL(triggered()), this, SLOT(tutorialTriggered()));
+ tutorialMenu->addAction(iter->second);
+ }
- buttonMenu->addMenu(tutorialMenu);
- buttonMenu->addAction(tr("About"), this, SLOT(about()));
- buttonMenu->addAction(tr("About Qt"), qApp, SLOT(aboutQt()));
+ buttonMenu->addMenu(tutorialMenu);
+ buttonMenu->addAction(tr("About"), this, SLOT(about()));
+ buttonMenu->addAction(tr("About Qt"), qApp, SLOT(aboutQt()));
}
-void MainWindow::modFilterActive(bool filterActive) {
- if (filterActive) {
- // m_OrganizerCore.modList()->setOverwriteMarkers(std::set<unsigned int>(), std::set<unsigned int>());
- ui->modList->setStyleSheet("QTreeView { border: 2px ridge #f00; }");
- } else if (ui->groupCombo->currentIndex() != 0) {
- ui->modList->setStyleSheet("QTreeView { border: 2px ridge #337733; }");
- } else {
- ui->modList->setStyleSheet("");
- }
+void MainWindow::modFilterActive(bool filterActive)
+{
+ if (filterActive) {
+// m_OrganizerCore.modList()->setOverwriteMarkers(std::set<unsigned int>(), std::set<unsigned int>());
+ ui->modList->setStyleSheet("QTreeView { border: 2px ridge #f00; }");
+ } else if (ui->groupCombo->currentIndex() != 0) {
+ ui->modList->setStyleSheet("QTreeView { border: 2px ridge #337733; }");
+ } else {
+ ui->modList->setStyleSheet("");
+ }
}
-void MainWindow::espFilterChanged(const QString& filter) {
- if (!filter.isEmpty()) {
- ui->espList->setStyleSheet("QTreeView { border: 2px ridge #f00; }");
- } else {
- ui->espList->setStyleSheet("");
- }
+void MainWindow::espFilterChanged(const QString &filter)
+{
+ if (!filter.isEmpty()) {
+ ui->espList->setStyleSheet("QTreeView { border: 2px ridge #f00; }");
+ } else {
+ ui->espList->setStyleSheet("");
+ }
}
-void MainWindow::downloadFilterChanged(const QString& filter) {
- if (!filter.isEmpty()) {
- ui->downloadView->setStyleSheet("QTreeView { border: 2px ridge #f00; }");
- } else {
- ui->downloadView->setStyleSheet("");
- }
+void MainWindow::downloadFilterChanged(const QString &filter)
+{
+ if (!filter.isEmpty()) {
+ ui->downloadView->setStyleSheet("QTreeView { border: 2px ridge #f00; }");
+ } else {
+ ui->downloadView->setStyleSheet("");
+ }
}
-void MainWindow::expandModList(const QModelIndex& index) {
- QAbstractItemModel* model = ui->modList->model();
+void MainWindow::expandModList(const QModelIndex &index)
+{
+ QAbstractItemModel *model = ui->modList->model();
#pragma message("why is this so complicated? mapping the index doesn't work, probably a bug in QtGroupingProxy?")
- for (int i = 0; i < model->rowCount(); ++i) {
- QModelIndex targetIdx = model->index(i, 0);
- if (model->data(targetIdx).toString() == index.data().toString()) {
- ui->modList->expand(targetIdx);
- break;
- }
+ for (int i = 0; i < model->rowCount(); ++i) {
+ QModelIndex targetIdx = model->index(i, 0);
+ if (model->data(targetIdx).toString() == index.data().toString()) {
+ ui->modList->expand(targetIdx);
+ break;
}
+ }
}
-bool MainWindow::addProfile() {
- QComboBox* profileBox = findChild<QComboBox*>("profileBox");
- bool okClicked = false;
- QString name = QInputDialog::getText(this, tr("Name"), tr("Please enter a name for the new profile"),
- QLineEdit::Normal, QString(), &okClicked);
- if (okClicked && (name.size() > 0)) {
- try {
- profileBox->addItem(name);
- profileBox->setCurrentIndex(profileBox->count() - 1);
- return true;
- } catch (const std::exception& e) {
- reportError(tr("failed to create profile: %1").arg(e.what()));
- return false;
- }
- } else {
- return false;
+bool MainWindow::addProfile()
+{
+ QComboBox *profileBox = findChild<QComboBox*>("profileBox");
+ bool okClicked = false;
+
+ QString name = QInputDialog::getText(this, tr("Name"),
+ tr("Please enter a name for the new profile"),
+ QLineEdit::Normal, QString(), &okClicked);
+ if (okClicked && (name.size() > 0)) {
+ try {
+ profileBox->addItem(name);
+ profileBox->setCurrentIndex(profileBox->count() - 1);
+ return true;
+ } catch (const std::exception& e) {
+ reportError(tr("failed to create profile: %1").arg(e.what()));
+ return false;
}
+ } else {
+ return false;
+ }
}
-void MainWindow::hookUpWindowTutorials() {
- QDirIterator dirIter(QApplication::applicationDirPath() + "/tutorials", QStringList("*.js"), QDir::Files);
- while (dirIter.hasNext()) {
- dirIter.next();
- QString fileName = dirIter.fileName();
- QFile file(dirIter.filePath());
- if (!file.open(QIODevice::ReadOnly)) {
- qCritical() << "Failed to open " << fileName;
- continue;
- }
- QString firstLine = QString::fromUtf8(file.readLine());
- if (firstLine.startsWith("//WIN")) {
- QString windowName = firstLine.mid(6).trimmed();
- if (!m_OrganizerCore.settings()
- .directInterface()
- .value("CompletedWindowTutorials/" + windowName, false)
- .toBool()) {
- TutorialManager::instance().activateTutorial(windowName, fileName);
- }
- }
+void MainWindow::hookUpWindowTutorials()
+{
+ QDirIterator dirIter(QApplication::applicationDirPath() + "/tutorials", QStringList("*.js"), QDir::Files);
+ while (dirIter.hasNext()) {
+ dirIter.next();
+ QString fileName = dirIter.fileName();
+ QFile file(dirIter.filePath());
+ if (!file.open(QIODevice::ReadOnly)) {
+ qCritical() << "Failed to open " << fileName;
+ continue;
+ }
+ QString firstLine = QString::fromUtf8(file.readLine());
+ if (firstLine.startsWith("//WIN")) {
+ QString windowName = firstLine.mid(6).trimmed();
+ if (!m_OrganizerCore.settings().directInterface().value("CompletedWindowTutorials/" + windowName, false).toBool()) {
+ TutorialManager::instance().activateTutorial(windowName, fileName);
+ }
}
+ }
}
-void MainWindow::showEvent(QShowEvent* event) {
- refreshFilters();
+void MainWindow::showEvent(QShowEvent *event)
+{
+ refreshFilters();
- QMainWindow::showEvent(event);
+ QMainWindow::showEvent(event);
- if (!m_WasVisible) {
- // only the first time the window becomes visible
- m_Tutorial.registerControl();
+ if (!m_WasVisible) {
+ // only the first time the window becomes visible
+ m_Tutorial.registerControl();
- hookUpWindowTutorials();
-
- if (m_OrganizerCore.settings().directInterface().value("first_start", true).toBool()) {
- QString firstStepsTutorial = ToQString(AppConfig::firstStepsTutorial());
- if (TutorialManager::instance().hasTutorial(firstStepsTutorial)) {
- if (QMessageBox::question(this, tr("Show tutorial?"),
- tr("You are starting Mod Organizer for the first time. "
- "Do you want to show a tutorial of its basic features? If you choose "
- "no you can always start the tutorial from the \"Help\"-menu."),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- TutorialManager::instance().activateTutorial("MainWindow", firstStepsTutorial);
- }
- } else {
- qCritical() << firstStepsTutorial << " missing";
- QPoint pos = ui->toolBar->mapToGlobal(QPoint());
- pos.rx() += ui->toolBar->width() / 2;
- pos.ry() += ui->toolBar->height();
- QWhatsThis::showText(
- pos, QObject::tr("Please use \"Help\" from the toolbar to get usage instructions to all elements"));
- }
+ hookUpWindowTutorials();
- m_OrganizerCore.settings().directInterface().setValue("first_start", false);
+ if (m_OrganizerCore.settings().directInterface().value("first_start", true).toBool()) {
+ QString firstStepsTutorial = ToQString(AppConfig::firstStepsTutorial());
+ if (TutorialManager::instance().hasTutorial(firstStepsTutorial)) {
+ if (QMessageBox::question(this, tr("Show tutorial?"),
+ tr("You are starting Mod Organizer for the first time. "
+ "Do you want to show a tutorial of its basic features? If you choose "
+ "no you can always start the tutorial from the \"Help\"-menu."),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ TutorialManager::instance().activateTutorial("MainWindow", firstStepsTutorial);
}
+ } else {
+ qCritical() << firstStepsTutorial << " missing";
+ QPoint pos = ui->toolBar->mapToGlobal(QPoint());
+ pos.rx() += ui->toolBar->width() / 2;
+ pos.ry() += ui->toolBar->height();
+ QWhatsThis::showText(pos,
+ QObject::tr("Please use \"Help\" from the toolbar to get usage instructions to all elements"));
+ }
- // this has no visible impact when called before the ui is visible
- int grouping = m_OrganizerCore.settings().directInterface().value("group_state").toInt();
- ui->groupCombo->setCurrentIndex(grouping);
+ m_OrganizerCore.settings().directInterface().setValue("first_start", false);
+ }
- allowListResize();
+ // this has no visible impact when called before the ui is visible
+ int grouping = m_OrganizerCore.settings().directInterface().value("group_state").toInt();
+ ui->groupCombo->setCurrentIndex(grouping);
- m_OrganizerCore.settings().registerAsNXMHandler(false);
- m_WasVisible = true;
- updateProblemsButton();
- }
+ allowListResize();
+
+ m_OrganizerCore.settings().registerAsNXMHandler(false);
+ m_WasVisible = true;
+ updateProblemsButton();
+ }
}
-void MainWindow::closeEvent(QCloseEvent* event) {
- m_closing = true;
- if (m_OrganizerCore.downloadManager()->downloadsInProgress()) {
- if (QMessageBox::question(this, tr("Downloads in progress"),
- tr("There are still downloads in progress, do you really want to quit?"),
- QMessageBox::Yes | QMessageBox::Cancel) == QMessageBox::Cancel) {
- event->ignore();
- return;
- } else {
- m_OrganizerCore.downloadManager()->pauseAll();
- }
+void MainWindow::closeEvent(QCloseEvent* event)
+{
+ m_closing = true;
+
+ if (m_OrganizerCore.downloadManager()->downloadsInProgress()) {
+ if (QMessageBox::question(this, tr("Downloads in progress"),
+ tr("There are still downloads in progress, do you really want to quit?"),
+ QMessageBox::Yes | QMessageBox::Cancel) == QMessageBox::Cancel) {
+ event->ignore();
+ return;
+ } else {
+ m_OrganizerCore.downloadManager()->pauseAll();
}
+ }
- std::vector<QString> hiddenList;
- hiddenList.push_back(QFileInfo(QCoreApplication::applicationFilePath()).fileName());
- HANDLE injected_process_still_running = m_OrganizerCore.findAndOpenAUSVFSProcess(hiddenList, GetCurrentProcessId());
- if (injected_process_still_running != INVALID_HANDLE_VALUE) {
- m_OrganizerCore.waitForApplication(injected_process_still_running);
- if (!m_closing) { // if operation cancelled
- event->ignore();
- return;
- }
+ std::vector<QString> hiddenList;
+ hiddenList.push_back(QFileInfo(QCoreApplication::applicationFilePath()).fileName());
+ HANDLE injected_process_still_running = m_OrganizerCore.findAndOpenAUSVFSProcess(hiddenList, GetCurrentProcessId());
+ if (injected_process_still_running != INVALID_HANDLE_VALUE)
+ {
+ m_OrganizerCore.waitForApplication(injected_process_still_running);
+ if (!m_closing) { // if operation cancelled
+ event->ignore();
+ return;
}
+ }
- setCursor(Qt::WaitCursor);
+ setCursor(Qt::WaitCursor);
}
-void MainWindow::cleanup() {
- if (ui->logList->model() != nullptr) {
- disconnect(ui->logList->model(), nullptr, nullptr, nullptr);
- ui->logList->setModel(nullptr);
- }
+void MainWindow::cleanup()
+{
+ if (ui->logList->model() != nullptr) {
+ disconnect(ui->logList->model(), nullptr, nullptr, nullptr);
+ ui->logList->setModel(nullptr);
+ }
- QWebEngineProfile::defaultProfile()->clearAllVisitedLinks();
- m_IntegratedBrowser.close();
+ QWebEngineProfile::defaultProfile()->clearAllVisitedLinks();
+ m_IntegratedBrowser.close();
}
-void MainWindow::setBrowserGeometry(const QByteArray& geometry) { m_IntegratedBrowser.restoreGeometry(geometry); }
-void MainWindow::displaySaveGameInfo(QListWidgetItem* newItem) {
- QString const& save = newItem->data(Qt::UserRole).toString();
+void MainWindow::setBrowserGeometry(const QByteArray &geometry)
+{
+ m_IntegratedBrowser.restoreGeometry(geometry);
+}
+
+void MainWindow::displaySaveGameInfo(QListWidgetItem *newItem)
+{
+ QString const &save = newItem->data(Qt::UserRole).toString();
+ if (m_CurrentSaveView == nullptr) {
+ IPluginGame const *game = m_OrganizerCore.managedGame();
+ SaveGameInfo const *info = game->feature<SaveGameInfo>();
+ if (info != nullptr) {
+ m_CurrentSaveView = info->getSaveGameWidget(this);
+ }
if (m_CurrentSaveView == nullptr) {
- IPluginGame const* game = m_OrganizerCore.managedGame();
- SaveGameInfo const* info = game->feature<SaveGameInfo>();
- if (info != nullptr) {
- m_CurrentSaveView = info->getSaveGameWidget(this);
- }
- if (m_CurrentSaveView == nullptr) {
- return;
- }
+ return;
}
- m_CurrentSaveView->setSave(save);
+ }
+ m_CurrentSaveView->setSave(save);
- QRect screenRect = QApplication::desktop()->availableGeometry(m_CurrentSaveView);
+ QRect screenRect = QApplication::desktop()->availableGeometry(m_CurrentSaveView);
- QPoint pos = QCursor::pos();
- if (pos.x() + m_CurrentSaveView->width() > screenRect.right()) {
- pos.rx() -= (m_CurrentSaveView->width() + 2);
- } else {
- pos.rx() += 5;
- }
+ QPoint pos = QCursor::pos();
+ if (pos.x() + m_CurrentSaveView->width() > screenRect.right()) {
+ pos.rx() -= (m_CurrentSaveView->width() + 2);
+ } else {
+ pos.rx() += 5;
+ }
- if (pos.y() + m_CurrentSaveView->height() > screenRect.bottom()) {
- pos.ry() -= (m_CurrentSaveView->height() + 10);
- } else {
- pos.ry() += 20;
- }
- m_CurrentSaveView->move(pos);
+ if (pos.y() + m_CurrentSaveView->height() > screenRect.bottom()) {
+ pos.ry() -= (m_CurrentSaveView->height() + 10);
+ } else {
+ pos.ry() += 20;
+ }
+ m_CurrentSaveView->move(pos);
- m_CurrentSaveView->show();
- m_CurrentSaveView->setProperty("displayItem", qVariantFromValue(static_cast<void*>(newItem)));
+ m_CurrentSaveView->show();
+ m_CurrentSaveView->setProperty("displayItem", qVariantFromValue(static_cast<void *>(newItem)));
- ui->savegameList->activateWindow();
+ ui->savegameList->activateWindow();
}
-void MainWindow::saveSelectionChanged(QListWidgetItem* newItem) {
- if (newItem == nullptr) {
- hideSaveGameInfo();
- } else if (m_CurrentSaveView == nullptr || newItem != m_CurrentSaveView->property("displayItem").value<void*>()) {
- displaySaveGameInfo(newItem);
- }
+
+void MainWindow::saveSelectionChanged(QListWidgetItem *newItem)
+{
+ if (newItem == nullptr) {
+ hideSaveGameInfo();
+ } else if (m_CurrentSaveView == nullptr || newItem != m_CurrentSaveView->property("displayItem").value<void*>()) {
+ displaySaveGameInfo(newItem);
+ }
}
-void MainWindow::hideSaveGameInfo() {
- if (m_CurrentSaveView != nullptr) {
- m_CurrentSaveView->deleteLater();
- m_CurrentSaveView = nullptr;
- }
+
+void MainWindow::hideSaveGameInfo()
+{
+ if (m_CurrentSaveView != nullptr) {
+ m_CurrentSaveView->deleteLater();
+ m_CurrentSaveView = nullptr;
+ }
}
-bool MainWindow::eventFilter(QObject* object, QEvent* event) {
- if ((object == ui->savegameList) &&
- ((event->type() == QEvent::Leave) || (event->type() == QEvent::WindowDeactivate))) {
- hideSaveGameInfo();
- }
- return false;
+bool MainWindow::eventFilter(QObject *object, QEvent *event)
+{
+ if ((object == ui->savegameList) &&
+ ((event->type() == QEvent::Leave) || (event->type() == QEvent::WindowDeactivate))) {
+ hideSaveGameInfo();
+ }
+ return false;
}
-void MainWindow::toolPluginInvoke() {
- QAction* triggeredAction = qobject_cast<QAction*>(sender());
- IPluginTool* plugin = qobject_cast<IPluginTool*>(triggeredAction->data().value<QObject*>());
- if (plugin != nullptr) {
- try {
- plugin->display();
- } catch (const std::exception& e) {
- reportError(tr("Plugin \"%1\" failed: %2").arg(plugin->name()).arg(e.what()));
- } catch (...) {
- reportError(tr("Plugin \"%1\" failed").arg(plugin->name()));
- }
+
+void MainWindow::toolPluginInvoke()
+{
+ QAction *triggeredAction = qobject_cast<QAction*>(sender());
+ IPluginTool *plugin = qobject_cast<IPluginTool*>(triggeredAction->data().value<QObject*>());
+ if (plugin != nullptr) {
+ try {
+ plugin->display();
+ } catch (const std::exception &e) {
+ reportError(tr("Plugin \"%1\" failed: %2").arg(plugin->name()).arg(e.what()));
+ } catch (...) {
+ reportError(tr("Plugin \"%1\" failed").arg(plugin->name()));
}
+ }
}
-void MainWindow::modPagePluginInvoke() {
- QAction* triggeredAction = qobject_cast<QAction*>(sender());
- IPluginModPage* plugin = qobject_cast<IPluginModPage*>(triggeredAction->data().value<QObject*>());
- if (plugin != nullptr) {
- if (plugin->useIntegratedBrowser()) {
- m_IntegratedBrowser.setWindowTitle(plugin->displayName());
- m_IntegratedBrowser.openUrl(plugin->pageURL());
- } else {
- ::ShellExecuteW(nullptr, L"open", ToWString(plugin->pageURL().toString()).c_str(), nullptr, nullptr,
- SW_SHOWNORMAL);
- }
+void MainWindow::modPagePluginInvoke()
+{
+ QAction *triggeredAction = qobject_cast<QAction*>(sender());
+ IPluginModPage *plugin = qobject_cast<IPluginModPage*>(triggeredAction->data().value<QObject*>());
+ if (plugin != nullptr) {
+ if (plugin->useIntegratedBrowser()) {
+ m_IntegratedBrowser.setWindowTitle(plugin->displayName());
+ m_IntegratedBrowser.openUrl(plugin->pageURL());
+ } else {
+ ::ShellExecuteW(nullptr, L"open", ToWString(plugin->pageURL().toString()).c_str(),
+ nullptr, nullptr, SW_SHOWNORMAL);
}
+ }
}
-void MainWindow::registerPluginTool(IPluginTool* tool) {
- QAction* action = new QAction(tool->icon(), tool->displayName(), ui->toolBar);
- action->setToolTip(tool->tooltip());
- tool->setParentWidget(this);
- action->setData(qVariantFromValue((QObject*)tool));
- connect(action, SIGNAL(triggered()), this, SLOT(toolPluginInvoke()), Qt::QueuedConnection);
- QToolButton* toolBtn = qobject_cast<QToolButton*>(ui->toolBar->widgetForAction(ui->actionTool));
- toolBtn->menu()->addAction(action);
+void MainWindow::registerPluginTool(IPluginTool *tool)
+{
+ QAction *action = new QAction(tool->icon(), tool->displayName(), ui->toolBar);
+ action->setToolTip(tool->tooltip());
+ tool->setParentWidget(this);
+ action->setData(qVariantFromValue((QObject*)tool));
+ connect(action, SIGNAL(triggered()), this, SLOT(toolPluginInvoke()), Qt::QueuedConnection);
+ QToolButton *toolBtn = qobject_cast<QToolButton*>(ui->toolBar->widgetForAction(ui->actionTool));
+ toolBtn->menu()->addAction(action);
}
-void MainWindow::registerModPage(IPluginModPage* modPage) {
- // turn the browser action into a drop-down menu if necessary
- if (ui->actionNexus->menu() == nullptr) {
- QAction* nexusAction = ui->actionNexus;
- // TODO: use a different icon for nexus!
- ui->actionNexus = new QAction(nexusAction->icon(), tr("Browse Mod Page"), ui->toolBar);
- ui->toolBar->insertAction(nexusAction, ui->actionNexus);
- ui->toolBar->removeAction(nexusAction);
- actionToToolButton(ui->actionNexus);
+void MainWindow::registerModPage(IPluginModPage *modPage)
+{
+ // turn the browser action into a drop-down menu if necessary
+ if (ui->actionNexus->menu() == nullptr) {
+ QAction *nexusAction = ui->actionNexus;
+ // TODO: use a different icon for nexus!
+ ui->actionNexus = new QAction(nexusAction->icon(), tr("Browse Mod Page"), ui->toolBar);
+ ui->toolBar->insertAction(nexusAction, ui->actionNexus);
+ ui->toolBar->removeAction(nexusAction);
+ actionToToolButton(ui->actionNexus);
- QToolButton* browserBtn = qobject_cast<QToolButton*>(ui->toolBar->widgetForAction(ui->actionNexus));
- browserBtn->menu()->addAction(nexusAction);
- }
+ QToolButton *browserBtn = qobject_cast<QToolButton*>(ui->toolBar->widgetForAction(ui->actionNexus));
+ browserBtn->menu()->addAction(nexusAction);
+ }
- QAction* action = new QAction(modPage->icon(), modPage->displayName(), ui->toolBar);
- modPage->setParentWidget(this);
- action->setData(qVariantFromValue(reinterpret_cast<QObject*>(modPage)));
+ QAction *action = new QAction(modPage->icon(), modPage->displayName(), ui->toolBar);
+ modPage->setParentWidget(this);
+ action->setData(qVariantFromValue(reinterpret_cast<QObject*>(modPage)));
- connect(action, SIGNAL(triggered()), this, SLOT(modPagePluginInvoke()), Qt::QueuedConnection);
- QToolButton* toolBtn = qobject_cast<QToolButton*>(ui->toolBar->widgetForAction(ui->actionNexus));
- toolBtn->menu()->addAction(action);
+ connect(action, SIGNAL(triggered()), this, SLOT(modPagePluginInvoke()), Qt::QueuedConnection);
+ QToolButton *toolBtn = qobject_cast<QToolButton*>(ui->toolBar->widgetForAction(ui->actionNexus));
+ toolBtn->menu()->addAction(action);
}
-void MainWindow::startExeAction() {
- QAction* action = qobject_cast<QAction*>(sender());
- if (action != nullptr) {
- const Executable& selectedExecutable(m_OrganizerCore.executablesList()->find(action->text()));
- QString customOverwrite =
- m_OrganizerCore.currentProfile()->setting("custom_overwrites", selectedExecutable.m_Title).toString();
- m_OrganizerCore.spawnBinary(selectedExecutable.m_BinaryInfo, selectedExecutable.m_Arguments,
- selectedExecutable.m_WorkingDirectory.length() != 0
- ? selectedExecutable.m_WorkingDirectory
- : selectedExecutable.m_BinaryInfo.absolutePath(),
- selectedExecutable.m_SteamAppID, customOverwrite);
- } else {
- qCritical("not an action?");
- }
+
+void MainWindow::startExeAction()
+{
+ QAction *action = qobject_cast<QAction*>(sender());
+ if (action != nullptr) {
+ const Executable &selectedExecutable(
+ m_OrganizerCore.executablesList()->find(action->text()));
+ QString customOverwrite= m_OrganizerCore.currentProfile()->setting("custom_overwrites", selectedExecutable.m_Title).toString();
+ m_OrganizerCore.spawnBinary(
+ selectedExecutable.m_BinaryInfo, selectedExecutable.m_Arguments,
+ selectedExecutable.m_WorkingDirectory.length() != 0
+ ? selectedExecutable.m_WorkingDirectory
+ : selectedExecutable.m_BinaryInfo.absolutePath(),
+ selectedExecutable.m_SteamAppID, customOverwrite);
+ } else {
+ qCritical("not an action?");
+ }
}
-void MainWindow::setExecutableIndex(int index) {
- QComboBox* executableBox = findChild<QComboBox*>("executablesListBox");
- if ((index != 0) && (executableBox->count() > index)) {
- executableBox->setCurrentIndex(index);
- } else {
- executableBox->setCurrentIndex(1);
- }
+void MainWindow::setExecutableIndex(int index)
+{
+ QComboBox *executableBox = findChild<QComboBox*>("executablesListBox");
+
+ if ((index != 0) && (executableBox->count() > index)) {
+ executableBox->setCurrentIndex(index);
+ } else {
+ executableBox->setCurrentIndex(1);
+ }
}
-void MainWindow::activateSelectedProfile() {
- m_OrganizerCore.setCurrentProfile(ui->profileBox->currentText());
+void MainWindow::activateSelectedProfile()
+{
+ m_OrganizerCore.setCurrentProfile(ui->profileBox->currentText());
- m_ModListSortProxy->setProfile(m_OrganizerCore.currentProfile());
+ m_ModListSortProxy->setProfile(m_OrganizerCore.currentProfile());
- refreshSaveList();
- m_OrganizerCore.refreshModList();
+ refreshSaveList();
+ m_OrganizerCore.refreshModList();
}
-void MainWindow::on_profileBox_currentIndexChanged(int index) {
- if (ui->profileBox->isEnabled()) {
- int previousIndex = m_OldProfileIndex;
- m_OldProfileIndex = index;
+void MainWindow::on_profileBox_currentIndexChanged(int index)
+{
+ if (ui->profileBox->isEnabled()) {
+ int previousIndex = m_OldProfileIndex;
+ m_OldProfileIndex = index;
- if ((previousIndex != -1) && (m_OrganizerCore.currentProfile() != nullptr) &&
- m_OrganizerCore.currentProfile()->exists()) {
- m_OrganizerCore.saveCurrentLists();
- }
+ if ((previousIndex != -1) &&
+ (m_OrganizerCore.currentProfile() != nullptr) &&
+ m_OrganizerCore.currentProfile()->exists()) {
+ m_OrganizerCore.saveCurrentLists();
+ }
- // ensure the new index is valid
- if (index < 0 || index >= ui->profileBox->count()) {
- qDebug("invalid profile index, using last profile");
- ui->profileBox->setCurrentIndex(ui->profileBox->count() - 1);
- }
+ // ensure the new index is valid
+ if (index < 0 || index >= ui->profileBox->count()) {
+ qDebug("invalid profile index, using last profile");
+ ui->profileBox->setCurrentIndex(ui->profileBox->count() - 1);
+ }
- if (ui->profileBox->currentIndex() == 0) {
- ui->profileBox->setCurrentIndex(previousIndex);
- ProfilesDialog(ui->profileBox->currentText(), m_OrganizerCore.managedGame(), this).exec();
- while (!refreshProfiles()) {
- ProfilesDialog(ui->profileBox->currentText(), m_OrganizerCore.managedGame(), this).exec();
- }
- } else {
- activateSelectedProfile();
- }
+ if (ui->profileBox->currentIndex() == 0) {
+ ui->profileBox->setCurrentIndex(previousIndex);
+ ProfilesDialog(ui->profileBox->currentText(), m_OrganizerCore.managedGame(), this).exec();
+ while (!refreshProfiles()) {
+ ProfilesDialog(ui->profileBox->currentText(), m_OrganizerCore.managedGame(), this).exec();
+ }
+ } else {
+ activateSelectedProfile();
}
+ }
}
-void MainWindow::updateTo(QTreeWidgetItem* subTree, const std::wstring& directorySoFar,
- const DirectoryEntry& directoryEntry, bool conflictsOnly) {
- {
- for (const FileEntry::Ptr current : directoryEntry.getFiles()) {
- if (conflictsOnly && (current->getAlternatives().size() == 0)) {
- continue;
- }
+void MainWindow::updateTo(QTreeWidgetItem *subTree, const std::wstring &directorySoFar, const DirectoryEntry &directoryEntry, bool conflictsOnly)
+{
+ {
+ for (const FileEntry::Ptr current : directoryEntry.getFiles()) {
+ if (conflictsOnly && (current->getAlternatives().size() == 0)) {
+ continue;
+ }
- QString fileName = ToQString(current->getName());
- QStringList columns(fileName);
- bool isArchive = false;
- int originID = current->getOrigin(isArchive);
- FilesOrigin origin = m_OrganizerCore.directoryStructure()->getOriginByID(originID);
- QString source("data");
- unsigned int modIndex = ModInfo::getIndex(ToQString(origin.getName()));
- if (modIndex != UINT_MAX) {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex);
- source = modInfo->name();
- }
+ QString fileName = ToQString(current->getName());
+ QStringList columns(fileName);
+ bool isArchive = false;
+ int originID = current->getOrigin(isArchive);
+ FilesOrigin origin = m_OrganizerCore.directoryStructure()->getOriginByID(originID);
+ QString source("data");
+ unsigned int modIndex = ModInfo::getIndex(ToQString(origin.getName()));
+ if (modIndex != UINT_MAX) {
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex);
+ source = modInfo->name();
+ }
- std::wstring archive = current->getArchive();
- if (archive.length() != 0) {
- source.append(" (").append(ToQString(archive)).append(")");
- }
- columns.append(source);
- QTreeWidgetItem* fileChild = new QTreeWidgetItem(columns);
- if (isArchive) {
- QFont font = fileChild->font(0);
- font.setItalic(true);
- fileChild->setFont(0, font);
- fileChild->setFont(1, font);
- } else if (fileName.endsWith(ModInfo::s_HiddenExt)) {
- QFont font = fileChild->font(0);
- font.setStrikeOut(true);
- fileChild->setFont(0, font);
- fileChild->setFont(1, font);
- }
- fileChild->setData(0, Qt::UserRole, ToQString(current->getFullPath()));
- fileChild->setData(0, Qt::UserRole + 1, isArchive);
- fileChild->setData(1, Qt::UserRole, source);
- fileChild->setData(1, Qt::UserRole + 1, originID);
+ std::wstring archive = current->getArchive();
+ if (archive.length() != 0) {
+ source.append(" (").append(ToQString(archive)).append(")");
+ }
+ columns.append(source);
+ QTreeWidgetItem *fileChild = new QTreeWidgetItem(columns);
+ if (isArchive) {
+ QFont font = fileChild->font(0);
+ font.setItalic(true);
+ fileChild->setFont(0, font);
+ fileChild->setFont(1, font);
+ } else if (fileName.endsWith(ModInfo::s_HiddenExt)) {
+ QFont font = fileChild->font(0);
+ font.setStrikeOut(true);
+ fileChild->setFont(0, font);
+ fileChild->setFont(1, font);
+ }
+ fileChild->setData(0, Qt::UserRole, ToQString(current->getFullPath()));
+ fileChild->setData(0, Qt::UserRole + 1, isArchive);
+ fileChild->setData(1, Qt::UserRole, source);
+ fileChild->setData(1, Qt::UserRole + 1, originID);
- std::vector<std::pair<int, std::wstring>> alternatives = current->getAlternatives();
+ std::vector<std::pair<int, std::wstring>> alternatives = current->getAlternatives();
- if (!alternatives.empty()) {
- std::wostringstream altString;
- altString << ToWString(tr("Also in: <br>"));
- for (std::vector<std::pair<int, std::wstring>>::iterator altIter = alternatives.begin();
- altIter != alternatives.end(); ++altIter) {
- if (altIter != alternatives.begin()) {
- altString << " , ";
- }
- altString << "<span style=\"white-space: nowrap;\"><i>"
- << m_OrganizerCore.directoryStructure()->getOriginByID(altIter->first).getName()
- << "</font></span>";
- }
- fileChild->setToolTip(1, QString("%1").arg(ToQString(altString.str())));
- fileChild->setForeground(1, QBrush(Qt::red));
- } else {
- fileChild->setToolTip(1, tr("No conflict"));
- }
- subTree->addChild(fileChild);
+ if (!alternatives.empty()) {
+ std::wostringstream altString;
+ altString << ToWString(tr("Also in: <br>"));
+ for (std::vector<std::pair<int, std::wstring>>::iterator altIter = alternatives.begin();
+ altIter != alternatives.end(); ++altIter) {
+ if (altIter != alternatives.begin()) {
+ altString << " , ";
+ }
+ altString << "<span style=\"white-space: nowrap;\"><i>" << m_OrganizerCore.directoryStructure()->getOriginByID(altIter->first).getName() << "</font></span>";
}
+ fileChild->setToolTip(1, QString("%1").arg(ToQString(altString.str())));
+ fileChild->setForeground(1, QBrush(Qt::red));
+ } else {
+ fileChild->setToolTip(1, tr("No conflict"));
+ }
+ subTree->addChild(fileChild);
}
+ }
- std::wostringstream temp;
- temp << directorySoFar << "\\" << directoryEntry.getName();
- {
- std::vector<DirectoryEntry*>::const_iterator current, end;
- directoryEntry.getSubDirectories(current, end);
- for (; current != end; ++current) {
- QString pathName = ToQString((*current)->getName());
- QStringList columns(pathName);
- columns.append("");
- if (!(*current)->isEmpty()) {
- QTreeWidgetItem* directoryChild = new QTreeWidgetItem(columns);
- if (conflictsOnly) {
- updateTo(directoryChild, temp.str(), **current, conflictsOnly);
- if (directoryChild->childCount() != 0) {
- subTree->addChild(directoryChild);
- } else {
- delete directoryChild;
- }
- } else {
- QTreeWidgetItem* onDemandLoad = new QTreeWidgetItem(QStringList());
- onDemandLoad->setData(0, Qt::UserRole + 0, "__loaded_on_demand__");
- onDemandLoad->setData(0, Qt::UserRole + 1, ToQString(temp.str()));
- onDemandLoad->setData(0, Qt::UserRole + 2, conflictsOnly);
- directoryChild->addChild(onDemandLoad);
- subTree->addChild(directoryChild);
- }
- }
+ std::wostringstream temp;
+ temp << directorySoFar << "\\" << directoryEntry.getName();
+ {
+ std::vector<DirectoryEntry*>::const_iterator current, end;
+ directoryEntry.getSubDirectories(current, end);
+ for (; current != end; ++current) {
+ QString pathName = ToQString((*current)->getName());
+ QStringList columns(pathName);
+ columns.append("");
+ if (!(*current)->isEmpty()) {
+ QTreeWidgetItem *directoryChild = new QTreeWidgetItem(columns);
+ if (conflictsOnly) {
+ updateTo(directoryChild, temp.str(), **current, conflictsOnly);
+ if (directoryChild->childCount() != 0) {
+ subTree->addChild(directoryChild);
+ } else {
+ delete directoryChild;
+ }
+ } else {
+ QTreeWidgetItem *onDemandLoad = new QTreeWidgetItem(QStringList());
+ onDemandLoad->setData(0, Qt::UserRole + 0, "__loaded_on_demand__");
+ onDemandLoad->setData(0, Qt::UserRole + 1, ToQString(temp.str()));
+ onDemandLoad->setData(0, Qt::UserRole + 2, conflictsOnly);
+ directoryChild->addChild(onDemandLoad);
+ subTree->addChild(directoryChild);
}
+ }
}
+ }
- subTree->sortChildren(0, Qt::AscendingOrder);
+ subTree->sortChildren(0, Qt::AscendingOrder);
}
-void MainWindow::delayedRemove() {
- for (QTreeWidgetItem* item : m_RemoveWidget) {
- item->removeChild(item->child(0));
- }
- m_RemoveWidget.clear();
+void MainWindow::delayedRemove()
+{
+ for (QTreeWidgetItem *item : m_RemoveWidget) {
+ item->removeChild(item->child(0));
+ }
+ m_RemoveWidget.clear();
}
-void MainWindow::expandDataTreeItem(QTreeWidgetItem* item) {
- if ((item->childCount() == 1) && (item->child(0)->data(0, Qt::UserRole).toString() == "__loaded_on_demand__")) {
- // read the data we need from the sub-item, then dispose of it
- QTreeWidgetItem* onDemandDataItem = item->child(0);
- std::wstring path = ToWString(onDemandDataItem->data(0, Qt::UserRole + 1).toString());
- bool conflictsOnly = onDemandDataItem->data(0, Qt::UserRole + 2).toBool();
+void MainWindow::expandDataTreeItem(QTreeWidgetItem *item)
+{
+ if ((item->childCount() == 1) && (item->child(0)->data(0, Qt::UserRole).toString() == "__loaded_on_demand__")) {
+ // read the data we need from the sub-item, then dispose of it
+ QTreeWidgetItem *onDemandDataItem = item->child(0);
+ std::wstring path = ToWString(onDemandDataItem->data(0, Qt::UserRole + 1).toString());
+ bool conflictsOnly = onDemandDataItem->data(0, Qt::UserRole + 2).toBool();
- std::wstring virtualPath = (path + L"\\").substr(6) + ToWString(item->text(0));
- DirectoryEntry* dir = m_OrganizerCore.directoryStructure()->findSubDirectoryRecursive(virtualPath);
- if (dir != nullptr) {
- updateTo(item, path, *dir, conflictsOnly);
- } else {
- qWarning("failed to update view of %ls", path.c_str());
- }
- m_RemoveWidget.push_back(item);
- QTimer::singleShot(5, this, SLOT(delayedRemove()));
+ std::wstring virtualPath = (path + L"\\").substr(6) + ToWString(item->text(0));
+ DirectoryEntry *dir = m_OrganizerCore.directoryStructure()->findSubDirectoryRecursive(virtualPath);
+ if (dir != nullptr) {
+ updateTo(item, path, *dir, conflictsOnly);
+ } else {
+ qWarning("failed to update view of %ls", path.c_str());
}
+ m_RemoveWidget.push_back(item);
+ QTimer::singleShot(5, this, SLOT(delayedRemove()));
+ }
}
-bool MainWindow::refreshProfiles(bool selectProfile) {
- QComboBox* profileBox = findChild<QComboBox*>("profileBox");
- QString currentProfileName = profileBox->currentText();
+bool MainWindow::refreshProfiles(bool selectProfile)
+{
+ QComboBox* profileBox = findChild<QComboBox*>("profileBox");
- profileBox->blockSignals(true);
- profileBox->clear();
- profileBox->addItem(QObject::tr("<Manage...>"));
+ QString currentProfileName = profileBox->currentText();
- QDir profilesDir(Settings::instance().getProfileDirectory());
- profilesDir.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot);
+ profileBox->blockSignals(true);
+ profileBox->clear();
+ profileBox->addItem(QObject::tr("<Manage...>"));
- QDirIterator profileIter(profilesDir);
+ QDir profilesDir(Settings::instance().getProfileDirectory());
+ profilesDir.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot);
- while (profileIter.hasNext()) {
- profileIter.next();
- try {
- profileBox->addItem(profileIter.fileName());
- } catch (const std::runtime_error& error) {
- reportError(QObject::tr("failed to parse profile %1: %2").arg(profileIter.fileName()).arg(error.what()));
- }
+ QDirIterator profileIter(profilesDir);
+
+ while (profileIter.hasNext()) {
+ profileIter.next();
+ try {
+ profileBox->addItem(profileIter.fileName());
+ } catch (const std::runtime_error& error) {
+ reportError(QObject::tr("failed to parse profile %1: %2").arg(profileIter.fileName()).arg(error.what()));
}
+ }
- // now select one of the profiles, preferably the one that was selected before
- profileBox->blockSignals(false);
+ // now select one of the profiles, preferably the one that was selected before
+ profileBox->blockSignals(false);
- if (selectProfile) {
- if (profileBox->count() > 1) {
- profileBox->setCurrentText(currentProfileName);
- if (profileBox->currentIndex() == 0) {
- profileBox->setCurrentIndex(1);
- }
- }
+ if (selectProfile) {
+ if (profileBox->count() > 1) {
+ profileBox->setCurrentText(currentProfileName);
+ if (profileBox->currentIndex() == 0) {
+ profileBox->setCurrentIndex(1);
+ }
}
- return profileBox->count() > 1;
+ }
+ return profileBox->count() > 1;
}
-void MainWindow::refreshExecutablesList() {
- QComboBox* executablesList = findChild<QComboBox*>("executablesListBox");
- executablesList->setEnabled(false);
- executablesList->clear();
- executablesList->addItem(tr("<Edit...>"));
- QAbstractItemModel* model = executablesList->model();
+void MainWindow::refreshExecutablesList()
+{
+ QComboBox* executablesList = findChild<QComboBox*>("executablesListBox");
+ executablesList->setEnabled(false);
+ executablesList->clear();
+ executablesList->addItem(tr("<Edit...>"));
- std::vector<Executable>::const_iterator current, end;
- m_OrganizerCore.executablesList()->getExecutables(current, end);
- for (int i = 0; current != end; ++current, ++i) {
- QIcon icon = iconForExecutable(current->m_BinaryInfo.filePath());
- executablesList->addItem(icon, current->m_Title);
- model->setData(model->index(i, 0), QSize(0, executablesList->iconSize().height() + 4), Qt::SizeHintRole);
- }
+ QAbstractItemModel *model = executablesList->model();
+
+ std::vector<Executable>::const_iterator current, end;
+ m_OrganizerCore.executablesList()->getExecutables(current, end);
+ for(int i = 0; current != end; ++current, ++i) {
+ QIcon icon = iconForExecutable(current->m_BinaryInfo.filePath());
+ executablesList->addItem(icon, current->m_Title);
+ model->setData(model->index(i, 0), QSize(0, executablesList->iconSize().height() + 4), Qt::SizeHintRole);
+ }
- setExecutableIndex(1);
- executablesList->setEnabled(true);
+ setExecutableIndex(1);
+ executablesList->setEnabled(true);
}
-void MainWindow::refreshDataTree() {
- QCheckBox* conflictsBox = findChild<QCheckBox*>("conflictsCheckBox");
- QTreeWidget* tree = findChild<QTreeWidget*>("dataTree");
- tree->clear();
- QStringList columns("data");
- columns.append("");
- QTreeWidgetItem* subTree = new QTreeWidgetItem(columns);
- updateTo(subTree, L"", *m_OrganizerCore.directoryStructure(), conflictsBox->isChecked());
- tree->insertTopLevelItem(0, subTree);
- subTree->setExpanded(true);
+
+void MainWindow::refreshDataTree()
+{
+ QCheckBox *conflictsBox = findChild<QCheckBox*>("conflictsCheckBox");
+ QTreeWidget *tree = findChild<QTreeWidget*>("dataTree");
+ tree->clear();
+ QStringList columns("data");
+ columns.append("");
+ QTreeWidgetItem *subTree = new QTreeWidgetItem(columns);
+ updateTo(subTree, L"", *m_OrganizerCore.directoryStructure(), conflictsBox->isChecked());
+ tree->insertTopLevelItem(0, subTree);
+ subTree->setExpanded(true);
}
-void MainWindow::refreshDataTreeKeepExpandedNodes() {
- QCheckBox* conflictsBox = findChild<QCheckBox*>("conflictsCheckBox");
- QTreeWidget* tree = findChild<QTreeWidget*>("dataTree");
+void MainWindow::refreshDataTreeKeepExpandedNodes()
+{
+ QCheckBox *conflictsBox = findChild<QCheckBox*>("conflictsCheckBox");
+ QTreeWidget *tree = findChild<QTreeWidget*>("dataTree");
- QStringList expandedNodes;
- QTreeWidgetItemIterator it1(tree, QTreeWidgetItemIterator::NotHidden | QTreeWidgetItemIterator::HasChildren);
- while (*it1) {
- QTreeWidgetItem* current = (*it1);
- if (current->isExpanded() && !(current->text(0) == "data")) {
- expandedNodes.append(current->text(0) + "/" + current->parent()->text(0));
- }
- ++it1;
- }
+ QStringList expandedNodes;
+ QTreeWidgetItemIterator it1(tree, QTreeWidgetItemIterator::NotHidden | QTreeWidgetItemIterator::HasChildren);
+ while (*it1) {
+ QTreeWidgetItem *current = (*it1);
+ if (current->isExpanded() && !(current->text(0)=="data")) {
+ expandedNodes.append(current->text(0)+"/"+current->parent()->text(0));
+ }
+ ++it1;
+ }
- tree->clear();
- QStringList columns("data");
- columns.append("");
- QTreeWidgetItem* subTree = new QTreeWidgetItem(columns);
- updateTo(subTree, L"", *m_OrganizerCore.directoryStructure(), conflictsBox->isChecked());
- tree->insertTopLevelItem(0, subTree);
- subTree->setExpanded(true);
- QTreeWidgetItemIterator it2(tree, QTreeWidgetItemIterator::HasChildren);
- while (*it2) {
- QTreeWidgetItem* current = (*it2);
- if (!(current->text(0) == "data") &&
- expandedNodes.contains(current->text(0) + "/" + current->parent()->text(0))) {
- current->setExpanded(true);
- }
- ++it2;
- }
+ tree->clear();
+ QStringList columns("data");
+ columns.append("");
+ QTreeWidgetItem *subTree = new QTreeWidgetItem(columns);
+ updateTo(subTree, L"", *m_OrganizerCore.directoryStructure(), conflictsBox->isChecked());
+ tree->insertTopLevelItem(0, subTree);
+ subTree->setExpanded(true);
+ QTreeWidgetItemIterator it2(tree, QTreeWidgetItemIterator::HasChildren);
+ while (*it2) {
+ QTreeWidgetItem *current = (*it2);
+ if (!(current->text(0)=="data") && expandedNodes.contains(current->text(0)+"/"+current->parent()->text(0))) {
+ current->setExpanded(true);
+ }
+ ++it2;
+ }
}
-void MainWindow::refreshSavesIfOpen() {
- if (ui->tabWidget->currentIndex() == 3) {
- refreshSaveList();
- }
+
+void MainWindow::refreshSavesIfOpen()
+{
+ if (ui->tabWidget->currentIndex() == 3) {
+ refreshSaveList();
+ }
}
-QDir MainWindow::currentSavesDir() const {
- QDir savesDir;
- if (m_OrganizerCore.currentProfile()->localSavesEnabled()) {
- savesDir.setPath(m_OrganizerCore.currentProfile()->savePath());
- } else {
- wchar_t path[MAX_PATH];
- ::GetPrivateProfileStringW(L"General", L"SLocalSavePath", L"Saves", path, MAX_PATH,
- ToWString(m_OrganizerCore.currentProfile()->absolutePath() + "/" +
- m_OrganizerCore.managedGame()->iniFiles()[0])
- .c_str());
- savesDir.setPath(
- m_OrganizerCore.managedGame()->documentsDirectory().absoluteFilePath(QString::fromWCharArray(path)));
- }
+QDir MainWindow::currentSavesDir() const
+{
+ QDir savesDir;
+ if (m_OrganizerCore.currentProfile()->localSavesEnabled()) {
+ savesDir.setPath(m_OrganizerCore.currentProfile()->savePath());
+ } else {
+ wchar_t path[MAX_PATH];
+ ::GetPrivateProfileStringW(
+ L"General", L"SLocalSavePath", L"Saves",
+ path, MAX_PATH,
+ ToWString(m_OrganizerCore.currentProfile()->absolutePath() + "/" +
+ m_OrganizerCore.managedGame()->iniFiles()[0]).c_str());
+ savesDir.setPath(m_OrganizerCore.managedGame()->documentsDirectory().absoluteFilePath(QString::fromWCharArray(path)));
+ }
- return savesDir;
+ return savesDir;
}
-void MainWindow::startMonitorSaves() {
- stopMonitorSaves();
+void MainWindow::startMonitorSaves()
+{
+ stopMonitorSaves();
- QDir savesDir = currentSavesDir();
+ QDir savesDir = currentSavesDir();
- m_SavesWatcher.addPath(savesDir.absolutePath());
+ m_SavesWatcher.addPath(savesDir.absolutePath());
}
-void MainWindow::stopMonitorSaves() {
- if (m_SavesWatcher.directories().length() > 0) {
- m_SavesWatcher.removePaths(m_SavesWatcher.directories());
- }
+void MainWindow::stopMonitorSaves()
+{
+ if (m_SavesWatcher.directories().length() > 0) {
+ m_SavesWatcher.removePaths(m_SavesWatcher.directories());
+ }
}
-void MainWindow::refreshSaveList() {
- ui->savegameList->clear();
+void MainWindow::refreshSaveList()
+{
+ ui->savegameList->clear();
- startMonitorSaves(); // re-starts monitoring
+ startMonitorSaves(); // re-starts monitoring
- QStringList filters;
- filters << QString("*.") + m_OrganizerCore.managedGame()->savegameExtension();
+ QStringList filters;
+ filters << QString("*.") + m_OrganizerCore.managedGame()->savegameExtension();
- QDir savesDir = currentSavesDir();
- savesDir.setNameFilters(filters);
- qDebug("reading save games from %s", qPrintable(savesDir.absolutePath()));
+ QDir savesDir = currentSavesDir();
+ savesDir.setNameFilters(filters);
+ qDebug("reading save games from %s", qPrintable(savesDir.absolutePath()));
- QFileInfoList files = savesDir.entryInfoList(QDir::Files, QDir::Time);
- for (const QFileInfo& file : files) {
- QListWidgetItem* item = new QListWidgetItem(file.fileName());
- item->setData(Qt::UserRole, file.absoluteFilePath());
- ui->savegameList->addItem(item);
- }
+ QFileInfoList files = savesDir.entryInfoList(QDir::Files, QDir::Time);
+ for (const QFileInfo &file : files) {
+ QListWidgetItem *item = new QListWidgetItem(file.fileName());
+ item->setData(Qt::UserRole, file.absoluteFilePath());
+ ui->savegameList->addItem(item);
+ }
}
-static bool BySortValue(const std::pair<UINT32, QTreeWidgetItem*>& LHS,
- const std::pair<UINT32, QTreeWidgetItem*>& RHS) {
- return LHS.first < RHS.first;
+
+static bool BySortValue(const std::pair<UINT32, QTreeWidgetItem*> &LHS, const std::pair<UINT32, QTreeWidgetItem*> &RHS)
+{
+ return LHS.first < RHS.first;
}
template <typename InputIterator>
-static QStringList toStringList(InputIterator current, InputIterator end) {
- QStringList result;
- for (; current != end; ++current) {
- result.append(*current);
- }
- return result;
+static QStringList toStringList(InputIterator current, InputIterator end)
+{
+ QStringList result;
+ for (; current != end; ++current) {
+ result.append(*current);
+ }
+ return result;
}
-void MainWindow::updateBSAList(const QStringList& defaultArchives, const QStringList& activeArchives) {
- m_DefaultArchives = defaultArchives;
- ui->bsaList->clear();
- ui->bsaList->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
- std::vector<std::pair<UINT32, QTreeWidgetItem*>> items;
+void MainWindow::updateBSAList(const QStringList &defaultArchives, const QStringList &activeArchives)
+{
+ m_DefaultArchives = defaultArchives;
+ ui->bsaList->clear();
+ ui->bsaList->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
+ std::vector<std::pair<UINT32, QTreeWidgetItem*>> items;
- BSAInvalidation* invalidation = m_OrganizerCore.managedGame()->feature<BSAInvalidation>();
- std::vector<FileEntry::Ptr> files = m_OrganizerCore.directoryStructure()->getFiles();
+ BSAInvalidation * invalidation = m_OrganizerCore.managedGame()->feature<BSAInvalidation>();
+ std::vector<FileEntry::Ptr> files = m_OrganizerCore.directoryStructure()->getFiles();
- QStringList plugins = m_OrganizerCore.findFiles("", [](const QString& fileName) -> bool {
- return fileName.endsWith(".esp", Qt::CaseInsensitive) || fileName.endsWith(".esm", Qt::CaseInsensitive) ||
- fileName.endsWith(".esl", Qt::CaseInsensitive);
- });
+ QStringList plugins = m_OrganizerCore.findFiles("", [](const QString &fileName) -> bool {
+ return fileName.endsWith(".esp", Qt::CaseInsensitive)
+ || fileName.endsWith(".esm", Qt::CaseInsensitive)
+ || fileName.endsWith(".esl", Qt::CaseInsensitive);
+ });
- auto hasAssociatedPlugin = [&](const QString& bsaName) -> bool {
- for (const QString& pluginName : plugins) {
- QFileInfo pluginInfo(pluginName);
- if (bsaName.startsWith(QFileInfo(pluginName).baseName(), Qt::CaseInsensitive) &&
- (m_OrganizerCore.pluginList()->state(pluginInfo.fileName()) == IPluginList::STATE_ACTIVE)) {
- return true;
- }
- }
- return false;
- };
+ auto hasAssociatedPlugin = [&](const QString &bsaName) -> bool {
+ for (const QString &pluginName : plugins) {
+ QFileInfo pluginInfo(pluginName);
+ if (bsaName.startsWith(QFileInfo(pluginName).baseName(), Qt::CaseInsensitive)
+ && (m_OrganizerCore.pluginList()->state(pluginInfo.fileName()) == IPluginList::STATE_ACTIVE)) {
+ return true;
+ }
+ }
+ return false;
+ };
- for (FileEntry::Ptr current : files) {
- QFileInfo fileInfo(ToQString(current->getName().c_str()));
+ for (FileEntry::Ptr current : files) {
+ QFileInfo fileInfo(ToQString(current->getName().c_str()));
- if (fileInfo.suffix().toLower() == "bsa" || fileInfo.suffix().toLower() == "ba2") {
- int index = activeArchives.indexOf(fileInfo.fileName());
- if (index == -1) {
- index = 0xFFFF;
- } else {
- index += 2;
- }
+ if (fileInfo.suffix().toLower() == "bsa" || fileInfo.suffix().toLower() == "ba2") {
+ int index = activeArchives.indexOf(fileInfo.fileName());
+ if (index == -1) {
+ index = 0xFFFF;
+ }
+ else {
+ index += 2;
+ }
- if ((invalidation != nullptr) && invalidation->isInvalidationBSA(fileInfo.fileName())) {
- index = 1;
- }
+ if ((invalidation != nullptr) && invalidation->isInvalidationBSA(fileInfo.fileName())) {
+ index = 1;
+ }
- int originId = current->getOrigin();
- FilesOrigin& origin = m_OrganizerCore.directoryStructure()->getOriginByID(originId);
+ int originId = current->getOrigin();
+ FilesOrigin & origin = m_OrganizerCore.directoryStructure()->getOriginByID(originId);
- QTreeWidgetItem* newItem =
- new QTreeWidgetItem(QStringList() << fileInfo.fileName() << ToQString(origin.getName()));
- newItem->setData(0, Qt::UserRole, index);
- newItem->setData(1, Qt::UserRole, originId);
- newItem->setFlags(newItem->flags() & ~(Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable));
- newItem->setCheckState(0, (index != -1) ? Qt::Checked : Qt::Unchecked);
- newItem->setData(0, Qt::UserRole, false);
- if (m_OrganizerCore.settings().forceEnableCoreFiles() && defaultArchives.contains(fileInfo.fileName())) {
- newItem->setCheckState(0, Qt::Checked);
- newItem->setDisabled(true);
- newItem->setData(0, Qt::UserRole, true);
- } else if (fileInfo.fileName().compare("update.bsa", Qt::CaseInsensitive) == 0) {
- newItem->setCheckState(0, Qt::Checked);
- newItem->setDisabled(true);
- } else if (hasAssociatedPlugin(fileInfo.fileName())) {
- newItem->setCheckState(0, Qt::Checked);
- newItem->setDisabled(true);
- } else {
- newItem->setCheckState(0, Qt::Unchecked);
- newItem->setDisabled(true);
- }
- if (index < 0)
- index = 0;
+ QTreeWidgetItem * newItem = new QTreeWidgetItem(QStringList()
+ << fileInfo.fileName()
+ << ToQString(origin.getName()));
+ newItem->setData(0, Qt::UserRole, index);
+ newItem->setData(1, Qt::UserRole, originId);
+ newItem->setFlags(newItem->flags() & ~(Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable));
+ newItem->setCheckState(0, (index != -1) ? Qt::Checked : Qt::Unchecked);
+ newItem->setData(0, Qt::UserRole, false);
+ if (m_OrganizerCore.settings().forceEnableCoreFiles()
+ && defaultArchives.contains(fileInfo.fileName())) {
+ newItem->setCheckState(0, Qt::Checked);
+ newItem->setDisabled(true);
+ newItem->setData(0, Qt::UserRole, true);
+ } else if (fileInfo.fileName().compare("update.bsa", Qt::CaseInsensitive) == 0) {
+ newItem->setCheckState(0, Qt::Checked);
+ newItem->setDisabled(true);
+ } else if (hasAssociatedPlugin(fileInfo.fileName())) {
+ newItem->setCheckState(0, Qt::Checked);
+ newItem->setDisabled(true);
+ } else {
+ newItem->setCheckState(0, Qt::Unchecked);
+ newItem->setDisabled(true);
+ }
+ if (index < 0) index = 0;
- UINT32 sortValue = ((origin.getPriority() & 0xFFFF) << 16) | (index & 0xFFFF);
- items.push_back(std::make_pair(sortValue, newItem));
- }
+ UINT32 sortValue = ((origin.getPriority() & 0xFFFF) << 16) | (index & 0xFFFF);
+ items.push_back(std::make_pair(sortValue, newItem));
}
- std::sort(items.begin(), items.end(), BySortValue);
+ }
+ std::sort(items.begin(), items.end(), BySortValue);
- for (auto iter = items.begin(); iter != items.end(); ++iter) {
- int originID = iter->second->data(1, Qt::UserRole).toInt();
+ for (auto iter = items.begin(); iter != items.end(); ++iter) {
+ int originID = iter->second->data(1, Qt::UserRole).toInt();
- FilesOrigin origin = m_OrganizerCore.directoryStructure()->getOriginByID(originID);
- QString modName("data");
- unsigned int modIndex = ModInfo::getIndex(ToQString(origin.getName()));
- if (modIndex != UINT_MAX) {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex);
- modName = modInfo->name();
- }
- QList<QTreeWidgetItem*> items = ui->bsaList->findItems(modName, Qt::MatchFixedString);
- QTreeWidgetItem* subItem = nullptr;
- if (items.length() > 0) {
- subItem = items.at(0);
- } else {
- subItem = new QTreeWidgetItem(QStringList(modName));
- subItem->setFlags(subItem->flags() & ~Qt::ItemIsDragEnabled);
- ui->bsaList->addTopLevelItem(subItem);
- }
- subItem->addChild(iter->second);
- subItem->setExpanded(true);
+ FilesOrigin origin = m_OrganizerCore.directoryStructure()->getOriginByID(originID);
+ QString modName("data");
+ unsigned int modIndex = ModInfo::getIndex(ToQString(origin.getName()));
+ if (modIndex != UINT_MAX) {
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex);
+ modName = modInfo->name();
+ }
+ QList<QTreeWidgetItem*> items = ui->bsaList->findItems(modName, Qt::MatchFixedString);
+ QTreeWidgetItem * subItem = nullptr;
+ if (items.length() > 0) {
+ subItem = items.at(0);
}
- checkBSAList();
+ else {
+ subItem = new QTreeWidgetItem(QStringList(modName));
+ subItem->setFlags(subItem->flags() & ~Qt::ItemIsDragEnabled);
+ ui->bsaList->addTopLevelItem(subItem);
+ }
+ subItem->addChild(iter->second);
+ subItem->setExpanded(true);
+ }
+ checkBSAList();
}
-void MainWindow::checkBSAList() {
- DataArchives* archives = m_OrganizerCore.managedGame()->feature<DataArchives>();
+void MainWindow::checkBSAList()
+{
+ DataArchives * archives = m_OrganizerCore.managedGame()->feature<DataArchives>();
- if (archives != nullptr) {
- ui->bsaList->blockSignals(true);
- ON_BLOCK_EXIT([&]() { ui->bsaList->blockSignals(false); });
+ if (archives != nullptr) {
+ ui->bsaList->blockSignals(true);
+ ON_BLOCK_EXIT([&]() { ui->bsaList->blockSignals(false); });
- QStringList defaultArchives = archives->archives(m_OrganizerCore.currentProfile());
+ QStringList defaultArchives = archives->archives(m_OrganizerCore.currentProfile());
- bool warning = false;
+ bool warning = false;
- for (int i = 0; i < ui->bsaList->topLevelItemCount(); ++i) {
- bool modWarning = false;
- QTreeWidgetItem* tlItem = ui->bsaList->topLevelItem(i);
- for (int j = 0; j < tlItem->childCount(); ++j) {
- QTreeWidgetItem* item = tlItem->child(j);
- QString filename = item->text(0);
- item->setIcon(0, QIcon());
- item->setToolTip(0, QString());
+ for (int i = 0; i < ui->bsaList->topLevelItemCount(); ++i) {
+ bool modWarning = false;
+ QTreeWidgetItem * tlItem = ui->bsaList->topLevelItem(i);
+ for (int j = 0; j < tlItem->childCount(); ++j) {
+ QTreeWidgetItem * item = tlItem->child(j);
+ QString filename = item->text(0);
+ item->setIcon(0, QIcon());
+ item->setToolTip(0, QString());
- if (item->checkState(0) == Qt::Unchecked) {
- if (defaultArchives.contains(filename)) {
- item->setIcon(0, QIcon(":/MO/gui/warning"));
- item->setToolTip(0, tr("This bsa is enabled in the ini file so it may be required!"));
- modWarning = true;
- }
- }
- }
- if (modWarning) {
- ui->bsaList->expandItem(ui->bsaList->topLevelItem(i));
- warning = true;
- }
- }
- if (warning) {
- ui->tabWidget->setTabIcon(1, QIcon(":/MO/gui/warning"));
- } else {
- ui->tabWidget->setTabIcon(1, QIcon());
+ if (item->checkState(0) == Qt::Unchecked) {
+ if (defaultArchives.contains(filename)) {
+ item->setIcon(0, QIcon(":/MO/gui/warning"));
+ item->setToolTip(0, tr("This bsa is enabled in the ini file so it may be required!"));
+ modWarning = true;
+ }
}
+ }
+ if (modWarning) {
+ ui->bsaList->expandItem(ui->bsaList->topLevelItem(i));
+ warning = true;
+ }
+ }
+ if (warning) {
+ ui->tabWidget->setTabIcon(1, QIcon(":/MO/gui/warning"));
+ } else {
+ ui->tabWidget->setTabIcon(1, QIcon());
}
+ }
}
-void MainWindow::saveModMetas() {
- for (unsigned int i = 0; i < ModInfo::getNumMods(); ++i) {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(i);
- modInfo->saveMeta();
- }
+void MainWindow::saveModMetas()
+{
+ for (unsigned int i = 0; i < ModInfo::getNumMods(); ++i) {
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(i);
+ modInfo->saveMeta();
+ }
}
-void MainWindow::fixCategories() {
- for (unsigned int i = 0; i < ModInfo::getNumMods(); ++i) {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(i);
- std::set<int> categories = modInfo->getCategories();
- for (std::set<int>::iterator iter = categories.begin(); iter != categories.end(); ++iter) {
- if (!m_CategoryFactory.categoryExists(*iter)) {
- modInfo->setCategory(*iter, false);
- }
- }
+void MainWindow::fixCategories()
+{
+ for (unsigned int i = 0; i < ModInfo::getNumMods(); ++i) {
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(i);
+ std::set<int> categories = modInfo->getCategories();
+ for (std::set<int>::iterator iter = categories.begin();
+ iter != categories.end(); ++iter) {
+ if (!m_CategoryFactory.categoryExists(*iter)) {
+ modInfo->setCategory(*iter, false);
+ }
}
+ }
}
-void MainWindow::setupNetworkProxy(bool activate) {
- QNetworkProxyFactory::setUseSystemConfiguration(activate);
- /* QNetworkProxyQuery query(QUrl("http://www.google.com"), QNetworkProxyQuery::UrlRequest);
- query.setProtocolTag("http");
- QList<QNetworkProxy> proxies = QNetworkProxyFactory::systemProxyForQuery(query);
- if ((proxies.size() > 0) && (proxies.at(0).type() != QNetworkProxy::NoProxy)) {
- qDebug("Using proxy: %s", qPrintable(proxies.at(0).hostName()));
- QNetworkProxy::setApplicationProxy(proxies[0]);
- } else {
- qDebug("Not using proxy");
- }*/
+
+void MainWindow::setupNetworkProxy(bool activate)
+{
+ QNetworkProxyFactory::setUseSystemConfiguration(activate);
+/* QNetworkProxyQuery query(QUrl("http://www.google.com"), QNetworkProxyQuery::UrlRequest);
+ query.setProtocolTag("http");
+ QList<QNetworkProxy> proxies = QNetworkProxyFactory::systemProxyForQuery(query);
+ if ((proxies.size() > 0) && (proxies.at(0).type() != QNetworkProxy::NoProxy)) {
+ qDebug("Using proxy: %s", qPrintable(proxies.at(0).hostName()));
+ QNetworkProxy::setApplicationProxy(proxies[0]);
+ } else {
+ qDebug("Not using proxy");
+ }*/
}
-void MainWindow::activateProxy(bool activate) {
- QProgressDialog busyDialog(tr("Activating Network Proxy"), QString(), 0, 0, parentWidget());
- busyDialog.setWindowFlags(busyDialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
- busyDialog.setWindowModality(Qt::WindowModal);
- busyDialog.show();
- QFuture<void> future = QtConcurrent::run(MainWindow::setupNetworkProxy, activate);
- while (!future.isFinished()) {
- QCoreApplication::processEvents();
- ::Sleep(100);
- }
- busyDialog.hide();
+
+void MainWindow::activateProxy(bool activate)
+{
+ QProgressDialog busyDialog(tr("Activating Network Proxy"), QString(), 0, 0, parentWidget());
+ busyDialog.setWindowFlags(busyDialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ busyDialog.setWindowModality(Qt::WindowModal);
+ busyDialog.show();
+ QFuture<void> future = QtConcurrent::run(MainWindow::setupNetworkProxy, activate);
+ while (!future.isFinished()) {
+ QCoreApplication::processEvents();
+ ::Sleep(100);
+ }
+ busyDialog.hide();
}
-void MainWindow::readSettings() {
- QSettings settings(qApp->property("dataPath").toString() + "/" + QString::fromStdWString(AppConfig::iniFileName()),
- QSettings::IniFormat);
+void MainWindow::readSettings()
+{
+ QSettings settings(qApp->property("dataPath").toString() + "/" + QString::fromStdWString(AppConfig::iniFileName()), QSettings::IniFormat);
- if (settings.contains("window_geometry")) {
- restoreGeometry(settings.value("window_geometry").toByteArray());
- }
+ if (settings.contains("window_geometry")) {
+ restoreGeometry(settings.value("window_geometry").toByteArray());
+ }
- if (settings.contains("window_split")) {
- ui->splitter->restoreState(settings.value("window_split").toByteArray());
- }
+ if (settings.contains("window_split")) {
+ ui->splitter->restoreState(settings.value("window_split").toByteArray());
+ }
- if (settings.contains("log_split")) {
- ui->topLevelSplitter->restoreState(settings.value("log_split").toByteArray());
- }
+ if (settings.contains("log_split")) {
+ ui->topLevelSplitter->restoreState(settings.value("log_split").toByteArray());
+ }
- bool filtersVisible = settings.value("filters_visible", false).toBool();
- setCategoryListVisible(filtersVisible);
- ui->displayCategoriesBtn->setChecked(filtersVisible);
+ bool filtersVisible = settings.value("filters_visible", false).toBool();
+ setCategoryListVisible(filtersVisible);
+ ui->displayCategoriesBtn->setChecked(filtersVisible);
- int selectedExecutable = settings.value("selected_executable").toInt();
- setExecutableIndex(selectedExecutable);
+ int selectedExecutable = settings.value("selected_executable").toInt();
+ setExecutableIndex(selectedExecutable);
- if (settings.value("Settings/use_proxy", false).toBool()) {
- activateProxy(true);
- }
+ if (settings.value("Settings/use_proxy", false).toBool()) {
+ activateProxy(true);
+ }
}
-void MainWindow::storeSettings(QSettings& settings) {
- settings.setValue("group_state", ui->groupCombo->currentIndex());
+void MainWindow::storeSettings(QSettings &settings) {
+ settings.setValue("group_state", ui->groupCombo->currentIndex());
- settings.setValue("window_geometry", saveGeometry());
- settings.setValue("window_split", ui->splitter->saveState());
- settings.setValue("log_split", ui->topLevelSplitter->saveState());
+ settings.setValue("window_geometry", saveGeometry());
+ settings.setValue("window_split", ui->splitter->saveState());
+ settings.setValue("log_split", ui->topLevelSplitter->saveState());
- settings.setValue("browser_geometry", m_IntegratedBrowser.saveGeometry());
+ settings.setValue("browser_geometry", m_IntegratedBrowser.saveGeometry());
- settings.setValue("filters_visible", ui->displayCategoriesBtn->isChecked());
+ settings.setValue("filters_visible", ui->displayCategoriesBtn->isChecked());
- settings.setValue("selected_executable", ui->executablesListBox->currentIndex());
+ settings.setValue("selected_executable",
+ ui->executablesListBox->currentIndex());
- for (const std::pair<QString, QHeaderView*> kv : m_PersistedGeometry) {
- QString key = QString("geometry/") + kv.first;
- settings.setValue(key, kv.second->saveState());
- }
+ for (const std::pair<QString, QHeaderView*> kv : m_PersistedGeometry) {
+ QString key = QString("geometry/") + kv.first;
+ settings.setValue(key, kv.second->saveState());
+ }
}
-ILockedWaitingForProcess* MainWindow::lock() {
- if (m_LockDialog != nullptr) {
- ++m_LockCount;
- return m_LockDialog;
- }
- if (m_closing)
- m_LockDialog = new WaitingOnCloseDialog(this);
- else
- m_LockDialog = new LockedDialog(this, true);
- m_LockDialog->setModal(true);
- m_LockDialog->show();
- setEnabled(false);
- m_LockDialog->setEnabled(true); // What's the point otherwise?
+ILockedWaitingForProcess* MainWindow::lock()
+{
+ if (m_LockDialog != nullptr) {
++m_LockCount;
return m_LockDialog;
+ }
+ if (m_closing)
+ m_LockDialog = new WaitingOnCloseDialog(this);
+ else
+ m_LockDialog = new LockedDialog(this, true);
+ m_LockDialog->setModal(true);
+ m_LockDialog->show();
+ setEnabled(false);
+ m_LockDialog->setEnabled(true); //What's the point otherwise?
+ ++m_LockCount;
+ return m_LockDialog;
}
-void MainWindow::unlock() {
- // If you come through here with a null lock pointer, it's a bug!
- if (m_LockDialog == nullptr) {
- qDebug("Unlocking main window when already unlocked");
- return;
- }
- --m_LockCount;
- if (m_LockCount == 0) {
- if (m_closing && m_LockDialog->canceled())
- m_closing = false;
- m_LockDialog->hide();
- m_LockDialog->deleteLater();
- m_LockDialog = nullptr;
- setEnabled(true);
- }
+void MainWindow::unlock()
+{
+ //If you come through here with a null lock pointer, it's a bug!
+ if (m_LockDialog == nullptr) {
+ qDebug("Unlocking main window when already unlocked");
+ return;
+ }
+ --m_LockCount;
+ if (m_LockCount == 0) {
+ if (m_closing && m_LockDialog->canceled())
+ m_closing = false;
+ m_LockDialog->hide();
+ m_LockDialog->deleteLater();
+ m_LockDialog = nullptr;
+ setEnabled(true);
+ }
}
-void MainWindow::on_btnRefreshData_clicked() { m_OrganizerCore.refreshDirectoryStructure(); }
+void MainWindow::on_btnRefreshData_clicked()
+{
+ m_OrganizerCore.refreshDirectoryStructure();
+}
-void MainWindow::on_tabWidget_currentChanged(int index) {
- if (index == 0) {
- m_OrganizerCore.refreshESPList();
- } else if (index == 1) {
- m_OrganizerCore.refreshBSAList();
- } else if (index == 2) {
- refreshDataTree();
- } else if (index == 3) {
- refreshSaveList();
- }
+void MainWindow::on_tabWidget_currentChanged(int index)
+{
+ if (index == 0) {
+ m_OrganizerCore.refreshESPList();
+ } else if (index == 1) {
+ m_OrganizerCore.refreshBSAList();
+ } else if (index == 2) {
+ refreshDataTree();
+ } else if (index == 3) {
+ refreshSaveList();
+ }
}
-void MainWindow::installMod(QString fileName) {
- try {
- if (fileName.isEmpty()) {
- QStringList extensions = m_OrganizerCore.installationManager()->getSupportedExtensions();
- for (auto iter = extensions.begin(); iter != extensions.end(); ++iter) {
- *iter = "*." + *iter;
- }
- fileName =
- FileDialogMemory::getOpenFileName("installMod", this, tr("Choose Mod"), QString(),
- tr("Mod Archive").append(QString(" (%1)").arg(extensions.join(" "))));
- }
+void MainWindow::installMod(QString fileName)
+{
+ try {
+ if (fileName.isEmpty()) {
+ QStringList extensions = m_OrganizerCore.installationManager()->getSupportedExtensions();
+ for (auto iter = extensions.begin(); iter != extensions.end(); ++iter) {
+ *iter = "*." + *iter;
+ }
- if (fileName.isEmpty()) {
- return;
- } else {
- m_OrganizerCore.installMod(fileName, QString());
- }
- } catch (const std::exception& e) {
- reportError(e.what());
+ fileName = FileDialogMemory::getOpenFileName("installMod", this, tr("Choose Mod"), QString(),
+ tr("Mod Archive").append(QString(" (%1)").arg(extensions.join(" "))));
+ }
+
+ if (fileName.isEmpty()) {
+ return;
+ } else {
+ m_OrganizerCore.installMod(fileName, QString());
}
+ } catch (const std::exception &e) {
+ reportError(e.what());
+ }
}
void MainWindow::on_startButton_clicked() {
- const Executable& selectedExecutable(getSelectedExecutable());
- QString customOverwrite =
- m_OrganizerCore.currentProfile()->setting("custom_overwrites", selectedExecutable.m_Title).toString();
- m_OrganizerCore.spawnBinary(selectedExecutable.m_BinaryInfo, selectedExecutable.m_Arguments,
- selectedExecutable.m_WorkingDirectory.length() != 0
- ? selectedExecutable.m_WorkingDirectory
- : selectedExecutable.m_BinaryInfo.absolutePath(),
- selectedExecutable.m_SteamAppID, customOverwrite);
+ const Executable &selectedExecutable(getSelectedExecutable());
+ QString customOverwrite = m_OrganizerCore.currentProfile()->setting("custom_overwrites", selectedExecutable.m_Title).toString();
+ m_OrganizerCore.spawnBinary(
+ selectedExecutable.m_BinaryInfo, selectedExecutable.m_Arguments,
+ selectedExecutable.m_WorkingDirectory.length() != 0
+ ? selectedExecutable.m_WorkingDirectory
+ : selectedExecutable.m_BinaryInfo.absolutePath(),
+ selectedExecutable.m_SteamAppID, customOverwrite);
}
-static HRESULT CreateShortcut(LPCWSTR targetFileName, LPCWSTR arguments, LPCSTR linkFileName, LPCWSTR description,
- LPCTSTR iconFileName, int iconNumber, LPCWSTR currentDirectory) {
- HRESULT result = E_INVALIDARG;
- if ((targetFileName != nullptr) && (wcslen(targetFileName) > 0) && (arguments != nullptr) &&
- (linkFileName != nullptr) && (strlen(linkFileName) > 0) && (description != nullptr) &&
- (currentDirectory != nullptr)) {
-
- IShellLink* shellLink;
- result = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&shellLink);
-
- if (!SUCCEEDED(result)) {
- qCritical("failed to create IShellLink instance");
- return result;
- }
+static HRESULT CreateShortcut(LPCWSTR targetFileName, LPCWSTR arguments,
+ LPCSTR linkFileName, LPCWSTR description,
+ LPCTSTR iconFileName, int iconNumber,
+ LPCWSTR currentDirectory)
+{
+ HRESULT result = E_INVALIDARG;
+ if ((targetFileName != nullptr) && (wcslen(targetFileName) > 0) &&
+ (arguments != nullptr) &&
+ (linkFileName != nullptr) && (strlen(linkFileName) > 0) &&
+ (description != nullptr) &&
+ (currentDirectory != nullptr)) {
- result = shellLink->SetPath(targetFileName);
- if (!SUCCEEDED(result)) {
- qCritical("failed to set target path %ls", targetFileName);
- shellLink->Release();
- return result;
- }
+ IShellLink* shellLink;
+ result = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER,
+ IID_IShellLink, (LPVOID*)&shellLink);
- result = shellLink->SetArguments(arguments);
- if (!SUCCEEDED(result)) {
- qCritical("failed to set arguments: %ls", arguments);
- shellLink->Release();
- return result;
- }
+ if (!SUCCEEDED(result)) {
+ qCritical("failed to create IShellLink instance");
+ return result;
+ }
- if (wcslen(description) > 0) {
- result = shellLink->SetDescription(description);
- if (!SUCCEEDED(result)) {
- qCritical("failed to set description: %ls", description);
- shellLink->Release();
- return result;
- }
- }
+ result = shellLink->SetPath(targetFileName);
+ if (!SUCCEEDED(result)) {
+ qCritical("failed to set target path %ls", targetFileName);
+ shellLink->Release();
+ return result;
+ }
- if (wcslen(currentDirectory) > 0) {
- result = shellLink->SetWorkingDirectory(currentDirectory);
- if (!SUCCEEDED(result)) {
- qCritical("failed to set working directory: %ls", currentDirectory);
- shellLink->Release();
- return result;
- }
- }
+ result = shellLink->SetArguments(arguments);
+ if (!SUCCEEDED(result)) {
+ qCritical("failed to set arguments: %ls", arguments);
+ shellLink->Release();
+ return result;
+ }
- if (iconFileName != nullptr) {
- result = shellLink->SetIconLocation(iconFileName, iconNumber);
- if (!SUCCEEDED(result)) {
- qCritical("failed to load program icon: %ls %d", iconFileName, iconNumber);
- shellLink->Release();
- return result;
- }
- }
+ if (wcslen(description) > 0) {
+ result = shellLink->SetDescription(description);
+ if (!SUCCEEDED(result)) {
+ qCritical("failed to set description: %ls", description);
+ shellLink->Release();
+ return result;
+ }
+ }
- IPersistFile* persistFile;
- result = shellLink->QueryInterface(IID_IPersistFile, (LPVOID*)&persistFile);
- if (SUCCEEDED(result)) {
- wchar_t linkFileNameW[MAX_PATH];
- if (MultiByteToWideChar(CP_ACP, 0, linkFileName, -1, linkFileNameW, MAX_PATH) > 0) {
- result = persistFile->Save(linkFileNameW, TRUE);
- } else {
- qCritical("failed to create link: %s", linkFileName);
- }
- persistFile->Release();
- } else {
- qCritical("failed to create IPersistFile instance");
- }
+ if (wcslen(currentDirectory) > 0) {
+ result = shellLink->SetWorkingDirectory(currentDirectory);
+ if (!SUCCEEDED(result)) {
+ qCritical("failed to set working directory: %ls", currentDirectory);
+ shellLink->Release();
+ return result;
+ }
+ }
+ if (iconFileName != nullptr) {
+ result = shellLink->SetIconLocation(iconFileName, iconNumber);
+ if (!SUCCEEDED(result)) {
+ qCritical("failed to load program icon: %ls %d", iconFileName, iconNumber);
shellLink->Release();
+ return result;
+ }
}
- return result;
+
+ IPersistFile *persistFile;
+ result = shellLink->QueryInterface(IID_IPersistFile, (LPVOID*)&persistFile);
+ if (SUCCEEDED(result)) {
+ wchar_t linkFileNameW[MAX_PATH];
+ if (MultiByteToWideChar(CP_ACP, 0, linkFileName, -1, linkFileNameW, MAX_PATH) > 0) {
+ result = persistFile->Save(linkFileNameW, TRUE);
+ } else {
+ qCritical("failed to create link: %s", linkFileName);
+ }
+ persistFile->Release();
+ } else {
+ qCritical("failed to create IPersistFile instance");
+ }
+
+ shellLink->Release();
+ }
+ return result;
}
-bool MainWindow::modifyExecutablesDialog() {
- bool result = false;
- try {
- EditExecutablesDialog dialog(*m_OrganizerCore.executablesList(), *m_OrganizerCore.modList(),
- m_OrganizerCore.currentProfile());
- if (dialog.exec() == QDialog::Accepted) {
- m_OrganizerCore.setExecutablesList(dialog.getExecutablesList());
- result = true;
- }
- refreshExecutablesList();
- } catch (const std::exception& e) {
- reportError(e.what());
+
+bool MainWindow::modifyExecutablesDialog()
+{
+ bool result = false;
+ try {
+ EditExecutablesDialog dialog(*m_OrganizerCore.executablesList(),
+ *m_OrganizerCore.modList(),
+ m_OrganizerCore.currentProfile());
+ if (dialog.exec() == QDialog::Accepted) {
+ m_OrganizerCore.setExecutablesList(dialog.getExecutablesList());
+ result = true;
}
- return result;
+ refreshExecutablesList();
+ } catch (const std::exception &e) {
+ reportError(e.what());
+ }
+ return result;
}
-void MainWindow::on_executablesListBox_currentIndexChanged(int index) {
- QComboBox* executablesList = findChild<QComboBox*>("executablesListBox");
+void MainWindow::on_executablesListBox_currentIndexChanged(int index)
+{
+ QComboBox* executablesList = findChild<QComboBox*>("executablesListBox");
- int previousIndex = m_OldExecutableIndex;
- m_OldExecutableIndex = index;
+ int previousIndex = m_OldExecutableIndex;
+ m_OldExecutableIndex = index;
- if (executablesList->isEnabled()) {
- // I think the 2nd test is impossible
- if ((index == 0) || (index > static_cast<int>(m_OrganizerCore.executablesList()->size()))) {
- if (modifyExecutablesDialog()) {
- setExecutableIndex(previousIndex);
- }
- } else {
- setExecutableIndex(index);
- }
+ if (executablesList->isEnabled()) {
+ //I think the 2nd test is impossible
+ if ((index == 0) || (index > static_cast<int>(m_OrganizerCore.executablesList()->size()))) {
+ if (modifyExecutablesDialog()) {
+ setExecutableIndex(previousIndex);
+ }
+ } else {
+ setExecutableIndex(index);
}
+ }
}
-void MainWindow::helpTriggered() { QWhatsThis::enterWhatsThisMode(); }
+void MainWindow::helpTriggered()
+{
+ QWhatsThis::enterWhatsThisMode();
+}
-void MainWindow::wikiTriggered() {
- ::ShellExecuteW(nullptr, L"open", L"http://wiki.step-project.com/Guide:Mod_Organizer", nullptr, nullptr,
- SW_SHOWNORMAL);
+void MainWindow::wikiTriggered()
+{
+ ::ShellExecuteW(nullptr, L"open", L"http://wiki.step-project.com/Guide:Mod_Organizer", nullptr, nullptr, SW_SHOWNORMAL);
}
-void MainWindow::issueTriggered() {
- ::ShellExecuteW(nullptr, L"open", L"http://github.com/LePresidente/modorganizer/issues", nullptr, nullptr,
- SW_SHOWNORMAL);
+void MainWindow::issueTriggered()
+{
+ ::ShellExecuteW(nullptr, L"open", L"http://github.com/LePresidente/modorganizer/issues", nullptr, nullptr, SW_SHOWNORMAL);
}
-void MainWindow::tutorialTriggered() {
- QAction* tutorialAction = qobject_cast<QAction*>(sender());
- if (tutorialAction != nullptr) {
- if (QMessageBox::question(this, tr("Start Tutorial?"),
- tr("You're about to start a tutorial. For technical reasons it's not possible to end "
- "the tutorial early. Continue?"),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- TutorialManager::instance().activateTutorial("MainWindow", tutorialAction->data().toString());
- }
+void MainWindow::tutorialTriggered()
+{
+ QAction *tutorialAction = qobject_cast<QAction*>(sender());
+ if (tutorialAction != nullptr) {
+ if (QMessageBox::question(this, tr("Start Tutorial?"),
+ tr("You're about to start a tutorial. For technical reasons it's not possible to end "
+ "the tutorial early. Continue?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ TutorialManager::instance().activateTutorial("MainWindow", tutorialAction->data().toString());
}
+ }
}
-void MainWindow::on_actionInstallMod_triggered() { installMod(); }
-void MainWindow::on_actionAdd_Profile_triggered() {
- for (;;) {
- // Note: Calling this with an invalid profile name. Not quite sure why
- ProfilesDialog profilesDialog(m_OrganizerCore.managedGame()->gameDirectory().absolutePath(),
- m_OrganizerCore.managedGame(), this);
- // workaround: need to disable monitoring of the saves directory, otherwise the active
- // profile directory is locked
- stopMonitorSaves();
- profilesDialog.exec();
- refreshSaveList(); // since the save list may now be outdated we have to refresh it completely
- if (refreshProfiles() && !profilesDialog.failed()) {
- break;
- }
- }
- // addProfile();
+void MainWindow::on_actionInstallMod_triggered()
+{
+ installMod();
}
-void MainWindow::on_actionModify_Executables_triggered() {
- if (modifyExecutablesDialog()) {
- setExecutableIndex(m_OldExecutableIndex);
+void MainWindow::on_actionAdd_Profile_triggered()
+{
+ for (;;) {
+ //Note: Calling this with an invalid profile name. Not quite sure why
+ ProfilesDialog profilesDialog(m_OrganizerCore.managedGame()->gameDirectory().absolutePath(),
+ m_OrganizerCore.managedGame(),
+ this);
+ // workaround: need to disable monitoring of the saves directory, otherwise the active
+ // profile directory is locked
+ stopMonitorSaves();
+ profilesDialog.exec();
+ refreshSaveList(); // since the save list may now be outdated we have to refresh it completely
+ if (refreshProfiles() && !profilesDialog.failed()) {
+ break;
}
+ }
+// addProfile();
+}
+
+void MainWindow::on_actionModify_Executables_triggered()
+{
+ if (modifyExecutablesDialog()) {
+ setExecutableIndex(m_OldExecutableIndex);
+ }
}
-void MainWindow::setModListSorting(int index) {
- Qt::SortOrder order = ((index & 0x01) != 0) ? Qt::DescendingOrder : Qt::AscendingOrder;
- int column = index >> 1;
- ui->modList->header()->setSortIndicator(column, order);
+
+void MainWindow::setModListSorting(int index)
+{
+ Qt::SortOrder order = ((index & 0x01) != 0) ? Qt::DescendingOrder : Qt::AscendingOrder;
+ int column = index >> 1;
+ ui->modList->header()->setSortIndicator(column, order);
}
-void MainWindow::setESPListSorting(int index) {
- switch (index) {
+
+void MainWindow::setESPListSorting(int index)
+{
+ switch (index) {
case 0: {
- ui->espList->header()->setSortIndicator(1, Qt::AscendingOrder);
+ ui->espList->header()->setSortIndicator(1, Qt::AscendingOrder);
} break;
case 1: {
- ui->espList->header()->setSortIndicator(1, Qt::DescendingOrder);
+ ui->espList->header()->setSortIndicator(1, Qt::DescendingOrder);
} break;
case 2: {
- ui->espList->header()->setSortIndicator(0, Qt::AscendingOrder);
+ ui->espList->header()->setSortIndicator(0, Qt::AscendingOrder);
} break;
case 3: {
- ui->espList->header()->setSortIndicator(0, Qt::DescendingOrder);
+ ui->espList->header()->setSortIndicator(0, Qt::DescendingOrder);
} break;
- }
+ }
}
-void MainWindow::refresher_progress(int percent) {
- if (percent == 100) {
- m_RefreshProgress->setVisible(false);
- statusBar()->hide();
- } else if (!m_RefreshProgress->isVisible()) {
- statusBar()->show();
- m_RefreshProgress->setVisible(true);
- m_RefreshProgress->setRange(0, 100);
- m_RefreshProgress->setValue(percent);
- }
+void MainWindow::refresher_progress(int percent)
+{
+ if (percent == 100) {
+ m_RefreshProgress->setVisible(false);
+ statusBar()->hide();
+ } else if (!m_RefreshProgress->isVisible()) {
+ statusBar()->show();
+ m_RefreshProgress->setVisible(true);
+ m_RefreshProgress->setRange(0, 100);
+ m_RefreshProgress->setValue(percent);
+ }
}
-void MainWindow::directory_refreshed() {
- // some problem-reports may rely on the virtual directory tree so they need to be updated
- // now
- refreshDataTree();
- updateProblemsButton();
- statusBar()->hide();
+void MainWindow::directory_refreshed()
+{
+ // some problem-reports may rely on the virtual directory tree so they need to be updated
+ // now
+ refreshDataTree();
+ updateProblemsButton();
+ statusBar()->hide();
}
-void MainWindow::modorder_changed() {
- for (unsigned int i = 0; i < m_OrganizerCore.currentProfile()->numMods(); ++i) {
- int priority = m_OrganizerCore.currentProfile()->getModPriority(i);
- if (m_OrganizerCore.currentProfile()->modEnabled(i)) {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(i);
- // priorities in the directory structure are one higher because data is 0
- m_OrganizerCore.directoryStructure()
- ->getOriginByName(ToWString(modInfo->internalName()))
- .setPriority(priority + 1);
- }
+void MainWindow::modorder_changed()
+{
+ for (unsigned int i = 0; i < m_OrganizerCore.currentProfile()->numMods(); ++i) {
+ int priority = m_OrganizerCore.currentProfile()->getModPriority(i);
+ if (m_OrganizerCore.currentProfile()->modEnabled(i)) {
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(i);
+ // priorities in the directory structure are one higher because data is 0
+ m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(modInfo->internalName())).setPriority(priority + 1);
}
- m_OrganizerCore.refreshBSAList();
- m_OrganizerCore.currentProfile()->writeModlist();
- m_ArchiveListWriter.write();
- m_OrganizerCore.directoryStructure()->getFileRegister()->sortOrigins();
+ }
+ m_OrganizerCore.refreshBSAList();
+ m_OrganizerCore.currentProfile()->writeModlist();
+ m_ArchiveListWriter.write();
+ m_OrganizerCore.directoryStructure()->getFileRegister()->sortOrigins();
- { // refresh selection
- QModelIndex current = ui->modList->currentIndex();
- if (current.isValid()) {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(current.data(Qt::UserRole + 1).toInt());
- // clear caches on all mods conflicting with the moved mod
- for (int i : modInfo->getModOverwrite()) {
- ModInfo::getByIndex(i)->clearCaches();
- }
- for (int i : modInfo->getModOverwritten()) {
- ModInfo::getByIndex(i)->clearCaches();
- }
- // update conflict check on the moved mod
- modInfo->doConflictCheck();
- m_OrganizerCore.modList()->setOverwriteMarkers(modInfo->getModOverwrite(), modInfo->getModOverwritten());
- if (m_ModListSortProxy != nullptr) {
- m_ModListSortProxy->invalidate();
- }
- ui->modList->verticalScrollBar()->repaint();
- }
+ { // refresh selection
+ QModelIndex current = ui->modList->currentIndex();
+ if (current.isValid()) {
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(current.data(Qt::UserRole + 1).toInt());
+ // clear caches on all mods conflicting with the moved mod
+ for (int i : modInfo->getModOverwrite()) {
+ ModInfo::getByIndex(i)->clearCaches();
+ }
+ for (int i : modInfo->getModOverwritten()) {
+ ModInfo::getByIndex(i)->clearCaches();
+ }
+ // update conflict check on the moved mod
+ modInfo->doConflictCheck();
+ m_OrganizerCore.modList()->setOverwriteMarkers(modInfo->getModOverwrite(), modInfo->getModOverwritten());
+ if (m_ModListSortProxy != nullptr) {
+ m_ModListSortProxy->invalidate();
+ }
+ ui->modList->verticalScrollBar()->repaint();
}
+ }
}
-void MainWindow::modInstalled(const QString& modName) {
- QModelIndexList posList =
- m_OrganizerCore.modList()->match(m_OrganizerCore.modList()->index(0, 0), Qt::DisplayRole, modName);
- if (posList.count() == 1) {
- ui->modList->scrollTo(posList.at(0));
- }
+void MainWindow::modInstalled(const QString &modName)
+{
+ QModelIndexList posList =
+ m_OrganizerCore.modList()->match(m_OrganizerCore.modList()->index(0, 0), Qt::DisplayRole, modName);
+ if (posList.count() == 1) {
+ ui->modList->scrollTo(posList.at(0));
+ }
}
-void MainWindow::procError(QProcess::ProcessError error) {
- reportError(tr("failed to spawn notepad.exe: %1").arg(error));
- this->sender()->deleteLater();
+void MainWindow::procError(QProcess::ProcessError error)
+{
+ reportError(tr("failed to spawn notepad.exe: %1").arg(error));
+ this->sender()->deleteLater();
}
-void MainWindow::procFinished(int, QProcess::ExitStatus) { this->sender()->deleteLater(); }
+void MainWindow::procFinished(int, QProcess::ExitStatus)
+{
+ this->sender()->deleteLater();
+}
-void MainWindow::showMessage(const QString& message) { MessageDialog::showMessage(message, this); }
+void MainWindow::showMessage(const QString &message)
+{
+ MessageDialog::showMessage(message, this);
+}
-void MainWindow::showError(const QString& message) { reportError(message); }
+void MainWindow::showError(const QString &message)
+{
+ reportError(message);
+}
-void MainWindow::installMod_clicked() { installMod(); }
+void MainWindow::installMod_clicked()
+{
+ installMod();
+}
-void MainWindow::modRenamed(const QString& oldName, const QString& newName) {
- Profile::renameModInAllProfiles(oldName, newName);
+void MainWindow::modRenamed(const QString &oldName, const QString &newName)
+{
+ Profile::renameModInAllProfiles(oldName, newName);
- // immediately refresh the active profile because the data in memory is invalid
- m_OrganizerCore.currentProfile()->refreshModStatus();
+ // immediately refresh the active profile because the data in memory is invalid
+ m_OrganizerCore.currentProfile()->refreshModStatus();
+
+ // also fix the directory structure
+ try {
+ if (m_OrganizerCore.directoryStructure()->originExists(ToWString(oldName))) {
+ FilesOrigin &origin = m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(oldName));
+ origin.setName(ToWString(newName));
+ } else {
- // also fix the directory structure
- try {
- if (m_OrganizerCore.directoryStructure()->originExists(ToWString(oldName))) {
- FilesOrigin& origin = m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(oldName));
- origin.setName(ToWString(newName));
- } else {
- }
- } catch (const std::exception& e) {
- reportError(tr("failed to change origin name: %1").arg(e.what()));
}
+ } catch (const std::exception &e) {
+ reportError(tr("failed to change origin name: %1").arg(e.what()));
+ }
}
-void MainWindow::fileMoved(const QString& filePath, const QString& oldOriginName, const QString& newOriginName) {
- const FileEntry::Ptr filePtr = m_OrganizerCore.directoryStructure()->findFile(ToWString(filePath));
- if (filePtr.get() != nullptr) {
- try {
- if (m_OrganizerCore.directoryStructure()->originExists(ToWString(newOriginName))) {
- FilesOrigin& newOrigin =
- m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(newOriginName));
+void MainWindow::fileMoved(const QString &filePath, const QString &oldOriginName, const QString &newOriginName)
+{
+ const FileEntry::Ptr filePtr = m_OrganizerCore.directoryStructure()->findFile(ToWString(filePath));
+ if (filePtr.get() != nullptr) {
+ try {
+ if (m_OrganizerCore.directoryStructure()->originExists(ToWString(newOriginName))) {
+ FilesOrigin &newOrigin = m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(newOriginName));
- QString fullNewPath = ToQString(newOrigin.getPath()) + "\\" + filePath;
- WIN32_FIND_DATAW findData;
- HANDLE hFind;
- hFind = ::FindFirstFileW(ToWString(fullNewPath).c_str(), &findData);
- filePtr->addOrigin(newOrigin.getID(), findData.ftCreationTime, L"");
- FindClose(hFind);
- }
- if (m_OrganizerCore.directoryStructure()->originExists(ToWString(oldOriginName))) {
- FilesOrigin& oldOrigin =
- m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(oldOriginName));
- filePtr->removeOrigin(oldOrigin.getID());
- }
- } catch (const std::exception& e) {
- reportError(tr("failed to move \"%1\" from mod \"%2\" to \"%3\": %4")
- .arg(filePath)
- .arg(oldOriginName)
- .arg(newOriginName)
- .arg(e.what()));
- }
- } else {
- // this is probably not an error, the specified path is likely a directory
+ QString fullNewPath = ToQString(newOrigin.getPath()) + "\\" + filePath;
+ WIN32_FIND_DATAW findData;
+ HANDLE hFind;
+ hFind = ::FindFirstFileW(ToWString(fullNewPath).c_str(), &findData);
+ filePtr->addOrigin(newOrigin.getID(), findData.ftCreationTime, L"");
+ FindClose(hFind);
+ }
+ if (m_OrganizerCore.directoryStructure()->originExists(ToWString(oldOriginName))) {
+ FilesOrigin &oldOrigin = m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(oldOriginName));
+ filePtr->removeOrigin(oldOrigin.getID());
+ }
+ } catch (const std::exception &e) {
+ reportError(tr("failed to move \"%1\" from mod \"%2\" to \"%3\": %4").arg(filePath).arg(oldOriginName).arg(newOriginName).arg(e.what()));
}
+ } else {
+ // this is probably not an error, the specified path is likely a directory
+ }
}
-QTreeWidgetItem* MainWindow::addFilterItem(QTreeWidgetItem* root, const QString& name, int categoryID,
- ModListSortProxy::FilterType type) {
- QTreeWidgetItem* item = new QTreeWidgetItem(QStringList(name));
- item->setData(0, Qt::ToolTipRole, name);
- item->setData(0, Qt::UserRole, categoryID);
- item->setData(0, Qt::UserRole + 1, type);
- if (root != nullptr) {
- root->addChild(item);
- } else {
- ui->categoriesList->addTopLevelItem(item);
- }
- return item;
+QTreeWidgetItem *MainWindow::addFilterItem(QTreeWidgetItem *root, const QString &name, int categoryID, ModListSortProxy::FilterType type)
+{
+ QTreeWidgetItem *item = new QTreeWidgetItem(QStringList(name));
+ item->setData(0, Qt::ToolTipRole, name);
+ item->setData(0, Qt::UserRole, categoryID);
+ item->setData(0, Qt::UserRole + 1, type);
+ if (root != nullptr) {
+ root->addChild(item);
+ } else {
+ ui->categoriesList->addTopLevelItem(item);
+ }
+ return item;
}
-void MainWindow::addContentFilters() {
- for (unsigned i = 0; i < ModInfo::NUM_CONTENT_TYPES; ++i) {
- addFilterItem(nullptr, tr("<Contains %1>").arg(ModInfo::getContentTypeName(i)), i,
- ModListSortProxy::TYPE_CONTENT);
- }
+void MainWindow::addContentFilters()
+{
+ for (unsigned i = 0; i < ModInfo::NUM_CONTENT_TYPES; ++i) {
+ addFilterItem(nullptr, tr("<Contains %1>").arg(ModInfo::getContentTypeName(i)), i, ModListSortProxy::TYPE_CONTENT);
+ }
}
-void MainWindow::addCategoryFilters(QTreeWidgetItem* root, const std::set<int>& categoriesUsed, int targetID) {
- for (unsigned int i = 1; i < static_cast<unsigned int>(m_CategoryFactory.numCategories()); ++i) {
- if ((m_CategoryFactory.getParentID(i) == targetID)) {
- int categoryID = m_CategoryFactory.getCategoryID(i);
- if (categoriesUsed.find(categoryID) != categoriesUsed.end()) {
- QTreeWidgetItem* item = addFilterItem(root, m_CategoryFactory.getCategoryName(i), categoryID,
- ModListSortProxy::TYPE_CATEGORY);
- if (m_CategoryFactory.hasChildren(i)) {
- addCategoryFilters(item, categoriesUsed, categoryID);
- }
- }
+void MainWindow::addCategoryFilters(QTreeWidgetItem *root, const std::set<int> &categoriesUsed, int targetID)
+{
+ for (unsigned int i = 1;
+ i < static_cast<unsigned int>(m_CategoryFactory.numCategories()); ++i) {
+ if ((m_CategoryFactory.getParentID(i) == targetID)) {
+ int categoryID = m_CategoryFactory.getCategoryID(i);
+ if (categoriesUsed.find(categoryID) != categoriesUsed.end()) {
+ QTreeWidgetItem *item =
+ addFilterItem(root, m_CategoryFactory.getCategoryName(i),
+ categoryID, ModListSortProxy::TYPE_CATEGORY);
+ if (m_CategoryFactory.hasChildren(i)) {
+ addCategoryFilters(item, categoriesUsed, categoryID);
}
+ }
}
+ }
}
-void MainWindow::refreshFilters() {
- QItemSelection currentSelection = ui->modList->selectionModel()->selection();
+void MainWindow::refreshFilters()
+{
+ QItemSelection currentSelection = ui->modList->selectionModel()->selection();
- QVariant currentIndexName = ui->modList->currentIndex().data();
- ui->modList->setCurrentIndex(QModelIndex());
+ QVariant currentIndexName = ui->modList->currentIndex().data();
+ ui->modList->setCurrentIndex(QModelIndex());
- QStringList selectedItems;
- for (QTreeWidgetItem* item : ui->categoriesList->selectedItems()) {
- selectedItems.append(item->text(0));
- }
+ QStringList selectedItems;
+ for (QTreeWidgetItem *item : ui->categoriesList->selectedItems()) {
+ selectedItems.append(item->text(0));
+ }
- ui->categoriesList->clear();
- addFilterItem(nullptr, tr("<Checked>"), CategoryFactory::CATEGORY_SPECIAL_CHECKED, ModListSortProxy::TYPE_SPECIAL);
- addFilterItem(nullptr, tr("<Unchecked>"), CategoryFactory::CATEGORY_SPECIAL_UNCHECKED,
- ModListSortProxy::TYPE_SPECIAL);
- addFilterItem(nullptr, tr("<Update>"), CategoryFactory::CATEGORY_SPECIAL_UPDATEAVAILABLE,
- ModListSortProxy::TYPE_SPECIAL);
- addFilterItem(nullptr, tr("<Managed by MO>"), CategoryFactory::CATEGORY_SPECIAL_MANAGED,
- ModListSortProxy::TYPE_SPECIAL);
- addFilterItem(nullptr, tr("<Managed outside MO>"), CategoryFactory::CATEGORY_SPECIAL_UNMANAGED,
- ModListSortProxy::TYPE_SPECIAL);
- addFilterItem(nullptr, tr("<No category>"), CategoryFactory::CATEGORY_SPECIAL_NOCATEGORY,
- ModListSortProxy::TYPE_SPECIAL);
- addFilterItem(nullptr, tr("<Conflicted>"), CategoryFactory::CATEGORY_SPECIAL_CONFLICT,
- ModListSortProxy::TYPE_SPECIAL);
- addFilterItem(nullptr, tr("<Not Endorsed>"), CategoryFactory::CATEGORY_SPECIAL_NOTENDORSED,
- ModListSortProxy::TYPE_SPECIAL);
+ ui->categoriesList->clear();
+ addFilterItem(nullptr, tr("<Checked>"), CategoryFactory::CATEGORY_SPECIAL_CHECKED, ModListSortProxy::TYPE_SPECIAL);
+ addFilterItem(nullptr, tr("<Unchecked>"), CategoryFactory::CATEGORY_SPECIAL_UNCHECKED, ModListSortProxy::TYPE_SPECIAL);
+ addFilterItem(nullptr, tr("<Update>"), CategoryFactory::CATEGORY_SPECIAL_UPDATEAVAILABLE, ModListSortProxy::TYPE_SPECIAL);
+ addFilterItem(nullptr, tr("<Managed by MO>"), CategoryFactory::CATEGORY_SPECIAL_MANAGED, ModListSortProxy::TYPE_SPECIAL);
+ addFilterItem(nullptr, tr("<Managed outside MO>"), CategoryFactory::CATEGORY_SPECIAL_UNMANAGED, ModListSortProxy::TYPE_SPECIAL);
+ addFilterItem(nullptr, tr("<No category>"), CategoryFactory::CATEGORY_SPECIAL_NOCATEGORY, ModListSortProxy::TYPE_SPECIAL);
+ addFilterItem(nullptr, tr("<Conflicted>"), CategoryFactory::CATEGORY_SPECIAL_CONFLICT, ModListSortProxy::TYPE_SPECIAL);
+ addFilterItem(nullptr, tr("<Not Endorsed>"), CategoryFactory::CATEGORY_SPECIAL_NOTENDORSED, ModListSortProxy::TYPE_SPECIAL);
- addContentFilters();
- std::set<int> categoriesUsed;
- for (unsigned int modIdx = 0; modIdx < ModInfo::getNumMods(); ++modIdx) {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(modIdx);
- for (int categoryID : modInfo->getCategories()) {
- int currentID = categoryID;
- std::set<int> cycleTest;
- // also add parents so they show up in the tree
- while (currentID != 0) {
- categoriesUsed.insert(currentID);
- if (!cycleTest.insert(currentID).second) {
- qWarning("cycle in categories: %s", qPrintable(SetJoin(cycleTest, ", ")));
- break;
- }
- currentID = m_CategoryFactory.getParentID(m_CategoryFactory.getCategoryIndex(currentID));
- }
+ addContentFilters();
+ std::set<int> categoriesUsed;
+ for (unsigned int modIdx = 0; modIdx < ModInfo::getNumMods(); ++modIdx) {
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(modIdx);
+ for (int categoryID : modInfo->getCategories()) {
+ int currentID = categoryID;
+ std::set<int> cycleTest;
+ // also add parents so they show up in the tree
+ while (currentID != 0) {
+ categoriesUsed.insert(currentID);
+ if (!cycleTest.insert(currentID).second) {
+ qWarning("cycle in categories: %s", qPrintable(SetJoin(cycleTest, ", ")));
+ break;
}
+ currentID = m_CategoryFactory.getParentID(m_CategoryFactory.getCategoryIndex(currentID));
+ }
}
+ }
- addCategoryFilters(nullptr, categoriesUsed, 0);
+ addCategoryFilters(nullptr, categoriesUsed, 0);
- for (const QString& item : selectedItems) {
- QList<QTreeWidgetItem*> matches =
- ui->categoriesList->findItems(item, Qt::MatchFixedString | Qt::MatchRecursive);
- if (matches.size() > 0) {
- matches.at(0)->setSelected(true);
- }
- }
- ui->modList->selectionModel()->select(currentSelection, QItemSelectionModel::Select);
- QModelIndexList matchList;
- if (currentIndexName.isValid()) {
- matchList = ui->modList->model()->match(ui->modList->model()->index(0, 0), Qt::DisplayRole, currentIndexName);
+ for (const QString &item : selectedItems) {
+ QList<QTreeWidgetItem*> matches = ui->categoriesList->findItems(item, Qt::MatchFixedString | Qt::MatchRecursive);
+ if (matches.size() > 0) {
+ matches.at(0)->setSelected(true);
}
+ }
+ ui->modList->selectionModel()->select(currentSelection, QItemSelectionModel::Select);
+ QModelIndexList matchList;
+ if (currentIndexName.isValid()) {
+ matchList = ui->modList->model()->match(ui->modList->model()->index(0, 0), Qt::DisplayRole, currentIndexName);
+ }
- if (matchList.size() > 0) {
- ui->modList->setCurrentIndex(matchList.at(0));
- }
+ if (matchList.size() > 0) {
+ ui->modList->setCurrentIndex(matchList.at(0));
+ }
}
-void MainWindow::renameMod_clicked() {
- try {
- ui->modList->edit(ui->modList->currentIndex());
- } catch (const std::exception& e) {
- reportError(tr("failed to rename mod: %1").arg(e.what()));
- }
+
+void MainWindow::renameMod_clicked()
+{
+ try {
+ ui->modList->edit(ui->modList->currentIndex());
+ } catch (const std::exception &e) {
+ reportError(tr("failed to rename mod: %1").arg(e.what()));
+ }
}
-void MainWindow::restoreBackup_clicked() {
- QRegExp backupRegEx("(.*)_backup[0-9]*$");
- ModInfo::Ptr modInfo = ModInfo::getByIndex(m_ContextRow);
- if (backupRegEx.indexIn(modInfo->name()) != -1) {
- QString regName = backupRegEx.cap(1);
- QDir modDir(QDir::fromNativeSeparators(m_OrganizerCore.settings().getModDirectory()));
- if (!modDir.exists(regName) ||
- (QMessageBox::question(this, tr("Overwrite?"),
- tr("This will replace the existing mod \"%1\". Continue?").arg(regName),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)) {
- if (modDir.exists(regName) && !shellDelete(QStringList(modDir.absoluteFilePath(regName)))) {
- reportError(tr("failed to remove mod \"%1\"").arg(regName));
- } else {
- QString destinationPath =
- QDir::fromNativeSeparators(m_OrganizerCore.settings().getModDirectory()) + "/" + regName;
- if (!modDir.rename(modInfo->absolutePath(), destinationPath)) {
- reportError(
- tr("failed to rename \"%1\" to \"%2\"").arg(modInfo->absolutePath()).arg(destinationPath));
- }
- m_OrganizerCore.refreshModList();
- }
+
+void MainWindow::restoreBackup_clicked()
+{
+ QRegExp backupRegEx("(.*)_backup[0-9]*$");
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(m_ContextRow);
+ if (backupRegEx.indexIn(modInfo->name()) != -1) {
+ QString regName = backupRegEx.cap(1);
+ QDir modDir(QDir::fromNativeSeparators(m_OrganizerCore.settings().getModDirectory()));
+ if (!modDir.exists(regName) ||
+ (QMessageBox::question(this, tr("Overwrite?"),
+ tr("This will replace the existing mod \"%1\". Continue?").arg(regName),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)) {
+ if (modDir.exists(regName) && !shellDelete(QStringList(modDir.absoluteFilePath(regName)))) {
+ reportError(tr("failed to remove mod \"%1\"").arg(regName));
+ } else {
+ QString destinationPath = QDir::fromNativeSeparators(m_OrganizerCore.settings().getModDirectory()) + "/" + regName;
+ if (!modDir.rename(modInfo->absolutePath(), destinationPath)) {
+ reportError(tr("failed to rename \"%1\" to \"%2\"").arg(modInfo->absolutePath()).arg(destinationPath));
}
+ m_OrganizerCore.refreshModList();
+ }
}
+ }
}
-void MainWindow::modlistChanged(const QModelIndex&, int) { m_OrganizerCore.currentProfile()->writeModlist(); }
+void MainWindow::modlistChanged(const QModelIndex&, int)
+{
+ m_OrganizerCore.currentProfile()->writeModlist();
+}
-void MainWindow::modlistSelectionChanged(const QModelIndex& current, const QModelIndex&) {
- if (current.isValid()) {
- ModInfo::Ptr selectedMod = ModInfo::getByIndex(current.data(Qt::UserRole + 1).toInt());
- m_OrganizerCore.modList()->setOverwriteMarkers(selectedMod->getModOverwrite(),
- selectedMod->getModOverwritten());
- } else {
- m_OrganizerCore.modList()->setOverwriteMarkers(std::set<unsigned int>(), std::set<unsigned int>());
- }
- /* if ((m_ModListSortProxy != nullptr)
- && !m_ModListSortProxy->beingInvalidated()) {
- m_ModListSortProxy->invalidate();
- }*/
- ui->modList->verticalScrollBar()->repaint();
+void MainWindow::modlistSelectionChanged(const QModelIndex &current, const QModelIndex&)
+{
+ if (current.isValid()) {
+ ModInfo::Ptr selectedMod = ModInfo::getByIndex(current.data(Qt::UserRole + 1).toInt());
+ m_OrganizerCore.modList()->setOverwriteMarkers(selectedMod->getModOverwrite(), selectedMod->getModOverwritten());
+ } else {
+ m_OrganizerCore.modList()->setOverwriteMarkers(std::set<unsigned int>(), std::set<unsigned int>());
+ }
+/* if ((m_ModListSortProxy != nullptr)
+ && !m_ModListSortProxy->beingInvalidated()) {
+ m_ModListSortProxy->invalidate();
+ }*/
+ ui->modList->verticalScrollBar()->repaint();
}
-void MainWindow::modlistSelectionsChanged(const QItemSelection& selected) {
- m_OrganizerCore.pluginList()->highlightPlugins(selected, *m_OrganizerCore.directoryStructure(),
- *m_OrganizerCore.currentProfile());
- ui->espList->verticalScrollBar()->repaint();
+void MainWindow::modlistSelectionsChanged(const QItemSelection &selected)
+{
+ m_OrganizerCore.pluginList()->highlightPlugins(selected, *m_OrganizerCore.directoryStructure(), *m_OrganizerCore.currentProfile());
+ ui->espList->verticalScrollBar()->repaint();
}
-void MainWindow::esplistSelectionsChanged(const QItemSelection& selected) {
- m_OrganizerCore.modList()->highlightMods(selected, *m_OrganizerCore.directoryStructure());
- ui->modList->verticalScrollBar()->repaint();
+void MainWindow::esplistSelectionsChanged(const QItemSelection &selected)
+{
+ m_OrganizerCore.modList()->highlightMods(selected, *m_OrganizerCore.directoryStructure());
+ ui->modList->verticalScrollBar()->repaint();
}
-void MainWindow::modListSortIndicatorChanged(int, Qt::SortOrder) { ui->modList->verticalScrollBar()->repaint(); }
+void MainWindow::modListSortIndicatorChanged(int, Qt::SortOrder)
+{
+ ui->modList->verticalScrollBar()->repaint();
+}
-void MainWindow::removeMod_clicked() {
- try {
- QItemSelectionModel* selection = ui->modList->selectionModel();
- if (selection->hasSelection() && selection->selectedRows().count() > 1) {
- QString mods;
- QStringList modNames;
- for (QModelIndex idx : selection->selectedRows()) {
- QString name = idx.data().toString();
- if (!ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt())->isRegular()) {
- continue;
- }
- mods += "<li>" + name + "</li>";
- modNames.append(name);
- }
- if (QMessageBox::question(this, tr("Confirm"), tr("Remove the following mods?<br><ul>%1</ul>").arg(mods),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- // use mod names instead of indexes because those become invalid during the removal
- for (QString name : modNames) {
- m_OrganizerCore.modList()->removeRowForce(ModInfo::getIndex(name), QModelIndex());
- }
- }
- } else {
- m_OrganizerCore.modList()->removeRow(m_ContextRow, QModelIndex());
+void MainWindow::removeMod_clicked()
+{
+ try {
+ QItemSelectionModel *selection = ui->modList->selectionModel();
+ if (selection->hasSelection() && selection->selectedRows().count() > 1) {
+ QString mods;
+ QStringList modNames;
+ for (QModelIndex idx : selection->selectedRows()) {
+ QString name = idx.data().toString();
+ if (!ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt())->isRegular()) {
+ continue;
}
- } catch (const std::exception& e) {
- reportError(tr("failed to remove mod: %1").arg(e.what()));
+ mods += "<li>" + name + "</li>";
+ modNames.append(name);
+ }
+ if (QMessageBox::question(this, tr("Confirm"),
+ tr("Remove the following mods?<br><ul>%1</ul>").arg(mods),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ // use mod names instead of indexes because those become invalid during the removal
+ for (QString name : modNames) {
+ m_OrganizerCore.modList()->removeRowForce(ModInfo::getIndex(name), QModelIndex());
+ }
+ }
+ } else {
+ m_OrganizerCore.modList()->removeRow(m_ContextRow, QModelIndex());
}
+ } catch (const std::exception &e) {
+ reportError(tr("failed to remove mod: %1").arg(e.what()));
+ }
}
-void MainWindow::modRemoved(const QString& fileName) {
- if (!fileName.isEmpty() && !QFileInfo(fileName).isAbsolute()) {
- int index = m_OrganizerCore.downloadManager()->indexByName(fileName);
- if (index >= 0) {
- m_OrganizerCore.downloadManager()->markUninstalled(index);
- }
+
+void MainWindow::modRemoved(const QString &fileName)
+{
+ if (!fileName.isEmpty() && !QFileInfo(fileName).isAbsolute()) {
+ int index = m_OrganizerCore.downloadManager()->indexByName(fileName);
+ if (index >= 0) {
+ m_OrganizerCore.downloadManager()->markUninstalled(index);
}
+ }
}
-void MainWindow::reinstallMod_clicked() {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(m_ContextRow);
- QString installationFile = modInfo->getInstallationFile();
- if (installationFile.length() != 0) {
- QString fullInstallationFile;
- QFileInfo fileInfo(installationFile);
- if (fileInfo.isAbsolute()) {
- if (fileInfo.exists()) {
- fullInstallationFile = installationFile;
- } else {
- fullInstallationFile =
- m_OrganizerCore.downloadManager()->getOutputDirectory() + "/" + fileInfo.fileName();
- }
- } else {
- fullInstallationFile = m_OrganizerCore.downloadManager()->getOutputDirectory() + "/" + installationFile;
- }
- if (QFile::exists(fullInstallationFile)) {
- m_OrganizerCore.installMod(fullInstallationFile, modInfo->name());
- } else {
- QMessageBox::information(this, tr("Failed"), tr("Installation file no longer exists"));
- }
+
+void MainWindow::reinstallMod_clicked()
+{
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(m_ContextRow);
+ QString installationFile = modInfo->getInstallationFile();
+ if (installationFile.length() != 0) {
+ QString fullInstallationFile;
+ QFileInfo fileInfo(installationFile);
+ if (fileInfo.isAbsolute()) {
+ if (fileInfo.exists()) {
+ fullInstallationFile = installationFile;
+ } else {
+ fullInstallationFile = m_OrganizerCore.downloadManager()->getOutputDirectory() + "/" + fileInfo.fileName();
+ }
} else {
- QMessageBox::information(this, tr("Failed"),
- tr("Mods installed with old versions of MO can't be reinstalled in this way."));
+ fullInstallationFile = m_OrganizerCore.downloadManager()->getOutputDirectory() + "/" + installationFile;
}
+ if (QFile::exists(fullInstallationFile)) {
+ m_OrganizerCore.installMod(fullInstallationFile, modInfo->name());
+ } else {
+ QMessageBox::information(this, tr("Failed"), tr("Installation file no longer exists"));
+ }
+ } else {
+ QMessageBox::information(this, tr("Failed"),
+ tr("Mods installed with old versions of MO can't be reinstalled in this way."));
+ }
}
-void MainWindow::resumeDownload(int downloadIndex) {
- if (NexusInterface::instance()->getAccessManager()->loggedIn()) {
- m_OrganizerCore.downloadManager()->resumeDownload(downloadIndex);
+
+void MainWindow::resumeDownload(int downloadIndex)
+{
+ if (NexusInterface::instance()->getAccessManager()->loggedIn()) {
+ m_OrganizerCore.downloadManager()->resumeDownload(downloadIndex);
+ } else {
+ QString username, password;
+ if (m_OrganizerCore.settings().getNexusLogin(username, password)) {
+ m_OrganizerCore.doAfterLogin([this, downloadIndex] () {
+ this->resumeDownload(downloadIndex);
+ });
+ NexusInterface::instance()->getAccessManager()->login(username, password);
} else {
- QString username, password;
- if (m_OrganizerCore.settings().getNexusLogin(username, password)) {
- m_OrganizerCore.doAfterLogin([this, downloadIndex]() { this->resumeDownload(downloadIndex); });
- NexusInterface::instance()->getAccessManager()->login(username, password);
- } else {
- MessageDialog::showMessage(tr("You need to be logged in with Nexus to resume a download"), this);
- }
+ MessageDialog::showMessage(tr("You need to be logged in with Nexus to resume a download"), this);
}
+ }
}
-void MainWindow::endorseMod(ModInfo::Ptr mod) {
- if (NexusInterface::instance()->getAccessManager()->loggedIn()) {
- mod->endorse(true);
+
+void MainWindow::endorseMod(ModInfo::Ptr mod)
+{
+ if (NexusInterface::instance()->getAccessManager()->loggedIn()) {
+ mod->endorse(true);
+ } else {
+ QString username, password;
+ if (m_OrganizerCore.settings().getNexusLogin(username, password)) {
+ m_OrganizerCore.doAfterLogin(boost::bind(&MainWindow::endorseMod, this, mod));
+ NexusInterface::instance()->getAccessManager()->login(username, password);
} else {
- QString username, password;
- if (m_OrganizerCore.settings().getNexusLogin(username, password)) {
- m_OrganizerCore.doAfterLogin(boost::bind(&MainWindow::endorseMod, this, mod));
- NexusInterface::instance()->getAccessManager()->login(username, password);
- } else {
- MessageDialog::showMessage(tr("You need to be logged in with Nexus to endorse"), this);
- }
+ MessageDialog::showMessage(tr("You need to be logged in with Nexus to endorse"), this);
}
+ }
}
-void MainWindow::endorse_clicked() { endorseMod(ModInfo::getByIndex(m_ContextRow)); }
-void MainWindow::dontendorse_clicked() { ModInfo::getByIndex(m_ContextRow)->setNeverEndorse(); }
+void MainWindow::endorse_clicked()
+{
+ endorseMod(ModInfo::getByIndex(m_ContextRow));
+}
-void MainWindow::unendorse_clicked() {
- QString username, password;
- if (NexusInterface::instance()->getAccessManager()->loggedIn()) {
- ModInfo::getByIndex(m_ContextRow)->endorse(false);
+void MainWindow::dontendorse_clicked()
+{
+ ModInfo::getByIndex(m_ContextRow)->setNeverEndorse();
+}
+
+
+void MainWindow::unendorse_clicked()
+{
+ QString username, password;
+ if (NexusInterface::instance()->getAccessManager()->loggedIn()) {
+ ModInfo::getByIndex(m_ContextRow)->endorse(false);
+ } else {
+ if (m_OrganizerCore.settings().getNexusLogin(username, password)) {
+ m_OrganizerCore.doAfterLogin([this] () { this->unendorse_clicked(); });
+ NexusInterface::instance()->getAccessManager()->login(username, password);
} else {
- if (m_OrganizerCore.settings().getNexusLogin(username, password)) {
- m_OrganizerCore.doAfterLogin([this]() { this->unendorse_clicked(); });
- NexusInterface::instance()->getAccessManager()->login(username, password);
- } else {
- MessageDialog::showMessage(tr("You need to be logged in with Nexus to endorse"), this);
- }
+ MessageDialog::showMessage(tr("You need to be logged in with Nexus to endorse"), this);
}
+ }
}
-void MainWindow::loginFailed(const QString& error) {
- qDebug("login failed: %s", qPrintable(error));
- statusBar()->hide();
+void MainWindow::loginFailed(const QString &error)
+{
+ qDebug("login failed: %s", qPrintable(error));
+ statusBar()->hide();
}
-void MainWindow::windowTutorialFinished(const QString& windowName) {
- m_OrganizerCore.settings().directInterface().setValue(QString("CompletedWindowTutorials/") + windowName, true);
+void MainWindow::windowTutorialFinished(const QString &windowName)
+{
+ m_OrganizerCore.settings().directInterface().setValue(QString("CompletedWindowTutorials/") + windowName, true);
}
-void MainWindow::overwriteClosed(int) {
- OverwriteInfoDialog* dialog = this->findChild<OverwriteInfoDialog*>("__overwriteDialog");
- if (dialog != nullptr) {
- m_OrganizerCore.modList()->modInfoChanged(dialog->modInfo());
- dialog->deleteLater();
- }
- m_OrganizerCore.refreshDirectoryStructure();
+void MainWindow::overwriteClosed(int)
+{
+ OverwriteInfoDialog *dialog = this->findChild<OverwriteInfoDialog*>("__overwriteDialog");
+ if (dialog != nullptr) {
+ m_OrganizerCore.modList()->modInfoChanged(dialog->modInfo());
+ dialog->deleteLater();
+ }
+ m_OrganizerCore.refreshDirectoryStructure();
}
-void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index, int tab) {
- if (!m_OrganizerCore.modList()->modInfoAboutToChange(modInfo)) {
- qDebug("A different mod information dialog is open. If this is incorrect, please restart MO");
- return;
+
+void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index, int tab)
+{
+ if (!m_OrganizerCore.modList()->modInfoAboutToChange(modInfo)) {
+ qDebug("A different mod information dialog is open. If this is incorrect, please restart MO");
+ return;
+ }
+ std::vector<ModInfo::EFlag> flags = modInfo->getFlags();
+ if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end()) {
+ QDialog *dialog = this->findChild<QDialog*>("__overwriteDialog");
+ try {
+ if (dialog == nullptr) {
+ dialog = new OverwriteInfoDialog(modInfo, this);
+ dialog->setObjectName("__overwriteDialog");
+ } else {
+ qobject_cast<OverwriteInfoDialog*>(dialog)->setModInfo(modInfo);
+ }
+ dialog->show();
+ dialog->raise();
+ dialog->activateWindow();
+ connect(dialog, SIGNAL(finished(int)), this, SLOT(overwriteClosed(int)));
+ } catch (const std::exception &e) {
+ reportError(tr("Failed to display overwrite dialog: %1").arg(e.what()));
}
- std::vector<ModInfo::EFlag> flags = modInfo->getFlags();
- if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end()) {
- QDialog* dialog = this->findChild<QDialog*>("__overwriteDialog");
- try {
- if (dialog == nullptr) {
- dialog = new OverwriteInfoDialog(modInfo, this);
- dialog->setObjectName("__overwriteDialog");
- } else {
- qobject_cast<OverwriteInfoDialog*>(dialog)->setModInfo(modInfo);
- }
- dialog->show();
- dialog->raise();
- dialog->activateWindow();
- connect(dialog, SIGNAL(finished(int)), this, SLOT(overwriteClosed(int)));
- } catch (const std::exception& e) {
- reportError(tr("Failed to display overwrite dialog: %1").arg(e.what()));
- }
- } else {
- modInfo->saveMeta();
- ModInfoDialog dialog(modInfo, m_OrganizerCore.directoryStructure(), modInfo->hasFlag(ModInfo::FLAG_FOREIGN),
- this);
- connect(&dialog, SIGNAL(nexusLinkActivated(QString)), this, SLOT(nexusLinkActivated(QString)));
- connect(&dialog, SIGNAL(downloadRequest(QString)), &m_OrganizerCore, SLOT(downloadRequestedNXM(QString)));
- connect(&dialog, SIGNAL(modOpen(QString, int)), this, SLOT(displayModInformation(QString, int)),
- Qt::QueuedConnection);
- connect(&dialog, SIGNAL(modOpenNext()), this, SLOT(modOpenNext()), Qt::QueuedConnection);
- connect(&dialog, SIGNAL(modOpenPrev()), this, SLOT(modOpenPrev()), Qt::QueuedConnection);
- connect(&dialog, SIGNAL(originModified(int)), this, SLOT(originModified(int)));
- connect(&dialog, SIGNAL(endorseMod(ModInfo::Ptr)), this, SLOT(endorseMod(ModInfo::Ptr)));
+ } else {
+ modInfo->saveMeta();
+ ModInfoDialog dialog(modInfo, m_OrganizerCore.directoryStructure(), modInfo->hasFlag(ModInfo::FLAG_FOREIGN), this);
+ connect(&dialog, SIGNAL(nexusLinkActivated(QString)), this, SLOT(nexusLinkActivated(QString)));
+ connect(&dialog, SIGNAL(downloadRequest(QString)), &m_OrganizerCore, SLOT(downloadRequestedNXM(QString)));
+ connect(&dialog, SIGNAL(modOpen(QString, int)), this, SLOT(displayModInformation(QString, int)), Qt::QueuedConnection);
+ connect(&dialog, SIGNAL(modOpenNext()), this, SLOT(modOpenNext()), Qt::QueuedConnection);
+ connect(&dialog, SIGNAL(modOpenPrev()), this, SLOT(modOpenPrev()), Qt::QueuedConnection);
+ connect(&dialog, SIGNAL(originModified(int)), this, SLOT(originModified(int)));
+ connect(&dialog, SIGNAL(endorseMod(ModInfo::Ptr)), this, SLOT(endorseMod(ModInfo::Ptr)));
- dialog.openTab(tab);
- dialog.restoreTabState(m_OrganizerCore.settings().directInterface().value("mod_info_tabs").toByteArray());
- dialog.exec();
- m_OrganizerCore.settings().directInterface().setValue("mod_info_tabs", dialog.saveTabState());
+ dialog.openTab(tab);
+ dialog.restoreTabState(m_OrganizerCore.settings().directInterface().value("mod_info_tabs").toByteArray());
+ dialog.exec();
+ m_OrganizerCore.settings().directInterface().setValue("mod_info_tabs", dialog.saveTabState());
- modInfo->saveMeta();
- emit modInfoDisplayed();
- m_OrganizerCore.modList()->modInfoChanged(modInfo);
- }
+ modInfo->saveMeta();
+ emit modInfoDisplayed();
+ m_OrganizerCore.modList()->modInfoChanged(modInfo);
+ }
- if (m_OrganizerCore.currentProfile()->modEnabled(index) && !modInfo->hasFlag(ModInfo::FLAG_FOREIGN)) {
- FilesOrigin& origin = m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(modInfo->name()));
- origin.enable(false);
+ if (m_OrganizerCore.currentProfile()->modEnabled(index)
+ && !modInfo->hasFlag(ModInfo::FLAG_FOREIGN)) {
+ FilesOrigin& origin = m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(modInfo->name()));
+ origin.enable(false);
- if (m_OrganizerCore.directoryStructure()->originExists(ToWString(modInfo->name()))) {
- FilesOrigin& origin = m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(modInfo->name()));
- origin.enable(false);
+ if (m_OrganizerCore.directoryStructure()->originExists(ToWString(modInfo->name()))) {
+ FilesOrigin& origin = m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(modInfo->name()));
+ origin.enable(false);
- m_OrganizerCore.directoryRefresher()->addModToStructure(
- m_OrganizerCore.directoryStructure(), modInfo->name(),
- m_OrganizerCore.currentProfile()->getModPriority(index), modInfo->absolutePath(), modInfo->stealFiles(),
- modInfo->archives());
- DirectoryRefresher::cleanStructure(m_OrganizerCore.directoryStructure());
- m_OrganizerCore.refreshLists();
- }
+ m_OrganizerCore.directoryRefresher()->addModToStructure(m_OrganizerCore.directoryStructure()
+ , modInfo->name()
+ , m_OrganizerCore.currentProfile()->getModPriority(index)
+ , modInfo->absolutePath()
+ , modInfo->stealFiles()
+ , modInfo->archives());
+ DirectoryRefresher::cleanStructure(m_OrganizerCore.directoryStructure());
+ m_OrganizerCore.refreshLists();
}
+ }
+}
+
+bool MainWindow::closeWindow()
+{
+ return close();
}
-bool MainWindow::closeWindow() { return close(); }
+void MainWindow::setWindowEnabled(bool enabled)
+{
+ setEnabled(enabled);
+}
-void MainWindow::setWindowEnabled(bool enabled) { setEnabled(enabled); }
-void MainWindow::modOpenNext() {
- QModelIndex index = m_ModListSortProxy->mapFromSource(m_OrganizerCore.modList()->index(m_ContextRow, 0));
- index = m_ModListSortProxy->index((index.row() + 1) % m_ModListSortProxy->rowCount(), 0);
+void MainWindow::modOpenNext()
+{
+ QModelIndex index = m_ModListSortProxy->mapFromSource(m_OrganizerCore.modList()->index(m_ContextRow, 0));
+ index = m_ModListSortProxy->index((index.row() + 1) % m_ModListSortProxy->rowCount(), 0);
- m_ContextRow = m_ModListSortProxy->mapToSource(index).row();
- ModInfo::Ptr mod = ModInfo::getByIndex(m_ContextRow);
- std::vector<ModInfo::EFlag> flags = mod->getFlags();
- if ((std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end()) ||
- (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP) != flags.end())) {
- // skip overwrite and backups
- modOpenNext();
- } else {
- displayModInformation(m_ContextRow);
- }
+ m_ContextRow = m_ModListSortProxy->mapToSource(index).row();
+ ModInfo::Ptr mod = ModInfo::getByIndex(m_ContextRow);
+ std::vector<ModInfo::EFlag> flags = mod->getFlags();
+ if ((std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end()) ||
+ (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP) != flags.end())) {
+ // skip overwrite and backups
+ modOpenNext();
+ } else {
+ displayModInformation(m_ContextRow);
+ }
}
-void MainWindow::modOpenPrev() {
- QModelIndex index = m_ModListSortProxy->mapFromSource(m_OrganizerCore.modList()->index(m_ContextRow, 0));
- int row = index.row() - 1;
- if (row == -1) {
- row = m_ModListSortProxy->rowCount() - 1;
- }
+void MainWindow::modOpenPrev()
+{
+ QModelIndex index = m_ModListSortProxy->mapFromSource(m_OrganizerCore.modList()->index(m_ContextRow, 0));
+ int row = index.row() - 1;
+ if (row == -1) {
+ row = m_ModListSortProxy->rowCount() - 1;
+ }
- m_ContextRow = m_ModListSortProxy->mapToSource(m_ModListSortProxy->index(row, 0)).row();
- ModInfo::Ptr mod = ModInfo::getByIndex(m_ContextRow);
- std::vector<ModInfo::EFlag> flags = mod->getFlags();
- if ((std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end()) ||
- (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP) != flags.end())) {
- // skip overwrite and backups
- modOpenPrev();
- } else {
- displayModInformation(m_ContextRow);
- }
+ m_ContextRow = m_ModListSortProxy->mapToSource(m_ModListSortProxy->index(row, 0)).row();
+ ModInfo::Ptr mod = ModInfo::getByIndex(m_ContextRow);
+ std::vector<ModInfo::EFlag> flags = mod->getFlags();
+ if ((std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end()) ||
+ (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP) != flags.end())) {
+ // skip overwrite and backups
+ modOpenPrev();
+ } else {
+ displayModInformation(m_ContextRow);
+ }
}
-void MainWindow::displayModInformation(const QString& modName, int tab) {
- unsigned int index = ModInfo::getIndex(modName);
- if (index == UINT_MAX) {
- qCritical("failed to resolve mod name %s", modName.toUtf8().constData());
- return;
- }
+void MainWindow::displayModInformation(const QString &modName, int tab)
+{
+ unsigned int index = ModInfo::getIndex(modName);
+ if (index == UINT_MAX) {
+ qCritical("failed to resolve mod name %s", modName.toUtf8().constData());
+ return;
+ }
- ModInfo::Ptr modInfo = ModInfo::getByIndex(index);
- displayModInformation(modInfo, index, tab);
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(index);
+ displayModInformation(modInfo, index, tab);
}
-void MainWindow::displayModInformation(int row, int tab) {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(row);
- displayModInformation(modInfo, row, tab);
+
+void MainWindow::displayModInformation(int row, int tab)
+{
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(row);
+ displayModInformation(modInfo, row, tab);
}
-void MainWindow::ignoreMissingData_clicked() {
- ModInfo::Ptr info = ModInfo::getByIndex(m_ContextRow);
- QDir(info->absolutePath()).mkdir("textures");
- info->testValid();
- connect(this, SIGNAL(modListDataChanged(QModelIndex, QModelIndex)), m_OrganizerCore.modList(),
- SIGNAL(dataChanged(QModelIndex, QModelIndex)));
- emit modListDataChanged(
- m_OrganizerCore.modList()->index(m_ContextRow, 0),
- m_OrganizerCore.modList()->index(m_ContextRow, m_OrganizerCore.modList()->columnCount() - 1));
+void MainWindow::ignoreMissingData_clicked()
+{
+ ModInfo::Ptr info = ModInfo::getByIndex(m_ContextRow);
+ QDir(info->absolutePath()).mkdir("textures");
+ info->testValid();
+ connect(this, SIGNAL(modListDataChanged(QModelIndex,QModelIndex)), m_OrganizerCore.modList(), SIGNAL(dataChanged(QModelIndex,QModelIndex)));
+
+ emit modListDataChanged(m_OrganizerCore.modList()->index(m_ContextRow, 0), m_OrganizerCore.modList()->index(m_ContextRow, m_OrganizerCore.modList()->columnCount() - 1));
}
-void MainWindow::visitOnNexus_clicked() {
- int modID =
- m_OrganizerCore.modList()->data(m_OrganizerCore.modList()->index(m_ContextRow, 0), Qt::UserRole).toInt();
- if (modID > 0) {
- nexusLinkActivated(NexusInterface::instance()->getModURL(modID));
- } else {
- MessageDialog::showMessage(tr("Nexus ID for this Mod is unknown"), this);
- }
+
+void MainWindow::visitOnNexus_clicked()
+{
+ int modID = m_OrganizerCore.modList()->data(m_OrganizerCore.modList()->index(m_ContextRow, 0), Qt::UserRole).toInt();
+ if (modID > 0) {
+ nexusLinkActivated(NexusInterface::instance()->getModURL(modID));
+ } else {
+ MessageDialog::showMessage(tr("Nexus ID for this Mod is unknown"), this);
+ }
}
-void MainWindow::visitWebPage_clicked() {
- ModInfo::Ptr info = ModInfo::getByIndex(m_ContextRow);
- if (info->getURL() != "") {
- linkClicked(info->getURL());
- } else {
- MessageDialog::showMessage(tr("Web page for this mod is unknown"), this);
- }
+void MainWindow::visitWebPage_clicked()
+{
+ ModInfo::Ptr info = ModInfo::getByIndex(m_ContextRow);
+ if (info->getURL() != "") {
+ linkClicked(info->getURL());
+ } else {
+ MessageDialog::showMessage(tr("Web page for this mod is unknown"), this);
+ }
}
-void MainWindow::openExplorer_clicked() {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(m_ContextRow);
+void MainWindow::openExplorer_clicked()
+{
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(m_ContextRow);
- ::ShellExecuteW(nullptr, L"explore", ToWString(modInfo->absolutePath()).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
+ ::ShellExecuteW(nullptr, L"explore", ToWString(modInfo->absolutePath()).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
}
-void MainWindow::information_clicked() {
- try {
- displayModInformation(m_ContextRow);
- } catch (const std::exception& e) {
- reportError(e.what());
- }
+void MainWindow::information_clicked()
+{
+ try {
+ displayModInformation(m_ContextRow);
+ } catch (const std::exception &e) {
+ reportError(e.what());
+ }
}
-void MainWindow::createEmptyMod_clicked() {
- GuessedValue<QString> name;
- name.setFilter(&fixDirectoryName);
+void MainWindow::createEmptyMod_clicked()
+{
+ GuessedValue<QString> name;
+ name.setFilter(&fixDirectoryName);
- while (name->isEmpty()) {
- bool ok;
- name.update(QInputDialog::getText(this, tr("Create Mod..."),
- tr("This will create an empty mod.\n"
- "Please enter a name:"),
- QLineEdit::Normal, "", &ok),
- GUESS_USER);
- if (!ok) {
- return;
- }
+ while (name->isEmpty()) {
+ bool ok;
+ name.update(QInputDialog::getText(this, tr("Create Mod..."),
+ tr("This will create an empty mod.\n"
+ "Please enter a name:"), QLineEdit::Normal, "", &ok),
+ GUESS_USER);
+ if (!ok) {
+ return;
}
+ }
- if (m_OrganizerCore.getMod(name) != nullptr) {
- reportError(tr("A mod with this name already exists"));
- return;
- }
+ if (m_OrganizerCore.getMod(name) != nullptr) {
+ reportError(tr("A mod with this name already exists"));
+ return;
+ }
- IModInterface* newMod = m_OrganizerCore.createMod(name);
- if (newMod == nullptr) {
- return;
- }
+ IModInterface *newMod = m_OrganizerCore.createMod(name);
+ if (newMod == nullptr) {
+ return;
+ }
- m_OrganizerCore.refreshModList();
+ m_OrganizerCore.refreshModList();
}
-void MainWindow::createModFromOverwrite() {
- GuessedValue<QString> name;
- name.setFilter(&fixDirectoryName);
+void MainWindow::createModFromOverwrite()
+{
+ GuessedValue<QString> name;
+ name.setFilter(&fixDirectoryName);
- while (name->isEmpty()) {
- bool ok;
- name.update(QInputDialog::getText(this, tr("Create Mod..."),
- tr("This will move all files from overwrite into a new, regular mod.\n"
- "Please enter a name:"),
- QLineEdit::Normal, "", &ok),
- GUESS_USER);
- if (!ok) {
- return;
- }
+ while (name->isEmpty()) {
+ bool ok;
+ name.update(QInputDialog::getText(this, tr("Create Mod..."),
+ tr("This will move all files from overwrite into a new, regular mod.\n"
+ "Please enter a name:"), QLineEdit::Normal, "", &ok),
+ GUESS_USER);
+ if (!ok) {
+ return;
}
+ }
- if (m_OrganizerCore.getMod(name) != nullptr) {
- reportError(tr("A mod with this name already exists"));
- return;
- }
+ if (m_OrganizerCore.getMod(name) != nullptr) {
+ reportError(tr("A mod with this name already exists"));
+ return;
+ }
- IModInterface* newMod = m_OrganizerCore.createMod(name);
- if (newMod == nullptr) {
- return;
- }
+ IModInterface *newMod = m_OrganizerCore.createMod(name);
+ if (newMod == nullptr) {
+ return;
+ }
- unsigned int overwriteIndex = ModInfo::findMod([](ModInfo::Ptr mod) -> bool {
- std::vector<ModInfo::EFlag> flags = mod->getFlags();
- return std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end();
- });
+ unsigned int overwriteIndex = ModInfo::findMod([](ModInfo::Ptr mod) -> bool {
+ std::vector<ModInfo::EFlag> flags = mod->getFlags();
+ return std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end(); });
- ModInfo::Ptr overwriteInfo = ModInfo::getByIndex(overwriteIndex);
- shellMove(QStringList(QDir::toNativeSeparators(overwriteInfo->absolutePath()) + "\\*"),
- QStringList(QDir::toNativeSeparators(newMod->absolutePath())), this);
+ ModInfo::Ptr overwriteInfo = ModInfo::getByIndex(overwriteIndex);
+ shellMove(QStringList(QDir::toNativeSeparators(overwriteInfo->absolutePath()) + "\\*"),
+ QStringList(QDir::toNativeSeparators(newMod->absolutePath())), this);
- m_OrganizerCore.refreshModList();
+ m_OrganizerCore.refreshModList();
}
-void MainWindow::clearOverwrite() {
- unsigned int overwriteIndex = ModInfo::findMod([](ModInfo::Ptr mod) -> bool {
- std::vector<ModInfo::EFlag> flags = mod->getFlags();
- return std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end();
- });
+void MainWindow::clearOverwrite()
+{
+ unsigned int overwriteIndex = ModInfo::findMod([](ModInfo::Ptr mod) -> bool {
+ std::vector<ModInfo::EFlag> flags = mod->getFlags();
+ return std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE)
+ != flags.end();
+ });
- ModInfo::Ptr modInfo = ModInfo::getByIndex(overwriteIndex);
- if (modInfo) {
- QDir overwriteDir(modInfo->absolutePath());
- if (QMessageBox::question(this, tr("Are you sure?"),
- tr("About to recursively delete:\n") + overwriteDir.absolutePath(),
- QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
- QStringList delList;
- for (auto f : overwriteDir.entryList(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot))
- delList.push_back(overwriteDir.absoluteFilePath(f));
- shellDelete(delList, true);
- updateProblemsButton();
- }
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(overwriteIndex);
+ if (modInfo)
+ {
+ QDir overwriteDir(modInfo->absolutePath());
+ if (QMessageBox::question(this, tr("Are you sure?"),
+ tr("About to recursively delete:\n") + overwriteDir.absolutePath(),
+ QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok)
+ {
+ QStringList delList;
+ for (auto f : overwriteDir.entryList(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot))
+ delList.push_back(overwriteDir.absoluteFilePath(f));
+ shellDelete(delList, true);
+ updateProblemsButton();
}
+ }
}
-void MainWindow::cancelModListEditor() {
- ui->modList->setEnabled(false);
- ui->modList->setEnabled(true);
+void MainWindow::cancelModListEditor()
+{
+ ui->modList->setEnabled(false);
+ ui->modList->setEnabled(true);
}
-void MainWindow::on_modList_doubleClicked(const QModelIndex& index) {
- if (!index.isValid()) {
- return;
- }
+void MainWindow::on_modList_doubleClicked(const QModelIndex &index)
+{
+ if (!index.isValid()) {
+ return;
+ }
- if (m_OrganizerCore.modList()->timeElapsedSinceLastChecked() <= QApplication::doubleClickInterval()) {
- // don't interpret double click if we only just checked a mod
- return;
- }
+ if (m_OrganizerCore.modList()->timeElapsedSinceLastChecked() <= QApplication::doubleClickInterval()) {
+ // don't interpret double click if we only just checked a mod
+ return;
+ }
- QModelIndex sourceIdx = mapToModel(m_OrganizerCore.modList(), index);
- if (!sourceIdx.isValid()) {
- return;
- }
+ QModelIndex sourceIdx = mapToModel(m_OrganizerCore.modList(), index);
+ if (!sourceIdx.isValid()) {
+ return;
+ }
- try {
- m_ContextRow = m_ModListSortProxy->mapToSource(index).row();
- displayModInformation(sourceIdx.row());
- // workaround to cancel the editor that might have opened because of
- // selection-click
- ui->modList->closePersistentEditor(index);
- } catch (const std::exception& e) {
- reportError(e.what());
- }
+ try {
+ m_ContextRow = m_ModListSortProxy->mapToSource(index).row();
+ displayModInformation(sourceIdx.row());
+ // workaround to cancel the editor that might have opened because of
+ // selection-click
+ ui->modList->closePersistentEditor(index);
+ } catch (const std::exception &e) {
+ reportError(e.what());
+ }
}
-bool MainWindow::populateMenuCategories(QMenu* menu, int targetID) {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(m_ContextRow);
- const std::set<int>& categories = modInfo->getCategories();
+bool MainWindow::populateMenuCategories(QMenu *menu, int targetID)
+{
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(m_ContextRow);
+ const std::set<int> &categories = modInfo->getCategories();
- bool childEnabled = false;
+ bool childEnabled = false;
- for (unsigned int i = 1; i < m_CategoryFactory.numCategories(); ++i) {
- if (m_CategoryFactory.getParentID(i) == targetID) {
- QMenu* targetMenu = menu;
- if (m_CategoryFactory.hasChildren(i)) {
- targetMenu = menu->addMenu(m_CategoryFactory.getCategoryName(i).replace('&', "&&"));
- }
+ for (unsigned int i = 1; i < m_CategoryFactory.numCategories(); ++i) {
+ if (m_CategoryFactory.getParentID(i) == targetID) {
+ QMenu *targetMenu = menu;
+ if (m_CategoryFactory.hasChildren(i)) {
+ targetMenu = menu->addMenu(m_CategoryFactory.getCategoryName(i).replace('&', "&&"));
+ }
- int id = m_CategoryFactory.getCategoryID(i);
- QScopedPointer<QCheckBox> checkBox(new QCheckBox(targetMenu));
- bool enabled = categories.find(id) != categories.end();
- checkBox->setText(m_CategoryFactory.getCategoryName(i).replace('&', "&&"));
- if (enabled) {
- childEnabled = true;
- }
- checkBox->setChecked(enabled ? Qt::Checked : Qt::Unchecked);
+ int id = m_CategoryFactory.getCategoryID(i);
+ QScopedPointer<QCheckBox> checkBox(new QCheckBox(targetMenu));
+ bool enabled = categories.find(id) != categories.end();
+ checkBox->setText(m_CategoryFactory.getCategoryName(i).replace('&', "&&"));
+ if (enabled) {
+ childEnabled = true;
+ }
+ checkBox->setChecked(enabled ? Qt::Checked : Qt::Unchecked);
- QScopedPointer<QWidgetAction> checkableAction(new QWidgetAction(targetMenu));
- checkableAction->setDefaultWidget(checkBox.take());
- checkableAction->setData(id);
- targetMenu->addAction(checkableAction.take());
+ QScopedPointer<QWidgetAction> checkableAction(new QWidgetAction(targetMenu));
+ checkableAction->setDefaultWidget(checkBox.take());
+ checkableAction->setData(id);
+ targetMenu->addAction(checkableAction.take());
- if (m_CategoryFactory.hasChildren(i)) {
- if (populateMenuCategories(targetMenu, m_CategoryFactory.getCategoryID(i)) || enabled) {
- targetMenu->setIcon(QIcon(":/MO/gui/resources/check.png"));
- }
- }
+ if (m_CategoryFactory.hasChildren(i)) {
+ if (populateMenuCategories(targetMenu, m_CategoryFactory.getCategoryID(i)) || enabled) {
+ targetMenu->setIcon(QIcon(":/MO/gui/resources/check.png"));
}
+ }
}
- return childEnabled;
+ }
+ return childEnabled;
}
-void MainWindow::replaceCategoriesFromMenu(QMenu* menu, int modRow) {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(modRow);
- for (QAction* action : menu->actions()) {
- if (action->menu() != nullptr) {
- replaceCategoriesFromMenu(action->menu(), modRow);
- } else {
- QWidgetAction* widgetAction = qobject_cast<QWidgetAction*>(action);
- if (widgetAction != nullptr) {
- QCheckBox* checkbox = qobject_cast<QCheckBox*>(widgetAction->defaultWidget());
- modInfo->setCategory(widgetAction->data().toInt(), checkbox->isChecked());
- }
- }
+void MainWindow::replaceCategoriesFromMenu(QMenu *menu, int modRow)
+{
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(modRow);
+ for (QAction* action : menu->actions()) {
+ if (action->menu() != nullptr) {
+ replaceCategoriesFromMenu(action->menu(), modRow);
+ } else {
+ QWidgetAction *widgetAction = qobject_cast<QWidgetAction*>(action);
+ if (widgetAction != nullptr) {
+ QCheckBox *checkbox = qobject_cast<QCheckBox*>(widgetAction->defaultWidget());
+ modInfo->setCategory(widgetAction->data().toInt(), checkbox->isChecked());
+ }
}
+ }
}
-void MainWindow::addRemoveCategoriesFromMenu(QMenu* menu, int modRow, int referenceRow) {
- if (referenceRow != -1 && referenceRow != modRow) {
- ModInfo::Ptr editedModInfo = ModInfo::getByIndex(referenceRow);
- for (QAction* action : menu->actions()) {
- if (action->menu() != nullptr) {
- addRemoveCategoriesFromMenu(action->menu(), modRow, referenceRow);
- } else {
- QWidgetAction* widgetAction = qobject_cast<QWidgetAction*>(action);
- if (widgetAction != nullptr) {
- QCheckBox* checkbox = qobject_cast<QCheckBox*>(widgetAction->defaultWidget());
- int categoryId = widgetAction->data().toInt();
- bool checkedBefore = editedModInfo->categorySet(categoryId);
- bool checkedAfter = checkbox->isChecked();
+void MainWindow::addRemoveCategoriesFromMenu(QMenu *menu, int modRow, int referenceRow)
+{
+ if (referenceRow != -1 && referenceRow != modRow) {
+ ModInfo::Ptr editedModInfo = ModInfo::getByIndex(referenceRow);
+ for (QAction* action : menu->actions()) {
+ if (action->menu() != nullptr) {
+ addRemoveCategoriesFromMenu(action->menu(), modRow, referenceRow);
+ } else {
+ QWidgetAction *widgetAction = qobject_cast<QWidgetAction*>(action);
+ if (widgetAction != nullptr) {
+ QCheckBox *checkbox = qobject_cast<QCheckBox*>(widgetAction->defaultWidget());
+ int categoryId = widgetAction->data().toInt();
+ bool checkedBefore = editedModInfo->categorySet(categoryId);
+ bool checkedAfter = checkbox->isChecked();
- if (checkedBefore != checkedAfter) { // only update if the category was changed on the edited mod
- ModInfo::Ptr currentModInfo = ModInfo::getByIndex(modRow);
- currentModInfo->setCategory(categoryId, checkedAfter);
- }
- }
- }
+ if (checkedBefore != checkedAfter) { // only update if the category was changed on the edited mod
+ ModInfo::Ptr currentModInfo = ModInfo::getByIndex(modRow);
+ currentModInfo->setCategory(categoryId, checkedAfter);
+ }
}
- } else {
- replaceCategoriesFromMenu(menu, modRow);
+ }
}
+ } else {
+ replaceCategoriesFromMenu(menu, modRow);
+ }
}
void MainWindow::addRemoveCategories_MenuHandler() {
- QMenu* menu = qobject_cast<QMenu*>(sender());
- if (menu == nullptr) {
- qCritical("not a menu?");
- return;
- }
+ QMenu *menu = qobject_cast<QMenu*>(sender());
+ if (menu == nullptr) {
+ qCritical("not a menu?");
+ return;
+ }
- QList<QPersistentModelIndex> selected;
- for (const QModelIndex& idx : ui->modList->selectionModel()->selectedRows()) {
- selected.append(QPersistentModelIndex(idx));
- }
+ QList<QPersistentModelIndex> selected;
+ for (const QModelIndex &idx : ui->modList->selectionModel()->selectedRows()) {
+ selected.append(QPersistentModelIndex(idx));
+ }
- if (selected.size() > 0) {
- int minRow = INT_MAX;
- int maxRow = -1;
+ if (selected.size() > 0) {
+ int minRow = INT_MAX;
+ int maxRow = -1;
- for (const QPersistentModelIndex& idx : selected) {
- qDebug("change categories on: %s", qPrintable(idx.data().toString()));
- QModelIndex modIdx = mapToModel(m_OrganizerCore.modList(), idx);
- if (modIdx.row() != m_ContextIdx.row()) {
- addRemoveCategoriesFromMenu(menu, modIdx.row(), m_ContextIdx.row());
- }
- if (idx.row() < minRow)
- minRow = idx.row();
- if (idx.row() > maxRow)
- maxRow = idx.row();
- }
- replaceCategoriesFromMenu(menu, m_ContextIdx.row());
+ for (const QPersistentModelIndex &idx : selected) {
+ qDebug("change categories on: %s", qPrintable(idx.data().toString()));
+ QModelIndex modIdx = mapToModel(m_OrganizerCore.modList(), idx);
+ if (modIdx.row() != m_ContextIdx.row()) {
+ addRemoveCategoriesFromMenu(menu, modIdx.row(), m_ContextIdx.row());
+ }
+ if (idx.row() < minRow) minRow = idx.row();
+ if (idx.row() > maxRow) maxRow = idx.row();
+ }
+ replaceCategoriesFromMenu(menu, m_ContextIdx.row());
- m_OrganizerCore.modList()->notifyChange(minRow, maxRow + 1);
+ m_OrganizerCore.modList()->notifyChange(minRow, maxRow + 1);
- for (const QPersistentModelIndex& idx : selected) {
- ui->modList->selectionModel()->select(idx, QItemSelectionModel::Select | QItemSelectionModel::Rows);
- }
- } else {
- // For single mod selections, just do a replace
- replaceCategoriesFromMenu(menu, m_ContextRow);
- m_OrganizerCore.modList()->notifyChange(m_ContextRow);
+ for (const QPersistentModelIndex &idx : selected) {
+ ui->modList->selectionModel()->select(idx, QItemSelectionModel::Select | QItemSelectionModel::Rows);
}
+ } else {
+ //For single mod selections, just do a replace
+ replaceCategoriesFromMenu(menu, m_ContextRow);
+ m_OrganizerCore.modList()->notifyChange(m_ContextRow);
+ }
- refreshFilters();
+ refreshFilters();
}
void MainWindow::replaceCategories_MenuHandler() {
- QMenu* menu = qobject_cast<QMenu*>(sender());
- if (menu == nullptr) {
- qCritical("not a menu?");
- return;
- }
+ QMenu *menu = qobject_cast<QMenu*>(sender());
+ if (menu == nullptr) {
+ qCritical("not a menu?");
+ return;
+ }
- QList<QPersistentModelIndex> selected;
- for (const QModelIndex& idx : ui->modList->selectionModel()->selectedRows()) {
- selected.append(QPersistentModelIndex(idx));
- }
+ QList<QPersistentModelIndex> selected;
+ for (const QModelIndex &idx : ui->modList->selectionModel()->selectedRows()) {
+ selected.append(QPersistentModelIndex(idx));
+ }
- if (selected.size() > 0) {
- QStringList selectedMods;
- int minRow = INT_MAX;
- int maxRow = -1;
- for (int i = 0; i < selected.size(); ++i) {
- QModelIndex temp = mapToModel(m_OrganizerCore.modList(), selected.at(i));
- selectedMods.append(temp.data().toString());
- replaceCategoriesFromMenu(menu, mapToModel(m_OrganizerCore.modList(), selected.at(i)).row());
- if (temp.row() < minRow)
- minRow = temp.row();
- if (temp.row() > maxRow)
- maxRow = temp.row();
- }
+ if (selected.size() > 0) {
+ QStringList selectedMods;
+ int minRow = INT_MAX;
+ int maxRow = -1;
+ for (int i = 0; i < selected.size(); ++i) {
+ QModelIndex temp = mapToModel(m_OrganizerCore.modList(), selected.at(i));
+ selectedMods.append(temp.data().toString());
+ replaceCategoriesFromMenu(menu, mapToModel(m_OrganizerCore.modList(), selected.at(i)).row());
+ if (temp.row() < minRow) minRow = temp.row();
+ if (temp.row() > maxRow) maxRow = temp.row();
+ }
- m_OrganizerCore.modList()->notifyChange(minRow, maxRow + 1);
+ m_OrganizerCore.modList()->notifyChange(minRow, maxRow + 1);
- // find mods by their name because indices are invalidated
- QAbstractItemModel* model = ui->modList->model();
- for (const QString& mod : selectedMods) {
- QModelIndexList matches = model->match(model->index(0, 0), Qt::DisplayRole, mod, 1,
- Qt::MatchFixedString | Qt::MatchCaseSensitive | Qt::MatchRecursive);
- if (matches.size() > 0) {
- ui->modList->selectionModel()->select(matches.at(0),
- QItemSelectionModel::Select | QItemSelectionModel::Rows);
- }
- }
- } else {
- // For single mod selections, just do a replace
- replaceCategoriesFromMenu(menu, m_ContextRow);
- m_OrganizerCore.modList()->notifyChange(m_ContextRow);
+ // find mods by their name because indices are invalidated
+ QAbstractItemModel *model = ui->modList->model();
+ for (const QString &mod : selectedMods) {
+ QModelIndexList matches = model->match(model->index(0, 0), Qt::DisplayRole, mod, 1,
+ Qt::MatchFixedString | Qt::MatchCaseSensitive | Qt::MatchRecursive);
+ if (matches.size() > 0) {
+ ui->modList->selectionModel()->select(matches.at(0), QItemSelectionModel::Select | QItemSelectionModel::Rows);
+ }
}
+ } else {
+ //For single mod selections, just do a replace
+ replaceCategoriesFromMenu(menu, m_ContextRow);
+ m_OrganizerCore.modList()->notifyChange(m_ContextRow);
+ }
- refreshFilters();
+ refreshFilters();
}
-void MainWindow::saveArchiveList() {
- if (m_OrganizerCore.isArchivesInit()) {
- SafeWriteFile archiveFile(m_OrganizerCore.currentProfile()->getArchivesFileName());
- for (int i = 0; i < ui->bsaList->topLevelItemCount(); ++i) {
- QTreeWidgetItem* tlItem = ui->bsaList->topLevelItem(i);
- for (int j = 0; j < tlItem->childCount(); ++j) {
- QTreeWidgetItem* item = tlItem->child(j);
- if (item->checkState(0) == Qt::Checked) {
- archiveFile->write(item->text(0).toUtf8().append("\r\n"));
- }
- }
+void MainWindow::saveArchiveList()
+{
+ if (m_OrganizerCore.isArchivesInit()) {
+ SafeWriteFile archiveFile(m_OrganizerCore.currentProfile()->getArchivesFileName());
+ for (int i = 0; i < ui->bsaList->topLevelItemCount(); ++i) {
+ QTreeWidgetItem * tlItem = ui->bsaList->topLevelItem(i);
+ for (int j = 0; j < tlItem->childCount(); ++j) {
+ QTreeWidgetItem * item = tlItem->child(j);
+ if (item->checkState(0) == Qt::Checked) {
+ archiveFile->write(item->text(0).toUtf8().append("\r\n"));
}
- if (archiveFile.commitIfDifferent(m_ArchiveListHash)) {
- qDebug("%s saved",
- qPrintable(QDir::toNativeSeparators(m_OrganizerCore.currentProfile()->getArchivesFileName())));
- }
- } else {
- qWarning("archive list not initialised");
+ }
}
+ if (archiveFile.commitIfDifferent(m_ArchiveListHash)) {
+ qDebug("%s saved", qPrintable(QDir::toNativeSeparators(m_OrganizerCore.currentProfile()->getArchivesFileName())));
+ }
+ } else {
+ qWarning("archive list not initialised");
+ }
}
-void MainWindow::checkModsForUpdates() {
- statusBar()->show();
- if (NexusInterface::instance()->getAccessManager()->loggedIn()) {
- m_ModsToUpdate = ModInfo::checkAllForUpdate(this);
- m_RefreshProgress->setRange(0, m_ModsToUpdate);
- } else {
- QString username, password;
- if (m_OrganizerCore.settings().getNexusLogin(username, password)) {
- m_OrganizerCore.doAfterLogin([this]() { this->checkModsForUpdates(); });
- NexusInterface::instance()->getAccessManager()->login(username, password);
- } else { // otherwise there will be no endorsement info
- MessageDialog::showMessage(tr("Not logged in, endorsement information will be wrong"), this, true);
- m_ModsToUpdate = ModInfo::checkAllForUpdate(this);
- }
+void MainWindow::checkModsForUpdates()
+{
+ statusBar()->show();
+ if (NexusInterface::instance()->getAccessManager()->loggedIn()) {
+ m_ModsToUpdate = ModInfo::checkAllForUpdate(this);
+ m_RefreshProgress->setRange(0, m_ModsToUpdate);
+ } else {
+ QString username, password;
+ if (m_OrganizerCore.settings().getNexusLogin(username, password)) {
+ m_OrganizerCore.doAfterLogin([this] () { this->checkModsForUpdates(); });
+ NexusInterface::instance()->getAccessManager()->login(username, password);
+ } else { // otherwise there will be no endorsement info
+ MessageDialog::showMessage(tr("Not logged in, endorsement information will be wrong"),
+ this, true);
+ m_ModsToUpdate = ModInfo::checkAllForUpdate(this);
}
+ }
}
void MainWindow::changeVersioningScheme() {
- if (QMessageBox::question(this, tr("Continue?"),
- tr("The versioning scheme decides which version is considered newer than another.\n"
- "This function will guess the versioning scheme under the assumption that the "
- "installed version is outdated."),
- QMessageBox::Yes | QMessageBox::Cancel) == QMessageBox::Yes) {
+ if (QMessageBox::question(this, tr("Continue?"),
+ tr("The versioning scheme decides which version is considered newer than another.\n"
+ "This function will guess the versioning scheme under the assumption that the installed version is outdated."),
+ QMessageBox::Yes | QMessageBox::Cancel) == QMessageBox::Yes) {
- ModInfo::Ptr info = ModInfo::getByIndex(m_ContextRow);
+ ModInfo::Ptr info = ModInfo::getByIndex(m_ContextRow);
- bool success = false;
+ bool success = false;
- static VersionInfo::VersionScheme schemes[] = {VersionInfo::SCHEME_REGULAR, VersionInfo::SCHEME_DECIMALMARK,
- VersionInfo::SCHEME_NUMBERSANDLETTERS};
+ static VersionInfo::VersionScheme schemes[] = { VersionInfo::SCHEME_REGULAR, VersionInfo::SCHEME_DECIMALMARK, VersionInfo::SCHEME_NUMBERSANDLETTERS };
- for (int i = 0; i < sizeof(schemes) / sizeof(VersionInfo::VersionScheme) && !success; ++i) {
- VersionInfo verOld(info->getVersion().canonicalString(), schemes[i]);
- VersionInfo verNew(info->getNewestVersion().canonicalString(), schemes[i]);
- if (verOld < verNew) {
- info->setVersion(verOld);
- info->setNewestVersion(verNew);
- success = true;
- }
- }
- if (!success) {
- QMessageBox::information(this, tr("Sorry"),
- tr("I don't know a versioning scheme where %1 is newer than %2.")
- .arg(info->getNewestVersion().canonicalString())
- .arg(info->getVersion().canonicalString()),
- QMessageBox::Ok);
- }
+ for (int i = 0; i < sizeof(schemes) / sizeof(VersionInfo::VersionScheme) && !success; ++i) {
+ VersionInfo verOld(info->getVersion().canonicalString(), schemes[i]);
+ VersionInfo verNew(info->getNewestVersion().canonicalString(), schemes[i]);
+ if (verOld < verNew) {
+ info->setVersion(verOld);
+ info->setNewestVersion(verNew);
+ success = true;
+ }
}
+ if (!success) {
+ QMessageBox::information(this, tr("Sorry"),
+ tr("I don't know a versioning scheme where %1 is newer than %2.").arg(info->getNewestVersion().canonicalString()).arg(info->getVersion().canonicalString()),
+ QMessageBox::Ok);
+ }
+ }
}
void MainWindow::ignoreUpdate() {
- ModInfo::Ptr info = ModInfo::getByIndex(m_ContextRow);
- info->ignoreUpdate(true);
+ ModInfo::Ptr info = ModInfo::getByIndex(m_ContextRow);
+ info->ignoreUpdate(true);
}
-void MainWindow::unignoreUpdate() {
- ModInfo::Ptr info = ModInfo::getByIndex(m_ContextRow);
- info->ignoreUpdate(false);
+void MainWindow::unignoreUpdate()
+{
+ ModInfo::Ptr info = ModInfo::getByIndex(m_ContextRow);
+ info->ignoreUpdate(false);
}
-void MainWindow::addPrimaryCategoryCandidates(QMenu* primaryCategoryMenu, ModInfo::Ptr info) {
- const std::set<int>& categories = info->getCategories();
- for (int categoryID : categories) {
- int catIdx = m_CategoryFactory.getCategoryIndex(categoryID);
- QWidgetAction* action = new QWidgetAction(primaryCategoryMenu);
- try {
- QRadioButton* categoryBox =
- new QRadioButton(m_CategoryFactory.getCategoryName(catIdx).replace('&', "&&"), primaryCategoryMenu);
- connect(categoryBox, &QRadioButton::toggled, [info, categoryID](bool enable) {
- if (enable) {
- info->setPrimaryCategory(categoryID);
- }
- });
- categoryBox->setChecked(categoryID == info->getPrimaryCategory());
- action->setDefaultWidget(categoryBox);
- } catch (const std::exception& e) {
- qCritical("failed to create category checkbox: %s", e.what());
+void MainWindow::addPrimaryCategoryCandidates(QMenu *primaryCategoryMenu,
+ ModInfo::Ptr info) {
+ const std::set<int> &categories = info->getCategories();
+ for (int categoryID : categories) {
+ int catIdx = m_CategoryFactory.getCategoryIndex(categoryID);
+ QWidgetAction *action = new QWidgetAction(primaryCategoryMenu);
+ try {
+ QRadioButton *categoryBox = new QRadioButton(
+ m_CategoryFactory.getCategoryName(catIdx).replace('&', "&&"),
+ primaryCategoryMenu);
+ connect(categoryBox, &QRadioButton::toggled, [info, categoryID](bool enable) {
+ if (enable) {
+ info->setPrimaryCategory(categoryID);
}
-
- action->setData(categoryID);
- primaryCategoryMenu->addAction(action);
+ });
+ categoryBox->setChecked(categoryID == info->getPrimaryCategory());
+ action->setDefaultWidget(categoryBox);
+ } catch (const std::exception &e) {
+ qCritical("failed to create category checkbox: %s", e.what());
}
+
+ action->setData(categoryID);
+ primaryCategoryMenu->addAction(action);
+ }
}
-void MainWindow::addPrimaryCategoryCandidates() {
- QMenu* menu = qobject_cast<QMenu*>(sender());
- if (menu == nullptr) {
- qCritical("not a menu?");
- return;
- }
- menu->clear();
- ModInfo::Ptr modInfo = ModInfo::getByIndex(m_ContextRow);
+void MainWindow::addPrimaryCategoryCandidates()
+{
+ QMenu *menu = qobject_cast<QMenu*>(sender());
+ if (menu == nullptr) {
+ qCritical("not a menu?");
+ return;
+ }
+ menu->clear();
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(m_ContextRow);
- addPrimaryCategoryCandidates(menu, modInfo);
+ addPrimaryCategoryCandidates(menu, modInfo);
}
-void MainWindow::enableVisibleMods() {
- if (QMessageBox::question(nullptr, tr("Confirm"), tr("Really enable all visible mods?"),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- m_ModListSortProxy->enableAllVisible();
- }
+void MainWindow::enableVisibleMods()
+{
+ if (QMessageBox::question(nullptr, tr("Confirm"), tr("Really enable all visible mods?"),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ m_ModListSortProxy->enableAllVisible();
+ }
}
-void MainWindow::disableVisibleMods() {
- if (QMessageBox::question(nullptr, tr("Confirm"), tr("Really disable all visible mods?"),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- m_ModListSortProxy->disableAllVisible();
- }
+void MainWindow::disableVisibleMods()
+{
+ if (QMessageBox::question(nullptr, tr("Confirm"), tr("Really disable all visible mods?"),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ m_ModListSortProxy->disableAllVisible();
+ }
}
-void MainWindow::openInstanceFolder() {
- ::ShellExecuteW(nullptr, L"explore", ToWString(m_OrganizerCore.settings().getBaseDirectory()).c_str(), nullptr,
- nullptr, SW_SHOWNORMAL);
+void MainWindow::openInstanceFolder()
+{
+ ::ShellExecuteW(nullptr, L"explore", ToWString(m_OrganizerCore.settings().getBaseDirectory()).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
}
-void MainWindow::openProfileFolder() {
- ::ShellExecuteW(nullptr, L"explore", ToWString(m_OrganizerCore.currentProfile()->absolutePath()).c_str(), nullptr,
- nullptr, SW_SHOWNORMAL);
+void MainWindow::openProfileFolder()
+{
+ ::ShellExecuteW(nullptr, L"explore", ToWString(m_OrganizerCore.currentProfile()->absolutePath()).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
}
-void MainWindow::openDownloadsFolder() {
- ::ShellExecuteW(nullptr, L"explore", ToWString(m_OrganizerCore.settings().getDownloadDirectory()).c_str(), nullptr,
- nullptr, SW_SHOWNORMAL);
+void MainWindow::openDownloadsFolder()
+{
+ ::ShellExecuteW(nullptr, L"explore", ToWString(m_OrganizerCore.settings().getDownloadDirectory()).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
}
-void MainWindow::openGameFolder() {
- ::ShellExecuteW(nullptr, L"explore",
- ToWString(m_OrganizerCore.managedGame()->gameDirectory().absolutePath()).c_str(), nullptr, nullptr,
- SW_SHOWNORMAL);
+void MainWindow::openGameFolder()
+{
+ ::ShellExecuteW(nullptr, L"explore", ToWString(m_OrganizerCore.managedGame()->gameDirectory().absolutePath()).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
}
-void MainWindow::openMyGamesFolder() {
- ::ShellExecuteW(nullptr, L"explore",
- ToWString(m_OrganizerCore.managedGame()->documentsDirectory().absolutePath()).c_str(), nullptr,
- nullptr, SW_SHOWNORMAL);
+void MainWindow::openMyGamesFolder()
+{
+ ::ShellExecuteW(nullptr, L"explore", ToWString(m_OrganizerCore.managedGame()->documentsDirectory().absolutePath()).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
}
-void MainWindow::exportModListCSV() {
- // SelectionDialog selection(tr("Choose what to export"));
- // selection.addChoice(tr("Everything"), tr("All installed mods are included in the list"), 0);
- // selection.addChoice(tr("Active Mods"), tr("Only active (checked) mods from your current profile are included"),
- // 1); selection.addChoice(tr("Visible"), tr("All mods visible in the mod list are included"), 2);
+void MainWindow::exportModListCSV()
+{
+ //SelectionDialog selection(tr("Choose what to export"));
- QDialog selection(this);
- QGridLayout* grid = new QGridLayout;
- selection.setWindowTitle(tr("Export to csv"));
+ //selection.addChoice(tr("Everything"), tr("All installed mods are included in the list"), 0);
+ //selection.addChoice(tr("Active Mods"), tr("Only active (checked) mods from your current profile are included"), 1);
+ //selection.addChoice(tr("Visible"), tr("All mods visible in the mod list are included"), 2);
- QGroupBox* groupBoxRows = new QGroupBox(tr("Select what mods you want export:"));
- QRadioButton* all = new QRadioButton(tr("All installed mods"));
- QRadioButton* active = new QRadioButton(tr("Only active (checked) mods from your current profile"));
- QRadioButton* visible = new QRadioButton(tr("All currently visible mods in the mod list"));
+ QDialog selection(this);
+ QGridLayout *grid = new QGridLayout;
+ selection.setWindowTitle(tr("Export to csv"));
- QVBoxLayout* vbox = new QVBoxLayout;
- vbox->addWidget(all);
- vbox->addWidget(active);
- vbox->addWidget(visible);
- vbox->addStretch(1);
- groupBoxRows->setLayout(vbox);
+ QGroupBox *groupBoxRows = new QGroupBox(tr("Select what mods you want export:"));
+ QRadioButton *all = new QRadioButton(tr("All installed mods"));
+ QRadioButton *active = new QRadioButton(tr("Only active (checked) mods from your current profile"));
+ QRadioButton *visible = new QRadioButton(tr("All currently visible mods in the mod list"));
- grid->addWidget(groupBoxRows);
+ QVBoxLayout *vbox = new QVBoxLayout;
+ vbox->addWidget(all);
+ vbox->addWidget(active);
+ vbox->addWidget(visible);
+ vbox->addStretch(1);
+ groupBoxRows->setLayout(vbox);
- QButtonGroup* buttonGroupRows = new QButtonGroup();
- buttonGroupRows->addButton(all, 0);
- buttonGroupRows->addButton(active, 1);
- buttonGroupRows->addButton(visible, 2);
- buttonGroupRows->button(0)->setChecked(true);
- QGroupBox* groupBoxColumns = new QGroupBox(tr("Choose what Columns to export:"));
- groupBoxColumns->setFlat(true);
- QCheckBox* mod_Priority = new QCheckBox(tr("Mod_Priority"));
- mod_Priority->setChecked(true);
- QCheckBox* mod_Name = new QCheckBox(tr("Mod_Name"));
- mod_Name->setChecked(true);
- QCheckBox* mod_Status = new QCheckBox(tr("Mod_Status"));
- QCheckBox* primary_Category = new QCheckBox(tr("Primary_Category"));
- QCheckBox* nexus_ID = new QCheckBox(tr("Nexus_ID"));
- QCheckBox* mod_Nexus_URL = new QCheckBox(tr("Mod_Nexus_URL"));
- QCheckBox* mod_Version = new QCheckBox(tr("Mod_Version"));
- QCheckBox* install_Date = new QCheckBox(tr("Install_Date"));
- QCheckBox* download_File_Name = new QCheckBox(tr("Download_File_Name"));
+ grid->addWidget(groupBoxRows);
- QVBoxLayout* vbox1 = new QVBoxLayout;
- vbox1->addWidget(mod_Priority);
- vbox1->addWidget(mod_Name);
- vbox1->addWidget(mod_Status);
- vbox1->addWidget(primary_Category);
- vbox1->addWidget(nexus_ID);
- vbox1->addWidget(mod_Nexus_URL);
- vbox1->addWidget(mod_Version);
- vbox1->addWidget(install_Date);
- vbox1->addWidget(download_File_Name);
- groupBoxColumns->setLayout(vbox1);
+ QButtonGroup *buttonGroupRows = new QButtonGroup();
+ buttonGroupRows->addButton(all, 0);
+ buttonGroupRows->addButton(active, 1);
+ buttonGroupRows->addButton(visible, 2);
+ buttonGroupRows->button(0)->setChecked(true);
- grid->addWidget(groupBoxColumns);
- QPushButton* ok = new QPushButton("Ok");
- QPushButton* cancel = new QPushButton("Cancel");
- QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
- connect(buttons, SIGNAL(accepted()), &selection, SLOT(accept()));
- connect(buttons, SIGNAL(rejected()), &selection, SLOT(reject()));
+ QGroupBox *groupBoxColumns = new QGroupBox(tr("Choose what Columns to export:"));
+ groupBoxColumns->setFlat(true);
- grid->addWidget(buttons);
+ QCheckBox *mod_Priority = new QCheckBox(tr("Mod_Priority"));
+ mod_Priority->setChecked(true);
+ QCheckBox *mod_Name = new QCheckBox(tr("Mod_Name"));
+ mod_Name->setChecked(true);
+ QCheckBox *mod_Status = new QCheckBox(tr("Mod_Status"));
+ QCheckBox *primary_Category = new QCheckBox(tr("Primary_Category"));
+ QCheckBox *nexus_ID = new QCheckBox(tr("Nexus_ID"));
+ QCheckBox *mod_Nexus_URL = new QCheckBox(tr("Mod_Nexus_URL"));
+ QCheckBox *mod_Version = new QCheckBox(tr("Mod_Version"));
+ QCheckBox *install_Date = new QCheckBox(tr("Install_Date"));
+ QCheckBox *download_File_Name = new QCheckBox(tr("Download_File_Name"));
- selection.setLayout(grid);
+ QVBoxLayout *vbox1 = new QVBoxLayout;
+ vbox1->addWidget(mod_Priority);
+ vbox1->addWidget(mod_Name);
+ vbox1->addWidget(mod_Status);
+ vbox1->addWidget(primary_Category);
+ vbox1->addWidget(nexus_ID);
+ vbox1->addWidget(mod_Nexus_URL);
+ vbox1->addWidget(mod_Version);
+ vbox1->addWidget(install_Date);
+ vbox1->addWidget(download_File_Name);
+ groupBoxColumns->setLayout(vbox1);
- if (selection.exec() == QDialog::Accepted) {
+ grid->addWidget(groupBoxColumns);
- unsigned int numMods = ModInfo::getNumMods();
- int selectedRowID = buttonGroupRows->checkedId();
+ QPushButton *ok = new QPushButton("Ok");
+ QPushButton *cancel = new QPushButton("Cancel");
+ QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
- try {
- QBuffer buffer;
- buffer.open(QIODevice::ReadWrite);
- CSVBuilder builder(&buffer);
- builder.setEscapeMode(CSVBuilder::TYPE_STRING, CSVBuilder::QUOTE_ALWAYS);
- std::vector<std::pair<QString, CSVBuilder::EFieldType>> fields;
- if (mod_Priority->isChecked())
- fields.push_back(std::make_pair(QString("#Mod_Priority"), CSVBuilder::TYPE_STRING));
- if (mod_Name->isChecked())
- fields.push_back(std::make_pair(QString("#Mod_Name"), CSVBuilder::TYPE_STRING));
- if (mod_Status->isChecked())
- fields.push_back(std::make_pair(QString("#Mod_Status"), CSVBuilder::TYPE_STRING));
- if (primary_Category->isChecked())
- fields.push_back(std::make_pair(QString("#Primary_Category"), CSVBuilder::TYPE_STRING));
- if (nexus_ID->isChecked())
- fields.push_back(std::make_pair(QString("#Nexus_ID"), CSVBuilder::TYPE_INTEGER));
- if (mod_Nexus_URL->isChecked())
- fields.push_back(std::make_pair(QString("#Mod_Nexus_URL"), CSVBuilder::TYPE_STRING));
- if (mod_Version->isChecked())
- fields.push_back(std::make_pair(QString("#Mod_Version"), CSVBuilder::TYPE_STRING));
- if (install_Date->isChecked())
- fields.push_back(std::make_pair(QString("#Install_Date"), CSVBuilder::TYPE_STRING));
- if (download_File_Name->isChecked())
- fields.push_back(std::make_pair(QString("#Download_File_Name"), CSVBuilder::TYPE_STRING));
+ connect(buttons, SIGNAL(accepted()), &selection, SLOT(accept()));
+ connect(buttons, SIGNAL(rejected()), &selection, SLOT(reject()));
- builder.setFields(fields);
+ grid->addWidget(buttons);
- builder.writeHeader();
+ selection.setLayout(grid);
- for (unsigned int i = 0; i < numMods; ++i) {
- ModInfo::Ptr info = ModInfo::getByIndex(i);
- bool enabled = m_OrganizerCore.currentProfile()->modEnabled(i);
- if ((selectedRowID == 1) && !enabled) {
- continue;
- } else if ((selectedRowID == 2) && !m_ModListSortProxy->filterMatchesMod(info, enabled)) {
- continue;
- }
- std::vector<ModInfo::EFlag> flags = info->getFlags();
- if ((std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) == flags.end()) &&
- (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP) == flags.end())) {
- if (mod_Priority->isChecked())
- builder.setRowField(
- "#Mod_Priority",
- QString("%1").arg(m_OrganizerCore.currentProfile()->getModPriority(i), 4, 10, QChar('0')));
- if (mod_Name->isChecked())
- builder.setRowField("#Mod_Name", info->name());
- if (mod_Status->isChecked())
- builder.setRowField("#Mod_Status", (enabled) ? "Enabled" : "Disabled");
- if (primary_Category->isChecked())
- builder.setRowField("#Primary_Category",
- (m_CategoryFactory.categoryExists(info->getPrimaryCategory()))
- ? m_CategoryFactory.getCategoryName(info->getPrimaryCategory())
- : "");
- if (nexus_ID->isChecked())
- builder.setRowField("#Nexus_ID", info->getNexusID());
- if (mod_Nexus_URL->isChecked())
- builder.setRowField("#Mod_Nexus_URL", info->getURL());
- if (mod_Version->isChecked())
- builder.setRowField("#Mod_Version", info->getVersion().canonicalString());
- if (install_Date->isChecked())
- builder.setRowField("#Install_Date", info->creationTime().toString("yyyy/MM/dd HH:mm:ss"));
- if (download_File_Name->isChecked())
- builder.setRowField("#Download_File_Name", info->getInstallationFile());
- builder.writeRow();
- }
- }
+ if (selection.exec() == QDialog::Accepted) {
- SaveTextAsDialog saveDialog(this);
- saveDialog.setText(buffer.data());
- saveDialog.exec();
- } catch (const std::exception& e) {
- reportError(tr("export failed: %1").arg(e.what()));
- }
- }
-}
+ unsigned int numMods = ModInfo::getNumMods();
+ int selectedRowID = buttonGroupRows->checkedId();
+
+ try {
+ QBuffer buffer;
+ buffer.open(QIODevice::ReadWrite);
+ CSVBuilder builder(&buffer);
+ builder.setEscapeMode(CSVBuilder::TYPE_STRING, CSVBuilder::QUOTE_ALWAYS);
+ std::vector<std::pair<QString, CSVBuilder::EFieldType> > fields;
+ if (mod_Priority->isChecked())
+ fields.push_back(std::make_pair(QString("#Mod_Priority"), CSVBuilder::TYPE_STRING));
+ if (mod_Name->isChecked())
+ fields.push_back(std::make_pair(QString("#Mod_Name"), CSVBuilder::TYPE_STRING));
+ if (mod_Status->isChecked())
+ fields.push_back(std::make_pair(QString("#Mod_Status"), CSVBuilder::TYPE_STRING));
+ if (primary_Category->isChecked())
+ fields.push_back(std::make_pair(QString("#Primary_Category"), CSVBuilder::TYPE_STRING));
+ if (nexus_ID->isChecked())
+ fields.push_back(std::make_pair(QString("#Nexus_ID"), CSVBuilder::TYPE_INTEGER));
+ if (mod_Nexus_URL->isChecked())
+ fields.push_back(std::make_pair(QString("#Mod_Nexus_URL"), CSVBuilder::TYPE_STRING));
+ if (mod_Version->isChecked())
+ fields.push_back(std::make_pair(QString("#Mod_Version"), CSVBuilder::TYPE_STRING));
+ if (install_Date->isChecked())
+ fields.push_back(std::make_pair(QString("#Install_Date"), CSVBuilder::TYPE_STRING));
+ if (download_File_Name->isChecked())
+ fields.push_back(std::make_pair(QString("#Download_File_Name"), CSVBuilder::TYPE_STRING));
+
+ builder.setFields(fields);
-static void addMenuAsPushButton(QMenu* menu, QMenu* subMenu) {
- QPushButton* pushBtn = new QPushButton(subMenu->title());
- pushBtn->setMenu(subMenu);
- QWidgetAction* action = new QWidgetAction(menu);
- action->setDefaultWidget(pushBtn);
- menu->addAction(action);
+ builder.writeHeader();
+
+ for (unsigned int i = 0; i < numMods; ++i) {
+ ModInfo::Ptr info = ModInfo::getByIndex(i);
+ bool enabled = m_OrganizerCore.currentProfile()->modEnabled(i);
+ if ((selectedRowID == 1) && !enabled) {
+ continue;
+ }
+ else if ((selectedRowID == 2) && !m_ModListSortProxy->filterMatchesMod(info, enabled)) {
+ continue;
+ }
+ std::vector<ModInfo::EFlag> flags = info->getFlags();
+ if ((std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) == flags.end()) &&
+ (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP) == flags.end())) {
+ if (mod_Priority->isChecked())
+ builder.setRowField("#Mod_Priority", QString("%1").arg(m_OrganizerCore.currentProfile()->getModPriority(i), 4, 10, QChar('0')));
+ if (mod_Name->isChecked())
+ builder.setRowField("#Mod_Name", info->name());
+ if (mod_Status->isChecked())
+ builder.setRowField("#Mod_Status", (enabled)? "Enabled" : "Disabled");
+ if (primary_Category->isChecked())
+ builder.setRowField("#Primary_Category", (m_CategoryFactory.categoryExists(info->getPrimaryCategory())) ? m_CategoryFactory.getCategoryName(info->getPrimaryCategory()) : "");
+ if (nexus_ID->isChecked())
+ builder.setRowField("#Nexus_ID", info->getNexusID());
+ if (mod_Nexus_URL->isChecked())
+ builder.setRowField("#Mod_Nexus_URL", info->getURL());
+ if (mod_Version->isChecked())
+ builder.setRowField("#Mod_Version", info->getVersion().canonicalString());
+ if (install_Date->isChecked())
+ builder.setRowField("#Install_Date", info->creationTime().toString("yyyy/MM/dd HH:mm:ss"));
+ if (download_File_Name->isChecked())
+ builder.setRowField("#Download_File_Name", info->getInstallationFile());
+
+ builder.writeRow();
+ }
+ }
+
+ SaveTextAsDialog saveDialog(this);
+ saveDialog.setText(buffer.data());
+ saveDialog.exec();
+ }
+ catch (const std::exception &e) {
+ reportError(tr("export failed: %1").arg(e.what()));
+ }
+ }
}
-QMenu* MainWindow::modListContextMenu() {
- QMenu* menu = new QMenu(this);
- menu->addAction(tr("Install Mod..."), this, SLOT(installMod_clicked()));
+static void addMenuAsPushButton(QMenu *menu, QMenu *subMenu)
+{
+ QPushButton *pushBtn = new QPushButton(subMenu->title());
+ pushBtn->setMenu(subMenu);
+ QWidgetAction *action = new QWidgetAction(menu);
+ action->setDefaultWidget(pushBtn);
+ menu->addAction(action);
+}
- menu->addAction(tr("Create empty mod"), this, SLOT(createEmptyMod_clicked()));
+QMenu *MainWindow::modListContextMenu()
+{
+ QMenu *menu = new QMenu(this);
+ menu->addAction(tr("Install Mod..."), this, SLOT(installMod_clicked()));
- menu->addSeparator();
+ menu->addAction(tr("Create empty mod"), this, SLOT(createEmptyMod_clicked()));
- menu->addAction(tr("Enable all visible"), this, SLOT(enableVisibleMods()));
- menu->addAction(tr("Disable all visible"), this, SLOT(disableVisibleMods()));
+ menu->addSeparator();
- menu->addAction(tr("Check all for update"), this, SLOT(checkModsForUpdates()));
+ menu->addAction(tr("Enable all visible"), this, SLOT(enableVisibleMods()));
+ menu->addAction(tr("Disable all visible"), this, SLOT(disableVisibleMods()));
- menu->addAction(tr("Refresh"), &m_OrganizerCore, SLOT(profileRefresh()));
+ menu->addAction(tr("Check all for update"), this, SLOT(checkModsForUpdates()));
- menu->addAction(tr("Export to csv..."), this, SLOT(exportModListCSV()));
+ menu->addAction(tr("Refresh"), &m_OrganizerCore, SLOT(profileRefresh()));
- menu->addSeparator();
+ menu->addAction(tr("Export to csv..."), this, SLOT(exportModListCSV()));
- QMenu* openSubMenu = new QMenu(this);
+ menu->addSeparator();
- openSubMenu->addAction(tr("Open Instance folder"), this, SLOT(openInstanceFolder()));
+ QMenu *openSubMenu = new QMenu(this);
- openSubMenu->addAction(tr("Open Profile folder"), this, SLOT(openProfileFolder()));
- openSubMenu->addAction(tr("Open Downloads folder"), this, SLOT(openDownloadsFolder()));
+ openSubMenu->addAction(tr("Open Instance folder"), this, SLOT(openInstanceFolder()));
- openSubMenu->addAction(tr("Open Game folder"), this, SLOT(openGameFolder()));
+ openSubMenu->addAction(tr("Open Profile folder"), this, SLOT(openProfileFolder()));
- openSubMenu->addAction(tr("Open MyGames folder"), this, SLOT(openMyGamesFolder()));
+ openSubMenu->addAction(tr("Open Downloads folder"), this, SLOT(openDownloadsFolder()));
- openSubMenu->setTitle(tr("Open Folder..."));
+ openSubMenu->addAction(tr("Open Game folder"), this, SLOT(openGameFolder()));
- menu->addMenu(openSubMenu);
+ openSubMenu->addAction(tr("Open MyGames folder"), this, SLOT(openMyGamesFolder()));
- return menu;
-}
+ openSubMenu->setTitle(tr("Open Folder..."));
-void MainWindow::on_modList_customContextMenuRequested(const QPoint& pos) {
- try {
- QTreeView* modList = findChild<QTreeView*>("modList");
+ menu->addMenu(openSubMenu);
- m_ContextIdx = mapToModel(m_OrganizerCore.modList(), modList->indexAt(pos));
- m_ContextRow = m_ContextIdx.row();
+ return menu;
+}
- QMenu* menu = nullptr;
- QMenu* allMods = modListContextMenu();
- if (m_ContextRow == -1) {
- // no selection
- menu = allMods;
- } else {
- menu = new QMenu(this);
- allMods->setTitle(tr("All Mods"));
- menu->addMenu(allMods);
- ModInfo::Ptr info = ModInfo::getByIndex(m_ContextRow);
- std::vector<ModInfo::EFlag> flags = info->getFlags();
- if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end()) {
- if (QDir(info->absolutePath()).count() > 2) {
- menu->addAction(tr("Sync to Mods..."), &m_OrganizerCore, SLOT(syncOverwrite()));
- menu->addAction(tr("Create Mod..."), this, SLOT(createModFromOverwrite()));
- menu->addAction(tr("Clear Overwrite..."), this, SLOT(clearOverwrite()));
- }
- menu->addAction(tr("Open in explorer"), this, SLOT(openExplorer_clicked()));
- } else if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP) != flags.end()) {
- menu->addAction(tr("Restore Backup"), this, SLOT(restoreBackup_clicked()));
- menu->addAction(tr("Remove Backup..."), this, SLOT(removeMod_clicked()));
- } else if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_FOREIGN) != flags.end()) {
- // nop, nothing to do with this mod
- } else {
- QMenu* addRemoveCategoriesMenu = new QMenu(tr("Add/Remove Categories"));
- populateMenuCategories(addRemoveCategoriesMenu, 0);
- connect(addRemoveCategoriesMenu, SIGNAL(aboutToHide()), this, SLOT(addRemoveCategories_MenuHandler()));
- addMenuAsPushButton(menu, addRemoveCategoriesMenu);
+void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos)
+{
+ try {
+ QTreeView *modList = findChild<QTreeView*>("modList");
- QMenu* replaceCategoriesMenu = new QMenu(tr("Replace Categories"));
- populateMenuCategories(replaceCategoriesMenu, 0);
- connect(replaceCategoriesMenu, SIGNAL(aboutToHide()), this, SLOT(replaceCategories_MenuHandler()));
- addMenuAsPushButton(menu, replaceCategoriesMenu);
+ m_ContextIdx = mapToModel(m_OrganizerCore.modList(), modList->indexAt(pos));
+ m_ContextRow = m_ContextIdx.row();
- QMenu* primaryCategoryMenu = new QMenu(tr("Primary Category"));
- connect(primaryCategoryMenu, SIGNAL(aboutToShow()), this, SLOT(addPrimaryCategoryCandidates()));
- addMenuAsPushButton(menu, primaryCategoryMenu);
+ QMenu *menu = nullptr;
+ QMenu *allMods = modListContextMenu();
+ if (m_ContextRow == -1) {
+ // no selection
+ menu = allMods;
+ } else {
+ menu = new QMenu(this);
+ allMods->setTitle(tr("All Mods"));
+ menu->addMenu(allMods);
+ ModInfo::Ptr info = ModInfo::getByIndex(m_ContextRow);
+ std::vector<ModInfo::EFlag> flags = info->getFlags();
+ if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end()) {
+ if (QDir(info->absolutePath()).count() > 2) {
+ menu->addAction(tr("Sync to Mods..."), &m_OrganizerCore, SLOT(syncOverwrite()));
+ menu->addAction(tr("Create Mod..."), this, SLOT(createModFromOverwrite()));
+ menu->addAction(tr("Clear Overwrite..."), this, SLOT(clearOverwrite()));
+ }
+ menu->addAction(tr("Open in explorer"), this, SLOT(openExplorer_clicked()));
+ } else if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP) != flags.end()) {
+ menu->addAction(tr("Restore Backup"), this, SLOT(restoreBackup_clicked()));
+ menu->addAction(tr("Remove Backup..."), this, SLOT(removeMod_clicked()));
+ } else if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_FOREIGN) != flags.end()) {
+ // nop, nothing to do with this mod
+ } else {
+ QMenu *addRemoveCategoriesMenu = new QMenu(tr("Add/Remove Categories"));
+ populateMenuCategories(addRemoveCategoriesMenu, 0);
+ connect(addRemoveCategoriesMenu, SIGNAL(aboutToHide()), this, SLOT(addRemoveCategories_MenuHandler()));
+ addMenuAsPushButton(menu, addRemoveCategoriesMenu);
- menu->addSeparator();
- if (info->downgradeAvailable()) {
- menu->addAction(tr("Change versioning scheme"), this, SLOT(changeVersioningScheme()));
- }
- if (info->updateAvailable() || info->downgradeAvailable()) {
- if (info->updateIgnored()) {
- menu->addAction(tr("Un-ignore update"), this, SLOT(unignoreUpdate()));
- } else {
- menu->addAction(tr("Ignore update"), this, SLOT(ignoreUpdate()));
- }
- }
- menu->addSeparator();
+ QMenu *replaceCategoriesMenu = new QMenu(tr("Replace Categories"));
+ populateMenuCategories(replaceCategoriesMenu, 0);
+ connect(replaceCategoriesMenu, SIGNAL(aboutToHide()), this, SLOT(replaceCategories_MenuHandler()));
+ addMenuAsPushButton(menu, replaceCategoriesMenu);
- menu->addAction(tr("Rename Mod..."), this, SLOT(renameMod_clicked()));
- menu->addAction(tr("Remove Mod..."), this, SLOT(removeMod_clicked()));
- menu->addAction(tr("Reinstall Mod"), this, SLOT(reinstallMod_clicked()));
+ QMenu *primaryCategoryMenu = new QMenu(tr("Primary Category"));
+ connect(primaryCategoryMenu, SIGNAL(aboutToShow()), this, SLOT(addPrimaryCategoryCandidates()));
+ addMenuAsPushButton(menu, primaryCategoryMenu);
- menu->addSeparator();
+ menu->addSeparator();
+ if (info->downgradeAvailable()) {
+ menu->addAction(tr("Change versioning scheme"), this, SLOT(changeVersioningScheme()));
+ }
+ if (info->updateAvailable() || info->downgradeAvailable()) {
+ if (info->updateIgnored()) {
+ menu->addAction(tr("Un-ignore update"), this, SLOT(unignoreUpdate()));
+ } else {
+ menu->addAction(tr("Ignore update"), this, SLOT(ignoreUpdate()));
+ }
+ }
+ menu->addSeparator();
- if (info->getNexusID() > 0) {
- switch (info->endorsedState()) {
- case ModInfo::ENDORSED_TRUE: {
- menu->addAction(tr("Un-Endorse"), this, SLOT(unendorse_clicked()));
- } break;
- case ModInfo::ENDORSED_FALSE: {
- menu->addAction(tr("Endorse"), this, SLOT(endorse_clicked()));
- menu->addAction(tr("Won't endorse"), this, SLOT(dontendorse_clicked()));
- } break;
- case ModInfo::ENDORSED_NEVER: {
- menu->addAction(tr("Endorse"), this, SLOT(endorse_clicked()));
- } break;
- default: {
- QAction* action = new QAction(tr("Endorsement state unknown"), menu);
- action->setEnabled(false);
- menu->addAction(action);
- } break;
- }
- }
+ menu->addAction(tr("Rename Mod..."), this, SLOT(renameMod_clicked()));
+ menu->addAction(tr("Remove Mod..."), this, SLOT(removeMod_clicked()));
+ menu->addAction(tr("Reinstall Mod"), this, SLOT(reinstallMod_clicked()));
- menu->addSeparator();
+ menu->addSeparator();
- std::vector<ModInfo::EFlag> flags = info->getFlags();
- if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_INVALID) != flags.end()) {
- menu->addAction(tr("Ignore missing data"), this, SLOT(ignoreMissingData_clicked()));
- }
+ if (info->getNexusID() > 0) {
+ switch (info->endorsedState()) {
+ case ModInfo::ENDORSED_TRUE: {
+ menu->addAction(tr("Un-Endorse"), this, SLOT(unendorse_clicked()));
+ } break;
+ case ModInfo::ENDORSED_FALSE: {
+ menu->addAction(tr("Endorse"), this, SLOT(endorse_clicked()));
+ menu->addAction(tr("Won't endorse"), this, SLOT(dontendorse_clicked()));
+ } break;
+ case ModInfo::ENDORSED_NEVER: {
+ menu->addAction(tr("Endorse"), this, SLOT(endorse_clicked()));
+ } break;
+ default: {
+ QAction *action = new QAction(tr("Endorsement state unknown"), menu);
+ action->setEnabled(false);
+ menu->addAction(action);
+ } break;
+ }
+ }
- if (info->getNexusID() > 0) {
- menu->addAction(tr("Visit on Nexus"), this, SLOT(visitOnNexus_clicked()));
- } else if ((info->getURL() != "")) {
- menu->addAction(tr("Visit web page"), this, SLOT(visitWebPage_clicked()));
- }
+ menu->addSeparator();
- menu->addAction(tr("Open in explorer"), this, SLOT(openExplorer_clicked()));
- }
+ std::vector<ModInfo::EFlag> flags = info->getFlags();
+ if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_INVALID) != flags.end()) {
+ menu->addAction(tr("Ignore missing data"), this, SLOT(ignoreMissingData_clicked()));
+ }
- if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_FOREIGN) == flags.end()) {
- QAction* infoAction = menu->addAction(tr("Information..."), this, SLOT(information_clicked()));
- menu->setDefaultAction(infoAction);
- }
+ if (info->getNexusID() > 0) {
+ menu->addAction(tr("Visit on Nexus"), this, SLOT(visitOnNexus_clicked()));
+ } else if ((info->getURL() != "")) {
+ menu->addAction(tr("Visit web page"), this, SLOT(visitWebPage_clicked()));
}
- menu->exec(modList->mapToGlobal(pos));
- } catch (const std::exception& e) {
- reportError(tr("Exception: ").arg(e.what()));
- } catch (...) {
- reportError(tr("Unknown exception"));
+ menu->addAction(tr("Open in explorer"), this, SLOT(openExplorer_clicked()));
+ }
+
+ if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_FOREIGN) == flags.end()) {
+ QAction *infoAction = menu->addAction(tr("Information..."), this, SLOT(information_clicked()));
+ menu->setDefaultAction(infoAction);
+ }
}
+
+ menu->exec(modList->mapToGlobal(pos));
+ } catch (const std::exception &e) {
+ reportError(tr("Exception: ").arg(e.what()));
+ } catch (...) {
+ reportError(tr("Unknown exception"));
+ }
}
-void MainWindow::on_categoriesList_itemSelectionChanged() {
- QModelIndexList indices = ui->categoriesList->selectionModel()->selectedRows();
- std::vector<int> categories;
- std::vector<int> content;
- for (const QModelIndex& index : indices) {
- int filterType = index.data(Qt::UserRole + 1).toInt();
- if ((filterType == ModListSortProxy::TYPE_CATEGORY) || (filterType == ModListSortProxy::TYPE_SPECIAL)) {
- int categoryId = index.data(Qt::UserRole).toInt();
- if (categoryId != CategoryFactory::CATEGORY_NONE) {
- categories.push_back(categoryId);
- }
- } else if (filterType == ModListSortProxy::TYPE_CONTENT) {
- int contentId = index.data(Qt::UserRole).toInt();
- content.push_back(contentId);
- }
+
+void MainWindow::on_categoriesList_itemSelectionChanged()
+{
+ QModelIndexList indices = ui->categoriesList->selectionModel()->selectedRows();
+ std::vector<int> categories;
+ std::vector<int> content;
+ for (const QModelIndex &index : indices) {
+ int filterType = index.data(Qt::UserRole + 1).toInt();
+ if ((filterType == ModListSortProxy::TYPE_CATEGORY)
+ || (filterType == ModListSortProxy::TYPE_SPECIAL)) {
+ int categoryId = index.data(Qt::UserRole).toInt();
+ if (categoryId != CategoryFactory::CATEGORY_NONE) {
+ categories.push_back(categoryId);
+ }
+ } else if (filterType == ModListSortProxy::TYPE_CONTENT) {
+ int contentId = index.data(Qt::UserRole).toInt();
+ content.push_back(contentId);
}
+ }
- m_ModListSortProxy->setCategoryFilter(categories);
- m_ModListSortProxy->setContentFilter(content);
- ui->clickBlankButton->setEnabled(categories.size() > 0 || content.size() > 0);
- // ui->clearFiltersButton->setStyleSheet("border:5px solid #ff0000;");
- ui->clearFiltersButton->setVisible(categories.size() > 0 || content.size() > 0);
+ m_ModListSortProxy->setCategoryFilter(categories);
+ m_ModListSortProxy->setContentFilter(content);
+ ui->clickBlankButton->setEnabled(categories.size() > 0 || content.size() >0);
+ //ui->clearFiltersButton->setStyleSheet("border:5px solid #ff0000;");
+ ui->clearFiltersButton->setVisible(categories.size() > 0 || content.size() > 0);
- if (indices.count() == 0) {
- ui->currentCategoryLabel->setText(QString("(%1)").arg(tr("<All>")));
- } else if (indices.count() > 1) {
- ui->currentCategoryLabel->setText(QString("(%1)").arg(tr("<Multiple>")));
- } else {
- ui->currentCategoryLabel->setText(QString("(%1)").arg(indices.first().data().toString()));
- }
- ui->modList->reset();
+ if (indices.count() == 0) {
+ ui->currentCategoryLabel->setText(QString("(%1)").arg(tr("<All>")));
+ } else if (indices.count() > 1) {
+ ui->currentCategoryLabel->setText(QString("(%1)").arg(tr("<Multiple>")));
+ } else {
+ ui->currentCategoryLabel->setText(QString("(%1)").arg(indices.first().data().toString()));
+ }
+ ui->modList->reset();
}
-void MainWindow::deleteSavegame_clicked() {
- SaveGameInfo const* info = m_OrganizerCore.managedGame()->feature<SaveGameInfo>();
- QString savesMsgLabel;
- QStringList deleteFiles;
+void MainWindow::deleteSavegame_clicked()
+{
+ SaveGameInfo const *info = m_OrganizerCore.managedGame()->feature<SaveGameInfo>();
- int count = 0;
+ QString savesMsgLabel;
+ QStringList deleteFiles;
- for (const QModelIndex& idx : ui->savegameList->selectionModel()->selectedIndexes()) {
- QString name = idx.data(Qt::UserRole).toString();
+ int count = 0;
- if (count < 10) {
- savesMsgLabel += "<li>" + QFileInfo(name).completeBaseName() + "</li>";
- }
- ++count;
+ for (const QModelIndex &idx : ui->savegameList->selectionModel()->selectedIndexes()) {
+ QString name = idx.data(Qt::UserRole).toString();
- if (info == nullptr) {
- deleteFiles.push_back(name);
- } else {
- ISaveGame const* save = info->getSaveGameInfo(name);
- deleteFiles += save->allFiles();
- }
+ if (count < 10) {
+ savesMsgLabel += "<li>" + QFileInfo(name).completeBaseName() + "</li>";
}
+ ++count;
- if (count > 10) {
- savesMsgLabel += "<li><i>... " + tr("%1 more").arg(count - 10) + "</i></li>";
+ if (info == nullptr) {
+ deleteFiles.push_back(name);
+ } else {
+ ISaveGame const *save = info->getSaveGameInfo(name);
+ deleteFiles += save->allFiles();
}
+ }
- if (QMessageBox::question(this, tr("Confirm"),
- tr("Are you sure you want to remove the following %n save(s)?<br>"
- "<ul>%1</ul><br>"
- "Removed saves will be sent to the Recycle Bin.",
- "", count)
- .arg(savesMsgLabel),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- shellDelete(deleteFiles, true); // recycle bin delete.
- refreshSaveList();
- }
+ if (count > 10) {
+ savesMsgLabel += "<li><i>... " + tr("%1 more").arg(count - 10) + "</i></li>";
+ }
+
+ if (QMessageBox::question(this, tr("Confirm"),
+ tr("Are you sure you want to remove the following %n save(s)?<br>"
+ "<ul>%1</ul><br>"
+ "Removed saves will be sent to the Recycle Bin.", "", count)
+ .arg(savesMsgLabel),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ shellDelete(deleteFiles, true); // recycle bin delete.
+ refreshSaveList();
+ }
}
-void MainWindow::fixMods_clicked(SaveGameInfo::MissingAssets const& missingAssets) {
- ActivateModsDialog dialog(missingAssets, this);
- if (dialog.exec() == QDialog::Accepted) {
- // activate the required mods, then enable all esps
- std::set<QString> modsToActivate = dialog.getModsToActivate();
- for (std::set<QString>::iterator iter = modsToActivate.begin(); iter != modsToActivate.end(); ++iter) {
- if ((*iter != "<data>") && (*iter != "<overwrite>")) {
- unsigned int modIndex = ModInfo::getIndex(*iter);
- m_OrganizerCore.currentProfile()->setModEnabled(modIndex, true);
- }
- }
- m_OrganizerCore.currentProfile()->writeModlist();
- m_OrganizerCore.refreshLists();
+void MainWindow::fixMods_clicked(SaveGameInfo::MissingAssets const &missingAssets)
+{
+ ActivateModsDialog dialog(missingAssets, this);
+ if (dialog.exec() == QDialog::Accepted) {
+ // activate the required mods, then enable all esps
+ std::set<QString> modsToActivate = dialog.getModsToActivate();
+ for (std::set<QString>::iterator iter = modsToActivate.begin(); iter != modsToActivate.end(); ++iter) {
+ if ((*iter != "<data>") && (*iter != "<overwrite>")) {
+ unsigned int modIndex = ModInfo::getIndex(*iter);
+ m_OrganizerCore.currentProfile()->setModEnabled(modIndex, true);
+ }
+ }
+
+ m_OrganizerCore.currentProfile()->writeModlist();
+ m_OrganizerCore.refreshLists();
- std::set<QString> espsToActivate = dialog.getESPsToActivate();
- for (std::set<QString>::iterator iter = espsToActivate.begin(); iter != espsToActivate.end(); ++iter) {
- m_OrganizerCore.pluginList()->enableESP(*iter);
- }
- m_OrganizerCore.saveCurrentLists();
+ std::set<QString> espsToActivate = dialog.getESPsToActivate();
+ for (std::set<QString>::iterator iter = espsToActivate.begin(); iter != espsToActivate.end(); ++iter) {
+ m_OrganizerCore.pluginList()->enableESP(*iter);
}
+ m_OrganizerCore.saveCurrentLists();
+ }
}
-void MainWindow::on_savegameList_customContextMenuRequested(const QPoint& pos) {
- QItemSelectionModel* selection = ui->savegameList->selectionModel();
- if (!selection->hasSelection()) {
- return;
- }
+void MainWindow::on_savegameList_customContextMenuRequested(const QPoint &pos)
+{
+ QItemSelectionModel *selection = ui->savegameList->selectionModel();
- QMenu menu;
- QAction* action = menu.addAction(tr("Enable Mods..."));
- action->setEnabled(false);
+ if (!selection->hasSelection()) {
+ return;
+ }
- if (selection->selectedIndexes().count() == 1) {
- SaveGameInfo const* info = this->m_OrganizerCore.managedGame()->feature<SaveGameInfo>();
- if (info != nullptr) {
- QString save = ui->savegameList->currentItem()->data(Qt::UserRole).toString();
- SaveGameInfo::MissingAssets missing = info->getMissingAssets(save);
- if (missing.size() != 0) {
- connect(action, &QAction::triggered, this, [this, missing] { fixMods_clicked(missing); });
- action->setEnabled(true);
- }
- }
+ QMenu menu;
+ QAction *action = menu.addAction(tr("Enable Mods..."));
+ action->setEnabled(false);
+
+ if (selection->selectedIndexes().count() == 1) {
+ SaveGameInfo const *info = this->m_OrganizerCore.managedGame()->feature<SaveGameInfo>();
+ if (info != nullptr) {
+ QString save = ui->savegameList->currentItem()->data(Qt::UserRole).toString();
+ SaveGameInfo::MissingAssets missing = info->getMissingAssets(save);
+ if (missing.size() != 0) {
+ connect(action, &QAction::triggered, this, [this, missing]{ fixMods_clicked(missing); });
+ action->setEnabled(true);
+ }
}
+ }
- QString deleteMenuLabel = tr("Delete %n save(s)", "", selection->selectedIndexes().count());
+ QString deleteMenuLabel = tr("Delete %n save(s)", "", selection->selectedIndexes().count());
- menu.addAction(deleteMenuLabel, this, SLOT(deleteSavegame_clicked()));
+ menu.addAction(deleteMenuLabel, this, SLOT(deleteSavegame_clicked()));
- menu.exec(ui->savegameList->mapToGlobal(pos));
+ menu.exec(ui->savegameList->mapToGlobal(pos));
}
-void MainWindow::linkToolbar() {
- Executable& exe(getSelectedExecutable());
- exe.showOnToolbar(!exe.isShownOnToolbar());
- ui->linkButton->menu()
- ->actions()
- .at(static_cast<int>(ShortcutType::Toolbar))
- ->setIcon(exe.isShownOnToolbar() ? QIcon(":/MO/gui/remove") : QIcon(":/MO/gui/link"));
- updateToolBar();
+void MainWindow::linkToolbar()
+{
+ Executable &exe(getSelectedExecutable());
+ exe.showOnToolbar(!exe.isShownOnToolbar());
+ ui->linkButton->menu()->actions().at(static_cast<int>(ShortcutType::Toolbar))->setIcon(exe.isShownOnToolbar() ? QIcon(":/MO/gui/remove") : QIcon(":/MO/gui/link"));
+ updateToolBar();
}
namespace {
-QString getLinkfile(const QString& dir, const Executable& exec) {
- return QDir::fromNativeSeparators(dir) + "/" + exec.m_Title + ".lnk";
+QString getLinkfile(const QString &dir, const Executable &exec)
+{
+ return QDir::fromNativeSeparators(dir) + "/" + exec.m_Title + ".lnk";
}
-QString getDesktopLinkfile(const Executable& exec) { return getLinkfile(getDesktopDirectory(), exec); }
+QString getDesktopLinkfile(const Executable &exec)
+{
+ return getLinkfile(getDesktopDirectory(), exec);
+}
-QString getStartMenuLinkfile(const Executable& exec) { return getLinkfile(getStartMenuDirectory(), exec); }
-} // namespace
+QString getStartMenuLinkfile(const Executable &exec)
+{
+ return getLinkfile(getStartMenuDirectory(), exec);
+}
+}
-void MainWindow::addWindowsLink(const ShortcutType mapping) {
- const Executable& selectedExecutable(getSelectedExecutable());
- QString const linkName = getLinkfile(
- mapping == ShortcutType::Desktop ? getDesktopDirectory() : getStartMenuDirectory(), selectedExecutable);
+void MainWindow::addWindowsLink(const ShortcutType mapping)
+{
+ const Executable &selectedExecutable(getSelectedExecutable());
+ QString const linkName = getLinkfile(mapping == ShortcutType::Desktop ? getDesktopDirectory() : getStartMenuDirectory(),
+ selectedExecutable);
- if (QFile::exists(linkName)) {
- if (QFile::remove(linkName)) {
- ui->linkButton->menu()->actions().at(static_cast<int>(mapping))->setIcon(QIcon(":/MO/gui/link"));
- } else {
- reportError(tr("failed to remove %1").arg(linkName));
- }
+ if (QFile::exists(linkName)) {
+ if (QFile::remove(linkName)) {
+ ui->linkButton->menu()->actions().at(static_cast<int>(mapping))->setIcon(QIcon(":/MO/gui/link"));
} else {
- QFileInfo const exeInfo(qApp->applicationFilePath());
- // create link
- QString executable = QDir::toNativeSeparators(selectedExecutable.m_BinaryInfo.absoluteFilePath());
+ reportError(tr("failed to remove %1").arg(linkName));
+ }
+ } else {
+ QFileInfo const exeInfo(qApp->applicationFilePath());
+ // create link
+ QString executable = QDir::toNativeSeparators(selectedExecutable.m_BinaryInfo.absoluteFilePath());
- std::wstring targetFile = ToWString(exeInfo.absoluteFilePath());
- std::wstring parameter =
- ToWString(QString("\"moshortcut://%1:%2\"")
- .arg(InstanceManager::instance().currentInstance(), selectedExecutable.m_Title));
- std::wstring description = ToWString(QString("Run %1 with ModOrganizer").arg(selectedExecutable.m_Title));
- std::wstring iconFile = ToWString(executable);
- std::wstring currentDirectory = ToWString(QDir::toNativeSeparators(qApp->applicationDirPath()));
+ std::wstring targetFile = ToWString(exeInfo.absoluteFilePath());
+ std::wstring parameter = ToWString(
+ QString("\"moshortcut://%1:%2\"").arg(InstanceManager::instance().currentInstance(),selectedExecutable.m_Title));
+ std::wstring description = ToWString(QString("Run %1 with ModOrganizer").arg(selectedExecutable.m_Title));
+ std::wstring iconFile = ToWString(executable);
+ std::wstring currentDirectory = ToWString(QDir::toNativeSeparators(qApp->applicationDirPath()));
- if (CreateShortcut(targetFile.c_str(), parameter.c_str(),
- QDir::toNativeSeparators(linkName).toUtf8().constData(), description.c_str(),
- (selectedExecutable.usesOwnIcon() ? iconFile.c_str() : nullptr), 0,
- currentDirectory.c_str()) == 0) {
- ui->linkButton->menu()->actions().at(static_cast<int>(mapping))->setIcon(QIcon(":/MO/gui/remove"));
- } else {
- reportError(tr("failed to create %1").arg(linkName));
- }
+ if (CreateShortcut(targetFile.c_str()
+ , parameter.c_str()
+ , QDir::toNativeSeparators(linkName).toUtf8().constData()
+ , description.c_str()
+ , (selectedExecutable.usesOwnIcon() ? iconFile.c_str() : nullptr), 0
+ , currentDirectory.c_str()) == 0) {
+ ui->linkButton->menu()->actions().at(static_cast<int>(mapping))->setIcon(QIcon(":/MO/gui/remove"));
+ } else {
+ reportError(tr("failed to create %1").arg(linkName));
}
+ }
}
-void MainWindow::linkDesktop() { addWindowsLink(ShortcutType::Desktop); }
+void MainWindow::linkDesktop()
+{
+ addWindowsLink(ShortcutType::Desktop);
+}
-void MainWindow::linkMenu() { addWindowsLink(ShortcutType::StartMenu); }
+void MainWindow::linkMenu()
+{
+ addWindowsLink(ShortcutType::StartMenu);
+}
-void MainWindow::on_actionSettings_triggered() {
- Settings& settings = m_OrganizerCore.settings();
+void MainWindow::on_actionSettings_triggered()
+{
+ Settings &settings = m_OrganizerCore.settings();
- QString oldModDirectory(settings.getModDirectory());
- QString oldCacheDirectory(settings.getCacheDirectory());
- QString oldProfilesDirectory(settings.getProfileDirectory());
- bool oldDisplayForeign(settings.displayForeign());
- bool proxy = settings.useProxy();
+ QString oldModDirectory(settings.getModDirectory());
+ QString oldCacheDirectory(settings.getCacheDirectory());
+ QString oldProfilesDirectory(settings.getProfileDirectory());
+ bool oldDisplayForeign(settings.displayForeign());
+ bool proxy = settings.useProxy();
- settings.query(this);
+ settings.query(this);
- InstallationManager* instManager = m_OrganizerCore.installationManager();
- instManager->setModsDirectory(settings.getModDirectory());
- instManager->setDownloadDirectory(settings.getDownloadDirectory());
+ InstallationManager *instManager = m_OrganizerCore.installationManager();
+ instManager->setModsDirectory(settings.getModDirectory());
+ instManager->setDownloadDirectory(settings.getDownloadDirectory());
- fixCategories();
- refreshFilters();
+ fixCategories();
+ refreshFilters();
- if (settings.getProfileDirectory() != oldProfilesDirectory) {
- refreshProfiles();
- }
+ if (settings.getProfileDirectory() != oldProfilesDirectory) {
+ refreshProfiles();
+ }
- DownloadManager* dlManager = m_OrganizerCore.downloadManager();
+ DownloadManager *dlManager = m_OrganizerCore.downloadManager();
- if (dlManager->getOutputDirectory() != settings.getDownloadDirectory()) {
- if (dlManager->downloadsInProgress()) {
- MessageDialog::showMessage(tr("Can't change download directory while "
- "downloads are in progress!"),
- this);
- } else {
- dlManager->setOutputDirectory(settings.getDownloadDirectory());
- }
+ if (dlManager->getOutputDirectory() != settings.getDownloadDirectory()) {
+ if (dlManager->downloadsInProgress()) {
+ MessageDialog::showMessage(tr("Can't change download directory while "
+ "downloads are in progress!"),
+ this);
+ } else {
+ dlManager->setOutputDirectory(settings.getDownloadDirectory());
}
- dlManager->setPreferredServers(settings.getPreferredServers());
+ }
+ dlManager->setPreferredServers(settings.getPreferredServers());
- if ((settings.getModDirectory() != oldModDirectory) || (settings.displayForeign() != oldDisplayForeign)) {
- m_OrganizerCore.profileRefresh();
- }
+ if ((settings.getModDirectory() != oldModDirectory)
+ || (settings.displayForeign() != oldDisplayForeign)) {
+ m_OrganizerCore.profileRefresh();
+ }
- if (settings.getCacheDirectory() != oldCacheDirectory) {
- NexusInterface::instance()->setCacheDirectory(settings.getCacheDirectory());
- }
+ if (settings.getCacheDirectory() != oldCacheDirectory) {
+ NexusInterface::instance()->setCacheDirectory(settings.getCacheDirectory());
+ }
- if (proxy != settings.useProxy()) {
- activateProxy(settings.useProxy());
- }
+ if (proxy != settings.useProxy()) {
+ activateProxy(settings.useProxy());
+ }
- NexusInterface::instance()->setNMMVersion(settings.getNMMVersion());
+ NexusInterface::instance()->setNMMVersion(settings.getNMMVersion());
- updateDownloadListDelegate();
+ updateDownloadListDelegate();
- m_OrganizerCore.updateVFSParams(settings.logLevel(), settings.crashDumpsType());
- m_OrganizerCore.cycleDiagnostics();
+ m_OrganizerCore.updateVFSParams(settings.logLevel(), settings.crashDumpsType());
+ m_OrganizerCore.cycleDiagnostics();
}
-void MainWindow::on_actionNexus_triggered() {
- ::ShellExecuteW(nullptr, L"open", NexusInterface::instance()->getGameURL().toStdWString().c_str(), nullptr, nullptr,
- SW_SHOWNORMAL);
+
+void MainWindow::on_actionNexus_triggered()
+{
+ ::ShellExecuteW(nullptr, L"open",
+ NexusInterface::instance()->getGameURL().toStdWString().c_str(),
+ nullptr, nullptr, SW_SHOWNORMAL);
}
-void MainWindow::nexusLinkActivated(const QString& link) {
- ::ShellExecuteW(nullptr, L"open", ToWString(link).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
- ui->tabWidget->setCurrentIndex(4);
+
+void MainWindow::nexusLinkActivated(const QString &link)
+{
+ ::ShellExecuteW(nullptr, L"open", ToWString(link).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
+ ui->tabWidget->setCurrentIndex(4);
}
-void MainWindow::linkClicked(const QString& url) {
- ::ShellExecuteW(nullptr, L"open", ToWString(url).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
+
+void MainWindow::linkClicked(const QString &url)
+{
+ ::ShellExecuteW(nullptr, L"open", ToWString(url).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
}
-void MainWindow::installTranslator(const QString& name) {
- QTranslator* translator = new QTranslator(this);
- QString fileName = name + "_" + m_CurrentLanguage;
- if (!translator->load(fileName, qApp->applicationDirPath() + "/translations")) {
- if ((m_CurrentLanguage != "en-US") && (m_CurrentLanguage != "en_US") && (m_CurrentLanguage != "en-GB")) {
- qDebug("localization file %s not found", qPrintable(fileName));
- } // we don't actually expect localization files for english
- }
- qApp->installTranslator(translator);
- m_Translators.push_back(translator);
+void MainWindow::installTranslator(const QString &name)
+{
+ QTranslator *translator = new QTranslator(this);
+ QString fileName = name + "_" + m_CurrentLanguage;
+ if (!translator->load(fileName, qApp->applicationDirPath() + "/translations")) {
+ if ((m_CurrentLanguage != "en-US")
+ && (m_CurrentLanguage != "en_US")
+ && (m_CurrentLanguage != "en-GB")) {
+ qDebug("localization file %s not found", qPrintable(fileName));
+ } // we don't actually expect localization files for english
+ }
+
+ qApp->installTranslator(translator);
+ m_Translators.push_back(translator);
}
-void MainWindow::languageChange(const QString& newLanguage) {
- for (QTranslator* trans : m_Translators) {
- qApp->removeTranslator(trans);
- }
- m_Translators.clear();
- m_CurrentLanguage = newLanguage;
+void MainWindow::languageChange(const QString &newLanguage)
+{
+ for (QTranslator *trans : m_Translators) {
+ qApp->removeTranslator(trans);
+ }
+ m_Translators.clear();
- installTranslator("qt");
- installTranslator(ToQString(AppConfig::translationPrefix()));
- ui->retranslateUi(this);
- qDebug("loaded language %s", qPrintable(newLanguage));
+ m_CurrentLanguage = newLanguage;
- ui->profileBox->setItemText(0, QObject::tr("<Manage...>"));
+ installTranslator("qt");
+ installTranslator(ToQString(AppConfig::translationPrefix()));
+ ui->retranslateUi(this);
+ qDebug("loaded language %s", qPrintable(newLanguage));
- createHelpWidget();
+ ui->profileBox->setItemText(0, QObject::tr("<Manage...>"));
- updateDownloadListDelegate();
- updateProblemsButton();
+ createHelpWidget();
- ui->listOptionsBtn->setMenu(modListContextMenu());
-}
+ updateDownloadListDelegate();
+ updateProblemsButton();
-void MainWindow::writeDataToFile(QFile& file, const QString& directory, const DirectoryEntry& directoryEntry) {
- for (FileEntry::Ptr current : directoryEntry.getFiles()) {
- bool isArchive = false;
- int origin = current->getOrigin(isArchive);
- if (isArchive) {
- // TODO: don't list files from archives. maybe make this an option?
- continue;
- }
- QString fullName = directory + "\\" + ToQString(current->getName());
- file.write(fullName.toUtf8());
+ ui->listOptionsBtn->setMenu(modListContextMenu());
+}
- file.write("\t(");
- file.write(ToQString(m_OrganizerCore.directoryStructure()->getOriginByID(origin).getName()).toUtf8());
- file.write(")\r\n");
+void MainWindow::writeDataToFile(QFile &file, const QString &directory, const DirectoryEntry &directoryEntry)
+{
+ for (FileEntry::Ptr current : directoryEntry.getFiles()) {
+ bool isArchive = false;
+ int origin = current->getOrigin(isArchive);
+ if (isArchive) {
+ // TODO: don't list files from archives. maybe make this an option?
+ continue;
}
+ QString fullName = directory + "\\" + ToQString(current->getName());
+ file.write(fullName.toUtf8());
- // recurse into subdirectories
- std::vector<DirectoryEntry*>::const_iterator current, end;
- directoryEntry.getSubDirectories(current, end);
- for (; current != end; ++current) {
- writeDataToFile(file, directory + "\\" + ToQString((*current)->getName()), **current);
- }
+ file.write("\t(");
+ file.write(ToQString(m_OrganizerCore.directoryStructure()->getOriginByID(origin).getName()).toUtf8());
+ file.write(")\r\n");
+ }
+
+ // recurse into subdirectories
+ std::vector<DirectoryEntry*>::const_iterator current, end;
+ directoryEntry.getSubDirectories(current, end);
+ for (; current != end; ++current) {
+ writeDataToFile(file, directory + "\\" + ToQString((*current)->getName()), **current);
+ }
}
-void MainWindow::writeDataToFile() {
- QString fileName = QFileDialog::getSaveFileName(this);
- QFile file(fileName);
- if (!file.open(QIODevice::WriteOnly)) {
- reportError(tr("failed to write to file %1").arg(fileName));
- }
+void MainWindow::writeDataToFile()
+{
+ QString fileName = QFileDialog::getSaveFileName(this);
+ QFile file(fileName);
+ if (!file.open(QIODevice::WriteOnly)) {
+ reportError(tr("failed to write to file %1").arg(fileName));
+ }
- writeDataToFile(file, "data", *m_OrganizerCore.directoryStructure());
- file.close();
+ writeDataToFile(file, "data", *m_OrganizerCore.directoryStructure());
+ file.close();
- MessageDialog::showMessage(tr("%1 written").arg(QDir::toNativeSeparators(fileName)), this);
+ MessageDialog::showMessage(tr("%1 written").arg(QDir::toNativeSeparators(fileName)), this);
}
-int MainWindow::getBinaryExecuteInfo(const QFileInfo& targetInfo, QFileInfo& binaryInfo, QString& arguments) {
- QString extension = targetInfo.suffix();
- if ((extension.compare("cmd", Qt::CaseInsensitive) == 0) || (extension.compare("com", Qt::CaseInsensitive) == 0) ||
- (extension.compare("bat", Qt::CaseInsensitive) == 0)) {
- binaryInfo = QFileInfo("C:\\Windows\\System32\\cmd.exe");
- arguments = QString("/C \"%1\"").arg(QDir::toNativeSeparators(targetInfo.absoluteFilePath()));
- return 1;
- } else if (extension.compare("exe", Qt::CaseInsensitive) == 0) {
- binaryInfo = targetInfo;
- return 1;
- } else if (extension.compare("jar", Qt::CaseInsensitive) == 0) {
- // types that need to be injected into
- std::wstring targetPathW = ToWString(targetInfo.absoluteFilePath());
- QString binaryPath;
- { // try to find java automatically
- WCHAR buffer[MAX_PATH];
- if (::FindExecutableW(targetPathW.c_str(), nullptr, buffer) > (HINSTANCE)32) {
- DWORD binaryType = 0UL;
- if (!::GetBinaryTypeW(buffer, &binaryType)) {
- qDebug("failed to determine binary type of \"%ls\": %lu", buffer, ::GetLastError());
- } else if (binaryType == SCS_32BIT_BINARY) {
- binaryPath = ToQString(buffer);
- }
- }
- }
- if (binaryPath.isEmpty() && (extension == "jar")) {
- // second attempt: look to the registry
- QSettings javaReg("HKEY_LOCAL_MACHINE\\Software\\JavaSoft\\Java Runtime Environment",
- QSettings::NativeFormat);
- if (javaReg.contains("CurrentVersion")) {
- QString currentVersion = javaReg.value("CurrentVersion").toString();
- binaryPath =
- javaReg.value(QString("%1/JavaHome").arg(currentVersion)).toString().append("\\bin\\javaw.exe");
- }
- }
- if (binaryPath.isEmpty()) {
- binaryPath = QFileDialog::getOpenFileName(this, tr("Select binary"), QString(), tr("Binary") + " (*.exe)");
- }
- if (binaryPath.isEmpty()) {
- return 0;
- }
- binaryInfo = QFileInfo(binaryPath);
- if (extension == "jar") {
- arguments = QString("-jar \"%1\"").arg(QDir::toNativeSeparators(targetInfo.absoluteFilePath()));
- } else {
- arguments = QString("\"%1\"").arg(QDir::toNativeSeparators(targetInfo.absoluteFilePath()));
+int MainWindow::getBinaryExecuteInfo(const QFileInfo &targetInfo, QFileInfo &binaryInfo, QString &arguments)
+{
+ QString extension = targetInfo.suffix();
+ if ((extension.compare("cmd", Qt::CaseInsensitive) == 0) ||
+ (extension.compare("com", Qt::CaseInsensitive) == 0) ||
+ (extension.compare("bat", Qt::CaseInsensitive) == 0)) {
+ binaryInfo = QFileInfo("C:\\Windows\\System32\\cmd.exe");
+ arguments = QString("/C \"%1\"").arg(QDir::toNativeSeparators(targetInfo.absoluteFilePath()));
+ return 1;
+ } else if (extension.compare("exe", Qt::CaseInsensitive) == 0) {
+ binaryInfo = targetInfo;
+ return 1;
+ } else if (extension.compare("jar", Qt::CaseInsensitive) == 0) {
+ // types that need to be injected into
+ std::wstring targetPathW = ToWString(targetInfo.absoluteFilePath());
+ QString binaryPath;
+
+ { // try to find java automatically
+ WCHAR buffer[MAX_PATH];
+ if (::FindExecutableW(targetPathW.c_str(), nullptr, buffer) > (HINSTANCE)32) {
+ DWORD binaryType = 0UL;
+ if (!::GetBinaryTypeW(buffer, &binaryType)) {
+ qDebug("failed to determine binary type of \"%ls\": %lu", buffer, ::GetLastError());
+ } else if (binaryType == SCS_32BIT_BINARY) {
+ binaryPath = ToQString(buffer);
}
- return 1;
+ }
+ }
+ if (binaryPath.isEmpty() && (extension == "jar")) {
+ // second attempt: look to the registry
+ QSettings javaReg("HKEY_LOCAL_MACHINE\\Software\\JavaSoft\\Java Runtime Environment", QSettings::NativeFormat);
+ if (javaReg.contains("CurrentVersion")) {
+ QString currentVersion = javaReg.value("CurrentVersion").toString();
+ binaryPath = javaReg.value(QString("%1/JavaHome").arg(currentVersion)).toString().append("\\bin\\javaw.exe");
+ }
+ }
+ if (binaryPath.isEmpty()) {
+ binaryPath = QFileDialog::getOpenFileName(this, tr("Select binary"), QString(), tr("Binary") + " (*.exe)");
+ }
+ if (binaryPath.isEmpty()) {
+ return 0;
+ }
+ binaryInfo = QFileInfo(binaryPath);
+ if (extension == "jar") {
+ arguments = QString("-jar \"%1\"").arg(QDir::toNativeSeparators(targetInfo.absoluteFilePath()));
} else {
- return 2;
+ arguments = QString("\"%1\"").arg(QDir::toNativeSeparators(targetInfo.absoluteFilePath()));
}
+ return 1;
+ } else {
+ return 2;
+ }
}
-void MainWindow::addAsExecutable() {
- if (m_ContextItem != nullptr) {
- QFileInfo targetInfo(m_ContextItem->data(0, Qt::UserRole).toString());
- QFileInfo binaryInfo;
- QString arguments;
- switch (getBinaryExecuteInfo(targetInfo, binaryInfo, arguments)) {
- case 1: {
- QString name = QInputDialog::getText(this, tr("Enter Name"), tr("Please enter a name for the executable"),
- QLineEdit::Normal, targetInfo.baseName());
- if (!name.isEmpty()) {
- // Note: If this already exists, you'll lose custom settings
- m_OrganizerCore.executablesList()->addExecutable(name, binaryInfo.absoluteFilePath(), arguments,
- targetInfo.absolutePath(), QString(),
- Executable::CustomExecutable);
- refreshExecutablesList();
- }
- } break;
- case 2: {
- QMessageBox::information(this, tr("Not an executable"), tr("This is not a recognized executable."));
- } break;
- default: {
- // nop
- } break;
+
+void MainWindow::addAsExecutable()
+{
+ if (m_ContextItem != nullptr) {
+ QFileInfo targetInfo(m_ContextItem->data(0, Qt::UserRole).toString());
+ QFileInfo binaryInfo;
+ QString arguments;
+ switch (getBinaryExecuteInfo(targetInfo, binaryInfo, arguments)) {
+ case 1: {
+ QString name = QInputDialog::getText(this, tr("Enter Name"),
+ tr("Please enter a name for the executable"), QLineEdit::Normal,
+ targetInfo.baseName());
+ if (!name.isEmpty()) {
+ //Note: If this already exists, you'll lose custom settings
+ m_OrganizerCore.executablesList()->addExecutable(name,
+ binaryInfo.absoluteFilePath(),
+ arguments,
+ targetInfo.absolutePath(),
+ QString(),
+ Executable::CustomExecutable);
+ refreshExecutablesList();
}
+ } break;
+ case 2: {
+ QMessageBox::information(this, tr("Not an executable"), tr("This is not a recognized executable."));
+ } break;
+ default: {
+ // nop
+ } break;
}
+ }
}
-void MainWindow::originModified(int originID) {
- FilesOrigin& origin = m_OrganizerCore.directoryStructure()->getOriginByID(originID);
- origin.enable(false);
- m_OrganizerCore.directoryStructure()->addFromOrigin(origin.getName(), origin.getPath(), origin.getPriority());
- DirectoryRefresher::cleanStructure(m_OrganizerCore.directoryStructure());
+
+void MainWindow::originModified(int originID)
+{
+ FilesOrigin &origin = m_OrganizerCore.directoryStructure()->getOriginByID(originID);
+ origin.enable(false);
+ m_OrganizerCore.directoryStructure()->addFromOrigin(origin.getName(), origin.getPath(), origin.getPriority());
+ DirectoryRefresher::cleanStructure(m_OrganizerCore.directoryStructure());
}
-void MainWindow::hideFile() {
- QString oldName = m_ContextItem->data(0, Qt::UserRole).toString();
- QString newName = oldName + ModInfo::s_HiddenExt;
- if (QFileInfo(newName).exists()) {
- if (QMessageBox::question(this, tr("Replace file?"),
- tr("There already is a hidden version of this file. Replace it?"),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- if (!QFile(newName).remove()) {
- QMessageBox::critical(
- this, tr("File operation failed"),
- tr("Failed to remove \"%1\". Maybe you lack the required file permissions?").arg(newName));
- return;
- }
- } else {
- return;
- }
- }
+void MainWindow::hideFile()
+{
+ QString oldName = m_ContextItem->data(0, Qt::UserRole).toString();
+ QString newName = oldName + ModInfo::s_HiddenExt;
- if (QFile::rename(oldName, newName)) {
- originModified(m_ContextItem->data(1, Qt::UserRole + 1).toInt());
- refreshDataTreeKeepExpandedNodes();
+ if (QFileInfo(newName).exists()) {
+ if (QMessageBox::question(this, tr("Replace file?"), tr("There already is a hidden version of this file. Replace it?"),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ if (!QFile(newName).remove()) {
+ QMessageBox::critical(this, tr("File operation failed"), tr("Failed to remove \"%1\". Maybe you lack the required file permissions?").arg(newName));
+ return;
+ }
} else {
- reportError(tr("failed to rename \"%1\" to \"%2\"").arg(oldName).arg(QDir::toNativeSeparators(newName)));
+ return;
}
+ }
+
+ if (QFile::rename(oldName, newName)) {
+ originModified(m_ContextItem->data(1, Qt::UserRole + 1).toInt());
+ refreshDataTreeKeepExpandedNodes();
+ } else {
+ reportError(tr("failed to rename \"%1\" to \"%2\"").arg(oldName).arg(QDir::toNativeSeparators(newName)));
+ }
}
-void MainWindow::unhideFile() {
- QString oldName = m_ContextItem->data(0, Qt::UserRole).toString();
- QString newName = oldName.left(oldName.length() - ModInfo::s_HiddenExt.length());
- if (QFileInfo(newName).exists()) {
- if (QMessageBox::question(this, tr("Replace file?"),
- tr("There already is a visible version of this file. Replace it?"),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- if (!QFile(newName).remove()) {
- QMessageBox::critical(
- this, tr("File operation failed"),
- tr("Failed to remove \"%1\". Maybe you lack the required file permissions?").arg(newName));
- return;
- }
- } else {
- return;
- }
- }
- if (QFile::rename(oldName, newName)) {
- originModified(m_ContextItem->data(1, Qt::UserRole + 1).toInt());
- refreshDataTreeKeepExpandedNodes();
+
+void MainWindow::unhideFile()
+{
+ QString oldName = m_ContextItem->data(0, Qt::UserRole).toString();
+ QString newName = oldName.left(oldName.length() - ModInfo::s_HiddenExt.length());
+ if (QFileInfo(newName).exists()) {
+ if (QMessageBox::question(this, tr("Replace file?"), tr("There already is a visible version of this file. Replace it?"),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ if (!QFile(newName).remove()) {
+ QMessageBox::critical(this, tr("File operation failed"), tr("Failed to remove \"%1\". Maybe you lack the required file permissions?").arg(newName));
+ return;
+ }
} else {
- reportError(tr("failed to rename \"%1\" to \"%2\"")
- .arg(QDir::toNativeSeparators(oldName))
- .arg(QDir::toNativeSeparators(newName)));
+ return;
}
+ }
+ if (QFile::rename(oldName, newName)) {
+ originModified(m_ContextItem->data(1, Qt::UserRole + 1).toInt());
+ refreshDataTreeKeepExpandedNodes();
+ } else {
+ reportError(tr("failed to rename \"%1\" to \"%2\"").arg(QDir::toNativeSeparators(oldName)).arg(QDir::toNativeSeparators(newName)));
+ }
}
-void MainWindow::previewDataFile() {
- QString fileName = QDir::fromNativeSeparators(m_ContextItem->data(0, Qt::UserRole).toString());
+void MainWindow::previewDataFile()
+{
+ QString fileName = QDir::fromNativeSeparators(m_ContextItem->data(0, Qt::UserRole).toString());
- // what we have is an absolute path to the file in its actual location (for the primary origin)
- // what we want is the path relative to the virtual data directory
+ // what we have is an absolute path to the file in its actual location (for the primary origin)
+ // what we want is the path relative to the virtual data directory
- // crude: we search for the next slash after the base mod directory to skip everything up to the data-relative
- // directory
- int offset = m_OrganizerCore.settings().getModDirectory().size() + 1;
- offset = fileName.indexOf("/", offset);
- fileName = fileName.mid(offset + 1);
+ // crude: we search for the next slash after the base mod directory to skip everything up to the data-relative directory
+ int offset = m_OrganizerCore.settings().getModDirectory().size() + 1;
+ offset = fileName.indexOf("/", offset);
+ fileName = fileName.mid(offset + 1);
- const FileEntry::Ptr file = m_OrganizerCore.directoryStructure()->searchFile(ToWString(fileName), nullptr);
+ const FileEntry::Ptr file = m_OrganizerCore.directoryStructure()->searchFile(ToWString(fileName), nullptr);
- if (file.get() == nullptr) {
- reportError(tr("file not found: %1").arg(fileName));
- return;
- }
+ if (file.get() == nullptr) {
+ reportError(tr("file not found: %1").arg(fileName));
+ return;
+ }
- // set up preview dialog
- PreviewDialog preview(fileName);
- auto addFunc = [&](int originId) {
- FilesOrigin& origin = m_OrganizerCore.directoryStructure()->getOriginByID(originId);
- QString filePath = QDir::fromNativeSeparators(ToQString(origin.getPath())) + "/" + fileName;
- if (QFile::exists(filePath)) {
- // it's very possible the file doesn't exist, because it's inside an archive. we don't support that
- QWidget* wid = m_PluginContainer.previewGenerator().genPreview(filePath);
- if (wid == nullptr) {
- reportError(tr("failed to generate preview for %1").arg(filePath));
- } else {
- preview.addVariant(ToQString(origin.getName()), wid);
- }
+ // set up preview dialog
+ PreviewDialog preview(fileName);
+ auto addFunc = [&] (int originId) {
+ FilesOrigin &origin = m_OrganizerCore.directoryStructure()->getOriginByID(originId);
+ QString filePath = QDir::fromNativeSeparators(ToQString(origin.getPath())) + "/" + fileName;
+ if (QFile::exists(filePath)) {
+ // it's very possible the file doesn't exist, because it's inside an archive. we don't support that
+ QWidget *wid = m_PluginContainer.previewGenerator().genPreview(filePath);
+ if (wid == nullptr) {
+ reportError(tr("failed to generate preview for %1").arg(filePath));
+ } else {
+ preview.addVariant(ToQString(origin.getName()), wid);
}
+ }
};
- addFunc(file->getOrigin());
- for (auto alt : file->getAlternatives()) {
- addFunc(alt.first);
- }
- if (preview.numVariants() > 0) {
- preview.exec();
- } else {
- QMessageBox::information(
- this, tr("Sorry"),
- tr("Sorry, can't preview anything. This function currently does not support extracting from bsas."));
- }
+ addFunc(file->getOrigin());
+ for (auto alt : file->getAlternatives()) {
+ addFunc(alt.first);
+ }
+ if (preview.numVariants() > 0) {
+ preview.exec();
+ } else {
+ QMessageBox::information(this, tr("Sorry"), tr("Sorry, can't preview anything. This function currently does not support extracting from bsas."));
+ }
}
-void MainWindow::openDataFile() {
- if (m_ContextItem != nullptr) {
- QFileInfo targetInfo(m_ContextItem->data(0, Qt::UserRole).toString());
- QFileInfo binaryInfo;
- QString arguments;
- switch (getBinaryExecuteInfo(targetInfo, binaryInfo, arguments)) {
- case 1: {
- m_OrganizerCore.spawnBinaryDirect(binaryInfo, arguments, m_OrganizerCore.currentProfile()->name(),
- targetInfo.absolutePath(), "", "");
- } break;
- case 2: {
- ::ShellExecuteW(nullptr, L"open", ToWString(targetInfo.absoluteFilePath()).c_str(), nullptr, nullptr,
- SW_SHOWNORMAL);
- } break;
- default: {
- // nop
- } break;
- }
+void MainWindow::openDataFile()
+{
+ if (m_ContextItem != nullptr) {
+ QFileInfo targetInfo(m_ContextItem->data(0, Qt::UserRole).toString());
+ QFileInfo binaryInfo;
+ QString arguments;
+ switch (getBinaryExecuteInfo(targetInfo, binaryInfo, arguments)) {
+ case 1: {
+ m_OrganizerCore.spawnBinaryDirect(
+ binaryInfo, arguments, m_OrganizerCore.currentProfile()->name(),
+ targetInfo.absolutePath(), "", "");
+ } break;
+ case 2: {
+ ::ShellExecuteW(nullptr, L"open",
+ ToWString(targetInfo.absoluteFilePath()).c_str(),
+ nullptr, nullptr, SW_SHOWNORMAL);
+ } break;
+ default: {
+ // nop
+ } break;
}
+ }
}
-void MainWindow::updateAvailable() {
- for (QAction* action : ui->toolBar->actions()) {
- if (action->text() == tr("Update")) {
- action->setEnabled(true);
- action->setToolTip(tr("Update available"));
- break;
- }
+
+void MainWindow::updateAvailable()
+{
+ for (QAction *action : ui->toolBar->actions()) {
+ if (action->text() == tr("Update")) {
+ action->setEnabled(true);
+ action->setToolTip(tr("Update available"));
+ break;
}
+ }
}
-void MainWindow::motdReceived(const QString& motd) {
- // don't show motd after 5 seconds, may be annoying. Hopefully the user's
- // internet connection is faster next time
- if (m_StartTime.secsTo(QTime::currentTime()) < 5) {
- uint hash = qHash(motd);
- if (hash != m_OrganizerCore.settings().getMotDHash()) {
- MotDDialog dialog(motd);
- dialog.exec();
- m_OrganizerCore.settings().setMotDHash(hash);
- }
+
+void MainWindow::motdReceived(const QString &motd)
+{
+ // don't show motd after 5 seconds, may be annoying. Hopefully the user's
+ // internet connection is faster next time
+ if (m_StartTime.secsTo(QTime::currentTime()) < 5) {
+ uint hash = qHash(motd);
+ if (hash != m_OrganizerCore.settings().getMotDHash()) {
+ MotDDialog dialog(motd);
+ dialog.exec();
+ m_OrganizerCore.settings().setMotDHash(hash);
}
+ }
- ui->actionEndorseMO->setVisible(false);
+ ui->actionEndorseMO->setVisible(false);
}
-void MainWindow::notEndorsedYet() { ui->actionEndorseMO->setVisible(true); }
-void MainWindow::on_dataTree_customContextMenuRequested(const QPoint& pos) {
- QTreeWidget* dataTree = findChild<QTreeWidget*>("dataTree");
- m_ContextItem = dataTree->itemAt(pos.x(), pos.y());
+void MainWindow::notEndorsedYet()
+{
+ ui->actionEndorseMO->setVisible(true);
+}
- QMenu menu;
- if ((m_ContextItem != nullptr) && (m_ContextItem->childCount() == 0)) {
- menu.addAction(tr("Open/Execute"), this, SLOT(openDataFile()));
- menu.addAction(tr("Add as Executable"), this, SLOT(addAsExecutable()));
- QString fileName = m_ContextItem->text(0);
- if (m_PluginContainer.previewGenerator().previewSupported(QFileInfo(fileName).suffix())) {
- menu.addAction(tr("Preview"), this, SLOT(previewDataFile()));
- }
+void MainWindow::on_dataTree_customContextMenuRequested(const QPoint &pos)
+{
+ QTreeWidget *dataTree = findChild<QTreeWidget*>("dataTree");
+ m_ContextItem = dataTree->itemAt(pos.x(), pos.y());
- // offer to hide/unhide file, but not for files from archives
- if (!m_ContextItem->data(0, Qt::UserRole + 1).toBool()) {
- if (m_ContextItem->text(0).endsWith(ModInfo::s_HiddenExt)) {
- menu.addAction(tr("Un-Hide"), this, SLOT(unhideFile()));
- } else {
- menu.addAction(tr("Hide"), this, SLOT(hideFile()));
- }
- }
+ QMenu menu;
+ if ((m_ContextItem != nullptr) && (m_ContextItem->childCount() == 0)) {
+ menu.addAction(tr("Open/Execute"), this, SLOT(openDataFile()));
+ menu.addAction(tr("Add as Executable"), this, SLOT(addAsExecutable()));
- menu.addSeparator();
+ QString fileName = m_ContextItem->text(0);
+ if (m_PluginContainer.previewGenerator().previewSupported(QFileInfo(fileName).suffix())) {
+ menu.addAction(tr("Preview"), this, SLOT(previewDataFile()));
+ }
+
+ // offer to hide/unhide file, but not for files from archives
+ if (!m_ContextItem->data(0, Qt::UserRole + 1).toBool()) {
+ if (m_ContextItem->text(0).endsWith(ModInfo::s_HiddenExt)) {
+ menu.addAction(tr("Un-Hide"), this, SLOT(unhideFile()));
+ } else {
+ menu.addAction(tr("Hide"), this, SLOT(hideFile()));
+ }
}
- menu.addAction(tr("Write To File..."), this, SLOT(writeDataToFile()));
- menu.addAction(tr("Refresh"), this, SLOT(on_btnRefreshData_clicked()));
- menu.exec(dataTree->mapToGlobal(pos));
+ menu.addSeparator();
+ }
+ menu.addAction(tr("Write To File..."), this, SLOT(writeDataToFile()));
+ menu.addAction(tr("Refresh"), this, SLOT(on_btnRefreshData_clicked()));
+
+ menu.exec(dataTree->mapToGlobal(pos));
}
-void MainWindow::on_conflictsCheckBox_toggled(bool) { refreshDataTree(); }
+void MainWindow::on_conflictsCheckBox_toggled(bool)
+{
+ refreshDataTree();
+}
-void MainWindow::on_actionUpdate_triggered() { m_OrganizerCore.startMOUpdate(); }
-void MainWindow::on_actionEndorseMO_triggered() {
- if (QMessageBox::question(
- this, tr("Endorse Mod Organizer"),
- tr("Do you want to endorse Mod Organizer on %1 now?").arg(NexusInterface::instance()->getGameURL()),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- NexusInterface::instance()->requestToggleEndorsement(m_OrganizerCore.managedGame()->nexusModOrganizerID(), true,
- this, QVariant(), QString());
- }
+void MainWindow::on_actionUpdate_triggered()
+{
+ m_OrganizerCore.startMOUpdate();
+}
+
+
+void MainWindow::on_actionEndorseMO_triggered()
+{
+ if (QMessageBox::question(this, tr("Endorse Mod Organizer"),
+ tr("Do you want to endorse Mod Organizer on %1 now?").arg(
+ NexusInterface::instance()->getGameURL()),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ NexusInterface::instance()->requestToggleEndorsement(
+ m_OrganizerCore.managedGame()->nexusModOrganizerID(), true, this, QVariant(), QString());
+ }
}
-void MainWindow::updateDownloadListDelegate() {
- if (m_OrganizerCore.settings().compactDownloads()) {
- ui->downloadView->setItemDelegate(new DownloadListWidgetCompactDelegate(
- m_OrganizerCore.downloadManager(), m_OrganizerCore.settings().metaDownloads(), ui->downloadView,
- ui->downloadView));
- } else {
- ui->downloadView->setItemDelegate(new DownloadListWidgetDelegate(m_OrganizerCore.downloadManager(),
- m_OrganizerCore.settings().metaDownloads(),
- ui->downloadView, ui->downloadView));
- }
- DownloadListSortProxy* sortProxy = new DownloadListSortProxy(m_OrganizerCore.downloadManager(), ui->downloadView);
- sortProxy->setSourceModel(new DownloadList(m_OrganizerCore.downloadManager(), ui->downloadView));
- connect(ui->downloadFilterEdit, SIGNAL(textChanged(QString)), sortProxy, SLOT(updateFilter(QString)));
- connect(ui->downloadFilterEdit, SIGNAL(textChanged(QString)), this, SLOT(downloadFilterChanged(QString)));
+void MainWindow::updateDownloadListDelegate()
+{
+ if (m_OrganizerCore.settings().compactDownloads()) {
+ ui->downloadView->setItemDelegate(
+ new DownloadListWidgetCompactDelegate(m_OrganizerCore.downloadManager(),
+ m_OrganizerCore.settings().metaDownloads(),
+ ui->downloadView,
+ ui->downloadView));
+ } else {
+ ui->downloadView->setItemDelegate(
+ new DownloadListWidgetDelegate(m_OrganizerCore.downloadManager(),
+ m_OrganizerCore.settings().metaDownloads(),
+ ui->downloadView,
+ ui->downloadView));
+ }
- ui->downloadView->setModel(sortProxy);
- ui->downloadView->sortByColumn(1, Qt::DescendingOrder);
- ui->downloadView->header()->resizeSections(QHeaderView::Fixed);
+ DownloadListSortProxy *sortProxy = new DownloadListSortProxy(m_OrganizerCore.downloadManager(), ui->downloadView);
+ sortProxy->setSourceModel(new DownloadList(m_OrganizerCore.downloadManager(), ui->downloadView));
+ connect(ui->downloadFilterEdit, SIGNAL(textChanged(QString)), sortProxy, SLOT(updateFilter(QString)));
+ connect(ui->downloadFilterEdit, SIGNAL(textChanged(QString)), this, SLOT(downloadFilterChanged(QString)));
- connect(ui->downloadView->itemDelegate(), SIGNAL(installDownload(int)), &m_OrganizerCore,
- SLOT(installDownload(int)));
- connect(ui->downloadView->itemDelegate(), SIGNAL(queryInfo(int)), m_OrganizerCore.downloadManager(),
- SLOT(queryInfo(int)));
- connect(ui->downloadView->itemDelegate(), SIGNAL(removeDownload(int, bool)), m_OrganizerCore.downloadManager(),
- SLOT(removeDownload(int, bool)));
- connect(ui->downloadView->itemDelegate(), SIGNAL(restoreDownload(int)), m_OrganizerCore.downloadManager(),
- SLOT(restoreDownload(int)));
- connect(ui->downloadView->itemDelegate(), SIGNAL(cancelDownload(int)), m_OrganizerCore.downloadManager(),
- SLOT(cancelDownload(int)));
- connect(ui->downloadView->itemDelegate(), SIGNAL(pauseDownload(int)), m_OrganizerCore.downloadManager(),
- SLOT(pauseDownload(int)));
- connect(ui->downloadView->itemDelegate(), SIGNAL(resumeDownload(int)), this, SLOT(resumeDownload(int)));
+ ui->downloadView->setModel(sortProxy);
+ ui->downloadView->sortByColumn(1, Qt::DescendingOrder);
+ ui->downloadView->header()->resizeSections(QHeaderView::Fixed);
+
+ connect(ui->downloadView->itemDelegate(), SIGNAL(installDownload(int)), &m_OrganizerCore, SLOT(installDownload(int)));
+ connect(ui->downloadView->itemDelegate(), SIGNAL(queryInfo(int)), m_OrganizerCore.downloadManager(), SLOT(queryInfo(int)));
+ connect(ui->downloadView->itemDelegate(), SIGNAL(removeDownload(int, bool)), m_OrganizerCore.downloadManager(), SLOT(removeDownload(int, bool)));
+ connect(ui->downloadView->itemDelegate(), SIGNAL(restoreDownload(int)), m_OrganizerCore.downloadManager(), SLOT(restoreDownload(int)));
+ connect(ui->downloadView->itemDelegate(), SIGNAL(cancelDownload(int)), m_OrganizerCore.downloadManager(), SLOT(cancelDownload(int)));
+ connect(ui->downloadView->itemDelegate(), SIGNAL(pauseDownload(int)), m_OrganizerCore.downloadManager(), SLOT(pauseDownload(int)));
+ connect(ui->downloadView->itemDelegate(), SIGNAL(resumeDownload(int)), this, SLOT(resumeDownload(int)));
}
-void MainWindow::modDetailsUpdated(bool) {
- if (--m_ModsToUpdate == 0) {
- statusBar()->hide();
- m_ModListSortProxy->setCategoryFilter(
- boost::assign::list_of(CategoryFactory::CATEGORY_SPECIAL_UPDATEAVAILABLE));
- for (int i = 0; i < ui->categoriesList->topLevelItemCount(); ++i) {
- if (ui->categoriesList->topLevelItem(i)->data(0, Qt::UserRole) ==
- CategoryFactory::CATEGORY_SPECIAL_UPDATEAVAILABLE) {
- ui->categoriesList->setCurrentItem(ui->categoriesList->topLevelItem(i));
- break;
- }
- }
- m_RefreshProgress->setVisible(false);
- } else {
- m_RefreshProgress->setValue(m_RefreshProgress->maximum() - m_ModsToUpdate);
+
+void MainWindow::modDetailsUpdated(bool)
+{
+ if (--m_ModsToUpdate == 0) {
+ statusBar()->hide();
+ m_ModListSortProxy->setCategoryFilter(boost::assign::list_of(CategoryFactory::CATEGORY_SPECIAL_UPDATEAVAILABLE));
+ for (int i = 0; i < ui->categoriesList->topLevelItemCount(); ++i) {
+ if (ui->categoriesList->topLevelItem(i)->data(0, Qt::UserRole) == CategoryFactory::CATEGORY_SPECIAL_UPDATEAVAILABLE) {
+ ui->categoriesList->setCurrentItem(ui->categoriesList->topLevelItem(i));
+ break;
+ }
}
+ m_RefreshProgress->setVisible(false);
+ } else {
+ m_RefreshProgress->setValue(m_RefreshProgress->maximum() - m_ModsToUpdate);
+ }
}
-void MainWindow::nxmUpdatesAvailable(const std::vector<int>& modIDs, QVariant userData, QVariant resultData, int) {
- m_ModsToUpdate -= static_cast<int>(modIDs.size());
- QVariantList resultList = resultData.toList();
- for (auto iter = resultList.begin(); iter != resultList.end(); ++iter) {
- QVariantMap result = iter->toMap();
- if (result["id"].toInt() == m_OrganizerCore.managedGame()->nexusModOrganizerID()) {
- if (!result["voted_by_user"].toBool()) {
- ui->actionEndorseMO->setVisible(true);
- }
- } else {
- std::vector<ModInfo::Ptr> info = ModInfo::getByModID(result["id"].toInt());
- for (auto iter = info.begin(); iter != info.end(); ++iter) {
- (*iter)->setNewestVersion(result["version"].toString());
- (*iter)->setNexusDescription(result["description"].toString());
- if (NexusInterface::instance()->getAccessManager()->loggedIn() && result.contains("voted_by_user")) {
- // don't use endorsement info if we're not logged in or if the response doesn't contain it
- (*iter)->setIsEndorsed(result["voted_by_user"].toBool());
- }
- }
+void MainWindow::nxmUpdatesAvailable(const std::vector<int> &modIDs, QVariant userData, QVariant resultData, int)
+{
+ m_ModsToUpdate -= static_cast<int>(modIDs.size());
+ QVariantList resultList = resultData.toList();
+ for (auto iter = resultList.begin(); iter != resultList.end(); ++iter) {
+ QVariantMap result = iter->toMap();
+ if (result["id"].toInt() == m_OrganizerCore.managedGame()->nexusModOrganizerID()) {
+ if (!result["voted_by_user"].toBool()) {
+ ui->actionEndorseMO->setVisible(true);
+ }
+ } else {
+ std::vector<ModInfo::Ptr> info = ModInfo::getByModID(result["id"].toInt());
+ for (auto iter = info.begin(); iter != info.end(); ++iter) {
+ (*iter)->setNewestVersion(result["version"].toString());
+ (*iter)->setNexusDescription(result["description"].toString());
+ if (NexusInterface::instance()->getAccessManager()->loggedIn() &&
+ result.contains("voted_by_user")) {
+ // don't use endorsement info if we're not logged in or if the response doesn't contain it
+ (*iter)->setIsEndorsed(result["voted_by_user"].toBool());
}
+ }
}
+ }
- if (m_ModsToUpdate <= 0) {
- statusBar()->hide();
- m_ModListSortProxy->setCategoryFilter(
- boost::assign::list_of(CategoryFactory::CATEGORY_SPECIAL_UPDATEAVAILABLE));
- for (int i = 0; i < ui->categoriesList->topLevelItemCount(); ++i) {
- if (ui->categoriesList->topLevelItem(i)->data(0, Qt::UserRole) ==
- CategoryFactory::CATEGORY_SPECIAL_UPDATEAVAILABLE) {
- ui->categoriesList->setCurrentItem(ui->categoriesList->topLevelItem(i));
- break;
- }
- }
- } else {
- m_RefreshProgress->setValue(m_RefreshProgress->maximum() - m_ModsToUpdate);
+ if (m_ModsToUpdate <= 0) {
+ statusBar()->hide();
+ m_ModListSortProxy->setCategoryFilter(boost::assign::list_of(CategoryFactory::CATEGORY_SPECIAL_UPDATEAVAILABLE));
+ for (int i = 0; i < ui->categoriesList->topLevelItemCount(); ++i) {
+ if (ui->categoriesList->topLevelItem(i)->data(0, Qt::UserRole) == CategoryFactory::CATEGORY_SPECIAL_UPDATEAVAILABLE) {
+ ui->categoriesList->setCurrentItem(ui->categoriesList->topLevelItem(i));
+ break;
+ }
}
+ } else {
+ m_RefreshProgress->setValue(m_RefreshProgress->maximum() - m_ModsToUpdate);
+ }
}
-void MainWindow::nxmEndorsementToggled(int, QVariant, QVariant resultData, int) {
- if (resultData.toBool()) {
- ui->actionEndorseMO->setVisible(false);
- QMessageBox::question(this, tr("Thank you!"), tr("Thank you for your endorsement!"));
- }
+void MainWindow::nxmEndorsementToggled(int, QVariant, QVariant resultData, int)
+{
+ if (resultData.toBool()) {
+ ui->actionEndorseMO->setVisible(false);
+ QMessageBox::question(this, tr("Thank you!"), tr("Thank you for your endorsement!"));
+ }
- if (!disconnect(sender(), SIGNAL(nxmEndorsementToggled(int, QVariant, QVariant, int)), this,
- SLOT(nxmEndorsementToggled(int, QVariant, QVariant, int)))) {
- qCritical("failed to disconnect endorsement slot");
- }
+ if (!disconnect(sender(), SIGNAL(nxmEndorsementToggled(int, QVariant, QVariant, int)),
+ this, SLOT(nxmEndorsementToggled(int, QVariant, QVariant, int)))) {
+ qCritical("failed to disconnect endorsement slot");
+ }
}
-void MainWindow::nxmDownloadURLs(int, int, QVariant, QVariant resultData, int) {
- QVariantList serverList = resultData.toList();
+void MainWindow::nxmDownloadURLs(int, int, QVariant, QVariant resultData, int)
+{
+ QVariantList serverList = resultData.toList();
- QList<ServerInfo> servers;
- for (const QVariant& server : serverList) {
- QVariantMap serverInfo = server.toMap();
- ServerInfo info;
- info.name = serverInfo["Name"].toString();
- info.premium = serverInfo["IsPremium"].toBool();
- info.lastSeen = QDate::currentDate();
- info.preferred = 0;
- // other keys: ConnectedUsers, Country, URI
- servers.append(info);
- }
- m_OrganizerCore.settings().updateServers(servers);
+ QList<ServerInfo> servers;
+ for (const QVariant &server : serverList) {
+ QVariantMap serverInfo = server.toMap();
+ ServerInfo info;
+ info.name = serverInfo["Name"].toString();
+ info.premium = serverInfo["IsPremium"].toBool();
+ info.lastSeen = QDate::currentDate();
+ info.preferred = 0;
+ // other keys: ConnectedUsers, Country, URI
+ servers.append(info);
+ }
+ m_OrganizerCore.settings().updateServers(servers);
}
-void MainWindow::nxmRequestFailed(int modID, int, QVariant, int, const QString& errorString) {
- if (modID == -1) {
- // must be the update-check that failed
- m_ModsToUpdate = 0;
- statusBar()->hide();
- }
- MessageDialog::showMessage(tr("Request to Nexus failed: %1").arg(errorString), this);
+
+void MainWindow::nxmRequestFailed(int modID, int, QVariant, int, const QString &errorString)
+{
+ if (modID == -1) {
+ // must be the update-check that failed
+ m_ModsToUpdate = 0;
+ statusBar()->hide();
+ }
+ MessageDialog::showMessage(tr("Request to Nexus failed: %1").arg(errorString), this);
}
-BSA::EErrorCode MainWindow::extractBSA(BSA::Archive& archive, BSA::Folder::Ptr folder, const QString& destination,
- QProgressDialog& progress) {
- QDir().mkdir(destination);
- BSA::EErrorCode result = BSA::ERROR_NONE;
- QString errorFile;
- for (unsigned int i = 0; i < folder->getNumFiles(); ++i) {
- BSA::File::Ptr file = folder->getFile(i);
- BSA::EErrorCode res = archive.extract(file, destination.toUtf8().constData());
- if (res != BSA::ERROR_NONE) {
- reportError(tr("failed to read %1: %2").arg(file->getName().c_str()).arg(res));
- result = res;
- }
- progress.setLabelText(file->getName().c_str());
- progress.setValue(progress.value() + 1);
- QCoreApplication::processEvents();
- if (progress.wasCanceled()) {
- result = BSA::ERROR_CANCELED;
- }
+BSA::EErrorCode MainWindow::extractBSA(BSA::Archive &archive, BSA::Folder::Ptr folder, const QString &destination,
+ QProgressDialog &progress)
+{
+ QDir().mkdir(destination);
+ BSA::EErrorCode result = BSA::ERROR_NONE;
+ QString errorFile;
+
+ for (unsigned int i = 0; i < folder->getNumFiles(); ++i) {
+ BSA::File::Ptr file = folder->getFile(i);
+ BSA::EErrorCode res = archive.extract(file, destination.toUtf8().constData());
+ if (res != BSA::ERROR_NONE) {
+ reportError(tr("failed to read %1: %2").arg(file->getName().c_str()).arg(res));
+ result = res;
}
+ progress.setLabelText(file->getName().c_str());
+ progress.setValue(progress.value() + 1);
+ QCoreApplication::processEvents();
+ if (progress.wasCanceled()) {
+ result = BSA::ERROR_CANCELED;
+ }
+ }
- if (result != BSA::ERROR_NONE) {
- if (QMessageBox::critical(this, tr("Error"),
- tr("failed to extract %1 (errorcode %2)").arg(errorFile).arg(result),
- QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) {
- return result;
- }
+ if (result != BSA::ERROR_NONE) {
+ if (QMessageBox::critical(this, tr("Error"), tr("failed to extract %1 (errorcode %2)").arg(errorFile).arg(result),
+ QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) {
+ return result;
}
+ }
- for (unsigned int i = 0; i < folder->getNumSubFolders(); ++i) {
- BSA::Folder::Ptr subFolder = folder->getSubFolder(i);
- BSA::EErrorCode res = extractBSA(archive, subFolder,
- destination.mid(0).append("/").append(subFolder->getName().c_str()), progress);
- if (res != BSA::ERROR_NONE) {
- return res;
- }
+ for (unsigned int i = 0; i < folder->getNumSubFolders(); ++i) {
+ BSA::Folder::Ptr subFolder = folder->getSubFolder(i);
+ BSA::EErrorCode res = extractBSA(archive, subFolder,
+ destination.mid(0).append("/").append(subFolder->getName().c_str()), progress);
+ if (res != BSA::ERROR_NONE) {
+ return res;
}
- return BSA::ERROR_NONE;
+ }
+ return BSA::ERROR_NONE;
}
-bool MainWindow::extractProgress(QProgressDialog& progress, int percentage, std::string fileName) {
- progress.setLabelText(fileName.c_str());
- progress.setValue(percentage);
- QCoreApplication::processEvents();
- return !progress.wasCanceled();
+
+bool MainWindow::extractProgress(QProgressDialog &progress, int percentage, std::string fileName)
+{
+ progress.setLabelText(fileName.c_str());
+ progress.setValue(percentage);
+ QCoreApplication::processEvents();
+ return !progress.wasCanceled();
}
-void MainWindow::extractBSATriggered() {
- QTreeWidgetItem* item = m_ContextItem;
- QString targetFolder = FileDialogMemory::getExistingDirectory("extractBSA", this, tr("Extract BSA"));
- if (!targetFolder.isEmpty()) {
- BSA::Archive archive;
- QString originPath = QDir::fromNativeSeparators(
- ToQString(m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(item->text(1))).getPath()));
- QString archivePath = QString("%1\\%2").arg(originPath).arg(item->text(0));
+void MainWindow::extractBSATriggered()
+{
+ QTreeWidgetItem *item = m_ContextItem;
- BSA::EErrorCode result = archive.read(archivePath.toLocal8Bit().constData(), true);
- if ((result != BSA::ERROR_NONE) && (result != BSA::ERROR_INVALIDHASHES)) {
- reportError(tr("failed to read %1: %2").arg(archivePath).arg(result));
- return;
- }
+ QString targetFolder = FileDialogMemory::getExistingDirectory("extractBSA", this, tr("Extract BSA"));
+ if (!targetFolder.isEmpty()) {
+ BSA::Archive archive;
+ QString originPath = QDir::fromNativeSeparators(ToQString(m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(item->text(1))).getPath()));
+ QString archivePath = QString("%1\\%2").arg(originPath).arg(item->text(0));
- QProgressDialog progress(this);
- progress.setMaximum(100);
- progress.setValue(0);
- progress.show();
- archive.extractAll(QDir::toNativeSeparators(targetFolder).toLocal8Bit().constData(),
- boost::bind(&MainWindow::extractProgress, this, boost::ref(progress), _1, _2));
- if (result == BSA::ERROR_INVALIDHASHES) {
- reportError(tr("This archive contains invalid hashes. Some files may be broken."));
- }
+ BSA::EErrorCode result = archive.read(archivePath.toLocal8Bit().constData(), true);
+ if ((result != BSA::ERROR_NONE) && (result != BSA::ERROR_INVALIDHASHES)) {
+ reportError(tr("failed to read %1: %2").arg(archivePath).arg(result));
+ return;
+ }
+
+ QProgressDialog progress(this);
+ progress.setMaximum(100);
+ progress.setValue(0);
+ progress.show();
+ archive.extractAll(QDir::toNativeSeparators(targetFolder).toLocal8Bit().constData(),
+ boost::bind(&MainWindow::extractProgress, this, boost::ref(progress), _1, _2));
+ if (result == BSA::ERROR_INVALIDHASHES) {
+ reportError(tr("This archive contains invalid hashes. Some files may be broken."));
}
+ }
}
-void MainWindow::displayColumnSelection(const QPoint& pos) {
- QMenu menu;
- // display a list of all headers as checkboxes
- QAbstractItemModel* model = ui->modList->header()->model();
- for (int i = 1; i < model->columnCount(); ++i) {
- QString columnName = model->headerData(i, Qt::Horizontal).toString();
- QCheckBox* checkBox = new QCheckBox(&menu);
- checkBox->setText(columnName);
- checkBox->setChecked(!ui->modList->header()->isSectionHidden(i));
- QWidgetAction* checkableAction = new QWidgetAction(&menu);
- checkableAction->setDefaultWidget(checkBox);
- menu.addAction(checkableAction);
- }
- menu.exec(pos);
+void MainWindow::displayColumnSelection(const QPoint &pos)
+{
+ QMenu menu;
- // view/hide columns depending on check-state
- int i = 1;
- for (const QAction* action : menu.actions()) {
- const QWidgetAction* widgetAction = qobject_cast<const QWidgetAction*>(action);
- if (widgetAction != nullptr) {
- const QCheckBox* checkBox = qobject_cast<const QCheckBox*>(widgetAction->defaultWidget());
- if (checkBox != nullptr) {
- ui->modList->header()->setSectionHidden(i, !checkBox->isChecked());
- }
- }
- ++i;
+ // display a list of all headers as checkboxes
+ QAbstractItemModel *model = ui->modList->header()->model();
+ for (int i = 1; i < model->columnCount(); ++i) {
+ QString columnName = model->headerData(i, Qt::Horizontal).toString();
+ QCheckBox *checkBox = new QCheckBox(&menu);
+ checkBox->setText(columnName);
+ checkBox->setChecked(!ui->modList->header()->isSectionHidden(i));
+ QWidgetAction *checkableAction = new QWidgetAction(&menu);
+ checkableAction->setDefaultWidget(checkBox);
+ menu.addAction(checkableAction);
+ }
+ menu.exec(pos);
+
+ // view/hide columns depending on check-state
+ int i = 1;
+ for (const QAction *action : menu.actions()) {
+ const QWidgetAction *widgetAction = qobject_cast<const QWidgetAction*>(action);
+ if (widgetAction != nullptr) {
+ const QCheckBox *checkBox = qobject_cast<const QCheckBox*>(widgetAction->defaultWidget());
+ if (checkBox != nullptr) {
+ ui->modList->header()->setSectionHidden(i, !checkBox->isChecked());
+ }
}
+ ++i;
+ }
}
-void MainWindow::on_bsaList_itemChanged(QTreeWidgetItem*, int) {
- m_ArchiveListWriter.write();
- m_CheckBSATimer.start(500);
+void MainWindow::on_bsaList_itemChanged(QTreeWidgetItem*, int)
+{
+ m_ArchiveListWriter.write();
+ m_CheckBSATimer.start(500);
}
-void MainWindow::on_actionProblems_triggered() {
- ProblemsDialog problems(m_PluginContainer.plugins<IPluginDiagnose>(), this);
- if (problems.hasProblems()) {
- problems.exec();
- updateProblemsButton();
- }
+void MainWindow::on_actionProblems_triggered()
+{
+ ProblemsDialog problems(m_PluginContainer.plugins<IPluginDiagnose>(), this);
+ if (problems.hasProblems()) {
+ problems.exec();
+ updateProblemsButton();
+ }
}
-void MainWindow::on_actionChange_Game_triggered() {
- if (QMessageBox::question(this, tr("Are you sure?"), tr("This will restart MO, continue?"),
- QMessageBox::Yes | QMessageBox::Cancel) == QMessageBox::Yes) {
- InstanceManager::instance().clearCurrentInstance();
- qApp->exit(INT_MAX);
- }
+void MainWindow::on_actionChange_Game_triggered()
+{
+ if (QMessageBox::question(this, tr("Are you sure?"),
+ tr("This will restart MO, continue?"),
+ QMessageBox::Yes | QMessageBox::Cancel)
+ == QMessageBox::Yes) {
+ InstanceManager::instance().clearCurrentInstance();
+ qApp->exit(INT_MAX);
+ }
}
-void MainWindow::setCategoryListVisible(bool visible) {
- if (visible) {
- ui->categoriesGroup->show();
- ui->displayCategoriesBtn->setText(ToQString(L"\u00ab"));
- } else {
- ui->categoriesGroup->hide();
- ui->displayCategoriesBtn->setText(ToQString(L"\u00bb"));
- }
+void MainWindow::setCategoryListVisible(bool visible)
+{
+ if (visible) {
+ ui->categoriesGroup->show();
+ ui->displayCategoriesBtn->setText(ToQString(L"\u00ab"));
+ } else {
+ ui->categoriesGroup->hide();
+ ui->displayCategoriesBtn->setText(ToQString(L"\u00bb"));
+ }
}
-void MainWindow::on_displayCategoriesBtn_toggled(bool checked) { setCategoryListVisible(checked); }
+void MainWindow::on_displayCategoriesBtn_toggled(bool checked)
+{
+ setCategoryListVisible(checked);
+}
-void MainWindow::editCategories() {
- CategoriesDialog dialog(this);
- if (dialog.exec() == QDialog::Accepted) {
- dialog.commitChanges();
- }
+void MainWindow::editCategories()
+{
+ CategoriesDialog dialog(this);
+ if (dialog.exec() == QDialog::Accepted) {
+ dialog.commitChanges();
+ }
}
-void MainWindow::deselectFilters() { ui->categoriesList->clearSelection(); }
+void MainWindow::deselectFilters()
+{
+ ui->categoriesList->clearSelection();
+}
-void MainWindow::on_categoriesList_customContextMenuRequested(const QPoint& pos) {
- QMenu menu;
- menu.addAction(tr("Edit Categories..."), this, SLOT(editCategories()));
- menu.addAction(tr("Deselect filter"), this, SLOT(deselectFilters()));
+void MainWindow::on_categoriesList_customContextMenuRequested(const QPoint &pos)
+{
+ QMenu menu;
+ menu.addAction(tr("Edit Categories..."), this, SLOT(editCategories()));
+ menu.addAction(tr("Deselect filter"), this, SLOT(deselectFilters()));
- menu.exec(ui->categoriesList->mapToGlobal(pos));
+ menu.exec(ui->categoriesList->mapToGlobal(pos));
}
-void MainWindow::updateESPLock(bool locked) {
- QItemSelection currentSelection = ui->espList->selectionModel()->selection();
- if (currentSelection.count() == 0) {
- // this path is probably useless
- m_OrganizerCore.pluginList()->lockESPIndex(m_ContextRow, locked);
- } else {
- Q_FOREACH (const QModelIndex& idx, currentSelection.indexes()) {
- m_OrganizerCore.pluginList()->lockESPIndex(mapToModel(m_OrganizerCore.pluginList(), idx).row(), locked);
- }
+
+void MainWindow::updateESPLock(bool locked)
+{
+ QItemSelection currentSelection = ui->espList->selectionModel()->selection();
+ if (currentSelection.count() == 0) {
+ // this path is probably useless
+ m_OrganizerCore.pluginList()->lockESPIndex(m_ContextRow, locked);
+ } else {
+ Q_FOREACH (const QModelIndex &idx, currentSelection.indexes()) {
+ m_OrganizerCore.pluginList()->lockESPIndex(mapToModel(m_OrganizerCore.pluginList(), idx).row(), locked);
}
+ }
}
-void MainWindow::lockESPIndex() { updateESPLock(true); }
-void MainWindow::unlockESPIndex() { updateESPLock(false); }
+void MainWindow::lockESPIndex()
+{
+ updateESPLock(true);
+}
-void MainWindow::removeFromToolbar() {
- try {
- Executable& exe = m_OrganizerCore.executablesList()->find(m_ContextAction->text());
- exe.showOnToolbar(false);
- } catch (const std::runtime_error&) {
- qDebug("executable doesn't exist any more");
- }
+void MainWindow::unlockESPIndex()
+{
+ updateESPLock(false);
+}
+
+
+void MainWindow::removeFromToolbar()
+{
+ try {
+ Executable &exe = m_OrganizerCore.executablesList()->find(m_ContextAction->text());
+ exe.showOnToolbar(false);
+ } catch (const std::runtime_error&) {
+ qDebug("executable doesn't exist any more");
+ }
- updateToolBar();
+ updateToolBar();
}
-void MainWindow::toolBar_customContextMenuRequested(const QPoint& point) {
- QAction* action = ui->toolBar->actionAt(point);
- if (action != nullptr) {
- if (action->objectName().startsWith("custom_")) {
- m_ContextAction = action;
- QMenu menu;
- menu.addAction(tr("Remove"), this, SLOT(removeFromToolbar()));
- menu.exec(ui->toolBar->mapToGlobal(point));
- }
+
+void MainWindow::toolBar_customContextMenuRequested(const QPoint &point)
+{
+ QAction *action = ui->toolBar->actionAt(point);
+ if (action != nullptr) {
+ if (action->objectName().startsWith("custom_")) {
+ m_ContextAction = action;
+ QMenu menu;
+ menu.addAction(tr("Remove"), this, SLOT(removeFromToolbar()));
+ menu.exec(ui->toolBar->mapToGlobal(point));
}
+ }
}
-void MainWindow::on_espList_customContextMenuRequested(const QPoint& pos) {
- m_ContextRow = m_PluginListSortProxy->mapToSource(ui->espList->indexAt(pos)).row();
+void MainWindow::on_espList_customContextMenuRequested(const QPoint &pos)
+{
+ m_ContextRow = m_PluginListSortProxy->mapToSource(ui->espList->indexAt(pos)).row();
- QMenu menu;
- menu.addAction(tr("Enable all"), m_OrganizerCore.pluginList(), SLOT(enableAll()));
- menu.addAction(tr("Disable all"), m_OrganizerCore.pluginList(), SLOT(disableAll()));
+ QMenu menu;
+ menu.addAction(tr("Enable all"), m_OrganizerCore.pluginList(), SLOT(enableAll()));
+ menu.addAction(tr("Disable all"), m_OrganizerCore.pluginList(), SLOT(disableAll()));
- QItemSelection currentSelection = ui->espList->selectionModel()->selection();
- bool hasLocked = false;
- bool hasUnlocked = false;
- for (const QModelIndex& idx : currentSelection.indexes()) {
- int row = m_PluginListSortProxy->mapToSource(idx).row();
- if (m_OrganizerCore.pluginList()->isEnabled(row)) {
- if (m_OrganizerCore.pluginList()->isESPLocked(row)) {
- hasLocked = true;
- } else {
- hasUnlocked = true;
- }
- }
+ QItemSelection currentSelection = ui->espList->selectionModel()->selection();
+ bool hasLocked = false;
+ bool hasUnlocked = false;
+ for (const QModelIndex &idx : currentSelection.indexes()) {
+ int row = m_PluginListSortProxy->mapToSource(idx).row();
+ if (m_OrganizerCore.pluginList()->isEnabled(row)) {
+ if (m_OrganizerCore.pluginList()->isESPLocked(row)) {
+ hasLocked = true;
+ } else {
+ hasUnlocked = true;
+ }
}
+ }
- menu.addSeparator();
+ menu.addSeparator();
- if (hasLocked) {
- menu.addAction(tr("Unlock load order"), this, SLOT(unlockESPIndex()));
- }
- if (hasUnlocked) {
- menu.addAction(tr("Lock load order"), this, SLOT(lockESPIndex()));
- }
+ if (hasLocked) {
+ menu.addAction(tr("Unlock load order"), this, SLOT(unlockESPIndex()));
+ }
+ if (hasUnlocked) {
+ menu.addAction(tr("Lock load order"), this, SLOT(lockESPIndex()));
+ }
- try {
- menu.exec(ui->espList->mapToGlobal(pos));
- } catch (const std::exception& e) {
- reportError(tr("Exception: ").arg(e.what()));
- } catch (...) {
- reportError(tr("Unknown exception"));
- }
+ try {
+ menu.exec(ui->espList->mapToGlobal(pos));
+ } catch (const std::exception &e) {
+ reportError(tr("Exception: ").arg(e.what()));
+ } catch (...) {
+ reportError(tr("Unknown exception"));
+ }
}
-void MainWindow::on_groupCombo_currentIndexChanged(int index) {
- if (m_ModListSortProxy == nullptr) {
- return;
- }
- QAbstractProxyModel* newModel = nullptr;
- switch (index) {
+void MainWindow::on_groupCombo_currentIndexChanged(int index)
+{
+ if (m_ModListSortProxy == nullptr) {
+ return;
+ }
+ QAbstractProxyModel *newModel = nullptr;
+ switch (index) {
case 1: {
- newModel = new QtGroupingProxy(m_OrganizerCore.modList(), QModelIndex(), ModList::COL_CATEGORY, Qt::UserRole, 0,
- Qt::UserRole + 2);
- } break;
+ newModel = new QtGroupingProxy(m_OrganizerCore.modList(), QModelIndex(), ModList::COL_CATEGORY, Qt::UserRole,
+ 0, Qt::UserRole + 2);
+ } break;
case 2: {
- newModel =
- new QtGroupingProxy(m_OrganizerCore.modList(), QModelIndex(), ModList::COL_MODID, Qt::DisplayRole,
- QtGroupingProxy::FLAG_NOGROUPNAME | QtGroupingProxy::FLAG_NOSINGLE, Qt::UserRole + 2);
- } break;
- default: { newModel = nullptr; } break;
- }
+ newModel = new QtGroupingProxy(m_OrganizerCore.modList(), QModelIndex(), ModList::COL_MODID, Qt::DisplayRole,
+ QtGroupingProxy::FLAG_NOGROUPNAME | QtGroupingProxy::FLAG_NOSINGLE,
+ Qt::UserRole + 2);
+ } break;
+ default: {
+ newModel = nullptr;
+ } break;
+ }
- if (newModel != nullptr) {
+ if (newModel != nullptr) {
#ifdef TEST_MODELS
- new ModelTest(newModel, this);
+ new ModelTest(newModel, this);
#endif // TEST_MODELS
- m_ModListSortProxy->setSourceModel(newModel);
- connect(ui->modList, SIGNAL(expanded(QModelIndex)), newModel, SLOT(expanded(QModelIndex)));
- connect(ui->modList, SIGNAL(collapsed(QModelIndex)), newModel, SLOT(collapsed(QModelIndex)));
- connect(newModel, SIGNAL(expandItem(QModelIndex)), this, SLOT(expandModList(QModelIndex)));
- } else {
- m_ModListSortProxy->setSourceModel(m_OrganizerCore.modList());
- }
- modFilterActive(m_ModListSortProxy->isFilterActive());
+ m_ModListSortProxy->setSourceModel(newModel);
+ connect(ui->modList, SIGNAL(expanded(QModelIndex)),newModel, SLOT(expanded(QModelIndex)));
+ connect(ui->modList, SIGNAL(collapsed(QModelIndex)), newModel, SLOT(collapsed(QModelIndex)));
+ connect(newModel, SIGNAL(expandItem(QModelIndex)), this, SLOT(expandModList(QModelIndex)));
+ } else {
+ m_ModListSortProxy->setSourceModel(m_OrganizerCore.modList());
+ }
+ modFilterActive(m_ModListSortProxy->isFilterActive());
}
-const Executable& MainWindow::getSelectedExecutable() const {
- QString name = ui->executablesListBox->itemText(ui->executablesListBox->currentIndex());
- return m_OrganizerCore.executablesList()->find(name);
+const Executable &MainWindow::getSelectedExecutable() const
+{
+ QString name = ui->executablesListBox->itemText(ui->executablesListBox->currentIndex());
+ return m_OrganizerCore.executablesList()->find(name);
}
-Executable& MainWindow::getSelectedExecutable() {
- QString name = ui->executablesListBox->itemText(ui->executablesListBox->currentIndex());
- return m_OrganizerCore.executablesList()->find(name);
+Executable &MainWindow::getSelectedExecutable()
+{
+ QString name = ui->executablesListBox->itemText(ui->executablesListBox->currentIndex());
+ return m_OrganizerCore.executablesList()->find(name);
}
-void MainWindow::on_linkButton_pressed() {
- const Executable& selectedExecutable(getSelectedExecutable());
+void MainWindow::on_linkButton_pressed()
+{
+ const Executable &selectedExecutable(getSelectedExecutable());
- const QIcon addIcon(":/MO/gui/link");
- const QIcon removeIcon(":/MO/gui/remove");
+ const QIcon addIcon(":/MO/gui/link");
+ const QIcon removeIcon(":/MO/gui/remove");
- const QFileInfo linkDesktopFile(getDesktopLinkfile(selectedExecutable));
- const QFileInfo linkMenuFile(getStartMenuLinkfile(selectedExecutable));
+ const QFileInfo linkDesktopFile(getDesktopLinkfile(selectedExecutable));
+ const QFileInfo linkMenuFile(getStartMenuLinkfile(selectedExecutable));
- ui->linkButton->menu()
- ->actions()
- .at(static_cast<int>(ShortcutType::Toolbar))
- ->setIcon(selectedExecutable.isShownOnToolbar() ? removeIcon : addIcon);
- ui->linkButton->menu()
- ->actions()
- .at(static_cast<int>(ShortcutType::Desktop))
- ->setIcon(linkDesktopFile.exists() ? removeIcon : addIcon);
- ui->linkButton->menu()
- ->actions()
- .at(static_cast<int>(ShortcutType::StartMenu))
- ->setIcon(linkMenuFile.exists() ? removeIcon : addIcon);
+ ui->linkButton->menu()->actions().at(static_cast<int>(ShortcutType::Toolbar))->setIcon(selectedExecutable.isShownOnToolbar() ? removeIcon : addIcon);
+ ui->linkButton->menu()->actions().at(static_cast<int>(ShortcutType::Desktop))->setIcon(linkDesktopFile.exists() ? removeIcon : addIcon);
+ ui->linkButton->menu()->actions().at(static_cast<int>(ShortcutType::StartMenu))->setIcon(linkMenuFile.exists() ? removeIcon : addIcon);
}
-void MainWindow::on_showHiddenBox_toggled(bool checked) { m_OrganizerCore.downloadManager()->setShowHidden(checked); }
+void MainWindow::on_showHiddenBox_toggled(bool checked)
+{
+ m_OrganizerCore.downloadManager()->setShowHidden(checked);
+}
-void MainWindow::createStdoutPipe(HANDLE* stdOutRead, HANDLE* stdOutWrite) {
- SECURITY_ATTRIBUTES secAttributes;
- secAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
- secAttributes.bInheritHandle = TRUE;
- secAttributes.lpSecurityDescriptor = nullptr;
- if (!::CreatePipe(stdOutRead, stdOutWrite, &secAttributes, 0)) {
- qCritical("failed to create stdout reroute");
- }
+void MainWindow::createStdoutPipe(HANDLE *stdOutRead, HANDLE *stdOutWrite)
+{
+ SECURITY_ATTRIBUTES secAttributes;
+ secAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
+ secAttributes.bInheritHandle = TRUE;
+ secAttributes.lpSecurityDescriptor = nullptr;
- if (!::SetHandleInformation(*stdOutRead, HANDLE_FLAG_INHERIT, 0)) {
- qCritical("failed to correctly set up the stdout reroute");
- *stdOutWrite = *stdOutRead = INVALID_HANDLE_VALUE;
- }
+ if (!::CreatePipe(stdOutRead, stdOutWrite, &secAttributes, 0)) {
+ qCritical("failed to create stdout reroute");
+ }
+
+ if (!::SetHandleInformation(*stdOutRead, HANDLE_FLAG_INHERIT, 0)) {
+ qCritical("failed to correctly set up the stdout reroute");
+ *stdOutWrite = *stdOutRead = INVALID_HANDLE_VALUE;
+ }
}
-std::string MainWindow::readFromPipe(HANDLE stdOutRead) {
- static const int chunkSize = 128;
- std::string result;
+std::string MainWindow::readFromPipe(HANDLE stdOutRead)
+{
+ static const int chunkSize = 128;
+ std::string result;
- char buffer[chunkSize + 1];
- buffer[chunkSize] = '\0';
+ char buffer[chunkSize + 1];
+ buffer[chunkSize] = '\0';
- DWORD read = 1;
- while (read > 0) {
- if (!::ReadFile(stdOutRead, buffer, chunkSize, &read, nullptr)) {
- break;
- }
- if (read > 0) {
- result.append(buffer, read);
- if (read < chunkSize) {
- break;
- }
- }
+ DWORD read = 1;
+ while (read > 0) {
+ if (!::ReadFile(stdOutRead, buffer, chunkSize, &read, nullptr)) {
+ break;
+ }
+ if (read > 0) {
+ result.append(buffer, read);
+ if (read < chunkSize) {
+ break;
+ }
}
- return result;
+ }
+ return result;
}
-void MainWindow::processLOOTOut(const std::string& lootOut, std::string& errorMessages, QProgressDialog& dialog) {
- std::vector<std::string> lines;
- boost::split(lines, lootOut, boost::is_any_of("\r\n"));
+void MainWindow::processLOOTOut(const std::string &lootOut, std::string &errorMessages, QProgressDialog &dialog)
+{
+ std::vector<std::string> lines;
+ boost::split(lines, lootOut, boost::is_any_of("\r\n"));
- std::tr1::regex exRequires("\"([^\"]*)\" requires \"([^\"]*)\", but it is missing\\.");
- std::tr1::regex exIncompatible("\"([^\"]*)\" is incompatible with \"([^\"]*)\", but both are present\\.");
+ std::tr1::regex exRequires("\"([^\"]*)\" requires \"([^\"]*)\", but it is missing\\.");
+ std::tr1::regex exIncompatible("\"([^\"]*)\" is incompatible with \"([^\"]*)\", but both are present\\.");
- for (const std::string& line : lines) {
- if (line.length() > 0) {
- size_t progidx = line.find("[progress]");
- size_t erroridx = line.find("[error]");
- if (progidx != std::string::npos) {
- dialog.setLabelText(line.substr(progidx + 11).c_str());
- } else if (erroridx != std::string::npos) {
- qWarning("%s", line.c_str());
- errorMessages.append(boost::algorithm::trim_copy(line.substr(erroridx + 8)) + "\n");
- } else {
- std::tr1::smatch match;
- if (std::tr1::regex_match(line, match, exRequires)) {
- std::string modName(match[1].first, match[1].second);
- std::string dependency(match[2].first, match[2].second);
- m_OrganizerCore.pluginList()->addInformation(
- modName.c_str(), tr("depends on missing \"%1\"").arg(dependency.c_str()));
- } else if (std::tr1::regex_match(line, match, exIncompatible)) {
- std::string modName(match[1].first, match[1].second);
- std::string dependency(match[2].first, match[2].second);
- m_OrganizerCore.pluginList()->addInformation(
- modName.c_str(), tr("incompatible with \"%1\"").arg(dependency.c_str()));
- } else {
- qDebug("[loot] %s", line.c_str());
- }
- }
+ for (const std::string &line : lines) {
+ if (line.length() > 0) {
+ size_t progidx = line.find("[progress]");
+ size_t erroridx = line.find("[error]");
+ if (progidx != std::string::npos) {
+ dialog.setLabelText(line.substr(progidx + 11).c_str());
+ } else if (erroridx != std::string::npos) {
+ qWarning("%s", line.c_str());
+ errorMessages.append(boost::algorithm::trim_copy(line.substr(erroridx + 8)) + "\n");
+ } else {
+ std::tr1::smatch match;
+ if (std::tr1::regex_match(line, match, exRequires)) {
+ std::string modName(match[1].first, match[1].second);
+ std::string dependency(match[2].first, match[2].second);
+ m_OrganizerCore.pluginList()->addInformation(modName.c_str(), tr("depends on missing \"%1\"").arg(dependency.c_str()));
+ } else if (std::tr1::regex_match(line, match, exIncompatible)) {
+ std::string modName(match[1].first, match[1].second);
+ std::string dependency(match[2].first, match[2].second);
+ m_OrganizerCore.pluginList()->addInformation(modName.c_str(), tr("incompatible with \"%1\"").arg(dependency.c_str()));
+ } else {
+ qDebug("[loot] %s", line.c_str());
}
+ }
}
+ }
}
-void MainWindow::on_bossButton_clicked() {
- std::string reportURL;
- std::string errorMessages;
+void MainWindow::on_bossButton_clicked()
+{
+ std::string reportURL;
+ std::string errorMessages;
- // m_OrganizerCore.currentProfile()->writeModlistNow();
- m_OrganizerCore.savePluginList();
- // Create a backup of the load orders w/ LOOT in name
- // to make sure that any sorting is easily undo-able.
- // Need to figure out how I want to do that.
-
- bool success = false;
+ //m_OrganizerCore.currentProfile()->writeModlistNow();
+ m_OrganizerCore.savePluginList();
+ //Create a backup of the load orders w/ LOOT in name
+ //to make sure that any sorting is easily undo-able.
+ //Need to figure out how I want to do that.
- try {
- setEnabled(false);
- ON_BLOCK_EXIT([&]() { setEnabled(true); });
- QProgressDialog dialog(this);
- dialog.setLabelText(tr("Please wait while LOOT is running"));
- dialog.setMaximum(0);
- dialog.show();
+ bool success = false;
- QString outPath = QDir::temp().absoluteFilePath("lootreport.json");
+ try {
+ setEnabled(false);
+ ON_BLOCK_EXIT([&] () { setEnabled(true); });
+ QProgressDialog dialog(this);
+ dialog.setLabelText(tr("Please wait while LOOT is running"));
+ dialog.setMaximum(0);
+ dialog.show();
- QStringList parameters;
- parameters << "--game" << m_OrganizerCore.managedGame()->gameShortName() << "--gamePath"
- << QString("\"%1\"").arg(m_OrganizerCore.managedGame()->gameDirectory().absolutePath())
- << "--pluginListPath" << QString("\"%1/loadorder.txt\"").arg(m_OrganizerCore.profilePath())
- << "--out" << QString("\"%1\"").arg(outPath);
+ QString outPath = QDir::temp().absoluteFilePath("lootreport.json");
+
+ QStringList parameters;
+ parameters << "--game" << m_OrganizerCore.managedGame()->gameShortName()
+ << "--gamePath" << QString("\"%1\"").arg(m_OrganizerCore.managedGame()->gameDirectory().absolutePath())
+ << "--pluginListPath" << QString("\"%1/loadorder.txt\"").arg(m_OrganizerCore.profilePath())
+ << "--out" << QString("\"%1\"").arg(outPath);
- if (m_DidUpdateMasterList) {
- parameters << "--skipUpdateMasterlist";
- }
- HANDLE stdOutWrite = INVALID_HANDLE_VALUE;
- HANDLE stdOutRead = INVALID_HANDLE_VALUE;
- createStdoutPipe(&stdOutRead, &stdOutWrite);
- try {
- m_OrganizerCore.prepareVFS();
- } catch (const std::exception& e) {
- QMessageBox::warning(qApp->activeWindow(), tr("Error"), e.what());
- return;
- }
+ if (m_DidUpdateMasterList) {
+ parameters << "--skipUpdateMasterlist";
+ }
+ HANDLE stdOutWrite = INVALID_HANDLE_VALUE;
+ HANDLE stdOutRead = INVALID_HANDLE_VALUE;
+ createStdoutPipe(&stdOutRead, &stdOutWrite);
+ try {
+ m_OrganizerCore.prepareVFS();
+ } catch (const std::exception &e) {
+ QMessageBox::warning(qApp->activeWindow(), tr("Error"), e.what());
+ return;
+ }
- HANDLE loot = startBinary(QFileInfo(qApp->applicationDirPath() + "/loot/lootcli.exe"), parameters.join(" "),
- qApp->applicationDirPath() + "/loot", true, stdOutWrite);
+ HANDLE loot = startBinary(QFileInfo(qApp->applicationDirPath() + "/loot/lootcli.exe"),
+ parameters.join(" "),
+ qApp->applicationDirPath() + "/loot",
+ true,
+ stdOutWrite);
- // we don't use the write end
- ::CloseHandle(stdOutWrite);
+ // we don't use the write end
+ ::CloseHandle(stdOutWrite);
- m_OrganizerCore.pluginList()->clearAdditionalInformation();
+ m_OrganizerCore.pluginList()->clearAdditionalInformation();
- DWORD retLen;
- JOBOBJECT_BASIC_PROCESS_ID_LIST info;
- HANDLE processHandle = loot;
+ DWORD retLen;
+ JOBOBJECT_BASIC_PROCESS_ID_LIST info;
+ HANDLE processHandle = loot;
- if (loot != INVALID_HANDLE_VALUE) {
- bool isJobHandle = true;
- ULONG lastProcessID;
- DWORD res = ::MsgWaitForMultipleObjects(1, &loot, false, 100, QS_KEY | QS_MOUSE);
- while ((res != WAIT_FAILED) && (res != WAIT_OBJECT_0)) {
- if (isJobHandle) {
- if (::QueryInformationJobObject(loot, JobObjectBasicProcessIdList, &info, sizeof(info), &retLen) >
- 0) {
- if (info.NumberOfProcessIdsInList == 0) {
- qDebug("no more processes in job");
- break;
- } else {
- if (lastProcessID != info.ProcessIdList[0]) {
- lastProcessID = info.ProcessIdList[0];
- if (processHandle != loot) {
- ::CloseHandle(processHandle);
- }
- processHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, lastProcessID);
- }
- }
- } else {
- // the info-object I passed only provides space for 1 process id. but since this code only cares
- // about whether there is more than one that's good enough. ERROR_MORE_DATA simply signals there
- // are at least two processes running. any other error probably means the handle is a regular
- // process handle, probably caused by running MO in a job without the right to break out.
- if (::GetLastError() != ERROR_MORE_DATA) {
- isJobHandle = false;
- }
- }
+ if (loot != INVALID_HANDLE_VALUE) {
+ bool isJobHandle = true;
+ ULONG lastProcessID;
+ DWORD res = ::MsgWaitForMultipleObjects(1, &loot, false, 100, QS_KEY | QS_MOUSE);
+ while ((res != WAIT_FAILED) && (res != WAIT_OBJECT_0)) {
+ if (isJobHandle) {
+ if (::QueryInformationJobObject(loot, JobObjectBasicProcessIdList, &info, sizeof(info), &retLen) > 0) {
+ if (info.NumberOfProcessIdsInList == 0) {
+ qDebug("no more processes in job");
+ break;
+ } else {
+ if (lastProcessID != info.ProcessIdList[0]) {
+ lastProcessID = info.ProcessIdList[0];
+ if (processHandle != loot) {
+ ::CloseHandle(processHandle);
}
+ processHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, lastProcessID);
+ }
+ }
+ } else {
+ // the info-object I passed only provides space for 1 process id. but since this code only cares about whether there
+ // is more than one that's good enough. ERROR_MORE_DATA simply signals there are at least two processes running.
+ // any other error probably means the handle is a regular process handle, probably caused by running MO in a job without
+ // the right to break out.
+ if (::GetLastError() != ERROR_MORE_DATA) {
+ isJobHandle = false;
+ }
+ }
+ }
- if (dialog.wasCanceled()) {
- if (isJobHandle) {
- ::TerminateJobObject(loot, 1);
- } else {
- ::TerminateProcess(loot, 1);
- }
- }
+ if (dialog.wasCanceled()) {
+ if (isJobHandle) {
+ ::TerminateJobObject(loot, 1);
+ } else {
+ ::TerminateProcess(loot, 1);
+ }
+ }
- // keep processing events so the app doesn't appear dead
- QCoreApplication::processEvents();
- std::string lootOut = readFromPipe(stdOutRead);
- processLOOTOut(lootOut, errorMessages, dialog);
+ // keep processing events so the app doesn't appear dead
+ QCoreApplication::processEvents();
+ std::string lootOut = readFromPipe(stdOutRead);
+ processLOOTOut(lootOut, errorMessages, dialog);
- res = ::MsgWaitForMultipleObjects(1, &loot, false, 100, QS_KEY | QS_MOUSE);
- }
+ res = ::MsgWaitForMultipleObjects(1, &loot, false, 100, QS_KEY | QS_MOUSE);
+ }
- std::string remainder = readFromPipe(stdOutRead).c_str();
- if (remainder.length() > 0) {
- processLOOTOut(remainder, errorMessages, dialog);
- }
- DWORD exitCode = 0UL;
- ::GetExitCodeProcess(processHandle, &exitCode);
- ::CloseHandle(processHandle);
- if (exitCode != 0UL) {
- reportError(tr("loot failed. Exit code was: %1").arg(exitCode));
- return;
- } else {
- success = true;
- QFile outFile(outPath);
- outFile.open(QIODevice::ReadOnly);
- QJsonDocument doc = QJsonDocument::fromJson(outFile.readAll());
- QJsonArray array = doc.array();
- for (auto iter = array.begin(); iter != array.end(); ++iter) {
- QJsonObject pluginObj = (*iter).toObject();
- QJsonArray pluginMessages = pluginObj["messages"].toArray();
- for (auto msgIter = pluginMessages.begin(); msgIter != pluginMessages.end(); ++msgIter) {
- QJsonObject msg = (*msgIter).toObject();
- m_OrganizerCore.pluginList()->addInformation(
- pluginObj["name"].toString(),
- QString("%1: %2").arg(msg["type"].toString(), msg["message"].toString()));
- }
- if (pluginObj["dirty"].toString() == "yes")
- m_OrganizerCore.pluginList()->addInformation(pluginObj["name"].toString(), "dirty");
- }
- }
- } else {
- reportError(tr("failed to start loot"));
+ std::string remainder = readFromPipe(stdOutRead).c_str();
+ if (remainder.length() > 0) {
+ processLOOTOut(remainder, errorMessages, dialog);
+ }
+ DWORD exitCode = 0UL;
+ ::GetExitCodeProcess(processHandle, &exitCode);
+ ::CloseHandle(processHandle);
+ if (exitCode != 0UL) {
+ reportError(tr("loot failed. Exit code was: %1").arg(exitCode));
+ return;
+ } else {
+ success = true;
+ QFile outFile(outPath);
+ outFile.open(QIODevice::ReadOnly);
+ QJsonDocument doc = QJsonDocument::fromJson(outFile.readAll());
+ QJsonArray array = doc.array();
+ for (auto iter = array.begin(); iter != array.end(); ++iter) {
+ QJsonObject pluginObj = (*iter).toObject();
+ QJsonArray pluginMessages = pluginObj["messages"].toArray();
+ for (auto msgIter = pluginMessages.begin(); msgIter != pluginMessages.end(); ++msgIter) {
+ QJsonObject msg = (*msgIter).toObject();
+ m_OrganizerCore.pluginList()->addInformation(pluginObj["name"].toString(),
+ QString("%1: %2").arg(msg["type"].toString(), msg["message"].toString()));
+ }
+ if (pluginObj["dirty"].toString() == "yes")
+ m_OrganizerCore.pluginList()->addInformation(pluginObj["name"].toString(), "dirty");
}
- } catch (const std::exception& e) {
- reportError(tr("failed to run loot: %1").arg(e.what()));
- }
- if (errorMessages.length() > 0) {
- QMessageBox* warn =
- new QMessageBox(QMessageBox::Warning, tr("Errors occured"), errorMessages.c_str(), QMessageBox::Ok, this);
- warn->setModal(false);
- warn->show();
+ }
+ } else {
+ reportError(tr("failed to start loot"));
}
+ } catch (const std::exception &e) {
+ reportError(tr("failed to run loot: %1").arg(e.what()));
+ }
- if (success) {
- m_DidUpdateMasterList = true;
- /*if (reportURL.length() > 0) {
- m_IntegratedBrowser.setWindowTitle("LOOT Report");
- QString report(reportURL.c_str());
- QStringList temp = report.split("?");
- QUrl url = QUrl::fromLocalFile(temp.at(0));
- if (temp.size() > 1) {
- url.setQuery(temp.at(1).toUtf8());
- }
- m_IntegratedBrowser.openUrl(url);
- }*/
+ if (errorMessages.length() > 0) {
+ QMessageBox *warn = new QMessageBox(QMessageBox::Warning, tr("Errors occured"), errorMessages.c_str(), QMessageBox::Ok, this);
+ warn->setModal(false);
+ warn->show();
+ }
- // if the game specifies load order by file time, our own load order file needs to be removed because it's
- // outdated. refreshESPList will then use the file time as the load order.
- if (m_OrganizerCore.managedGame()->loadOrderMechanism() == IPluginGame::LoadOrderMechanism::FileTime) {
- qDebug("removing loadorder.txt");
- QFile::remove(m_OrganizerCore.currentProfile()->getLoadOrderFileName());
- }
- m_OrganizerCore.refreshESPList();
- m_OrganizerCore.savePluginList();
+ if (success) {
+ m_DidUpdateMasterList = true;
+ /*if (reportURL.length() > 0) {
+ m_IntegratedBrowser.setWindowTitle("LOOT Report");
+ QString report(reportURL.c_str());
+ QStringList temp = report.split("?");
+ QUrl url = QUrl::fromLocalFile(temp.at(0));
+ if (temp.size() > 1) {
+ url.setQuery(temp.at(1).toUtf8());
+ }
+ m_IntegratedBrowser.openUrl(url);
+ }*/
+
+ // if the game specifies load order by file time, our own load order file needs to be removed because it's outdated.
+ // refreshESPList will then use the file time as the load order.
+ if (m_OrganizerCore.managedGame()->loadOrderMechanism() == IPluginGame::LoadOrderMechanism::FileTime) {
+ qDebug("removing loadorder.txt");
+ QFile::remove(m_OrganizerCore.currentProfile()->getLoadOrderFileName());
}
+ m_OrganizerCore.refreshESPList();
+ m_OrganizerCore.savePluginList();
+ }
}
-const char* MainWindow::PATTERN_BACKUP_GLOB = ".????_??_??_??_??_??";
-const char* MainWindow::PATTERN_BACKUP_REGEX = "\\.(\\d\\d\\d\\d_\\d\\d_\\d\\d_\\d\\d_\\d\\d_\\d\\d)";
-const char* MainWindow::PATTERN_BACKUP_DATE = "yyyy_MM_dd_hh_mm_ss";
-bool MainWindow::createBackup(const QString& filePath, const QDateTime& time) {
- QString outPath = filePath + "." + time.toString(PATTERN_BACKUP_DATE);
- if (shellCopy(QStringList(filePath), QStringList(outPath), this)) {
- QFileInfo fileInfo(filePath);
- removeOldFiles(fileInfo.absolutePath(), fileInfo.fileName() + PATTERN_BACKUP_GLOB, 3, QDir::Name);
- return true;
- } else {
- return false;
- }
+const char *MainWindow::PATTERN_BACKUP_GLOB = ".????_??_??_??_??_??";
+const char *MainWindow::PATTERN_BACKUP_REGEX = "\\.(\\d\\d\\d\\d_\\d\\d_\\d\\d_\\d\\d_\\d\\d_\\d\\d)";
+const char *MainWindow::PATTERN_BACKUP_DATE = "yyyy_MM_dd_hh_mm_ss";
+
+
+bool MainWindow::createBackup(const QString &filePath, const QDateTime &time)
+{
+ QString outPath = filePath + "." + time.toString(PATTERN_BACKUP_DATE);
+ if (shellCopy(QStringList(filePath), QStringList(outPath), this)) {
+ QFileInfo fileInfo(filePath);
+ removeOldFiles(fileInfo.absolutePath(), fileInfo.fileName() + PATTERN_BACKUP_GLOB, 3, QDir::Name);
+ return true;
+ } else {
+ return false;
+ }
}
-void MainWindow::on_saveButton_clicked() {
- m_OrganizerCore.savePluginList();
- QDateTime now = QDateTime::currentDateTime();
- if (createBackup(m_OrganizerCore.currentProfile()->getPluginsFileName(), now) &&
- createBackup(m_OrganizerCore.currentProfile()->getLoadOrderFileName(), now) &&
- createBackup(m_OrganizerCore.currentProfile()->getLockedOrderFileName(), now)) {
- MessageDialog::showMessage(tr("Backup of load order created"), this);
- }
+void MainWindow::on_saveButton_clicked()
+{
+ m_OrganizerCore.savePluginList();
+ QDateTime now = QDateTime::currentDateTime();
+ if (createBackup(m_OrganizerCore.currentProfile()->getPluginsFileName(), now)
+ && createBackup(m_OrganizerCore.currentProfile()->getLoadOrderFileName(), now)
+ && createBackup(m_OrganizerCore.currentProfile()->getLockedOrderFileName(), now)) {
+ MessageDialog::showMessage(tr("Backup of load order created"), this);
+ }
}
-QString MainWindow::queryRestore(const QString& filePath) {
- QFileInfo pluginFileInfo(filePath);
- QString pattern = pluginFileInfo.fileName() + ".*";
- QFileInfoList files = pluginFileInfo.absoluteDir().entryInfoList(QStringList(pattern), QDir::Files, QDir::Name);
+QString MainWindow::queryRestore(const QString &filePath)
+{
+ QFileInfo pluginFileInfo(filePath);
+ QString pattern = pluginFileInfo.fileName() + ".*";
+ QFileInfoList files = pluginFileInfo.absoluteDir().entryInfoList(QStringList(pattern), QDir::Files, QDir::Name);
- SelectionDialog dialog(tr("Choose backup to restore"), this);
- QRegExp exp(pluginFileInfo.fileName() + PATTERN_BACKUP_REGEX);
- QRegExp exp2(pluginFileInfo.fileName() + "\\.(.*)");
- for (const QFileInfo& info : files) {
- if (exp.exactMatch(info.fileName())) {
- QDateTime time = QDateTime::fromString(exp.cap(1), PATTERN_BACKUP_DATE);
- dialog.addChoice(time.toString(), "", exp.cap(1));
- } else if (exp2.exactMatch(info.fileName())) {
- dialog.addChoice(exp2.cap(1), "", exp2.cap(1));
- }
+ SelectionDialog dialog(tr("Choose backup to restore"), this);
+ QRegExp exp(pluginFileInfo.fileName() + PATTERN_BACKUP_REGEX);
+ QRegExp exp2(pluginFileInfo.fileName() + "\\.(.*)");
+ for(const QFileInfo &info : files) {
+ if (exp.exactMatch(info.fileName())) {
+ QDateTime time = QDateTime::fromString(exp.cap(1), PATTERN_BACKUP_DATE);
+ dialog.addChoice(time.toString(), "", exp.cap(1));
+ } else if (exp2.exactMatch(info.fileName())) {
+ dialog.addChoice(exp2.cap(1), "", exp2.cap(1));
}
+ }
- if (dialog.numChoices() == 0) {
- QMessageBox::information(this, tr("No Backups"), tr("There are no backups to restore"));
- return QString();
- }
+ if (dialog.numChoices() == 0) {
+ QMessageBox::information(this, tr("No Backups"), tr("There are no backups to restore"));
+ return QString();
+ }
- if (dialog.exec() == QDialog::Accepted) {
- return dialog.getChoiceData().toString();
- } else {
- return QString();
- }
+ if (dialog.exec() == QDialog::Accepted) {
+ return dialog.getChoiceData().toString();
+ } else {
+ return QString();
+ }
}
-void MainWindow::on_restoreButton_clicked() {
- QString pluginName = m_OrganizerCore.currentProfile()->getPluginsFileName();
- QString choice = queryRestore(pluginName);
- if (!choice.isEmpty()) {
- QString loadOrderName = m_OrganizerCore.currentProfile()->getLoadOrderFileName();
- QString lockedName = m_OrganizerCore.currentProfile()->getLockedOrderFileName();
- if (!shellCopy(pluginName + "." + choice, pluginName, true, this) ||
- !shellCopy(loadOrderName + "." + choice, loadOrderName, true, this) ||
- !shellCopy(lockedName + "." + choice, lockedName, true, this)) {
- QMessageBox::critical(
- this, tr("Restore failed"),
- tr("Failed to restore the backup. Errorcode: %1").arg(windowsErrorString(::GetLastError())));
- }
- m_OrganizerCore.refreshESPList();
+void MainWindow::on_restoreButton_clicked()
+{
+ QString pluginName = m_OrganizerCore.currentProfile()->getPluginsFileName();
+ QString choice = queryRestore(pluginName);
+ if (!choice.isEmpty()) {
+ QString loadOrderName = m_OrganizerCore.currentProfile()->getLoadOrderFileName();
+ QString lockedName = m_OrganizerCore.currentProfile()->getLockedOrderFileName();
+ if (!shellCopy(pluginName + "." + choice, pluginName, true, this) ||
+ !shellCopy(loadOrderName + "." + choice, loadOrderName, true, this) ||
+ !shellCopy(lockedName + "." + choice, lockedName, true, this)) {
+ QMessageBox::critical(this, tr("Restore failed"),
+ tr("Failed to restore the backup. Errorcode: %1").arg(windowsErrorString(::GetLastError())));
}
+ m_OrganizerCore.refreshESPList();
+ }
}
-void MainWindow::on_saveModsButton_clicked() {
- m_OrganizerCore.currentProfile()->writeModlistNow(true);
- QDateTime now = QDateTime::currentDateTime();
- if (createBackup(m_OrganizerCore.currentProfile()->getModlistFileName(), now)) {
- MessageDialog::showMessage(tr("Backup of modlist created"), this);
- }
+void MainWindow::on_saveModsButton_clicked()
+{
+ m_OrganizerCore.currentProfile()->writeModlistNow(true);
+ QDateTime now = QDateTime::currentDateTime();
+ if (createBackup(m_OrganizerCore.currentProfile()->getModlistFileName(), now)) {
+ MessageDialog::showMessage(tr("Backup of modlist created"), this);
+ }
}
-void MainWindow::on_restoreModsButton_clicked() {
- QString modlistName = m_OrganizerCore.currentProfile()->getModlistFileName();
- QString choice = queryRestore(modlistName);
- if (!choice.isEmpty()) {
- if (!shellCopy(modlistName + "." + choice, modlistName, true, this)) {
- QMessageBox::critical(
- this, tr("Restore failed"),
- tr("Failed to restore the backup. Errorcode: %1").arg(windowsErrorString(::GetLastError())));
- }
- m_OrganizerCore.refreshModList(false);
+void MainWindow::on_restoreModsButton_clicked()
+{
+ QString modlistName = m_OrganizerCore.currentProfile()->getModlistFileName();
+ QString choice = queryRestore(modlistName);
+ if (!choice.isEmpty()) {
+ if (!shellCopy(modlistName + "." + choice, modlistName, true, this)) {
+ QMessageBox::critical(this, tr("Restore failed"),
+ tr("Failed to restore the backup. Errorcode: %1").arg(windowsErrorString(::GetLastError())));
}
+ m_OrganizerCore.refreshModList(false);
+ }
}
-void MainWindow::on_actionCopy_Log_to_Clipboard_triggered() {
- QStringList lines;
- QAbstractItemModel* model = ui->logList->model();
- for (int i = 0; i < model->rowCount(); ++i) {
- lines.append(QString("%1 [%2] %3")
- .arg(model->index(i, 0).data().toString())
- .arg(model->index(i, 1).data(Qt::UserRole).toString())
- .arg(model->index(i, 1).data().toString()));
- }
- QApplication::clipboard()->setText(lines.join("\n"));
+void MainWindow::on_actionCopy_Log_to_Clipboard_triggered()
+{
+ QStringList lines;
+ QAbstractItemModel *model = ui->logList->model();
+ for (int i = 0; i < model->rowCount(); ++i) {
+ lines.append(QString("%1 [%2] %3").arg(model->index(i, 0).data().toString())
+ .arg(model->index(i, 1).data(Qt::UserRole).toString())
+ .arg(model->index(i, 1).data().toString()));
+ }
+ QApplication::clipboard()->setText(lines.join("\n"));
}
-void MainWindow::on_categoriesAndBtn_toggled(bool checked) {
- if (checked) {
- m_ModListSortProxy->setFilterMode(ModListSortProxy::FILTER_AND);
- }
+void MainWindow::on_categoriesAndBtn_toggled(bool checked)
+{
+ if (checked) {
+ m_ModListSortProxy->setFilterMode(ModListSortProxy::FILTER_AND);
+ }
}
-void MainWindow::on_categoriesOrBtn_toggled(bool checked) {
- if (checked) {
- m_ModListSortProxy->setFilterMode(ModListSortProxy::FILTER_OR);
- }
+void MainWindow::on_categoriesOrBtn_toggled(bool checked)
+{
+ if (checked) {
+ m_ModListSortProxy->setFilterMode(ModListSortProxy::FILTER_OR);
+ }
}
-void MainWindow::on_managedArchiveLabel_linkHovered(const QString&) {
- QToolTip::showText(QCursor::pos(), ui->managedArchiveLabel->toolTip());
+void MainWindow::on_managedArchiveLabel_linkHovered(const QString&)
+{
+ QToolTip::showText(QCursor::pos(),
+ ui->managedArchiveLabel->toolTip());
}
-void MainWindow::dragEnterEvent(QDragEnterEvent* event) {
- // Accept copy or move drags to the download window. Link drags are not
- // meaningful (Well, they are - we could drop a link in the download folder,
- // but you need privileges to do that).
- if (ui->downloadTab->isVisible() &&
- (event->proposedAction() == Qt::CopyAction || event->proposedAction() == Qt::MoveAction) &&
- event->answerRect().intersects(ui->downloadTab->rect())) {
+void MainWindow::dragEnterEvent(QDragEnterEvent *event)
+{
+ //Accept copy or move drags to the download window. Link drags are not
+ //meaningful (Well, they are - we could drop a link in the download folder,
+ //but you need privileges to do that).
+ if (ui->downloadTab->isVisible() &&
+ (event->proposedAction() == Qt::CopyAction ||
+ event->proposedAction() == Qt::MoveAction) &&
+ event->answerRect().intersects(ui->downloadTab->rect())) {
- // If I read the documentation right, this won't work under a motif windows
- // manager and the check needs to be done at the drop. However, that means
- // the user might be allowed to drop things which we can't sanely process
- QMimeData const* data = event->mimeData();
+ //If I read the documentation right, this won't work under a motif windows
+ //manager and the check needs to be done at the drop. However, that means
+ //the user might be allowed to drop things which we can't sanely process
+ QMimeData const *data = event->mimeData();
- if (data->hasUrls()) {
- QStringList extensions = m_OrganizerCore.installationManager()->getSupportedExtensions();
+ if (data->hasUrls()) {
+ QStringList extensions =
+ m_OrganizerCore.installationManager()->getSupportedExtensions();
- // This is probably OK - scan to see if these are moderately sane archive
- // types
- QList<QUrl> urls = data->urls();
- bool ok = true;
- for (const QUrl& url : urls) {
- if (url.isLocalFile()) {
- QString local = url.toLocalFile();
- bool fok = false;
- for (auto ext : extensions) {
- if (local.endsWith(ext, Qt::CaseInsensitive)) {
- fok = true;
- break;
- }
- }
- if (!fok) {
- ok = false;
- break;
- }
- }
- }
- if (ok) {
- event->accept();
+ //This is probably OK - scan to see if these are moderately sane archive
+ //types
+ QList<QUrl> urls = data->urls();
+ bool ok = true;
+ for (const QUrl &url : urls) {
+ if (url.isLocalFile()) {
+ QString local = url.toLocalFile();
+ bool fok = false;
+ for (auto ext : extensions) {
+ if (local.endsWith(ext, Qt::CaseInsensitive)) {
+ fok = true;
+ break;
}
+ }
+ if (! fok) {
+ ok = false;
+ break;
+ }
}
+ }
+ if (ok) {
+ event->accept();
+ }
}
+ }
}
-void MainWindow::dropLocalFile(const QUrl& url, const QString& outputDir, bool move) {
- QFileInfo file(url.toLocalFile());
- if (!file.exists()) {
- qWarning("invalid source file %s", qPrintable(file.absoluteFilePath()));
- return;
- }
- QString target = outputDir + "/" + file.fileName();
- if (QFile::exists(target)) {
- QMessageBox box(QMessageBox::Question, file.fileName(),
- tr("A file with the same name has already been downloaded. "
- "What would you like to do?"));
- box.addButton(tr("Overwrite"), QMessageBox::ActionRole);
- box.addButton(tr("Rename new file"), QMessageBox::YesRole);
- box.addButton(tr("Ignore file"), QMessageBox::RejectRole);
+void MainWindow::dropLocalFile(const QUrl &url, const QString &outputDir, bool move)
+{
+ QFileInfo file(url.toLocalFile());
+ if (!file.exists()) {
+ qWarning("invalid source file %s", qPrintable(file.absoluteFilePath()));
+ return;
+ }
+ QString target = outputDir + "/" + file.fileName();
+ if (QFile::exists(target)) {
+ QMessageBox box(QMessageBox::Question,
+ file.fileName(),
+ tr("A file with the same name has already been downloaded. "
+ "What would you like to do?"));
+ box.addButton(tr("Overwrite"), QMessageBox::ActionRole);
+ box.addButton(tr("Rename new file"), QMessageBox::YesRole);
+ box.addButton(tr("Ignore file"), QMessageBox::RejectRole);
- box.exec();
- switch (box.buttonRole(box.clickedButton())) {
- case QMessageBox::RejectRole:
- return;
- case QMessageBox::ActionRole:
- break;
- default:
- case QMessageBox::YesRole:
- target = m_OrganizerCore.downloadManager()->getDownloadFileName(file.fileName());
- break;
- }
+ box.exec();
+ switch (box.buttonRole(box.clickedButton())) {
+ case QMessageBox::RejectRole:
+ return;
+ case QMessageBox::ActionRole:
+ break;
+ default:
+ case QMessageBox::YesRole:
+ target = m_OrganizerCore.downloadManager()->getDownloadFileName(file.fileName());
+ break;
}
+ }
- bool success = false;
- if (move) {
- success = shellMove(file.absoluteFilePath(), target, true, this);
- } else {
- success = shellCopy(file.absoluteFilePath(), target, true, this);
- }
- if (!success) {
- qCritical("file operation failed: %s", qPrintable(windowsErrorString(::GetLastError())));
- }
+ bool success = false;
+ if (move) {
+ success = shellMove(file.absoluteFilePath(), target, true, this);
+ } else {
+ success = shellCopy(file.absoluteFilePath(), target, true, this);
+ }
+ if (!success) {
+ qCritical("file operation failed: %s", qPrintable(windowsErrorString(::GetLastError())));
+ }
}
-bool MainWindow::registerWidgetState(const QString& name, QHeaderView* view, const char* oldSettingName) {
- // register the view so it's geometry gets saved at exit
- m_PersistedGeometry.push_back(std::make_pair(name, view));
+bool MainWindow::registerWidgetState(const QString &name, QHeaderView *view, const char *oldSettingName) {
+ // register the view so it's geometry gets saved at exit
+ m_PersistedGeometry.push_back(std::make_pair(name, view));
- // also, restore the geometry if it was saved before
- QSettings& settings = m_OrganizerCore.settings().directInterface();
+ // also, restore the geometry if it was saved before
+ QSettings &settings = m_OrganizerCore.settings().directInterface();
- QString key = QString("geometry/%1").arg(name);
- QByteArray data;
+ QString key = QString("geometry/%1").arg(name);
+ QByteArray data;
- if ((oldSettingName != nullptr) && settings.contains(oldSettingName)) {
- data = settings.value(oldSettingName).toByteArray();
- settings.remove(oldSettingName);
- } else if (settings.contains(key)) {
- data = settings.value(key).toByteArray();
- }
+ if ((oldSettingName != nullptr) && settings.contains(oldSettingName)) {
+ data = settings.value(oldSettingName).toByteArray();
+ settings.remove(oldSettingName);
+ } else if (settings.contains(key)) {
+ data = settings.value(key).toByteArray();
+ }
- if (!data.isEmpty()) {
- view->restoreState(data);
- return true;
+ if (!data.isEmpty()) {
+ view->restoreState(data);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void MainWindow::dropEvent(QDropEvent *event)
+{
+ Qt::DropAction action = event->proposedAction();
+ QString outputDir = m_OrganizerCore.downloadManager()->getOutputDirectory();
+ if (action == Qt::MoveAction) {
+ //Tell windows I'm taking control and will delete the source of a move.
+ event->setDropAction(Qt::TargetMoveAction);
+ }
+ for (const QUrl &url : event->mimeData()->urls()) {
+ if (url.isLocalFile()) {
+ dropLocalFile(url, outputDir, action == Qt::MoveAction);
} else {
- return false;
+ m_OrganizerCore.downloadManager()->startDownloadURLs(QStringList() << url.url());
}
+ }
+ event->accept();
}
-void MainWindow::dropEvent(QDropEvent* event) {
- Qt::DropAction action = event->proposedAction();
- QString outputDir = m_OrganizerCore.downloadManager()->getOutputDirectory();
- if (action == Qt::MoveAction) {
- // Tell windows I'm taking control and will delete the source of a move.
- event->setDropAction(Qt::TargetMoveAction);
- }
- for (const QUrl& url : event->mimeData()->urls()) {
- if (url.isLocalFile()) {
- dropLocalFile(url, outputDir, action == Qt::MoveAction);
- } else {
- m_OrganizerCore.downloadManager()->startDownloadURLs(QStringList() << url.url());
- }
- }
- event->accept();
+
+void MainWindow::on_clickBlankButton_clicked()
+{
+ deselectFilters();
}
-void MainWindow::on_clickBlankButton_clicked() { deselectFilters(); }
+void MainWindow::on_clearFiltersButton_clicked()
+{
+ deselectFilters();
+}
-void MainWindow::on_clearFiltersButton_clicked() { deselectFilters(); }
diff --git a/src/mainwindow.h b/src/mainwindow.h
index c0748bdb..b7eca72e 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -20,8 +20,8 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
-#include "browserdialog.h"
#include "bsafolder.h"
+#include "browserdialog.h"
#include "delayedfilewriter.h"
#include "errorcodes.h"
#include "imoinfo.h"
@@ -31,37 +31,26 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "savegameinfo.h"
#include "tutorialcontrol.h"
-// Note the commented headers here can be replaced with forward references,
-// when I get round to cleaning up main.cpp
+//Note the commented headers here can be replaced with forward references,
+//when I get round to cleaning up main.cpp
struct Executable;
class CategoryFactory;
class LockedDialogBase;
class OrganizerCore;
#include "plugincontainer.h" //class PluginContainer;
class PluginListSortProxy;
-namespace BSA {
-class Archive;
-}
+namespace BSA { class Archive; }
#include "iplugingame.h" //namespace MOBase { class IPluginGame; }
-namespace MOBase {
-class IPluginModPage;
-}
-namespace MOBase {
-class IPluginTool;
-}
-namespace MOBase {
-class ISaveGame;
-}
+namespace MOBase { class IPluginModPage; }
+namespace MOBase { class IPluginTool; }
+namespace MOBase { class ISaveGame; }
-namespace MOShared {
-class DirectoryEntry;
-}
+namespace MOShared { class DirectoryEntry; }
#include <QByteArray>
#include <QDir>
#include <QFileInfo>
#include <QFileSystemWatcher>
-#include <QHeaderView>
#include <QList>
#include <QMainWindow>
#include <QObject>
@@ -71,6 +60,7 @@ class DirectoryEntry;
#include <QStringList>
#include <QTime>
#include <QTimer>
+#include <QHeaderView>
#include <QVariant>
#include <Qt>
@@ -95,7 +85,7 @@ class QWidget;
#include <boost/signals2.hpp>
#endif
-// Sigh - just for HANDLE
+//Sigh - just for HANDLE
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
@@ -105,479 +95,492 @@ class QWidget;
#include <vector>
namespace Ui {
-class MainWindow;
+ class MainWindow;
}
-class MainWindow : public QMainWindow, public IUserInterface {
- Q_OBJECT
- friend class OrganizerProxy;
+
+class MainWindow : public QMainWindow, public IUserInterface
+{
+ Q_OBJECT
+
+ friend class OrganizerProxy;
public:
- explicit MainWindow(QSettings& initSettings, OrganizerCore& organizerCore, PluginContainer& pluginContainer,
- QWidget* parent = 0);
- ~MainWindow();
- void storeSettings(QSettings& settings) override;
- void readSettings();
+ explicit MainWindow(QSettings &initSettings,
+ OrganizerCore &organizerCore, PluginContainer &pluginContainer,
+ QWidget *parent = 0);
+ ~MainWindow();
+
+ void storeSettings(QSettings &settings) override;
+ void readSettings();
- virtual ILockedWaitingForProcess* lock() override;
- virtual void unlock() override;
+ virtual ILockedWaitingForProcess* lock() override;
+ virtual void unlock() override;
- bool addProfile();
- void updateBSAList(const QStringList& defaultArchives, const QStringList& activeArchives);
- void refreshDataTree();
- void refreshDataTreeKeepExpandedNodes();
- void refreshSaveList();
+ bool addProfile();
+ void updateBSAList(const QStringList &defaultArchives, const QStringList &activeArchives);
+ void refreshDataTree();
+ void refreshDataTreeKeepExpandedNodes();
+ void refreshSaveList();
- void setModListSorting(int index);
- void setESPListSorting(int index);
+ void setModListSorting(int index);
+ void setESPListSorting(int index);
- void saveArchiveList();
+ void saveArchiveList();
- void registerPluginTool(MOBase::IPluginTool* tool);
- void registerModPage(MOBase::IPluginModPage* modPage);
+ void registerPluginTool(MOBase::IPluginTool *tool);
+ void registerModPage(MOBase::IPluginModPage *modPage);
- void addPrimaryCategoryCandidates(QMenu* primaryCategoryMenu, ModInfo::Ptr info);
+ void addPrimaryCategoryCandidates(QMenu *primaryCategoryMenu, ModInfo::Ptr info);
- void createStdoutPipe(HANDLE* stdOutRead, HANDLE* stdOutWrite);
- std::string readFromPipe(HANDLE stdOutRead);
- void processLOOTOut(const std::string& lootOut, std::string& errorMessages, QProgressDialog& dialog);
+ void createStdoutPipe(HANDLE *stdOutRead, HANDLE *stdOutWrite);
+ std::string readFromPipe(HANDLE stdOutRead);
+ void processLOOTOut(const std::string &lootOut, std::string &errorMessages, QProgressDialog &dialog);
- void updateModInDirectoryStructure(unsigned int index, ModInfo::Ptr modInfo);
+ void updateModInDirectoryStructure(unsigned int index, ModInfo::Ptr modInfo);
- QString getOriginDisplayName(int originID);
+ QString getOriginDisplayName(int originID);
- void installTranslator(const QString& name);
+ void installTranslator(const QString &name);
- virtual void disconnectPlugins();
+ virtual void disconnectPlugins();
- void displayModInformation(ModInfo::Ptr modInfo, unsigned int index, int tab);
+ void displayModInformation(ModInfo::Ptr modInfo, unsigned int index, int tab);
- virtual bool closeWindow();
- virtual void setWindowEnabled(bool enabled);
+ virtual bool closeWindow();
+ virtual void setWindowEnabled(bool enabled);
- virtual MOBase::DelayedFileWriterBase& archivesWriter() override { return m_ArchiveListWriter; }
+ virtual MOBase::DelayedFileWriterBase &archivesWriter() override { return m_ArchiveListWriter; }
public slots:
- void displayColumnSelection(const QPoint& pos);
+ void displayColumnSelection(const QPoint &pos);
- void modorder_changed();
- void refresher_progress(int percent);
- void directory_refreshed();
+ void modorder_changed();
+ void refresher_progress(int percent);
+ void directory_refreshed();
- void toolPluginInvoke();
- void modPagePluginInvoke();
+ void toolPluginInvoke();
+ void modPagePluginInvoke();
signals:
- /**
- * @brief emitted after the information dialog has been closed
- */
- void modInfoDisplayed();
+ /**
+ * @brief emitted after the information dialog has been closed
+ */
+ void modInfoDisplayed();
+
+ /**
+ * @brief emitted when the selected style changes
+ */
+ void styleChanged(const QString &styleFile);
- /**
- * @brief emitted when the selected style changes
- */
- void styleChanged(const QString& styleFile);
- void modListDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
+ void modListDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
protected:
- virtual void showEvent(QShowEvent* event);
- virtual void closeEvent(QCloseEvent* event);
- virtual bool eventFilter(QObject* obj, QEvent* event);
- virtual void resizeEvent(QResizeEvent* event);
- virtual void dragEnterEvent(QDragEnterEvent* event);
- virtual void dropEvent(QDropEvent* event);
+
+ virtual void showEvent(QShowEvent *event);
+ virtual void closeEvent(QCloseEvent *event);
+ virtual bool eventFilter(QObject *obj, QEvent *event);
+ virtual void resizeEvent(QResizeEvent *event);
+ virtual void dragEnterEvent(QDragEnterEvent *event);
+ virtual void dropEvent(QDropEvent *event);
private slots:
- void on_actionChange_Game_triggered();
+ void on_actionChange_Game_triggered();
private slots:
- void on_clickBlankButton_clicked();
+ void on_clickBlankButton_clicked();
private:
- void cleanup();
- void actionToToolButton(QAction*& sourceAction);
+ void cleanup();
+
+ void actionToToolButton(QAction *&sourceAction);
- void updateToolBar();
- void activateSelectedProfile();
+ void updateToolBar();
+ void activateSelectedProfile();
- void setExecutableIndex(int index);
+ void setExecutableIndex(int index);
- void startSteam();
+ void startSteam();
- void updateTo(QTreeWidgetItem* subTree, const std::wstring& directorySoFar,
- const MOShared::DirectoryEntry& directoryEntry, bool conflictsOnly);
- bool refreshProfiles(bool selectProfile = true);
- void refreshExecutablesList();
- void installMod(QString fileName = "");
+ void updateTo(QTreeWidgetItem *subTree, const std::wstring &directorySoFar, const MOShared::DirectoryEntry &directoryEntry, bool conflictsOnly);
+ bool refreshProfiles(bool selectProfile = true);
+ void refreshExecutablesList();
+ void installMod(QString fileName = "");
- QList<MOBase::IOrganizer::FileInfo>
- findFileInfos(const QString& path, const std::function<bool(const MOBase::IOrganizer::FileInfo&)>& filter) const;
+ QList<MOBase::IOrganizer::FileInfo> findFileInfos(const QString &path, const std::function<bool (const MOBase::IOrganizer::FileInfo &)> &filter) const;
- bool modifyExecutablesDialog();
- void displayModInformation(int row, int tab = 0);
- void testExtractBSA(int modIndex);
+ bool modifyExecutablesDialog();
+ void displayModInformation(int row, int tab = 0);
+ void testExtractBSA(int modIndex);
- void writeDataToFile(QFile& file, const QString& directory, const MOShared::DirectoryEntry& directoryEntry);
+ void writeDataToFile(QFile &file, const QString &directory, const MOShared::DirectoryEntry &directoryEntry);
- void refreshFilters();
+ void refreshFilters();
- /**
- * Sets category selections from menu; for multiple mods, this will only apply
- * the changes made in the menu (which is the delta between the current menu selection and the reference mod)
- * @param menu the menu after editing by the user
- * @param modRow index of the mod to edit
- * @param referenceRow row of the reference mod
- */
- void addRemoveCategoriesFromMenu(QMenu* menu, int modRow, int referenceRow);
+ /**
+ * Sets category selections from menu; for multiple mods, this will only apply
+ * the changes made in the menu (which is the delta between the current menu selection and the reference mod)
+ * @param menu the menu after editing by the user
+ * @param modRow index of the mod to edit
+ * @param referenceRow row of the reference mod
+ */
+ void addRemoveCategoriesFromMenu(QMenu *menu, int modRow, int referenceRow);
- /**
- * Sets category selections from menu; for multiple mods, this will completely
- * replace the current set of categories on each selected with those selected in the menu
- * @param menu the menu after editing by the user
- * @param modRow index of the mod to edit
- */
- void replaceCategoriesFromMenu(QMenu* menu, int modRow);
+ /**
+ * Sets category selections from menu; for multiple mods, this will completely
+ * replace the current set of categories on each selected with those selected in the menu
+ * @param menu the menu after editing by the user
+ * @param modRow index of the mod to edit
+ */
+ void replaceCategoriesFromMenu(QMenu *menu, int modRow);
- bool populateMenuCategories(QMenu* menu, int targetID);
+ bool populateMenuCategories(QMenu *menu, int targetID);
- void updateDownloadListDelegate();
+ void updateDownloadListDelegate();
- // remove invalid category-references from mods
- void fixCategories();
+ // remove invalid category-references from mods
+ void fixCategories();
- void createHelpWidget();
+ void createHelpWidget();
- bool extractProgress(QProgressDialog& extractProgress, int percentage, std::string fileName);
+ bool extractProgress(QProgressDialog &extractProgress, int percentage, std::string fileName);
- size_t checkForProblems();
+ size_t checkForProblems();
- int getBinaryExecuteInfo(const QFileInfo& targetInfo, QFileInfo& binaryInfo, QString& arguments);
- QTreeWidgetItem* addFilterItem(QTreeWidgetItem* root, const QString& name, int categoryID,
- ModListSortProxy::FilterType type);
- void addContentFilters();
- void addCategoryFilters(QTreeWidgetItem* root, const std::set<int>& categoriesUsed, int targetID);
+ int getBinaryExecuteInfo(const QFileInfo &targetInfo, QFileInfo &binaryInfo, QString &arguments);
+ QTreeWidgetItem *addFilterItem(QTreeWidgetItem *root, const QString &name, int categoryID, ModListSortProxy::FilterType type);
+ void addContentFilters();
+ void addCategoryFilters(QTreeWidgetItem *root, const std::set<int> &categoriesUsed, int targetID);
- void setCategoryListVisible(bool visible);
+ void setCategoryListVisible(bool visible);
- void displaySaveGameInfo(QListWidgetItem* newItem);
+ void displaySaveGameInfo(QListWidgetItem *newItem);
- HANDLE nextChildProcess();
+ HANDLE nextChildProcess();
- bool errorReported(QString& logFile);
+ bool errorReported(QString &logFile);
- void updateESPLock(bool locked);
+ void updateESPLock(bool locked);
- static void setupNetworkProxy(bool activate);
- void activateProxy(bool activate);
- void setBrowserGeometry(const QByteArray& geometry);
+ static void setupNetworkProxy(bool activate);
+ void activateProxy(bool activate);
+ void setBrowserGeometry(const QByteArray &geometry);
- bool createBackup(const QString& filePath, const QDateTime& time);
- QString queryRestore(const QString& filePath);
+ bool createBackup(const QString &filePath, const QDateTime &time);
+ QString queryRestore(const QString &filePath);
- QMenu* modListContextMenu();
+ QMenu *modListContextMenu();
- std::set<QString> enabledArchives();
+ std::set<QString> enabledArchives();
- void scheduleUpdateButton();
+ void scheduleUpdateButton();
- QDir currentSavesDir() const;
+ QDir currentSavesDir() const;
- void startMonitorSaves();
- void stopMonitorSaves();
+ void startMonitorSaves();
+ void stopMonitorSaves();
- void dropLocalFile(const QUrl& url, const QString& outputDir, bool move);
+ void dropLocalFile(const QUrl &url, const QString &outputDir, bool move);
- bool registerWidgetState(const QString& name, QHeaderView* view, const char* oldSettingName = nullptr);
+ bool registerWidgetState(const QString &name, QHeaderView *view, const char *oldSettingName = nullptr);
private:
- static const char* PATTERN_BACKUP_GLOB;
- static const char* PATTERN_BACKUP_REGEX;
- static const char* PATTERN_BACKUP_DATE;
+
+ static const char *PATTERN_BACKUP_GLOB;
+ static const char *PATTERN_BACKUP_REGEX;
+ static const char *PATTERN_BACKUP_DATE;
private:
- Ui::MainWindow* ui;
- bool m_WasVisible;
+ Ui::MainWindow *ui;
+
+ bool m_WasVisible;
- MOBase::TutorialControl m_Tutorial;
+ MOBase::TutorialControl m_Tutorial;
- int m_OldProfileIndex;
+ int m_OldProfileIndex;
- std::vector<QString> m_ModNameList; // the mod-list to go with the directory structure
- QProgressBar* m_RefreshProgress;
- bool m_Refreshing;
+ std::vector<QString> m_ModNameList; // the mod-list to go with the directory structure
+ QProgressBar *m_RefreshProgress;
+ bool m_Refreshing;
- QStringList m_DefaultArchives;
+ QStringList m_DefaultArchives;
- QAbstractItemModel* m_ModListGroupingProxy;
- ModListSortProxy* m_ModListSortProxy;
+ QAbstractItemModel *m_ModListGroupingProxy;
+ ModListSortProxy *m_ModListSortProxy;
- PluginListSortProxy* m_PluginListSortProxy;
+ PluginListSortProxy *m_PluginListSortProxy;
- int m_OldExecutableIndex;
+ int m_OldExecutableIndex;
- int m_ContextRow;
- QPersistentModelIndex m_ContextIdx;
- QTreeWidgetItem* m_ContextItem;
- QAction* m_ContextAction;
+ int m_ContextRow;
+ QPersistentModelIndex m_ContextIdx;
+ QTreeWidgetItem *m_ContextItem;
+ QAction *m_ContextAction;
- CategoryFactory& m_CategoryFactory;
+ CategoryFactory &m_CategoryFactory;
- int m_ModsToUpdate;
+ int m_ModsToUpdate;
- bool m_LoginAttempted;
+ bool m_LoginAttempted;
- QTimer m_CheckBSATimer;
- QTimer m_SaveMetaTimer;
- QTimer m_UpdateProblemsTimer;
+ QTimer m_CheckBSATimer;
+ QTimer m_SaveMetaTimer;
+ QTimer m_UpdateProblemsTimer;
- QTime m_StartTime;
- // SaveGameInfoWidget *m_CurrentSaveView;
- MOBase::ISaveGameInfoWidget* m_CurrentSaveView;
+ QTime m_StartTime;
+ //SaveGameInfoWidget *m_CurrentSaveView;
+ MOBase::ISaveGameInfoWidget *m_CurrentSaveView;
- OrganizerCore& m_OrganizerCore;
- PluginContainer& m_PluginContainer;
+ OrganizerCore &m_OrganizerCore;
+ PluginContainer &m_PluginContainer;
- QString m_CurrentLanguage;
- std::vector<QTranslator*> m_Translators;
+ QString m_CurrentLanguage;
+ std::vector<QTranslator*> m_Translators;
- BrowserDialog m_IntegratedBrowser;
+ BrowserDialog m_IntegratedBrowser;
- QFileSystemWatcher m_SavesWatcher;
+ QFileSystemWatcher m_SavesWatcher;
- std::vector<QTreeWidgetItem*> m_RemoveWidget;
+ std::vector<QTreeWidgetItem*> m_RemoveWidget;
- QByteArray m_ArchiveListHash;
+ QByteArray m_ArchiveListHash;
- bool m_DidUpdateMasterList;
+ bool m_DidUpdateMasterList;
- LockedDialogBase* m_LockDialog{nullptr};
- uint64_t m_LockCount{0};
+ LockedDialogBase *m_LockDialog { nullptr };
+ uint64_t m_LockCount { 0 };
- bool m_closing{false};
+ bool m_closing{ false };
- std::vector<std::pair<QString, QHeaderView*>> m_PersistedGeometry;
+ std::vector<std::pair<QString, QHeaderView*>> m_PersistedGeometry;
- MOBase::DelayedFileWriter m_ArchiveListWriter;
+ MOBase::DelayedFileWriter m_ArchiveListWriter;
- enum class ShortcutType { Toolbar, Desktop, StartMenu };
+ enum class ShortcutType {
+ Toolbar,
+ Desktop,
+ StartMenu
+ };
- void addWindowsLink(ShortcutType const);
+ void addWindowsLink(ShortcutType const);
- Executable const& getSelectedExecutable() const;
- Executable& getSelectedExecutable();
+ Executable const &getSelectedExecutable() const;
+ Executable &getSelectedExecutable();
private slots:
- void updateWindowTitle(const QString& accountName, bool premium);
+ void updateWindowTitle(const QString &accountName, bool premium);
+
+ void showMessage(const QString &message);
+ void showError(const QString &message);
- void showMessage(const QString& message);
- void showError(const QString& message);
+ // main window actions
+ void helpTriggered();
+ void issueTriggered();
+ void wikiTriggered();
+ void tutorialTriggered();
+ void extractBSATriggered();
- // main window actions
- void helpTriggered();
- void issueTriggered();
- void wikiTriggered();
- void tutorialTriggered();
- void extractBSATriggered();
+ // modlist context menu
+ void installMod_clicked();
+ void createEmptyMod_clicked();
+ void restoreBackup_clicked();
+ void renameMod_clicked();
+ void removeMod_clicked();
+ void reinstallMod_clicked();
+ void endorse_clicked();
+ void dontendorse_clicked();
+ void unendorse_clicked();
+ void ignoreMissingData_clicked();
+ void visitOnNexus_clicked();
+ void visitWebPage_clicked();
+ void openExplorer_clicked();
+ void information_clicked();
+ // savegame context menu
+ void deleteSavegame_clicked();
+ void fixMods_clicked(SaveGameInfo::MissingAssets const &missingAssets);
+ // data-tree context menu
+ void writeDataToFile();
+ void openDataFile();
+ void addAsExecutable();
+ void previewDataFile();
+ void hideFile();
+ void unhideFile();
- // modlist context menu
- void installMod_clicked();
- void createEmptyMod_clicked();
- void restoreBackup_clicked();
- void renameMod_clicked();
- void removeMod_clicked();
- void reinstallMod_clicked();
- void endorse_clicked();
- void dontendorse_clicked();
- void unendorse_clicked();
- void ignoreMissingData_clicked();
- void visitOnNexus_clicked();
- void visitWebPage_clicked();
- void openExplorer_clicked();
- void information_clicked();
- // savegame context menu
- void deleteSavegame_clicked();
- void fixMods_clicked(SaveGameInfo::MissingAssets const& missingAssets);
- // data-tree context menu
- void writeDataToFile();
- void openDataFile();
- void addAsExecutable();
- void previewDataFile();
- void hideFile();
- void unhideFile();
+ void linkToolbar();
+ void linkDesktop();
+ void linkMenu();
- void linkToolbar();
- void linkDesktop();
- void linkMenu();
+ void languageChange(const QString &newLanguage);
+ void saveSelectionChanged(QListWidgetItem *newItem);
- void languageChange(const QString& newLanguage);
- void saveSelectionChanged(QListWidgetItem* newItem);
+ void windowTutorialFinished(const QString &windowName);
- void windowTutorialFinished(const QString& windowName);
+ BSA::EErrorCode extractBSA(BSA::Archive &archive, BSA::Folder::Ptr folder, const QString &destination, QProgressDialog &extractProgress);
- BSA::EErrorCode extractBSA(BSA::Archive& archive, BSA::Folder::Ptr folder, const QString& destination,
- QProgressDialog& extractProgress);
+ void createModFromOverwrite();
+ void clearOverwrite();
- void createModFromOverwrite();
- void clearOverwrite();
+ void procError(QProcess::ProcessError error);
+ void procFinished(int exitCode, QProcess::ExitStatus exitStatus);
- void procError(QProcess::ProcessError error);
- void procFinished(int exitCode, QProcess::ExitStatus exitStatus);
+ // nexus related
+ void checkModsForUpdates();
+ void nexusLinkActivated(const QString &link);
- // nexus related
- void checkModsForUpdates();
- void nexusLinkActivated(const QString& link);
+ void loginFailed(const QString &message);
- void loginFailed(const QString& message);
+ void linkClicked(const QString &url);
- void linkClicked(const QString& url);
+ void updateAvailable();
- void updateAvailable();
+ void motdReceived(const QString &motd);
+ void notEndorsedYet();
- void motdReceived(const QString& motd);
- void notEndorsedYet();
+ void originModified(int originID);
- void originModified(int originID);
+ void addRemoveCategories_MenuHandler();
+ void replaceCategories_MenuHandler();
- void addRemoveCategories_MenuHandler();
- void replaceCategories_MenuHandler();
+ void addPrimaryCategoryCandidates();
- void addPrimaryCategoryCandidates();
+ void modDetailsUpdated(bool success);
- void modDetailsUpdated(bool success);
+ void modInstalled(const QString &modName);
- void modInstalled(const QString& modName);
+ void nxmUpdatesAvailable(const std::vector<int> &modIDs, QVariant userData, QVariant resultData, int requestID);
+ void nxmEndorsementToggled(int, QVariant, QVariant resultData, int);
+ void nxmDownloadURLs(int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
+ void nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorString);
- void nxmUpdatesAvailable(const std::vector<int>& modIDs, QVariant userData, QVariant resultData, int requestID);
- void nxmEndorsementToggled(int, QVariant, QVariant resultData, int);
- void nxmDownloadURLs(int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
- void nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString& errorString);
+ void editCategories();
+ void deselectFilters();
- void editCategories();
- void deselectFilters();
+ void displayModInformation(const QString &modName, int tab);
+ void modOpenNext();
+ void modOpenPrev();
- void displayModInformation(const QString& modName, int tab);
- void modOpenNext();
- void modOpenPrev();
+ void modRenamed(const QString &oldName, const QString &newName);
+ void modRemoved(const QString &fileName);
- void modRenamed(const QString& oldName, const QString& newName);
- void modRemoved(const QString& fileName);
+ void hideSaveGameInfo();
- void hideSaveGameInfo();
+ void hookUpWindowTutorials();
- void hookUpWindowTutorials();
+ void resumeDownload(int downloadIndex);
+ void endorseMod(ModInfo::Ptr mod);
+ void cancelModListEditor();
- void resumeDownload(int downloadIndex);
- void endorseMod(ModInfo::Ptr mod);
- void cancelModListEditor();
+ void lockESPIndex();
+ void unlockESPIndex();
- void lockESPIndex();
- void unlockESPIndex();
+ void enableVisibleMods();
+ void disableVisibleMods();
+ void exportModListCSV();
+ void openInstanceFolder();
+ void openDownloadsFolder();
+ void openProfileFolder();
+ void openGameFolder();
+ void openMyGamesFolder();
+ void startExeAction();
- void enableVisibleMods();
- void disableVisibleMods();
- void exportModListCSV();
- void openInstanceFolder();
- void openDownloadsFolder();
- void openProfileFolder();
- void openGameFolder();
- void openMyGamesFolder();
- void startExeAction();
+ void checkBSAList();
- void checkBSAList();
+ void updateProblemsButton();
- void updateProblemsButton();
+ void saveModMetas();
- void saveModMetas();
+ void updateStyle(const QString &style);
- void updateStyle(const QString& style);
+ void modlistChanged(const QModelIndex &index, int role);
+ void fileMoved(const QString &filePath, const QString &oldOriginName, const QString &newOriginName);
- void modlistChanged(const QModelIndex& index, int role);
- void fileMoved(const QString& filePath, const QString& oldOriginName, const QString& newOriginName);
- void modFilterActive(bool active);
- void espFilterChanged(const QString& filter);
- void downloadFilterChanged(const QString& filter);
+ void modFilterActive(bool active);
+ void espFilterChanged(const QString &filter);
+ void downloadFilterChanged(const QString &filter);
- void expandModList(const QModelIndex& index);
+ void expandModList(const QModelIndex &index);
- /**
- * @brief resize columns in mod list and plugin list to content
- */
- void resizeLists(bool modListCustom, bool pluginListCustom);
+ /**
+ * @brief resize columns in mod list and plugin list to content
+ */
+ void resizeLists(bool modListCustom, bool pluginListCustom);
- /**
- * @brief allow columns in mod list and plugin list to be resized
- */
- void allowListResize();
+ /**
+ * @brief allow columns in mod list and plugin list to be resized
+ */
+ void allowListResize();
- void toolBar_customContextMenuRequested(const QPoint& point);
- void removeFromToolbar();
- void overwriteClosed(int);
+ void toolBar_customContextMenuRequested(const QPoint &point);
+ void removeFromToolbar();
+ void overwriteClosed(int);
- void changeVersioningScheme();
- void ignoreUpdate();
- void unignoreUpdate();
+ void changeVersioningScheme();
+ void ignoreUpdate();
+ void unignoreUpdate();
- void refreshSavesIfOpen();
- void expandDataTreeItem(QTreeWidgetItem* item);
- void about();
- void delayedRemove();
+ void refreshSavesIfOpen();
+ void expandDataTreeItem(QTreeWidgetItem *item);
+ void about();
+ void delayedRemove();
- void modlistSelectionChanged(const QModelIndex& current, const QModelIndex& previous);
- void modListSortIndicatorChanged(int column, Qt::SortOrder order);
+ void modlistSelectionChanged(const QModelIndex &current, const QModelIndex &previous);
+ void modListSortIndicatorChanged(int column, Qt::SortOrder order);
- void modlistSelectionsChanged(const QItemSelection& current);
- void esplistSelectionsChanged(const QItemSelection& current);
+ void modlistSelectionsChanged(const QItemSelection &current);
+ void esplistSelectionsChanged(const QItemSelection &current);
private slots: // ui slots
- // actions
- void on_actionAdd_Profile_triggered();
- void on_actionInstallMod_triggered();
- void on_actionModify_Executables_triggered();
- void on_actionNexus_triggered();
- void on_actionProblems_triggered();
- void on_actionSettings_triggered();
- void on_actionUpdate_triggered();
- void on_actionEndorseMO_triggered();
+ // actions
+ void on_actionAdd_Profile_triggered();
+ void on_actionInstallMod_triggered();
+ void on_actionModify_Executables_triggered();
+ void on_actionNexus_triggered();
+ void on_actionProblems_triggered();
+ void on_actionSettings_triggered();
+ void on_actionUpdate_triggered();
+ void on_actionEndorseMO_triggered();
- void on_clearFiltersButton_clicked();
- void on_btnRefreshData_clicked();
- void on_categoriesList_customContextMenuRequested(const QPoint& pos);
- void on_conflictsCheckBox_toggled(bool checked);
- void on_dataTree_customContextMenuRequested(const QPoint& pos);
- void on_executablesListBox_currentIndexChanged(int index);
- void on_modList_customContextMenuRequested(const QPoint& pos);
- void on_modList_doubleClicked(const QModelIndex& index);
- void on_profileBox_currentIndexChanged(int index);
- void on_savegameList_customContextMenuRequested(const QPoint& pos);
- void on_startButton_clicked();
- void on_tabWidget_currentChanged(int index);
+ void on_clearFiltersButton_clicked();
+ void on_btnRefreshData_clicked();
+ void on_categoriesList_customContextMenuRequested(const QPoint &pos);
+ void on_conflictsCheckBox_toggled(bool checked);
+ void on_dataTree_customContextMenuRequested(const QPoint &pos);
+ void on_executablesListBox_currentIndexChanged(int index);
+ void on_modList_customContextMenuRequested(const QPoint &pos);
+ void on_modList_doubleClicked(const QModelIndex &index);
+ void on_profileBox_currentIndexChanged(int index);
+ void on_savegameList_customContextMenuRequested(const QPoint &pos);
+ void on_startButton_clicked();
+ void on_tabWidget_currentChanged(int index);
- void on_espList_customContextMenuRequested(const QPoint& pos);
- void on_displayCategoriesBtn_toggled(bool checked);
- void on_groupCombo_currentIndexChanged(int index);
- void on_categoriesList_itemSelectionChanged();
- void on_linkButton_pressed();
- void on_showHiddenBox_toggled(bool checked);
- void on_bsaList_itemChanged(QTreeWidgetItem* item, int column);
- void on_bossButton_clicked();
+ void on_espList_customContextMenuRequested(const QPoint &pos);
+ void on_displayCategoriesBtn_toggled(bool checked);
+ void on_groupCombo_currentIndexChanged(int index);
+ void on_categoriesList_itemSelectionChanged();
+ void on_linkButton_pressed();
+ void on_showHiddenBox_toggled(bool checked);
+ void on_bsaList_itemChanged(QTreeWidgetItem *item, int column);
+ void on_bossButton_clicked();
- void on_saveButton_clicked();
- void on_restoreButton_clicked();
- void on_restoreModsButton_clicked();
- void on_saveModsButton_clicked();
- void on_actionCopy_Log_to_Clipboard_triggered();
- void on_categoriesAndBtn_toggled(bool checked);
- void on_categoriesOrBtn_toggled(bool checked);
- void on_managedArchiveLabel_linkHovered(const QString& link);
+ void on_saveButton_clicked();
+ void on_restoreButton_clicked();
+ void on_restoreModsButton_clicked();
+ void on_saveModsButton_clicked();
+ void on_actionCopy_Log_to_Clipboard_triggered();
+ void on_categoriesAndBtn_toggled(bool checked);
+ void on_categoriesOrBtn_toggled(bool checked);
+ void on_managedArchiveLabel_linkHovered(const QString &link);
};
+
+
#endif // MAINWINDOW_H
diff --git a/src/messagedialog.cpp b/src/messagedialog.cpp
index 33594d83..90b0a9d3 100644
--- a/src/messagedialog.cpp
+++ b/src/messagedialog.cpp
@@ -19,65 +19,74 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "messagedialog.h"
#include "ui_messagedialog.h"
-#include <QResizeEvent>
#include <QTimer>
+#include <QResizeEvent>
#include <Windows.h>
-MessageDialog::MessageDialog(const QString& text, QWidget* reference) : QDialog(reference), ui(new Ui::MessageDialog) {
- ui->setupUi(this);
+MessageDialog::MessageDialog(const QString &text, QWidget *reference) :
+ QDialog(reference),
+ ui(new Ui::MessageDialog)
+{
+ ui->setupUi(this);
- // very crude way to ensure no single word in the test is wider than the message window. ellide in the center if
- // necessary
- QFontMetrics metrics(ui->message->font());
- QString restrictedText;
- QStringList lines = text.split("\n");
- foreach (const QString& line, lines) {
- QString newLine;
- QStringList words = line.split(" ");
- foreach (const QString& word, words) {
- if (word.length() > 10) {
- newLine += "<span style=\"nobreak\">" +
- metrics.elidedText(word, Qt::ElideMiddle, ui->message->maximumWidth()) + "</span>";
- } else {
- newLine += word;
- }
- newLine += " ";
- }
- restrictedText += newLine + "\n";
+ // very crude way to ensure no single word in the test is wider than the message window. ellide in the center if necessary
+ QFontMetrics metrics(ui->message->font());
+ QString restrictedText;
+ QStringList lines = text.split("\n");
+ foreach (const QString &line, lines) {
+ QString newLine;
+ QStringList words = line.split(" ");
+ foreach (const QString &word, words) {
+ if (word.length() > 10) {
+ newLine += "<span style=\"nobreak\">" + metrics.elidedText(word, Qt::ElideMiddle, ui->message->maximumWidth()) + "</span>";
+ } else {
+ newLine += word;
+ }
+ newLine += " ";
}
+ restrictedText += newLine + "\n";
+ }
- ui->message->setText(restrictedText);
- this->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
- this->setFocusPolicy(Qt::NoFocus);
- this->setAttribute(Qt::WA_ShowWithoutActivating);
- QTimer::singleShot(1000 + (text.length() * 40), this, SLOT(hide()));
- if (reference != nullptr) {
- QPoint position = reference->mapToGlobal(QPoint(reference->width() / 2, reference->height()));
- position.rx() -= this->width() / 2;
- position.ry() -= this->height() + 5;
- move(position);
- }
+ ui->message->setText(restrictedText);
+ this->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
+ this->setFocusPolicy(Qt::NoFocus);
+ this->setAttribute(Qt::WA_ShowWithoutActivating);
+ QTimer::singleShot(1000 + (text.length() * 40), this, SLOT(hide()));
+ if (reference != nullptr) {
+ QPoint position = reference->mapToGlobal(QPoint(reference->width() / 2, reference->height()));
+ position.rx() -= this->width() / 2;
+ position.ry() -= this->height() + 5;
+ move(position);
+ }
}
-MessageDialog::~MessageDialog() { delete ui; }
-void MessageDialog::resizeEvent(QResizeEvent* event) {
- QWidget* par = parentWidget();
- if (par != nullptr) {
- QPoint position = par->mapToGlobal(QPoint(par->width() / 2, par->height()));
- position.rx() -= event->size().width() / 2;
- position.ry() -= event->size().height() + 5;
- move(position);
- }
+MessageDialog::~MessageDialog()
+{
+ delete ui;
}
-void MessageDialog::showMessage(const QString& text, QWidget* reference, bool bringToFront) {
- qDebug("%s", qPrintable(text));
- if (reference != nullptr) {
- if (bringToFront || (qApp->activeWindow() != nullptr)) {
- MessageDialog* dialog = new MessageDialog(text, reference);
- dialog->show();
- reference->activateWindow();
- }
+
+void MessageDialog::resizeEvent(QResizeEvent *event)
+{
+ QWidget *par = parentWidget();
+ if (par != nullptr) {
+ QPoint position = par->mapToGlobal(QPoint(par->width() / 2, par->height()));
+ position.rx() -= event->size().width() / 2;
+ position.ry() -= event->size().height() + 5;
+ move(position);
+ }
+}
+
+
+void MessageDialog::showMessage(const QString &text, QWidget *reference, bool bringToFront)
+{
+ qDebug("%s", qPrintable(text));
+ if (reference != nullptr) {
+ if (bringToFront || (qApp->activeWindow() != nullptr)) {
+ MessageDialog *dialog = new MessageDialog(text, reference);
+ dialog->show();
+ reference->activateWindow();
}
+ }
}
diff --git a/src/messagedialog.h b/src/messagedialog.h
index a37e53e3..7e9b9c3b 100644
--- a/src/messagedialog.h
+++ b/src/messagedialog.h
@@ -23,43 +23,45 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QDialog>
namespace Ui {
-class MessageDialog;
+ class MessageDialog;
}
/**
* borderless dialog used to display short messages that will automatically
* vanish after a moment
**/
-class MessageDialog : public QDialog {
+class MessageDialog : public QDialog
+{
Q_OBJECT
public:
- /**
- * @brief constructor
- *
- * @param text the message to display
- * @param reference parent widget. This will also be used to position the message at the bottom center of the dialog
- **/
+ /**
+ * @brief constructor
+ *
+ * @param text the message to display
+ * @param reference parent widget. This will also be used to position the message at the bottom center of the dialog
+ **/
+
+ explicit MessageDialog(const QString &text, QWidget *reference);
- explicit MessageDialog(const QString& text, QWidget* reference);
+ ~MessageDialog();
- ~MessageDialog();
-
- /**
- * factory function for message dialogs. This can be used as a fire-and-forget. The message
- * will automatically positioned to the reference dialog and get a reasonable view time
- *
- * @param text the text to display. The length of this text is used to determine how long the dialog is to be shown
- * @param reference the reference widget on top of which the message should be displayed
- * @param true if the message should bring MO to front to ensure this message is visible
- **/
- static void showMessage(const QString& text, QWidget* reference, bool bringToFront = true);
+ /**
+ * factory function for message dialogs. This can be used as a fire-and-forget. The message
+ * will automatically positioned to the reference dialog and get a reasonable view time
+ *
+ * @param text the text to display. The length of this text is used to determine how long the dialog is to be shown
+ * @param reference the reference widget on top of which the message should be displayed
+ * @param true if the message should bring MO to front to ensure this message is visible
+ **/
+ static void showMessage(const QString &text, QWidget *reference, bool bringToFront = true);
protected:
- virtual void resizeEvent(QResizeEvent* event);
+
+ virtual void resizeEvent(QResizeEvent *event);
private:
- Ui::MessageDialog* ui;
+ Ui::MessageDialog *ui;
};
#endif // MESSAGEDIALOG_H
diff --git a/src/moapplication.cpp b/src/moapplication.cpp
index 9397dadd..9ddd9e54 100644
--- a/src/moapplication.cpp
+++ b/src/moapplication.cpp
@@ -18,111 +18,126 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "moapplication.h"
-#include <QFile>
-#include <QStringList>
-#include <appconfig.h>
#include <report.h>
#include <utility.h>
-#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
-#include <QCleanlooksStyle>
+#include <appconfig.h>
+#include <QFile>
+#include <QStringList>
+#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
#include <QPlastiqueStyle>
+#include <QCleanlooksStyle>
#endif
-#include <QPainter>
#include <QProxyStyle>
#include <QStyleFactory>
+#include <QPainter>
#include <QStyleOption>
+
#include <QDebug>
+
using MOBase::reportError;
+
class ProxyStyle : public QProxyStyle {
public:
- ProxyStyle(QStyle* baseStyle = 0) : QProxyStyle(baseStyle) {}
+ ProxyStyle(QStyle *baseStyle = 0)
+ : QProxyStyle(baseStyle)
+ {
+ }
- void drawPrimitive(PrimitiveElement element, const QStyleOption* option, QPainter* painter,
- const QWidget* widget) const {
- if (element == QStyle::PE_IndicatorItemViewItemDrop) {
- painter->setRenderHint(QPainter::Antialiasing, true);
+ void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const {
+ if(element == QStyle::PE_IndicatorItemViewItemDrop) {
+ painter->setRenderHint(QPainter::Antialiasing, true);
- QColor col(option->palette.foreground().color());
- QPen pen(col);
- pen.setWidth(2);
- col.setAlpha(50);
- QBrush brush(col);
+ QColor col(option->palette.foreground().color());
+ QPen pen(col);
+ pen.setWidth(2);
+ col.setAlpha(50);
+ QBrush brush(col);
- painter->setPen(pen);
- painter->setBrush(brush);
- if (option->rect.height() == 0) {
- QPoint tri[3] = {option->rect.topLeft(), option->rect.topLeft() + QPoint(-5, 5),
- option->rect.topLeft() + QPoint(-5, -5)};
- painter->drawPolygon(tri, 3);
- painter->drawLine(QPoint(option->rect.topLeft().x(), option->rect.topLeft().y()),
- option->rect.topRight());
- } else {
- painter->drawRoundedRect(option->rect, 5, 5);
- }
- } else {
- QProxyStyle::drawPrimitive(element, option, painter, widget);
- }
+ painter->setPen(pen);
+ painter->setBrush(brush);
+ if(option->rect.height() == 0) {
+ QPoint tri[3] = {
+ option->rect.topLeft(),
+ option->rect.topLeft() + QPoint(-5, 5),
+ option->rect.topLeft() + QPoint(-5, -5)
+ };
+ painter->drawPolygon(tri, 3);
+ painter->drawLine(QPoint(option->rect.topLeft().x(), option->rect.topLeft().y()), option->rect.topRight());
+ } else {
+ painter->drawRoundedRect(option->rect, 5, 5);
+ }
+ } else {
+ QProxyStyle::drawPrimitive(element, option, painter, widget);
}
+ }
};
-MOApplication::MOApplication(int& argc, char** argv) : QApplication(argc, argv) {
- connect(&m_StyleWatcher, SIGNAL(fileChanged(QString)), SLOT(updateStyle(QString)));
- m_DefaultStyle = style()->objectName();
- setStyle(new ProxyStyle(style()));
+
+MOApplication::MOApplication(int &argc, char **argv)
+ : QApplication(argc, argv)
+{
+ connect(&m_StyleWatcher, SIGNAL(fileChanged(QString)), SLOT(updateStyle(QString)));
+ m_DefaultStyle = style()->objectName();
+ setStyle(new ProxyStyle(style()));
}
-bool MOApplication::setStyleFile(const QString& styleName) {
- // remove all files from watch
- QStringList currentWatch = m_StyleWatcher.files();
- if (currentWatch.count() != 0) {
- m_StyleWatcher.removePaths(currentWatch);
- }
- // set new stylesheet or clear it
- if (styleName.length() != 0) {
- QString styleSheetName =
- applicationDirPath() + "/" + MOBase::ToQString(AppConfig::stylesheetsPath()) + "/" + styleName;
- if (QFile::exists(styleSheetName)) {
- m_StyleWatcher.addPath(styleSheetName);
- updateStyle(styleSheetName);
- } else {
- updateStyle(styleName);
- }
+
+bool MOApplication::setStyleFile(const QString &styleName)
+{
+ // remove all files from watch
+ QStringList currentWatch = m_StyleWatcher.files();
+ if (currentWatch.count() != 0) {
+ m_StyleWatcher.removePaths(currentWatch);
+ }
+ // set new stylesheet or clear it
+ if (styleName.length() != 0) {
+ QString styleSheetName = applicationDirPath() + "/" + MOBase::ToQString(AppConfig::stylesheetsPath()) + "/" + styleName;
+ if (QFile::exists(styleSheetName)) {
+ m_StyleWatcher.addPath(styleSheetName);
+ updateStyle(styleSheetName);
} else {
- setStyle(new ProxyStyle(QStyleFactory::create(m_DefaultStyle)));
- setStyleSheet("");
+ updateStyle(styleName);
}
- return true;
+ } else {
+ setStyle(new ProxyStyle(QStyleFactory::create(m_DefaultStyle)));
+ setStyleSheet("");
+ }
+ return true;
}
-bool MOApplication::notify(QObject* receiver, QEvent* event) {
- try {
- return QApplication::notify(receiver, event);
- } catch (const std::exception& e) {
- qCritical("uncaught exception in handler (object %s, eventtype %d): %s",
- receiver->objectName().toUtf8().constData(), event->type(), e.what());
- reportError(tr("an error occured: %1").arg(e.what()));
- return false;
- } catch (...) {
- qCritical("uncaught non-std exception in handler (object %s, eventtype %d)",
- receiver->objectName().toUtf8().constData(), event->type());
- reportError(tr("an error occured"));
- return false;
- }
+
+bool MOApplication::notify(QObject *receiver, QEvent *event)
+{
+ try {
+ return QApplication::notify(receiver, event);
+ } catch (const std::exception &e) {
+ qCritical("uncaught exception in handler (object %s, eventtype %d): %s",
+ receiver->objectName().toUtf8().constData(), event->type(), e.what());
+ reportError(tr("an error occured: %1").arg(e.what()));
+ return false;
+ } catch (...) {
+ qCritical("uncaught non-std exception in handler (object %s, eventtype %d)",
+ receiver->objectName().toUtf8().constData(), event->type());
+ reportError(tr("an error occured"));
+ return false;
+ }
}
-void MOApplication::updateStyle(const QString& fileName) {
- if (fileName == "Fusion") {
- setStyle(QStyleFactory::create("fusion"));
- setStyleSheet("");
+
+void MOApplication::updateStyle(const QString &fileName)
+{
+ if (fileName == "Fusion") {
+ setStyle(QStyleFactory::create("fusion"));
+ setStyleSheet("");
+ } else {
+ setStyle(new ProxyStyle(QStyleFactory::create(m_DefaultStyle)));
+ if (QFile::exists(fileName)) {
+ setStyleSheet(QString("file:///%1").arg(fileName));
} else {
- setStyle(new ProxyStyle(QStyleFactory::create(m_DefaultStyle)));
- if (QFile::exists(fileName)) {
- setStyleSheet(QString("file:///%1").arg(fileName));
- } else {
- qWarning("invalid stylesheet: %s", qPrintable(fileName));
- }
+ qWarning("invalid stylesheet: %s", qPrintable(fileName));
}
+ }
}
diff --git a/src/moapplication.h b/src/moapplication.h
index bb8de414..9db130af 100644
--- a/src/moapplication.h
+++ b/src/moapplication.h
@@ -23,24 +23,29 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QApplication>
#include <QFileSystemWatcher>
+
class MOApplication : public QApplication {
- Q_OBJECT
+Q_OBJECT
public:
- MOApplication(int& argc, char** argv);
- virtual bool notify(QObject* receiver, QEvent* event);
+ MOApplication(int &argc, char **argv);
+
+ virtual bool notify (QObject *receiver, QEvent *event);
public slots:
- bool setStyleFile(const QString& style);
+ bool setStyleFile(const QString &style);
private slots:
- void updateStyle(const QString& fileName);
+ void updateStyle(const QString &fileName);
private:
- QFileSystemWatcher m_StyleWatcher;
- QString m_DefaultStyle;
+
+ QFileSystemWatcher m_StyleWatcher;
+ QString m_DefaultStyle;
+
};
+
#endif // MOAPPLICATION_H
diff --git a/src/modeltest.cpp b/src/modeltest.cpp
index d645d464..90061261 100644
--- a/src/modeltest.cpp
+++ b/src/modeltest.cpp
@@ -39,6 +39,7 @@
**
****************************************************************************/
+
#include <QtGui/QtGui>
#include "modeltest.h"
@@ -50,48 +51,61 @@
#undef QCOMPARE
#define QCOMPARE(x, y) Q_ASSERT(x == y)
-Q_DECLARE_METATYPE(QModelIndex)
+Q_DECLARE_METATYPE ( QModelIndex )
/*!
Connect to all of the models signals. Whenever anything happens recheck everything.
*/
-ModelTest::ModelTest(QAbstractItemModel* _model, QObject* parent)
- : QObject(parent), model(_model), fetchingMore(false) {
+ModelTest::ModelTest ( QAbstractItemModel *_model, QObject *parent ) : QObject ( parent ), model ( _model ), fetchingMore ( false )
+{
if (!model)
qFatal("%s: model must not be null", Q_FUNC_INFO);
- connect(model, SIGNAL(columnsAboutToBeInserted(const QModelIndex&, int, int)), this, SLOT(runAllTests()));
- connect(model, SIGNAL(columnsAboutToBeRemoved(const QModelIndex&, int, int)), this, SLOT(runAllTests()));
- connect(model, SIGNAL(columnsInserted(const QModelIndex&, int, int)), this, SLOT(runAllTests()));
- connect(model, SIGNAL(columnsRemoved(const QModelIndex&, int, int)), this, SLOT(runAllTests()));
- connect(model, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(runAllTests()));
- connect(model, SIGNAL(headerDataChanged(Qt::Orientation, int, int)), this, SLOT(runAllTests()));
- connect(model, SIGNAL(layoutAboutToBeChanged()), this, SLOT(runAllTests()));
- connect(model, SIGNAL(layoutChanged()), this, SLOT(runAllTests()));
- connect(model, SIGNAL(modelReset()), this, SLOT(runAllTests()));
- connect(model, SIGNAL(rowsAboutToBeInserted(const QModelIndex&, int, int)), this, SLOT(runAllTests()));
- connect(model, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)), this, SLOT(runAllTests()));
- connect(model, SIGNAL(rowsInserted(const QModelIndex&, int, int)), this, SLOT(runAllTests()));
- connect(model, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), this, SLOT(runAllTests()));
+ connect ( model, SIGNAL ( columnsAboutToBeInserted ( const QModelIndex &, int, int ) ),
+ this, SLOT ( runAllTests() ) );
+ connect ( model, SIGNAL ( columnsAboutToBeRemoved ( const QModelIndex &, int, int ) ),
+ this, SLOT ( runAllTests() ) );
+ connect ( model, SIGNAL ( columnsInserted ( const QModelIndex &, int, int ) ),
+ this, SLOT ( runAllTests() ) );
+ connect ( model, SIGNAL ( columnsRemoved ( const QModelIndex &, int, int ) ),
+ this, SLOT ( runAllTests() ) );
+ connect ( model, SIGNAL ( dataChanged ( const QModelIndex &, const QModelIndex & ) ),
+ this, SLOT ( runAllTests() ) );
+ connect ( model, SIGNAL ( headerDataChanged ( Qt::Orientation, int, int ) ),
+ this, SLOT ( runAllTests() ) );
+ connect ( model, SIGNAL ( layoutAboutToBeChanged () ), this, SLOT ( runAllTests() ) );
+ connect ( model, SIGNAL ( layoutChanged () ), this, SLOT ( runAllTests() ) );
+ connect ( model, SIGNAL ( modelReset () ), this, SLOT ( runAllTests() ) );
+ connect ( model, SIGNAL ( rowsAboutToBeInserted ( const QModelIndex &, int, int ) ),
+ this, SLOT ( runAllTests() ) );
+ connect ( model, SIGNAL ( rowsAboutToBeRemoved ( const QModelIndex &, int, int ) ),
+ this, SLOT ( runAllTests() ) );
+ connect ( model, SIGNAL ( rowsInserted ( const QModelIndex &, int, int ) ),
+ this, SLOT ( runAllTests() ) );
+ connect ( model, SIGNAL ( rowsRemoved ( const QModelIndex &, int, int ) ),
+ this, SLOT ( runAllTests() ) );
// Special checks for inserting/removing
- connect(model, SIGNAL(layoutAboutToBeChanged()), this, SLOT(layoutAboutToBeChanged()));
- connect(model, SIGNAL(layoutChanged()), this, SLOT(layoutChanged()));
+ connect ( model, SIGNAL ( layoutAboutToBeChanged() ),
+ this, SLOT ( layoutAboutToBeChanged() ) );
+ connect ( model, SIGNAL ( layoutChanged() ),
+ this, SLOT ( layoutChanged() ) );
- connect(model, SIGNAL(rowsAboutToBeInserted(const QModelIndex&, int, int)), this,
- SLOT(rowsAboutToBeInserted(const QModelIndex&, int, int)));
- connect(model, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)), this,
- SLOT(rowsAboutToBeRemoved(const QModelIndex&, int, int)));
- connect(model, SIGNAL(rowsInserted(const QModelIndex&, int, int)), this,
- SLOT(rowsInserted(const QModelIndex&, int, int)));
- connect(model, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), this,
- SLOT(rowsRemoved(const QModelIndex&, int, int)));
+ connect ( model, SIGNAL ( rowsAboutToBeInserted ( const QModelIndex &, int, int ) ),
+ this, SLOT ( rowsAboutToBeInserted ( const QModelIndex &, int, int ) ) );
+ connect ( model, SIGNAL ( rowsAboutToBeRemoved ( const QModelIndex &, int, int ) ),
+ this, SLOT ( rowsAboutToBeRemoved ( const QModelIndex &, int, int ) ) );
+ connect ( model, SIGNAL ( rowsInserted ( const QModelIndex &, int, int ) ),
+ this, SLOT ( rowsInserted ( const QModelIndex &, int, int ) ) );
+ connect ( model, SIGNAL ( rowsRemoved ( const QModelIndex &, int, int ) ),
+ this, SLOT ( rowsRemoved ( const QModelIndex &, int, int ) ) );
runAllTests();
}
-void ModelTest::runAllTests() {
- if (fetchingMore)
+void ModelTest::runAllTests()
+{
+ if ( fetchingMore )
return;
nonDestructiveBasicTest();
rowCount();
@@ -106,33 +120,34 @@ void ModelTest::runAllTests() {
nonDestructiveBasicTest tries to call a number of the basic functions (not all)
to make sure the model doesn't outright segfault, testing the functions that makes sense.
*/
-void ModelTest::nonDestructiveBasicTest() {
- QVERIFY(model->buddy(QModelIndex()) == QModelIndex());
- model->canFetchMore(QModelIndex());
- QVERIFY(model->columnCount(QModelIndex()) >= 0);
- QVERIFY(model->data(QModelIndex()) == QVariant());
+void ModelTest::nonDestructiveBasicTest()
+{
+ QVERIFY( model->buddy ( QModelIndex() ) == QModelIndex() );
+ model->canFetchMore ( QModelIndex() );
+ QVERIFY( model->columnCount ( QModelIndex() ) >= 0 );
+ QVERIFY( model->data ( QModelIndex() ) == QVariant() );
fetchingMore = true;
- model->fetchMore(QModelIndex());
+ model->fetchMore ( QModelIndex() );
fetchingMore = false;
- Qt::ItemFlags flags = model->flags(QModelIndex());
- QVERIFY(flags == Qt::ItemIsDropEnabled || flags == 0);
- model->hasChildren(QModelIndex());
- model->hasIndex(0, 0);
- model->headerData(0, Qt::Horizontal);
- model->index(0, 0);
- model->itemData(QModelIndex());
+ Qt::ItemFlags flags = model->flags ( QModelIndex() );
+ QVERIFY( flags == Qt::ItemIsDropEnabled || flags == 0 );
+ model->hasChildren ( QModelIndex() );
+ model->hasIndex ( 0, 0 );
+ model->headerData ( 0, Qt::Horizontal );
+ model->index ( 0, 0 );
+ model->itemData ( QModelIndex() );
QVariant cache;
- model->match(QModelIndex(), -1, cache);
+ model->match ( QModelIndex(), -1, cache );
model->mimeTypes();
- QVERIFY(model->parent(QModelIndex()) == QModelIndex());
- QVERIFY(model->rowCount() >= 0);
+ QVERIFY( model->parent ( QModelIndex() ) == QModelIndex() );
+ QVERIFY( model->rowCount() >= 0 );
QVariant variant;
- model->setData(QModelIndex(), variant, -1);
- model->setHeaderData(-1, Qt::Horizontal, QVariant());
- model->setHeaderData(999999, Qt::Horizontal, QVariant());
+ model->setData ( QModelIndex(), variant, -1 );
+ model->setHeaderData ( -1, Qt::Horizontal, QVariant() );
+ model->setHeaderData ( 999999, Qt::Horizontal, QVariant() );
QMap<int, QVariant> roles;
- model->sibling(0, 0, QModelIndex());
- model->span(QModelIndex());
+ model->sibling ( 0, 0, QModelIndex() );
+ model->span ( QModelIndex() );
model->supportedDropActions();
}
@@ -141,28 +156,29 @@ void ModelTest::nonDestructiveBasicTest() {
Models that are dynamically populated are not as fully tested here.
*/
-void ModelTest::rowCount() {
- // qDebug() << "rc";
+void ModelTest::rowCount()
+{
+// qDebug() << "rc";
// check top row
- QModelIndex topIndex = model->index(0, 0, QModelIndex());
- if (!model->hasChildren(topIndex) && model->rowCount(topIndex) > 0) {
- qDebug() << "it's gonna blow: " << topIndex;
- }
+ QModelIndex topIndex = model->index ( 0, 0, QModelIndex() );
+ if (!model->hasChildren ( topIndex ) && model->rowCount(topIndex) > 0) {
+ qDebug() << "it's gonna blow: " << topIndex;
+ }
- int rows = model->rowCount(topIndex);
- QVERIFY(rows >= 0);
- if (rows > 0) {
- QVERIFY(model->hasChildren(topIndex));
+ int rows = model->rowCount ( topIndex );
+ QVERIFY( rows >= 0 );
+ if ( rows > 0 ) {
+ QVERIFY( model->hasChildren ( topIndex ) );
}
- QModelIndex secondLevelIndex = model->index(0, 0, topIndex);
- if (secondLevelIndex.isValid()) { // not the top level
+ QModelIndex secondLevelIndex = model->index ( 0, 0, topIndex );
+ if ( secondLevelIndex.isValid() ) { // not the top level
// check a row count where parent is valid
- rows = model->rowCount(secondLevelIndex);
- QVERIFY(rows >= 0);
- if (rows > 0)
- QVERIFY(model->hasChildren(secondLevelIndex));
+ rows = model->rowCount ( secondLevelIndex );
+ QVERIFY( rows >= 0 );
+ if ( rows > 0 )
+ QVERIFY( model->hasChildren ( secondLevelIndex ) );
}
// The models rowCount() is tested more extensively in checkChildren(),
@@ -172,15 +188,16 @@ void ModelTest::rowCount() {
/*!
Tests model's implementation of QAbstractItemModel::columnCount() and hasChildren()
*/
-void ModelTest::columnCount() {
+void ModelTest::columnCount()
+{
// check top row
- QModelIndex topIndex = model->index(0, 0, QModelIndex());
- QVERIFY(model->columnCount(topIndex) >= 0);
+ QModelIndex topIndex = model->index ( 0, 0, QModelIndex() );
+ QVERIFY( model->columnCount ( topIndex ) >= 0 );
// check a column count where parent is valid
- QModelIndex childIndex = model->index(0, 0, topIndex);
- if (childIndex.isValid())
- QVERIFY(model->columnCount(childIndex) >= 0);
+ QModelIndex childIndex = model->index ( 0, 0, topIndex );
+ if ( childIndex.isValid() )
+ QVERIFY( model->columnCount ( childIndex ) >= 0 );
// columnCount() is tested more extensively in checkChildren(),
// but this catches the big mistakes
@@ -189,22 +206,23 @@ void ModelTest::columnCount() {
/*!
Tests model's implementation of QAbstractItemModel::hasIndex()
*/
-void ModelTest::hasIndex() {
- // qDebug() << "hi";
+void ModelTest::hasIndex()
+{
+// qDebug() << "hi";
// Make sure that invalid values returns an invalid index
- QVERIFY(!model->hasIndex(-2, -2));
- QVERIFY(!model->hasIndex(-2, 0));
- QVERIFY(!model->hasIndex(0, -2));
+ QVERIFY( !model->hasIndex ( -2, -2 ) );
+ QVERIFY( !model->hasIndex ( -2, 0 ) );
+ QVERIFY( !model->hasIndex ( 0, -2 ) );
int rows = model->rowCount();
int columns = model->columnCount();
// check out of bounds
- QVERIFY(!model->hasIndex(rows, columns));
- QVERIFY(!model->hasIndex(rows + 1, columns + 1));
+ QVERIFY( !model->hasIndex ( rows, columns ) );
+ QVERIFY( !model->hasIndex ( rows + 1, columns + 1 ) );
- if (rows > 0)
- QVERIFY(model->hasIndex(0, 0));
+ if ( rows > 0 )
+ QVERIFY( model->hasIndex ( 0, 0 ) );
// hasIndex() is tested more extensively in checkChildren(),
// but this catches the big mistakes
@@ -213,31 +231,32 @@ void ModelTest::hasIndex() {
/*!
Tests model's implementation of QAbstractItemModel::index()
*/
-void ModelTest::index() {
- // qDebug() << "i";
+void ModelTest::index()
+{
+// qDebug() << "i";
// Make sure that invalid values returns an invalid index
- /* QVERIFY( model->index ( -2, -2 ) == QModelIndex() );
- QVERIFY( model->index ( -2, 0 ) == QModelIndex() );
- QVERIFY( model->index ( 0, -2 ) == QModelIndex() );*/
- QVERIFY(!model->index(-2, -2).isValid());
- QVERIFY(!model->index(-2, 0).isValid());
- QVERIFY(!model->index(0, -2).isValid());
+/* QVERIFY( model->index ( -2, -2 ) == QModelIndex() );
+ QVERIFY( model->index ( -2, 0 ) == QModelIndex() );
+ QVERIFY( model->index ( 0, -2 ) == QModelIndex() );*/
+ QVERIFY( !model->index ( -2, -2 ).isValid() );
+ QVERIFY( !model->index ( -2, 0 ).isValid() );
+ QVERIFY( !model->index ( 0, -2 ).isValid() );
int rows = model->rowCount();
int columns = model->columnCount();
- if (rows == 0)
+ if ( rows == 0 )
return;
// Catch off by one errors
- // QVERIFY( model->index ( rows, columns ) == QModelIndex() );
- QVERIFY(!model->index(rows, columns).isValid());
- QVERIFY(model->index(0, 0).isValid());
+ //QVERIFY( model->index ( rows, columns ) == QModelIndex() );
+ QVERIFY( !model->index ( rows, columns ).isValid() );
+ QVERIFY( model->index ( 0, 0 ).isValid() );
// Make sure that the same index is *always* returned
- QModelIndex a = model->index(0, 0);
- QModelIndex b = model->index(0, 0);
- QVERIFY(a == b);
+ QModelIndex a = model->index ( 0, 0 );
+ QModelIndex b = model->index ( 0, 0 );
+ QVERIFY( a == b );
// index() is tested more extensively in checkChildren(),
// but this catches the big mistakes
@@ -246,13 +265,14 @@ void ModelTest::index() {
/*!
Tests model's implementation of QAbstractItemModel::parent()
*/
-void ModelTest::parent() {
- // qDebug() << "p";
+void ModelTest::parent()
+{
+// qDebug() << "p";
// Make sure the model wont crash and will return an invalid QModelIndex
// when asked for the parent of an invalid index.
- QVERIFY(model->parent(QModelIndex()) == QModelIndex());
+ QVERIFY( model->parent ( QModelIndex() ) == QModelIndex() );
- if (model->rowCount() == 0)
+ if ( model->rowCount() == 0 )
return;
// Column 0 | Column 1 |
@@ -262,29 +282,29 @@ void ModelTest::parent() {
// Common error test #1, make sure that a top level index has a parent
// that is a invalid QModelIndex.
- QModelIndex topIndex = model->index(0, 0, QModelIndex());
- QVERIFY(model->parent(topIndex) == QModelIndex());
+ QModelIndex topIndex = model->index ( 0, 0, QModelIndex() );
+ QVERIFY( model->parent ( topIndex ) == QModelIndex() );
// Common error test #2, make sure that a second level index has a parent
// that is the first level index.
- if (model->rowCount(topIndex) > 0) {
- QModelIndex childIndex = model->index(0, 0, topIndex);
- QVERIFY(model->parent(childIndex) == topIndex);
+ if ( model->rowCount ( topIndex ) > 0 ) {
+ QModelIndex childIndex = model->index ( 0, 0, topIndex );
+ QVERIFY( model->parent ( childIndex ) == topIndex );
}
// Common error test #3, the second column should NOT have the same children
// as the first column in a row.
// Usually the second column shouldn't have children.
- QModelIndex topIndex1 = model->index(0, 1, QModelIndex());
- if (model->rowCount(topIndex1) > 0) {
- QModelIndex childIndex = model->index(0, 0, topIndex);
- QModelIndex childIndex1 = model->index(0, 0, topIndex1);
- QVERIFY(childIndex != childIndex1);
+ QModelIndex topIndex1 = model->index ( 0, 1, QModelIndex() );
+ if ( model->rowCount ( topIndex1 ) > 0 ) {
+ QModelIndex childIndex = model->index ( 0, 0, topIndex );
+ QModelIndex childIndex1 = model->index ( 0, 0, topIndex1 );
+ QVERIFY( childIndex != childIndex1 );
}
// Full test, walk n levels deep through the model making sure that all
// parent's children correctly specify their parent.
- checkChildren(QModelIndex());
+ checkChildren ( QModelIndex() );
}
/*!
@@ -301,88 +321,90 @@ void ModelTest::parent() {
found the basic bugs because it is easier to figure out the problem in
those tests then this one.
*/
-void ModelTest::checkChildren(const QModelIndex& parent, int currentDepth) {
+void ModelTest::checkChildren ( const QModelIndex &parent, int currentDepth )
+{
// First just try walking back up the tree.
QModelIndex p = parent;
- while (p.isValid())
+ while ( p.isValid() )
p = p.parent();
// For models that are dynamically populated
- if (model->canFetchMore(parent)) {
+ if ( model->canFetchMore ( parent ) ) {
fetchingMore = true;
- model->fetchMore(parent);
+ model->fetchMore ( parent );
fetchingMore = false;
}
- int rows = model->rowCount(parent);
- int columns = model->columnCount(parent);
+ int rows = model->rowCount ( parent );
+ int columns = model->columnCount ( parent );
- if (rows > 0)
- QVERIFY(model->hasChildren(parent));
+ if ( rows > 0 )
+ QVERIFY( model->hasChildren ( parent ) );
// Some further testing against rows(), columns(), and hasChildren()
- QVERIFY(rows >= 0);
- QVERIFY(columns >= 0);
- if (rows > 0)
- QVERIFY(model->hasChildren(parent));
+ QVERIFY( rows >= 0 );
+ QVERIFY( columns >= 0 );
+ if ( rows > 0 )
+ QVERIFY( model->hasChildren ( parent ) );
- // qDebug() << "parent:" << model->data(parent).toString() << "rows:" << rows
+ //qDebug() << "parent:" << model->data(parent).toString() << "rows:" << rows
// << "columns:" << columns << "parent column:" << parent.column();
- QVERIFY(!model->hasIndex(rows + 1, 0, parent));
- for (int r = 0; r < rows; ++r) {
- if (model->canFetchMore(parent)) {
+ QVERIFY( !model->hasIndex ( rows + 1, 0, parent ) );
+ for ( int r = 0; r < rows; ++r ) {
+ if ( model->canFetchMore ( parent ) ) {
fetchingMore = true;
- model->fetchMore(parent);
+ model->fetchMore ( parent );
fetchingMore = false;
}
- QVERIFY(!model->hasIndex(r, columns + 1, parent));
- for (int c = 0; c < columns; ++c) {
- QVERIFY(model->hasIndex(r, c, parent));
- QModelIndex index = model->index(r, c, parent);
+ QVERIFY( !model->hasIndex ( r, columns + 1, parent ) );
+ for ( int c = 0; c < columns; ++c ) {
+ QVERIFY( model->hasIndex ( r, c, parent ) );
+ QModelIndex index = model->index ( r, c, parent );
// rowCount() and columnCount() said that it existed...
- QVERIFY(index.isValid());
+ QVERIFY( index.isValid() );
// index() should always return the same index when called twice in a row
- QModelIndex modifiedIndex = model->index(r, c, parent);
- QVERIFY(index == modifiedIndex);
+ QModelIndex modifiedIndex = model->index ( r, c, parent );
+ QVERIFY( index == modifiedIndex );
// Make sure we get the same index if we request it twice in a row
- QModelIndex a = model->index(r, c, parent);
- QModelIndex b = model->index(r, c, parent);
- QVERIFY(a == b);
+ QModelIndex a = model->index ( r, c, parent );
+ QModelIndex b = model->index ( r, c, parent );
+ QVERIFY( a == b );
// Some basic checking on the index that is returned
- QVERIFY(index.model() == model);
- QCOMPARE(index.row(), r);
- QCOMPARE(index.column(), c);
+ QVERIFY( index.model() == model );
+ QCOMPARE( index.row(), r );
+ QCOMPARE( index.column(), c );
// While you can technically return a QVariant usually this is a sign
// of a bug in data(). Disable if this really is ok in your model.
- // QVERIFY( model->data ( index, Qt::DisplayRole ).isValid() );
+// QVERIFY( model->data ( index, Qt::DisplayRole ).isValid() );
// If the next test fails here is some somewhat useful debug you play with.
if (model->parent(index) != parent) {
- qDebug() << r << c << currentDepth << model->data(index).toString() << model->data(parent).toString();
+ qDebug() << r << c << currentDepth << model->data(index).toString()
+ << model->data(parent).toString();
qDebug() << index << parent << model->parent(index);
- // And a view that you can even use to show the model.
- // QTreeView view;
- // view.setModel(model);
- // view.show();
+// And a view that you can even use to show the model.
+// QTreeView view;
+// view.setModel(model);
+// view.show();
}
// Check that we can get back our real parent.
- QCOMPARE(model->parent(index), parent);
+ QCOMPARE( model->parent ( index ), parent );
// recursively go down the children
- if (model->hasChildren(index) && currentDepth < 10) {
- // qDebug() << r << c << "has children" << model->rowCount(index);
- checkChildren(index, ++currentDepth);
- } /* else { if (currentDepth >= 10) qDebug() << "checked 10 deep"; };*/
+ if ( model->hasChildren ( index ) && currentDepth < 10 ) {
+ //qDebug() << r << c << "has children" << model->rowCount(index);
+ checkChildren ( index, ++currentDepth );
+ }/* else { if (currentDepth >= 10) qDebug() << "checked 10 deep"; };*/
// make sure that after testing the children that the index doesn't change.
- QModelIndex newerIndex = model->index(r, c, parent);
- QVERIFY(index == newerIndex);
+ QModelIndex newerIndex = model->index ( r, c, parent );
+ QVERIFY( index == newerIndex );
}
}
}
@@ -390,68 +412,71 @@ void ModelTest::checkChildren(const QModelIndex& parent, int currentDepth) {
/*!
Tests model's implementation of QAbstractItemModel::data()
*/
-void ModelTest::data() {
+void ModelTest::data()
+{
// Invalid index should return an invalid qvariant
- QVERIFY(!model->data(QModelIndex()).isValid());
+ QVERIFY( !model->data ( QModelIndex() ).isValid() );
- if (model->rowCount() == 0)
+ if ( model->rowCount() == 0 )
return;
// A valid index should have a valid QVariant data
- QVERIFY(model->index(0, 0).isValid());
+ QVERIFY( model->index ( 0, 0 ).isValid() );
// shouldn't be able to set data on an invalid index
- QVERIFY(!model->setData(QModelIndex(), QLatin1String("foo"), Qt::DisplayRole));
+ QVERIFY( !model->setData ( QModelIndex(), QLatin1String ( "foo" ), Qt::DisplayRole ) );
// General Purpose roles that should return a QString
- QVariant variant = model->data(model->index(0, 0), Qt::ToolTipRole);
- if (variant.isValid()) {
- QVERIFY(variant.canConvert(QMetaType::QString));
+ QVariant variant = model->data ( model->index ( 0, 0 ), Qt::ToolTipRole );
+ if ( variant.isValid() ) {
+ QVERIFY( variant.canConvert(QMetaType::QString) );
}
- variant = model->data(model->index(0, 0), Qt::StatusTipRole);
- if (variant.isValid()) {
- QVERIFY(variant.canConvert(QMetaType::QString));
+ variant = model->data ( model->index ( 0, 0 ), Qt::StatusTipRole );
+ if ( variant.isValid() ) {
+ QVERIFY( variant.canConvert(QMetaType::QString) );
}
- variant = model->data(model->index(0, 0), Qt::WhatsThisRole);
- if (variant.isValid()) {
- QVERIFY(variant.canConvert(QMetaType::QString));
+ variant = model->data ( model->index ( 0, 0 ), Qt::WhatsThisRole );
+ if ( variant.isValid() ) {
+ QVERIFY( variant.canConvert(QMetaType::QString) );
}
// General Purpose roles that should return a QSize
- variant = model->data(model->index(0, 0), Qt::SizeHintRole);
- if (variant.isValid()) {
- QVERIFY(variant.canConvert(QMetaType::QSize));
+ variant = model->data ( model->index ( 0, 0 ), Qt::SizeHintRole );
+ if ( variant.isValid() ) {
+ QVERIFY( variant.canConvert(QMetaType::QSize) );
}
// General Purpose roles that should return a QFont
- QVariant fontVariant = model->data(model->index(0, 0), Qt::FontRole);
- if (fontVariant.isValid()) {
- QVERIFY(fontVariant.canConvert(QMetaType::QFont));
+ QVariant fontVariant = model->data ( model->index ( 0, 0 ), Qt::FontRole );
+ if ( fontVariant.isValid() ) {
+ QVERIFY( fontVariant.canConvert(QMetaType::QFont) );
}
// Check that the alignment is one we know about
- QVariant textAlignmentVariant = model->data(model->index(0, 0), Qt::TextAlignmentRole);
- if (textAlignmentVariant.isValid()) {
+ QVariant textAlignmentVariant = model->data ( model->index ( 0, 0 ), Qt::TextAlignmentRole );
+ if ( textAlignmentVariant.isValid() ) {
int alignment = textAlignmentVariant.toInt();
- QCOMPARE(alignment, (alignment & (Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask)));
+ QCOMPARE( alignment, ( alignment & ( Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask ) ) );
}
// General Purpose roles that should return a QColor
- QVariant colorVariant = model->data(model->index(0, 0), Qt::BackgroundColorRole);
- if (colorVariant.isValid()) {
- QVERIFY(colorVariant.canConvert(QMetaType::QColor));
+ QVariant colorVariant = model->data ( model->index ( 0, 0 ), Qt::BackgroundColorRole );
+ if ( colorVariant.isValid() ) {
+ QVERIFY( colorVariant.canConvert(QMetaType::QColor) );
}
- colorVariant = model->data(model->index(0, 0), Qt::TextColorRole);
- if (colorVariant.isValid()) {
- QVERIFY(colorVariant.canConvert(QMetaType::QColor));
+ colorVariant = model->data ( model->index ( 0, 0 ), Qt::TextColorRole );
+ if ( colorVariant.isValid() ) {
+ QVERIFY( colorVariant.canConvert(QMetaType::QColor) );
}
// Check that the "check state" is one we know about.
- QVariant checkStateVariant = model->data(model->index(0, 0), Qt::CheckStateRole);
- if (checkStateVariant.isValid()) {
+ QVariant checkStateVariant = model->data ( model->index ( 0, 0 ), Qt::CheckStateRole );
+ if ( checkStateVariant.isValid() ) {
int state = checkStateVariant.toInt();
- QVERIFY(state == Qt::Unchecked || state == Qt::PartiallyChecked || state == Qt::Checked);
+ QVERIFY( state == Qt::Unchecked ||
+ state == Qt::PartiallyChecked ||
+ state == Qt::Checked );
}
}
@@ -460,20 +485,19 @@ void ModelTest::data() {
\sa rowsInserted()
*/
-void ModelTest::rowsAboutToBeInserted(const QModelIndex& parent, int start, int end) {
- // Q_UNUSED(end);
- // qDebug() << "rowsAboutToBeInserted" << "start=" << start << "end=" << end << "parent=" << model->data ( parent
- // ).toString()
- // << "current count of parent=" << model->rowCount ( parent ); // << "display of last=" << model->data(
- // model->index(start-1, 0, parent) );
- // qDebug() << model->index(start-1, 0, parent) << model->data( model->index(start-1, 0, parent) );
+void ModelTest::rowsAboutToBeInserted ( const QModelIndex &parent, int start, int end )
+{
+// Q_UNUSED(end);
+// qDebug() << "rowsAboutToBeInserted" << "start=" << start << "end=" << end << "parent=" << model->data ( parent ).toString()
+// << "current count of parent=" << model->rowCount ( parent ); // << "display of last=" << model->data( model->index(start-1, 0, parent) );
+// qDebug() << model->index(start-1, 0, parent) << model->data( model->index(start-1, 0, parent) );
Changing c;
c.parent = parent;
- c.oldSize = model->rowCount(parent);
- c.last = model->data(model->index(start - 1, 0, parent));
- c.next = model->data(model->index(start, 0, parent));
- qDebug() << start << " - " << parent << " - " << model->data(model->index(start, 0, parent), Qt::UserRole);
- insert.push(c);
+ c.oldSize = model->rowCount ( parent );
+ c.last = model->data ( model->index ( start - 1, 0, parent ) );
+ c.next = model->data ( model->index ( start, 0, parent ) );
+qDebug() << start << " - " << parent << " - " << model->data ( model->index ( start, 0, parent ), Qt::UserRole );
+ insert.push ( c );
}
/*!
@@ -481,44 +505,46 @@ void ModelTest::rowsAboutToBeInserted(const QModelIndex& parent, int start, int
\sa rowsAboutToBeInserted()
*/
-void ModelTest::rowsInserted(const QModelIndex& parent, int start, int end) {
+void ModelTest::rowsInserted ( const QModelIndex & parent, int start, int end )
+{
Changing c = insert.pop();
- QVERIFY(c.parent == parent);
- // qDebug() << "rowsInserted" << "start=" << start << "end=" << end << "oldsize=" << c.oldSize
- // << "parent=" << model->data ( parent ).toString() << "current rowcount of parent=" << model->rowCount ( parent
- // );
+ QVERIFY( c.parent == parent );
+// qDebug() << "rowsInserted" << "start=" << start << "end=" << end << "oldsize=" << c.oldSize
+// << "parent=" << model->data ( parent ).toString() << "current rowcount of parent=" << model->rowCount ( parent );
- // for (int ii=start; ii <= end; ii++)
- // {
- // qDebug() << "itemWasInserted:" << ii << model->data ( model->index ( ii, 0, parent ));
- // }
- // qDebug();
+// for (int ii=start; ii <= end; ii++)
+// {
+// qDebug() << "itemWasInserted:" << ii << model->data ( model->index ( ii, 0, parent ));
+// }
+// qDebug();
- QVERIFY(c.oldSize + (end - start + 1) == model->rowCount(parent));
- QVERIFY(c.last == model->data(model->index(start - 1, 0, c.parent)));
+ QVERIFY( c.oldSize + ( end - start + 1 ) == model->rowCount ( parent ) );
+ QVERIFY( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) );
if (c.next != model->data(model->index(end + 1, 0, c.parent))) {
qDebug() << start << end;
- for (int i = 0; i < model->rowCount(); ++i)
+ for (int i=0; i < model->rowCount(); ++i)
qDebug() << model->index(i, 0).data().toString();
qDebug() << c.next << model->data(model->index(end + 1, 0, c.parent));
}
- if (c.next != model->data(model->index(end + 1, 0, c.parent))) {
- qDebug("break");
- }
- QVERIFY(c.next == model->data(model->index(end + 1, 0, c.parent)));
+if (c.next != model->data ( model->index ( end + 1, 0, c.parent ) )) {
+ qDebug("break");
+}
+ QVERIFY( c.next == model->data ( model->index ( end + 1, 0, c.parent ) ) );
}
-void ModelTest::layoutAboutToBeChanged() {
- for (int i = 0; i < qBound(0, model->rowCount(), 100); ++i)
- changing.append(QPersistentModelIndex(model->index(i, 0)));
+void ModelTest::layoutAboutToBeChanged()
+{
+ for ( int i = 0; i < qBound ( 0, model->rowCount(), 100 ); ++i )
+ changing.append ( QPersistentModelIndex ( model->index ( i, 0 ) ) );
}
-void ModelTest::layoutChanged() {
- for (int i = 0; i < changing.count(); ++i) {
+void ModelTest::layoutChanged()
+{
+ for ( int i = 0; i < changing.count(); ++i ) {
QPersistentModelIndex p = changing[i];
- QVERIFY(p == model->index(p.row(), p.column(), p.parent()));
+ QVERIFY( p == model->index ( p.row(), p.column(), p.parent() ) );
}
changing.clear();
}
@@ -528,14 +554,15 @@ void ModelTest::layoutChanged() {
\sa rowsRemoved()
*/
-void ModelTest::rowsAboutToBeRemoved(const QModelIndex& parent, int start, int end) {
- qDebug() << "ratbr" << parent << start << end;
+void ModelTest::rowsAboutToBeRemoved ( const QModelIndex &parent, int start, int end )
+{
+qDebug() << "ratbr" << parent << start << end;
Changing c;
c.parent = parent;
- c.oldSize = model->rowCount(parent);
- c.last = model->data(model->index(start - 1, 0, parent));
- c.next = model->data(model->index(end + 1, 0, parent));
- remove.push(c);
+ c.oldSize = model->rowCount ( parent );
+ c.last = model->data ( model->index ( start - 1, 0, parent ) );
+ c.next = model->data ( model->index ( end + 1, 0, parent ) );
+ remove.push ( c );
}
/*!
@@ -543,11 +570,14 @@ void ModelTest::rowsAboutToBeRemoved(const QModelIndex& parent, int start, int e
\sa rowsAboutToBeRemoved()
*/
-void ModelTest::rowsRemoved(const QModelIndex& parent, int start, int end) {
- qDebug() << "rr" << parent << start << end;
+void ModelTest::rowsRemoved ( const QModelIndex & parent, int start, int end )
+{
+ qDebug() << "rr" << parent << start << end;
Changing c = remove.pop();
- QVERIFY(c.parent == parent);
- QVERIFY(c.oldSize - (end - start + 1) == model->rowCount(parent));
- QVERIFY(c.last == model->data(model->index(start - 1, 0, c.parent)));
- QVERIFY(c.next == model->data(model->index(start, 0, c.parent)));
+ QVERIFY( c.parent == parent );
+ QVERIFY( c.oldSize - ( end - start + 1 ) == model->rowCount ( parent ) );
+ QVERIFY( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) );
+ QVERIFY( c.next == model->data ( model->index ( start, 0, c.parent ) ) );
}
+
+
diff --git a/src/modeltest.h b/src/modeltest.h
index b0197a1a..68090f3f 100644
--- a/src/modeltest.h
+++ b/src/modeltest.h
@@ -39,54 +39,56 @@
**
****************************************************************************/
+
#ifndef MODELTEST_H
#define MODELTEST_H
-#include <QtCore/QAbstractItemModel>
#include <QtCore/QObject>
+#include <QtCore/QAbstractItemModel>
#include <QtCore/QStack>
-class ModelTest : public QObject {
- Q_OBJECT
+class ModelTest : public QObject
+{
+ Q_OBJECT
public:
- ModelTest(QAbstractItemModel* model, QObject* parent = 0);
+ ModelTest( QAbstractItemModel *model, QObject *parent = 0 );
private Q_SLOTS:
- void nonDestructiveBasicTest();
- void rowCount();
- void columnCount();
- void hasIndex();
- void index();
- void parent();
- void data();
+ void nonDestructiveBasicTest();
+ void rowCount();
+ void columnCount();
+ void hasIndex();
+ void index();
+ void parent();
+ void data();
protected Q_SLOTS:
- void runAllTests();
- void layoutAboutToBeChanged();
- void layoutChanged();
- void rowsAboutToBeInserted(const QModelIndex& parent, int start, int end);
- void rowsInserted(const QModelIndex& parent, int start, int end);
- void rowsAboutToBeRemoved(const QModelIndex& parent, int start, int end);
- void rowsRemoved(const QModelIndex& parent, int start, int end);
+ void runAllTests();
+ void layoutAboutToBeChanged();
+ void layoutChanged();
+ void rowsAboutToBeInserted( const QModelIndex &parent, int start, int end );
+ void rowsInserted( const QModelIndex & parent, int start, int end );
+ void rowsAboutToBeRemoved( const QModelIndex &parent, int start, int end );
+ void rowsRemoved( const QModelIndex & parent, int start, int end );
private:
- void checkChildren(const QModelIndex& parent, int currentDepth = 0);
+ void checkChildren( const QModelIndex &parent, int currentDepth = 0 );
- QAbstractItemModel* model;
+ QAbstractItemModel *model;
- struct Changing {
- QModelIndex parent;
- int oldSize;
- QVariant last;
- QVariant next;
- };
- QStack<Changing> insert;
- QStack<Changing> remove;
+ struct Changing {
+ QModelIndex parent;
+ int oldSize;
+ QVariant last;
+ QVariant next;
+ };
+ QStack<Changing> insert;
+ QStack<Changing> remove;
- bool fetchingMore;
+ bool fetchingMore;
- QList<QPersistentModelIndex> changing;
+ QList<QPersistentModelIndex> changing;
};
#endif
diff --git a/src/modflagicondelegate.cpp b/src/modflagicondelegate.cpp
index c80f7b8c..61df0a0d 100644
--- a/src/modflagicondelegate.cpp
+++ b/src/modflagicondelegate.cpp
@@ -1,85 +1,87 @@
-#include "modflagicondelegate.h"
+ #include "modflagicondelegate.h"
#include <QList>
-ModInfo::EFlag ModFlagIconDelegate::m_ConflictFlags[4] = {
- ModInfo::FLAG_CONFLICT_MIXED, ModInfo::FLAG_CONFLICT_OVERWRITE, ModInfo::FLAG_CONFLICT_OVERWRITTEN,
- ModInfo::FLAG_CONFLICT_REDUNDANT};
-ModFlagIconDelegate::ModFlagIconDelegate(QObject* parent) : IconDelegate(parent) {}
+ModInfo::EFlag ModFlagIconDelegate::m_ConflictFlags[4] = { ModInfo::FLAG_CONFLICT_MIXED
+ , ModInfo::FLAG_CONFLICT_OVERWRITE
+ , ModInfo::FLAG_CONFLICT_OVERWRITTEN
+ , ModInfo::FLAG_CONFLICT_REDUNDANT };
-QList<QString> ModFlagIconDelegate::getIcons(const QModelIndex& index) const {
- QList<QString> result;
- QVariant modid = index.data(Qt::UserRole + 1);
- if (modid.isValid()) {
- ModInfo::Ptr info = ModInfo::getByIndex(modid.toInt());
- std::vector<ModInfo::EFlag> flags = info->getFlags();
+ModFlagIconDelegate::ModFlagIconDelegate(QObject *parent)
+ : IconDelegate(parent)
+{
+}
- { // insert conflict icon first to provide nicer alignment
- auto iter = std::find_first_of(flags.begin(), flags.end(), m_ConflictFlags, m_ConflictFlags + 4);
- if (iter != flags.end()) {
- result.append(getFlagIcon(*iter));
- flags.erase(iter);
- } else {
- result.append(QString());
- }
- }
+QList<QString> ModFlagIconDelegate::getIcons(const QModelIndex &index) const {
+ QList<QString> result;
+ QVariant modid = index.data(Qt::UserRole + 1);
+ if (modid.isValid()) {
+ ModInfo::Ptr info = ModInfo::getByIndex(modid.toInt());
+ std::vector<ModInfo::EFlag> flags = info->getFlags();
- for (auto iter = flags.begin(); iter != flags.end(); ++iter) {
- result.append(getFlagIcon(*iter));
- }
+ { // insert conflict icon first to provide nicer alignment
+ auto iter = std::find_first_of(flags.begin(), flags.end(),
+ m_ConflictFlags, m_ConflictFlags + 4);
+ if (iter != flags.end()) {
+ result.append(getFlagIcon(*iter));
+ flags.erase(iter);
+ } else {
+ result.append(QString());
+ }
}
- return result;
-}
-QString ModFlagIconDelegate::getFlagIcon(ModInfo::EFlag flag) const {
- switch (flag) {
- case ModInfo::FLAG_BACKUP:
- return ":/MO/gui/emblem_backup";
- case ModInfo::FLAG_INVALID:
- return ":/MO/gui/problem";
- case ModInfo::FLAG_NOTENDORSED:
- return ":/MO/gui/emblem_notendorsed";
- case ModInfo::FLAG_NOTES:
- return ":/MO/gui/emblem_notes";
- case ModInfo::FLAG_CONFLICT_OVERWRITE:
- return ":/MO/gui/emblem_conflict_overwrite";
- case ModInfo::FLAG_CONFLICT_OVERWRITTEN:
- return ":/MO/gui/emblem_conflict_overwritten";
- case ModInfo::FLAG_CONFLICT_MIXED:
- return ":/MO/gui/emblem_conflict_mixed";
- case ModInfo::FLAG_CONFLICT_REDUNDANT:
- return ":MO/gui/emblem_conflict_redundant";
- default:
- return QString();
+ for (auto iter = flags.begin(); iter != flags.end(); ++iter) {
+ result.append(getFlagIcon(*iter));
}
+ }
+ return result;
}
-size_t ModFlagIconDelegate::getNumIcons(const QModelIndex& index) const {
- unsigned int modIdx = index.data(Qt::UserRole + 1).toInt();
- if (modIdx < ModInfo::getNumMods()) {
- ModInfo::Ptr info = ModInfo::getByIndex(modIdx);
- std::vector<ModInfo::EFlag> flags = info->getFlags();
- size_t count = flags.size();
- if (std::find_first_of(flags.begin(), flags.end(), m_ConflictFlags, m_ConflictFlags + 4) == flags.end()) {
- ++count;
- }
- return count;
- } else {
- return 0;
- }
+QString ModFlagIconDelegate::getFlagIcon(ModInfo::EFlag flag) const
+{
+ switch (flag) {
+ case ModInfo::FLAG_BACKUP: return ":/MO/gui/emblem_backup";
+ case ModInfo::FLAG_INVALID: return ":/MO/gui/problem";
+ case ModInfo::FLAG_NOTENDORSED: return ":/MO/gui/emblem_notendorsed";
+ case ModInfo::FLAG_NOTES: return ":/MO/gui/emblem_notes";
+ case ModInfo::FLAG_CONFLICT_OVERWRITE: return ":/MO/gui/emblem_conflict_overwrite";
+ case ModInfo::FLAG_CONFLICT_OVERWRITTEN: return ":/MO/gui/emblem_conflict_overwritten";
+ case ModInfo::FLAG_CONFLICT_MIXED: return ":/MO/gui/emblem_conflict_mixed";
+ case ModInfo::FLAG_CONFLICT_REDUNDANT: return ":MO/gui/emblem_conflict_redundant";
+ default: return QString();
+ }
}
-QSize ModFlagIconDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& modelIndex) const {
- size_t count = getNumIcons(modelIndex);
- unsigned int index = modelIndex.data(Qt::UserRole + 1).toInt();
- QSize result;
- if (index < ModInfo::getNumMods()) {
- result = QSize(static_cast<int>(count) * 40, 20);
- } else {
- result = QSize(1, 20);
- }
- if (option.rect.width() > 0) {
- result.setWidth(std::min(option.rect.width(), result.width()));
+size_t ModFlagIconDelegate::getNumIcons(const QModelIndex &index) const
+{
+ unsigned int modIdx = index.data(Qt::UserRole + 1).toInt();
+ if (modIdx < ModInfo::getNumMods()) {
+ ModInfo::Ptr info = ModInfo::getByIndex(modIdx);
+ std::vector<ModInfo::EFlag> flags = info->getFlags();
+ size_t count = flags.size();
+ if (std::find_first_of(flags.begin(), flags.end(), m_ConflictFlags, m_ConflictFlags + 4) == flags.end()) {
+ ++count;
}
- return result;
+ return count;
+ } else {
+ return 0;
+ }
}
+
+
+QSize ModFlagIconDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &modelIndex) const
+{
+ size_t count = getNumIcons(modelIndex);
+ unsigned int index = modelIndex.data(Qt::UserRole + 1).toInt();
+ QSize result;
+ if (index < ModInfo::getNumMods()) {
+ result = QSize(static_cast<int>(count) * 40, 20);
+ } else {
+ result = QSize(1, 20);
+ }
+ if (option.rect.width() > 0) {
+ result.setWidth(std::min(option.rect.width(), result.width()));
+ }
+ return result;
+}
+
diff --git a/src/modflagicondelegate.h b/src/modflagicondelegate.h
index 5ee43a90..b31a250b 100644
--- a/src/modflagicondelegate.h
+++ b/src/modflagicondelegate.h
@@ -3,19 +3,18 @@
#include "icondelegate.h"
-class ModFlagIconDelegate : public IconDelegate {
+class ModFlagIconDelegate : public IconDelegate
+{
public:
- explicit ModFlagIconDelegate(QObject* parent = 0);
- virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
-
+ explicit ModFlagIconDelegate(QObject *parent = 0);
+ virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
private:
- virtual QList<QString> getIcons(const QModelIndex& index) const;
- virtual size_t getNumIcons(const QModelIndex& index) const;
-
- QString getFlagIcon(ModInfo::EFlag flag) const;
+ virtual QList<QString> getIcons(const QModelIndex &index) const;
+ virtual size_t getNumIcons(const QModelIndex &index) const;
+ QString getFlagIcon(ModInfo::EFlag flag) const;
private:
- static ModInfo::EFlag m_ConflictFlags[4];
+ static ModInfo::EFlag m_ConflictFlags[4];
};
#endif // MODFLAGICONDELEGATE_H
diff --git a/src/modinfo.cpp b/src/modinfo.cpp
index 0b9d65f8..c14eedb7 100644
--- a/src/modinfo.cpp
+++ b/src/modinfo.cpp
@@ -20,22 +20,22 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "modinfo.h"
#include "modinfobackup.h"
+#include "modinforegular.h"
#include "modinfoforeign.h"
#include "modinfooverwrite.h"
-#include "modinforegular.h"
-#include "categories.h"
-#include "filenamestring.h"
#include "installationtester.h"
+#include "categories.h"
#include "modinfodialog.h"
#include "overwriteinfodialog.h"
+#include "filenamestring.h"
#include "versioninfo.h"
-#include <appconfig.h>
#include <iplugingame.h>
+#include <versioninfo.h>
+#include <appconfig.h>
#include <scriptextender.h>
#include <unmanagedmods.h>
-#include <versioninfo.h>
#include <QApplication>
#include <QDirIterator>
@@ -45,317 +45,353 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
using namespace MOBase;
using namespace MOShared;
+
std::vector<ModInfo::Ptr> ModInfo::s_Collection;
std::map<QString, unsigned int> ModInfo::s_ModsByName;
-std::map<int, std::vector<unsigned int>> ModInfo::s_ModsByModID;
+std::map<int, std::vector<unsigned int> > ModInfo::s_ModsByModID;
int ModInfo::s_NextID;
QMutex ModInfo::s_Mutex(QMutex::Recursive);
QString ModInfo::s_HiddenExt(".mohidden");
-static bool ByName(const ModInfo::Ptr& LHS, const ModInfo::Ptr& RHS) {
- return QString::compare(LHS->name(), RHS->name(), Qt::CaseInsensitive) < 0;
+
+static bool ByName(const ModInfo::Ptr &LHS, const ModInfo::Ptr &RHS)
+{
+ return QString::compare(LHS->name(), RHS->name(), Qt::CaseInsensitive) < 0;
}
-ModInfo::Ptr ModInfo::createFrom(const QDir& dir, DirectoryEntry** directoryStructure) {
- QMutexLocker locker(&s_Mutex);
- // int id = s_NextID++;
- static QRegExp backupExp(".*backup[0-9]*");
- ModInfo::Ptr result;
- if (backupExp.exactMatch(dir.dirName())) {
- result = ModInfo::Ptr(new ModInfoBackup(dir, directoryStructure));
- } else {
- result = ModInfo::Ptr(new ModInfoRegular(dir, directoryStructure));
- }
- s_Collection.push_back(result);
- return result;
+
+ModInfo::Ptr ModInfo::createFrom(const QDir &dir, DirectoryEntry **directoryStructure)
+{
+ QMutexLocker locker(&s_Mutex);
+// int id = s_NextID++;
+ static QRegExp backupExp(".*backup[0-9]*");
+ ModInfo::Ptr result;
+ if (backupExp.exactMatch(dir.dirName())) {
+ result = ModInfo::Ptr(new ModInfoBackup(dir, directoryStructure));
+ } else {
+ result = ModInfo::Ptr(new ModInfoRegular(dir, directoryStructure));
+ }
+ s_Collection.push_back(result);
+ return result;
}
-ModInfo::Ptr ModInfo::createFromPlugin(const QString& modName, const QString& espName, const QStringList& bsaNames,
- ModInfo::EModType modType, DirectoryEntry** directoryStructure) {
- QMutexLocker locker(&s_Mutex);
- ModInfo::Ptr result = ModInfo::Ptr(new ModInfoForeign(modName, espName, bsaNames, modType, directoryStructure));
- s_Collection.push_back(result);
- return result;
+ModInfo::Ptr ModInfo::createFromPlugin(const QString &modName,
+ const QString &espName,
+ const QStringList &bsaNames,
+ ModInfo::EModType modType,
+ DirectoryEntry **directoryStructure) {
+ QMutexLocker locker(&s_Mutex);
+ ModInfo::Ptr result = ModInfo::Ptr(
+ new ModInfoForeign(modName, espName, bsaNames, modType, directoryStructure));
+ s_Collection.push_back(result);
+ return result;
}
-QString ModInfo::getContentTypeName(int contentType) {
- switch (contentType) {
- case CONTENT_PLUGIN:
- return tr("Plugins");
- case CONTENT_TEXTURE:
- return tr("Textures");
- case CONTENT_MESH:
- return tr("Meshes");
- case CONTENT_BSA:
- return tr("Bethesda Archive");
- case CONTENT_INTERFACE:
- return tr("UI Changes");
- case CONTENT_SOUND:
- return tr("Sound Effects");
- case CONTENT_SCRIPT:
- return tr("Scripts");
- case CONTENT_SKSE:
- return tr("SKSE Plugins");
- case CONTENT_SKYPROC:
- return tr("SkyProc Tools");
- case CONTENT_MCM:
- return tr("MCM Data");
- default:
- throw MyException(tr("invalid content type %1").arg(contentType));
- }
+QString ModInfo::getContentTypeName(int contentType)
+{
+ switch (contentType) {
+ case CONTENT_PLUGIN: return tr("Plugins");
+ case CONTENT_TEXTURE: return tr("Textures");
+ case CONTENT_MESH: return tr("Meshes");
+ case CONTENT_BSA: return tr("Bethesda Archive");
+ case CONTENT_INTERFACE: return tr("UI Changes");
+ case CONTENT_SOUND: return tr("Sound Effects");
+ case CONTENT_SCRIPT: return tr("Scripts");
+ case CONTENT_SKSE: return tr("SKSE Plugins");
+ case CONTENT_SKYPROC: return tr("SkyProc Tools");
+ case CONTENT_MCM: return tr("MCM Data");
+ default: throw MyException(tr("invalid content type %1").arg(contentType));
+ }
}
-void ModInfo::createFromOverwrite() {
- QMutexLocker locker(&s_Mutex);
+void ModInfo::createFromOverwrite()
+{
+ QMutexLocker locker(&s_Mutex);
- s_Collection.push_back(ModInfo::Ptr(new ModInfoOverwrite));
+ s_Collection.push_back(ModInfo::Ptr(new ModInfoOverwrite));
}
-unsigned int ModInfo::getNumMods() {
- QMutexLocker locker(&s_Mutex);
- return static_cast<unsigned int>(s_Collection.size());
+unsigned int ModInfo::getNumMods()
+{
+ QMutexLocker locker(&s_Mutex);
+ return static_cast<unsigned int>(s_Collection.size());
}
-ModInfo::Ptr ModInfo::getByIndex(unsigned int index) {
- QMutexLocker locker(&s_Mutex);
- if (index >= s_Collection.size() && index != ULONG_MAX) {
- throw MyException(tr("invalid mod index %1").arg(index));
- }
- if (index == ULONG_MAX)
- return s_Collection[ModInfo::getIndex("Overwrite")];
- return s_Collection[index];
+ModInfo::Ptr ModInfo::getByIndex(unsigned int index)
+{
+ QMutexLocker locker(&s_Mutex);
+
+ if (index >= s_Collection.size() && index != ULONG_MAX) {
+ throw MyException(tr("invalid mod index %1").arg(index));
+ }
+ if (index == ULONG_MAX) return s_Collection[ModInfo::getIndex("Overwrite")];
+ return s_Collection[index];
}
-std::vector<ModInfo::Ptr> ModInfo::getByModID(int modID) {
- QMutexLocker locker(&s_Mutex);
- auto iter = s_ModsByModID.find(modID);
- if (iter == s_ModsByModID.end()) {
- return std::vector<ModInfo::Ptr>();
- }
+std::vector<ModInfo::Ptr> ModInfo::getByModID(int modID)
+{
+ QMutexLocker locker(&s_Mutex);
- std::vector<ModInfo::Ptr> result;
- for (auto idxIter = iter->second.begin(); idxIter != iter->second.end(); ++idxIter) {
- result.push_back(getByIndex(*idxIter));
- }
+ auto iter = s_ModsByModID.find(modID);
+ if (iter == s_ModsByModID.end()) {
+ return std::vector<ModInfo::Ptr>();
+ }
+
+ std::vector<ModInfo::Ptr> result;
+ for (auto idxIter = iter->second.begin(); idxIter != iter->second.end(); ++idxIter) {
+ result.push_back(getByIndex(*idxIter));
+ }
- return result;
+ return result;
}
-bool ModInfo::removeMod(unsigned int index) {
- QMutexLocker locker(&s_Mutex);
- if (index >= s_Collection.size()) {
- throw MyException(tr("remove: invalid mod index %1").arg(index));
- }
- // update the indices first
- ModInfo::Ptr modInfo = s_Collection[index];
- s_ModsByName.erase(s_ModsByName.find(modInfo->name()));
+bool ModInfo::removeMod(unsigned int index)
+{
+ QMutexLocker locker(&s_Mutex);
- auto iter = s_ModsByModID.find(modInfo->getNexusID());
- if (iter != s_ModsByModID.end()) {
- std::vector<unsigned int> indices = iter->second;
- indices.erase(std::remove(indices.begin(), indices.end(), index), indices.end());
- s_ModsByModID[modInfo->getNexusID()] = indices;
- }
+ if (index >= s_Collection.size()) {
+ throw MyException(tr("remove: invalid mod index %1").arg(index));
+ }
+ // update the indices first
+ ModInfo::Ptr modInfo = s_Collection[index];
+ s_ModsByName.erase(s_ModsByName.find(modInfo->name()));
+
+ auto iter = s_ModsByModID.find(modInfo->getNexusID());
+ if (iter != s_ModsByModID.end()) {
+ std::vector<unsigned int> indices = iter->second;
+ indices.erase(std::remove(indices.begin(), indices.end(), index), indices.end());
+ s_ModsByModID[modInfo->getNexusID()] = indices;
+ }
- // physically remove the mod directory
- // TODO the return value is ignored because the indices were already removed here, so stopping
- // would cause data inconsistencies. Instead we go through with the removal but the mod will show up
- // again if the user refreshes
- modInfo->remove();
+ // physically remove the mod directory
+ //TODO the return value is ignored because the indices were already removed here, so stopping
+ // would cause data inconsistencies. Instead we go through with the removal but the mod will show up
+ // again if the user refreshes
+ modInfo->remove();
- // finally, remove the mod from the collection
- s_Collection.erase(s_Collection.begin() + index);
+ // finally, remove the mod from the collection
+ s_Collection.erase(s_Collection.begin() + index);
- // and update the indices
- updateIndices();
- return true;
+ // and update the indices
+ updateIndices();
+ return true;
}
-unsigned int ModInfo::getIndex(const QString& name) {
- QMutexLocker locker(&s_Mutex);
- std::map<QString, unsigned int>::iterator iter = s_ModsByName.find(name);
- if (iter == s_ModsByName.end()) {
- return UINT_MAX;
- }
+unsigned int ModInfo::getIndex(const QString &name)
+{
+ QMutexLocker locker(&s_Mutex);
+
+ std::map<QString, unsigned int>::iterator iter = s_ModsByName.find(name);
+ if (iter == s_ModsByName.end()) {
+ return UINT_MAX;
+ }
- return iter->second;
+ return iter->second;
}
-unsigned int ModInfo::findMod(const boost::function<bool(ModInfo::Ptr)>& filter) {
- for (unsigned int i = 0U; i < s_Collection.size(); ++i) {
- if (filter(s_Collection[i])) {
- return i;
- }
+unsigned int ModInfo::findMod(const boost::function<bool (ModInfo::Ptr)> &filter)
+{
+ for (unsigned int i = 0U; i < s_Collection.size(); ++i) {
+ if (filter(s_Collection[i])) {
+ return i;
}
- return UINT_MAX;
+ }
+ return UINT_MAX;
}
-void ModInfo::updateFromDisc(const QString& modDirectory, DirectoryEntry** directoryStructure, bool displayForeign,
- MOBase::IPluginGame const* game) {
- QMutexLocker lock(&s_Mutex);
- s_Collection.clear();
- s_NextID = 0;
- { // list all directories in the mod directory and make a mod out of each
- QDir mods(QDir::fromNativeSeparators(modDirectory));
- mods.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
- QDirIterator modIter(mods);
- while (modIter.hasNext()) {
- createFrom(QDir(modIter.next()), directoryStructure);
- }
+void ModInfo::updateFromDisc(const QString &modDirectory,
+ DirectoryEntry **directoryStructure,
+ bool displayForeign,
+ MOBase::IPluginGame const *game)
+{
+ QMutexLocker lock(&s_Mutex);
+ s_Collection.clear();
+ s_NextID = 0;
+
+ { // list all directories in the mod directory and make a mod out of each
+ QDir mods(QDir::fromNativeSeparators(modDirectory));
+ mods.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
+ QDirIterator modIter(mods);
+ while (modIter.hasNext()) {
+ createFrom(QDir(modIter.next()), directoryStructure);
}
+ }
- UnmanagedMods* unmanaged = game->feature<UnmanagedMods>();
- if (unmanaged != nullptr) {
- for (const QString& modName : unmanaged->mods(!displayForeign)) {
- ModInfo::EModType modType =
- game->DLCPlugins().contains(unmanaged->referenceFile(modName).fileName(), Qt::CaseInsensitive)
- ? ModInfo::EModType::MOD_DLC
- : (game->CCPlugins().contains(unmanaged->referenceFile(modName).fileName(), Qt::CaseInsensitive)
- ? ModInfo::EModType::MOD_CC
- : ModInfo::EModType::MOD_DEFAULT);
+ UnmanagedMods *unmanaged = game->feature<UnmanagedMods>();
+ if (unmanaged != nullptr) {
+ for (const QString &modName : unmanaged->mods(!displayForeign)) {
+ ModInfo::EModType modType = game->DLCPlugins().contains(unmanaged->referenceFile(modName).fileName(), Qt::CaseInsensitive) ? ModInfo::EModType::MOD_DLC :
+ (game->CCPlugins().contains(unmanaged->referenceFile(modName).fileName(), Qt::CaseInsensitive) ? ModInfo::EModType::MOD_CC : ModInfo::EModType::MOD_DEFAULT);
- createFromPlugin(unmanaged->displayName(modName), unmanaged->referenceFile(modName).absoluteFilePath(),
- unmanaged->secondaryFiles(modName), modType, directoryStructure);
- }
+ createFromPlugin(unmanaged->displayName(modName),
+ unmanaged->referenceFile(modName).absoluteFilePath(),
+ unmanaged->secondaryFiles(modName),
+ modType,
+ directoryStructure);
}
+ }
- createFromOverwrite();
+ createFromOverwrite();
- std::sort(s_Collection.begin(), s_Collection.end(), ByName);
+ std::sort(s_Collection.begin(), s_Collection.end(), ByName);
- updateIndices();
+ updateIndices();
}
-void ModInfo::updateIndices() {
- s_ModsByName.clear();
- s_ModsByModID.clear();
- for (unsigned int i = 0; i < s_Collection.size(); ++i) {
- QString modName = s_Collection[i]->internalName();
- int modID = s_Collection[i]->getNexusID();
- s_ModsByName[modName] = i;
- s_ModsByModID[modID].push_back(i);
- }
+void ModInfo::updateIndices()
+{
+ s_ModsByName.clear();
+ s_ModsByModID.clear();
+
+ for (unsigned int i = 0; i < s_Collection.size(); ++i) {
+ QString modName = s_Collection[i]->internalName();
+ int modID = s_Collection[i]->getNexusID();
+ s_ModsByName[modName] = i;
+ s_ModsByModID[modID].push_back(i);
+ }
}
-ModInfo::ModInfo() : m_Valid(false), m_PrimaryCategory(-1) {}
-void ModInfo::checkChunkForUpdate(const std::vector<int>& modIDs, QObject* receiver) {
- if (modIDs.size() != 0) {
- NexusInterface::instance()->requestUpdates(modIDs, receiver, QVariant(), QString());
- }
+ModInfo::ModInfo()
+ : m_Valid(false), m_PrimaryCategory(-1)
+{
+}
+
+
+void ModInfo::checkChunkForUpdate(const std::vector<int> &modIDs, QObject *receiver)
+{
+ if (modIDs.size() != 0) {
+ NexusInterface::instance()->requestUpdates(modIDs, receiver, QVariant(), QString());
+ }
}
-int ModInfo::checkAllForUpdate(QObject* receiver) {
- // technically this should be 255 but those requests can take nexus fairly long, produce
- // large output and may have been the cause of issue #1166
- static const int chunkSize = 64;
- int result = 0;
- std::vector<int> modIDs;
+int ModInfo::checkAllForUpdate(QObject *receiver)
+{
+ // technically this should be 255 but those requests can take nexus fairly long, produce
+ // large output and may have been the cause of issue #1166
+ static const int chunkSize = 64;
+
+ int result = 0;
+ std::vector<int> modIDs;
- // I ought to store this, it's used elsewhere
- IPluginGame const* game = qApp->property("managed_game").value<IPluginGame*>();
+ //I ought to store this, it's used elsewhere
+ IPluginGame const *game = qApp->property("managed_game").value<IPluginGame *>();
- modIDs.push_back(game->nexusModOrganizerID());
+ modIDs.push_back(game->nexusModOrganizerID());
- for (const ModInfo::Ptr& mod : s_Collection) {
- if (mod->canBeUpdated()) {
- modIDs.push_back(mod->getNexusID());
- if (modIDs.size() >= chunkSize) {
- checkChunkForUpdate(modIDs, receiver);
- modIDs.clear();
- }
- }
+ for (const ModInfo::Ptr &mod : s_Collection) {
+ if (mod->canBeUpdated()) {
+ modIDs.push_back(mod->getNexusID());
+ if (modIDs.size() >= chunkSize) {
+ checkChunkForUpdate(modIDs, receiver);
+ modIDs.clear();
+ }
}
+ }
- checkChunkForUpdate(modIDs, receiver);
+ checkChunkForUpdate(modIDs, receiver);
- return result;
+ return result;
}
-void ModInfo::setVersion(const VersionInfo& version) { m_Version = version; }
+void ModInfo::setVersion(const VersionInfo &version)
+{
+ m_Version = version;
+}
-void ModInfo::setPluginSelected(const bool& isSelected) { m_PluginSelected = isSelected; }
+void ModInfo::setPluginSelected(const bool &isSelected)
+{
+ m_PluginSelected = isSelected;
+}
-void ModInfo::addCategory(const QString& categoryName) {
- int id = CategoryFactory::instance().getCategoryID(categoryName);
- if (id == -1) {
- id = CategoryFactory::instance().addCategory(categoryName, std::vector<int>(), 0);
- }
- setCategory(id, true);
+void ModInfo::addCategory(const QString &categoryName)
+{
+ int id = CategoryFactory::instance().getCategoryID(categoryName);
+ if (id == -1) {
+ id = CategoryFactory::instance().addCategory(categoryName, std::vector<int>(), 0);
+ }
+ setCategory(id, true);
}
-bool ModInfo::removeCategory(const QString& categoryName) {
- int id = CategoryFactory::instance().getCategoryID(categoryName);
- if (id == -1) {
- return false;
- }
- if (!categorySet(id)) {
- return false;
- }
- setCategory(id, false);
- return true;
+bool ModInfo::removeCategory(const QString &categoryName)
+{
+ int id = CategoryFactory::instance().getCategoryID(categoryName);
+ if (id == -1) {
+ return false;
+ }
+ if (!categorySet(id)) {
+ return false;
+ }
+ setCategory(id, false);
+ return true;
}
-QStringList ModInfo::categories() {
- QStringList result;
+QStringList ModInfo::categories()
+{
+ QStringList result;
- CategoryFactory& catFac = CategoryFactory::instance();
- for (int id : m_Categories) {
- result.append(catFac.getCategoryName(catFac.getCategoryIndex(id)));
- }
+ CategoryFactory &catFac = CategoryFactory::instance();
+ for (int id : m_Categories) {
+ result.append(catFac.getCategoryName(catFac.getCategoryIndex(id)));
+ }
- return result;
+ return result;
}
-bool ModInfo::hasFlag(ModInfo::EFlag flag) const {
- std::vector<EFlag> flags = getFlags();
- return std::find(flags.begin(), flags.end(), flag) != flags.end();
+bool ModInfo::hasFlag(ModInfo::EFlag flag) const
+{
+ std::vector<EFlag> flags = getFlags();
+ return std::find(flags.begin(), flags.end(), flag) != flags.end();
}
-bool ModInfo::hasContent(ModInfo::EContent content) const {
- std::vector<EContent> contents = getContents();
- return std::find(contents.begin(), contents.end(), content) != contents.end();
+bool ModInfo::hasContent(ModInfo::EContent content) const
+{
+ std::vector<EContent> contents = getContents();
+ return std::find(contents.begin(), contents.end(), content) != contents.end();
}
-bool ModInfo::categorySet(int categoryID) const {
- for (std::set<int>::const_iterator iter = m_Categories.begin(); iter != m_Categories.end(); ++iter) {
- if ((*iter == categoryID) || (CategoryFactory::instance().isDecendantOf(*iter, categoryID))) {
- return true;
- }
+bool ModInfo::categorySet(int categoryID) const
+{
+ for (std::set<int>::const_iterator iter = m_Categories.begin(); iter != m_Categories.end(); ++iter) {
+ if ((*iter == categoryID) ||
+ (CategoryFactory::instance().isDecendantOf(*iter, categoryID))) {
+ return true;
}
+ }
- return false;
+ return false;
}
-void ModInfo::testValid() {
- m_Valid = false;
- QDirIterator dirIter(absolutePath());
- while (dirIter.hasNext()) {
- dirIter.next();
- if (dirIter.fileInfo().isDir()) {
- if (InstallationTester::isTopLevelDirectory(dirIter.fileName())) {
- m_Valid = true;
- break;
- }
- } else {
- if (InstallationTester::isTopLevelSuffix(dirIter.fileName())) {
- m_Valid = true;
- break;
- }
- }
+void ModInfo::testValid()
+{
+ m_Valid = false;
+ QDirIterator dirIter(absolutePath());
+ while (dirIter.hasNext()) {
+ dirIter.next();
+ if (dirIter.fileInfo().isDir()) {
+ if (InstallationTester::isTopLevelDirectory(dirIter.fileName())) {
+ m_Valid = true;
+ break;
+ }
+ } else {
+ if (InstallationTester::isTopLevelSuffix(dirIter.fileName())) {
+ m_Valid = true;
+ break;
+ }
}
+ }
- // NOTE: in Qt 4.7 it seems that QDirIterator leaves a file handle open if it is not iterated to the
- // end
- while (dirIter.hasNext()) {
- dirIter.next();
- }
+ // NOTE: in Qt 4.7 it seems that QDirIterator leaves a file handle open if it is not iterated to the
+ // end
+ while (dirIter.hasNext()) {
+ dirIter.next();
+ }
}
diff --git a/src/modinfo.h b/src/modinfo.h
index 2c5cdf9a..0bdf6e43 100644
--- a/src/modinfo.h
+++ b/src/modinfo.h
@@ -36,584 +36,595 @@ class QDir;
#include <set>
#include <vector>
-namespace MOBase {
-class IPluginGame;
-}
-namespace MOShared {
-class DirectoryEntry;
-}
+namespace MOBase { class IPluginGame; }
+namespace MOShared { class DirectoryEntry; }
/**
* @brief Represents meta information about a single mod.
- *
+ *
* Represents meta information about a single mod. The class interface is used
* to manage the mod collection
*
**/
-class ModInfo : public QObject, public MOBase::IModInterface {
+class ModInfo : public QObject, public MOBase::IModInterface
+{
- Q_OBJECT
+ Q_OBJECT
public:
- typedef QSharedPointer<ModInfo> Ptr;
- static QString s_HiddenExt;
+ typedef QSharedPointer<ModInfo> Ptr;
+
+ static QString s_HiddenExt;
+
+ enum EFlag {
+ FLAG_INVALID,
+ FLAG_BACKUP,
+ FLAG_OVERWRITE,
+ FLAG_FOREIGN,
+ FLAG_NOTENDORSED,
+ FLAG_NOTES,
+ FLAG_CONFLICT_OVERWRITE,
+ FLAG_CONFLICT_OVERWRITTEN,
+ FLAG_CONFLICT_MIXED,
+ FLAG_CONFLICT_REDUNDANT,
+ FLAG_PLUGIN_SELECTED
+ };
- enum EFlag {
- FLAG_INVALID,
- FLAG_BACKUP,
- FLAG_OVERWRITE,
- FLAG_FOREIGN,
- FLAG_NOTENDORSED,
- FLAG_NOTES,
- FLAG_CONFLICT_OVERWRITE,
- FLAG_CONFLICT_OVERWRITTEN,
- FLAG_CONFLICT_MIXED,
- FLAG_CONFLICT_REDUNDANT,
- FLAG_PLUGIN_SELECTED
- };
+ enum EContent {
+ CONTENT_PLUGIN,
+ CONTENT_TEXTURE,
+ CONTENT_MESH,
+ CONTENT_BSA,
+ CONTENT_INTERFACE,
+ CONTENT_SOUND,
+ CONTENT_SCRIPT,
+ CONTENT_SKSE,
+ CONTENT_SKYPROC,
+ CONTENT_MCM
+ };
- enum EContent {
- CONTENT_PLUGIN,
- CONTENT_TEXTURE,
- CONTENT_MESH,
- CONTENT_BSA,
- CONTENT_INTERFACE,
- CONTENT_SOUND,
- CONTENT_SCRIPT,
- CONTENT_SKSE,
- CONTENT_SKYPROC,
- CONTENT_MCM
- };
+ static const int NUM_CONTENT_TYPES = CONTENT_SKYPROC + 1;
- static const int NUM_CONTENT_TYPES = CONTENT_SKYPROC + 1;
+ enum EHighlight {
+ HIGHLIGHT_NONE = 0,
+ HIGHLIGHT_INVALID = 1,
+ HIGHLIGHT_CENTER = 2,
+ HIGHLIGHT_IMPORTANT = 4,
+ HIGHLIGHT_PLUGIN = 8
+ };
- enum EHighlight {
- HIGHLIGHT_NONE = 0,
- HIGHLIGHT_INVALID = 1,
- HIGHLIGHT_CENTER = 2,
- HIGHLIGHT_IMPORTANT = 4,
- HIGHLIGHT_PLUGIN = 8
- };
+ enum EEndorsedState {
+ ENDORSED_FALSE,
+ ENDORSED_TRUE,
+ ENDORSED_UNKNOWN,
+ ENDORSED_NEVER
+ };
- enum EEndorsedState { ENDORSED_FALSE, ENDORSED_TRUE, ENDORSED_UNKNOWN, ENDORSED_NEVER };
+ enum EModType {
+ MOD_DEFAULT,
+ MOD_DLC,
+ MOD_CC
+ };
- enum EModType { MOD_DEFAULT, MOD_DLC, MOD_CC };
public:
- /**
- * @brief read the mod directory and Mod ModInfo objects for all subdirectories
- **/
- static void updateFromDisc(const QString& modDirectory, MOShared::DirectoryEntry** directoryStructure,
- bool displayForeign, MOBase::IPluginGame const* game);
- static void clear() {
- s_Collection.clear();
- s_ModsByName.clear();
- s_ModsByModID.clear();
- }
+ /**
+ * @brief read the mod directory and Mod ModInfo objects for all subdirectories
+ **/
+ static void updateFromDisc(const QString &modDirectory,
+ MOShared::DirectoryEntry **directoryStructure,
+ bool displayForeign,
+ MOBase::IPluginGame const *game);
- /**
- * @brief retrieve the number of mods
- *
- * @return number of mods
- **/
- static unsigned int getNumMods();
+ static void clear() { s_Collection.clear(); s_ModsByName.clear(); s_ModsByModID.clear(); }
- /**
- * @brief retrieve a ModInfo object based on its index
- *
- * @param index the index to look up. the maximum is getNumMods() - 1
- * @return a reference counting pointer to the mod info.
- * @note since the pointer is reference counting, the pointer remains valid even if the collection is refreshed in a
- *different thread
- **/
- static ModInfo::Ptr getByIndex(unsigned int index);
+ /**
+ * @brief retrieve the number of mods
+ *
+ * @return number of mods
+ **/
+ static unsigned int getNumMods();
- /**
- * @brief retrieve a ModInfo object based on its nexus mod id
- *
- * @param modID the nexus mod id to look up
- * @return a reference counting pointer to the mod info
- * @todo in its current form, this function is broken! There may be multiple mods with the same nexus id,
- * this function will return only one of them
- **/
- static std::vector<ModInfo::Ptr> getByModID(int modID);
+ /**
+ * @brief retrieve a ModInfo object based on its index
+ *
+ * @param index the index to look up. the maximum is getNumMods() - 1
+ * @return a reference counting pointer to the mod info.
+ * @note since the pointer is reference counting, the pointer remains valid even if the collection is refreshed in a different thread
+ **/
+ static ModInfo::Ptr getByIndex(unsigned int index);
- /**
- * @brief remove a mod by index
- *
- * this physically deletes the specified mod from the disc and updates the ModInfo collection
- * but not other structures that reference mods
- * @param index index of the mod to delete
- * @return true if removal was successful, fals otherwise
- **/
- static bool removeMod(unsigned int index);
+ /**
+ * @brief retrieve a ModInfo object based on its nexus mod id
+ *
+ * @param modID the nexus mod id to look up
+ * @return a reference counting pointer to the mod info
+ * @todo in its current form, this function is broken! There may be multiple mods with the same nexus id,
+ * this function will return only one of them
+ **/
+ static std::vector<ModInfo::Ptr> getByModID(int modID);
- /**
- * @brief retrieve the mod index by the mod name
- *
- * @param name name of the mod to look up
- * @return the index of the mod. If the mod doesn't exist, UINT_MAX is returned
- **/
- static unsigned int getIndex(const QString& name);
+ /**
+ * @brief remove a mod by index
+ *
+ * this physically deletes the specified mod from the disc and updates the ModInfo collection
+ * but not other structures that reference mods
+ * @param index index of the mod to delete
+ * @return true if removal was successful, fals otherwise
+ **/
+ static bool removeMod(unsigned int index);
- /**
- * @brief find the first mod that fulfills the filter function (after no particular order)
- * @param filter a function to filter by. should return true for a match
- * @return index of the matching mod or UINT_MAX if there wasn't a match
- */
- static unsigned int findMod(const boost::function<bool(ModInfo::Ptr)>& filter);
+ /**
+ * @brief retrieve the mod index by the mod name
+ *
+ * @param name name of the mod to look up
+ * @return the index of the mod. If the mod doesn't exist, UINT_MAX is returned
+ **/
+ static unsigned int getIndex(const QString &name);
- /**
- * @brief check a bunch of mods for updates
- * @param modIDs list of mods (Nexus Mod IDs) to check for updates
- * @return
- */
- static void checkChunkForUpdate(const std::vector<int>& modIDs, QObject* receiver);
+ /**
+ * @brief find the first mod that fulfills the filter function (after no particular order)
+ * @param filter a function to filter by. should return true for a match
+ * @return index of the matching mod or UINT_MAX if there wasn't a match
+ */
+ static unsigned int findMod(const boost::function<bool (ModInfo::Ptr)> &filter);
- /**
- * @brief query nexus information for every mod and update the "newest version" information
- **/
- static int checkAllForUpdate(QObject* receiver);
+ /**
+ * @brief check a bunch of mods for updates
+ * @param modIDs list of mods (Nexus Mod IDs) to check for updates
+ * @return
+ */
+ static void checkChunkForUpdate(const std::vector<int> &modIDs, QObject *receiver);
- /**
- * @brief create a new mod from the specified directory and add it to the collection
- * @param dir directory to create from
- * @return pointer to the info-structure of the newly created/added mod
- */
- static ModInfo::Ptr createFrom(const QDir& dir, MOShared::DirectoryEntry** directoryStructure);
+ /**
+ * @brief query nexus information for every mod and update the "newest version" information
+ **/
+ static int checkAllForUpdate(QObject *receiver);
- /**
- * @brief create a new "foreign-managed" mod from a tuple of plugin and archives
- * @param espName name of the plugin
- * @param bsaNames names of archives
- * @return a new mod
- */
- static ModInfo::Ptr createFromPlugin(const QString& modName, const QString& espName, const QStringList& bsaNames,
- ModInfo::EModType modType, MOShared::DirectoryEntry** directoryStructure);
+ /**
+ * @brief create a new mod from the specified directory and add it to the collection
+ * @param dir directory to create from
+ * @return pointer to the info-structure of the newly created/added mod
+ */
+ static ModInfo::Ptr createFrom(const QDir &dir, MOShared::DirectoryEntry **directoryStructure);
- /**
- * @brief retieve a name for one of the CONTENT_ enums
- * @param contentType the content value
- * @return a display string
- */
- static QString getContentTypeName(int contentType);
+ /**
+ * @brief create a new "foreign-managed" mod from a tuple of plugin and archives
+ * @param espName name of the plugin
+ * @param bsaNames names of archives
+ * @return a new mod
+ */
+ static ModInfo::Ptr createFromPlugin(const QString &modName, const QString &espName, const QStringList &bsaNames, ModInfo::EModType modType, MOShared::DirectoryEntry **directoryStructure);
- virtual bool isRegular() const { return false; }
+ /**
+ * @brief retieve a name for one of the CONTENT_ enums
+ * @param contentType the content value
+ * @return a display string
+ */
+ static QString getContentTypeName(int contentType);
- virtual bool isEmpty() const { return false; }
+ virtual bool isRegular() const { return false; }
- /**
- * @brief test if there is a newer version of the mod
- *
- * test if there is a newer version of the mod. This does NOT cause
- * information to be retrieved from the nexus, it will only test version information already
- * available locally. Use checkAllForUpdate() to update this version information
- *
- * @return true if there is a newer version
- **/
- virtual bool updateAvailable() const = 0;
+ virtual bool isEmpty() const { return false; }
- /**
- * @return true if the update currently available is ignored
- */
- virtual bool updateIgnored() const = 0;
+ /**
+ * @brief test if there is a newer version of the mod
+ *
+ * test if there is a newer version of the mod. This does NOT cause
+ * information to be retrieved from the nexus, it will only test version information already
+ * available locally. Use checkAllForUpdate() to update this version information
+ *
+ * @return true if there is a newer version
+ **/
+ virtual bool updateAvailable() const = 0;
- /**
- * @brief test if the "newest" version of the mod is older than the installed version
- *
- * test if there is a newer version of the mod. This does NOT cause
- * information to be retrieved from the nexus, it will only test version information already
- * available locally. Use checkAllForUpdate() to update this version information
- *
- * @return true if the newest version is older than the installed one
- **/
- virtual bool downgradeAvailable() const = 0;
+ /**
+ * @return true if the update currently available is ignored
+ */
+ virtual bool updateIgnored() const = 0;
- /**
- * @brief request an update of nexus description for this mod.
- *
- * This requests mod information from the nexus. This is an asynchronous request,
- * so there is no immediate effect of this call.
- * Right now, Mod Organizer interprets the "newest version" and "description" from the
- * response, though the description is only stored in memory
- *
- **/
- virtual bool updateNXMInfo() = 0;
+ /**
+ * @brief test if the "newest" version of the mod is older than the installed version
+ *
+ * test if there is a newer version of the mod. This does NOT cause
+ * information to be retrieved from the nexus, it will only test version information already
+ * available locally. Use checkAllForUpdate() to update this version information
+ *
+ * @return true if the newest version is older than the installed one
+ **/
+ virtual bool downgradeAvailable() const = 0;
- /**
- * @brief assign or unassign the specified category
- *
- * Every mod can have an arbitrary number of categories assigned to it
- *
- * @param categoryID id of the category to set
- * @param active determines wheter the category is assigned or unassigned
- * @note this function does not test whether categoryID actually identifies a valid category
- **/
- virtual void setCategory(int categoryID, bool active) = 0;
+ /**
+ * @brief request an update of nexus description for this mod.
+ *
+ * This requests mod information from the nexus. This is an asynchronous request,
+ * so there is no immediate effect of this call.
+ * Right now, Mod Organizer interprets the "newest version" and "description" from the
+ * response, though the description is only stored in memory
+ *
+ **/
+ virtual bool updateNXMInfo() = 0;
- /**
- * @brief change the notes (manually set information) for this mod
- * @param notes new notes
- */
- virtual void setNotes(const QString& notes) = 0;
+ /**
+ * @brief assign or unassign the specified category
+ *
+ * Every mod can have an arbitrary number of categories assigned to it
+ *
+ * @param categoryID id of the category to set
+ * @param active determines wheter the category is assigned or unassigned
+ * @note this function does not test whether categoryID actually identifies a valid category
+ **/
+ virtual void setCategory(int categoryID, bool active) = 0;
- /**
- * @brief set/change the nexus mod id of this mod
- *
- * @param modID the nexus mod id
- **/
- virtual void setNexusID(int modID) = 0;
+ /**
+ * @brief change the notes (manually set information) for this mod
+ * @param notes new notes
+ */
+ virtual void setNotes(const QString &notes) = 0;
- /**
- * @brief set/change the version of this mod
- * @param version new version of the mod
- */
- virtual void setVersion(const MOBase::VersionInfo& version);
+ /**
+ * @brief set/change the nexus mod id of this mod
+ *
+ * @param modID the nexus mod id
+ **/
+ virtual void setNexusID(int modID) = 0;
- /**
- * @brief Controls if mod should be highlighted based on plugin selection
- * @param isSelected whether or not the plugin has a selected mod
- **/
- virtual void setPluginSelected(const bool& isSelected);
+ /**
+ * @brief set/change the version of this mod
+ * @param version new version of the mod
+ */
+ virtual void setVersion(const MOBase::VersionInfo &version);
- /**
- * @brief set the newest version of this mod on the nexus
- *
- * this can be used to overwrite the version of a mod without actually
- * updating the mod
- *
- * @param version the new version to use
- * @todo this function should be made obsolete. All queries for mod information should go through
- * this class so no public function for this change is required
- **/
- virtual void setNewestVersion(const MOBase::VersionInfo& version) = 0;
+ /**
+ * @brief Controls if mod should be highlighted based on plugin selection
+ * @param isSelected whether or not the plugin has a selected mod
+ **/
+ virtual void setPluginSelected(const bool &isSelected);
- /**
- * @brief sets the repository that was used to download the mod
- */
- virtual void setRepository(const QString&) {}
+ /**
+ * @brief set the newest version of this mod on the nexus
+ *
+ * this can be used to overwrite the version of a mod without actually
+ * updating the mod
+ *
+ * @param version the new version to use
+ * @todo this function should be made obsolete. All queries for mod information should go through
+ * this class so no public function for this change is required
+ **/
+ virtual void setNewestVersion(const MOBase::VersionInfo &version) = 0;
- /**
- * @brief changes/updates the nexus description text
- * @param description the current description text
- */
- virtual void setNexusDescription(const QString& description) = 0;
+ /**
+ * @brief sets the repository that was used to download the mod
+ */
+ virtual void setRepository(const QString &) {}
- /**
- * @brief sets the file this mod was installed from
- * @param fileName name of the file
- */
- virtual void setInstallationFile(const QString& fileName) = 0;
+ /**
+ * @brief changes/updates the nexus description text
+ * @param description the current description text
+ */
+ virtual void setNexusDescription(const QString &description) = 0;
- /**
- * @brief sets the category id from a nexus category id. Conversion to MO id happens internally
- * @param categoryID the nexus category id
- * @note if a mapping is not possible, the category is set to the default value
- */
- virtual void addNexusCategory(int categoryID) = 0;
+ /**
+ * @brief sets the file this mod was installed from
+ * @param fileName name of the file
+ */
+ virtual void setInstallationFile(const QString &fileName) = 0;
- virtual void addCategory(const QString& categoryName) override;
- virtual bool removeCategory(const QString& categoryName) override;
- virtual QStringList categories() override;
+ /**
+ * @brief sets the category id from a nexus category id. Conversion to MO id happens internally
+ * @param categoryID the nexus category id
+ * @note if a mapping is not possible, the category is set to the default value
+ */
+ virtual void addNexusCategory(int categoryID) = 0;
- /**
- * update the endorsement state for the mod. This only changes the
- * buffered state, it does not sync with Nexus
- * @param endorsed the new endorsement state
- */
- virtual void setIsEndorsed(bool endorsed) = 0;
+ virtual void addCategory(const QString &categoryName) override;
+ virtual bool removeCategory(const QString &categoryName) override;
+ virtual QStringList categories() override;
- /**
- * set the mod to "i don't intend to endorse". The mod will not show as unendorsed but can still be endorsed
- */
- virtual void setNeverEndorse() = 0;
+ /**
+ * update the endorsement state for the mod. This only changes the
+ * buffered state, it does not sync with Nexus
+ * @param endorsed the new endorsement state
+ */
+ virtual void setIsEndorsed(bool endorsed) = 0;
- /**
- * @brief delete the mod from the disc. This does not update the global ModInfo structure or indices
- * @return true if the mod was successfully removed
- **/
- virtual bool remove() = 0;
+ /**
+ * set the mod to "i don't intend to endorse". The mod will not show as unendorsed but can still be endorsed
+ */
+ virtual void setNeverEndorse() = 0;
- /**
- * @brief endorse or un-endorse the mod. This will sync with nexus!
- * @param doEndorse if true, the mod is endorsed, if false, it's un-endorsed.
- * @note if doEndorse doesn't differ from the current value, nothing happens.
- */
- virtual void endorse(bool doEndorse) = 0;
+ /**
+ * @brief delete the mod from the disc. This does not update the global ModInfo structure or indices
+ * @return true if the mod was successfully removed
+ **/
+ virtual bool remove() = 0;
- /**
- * @brief clear all caches held for this mod
- */
- virtual void clearCaches() {}
+ /**
+ * @brief endorse or un-endorse the mod. This will sync with nexus!
+ * @param doEndorse if true, the mod is endorsed, if false, it's un-endorsed.
+ * @note if doEndorse doesn't differ from the current value, nothing happens.
+ */
+ virtual void endorse(bool doEndorse) = 0;
- /**
- * @brief getter for the mod name
- *
- * @return the mod name
- **/
- virtual QString name() const = 0;
+ /**
+ * @brief clear all caches held for this mod
+ */
+ virtual void clearCaches() {}
- /**
- * @brief getter for an internal name. This is usually the same as the regular name, but with special mod types it
- * might be this is used to distinguish between mods that have the same visible name
- * @return internal mod name
- */
- virtual QString internalName() const { return name(); }
+ /**
+ * @brief getter for the mod name
+ *
+ * @return the mod name
+ **/
+ virtual QString name() const = 0;
- /**
- * @brief getter for the mod path
- *
- * @return the (absolute) path to the mod
- **/
- virtual QString absolutePath() const = 0;
+ /**
+ * @brief getter for an internal name. This is usually the same as the regular name, but with special mod types it might be
+ * this is used to distinguish between mods that have the same visible name
+ * @return internal mod name
+ */
+ virtual QString internalName() const { return name(); }
- /**
- * @brief getter for the installation file
- *
- * @return file used to install this mod from
- */
- virtual QString getInstallationFile() const = 0;
+ /**
+ * @brief getter for the mod path
+ *
+ * @return the (absolute) path to the mod
+ **/
+ virtual QString absolutePath() const = 0;
- /**
- * @return version object for machine based comparisons
- **/
- virtual MOBase::VersionInfo getVersion() const { return m_Version; }
+ /**
+ * @brief getter for the installation file
+ *
+ * @return file used to install this mod from
+ */
+ virtual QString getInstallationFile() const = 0;
- /**
- * @brief getter for the newest version number of this mod
- *
- * @return newest version of the mod
- **/
- virtual MOBase::VersionInfo getNewestVersion() const = 0;
+ /**
+ * @return version object for machine based comparisons
+ **/
+ virtual MOBase::VersionInfo getVersion() const { return m_Version; }
- /**
- * @return the repository from which the file was downloaded. Only relevant regular mods
- */
- virtual QString repository() const { return ""; }
+ /**
+ * @brief getter for the newest version number of this mod
+ *
+ * @return newest version of the mod
+ **/
+ virtual MOBase::VersionInfo getNewestVersion() const = 0;
- /**
- * @brief ignore the newest version for updates
- */
- virtual void ignoreUpdate(bool ignore) = 0;
+ /**
+ * @return the repository from which the file was downloaded. Only relevant regular mods
+ */
+ virtual QString repository() const { return ""; }
- /**
- * @brief getter for the nexus mod id
- *
- * @return the nexus mod id. may be 0 if the mod id isn't known or doesn't exist
- **/
- virtual int getNexusID() const = 0;
+ /**
+ * @brief ignore the newest version for updates
+ */
+ virtual void ignoreUpdate(bool ignore) = 0;
- /**
- * @return the fixed priority of mods of this type or INT_MIN if the priority of mods
- * needs to be user-modifiable. Can be < 0 to force a priority below user-modifable mods
- * or INT_MAX to force priority above all user-modifiables
- */
- virtual int getFixedPriority() const = 0;
+ /**
+ * @brief getter for the nexus mod id
+ *
+ * @return the nexus mod id. may be 0 if the mod id isn't known or doesn't exist
+ **/
+ virtual int getNexusID() const = 0;
- /**
- * @return true if the mod is always enabled
- */
- virtual bool alwaysEnabled() const { return false; }
+ /**
+ * @return the fixed priority of mods of this type or INT_MIN if the priority of mods
+ * needs to be user-modifiable. Can be < 0 to force a priority below user-modifable mods
+ * or INT_MAX to force priority above all user-modifiables
+ */
+ virtual int getFixedPriority() const = 0;
- /**
- * @return true if the mod can be updated
- */
- virtual bool canBeUpdated() const { return false; }
+ /**
+ * @return true if the mod is always enabled
+ */
+ virtual bool alwaysEnabled() const { return false; }
- /**
- * @return true if the mod can be enabled/disabled
- */
- virtual bool canBeEnabled() const { return false; }
+ /**
+ * @return true if the mod can be updated
+ */
+ virtual bool canBeUpdated() const { return false; }
- /**
- * @return a list of flags for this mod
- */
- virtual std::vector<EFlag> getFlags() const = 0;
+ /**
+ * @return true if the mod can be enabled/disabled
+ */
+ virtual bool canBeEnabled() const { return false; }
- /**
- * @return a list of content types contained in a mod
- */
- virtual std::vector<EContent> getContents() const { return std::vector<EContent>(); }
+ /**
+ * @return a list of flags for this mod
+ */
+ virtual std::vector<EFlag> getFlags() const = 0;
- /**
- * @brief test if the specified flag is set for this mod
- * @param flag the flag to test
- * @return true if the flag is set, false otherwise
- */
- bool hasFlag(EFlag flag) const;
+ /**
+ * @return a list of content types contained in a mod
+ */
+ virtual std::vector<EContent> getContents() const { return std::vector<EContent>(); }
- /**
- * @brief test if the mods contains the specified content
- * @param content the content to test
- * @return true if the content is there, false otherwise
- */
- bool hasContent(ModInfo::EContent content) const;
+ /**
+ * @brief test if the specified flag is set for this mod
+ * @param flag the flag to test
+ * @return true if the flag is set, false otherwise
+ */
+ bool hasFlag(EFlag flag) const;
- /**
- * @return an indicator if and how this mod should be highlighted by the UI
- */
- virtual int getHighlight() const { return HIGHLIGHT_NONE; }
+ /**
+ * @brief test if the mods contains the specified content
+ * @param content the content to test
+ * @return true if the content is there, false otherwise
+ */
+ bool hasContent(ModInfo::EContent content) const;
- /**
- * @return list of names of ini tweaks
- **/
- virtual std::vector<QString> getIniTweaks() const = 0;
+ /**
+ * @return an indicator if and how this mod should be highlighted by the UI
+ */
+ virtual int getHighlight() const { return HIGHLIGHT_NONE; }
- /**
- * @return a description about the mod, to be displayed in the ui
- */
- virtual QString getDescription() const = 0;
+ /**
+ * @return list of names of ini tweaks
+ **/
+ virtual std::vector<QString> getIniTweaks() const = 0;
- /**
- * @return notes for this mod
- */
- virtual QString notes() const = 0;
+ /**
+ * @return a description about the mod, to be displayed in the ui
+ */
+ virtual QString getDescription() const = 0;
- /**
- * @return creation time of this mod
- */
- virtual QDateTime creationTime() const = 0;
+ /**
+ * @return notes for this mod
+ */
+ virtual QString notes() const = 0;
- /**
- * @return nexus description of the mod (html)
- */
- virtual QString getNexusDescription() const = 0;
+ /**
+ * @return creation time of this mod
+ */
+ virtual QDateTime creationTime() const = 0;
- /**
- * @return last time nexus was queried for infos on this mod
- */
- virtual QDateTime getLastNexusQuery() const = 0;
+ /**
+ * @return nexus description of the mod (html)
+ */
+ virtual QString getNexusDescription() const = 0;
- /**
- * @return a list of files that, if they exist in the data directory are treated as files in THIS mod
- */
- virtual QStringList stealFiles() const { return QStringList(); }
+ /**
+ * @return last time nexus was queried for infos on this mod
+ */
+ virtual QDateTime getLastNexusQuery() const = 0;
- /**
- * @return a list of archives belonging to this mod (as absolute file paths)
- */
- virtual QStringList archives() const = 0;
+ /**
+ * @return a list of files that, if they exist in the data directory are treated as files in THIS mod
+ */
+ virtual QStringList stealFiles() const { return QStringList(); }
- /**
- * @brief adds the information that a file has been installed into this mod
- * @param modId id of the mod installed
- * @param fileId id of the file installed
- */
- virtual void addInstalledFile(int modId, int fileId) = 0;
+ /**
+ * @return a list of archives belonging to this mod (as absolute file paths)
+ */
+ virtual QStringList archives() const = 0;
- /**
- * @brief test if the mod belongs to the specified category
- *
- * @param categoryID the category to test for.
- * @return true if the mod belongs to the specified category
- * @note this does not verify the id actually identifies a category
- **/
- bool categorySet(int categoryID) const;
+ /**
+ * @brief adds the information that a file has been installed into this mod
+ * @param modId id of the mod installed
+ * @param fileId id of the file installed
+ */
+ virtual void addInstalledFile(int modId, int fileId) = 0;
- /**
- * @brief retrive the whole list of categories (as ids) this mod belongs to
- *
- * @return list of categories
- **/
- const std::set<int>& getCategories() const { return m_Categories; }
+ /**
+ * @brief test if the mod belongs to the specified category
+ *
+ * @param categoryID the category to test for.
+ * @return true if the mod belongs to the specified category
+ * @note this does not verify the id actually identifies a category
+ **/
+ bool categorySet(int categoryID) const;
- /**
- * @return id of the primary category of this mod
- */
- int getPrimaryCategory() const { return m_PrimaryCategory; }
+ /**
+ * @brief retrive the whole list of categories (as ids) this mod belongs to
+ *
+ * @return list of categories
+ **/
+ const std::set<int> &getCategories() const { return m_Categories; }
- /**
- * @brief sets the new primary category of the mod
- * @param categoryID the category to set
- */
- virtual void setPrimaryCategory(int categoryID) { m_PrimaryCategory = categoryID; }
+ /**
+ * @return id of the primary category of this mod
+ */
+ int getPrimaryCategory() const { return m_PrimaryCategory; }
- /**
- * @return true if this mod is considered "valid", that is: it contains data used by the game
- **/
- bool isValid() const { return m_Valid; }
+ /**
+ * @brief sets the new primary category of the mod
+ * @param categoryID the category to set
+ */
+ virtual void setPrimaryCategory(int categoryID) { m_PrimaryCategory = categoryID; }
- /**
- * @return true if the file has been endorsed on nexus
- */
- virtual EEndorsedState endorsedState() const { return ENDORSED_NEVER; }
+ /**
+ * @return true if this mod is considered "valid", that is: it contains data used by the game
+ **/
+ bool isValid() const { return m_Valid; }
- /**
- * @brief updates the valid-flag for this mod
- */
- void testValid();
+ /**
+ * @return true if the file has been endorsed on nexus
+ */
+ virtual EEndorsedState endorsedState() const { return ENDORSED_NEVER; }
- /**
- * @brief reads meta information from disk
- */
- virtual void readMeta() {}
+ /**
+ * @brief updates the valid-flag for this mod
+ */
+ void testValid();
- /**
- * @brief stores meta information back to disk
- */
- virtual void saveMeta() {}
+ /**
+ * @brief reads meta information from disk
+ */
+ virtual void readMeta() {}
- /**
- * @return retrieve list of mods (as mod index) that are overwritten by this one. Updates may be delayed
- */
- virtual std::set<unsigned int> getModOverwrite() { return std::set<unsigned int>(); }
+ /**
+ * @brief stores meta information back to disk
+ */
+ virtual void saveMeta() {}
- /**
- * @return list of mods (as mod index) that overwrite this one. Updates may be delayed
- */
- virtual std::set<unsigned int> getModOverwritten() { return std::set<unsigned int>(); }
+ /**
+ * @return retrieve list of mods (as mod index) that are overwritten by this one. Updates may be delayed
+ */
+ virtual std::set<unsigned int> getModOverwrite() { return std::set<unsigned int>(); }
- /**
- * @brief update conflict information
- */
- virtual void doConflictCheck() const {}
+ /**
+ * @return list of mods (as mod index) that overwrite this one. Updates may be delayed
+ */
+ virtual std::set<unsigned int> getModOverwritten() { return std::set<unsigned int>(); }
- /**
- * @brief set the URL for a mod
- */
- virtual void setURL(QString const&) {}
+ /**
+ * @brief update conflict information
+ */
+ virtual void doConflictCheck() const {}
- /**
- * @returns the URL for a mod
- */
- virtual QString getURL() const { return ""; }
+ /**
+ * @brief set the URL for a mod
+ */
+ virtual void setURL(QString const &) {}
+
+ /**
+ * @returns the URL for a mod
+ */
+ virtual QString getURL() const { return ""; }
signals:
- /**
- * @brief emitted whenever the information of a mod changes
- *
- * @param success true if the mod details were updated successfully, false if not
- **/
- void modDetailsUpdated(bool success);
+ /**
+ * @brief emitted whenever the information of a mod changes
+ *
+ * @param success true if the mod details were updated successfully, false if not
+ **/
+ void modDetailsUpdated(bool success);
protected:
- ModInfo();
- static void updateIndices();
+ ModInfo();
+
+ static void updateIndices();
private:
- static void createFromOverwrite();
+
+ static void createFromOverwrite();
protected:
- static std::vector<ModInfo::Ptr> s_Collection;
- static std::map<QString, unsigned int> s_ModsByName;
- int m_PrimaryCategory;
- std::set<int> m_Categories;
+ static std::vector<ModInfo::Ptr> s_Collection;
+ static std::map<QString, unsigned int> s_ModsByName;
+
+ int m_PrimaryCategory;
+ std::set<int> m_Categories;
- MOBase::VersionInfo m_Version;
+ MOBase::VersionInfo m_Version;
- bool m_PluginSelected = false;
+ bool m_PluginSelected = false;
private:
- static QMutex s_Mutex;
- static std::map<int, std::vector<unsigned int>> s_ModsByModID;
- static int s_NextID;
- bool m_Valid;
+ static QMutex s_Mutex;
+ static std::map<int, std::vector<unsigned int> > s_ModsByModID;
+ static int s_NextID;
+
+ bool m_Valid;
+
};
+
#endif // MODINFO_H
diff --git a/src/modinfobackup.cpp b/src/modinfobackup.cpp
index ddd23b43..a57b84fe 100644
--- a/src/modinfobackup.cpp
+++ b/src/modinfobackup.cpp
@@ -1,12 +1,20 @@
#include "modinfobackup.h"
-std::vector<ModInfo::EFlag> ModInfoBackup::getFlags() const {
- std::vector<ModInfo::EFlag> result = ModInfoRegular::getFlags();
- result.insert(result.begin(), ModInfo::FLAG_BACKUP);
- return result;
+std::vector<ModInfo::EFlag> ModInfoBackup::getFlags() const
+{
+ std::vector<ModInfo::EFlag> result = ModInfoRegular::getFlags();
+ result.insert(result.begin(), ModInfo::FLAG_BACKUP);
+ return result;
}
-QString ModInfoBackup::getDescription() const { return tr("This is the backup of a mod"); }
-ModInfoBackup::ModInfoBackup(const QDir& path, MOShared::DirectoryEntry** directoryStructure)
- : ModInfoRegular(path, directoryStructure) {}
+QString ModInfoBackup::getDescription() const
+{
+ return tr("This is the backup of a mod");
+}
+
+
+ModInfoBackup::ModInfoBackup(const QDir &path, MOShared::DirectoryEntry **directoryStructure)
+ : ModInfoRegular(path, directoryStructure)
+{
+}
diff --git a/src/modinfobackup.h b/src/modinfobackup.h
index 7c8ce874..adbac783 100644
--- a/src/modinfobackup.h
+++ b/src/modinfobackup.h
@@ -3,33 +3,38 @@
#include "modinforegular.h"
-class ModInfoBackup : public ModInfoRegular {
+class ModInfoBackup : public ModInfoRegular
+{
- friend class ModInfo;
+ friend class ModInfo;
public:
- virtual bool updateAvailable() const { return false; }
- virtual bool updateIgnored() const { return false; }
- virtual bool downgradeAvailable() const { return false; }
- virtual bool updateNXMInfo() { return false; }
- virtual void setNexusID(int) {}
- virtual void endorse(bool) {}
- virtual int getFixedPriority() const { return -1; }
- virtual void ignoreUpdate(bool) {}
- virtual bool canBeUpdated() const { return false; }
- virtual bool canBeEnabled() const { return false; }
- virtual std::vector<QString> getIniTweaks() const { return std::vector<QString>(); }
- virtual std::vector<EFlag> getFlags() const;
- virtual QString getDescription() const;
- virtual QDateTime getLastNexusQuery() const { return QDateTime(); }
- virtual void getNexusFiles(QList<MOBase::ModRepositoryFileInfo*>::const_iterator&,
- QList<MOBase::ModRepositoryFileInfo*>::const_iterator&) {}
- virtual QString getNexusDescription() const { return QString(); }
- virtual void addInstalledFile(int, int) {}
+ virtual bool updateAvailable() const { return false; }
+ virtual bool updateIgnored() const { return false; }
+ virtual bool downgradeAvailable() const { return false; }
+ virtual bool updateNXMInfo() { return false; }
+ virtual void setNexusID(int) {}
+ virtual void endorse(bool) {}
+ virtual int getFixedPriority() const { return -1; }
+ virtual void ignoreUpdate(bool) {}
+ virtual bool canBeUpdated() const { return false; }
+ virtual bool canBeEnabled() const { return false; }
+ virtual std::vector<QString> getIniTweaks() const { return std::vector<QString>(); }
+ virtual std::vector<EFlag> getFlags() const;
+ virtual QString getDescription() const;
+ virtual QDateTime getLastNexusQuery() const { return QDateTime(); }
+ virtual void getNexusFiles(QList<MOBase::ModRepositoryFileInfo*>::const_iterator&,
+ QList<MOBase::ModRepositoryFileInfo*>::const_iterator&) {}
+ virtual QString getNexusDescription() const { return QString(); }
+
+ virtual void addInstalledFile(int, int) {}
private:
- ModInfoBackup(const QDir& path, MOShared::DirectoryEntry** directoryStructure);
+
+ ModInfoBackup(const QDir &path, MOShared::DirectoryEntry **directoryStructure);
+
};
+
#endif // MODINFOBACKUP_H
diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp
index 9afecbfa..ccd2a122 100644
--- a/src/modinfodialog.cpp
+++ b/src/modinfodialog.cpp
@@ -18,645 +18,714 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "modinfodialog.h"
-#include "descriptionpage.h"
#include "ui_modinfodialog.h"
+#include "descriptionpage.h"
-#include "bbcode.h"
-#include "categories.h"
#include "iplugingame.h"
-#include "messagedialog.h"
#include "nexusinterface.h"
-#include "questionboxmemory.h"
#include "report.h"
-#include "settings.h"
#include "utility.h"
+#include "messagedialog.h"
+#include "bbcode.h"
+#include "questionboxmemory.h"
+#include "settings.h"
+#include "categories.h"
#include <QDir>
#include <QDirIterator>
-#include <QFileSystemModel>
+#include <QPushButton>
#include <QInputDialog>
-#include <QMenu>
#include <QMessageBox>
+#include <QMenu>
+#include <QFileSystemModel>
+#include <QInputDialog>
#include <QPointer>
-#include <QPushButton>
#include <Shlwapi.h>
#include <sstream>
+
using namespace MOBase;
using namespace MOShared;
-class ModFileListWidget : public QListWidgetItem {
- friend bool operator<(const ModFileListWidget& LHS, const ModFileListWidget& RHS);
+class ModFileListWidget : public QListWidgetItem {
+ friend bool operator<(const ModFileListWidget &LHS, const ModFileListWidget &RHS);
public:
- ModFileListWidget(const QString& text, int sortValue, QListWidget* parent = 0)
- : QListWidgetItem(text, parent, QListWidgetItem::UserType + 1), m_SortValue(sortValue) {}
-
+ ModFileListWidget(const QString &text, int sortValue, QListWidget *parent = 0)
+ : QListWidgetItem(text, parent, QListWidgetItem::UserType + 1), m_SortValue(sortValue) {}
private:
- int m_SortValue;
+ int m_SortValue;
};
-static bool operator<(const ModFileListWidget& LHS, const ModFileListWidget& RHS) {
- return LHS.m_SortValue < RHS.m_SortValue;
+
+static bool operator<(const ModFileListWidget &LHS, const ModFileListWidget &RHS)
+{
+ return LHS.m_SortValue < RHS.m_SortValue;
}
-ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry* directory, bool unmanaged, QWidget* parent)
- : TutorableDialog("ModInfoDialog", parent), ui(new Ui::ModInfoDialog), m_ModInfo(modInfo), m_ThumbnailMapper(this),
- m_RequestStarted(false), m_DeleteAction(nullptr), m_RenameAction(nullptr), m_OpenAction(nullptr),
- m_Directory(directory), m_Origin(nullptr) {
- ui->setupUi(this);
- this->setWindowTitle(modInfo->name());
- this->setWindowModality(Qt::WindowModal);
- m_RootPath = modInfo->absolutePath();
+ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directory, bool unmanaged, QWidget *parent)
+ : TutorableDialog("ModInfoDialog", parent), ui(new Ui::ModInfoDialog), m_ModInfo(modInfo),
+ m_ThumbnailMapper(this), m_RequestStarted(false),
+ m_DeleteAction(nullptr), m_RenameAction(nullptr), m_OpenAction(nullptr),
+ m_Directory(directory), m_Origin(nullptr)
+{
+ ui->setupUi(this);
+ this->setWindowTitle(modInfo->name());
+ this->setWindowModality(Qt::WindowModal);
- QString metaFileName = m_RootPath.mid(0).append("/meta.ini");
- m_Settings = new QSettings(metaFileName, QSettings::IniFormat);
+ m_RootPath = modInfo->absolutePath();
- QLineEdit* modIDEdit = findChild<QLineEdit*>("modIDEdit");
- ui->modIDEdit->setValidator(new QIntValidator(modIDEdit));
- ui->modIDEdit->setText(QString("%1").arg(modInfo->getNexusID()));
+ QString metaFileName = m_RootPath.mid(0).append("/meta.ini");
+ m_Settings = new QSettings(metaFileName, QSettings::IniFormat);
- ui->notesEdit->setText(modInfo->notes());
+ QLineEdit *modIDEdit = findChild<QLineEdit*>("modIDEdit");
+ ui->modIDEdit->setValidator(new QIntValidator(modIDEdit));
+ ui->modIDEdit->setText(QString("%1").arg(modInfo->getNexusID()));
- ui->descriptionView->setPage(new DescriptionPage);
+ ui->notesEdit->setText(modInfo->notes());
- connect(&m_ThumbnailMapper, SIGNAL(mapped(const QString&)), this, SIGNAL(thumbnailClickedSignal(const QString&)));
- connect(this, SIGNAL(thumbnailClickedSignal(const QString&)), this, SLOT(thumbnailClicked(const QString&)));
- connect(m_ModInfo.data(), SIGNAL(modDetailsUpdated(bool)), this, SLOT(modDetailsUpdated(bool)));
- connect(ui->descriptionView->page(), SIGNAL(linkClicked(QUrl)), this, SLOT(linkClicked(QUrl)));
- // TODO: No easy way to delegate links
- // ui->descriptionView->page()->acceptNavigationRequest(QWebEnginePage::DelegateAllLinks);
+ ui->descriptionView->setPage(new DescriptionPage);
- if (directory->originExists(ToWString(modInfo->name()))) {
- m_Origin = &directory->getOriginByName(ToWString(modInfo->name()));
- if (m_Origin->isDisabled()) {
- m_Origin = nullptr;
- }
+ connect(&m_ThumbnailMapper, SIGNAL(mapped(const QString&)), this, SIGNAL(thumbnailClickedSignal(const QString&)));
+ connect(this, SIGNAL(thumbnailClickedSignal(const QString&)), this, SLOT(thumbnailClicked(const QString&)));
+ connect(m_ModInfo.data(), SIGNAL(modDetailsUpdated(bool)), this, SLOT(modDetailsUpdated(bool)));
+ connect(ui->descriptionView->page(), SIGNAL(linkClicked(QUrl)), this, SLOT(linkClicked(QUrl)));
+ //TODO: No easy way to delegate links
+ //ui->descriptionView->page()->acceptNavigationRequest(QWebEnginePage::DelegateAllLinks);
+
+ if (directory->originExists(ToWString(modInfo->name()))) {
+ m_Origin = &directory->getOriginByName(ToWString(modInfo->name()));
+ if (m_Origin->isDisabled()) {
+ m_Origin = nullptr;
}
+ }
- refreshLists();
+ refreshLists();
- if (unmanaged) {
- ui->tabWidget->setTabEnabled(TAB_INIFILES, false);
- ui->tabWidget->setTabEnabled(TAB_CATEGORIES, false);
- ui->tabWidget->setTabEnabled(TAB_NEXUS, false);
- ui->tabWidget->setTabEnabled(TAB_FILETREE, false);
- ui->tabWidget->setTabEnabled(TAB_NOTES, false);
- ui->tabWidget->setTabEnabled(TAB_ESPS, false);
- ui->tabWidget->setTabEnabled(TAB_TEXTFILES, false);
- ui->tabWidget->setTabEnabled(TAB_IMAGES, false);
- } else {
- initFiletree(modInfo);
- addCategories(CategoryFactory::instance(), modInfo->getCategories(), ui->categoriesTree->invisibleRootItem(),
- 0);
- refreshPrimaryCategoriesBox();
- ui->tabWidget->setTabEnabled(TAB_TEXTFILES, ui->textFileList->count() != 0);
- ui->tabWidget->setTabEnabled(TAB_IMAGES, ui->thumbnailArea->count() != 0);
- ui->tabWidget->setTabEnabled(TAB_ESPS,
- (ui->inactiveESPList->count() != 0) || (ui->activeESPList->count() != 0));
- }
- initINITweaks();
+ if (unmanaged) {
+ ui->tabWidget->setTabEnabled(TAB_INIFILES, false);
+ ui->tabWidget->setTabEnabled(TAB_CATEGORIES, false);
+ ui->tabWidget->setTabEnabled(TAB_NEXUS, false);
+ ui->tabWidget->setTabEnabled(TAB_FILETREE, false);
+ ui->tabWidget->setTabEnabled(TAB_NOTES, false);
+ ui->tabWidget->setTabEnabled(TAB_ESPS, false);
+ ui->tabWidget->setTabEnabled(TAB_TEXTFILES, false);
+ ui->tabWidget->setTabEnabled(TAB_IMAGES, false);
+ } else {
+ initFiletree(modInfo);
+ addCategories(CategoryFactory::instance(), modInfo->getCategories(), ui->categoriesTree->invisibleRootItem(), 0);
+ refreshPrimaryCategoriesBox();
+ ui->tabWidget->setTabEnabled(TAB_TEXTFILES, ui->textFileList->count() != 0);
+ ui->tabWidget->setTabEnabled(TAB_IMAGES, ui->thumbnailArea->count() != 0);
+ ui->tabWidget->setTabEnabled(TAB_ESPS, (ui->inactiveESPList->count() != 0) || (ui->activeESPList->count() != 0));
+ }
+ initINITweaks();
- ui->tabWidget->setTabEnabled(TAB_CONFLICTS, m_Origin != nullptr);
+ ui->tabWidget->setTabEnabled(TAB_CONFLICTS, m_Origin != nullptr);
- if (ui->tabWidget->currentIndex() == TAB_NEXUS) {
- activateNexusTab();
- }
+ if (ui->tabWidget->currentIndex() == TAB_NEXUS) {
+ activateNexusTab();
+ }
- ui->endorseBtn->setEnabled((m_ModInfo->endorsedState() == ModInfo::ENDORSED_FALSE) ||
- (m_ModInfo->endorsedState() == ModInfo::ENDORSED_NEVER));
+ ui->endorseBtn->setEnabled((m_ModInfo->endorsedState() == ModInfo::ENDORSED_FALSE) ||
+ (m_ModInfo->endorsedState() == ModInfo::ENDORSED_NEVER));
- // activate first enabled tab
- for (int i = 0; i < ui->tabWidget->count(); ++i) {
- if (ui->tabWidget->isTabEnabled(i)) {
- ui->tabWidget->setCurrentIndex(i);
- break;
- }
+ // activate first enabled tab
+ for (int i = 0; i < ui->tabWidget->count(); ++i) {
+ if (ui->tabWidget->isTabEnabled(i)) {
+ ui->tabWidget->setCurrentIndex(i);
+ break;
}
+ }
}
-ModInfoDialog::~ModInfoDialog() {
- m_ModInfo->setNotes(ui->notesEdit->toPlainText());
- saveCategories(ui->categoriesTree->invisibleRootItem());
- saveIniTweaks(); // ini tweaks are written to the ini file directly. This is the only information not managed by
- // ModInfo
- delete ui->descriptionView->page();
- delete ui->descriptionView;
- delete ui;
- delete m_Settings;
+
+ModInfoDialog::~ModInfoDialog()
+{
+ m_ModInfo->setNotes(ui->notesEdit->toPlainText());
+ saveCategories(ui->categoriesTree->invisibleRootItem());
+ saveIniTweaks(); // ini tweaks are written to the ini file directly. This is the only information not managed by ModInfo
+ delete ui->descriptionView->page();
+ delete ui->descriptionView;
+ delete ui;
+ delete m_Settings;
}
-void ModInfoDialog::initINITweaks() {
- int numTweaks = m_Settings->beginReadArray("INI Tweaks");
- for (int i = 0; i < numTweaks; ++i) {
- m_Settings->setArrayIndex(i);
- QList<QListWidgetItem*> items =
- ui->iniTweaksList->findItems(m_Settings->value("name").toString(), Qt::MatchFixedString);
- if (items.size() != 0) {
- items.at(0)->setCheckState(Qt::Checked);
- }
+
+void ModInfoDialog::initINITweaks()
+{
+ int numTweaks = m_Settings->beginReadArray("INI Tweaks");
+ for (int i = 0; i < numTweaks; ++i) {
+ m_Settings->setArrayIndex(i);
+ QList<QListWidgetItem*> items = ui->iniTweaksList->findItems(m_Settings->value("name").toString(), Qt::MatchFixedString);
+ if (items.size() != 0) {
+ items.at(0)->setCheckState(Qt::Checked);
}
- m_Settings->endArray();
+ }
+ m_Settings->endArray();
}
-void ModInfoDialog::initFiletree(ModInfo::Ptr modInfo) {
- ui->fileTree = findChild<QTreeView*>("fileTree");
+void ModInfoDialog::initFiletree(ModInfo::Ptr modInfo)
+{
+ ui->fileTree = findChild<QTreeView*>("fileTree");
- m_FileSystemModel = new QFileSystemModel(this);
- m_FileSystemModel->setReadOnly(false);
- m_FileSystemModel->setRootPath(m_RootPath);
- ui->fileTree->setModel(m_FileSystemModel);
- ui->fileTree->setRootIndex(m_FileSystemModel->index(m_RootPath));
- ui->fileTree->setColumnWidth(0, 300);
+ m_FileSystemModel = new QFileSystemModel(this);
+ m_FileSystemModel->setReadOnly(false);
+ m_FileSystemModel->setRootPath(m_RootPath);
+ ui->fileTree->setModel(m_FileSystemModel);
+ ui->fileTree->setRootIndex(m_FileSystemModel->index(m_RootPath));
+ ui->fileTree->setColumnWidth(0, 300);
- m_DeleteAction = new QAction(tr("&Delete"), ui->fileTree);
- m_RenameAction = new QAction(tr("&Rename"), ui->fileTree);
- m_HideAction = new QAction(tr("&Hide"), ui->fileTree);
- m_UnhideAction = new QAction(tr("&Unhide"), ui->fileTree);
- m_OpenAction = new QAction(tr("&Open"), ui->fileTree);
- m_NewFolderAction = new QAction(tr("&New Folder"), ui->fileTree);
- QObject::connect(m_DeleteAction, SIGNAL(triggered()), this, SLOT(deleteTriggered()));
- QObject::connect(m_RenameAction, SIGNAL(triggered()), this, SLOT(renameTriggered()));
- QObject::connect(m_OpenAction, SIGNAL(triggered()), this, SLOT(openTriggered()));
- QObject::connect(m_NewFolderAction, SIGNAL(triggered()), this, SLOT(createDirectoryTriggered()));
- QObject::connect(m_HideAction, SIGNAL(triggered()), this, SLOT(hideTriggered()));
- connect(m_UnhideAction, SIGNAL(triggered()), this, SLOT(unhideTriggered()));
+ m_DeleteAction = new QAction(tr("&Delete"), ui->fileTree);
+ m_RenameAction = new QAction(tr("&Rename"), ui->fileTree);
+ m_HideAction = new QAction(tr("&Hide"), ui->fileTree);
+ m_UnhideAction = new QAction(tr("&Unhide"), ui->fileTree);
+ m_OpenAction = new QAction(tr("&Open"), ui->fileTree);
+ m_NewFolderAction = new QAction(tr("&New Folder"), ui->fileTree);
+ QObject::connect(m_DeleteAction, SIGNAL(triggered()), this, SLOT(deleteTriggered()));
+ QObject::connect(m_RenameAction, SIGNAL(triggered()), this, SLOT(renameTriggered()));
+ QObject::connect(m_OpenAction, SIGNAL(triggered()), this, SLOT(openTriggered()));
+ QObject::connect(m_NewFolderAction, SIGNAL(triggered()), this, SLOT(createDirectoryTriggered()));
+ QObject::connect(m_HideAction, SIGNAL(triggered()), this, SLOT(hideTriggered()));
+ connect(m_UnhideAction, SIGNAL(triggered()), this, SLOT(unhideTriggered()));
}
-int ModInfoDialog::tabIndex(const QString& tabId) {
- for (int i = 0; i < ui->tabWidget->count(); ++i) {
- if (ui->tabWidget->widget(i)->objectName() == tabId) {
- return i;
- }
+
+int ModInfoDialog::tabIndex(const QString &tabId)
+{
+ for (int i = 0; i < ui->tabWidget->count(); ++i) {
+ if (ui->tabWidget->widget(i)->objectName() == tabId) {
+ return i;
}
- return -1;
+ }
+ return -1;
}
-void ModInfoDialog::restoreTabState(const QByteArray& state) {
- QDataStream stream(state);
- int count = 0;
- stream >> count;
- QStringList tabIds;
+void ModInfoDialog::restoreTabState(const QByteArray &state)
+{
+ QDataStream stream(state);
+ int count = 0;
+ stream >> count;
- // first, only determine the new mapping
- for (int newPos = 0; newPos < count; ++newPos) {
- QString tabId;
- stream >> tabId;
- tabIds.append(tabId);
- int oldPos = tabIndex(tabId);
- if (oldPos != -1) {
- m_RealTabPos[newPos] = oldPos;
- } else {
- m_RealTabPos[newPos] = newPos;
- }
- }
- // then actually move the tabs
- QTabBar* tabBar = ui->tabWidget->findChild<QTabBar*>("qt_tabwidget_tabbar"); // magic name = bad
- ui->tabWidget->blockSignals(true);
- for (int newPos = 0; newPos < count; ++newPos) {
- QString tabId = tabIds.at(newPos);
- int oldPos = tabIndex(tabId);
- tabBar->moveTab(oldPos, newPos);
+ QStringList tabIds;
+
+ // first, only determine the new mapping
+ for (int newPos = 0; newPos < count; ++newPos) {
+ QString tabId;
+ stream >> tabId;
+ tabIds.append(tabId);
+ int oldPos = tabIndex(tabId);
+ if (oldPos != -1) {
+ m_RealTabPos[newPos] = oldPos;
+ } else {
+ m_RealTabPos[newPos] = newPos;
}
- ui->tabWidget->blockSignals(false);
+ }
+ // then actually move the tabs
+ QTabBar *tabBar = ui->tabWidget->findChild<QTabBar*>("qt_tabwidget_tabbar"); // magic name = bad
+ ui->tabWidget->blockSignals(true);
+ for (int newPos = 0; newPos < count; ++newPos) {
+ QString tabId = tabIds.at(newPos);
+ int oldPos = tabIndex(tabId);
+ tabBar->moveTab(oldPos, newPos);
+ }
+ ui->tabWidget->blockSignals(false);
}
-QByteArray ModInfoDialog::saveTabState() const {
- QByteArray result;
- QDataStream stream(&result, QIODevice::WriteOnly);
- stream << ui->tabWidget->count();
- for (int i = 0; i < ui->tabWidget->count(); ++i) {
- stream << ui->tabWidget->widget(i)->objectName();
- }
- return result;
+QByteArray ModInfoDialog::saveTabState() const
+{
+ QByteArray result;
+ QDataStream stream(&result, QIODevice::WriteOnly);
+ stream << ui->tabWidget->count();
+ for (int i = 0; i < ui->tabWidget->count(); ++i) {
+ stream << ui->tabWidget->widget(i)->objectName();
+ }
+
+ return result;
}
-void ModInfoDialog::refreshLists() {
- int numNonConflicting = 0;
- int numOverwrite = 0;
- int numOverwritten = 0;
- ui->overwriteTree->clear();
- ui->overwrittenTree->clear();
+void ModInfoDialog::refreshLists()
+{
+ int numNonConflicting = 0;
+ int numOverwrite = 0;
+ int numOverwritten = 0;
+
+ ui->overwriteTree->clear();
+ ui->overwrittenTree->clear();
- if (m_Origin != nullptr) {
- std::vector<FileEntry::Ptr> files = m_Origin->getFiles();
- for (auto iter = files.begin(); iter != files.end(); ++iter) {
- QString relativeName = QDir::fromNativeSeparators(ToQString((*iter)->getRelativePath()));
- QString fileName = relativeName.mid(0).prepend(m_RootPath);
- bool archive;
- if ((*iter)->getOrigin(archive) == m_Origin->getID()) {
- std::vector<std::pair<int, std::wstring>> alternatives = (*iter)->getAlternatives();
- if (!alternatives.empty()) {
- std::wostringstream altString;
- for (std::vector<std::pair<int, std::wstring>>::iterator altIter = alternatives.begin();
- altIter != alternatives.end(); ++altIter) {
- if (altIter != alternatives.begin()) {
- altString << ", ";
- }
- altString << m_Directory->getOriginByID(altIter->first).getName();
- }
- QStringList fields(relativeName.prepend("..."));
- fields.append(ToQString(altString.str()));
- QTreeWidgetItem* item = new QTreeWidgetItem(fields);
- item->setData(0, Qt::UserRole, fileName);
- item->setData(1, Qt::UserRole,
- ToQString(m_Directory->getOriginByID(alternatives.begin()->first).getName()));
- item->setData(1, Qt::UserRole + 1, alternatives.begin()->first);
- item->setData(1, Qt::UserRole + 2, archive);
- ui->overwriteTree->addTopLevelItem(item);
- ++numOverwrite;
- } else { // otherwise don't display the file
- ++numNonConflicting;
- }
- } else {
- FilesOrigin& realOrigin = m_Directory->getOriginByID((*iter)->getOrigin(archive));
- QStringList fields(relativeName);
- fields.append(ToQString(realOrigin.getName()));
- QTreeWidgetItem* item = new QTreeWidgetItem(fields);
- item->setData(1, Qt::UserRole, ToQString(realOrigin.getName()));
- ui->overwrittenTree->addTopLevelItem(item);
- ++numOverwritten;
+ if (m_Origin != nullptr) {
+ std::vector<FileEntry::Ptr> files = m_Origin->getFiles();
+ for (auto iter = files.begin(); iter != files.end(); ++iter) {
+ QString relativeName = QDir::fromNativeSeparators(ToQString((*iter)->getRelativePath()));
+ QString fileName = relativeName.mid(0).prepend(m_RootPath);
+ bool archive;
+ if ((*iter)->getOrigin(archive) == m_Origin->getID()) {
+ std::vector<std::pair<int, std::wstring>> alternatives = (*iter)->getAlternatives();
+ if (!alternatives.empty()) {
+ std::wostringstream altString;
+ for (std::vector<std::pair<int, std::wstring>>::iterator altIter = alternatives.begin();
+ altIter != alternatives.end(); ++altIter) {
+ if (altIter != alternatives.begin()) {
+ altString << ", ";
}
+ altString << m_Directory->getOriginByID(altIter->first).getName();
+ }
+ QStringList fields(relativeName.prepend("..."));
+ fields.append(ToQString(altString.str()));
+ QTreeWidgetItem *item = new QTreeWidgetItem(fields);
+ item->setData(0, Qt::UserRole, fileName);
+ item->setData(1, Qt::UserRole, ToQString(m_Directory->getOriginByID(alternatives.begin()->first).getName()));
+ item->setData(1, Qt::UserRole + 1, alternatives.begin()->first);
+ item->setData(1, Qt::UserRole + 2, archive);
+ ui->overwriteTree->addTopLevelItem(item);
+ ++numOverwrite;
+ } else {// otherwise don't display the file
+ ++numNonConflicting;
}
+ } else {
+ FilesOrigin &realOrigin = m_Directory->getOriginByID((*iter)->getOrigin(archive));
+ QStringList fields(relativeName);
+ fields.append(ToQString(realOrigin.getName()));
+ QTreeWidgetItem *item = new QTreeWidgetItem(fields);
+ item->setData(1, Qt::UserRole, ToQString(realOrigin.getName()));
+ ui->overwrittenTree->addTopLevelItem(item);
+ ++numOverwritten;
+ }
}
+ }
- if (m_RootPath.length() > 0) {
- QDirIterator dirIterator(m_RootPath, QDir::Files, QDirIterator::Subdirectories);
- while (dirIterator.hasNext()) {
- QString fileName = dirIterator.next();
+ if (m_RootPath.length() > 0) {
+ QDirIterator dirIterator(m_RootPath, QDir::Files, QDirIterator::Subdirectories);
+ while (dirIterator.hasNext()) {
+ QString fileName = dirIterator.next();
- if (fileName.endsWith(".txt", Qt::CaseInsensitive)) {
- ui->textFileList->addItem(fileName.mid(m_RootPath.length() + 1));
- } else if ((fileName.endsWith(".ini", Qt::CaseInsensitive) ||
- fileName.endsWith(".cfg", Qt::CaseInsensitive)) &&
- !fileName.endsWith("meta.ini")) {
- QString namePart = fileName.mid(m_RootPath.length() + 1);
- if (namePart.startsWith("INI Tweaks", Qt::CaseInsensitive)) {
- QListWidgetItem* newItem = new QListWidgetItem(namePart.mid(11), ui->iniTweaksList);
- newItem->setData(Qt::UserRole, namePart);
- newItem->setFlags(newItem->flags() | Qt::ItemIsUserCheckable);
- newItem->setCheckState(Qt::Unchecked);
- ui->iniTweaksList->addItem(newItem);
- } else {
- ui->iniFileList->addItem(namePart);
- }
- } else if (fileName.endsWith(".esp", Qt::CaseInsensitive) ||
- fileName.endsWith(".esm", Qt::CaseInsensitive) ||
- fileName.endsWith(".esl", Qt::CaseInsensitive)) {
- QString relativePath = fileName.mid(m_RootPath.length() + 1);
- if (relativePath.contains('/')) {
- QFileInfo fileInfo(fileName);
- QListWidgetItem* newItem = new QListWidgetItem(fileInfo.fileName());
- newItem->setData(Qt::UserRole, relativePath);
- ui->inactiveESPList->addItem(newItem);
- } else {
- ui->activeESPList->addItem(relativePath);
- }
- } else if ((fileName.endsWith(".png", Qt::CaseInsensitive)) ||
- (fileName.endsWith(".jpg", Qt::CaseInsensitive))) {
- QImage image = QImage(fileName);
- if (!image.isNull()) {
- if (static_cast<float>(image.width()) / static_cast<float>(image.height()) > 1.34) {
- image = image.scaledToWidth(128);
- } else {
- image = image.scaledToHeight(96);
- }
+ if (fileName.endsWith(".txt", Qt::CaseInsensitive)) {
+ ui->textFileList->addItem(fileName.mid(m_RootPath.length() + 1));
+ } else if ((fileName.endsWith(".ini", Qt::CaseInsensitive) || fileName.endsWith(".cfg", Qt::CaseInsensitive)) &&
+ !fileName.endsWith("meta.ini")) {
+ QString namePart = fileName.mid(m_RootPath.length() + 1);
+ if (namePart.startsWith("INI Tweaks", Qt::CaseInsensitive)) {
+ QListWidgetItem *newItem = new QListWidgetItem(namePart.mid(11), ui->iniTweaksList);
+ newItem->setData(Qt::UserRole, namePart);
+ newItem->setFlags(newItem->flags() | Qt::ItemIsUserCheckable);
+ newItem->setCheckState(Qt::Unchecked);
+ ui->iniTweaksList->addItem(newItem);
+ } else {
+ ui->iniFileList->addItem(namePart);
+ }
+ } else if (fileName.endsWith(".esp", Qt::CaseInsensitive) ||
+ fileName.endsWith(".esm", Qt::CaseInsensitive) ||
+ fileName.endsWith(".esl", Qt::CaseInsensitive)) {
+ QString relativePath = fileName.mid(m_RootPath.length() + 1);
+ if (relativePath.contains('/')) {
+ QFileInfo fileInfo(fileName);
+ QListWidgetItem *newItem = new QListWidgetItem(fileInfo.fileName());
+ newItem->setData(Qt::UserRole, relativePath);
+ ui->inactiveESPList->addItem(newItem);
+ } else {
+ ui->activeESPList->addItem(relativePath);
+ }
+ } else if ((fileName.endsWith(".png", Qt::CaseInsensitive)) ||
+ (fileName.endsWith(".jpg", Qt::CaseInsensitive))) {
+ QImage image = QImage(fileName);
+ if (!image.isNull()) {
+ if (static_cast<float>(image.width()) / static_cast<float>(image.height()) > 1.34) {
+ image = image.scaledToWidth(128);
+ } else {
+ image = image.scaledToHeight(96);
+ }
- QPushButton* thumbnailButton = new QPushButton(QPixmap::fromImage(image), "");
- thumbnailButton->setIconSize(QSize(image.width(), image.height()));
- connect(thumbnailButton, SIGNAL(clicked()), &m_ThumbnailMapper, SLOT(map()));
- m_ThumbnailMapper.setMapping(thumbnailButton, fileName);
- ui->thumbnailArea->addWidget(thumbnailButton);
- }
- }
+ QPushButton *thumbnailButton = new QPushButton(QPixmap::fromImage(image), "");
+ thumbnailButton->setIconSize(QSize(image.width(), image.height()));
+ connect(thumbnailButton, SIGNAL(clicked()), &m_ThumbnailMapper, SLOT(map()));
+ m_ThumbnailMapper.setMapping(thumbnailButton, fileName);
+ ui->thumbnailArea->addWidget(thumbnailButton);
}
+ }
}
+ }
- ui->overwriteCount->display(numOverwrite);
- ui->overwrittenCount->display(numOverwritten);
- ui->noConflictCount->display(numNonConflicting);
+ ui->overwriteCount->display(numOverwrite);
+ ui->overwrittenCount->display(numOverwritten);
+ ui->noConflictCount->display(numNonConflicting);
}
-void ModInfoDialog::addCategories(const CategoryFactory& factory, const std::set<int>& enabledCategories,
- QTreeWidgetItem* root, int rootLevel) {
- for (int i = 0; i < static_cast<int>(factory.numCategories()); ++i) {
- if (factory.getParentID(i) != rootLevel) {
- continue;
- }
- int categoryID = factory.getCategoryID(i);
- QTreeWidgetItem* newItem = new QTreeWidgetItem(QStringList(factory.getCategoryName(i)));
- newItem->setFlags(newItem->flags() | Qt::ItemIsUserCheckable);
- newItem->setCheckState(0, enabledCategories.find(categoryID) != enabledCategories.end() ? Qt::Checked
- : Qt::Unchecked);
- newItem->setData(0, Qt::UserRole, categoryID);
- if (factory.hasChildren(i)) {
- addCategories(factory, enabledCategories, newItem, categoryID);
- }
- root->addChild(newItem);
+
+void ModInfoDialog::addCategories(const CategoryFactory &factory, const std::set<int> &enabledCategories, QTreeWidgetItem *root, int rootLevel)
+{
+ for (int i = 0; i < static_cast<int>(factory.numCategories()); ++i) {
+ if (factory.getParentID(i) != rootLevel) {
+ continue;
+ }
+ int categoryID = factory.getCategoryID(i);
+ QTreeWidgetItem *newItem
+ = new QTreeWidgetItem(QStringList(factory.getCategoryName(i)));
+ newItem->setFlags(newItem->flags() | Qt::ItemIsUserCheckable);
+ newItem->setCheckState(0, enabledCategories.find(categoryID)
+ != enabledCategories.end()
+ ? Qt::Checked
+ : Qt::Unchecked);
+ newItem->setData(0, Qt::UserRole, categoryID);
+ if (factory.hasChildren(i)) {
+ addCategories(factory, enabledCategories, newItem, categoryID);
}
+ root->addChild(newItem);
+ }
}
-void ModInfoDialog::saveCategories(QTreeWidgetItem* currentNode) {
- for (int i = 0; i < currentNode->childCount(); ++i) {
- QTreeWidgetItem* childNode = currentNode->child(i);
- m_ModInfo->setCategory(childNode->data(0, Qt::UserRole).toInt(), childNode->checkState(0));
- saveCategories(childNode);
- }
+
+void ModInfoDialog::saveCategories(QTreeWidgetItem *currentNode)
+{
+ for (int i = 0; i < currentNode->childCount(); ++i) {
+ QTreeWidgetItem *childNode = currentNode->child(i);
+ m_ModInfo->setCategory(childNode->data(0, Qt::UserRole).toInt(), childNode->checkState(0));
+ saveCategories(childNode);
+ }
}
-void ModInfoDialog::on_closeButton_clicked() {
- if (allowNavigateFromTXT() && allowNavigateFromINI()) {
- this->close();
- }
+
+void ModInfoDialog::on_closeButton_clicked()
+{
+ if (allowNavigateFromTXT() && allowNavigateFromINI()) {
+ this->close();
+ }
}
-QString ModInfoDialog::getModVersion() const { return m_Settings->value("version", "").toString(); }
-const int ModInfoDialog::getModID() const { return m_Settings->value("modid", 0).toInt(); }
-void ModInfoDialog::openTab(int tab) {
- QTabWidget* tabWidget = findChild<QTabWidget*>("tabWidget");
- if (tabWidget->isTabEnabled(tab)) {
- tabWidget->setCurrentIndex(tab);
- }
+QString ModInfoDialog::getModVersion() const
+{
+ return m_Settings->value("version", "").toString();
}
-void ModInfoDialog::thumbnailClicked(const QString& fileName) {
- QLabel* imageLabel = findChild<QLabel*>("imageLabel");
- imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
- QImage image(fileName);
- if (static_cast<float>(image.width()) / static_cast<float>(image.height()) > 1.34) {
- image = image.scaledToWidth(imageLabel->geometry().width());
- } else {
- image = image.scaledToHeight(imageLabel->geometry().height());
- }
- imageLabel->setPixmap(QPixmap::fromImage(image));
+
+const int ModInfoDialog::getModID() const
+{
+ return m_Settings->value("modid", 0).toInt();
}
-bool ModInfoDialog::allowNavigateFromTXT() {
- if (ui->saveTXTButton->isEnabled()) {
- int res = QMessageBox::question(
- this, tr("Save changes?"),
- tr("Save changes to \"%1\"?").arg(ui->textFileView->property("currentFile").toString()),
- QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
- if (res == QMessageBox::Cancel) {
- return false;
- } else if (res == QMessageBox::Yes) {
- saveCurrentTextFile();
- }
- }
- return true;
+void ModInfoDialog::openTab(int tab)
+{
+ QTabWidget *tabWidget = findChild<QTabWidget*>("tabWidget");
+ if (tabWidget->isTabEnabled(tab)) {
+ tabWidget->setCurrentIndex(tab);
+ }
}
-bool ModInfoDialog::allowNavigateFromINI() {
- if (ui->saveButton->isEnabled()) {
- int res = QMessageBox::question(
- this, tr("Save changes?"),
- tr("Save changes to \"%1\"?").arg(ui->iniFileView->property("currentFile").toString()),
- QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
- if (res == QMessageBox::Cancel) {
- return false;
- } else if (res == QMessageBox::Yes) {
- saveCurrentIniFile();
- }
+void ModInfoDialog::thumbnailClicked(const QString &fileName)
+{
+ QLabel *imageLabel = findChild<QLabel*>("imageLabel");
+ imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
+ QImage image(fileName);
+ if (static_cast<float>(image.width()) / static_cast<float>(image.height()) > 1.34) {
+ image = image.scaledToWidth(imageLabel->geometry().width());
+ } else {
+ image = image.scaledToHeight(imageLabel->geometry().height());
+ }
+ imageLabel->setPixmap(QPixmap::fromImage(image));
+}
+
+bool ModInfoDialog::allowNavigateFromTXT()
+{
+ if (ui->saveTXTButton->isEnabled()) {
+ int res = QMessageBox::question(this, tr("Save changes?"), tr("Save changes to \"%1\"?").arg(ui->textFileView->property("currentFile").toString()),
+ QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
+ if (res == QMessageBox::Cancel) {
+ return false;
+ } else if (res == QMessageBox::Yes) {
+ saveCurrentTextFile();
}
- return true;
+ }
+ return true;
}
-void ModInfoDialog::on_textFileList_currentItemChanged(QListWidgetItem* current, QListWidgetItem* previous) {
- QString fullPath = m_RootPath + "/" + current->text();
- QVariant currentFile = ui->textFileView->property("currentFile");
- if (currentFile.isValid() && (currentFile.toString() == fullPath)) {
- // the new file is the same as the currently displayed file. May be the result of a cancelation
- return;
+bool ModInfoDialog::allowNavigateFromINI()
+{
+ if (ui->saveButton->isEnabled()) {
+ int res = QMessageBox::question(this, tr("Save changes?"), tr("Save changes to \"%1\"?").arg(ui->iniFileView->property("currentFile").toString()),
+ QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
+ if (res == QMessageBox::Cancel) {
+ return false;
+ } else if (res == QMessageBox::Yes) {
+ saveCurrentIniFile();
}
+ }
+ return true;
+}
- if (allowNavigateFromTXT()) {
- openTextFile(fullPath);
- } else {
- ui->textFileList->setCurrentItem(previous, QItemSelectionModel::Current);
- }
+
+void ModInfoDialog::on_textFileList_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
+{
+ QString fullPath = m_RootPath + "/" + current->text();
+
+ QVariant currentFile = ui->textFileView->property("currentFile");
+ if (currentFile.isValid() && (currentFile.toString() == fullPath)) {
+ // the new file is the same as the currently displayed file. May be the result of a cancelation
+ return;
+ }
+
+ if (allowNavigateFromTXT()) {
+ openTextFile(fullPath);
+ } else {
+ ui->textFileList->setCurrentItem(previous, QItemSelectionModel::Current);
+ }
}
-void ModInfoDialog::openTextFile(const QString& fileName) {
- QString encoding;
- ui->textFileView->setText(MOBase::readFileText(fileName, &encoding));
- ui->textFileView->setProperty("currentFile", fileName);
- ui->textFileView->setProperty("encoding", encoding);
- ui->saveTXTButton->setEnabled(false);
+
+void ModInfoDialog::openTextFile(const QString &fileName)
+{
+ QString encoding;
+ ui->textFileView->setText(MOBase::readFileText(fileName, &encoding));
+ ui->textFileView->setProperty("currentFile", fileName);
+ ui->textFileView->setProperty("encoding", encoding);
+ ui->saveTXTButton->setEnabled(false);
}
-void ModInfoDialog::openIniFile(const QString& fileName) {
- QFile iniFile(fileName);
- iniFile.open(QIODevice::ReadOnly);
- QByteArray buffer = iniFile.readAll();
- QTextCodec* codec = QTextCodec::codecForUtfText(buffer, QTextCodec::codecForName("utf-8"));
- QTextEdit* iniFileView = findChild<QTextEdit*>("iniFileView");
- iniFileView->setText(codec->toUnicode(buffer));
- iniFileView->setProperty("currentFile", fileName);
- iniFileView->setProperty("encoding", codec->name());
- iniFile.close();
+void ModInfoDialog::openIniFile(const QString &fileName)
+{
+ QFile iniFile(fileName);
+ iniFile.open(QIODevice::ReadOnly);
+ QByteArray buffer = iniFile.readAll();
- ui->saveButton->setEnabled(false);
+ QTextCodec *codec = QTextCodec::codecForUtfText(buffer, QTextCodec::codecForName("utf-8"));
+ QTextEdit *iniFileView = findChild<QTextEdit*>("iniFileView");
+ iniFileView->setText(codec->toUnicode(buffer));
+ iniFileView->setProperty("currentFile", fileName);
+ iniFileView->setProperty("encoding", codec->name());
+ iniFile.close();
+
+ ui->saveButton->setEnabled(false);
}
-void ModInfoDialog::saveIniTweaks() {
- m_Settings->beginWriteArray("INI Tweaks");
- int countEnabled = 0;
- for (int i = 0; i < ui->iniTweaksList->count(); ++i) {
- if (ui->iniTweaksList->item(i)->checkState() == Qt::Checked) {
- m_Settings->setArrayIndex(countEnabled++);
- m_Settings->setValue("name", ui->iniTweaksList->item(i)->text());
- }
+void ModInfoDialog::saveIniTweaks()
+{
+ m_Settings->beginWriteArray("INI Tweaks");
+
+ int countEnabled = 0;
+ for (int i = 0; i < ui->iniTweaksList->count(); ++i) {
+ if (ui->iniTweaksList->item(i)->checkState() == Qt::Checked) {
+ m_Settings->setArrayIndex(countEnabled++);
+ m_Settings->setValue("name", ui->iniTweaksList->item(i)->text());
}
- m_Settings->endArray();
+ }
+ m_Settings->endArray();
}
-void ModInfoDialog::on_iniFileList_currentItemChanged(QListWidgetItem* current, QListWidgetItem* previous) {
- QString fullPath = m_RootPath + "/" + current->text();
- QVariant currentFile = ui->iniFileView->property("currentFile");
- if (currentFile.isValid() && (currentFile.toString() == fullPath)) {
- // the new file is the same as the currently displayed file. May be the result of a cancelation
- return;
- }
+void ModInfoDialog::on_iniFileList_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
+{
+ QString fullPath = m_RootPath + "/" + current->text();
- if (allowNavigateFromINI()) {
- openIniFile(fullPath);
- } else {
- ui->iniFileList->setCurrentItem(previous, QItemSelectionModel::Current);
- }
+ QVariant currentFile = ui->iniFileView->property("currentFile");
+ if (currentFile.isValid() && (currentFile.toString() == fullPath)) {
+ // the new file is the same as the currently displayed file. May be the result of a cancelation
+ return;
+ }
+
+ if (allowNavigateFromINI()) {
+ openIniFile(fullPath);
+ } else {
+ ui->iniFileList->setCurrentItem(previous, QItemSelectionModel::Current);
+ }
}
-void ModInfoDialog::on_iniTweaksList_currentItemChanged(QListWidgetItem* current, QListWidgetItem* previous) {
- QString fullPath = m_RootPath + "/" + current->data(Qt::UserRole).toString();
- QVariant currentFile = ui->iniFileView->property("currentFile");
- if (currentFile.isValid() && (currentFile.toString() == fullPath)) {
- // the new file is the same as the currently displayed file. May be the result of a cancelation
- return;
- }
+void ModInfoDialog::on_iniTweaksList_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
+{
+ QString fullPath = m_RootPath + "/" + current->data(Qt::UserRole).toString();
+
+ QVariant currentFile = ui->iniFileView->property("currentFile");
+ if (currentFile.isValid() && (currentFile.toString() == fullPath)) {
+ // the new file is the same as the currently displayed file. May be the result of a cancelation
+ return;
+ }
+
+ if (allowNavigateFromINI()) {
+ openIniFile(fullPath);
+ } else {
+ ui->iniFileList->setCurrentItem(previous, QItemSelectionModel::Current);
+ }
- if (allowNavigateFromINI()) {
- openIniFile(fullPath);
- } else {
- ui->iniFileList->setCurrentItem(previous, QItemSelectionModel::Current);
- }
}
-void ModInfoDialog::on_saveButton_clicked() { saveCurrentIniFile(); }
-void ModInfoDialog::on_saveTXTButton_clicked() { saveCurrentTextFile(); }
+void ModInfoDialog::on_saveButton_clicked()
+{
+ saveCurrentIniFile();
+}
-void ModInfoDialog::saveCurrentTextFile() {
- QVariant fileNameVar = ui->textFileView->property("currentFile");
- QVariant encodingVar = ui->textFileView->property("encoding");
- if (fileNameVar.isValid() && encodingVar.isValid()) {
- QString fileName = fileNameVar.toString();
- QFile txtFile(fileName);
- txtFile.open(QIODevice::WriteOnly);
- txtFile.resize(0);
- QTextCodec* codec = QTextCodec::codecForName(encodingVar.toString().toUtf8());
- QString data = ui->textFileView->toPlainText().replace("\n", "\r\n");
- txtFile.write(codec->fromUnicode(data));
- } else {
- reportError("no file selected");
- }
- ui->saveTXTButton->setEnabled(false);
+
+void ModInfoDialog::on_saveTXTButton_clicked()
+{
+ saveCurrentTextFile();
}
-void ModInfoDialog::saveCurrentIniFile() {
- QVariant fileNameVar = ui->iniFileView->property("currentFile");
- QVariant encodingVar = ui->iniFileView->property("encoding");
- if (fileNameVar.isValid() && !fileNameVar.toString().isEmpty()) {
- QString fileName = fileNameVar.toString();
- QDir().mkpath(QFileInfo(fileName).absolutePath());
- QFile txtFile(fileName);
- txtFile.open(QIODevice::WriteOnly);
- txtFile.resize(0);
- QTextCodec* codec = QTextCodec::codecForName(encodingVar.toString().toUtf8());
- QString data = ui->iniFileView->toPlainText().replace("\n", "\r\n");
- txtFile.write(codec->fromUnicode(data));
- } else {
- reportError("no file selected");
- }
- ui->saveButton->setEnabled(false);
+
+void ModInfoDialog::saveCurrentTextFile()
+{
+ QVariant fileNameVar = ui->textFileView->property("currentFile");
+ QVariant encodingVar = ui->textFileView->property("encoding");
+ if (fileNameVar.isValid() && encodingVar.isValid()) {
+ QString fileName = fileNameVar.toString();
+ QFile txtFile(fileName);
+ txtFile.open(QIODevice::WriteOnly);
+ txtFile.resize(0);
+ QTextCodec *codec = QTextCodec::codecForName(encodingVar.toString().toUtf8());
+ QString data = ui->textFileView->toPlainText().replace("\n", "\r\n");
+ txtFile.write(codec->fromUnicode(data));
+ } else {
+ reportError("no file selected");
+ }
+ ui->saveTXTButton->setEnabled(false);
}
-void ModInfoDialog::on_iniFileView_textChanged() {
- QPushButton* saveButton = findChild<QPushButton*>("saveButton");
- saveButton->setEnabled(true);
+
+void ModInfoDialog::saveCurrentIniFile()
+{
+ QVariant fileNameVar = ui->iniFileView->property("currentFile");
+ QVariant encodingVar = ui->iniFileView->property("encoding");
+ if (fileNameVar.isValid() && !fileNameVar.toString().isEmpty()) {
+ QString fileName = fileNameVar.toString();
+ QDir().mkpath(QFileInfo(fileName).absolutePath());
+ QFile txtFile(fileName);
+ txtFile.open(QIODevice::WriteOnly);
+ txtFile.resize(0);
+ QTextCodec *codec = QTextCodec::codecForName(encodingVar.toString().toUtf8());
+ QString data = ui->iniFileView->toPlainText().replace("\n", "\r\n");
+ txtFile.write(codec->fromUnicode(data));
+ } else {
+ reportError("no file selected");
+ }
+ ui->saveButton->setEnabled(false);
}
-void ModInfoDialog::on_textFileView_textChanged() { ui->saveTXTButton->setEnabled(true); }
-void ModInfoDialog::on_activateESP_clicked() {
- QListWidget* activeESPList = findChild<QListWidget*>("activeESPList");
- QListWidget* inactiveESPList = findChild<QListWidget*>("inactiveESPList");
+void ModInfoDialog::on_iniFileView_textChanged()
+{
+ QPushButton* saveButton = findChild<QPushButton*>("saveButton");
+ saveButton->setEnabled(true);
+}
- int selectedRow = inactiveESPList->currentRow();
- if (selectedRow < 0) {
- return;
- }
- QListWidgetItem* selectedItem = inactiveESPList->takeItem(selectedRow);
+void ModInfoDialog::on_textFileView_textChanged()
+{
+ ui->saveTXTButton->setEnabled(true);
+}
- QDir root(m_RootPath);
- bool renamed = false;
- while (root.exists(selectedItem->text())) {
- bool okClicked = false;
- QString newName =
- QInputDialog::getText(this, tr("File Exists"), tr("A file with that name exists, please enter a new one"),
- QLineEdit::Normal, selectedItem->text(), &okClicked);
- if (!okClicked) {
- inactiveESPList->insertItem(selectedRow, selectedItem);
- return;
- } else if (newName.size() > 0) {
- selectedItem->setText(newName);
- renamed = true;
- }
+void ModInfoDialog::on_activateESP_clicked()
+{
+ QListWidget *activeESPList = findChild<QListWidget*>("activeESPList");
+ QListWidget *inactiveESPList = findChild<QListWidget*>("inactiveESPList");
+
+ int selectedRow = inactiveESPList->currentRow();
+ if (selectedRow < 0) {
+ return;
+ }
+
+ QListWidgetItem *selectedItem = inactiveESPList->takeItem(selectedRow);
+
+ QDir root(m_RootPath);
+ bool renamed = false;
+
+ while (root.exists(selectedItem->text())) {
+ bool okClicked = false;
+ QString newName = QInputDialog::getText(this, tr("File Exists"), tr("A file with that name exists, please enter a new one"), QLineEdit::Normal, selectedItem->text(), &okClicked);
+ if (!okClicked) {
+ inactiveESPList->insertItem(selectedRow, selectedItem);
+ return;
+ } else if (newName.size() > 0) {
+ selectedItem->setText(newName);
+ renamed = true;
}
+ }
- if (root.rename(selectedItem->data(Qt::UserRole).toString(), selectedItem->text())) {
- activeESPList->addItem(selectedItem);
- if (renamed) {
- selectedItem->setData(Qt::UserRole, QVariant());
- }
- } else {
- inactiveESPList->insertItem(selectedRow, selectedItem);
- reportError(tr("failed to move file"));
+ if (root.rename(selectedItem->data(Qt::UserRole).toString(), selectedItem->text())) {
+ activeESPList->addItem(selectedItem);
+ if (renamed) {
+ selectedItem->setData(Qt::UserRole, QVariant());
}
+ } else {
+ inactiveESPList->insertItem(selectedRow, selectedItem);
+ reportError(tr("failed to move file"));
+ }
}
-void ModInfoDialog::on_deactivateESP_clicked() {
- QListWidget* activeESPList = findChild<QListWidget*>("activeESPList");
- QListWidget* inactiveESPList = findChild<QListWidget*>("inactiveESPList");
- int selectedRow = activeESPList->currentRow();
- if (selectedRow < 0) {
- return;
- }
+void ModInfoDialog::on_deactivateESP_clicked()
+{
+ QListWidget *activeESPList = findChild<QListWidget*>("activeESPList");
+ QListWidget *inactiveESPList = findChild<QListWidget*>("inactiveESPList");
- QDir root(m_RootPath);
+ int selectedRow = activeESPList->currentRow();
+ if (selectedRow < 0) {
+ return;
+ }
- QListWidgetItem* selectedItem = activeESPList->takeItem(selectedRow);
+ QDir root(m_RootPath);
- // if we moved the file from optional to active in this session, we move the file back to
- // where it came from. Otherwise, it is moved to the new folder "optional"
- if (selectedItem->data(Qt::UserRole).isNull()) {
- selectedItem->setData(Qt::UserRole, QString("optional/") + selectedItem->text());
- if (!root.exists("optional")) {
- if (!root.mkdir("optional")) {
- reportError(tr("failed to create directory \"optional\""));
- activeESPList->insertItem(selectedRow, selectedItem);
- return;
- }
- }
- }
+ QListWidgetItem *selectedItem = activeESPList->takeItem(selectedRow);
- if (root.rename(selectedItem->text(), selectedItem->data(Qt::UserRole).toString())) {
- inactiveESPList->addItem(selectedItem);
- } else {
+ // if we moved the file from optional to active in this session, we move the file back to
+ // where it came from. Otherwise, it is moved to the new folder "optional"
+ if (selectedItem->data(Qt::UserRole).isNull()) {
+ selectedItem->setData(Qt::UserRole, QString("optional/") + selectedItem->text());
+ if (!root.exists("optional")) {
+ if (!root.mkdir("optional")) {
+ reportError(tr("failed to create directory \"optional\""));
activeESPList->insertItem(selectedRow, selectedItem);
+ return;
+ }
}
+ }
+
+ if (root.rename(selectedItem->text(), selectedItem->data(Qt::UserRole).toString())) {
+ inactiveESPList->addItem(selectedItem);
+ } else {
+ activeESPList->insertItem(selectedRow, selectedItem);
+ }
}
-void ModInfoDialog::on_visitNexusLabel_linkActivated(const QString& link) {
- this->close();
- emit nexusLinkActivated(link);
+void ModInfoDialog::on_visitNexusLabel_linkActivated(const QString &link)
+{
+ this->close();
+ emit nexusLinkActivated(link);
}
-void ModInfoDialog::linkClicked(const QUrl& url) {
- // Ideally we'd ask the mod for the game and the web service then pass the game
- // and URL to the web service
- if (NexusInterface::instance()->isURLGameRelated(url)) {
- this->close();
- emit nexusLinkActivated(url.toString());
- } else {
- ::ShellExecuteW(nullptr, L"open", ToWString(url.toString()).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
- }
+void ModInfoDialog::linkClicked(const QUrl &url)
+{
+ //Ideally we'd ask the mod for the game and the web service then pass the game
+ //and URL to the web service
+ if (NexusInterface::instance()->isURLGameRelated(url)) {
+ this->close();
+ emit nexusLinkActivated(url.toString());
+ } else {
+ ::ShellExecuteW(nullptr, L"open", ToWString(url.toString()).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
+ }
}
-void ModInfoDialog::refreshNexusData(int modID) {
- if ((!m_RequestStarted) && (modID > 0)) {
- m_RequestStarted = true;
- m_ModInfo->updateNXMInfo();
+void ModInfoDialog::refreshNexusData(int modID)
+{
+ if ((!m_RequestStarted) && (modID > 0)) {
+ m_RequestStarted = true;
- MessageDialog::showMessage(tr("Info requested, please wait"), this);
- }
+ m_ModInfo->updateNXMInfo();
+
+ MessageDialog::showMessage(tr("Info requested, please wait"), this);
+ }
}
+
/*void ModInfoDialog::nxmDescriptionAvailable(int, QVariant, QVariant resultData, int requestID)
{
std::set<int>::iterator idIter = m_RequestIDs.find(requestID);
@@ -678,8 +747,7 @@ void ModInfoDialog::refreshNexusData(int modID) {
// QString descriptionAsHTML = BBCode::convertToHTML(result["description"].toString());
ui->descriptionView->setHtml(descriptionAsHTML);
} else {
- ui->descriptionView->setHtml(result["summary"].toString().append(QString("\r\n") + tr("(description incomplete,
-please visit nexus)")));
+ ui->descriptionView->setHtml(result["summary"].toString().append(QString("\r\n") + tr("(description incomplete, please visit nexus)")));
}
QLineEdit *versionEdit = findChild<QLineEdit*>("versionEdit");
@@ -703,454 +771,506 @@ please visit nexus)")));
}
}*/
-QString ModInfoDialog::getFileCategory(int categoryID) {
- switch (categoryID) {
- case 1:
- return tr("Main");
- case 2:
- return tr("Update");
- case 3:
- return tr("Optional");
- case 4:
- return tr("Old");
- case 5:
- return tr("Misc");
- default:
- return tr("Unknown");
- }
+
+QString ModInfoDialog::getFileCategory(int categoryID)
+{
+ switch (categoryID) {
+ case 1: return tr("Main");
+ case 2: return tr("Update");
+ case 3: return tr("Optional");
+ case 4: return tr("Old");
+ case 5: return tr("Misc");
+ default: return tr("Unknown");
+ }
}
-void ModInfoDialog::updateVersionColor() {
- // QPalette versionColor;
- if (m_ModInfo->getVersion() != m_ModInfo->getNewestVersion()) {
- ui->versionEdit->setStyleSheet("color: red");
- // versionColor.setColor(QPalette::Text, Qt::red);
- ui->versionEdit->setToolTip(tr("Current Version: %1").arg(m_ModInfo->getNewestVersion().canonicalString()));
- } else {
- ui->versionEdit->setStyleSheet("color: green");
- // versionColor.setColor(QPalette::Text, Qt::green);
- ui->versionEdit->setToolTip(tr("No update available"));
- }
- // ui->versionEdit->setPalette(versionColor);
+
+void ModInfoDialog::updateVersionColor()
+{
+// QPalette versionColor;
+ if (m_ModInfo->getVersion() != m_ModInfo->getNewestVersion()) {
+ ui->versionEdit->setStyleSheet("color: red");
+// versionColor.setColor(QPalette::Text, Qt::red);
+ ui->versionEdit->setToolTip(tr("Current Version: %1").arg(m_ModInfo->getNewestVersion().canonicalString()));
+ } else {
+ ui->versionEdit->setStyleSheet("color: green");
+// versionColor.setColor(QPalette::Text, Qt::green);
+ ui->versionEdit->setToolTip(tr("No update available"));
+ }
+// ui->versionEdit->setPalette(versionColor);
}
-void ModInfoDialog::modDetailsUpdated(bool success) {
- if (success) {
- QString nexusDescription = m_ModInfo->getNexusDescription();
- if (!nexusDescription.isEmpty()) {
- /* QString input =
- "[size=20]sizetest[/size]\r\n"
- "[COLOR=yellow]colortest[/COLOR]\r\n"
- "[center]centertest[/center]\r\n"
- "[quote]quotetest 1[/quote]\r\n"
- "[quote=bla]quotetest 2[/quote]\r\n"
- "[url]www.skyrimnexus.com[/url]\r\n"
- "[url=www.skyrimnexus.com]urltest 2[/url]\r\n"
- "[ol]\r\n"
- "[li]item 2[/li]"
- "[*]item 1\r\n"
- "[/ol]\r\n"
- "[img]http://www.bbcode.org/images/bbcode_logo.png[/img]\r\n"
- "[table][tr][th]headertest1[/th]"
- "[th]headertest2[/th][/tr]"
- "[tr][td]rowtest11[/td][td]rowtest12[/td][/tr]"
- "[tr][td]rowtest21[/td][td]rowtest22[/td][/tr][/table]"
- "[email=\"sherb@gmx.net\"]mail me[/email]";
- ui->descriptionView->setHtml(BBCode::convertToHTML(input));*/
- QString descriptionAsHTML =
- QString("<html>"
- "<head><style>body {background: #707070; } a { color: #5EA2E5; }</style></head>"
- "<body>%1</body>"
- "</html>")
- .arg(BBCode::convertToHTML(nexusDescription));
+void ModInfoDialog::modDetailsUpdated(bool success)
+{
+ if (success) {
+ QString nexusDescription = m_ModInfo->getNexusDescription();
+ if (!nexusDescription.isEmpty()) {
+ /* QString input =
+ "[size=20]sizetest[/size]\r\n"
+ "[COLOR=yellow]colortest[/COLOR]\r\n"
+ "[center]centertest[/center]\r\n"
+ "[quote]quotetest 1[/quote]\r\n"
+ "[quote=bla]quotetest 2[/quote]\r\n"
+ "[url]www.skyrimnexus.com[/url]\r\n"
+ "[url=www.skyrimnexus.com]urltest 2[/url]\r\n"
+ "[ol]\r\n"
+ "[li]item 2[/li]"
+ "[*]item 1\r\n"
+ "[/ol]\r\n"
+ "[img]http://www.bbcode.org/images/bbcode_logo.png[/img]\r\n"
+ "[table][tr][th]headertest1[/th]"
+ "[th]headertest2[/th][/tr]"
+ "[tr][td]rowtest11[/td][td]rowtest12[/td][/tr]"
+ "[tr][td]rowtest21[/td][td]rowtest22[/td][/tr][/table]"
+ "[email=\"sherb@gmx.net\"]mail me[/email]";
+ ui->descriptionView->setHtml(BBCode::convertToHTML(input));*/
- ui->descriptionView->page()->setHtml(descriptionAsHTML);
+ QString descriptionAsHTML =
+ QString("<html>"
+ "<head><style>body {background: #707070; } a { color: #5EA2E5; }</style></head>"
+ "<body>%1</body>"
+ "</html>").arg(BBCode::convertToHTML(nexusDescription));
- // QString descriptionAsHTML = BBCode::convertToHTML(result["description"].toString());
- // ui->descriptionView->setHtml(descriptionAsHTML);
- } else {
- // ui->descriptionView->setHtml(result["summary"].toString().append(QString("\r\n") + tr("(description
- // incomplete, please visit nexus)")));
- ui->descriptionView->page()->setHtml(tr("(description incomplete, please visit nexus)"));
- }
+ ui->descriptionView->page()->setHtml(descriptionAsHTML);
- updateVersionColor();
+ // QString descriptionAsHTML = BBCode::convertToHTML(result["description"].toString());
+ // ui->descriptionView->setHtml(descriptionAsHTML);
+ } else {
+ // ui->descriptionView->setHtml(result["summary"].toString().append(QString("\r\n") + tr("(description incomplete, please visit nexus)")));
+ ui->descriptionView->page()->setHtml(tr("(description incomplete, please visit nexus)"));
}
+
+ updateVersionColor();
+ }
}
-void ModInfoDialog::activateNexusTab() {
- QLineEdit* modIDEdit = findChild<QLineEdit*>("modIDEdit");
- int modID = modIDEdit->text().toInt();
- if (modID != 0) {
- QString nexusLink = NexusInterface::instance()->getModURL(modID);
- QLabel* visitNexusLabel = findChild<QLabel*>("visitNexusLabel");
- visitNexusLabel->setText(tr("<a href=\"%1\">Visit on Nexus</a>").arg(nexusLink));
- visitNexusLabel->setToolTip(nexusLink);
- if (m_ModInfo->getNexusDescription().isEmpty() ||
- QDateTime::currentDateTime() > m_ModInfo->getLastNexusQuery().addDays(1)) {
- refreshNexusData(modID);
- } else {
- this->modDetailsUpdated(true);
- }
+void ModInfoDialog::activateNexusTab()
+{
+ QLineEdit *modIDEdit = findChild<QLineEdit*>("modIDEdit");
+ int modID = modIDEdit->text().toInt();
+ if (modID != 0) {
+ QString nexusLink = NexusInterface::instance()->getModURL(modID);
+ QLabel *visitNexusLabel = findChild<QLabel*>("visitNexusLabel");
+ visitNexusLabel->setText(tr("<a href=\"%1\">Visit on Nexus</a>").arg(nexusLink));
+ visitNexusLabel->setToolTip(nexusLink);
+
+ if (m_ModInfo->getNexusDescription().isEmpty() ||
+ QDateTime::currentDateTime() > m_ModInfo->getLastNexusQuery().addDays(1)) {
+ refreshNexusData(modID);
+ } else {
+ this->modDetailsUpdated(true);
}
- QLineEdit* versionEdit = findChild<QLineEdit*>("versionEdit");
- QString currentVersion = m_Settings->value("version", "0.0").toString();
- versionEdit->setText(currentVersion);
+ }
+ QLineEdit *versionEdit = findChild<QLineEdit*>("versionEdit");
+ QString currentVersion = m_Settings->value("version", "0.0").toString();
+ versionEdit->setText(currentVersion);
}
-void ModInfoDialog::on_tabWidget_currentChanged(int index) {
- if (m_RealTabPos[index] == TAB_NEXUS) {
- activateNexusTab();
- }
+
+void ModInfoDialog::on_tabWidget_currentChanged(int index)
+{
+ if (m_RealTabPos[index] == TAB_NEXUS) {
+ activateNexusTab();
+ }
}
-void ModInfoDialog::on_modIDEdit_editingFinished() {
- int oldID = m_Settings->value("modid", 0).toInt();
- int modID = ui->modIDEdit->text().toInt();
- if (oldID != modID) {
- m_ModInfo->setNexusID(modID);
- ui->descriptionView->page()->setHtml("");
- if (modID != 0) {
- m_RequestStarted = false;
- refreshNexusData(modID);
- }
+void ModInfoDialog::on_modIDEdit_editingFinished()
+{
+ int oldID = m_Settings->value("modid", 0).toInt();
+ int modID = ui->modIDEdit->text().toInt();
+ if (oldID != modID){
+ m_ModInfo->setNexusID(modID);
+
+ ui->descriptionView->page()->setHtml("");
+ if (modID != 0) {
+ m_RequestStarted = false;
+ refreshNexusData(modID);
}
+ }
}
-void ModInfoDialog::on_versionEdit_editingFinished() {
- VersionInfo version(ui->versionEdit->text());
- m_ModInfo->setVersion(version);
- updateVersionColor();
+void ModInfoDialog::on_versionEdit_editingFinished()
+{
+ VersionInfo version(ui->versionEdit->text());
+ m_ModInfo->setVersion(version);
+ updateVersionColor();
}
-bool ModInfoDialog::recursiveDelete(const QModelIndex& index) {
- for (int childRow = 0; childRow < m_FileSystemModel->rowCount(index); ++childRow) {
- QModelIndex childIndex = m_FileSystemModel->index(childRow, 0, index);
- if (m_FileSystemModel->isDir(childIndex)) {
- if (!recursiveDelete(childIndex)) {
- qCritical("failed to delete %s", m_FileSystemModel->fileName(childIndex).toUtf8().constData());
- return false;
- }
- } else {
- if (!m_FileSystemModel->remove(childIndex)) {
- qCritical("failed to delete %s", m_FileSystemModel->fileName(childIndex).toUtf8().constData());
- return false;
- }
- }
- }
- if (!m_FileSystemModel->remove(index)) {
- qCritical("failed to delete %s", m_FileSystemModel->fileName(index).toUtf8().constData());
+
+bool ModInfoDialog::recursiveDelete(const QModelIndex &index)
+{
+ for (int childRow = 0; childRow < m_FileSystemModel->rowCount(index); ++childRow) {
+ QModelIndex childIndex = m_FileSystemModel->index(childRow, 0, index);
+ if (m_FileSystemModel->isDir(childIndex)) {
+ if (!recursiveDelete(childIndex)) {
+ qCritical("failed to delete %s", m_FileSystemModel->fileName(childIndex).toUtf8().constData());
+ return false;
+ }
+ } else {
+ if (!m_FileSystemModel->remove(childIndex)) {
+ qCritical("failed to delete %s", m_FileSystemModel->fileName(childIndex).toUtf8().constData());
return false;
+ }
}
- return true;
+ }
+ if (!m_FileSystemModel->remove(index)) {
+ qCritical("failed to delete %s", m_FileSystemModel->fileName(index).toUtf8().constData());
+ return false;
+ }
+ return true;
}
-void ModInfoDialog::deleteFile(const QModelIndex& index) {
- bool res = m_FileSystemModel->isDir(index) ? recursiveDelete(index) : m_FileSystemModel->remove(index);
- if (!res) {
- QString fileName = m_FileSystemModel->fileName(index);
- reportError(tr("Failed to delete %1").arg(fileName));
- }
+void ModInfoDialog::deleteFile(const QModelIndex &index)
+{
+
+ bool res = m_FileSystemModel->isDir(index) ? recursiveDelete(index)
+ : m_FileSystemModel->remove(index);
+ if (!res) {
+ QString fileName = m_FileSystemModel->fileName(index);
+ reportError(tr("Failed to delete %1").arg(fileName));
+ }
}
-void ModInfoDialog::deleteTriggered() {
- if (m_FileSelection.count() == 0) {
- return;
- } else if (m_FileSelection.count() == 1) {
- QString fileName = m_FileSystemModel->fileName(m_FileSelection.at(0));
- if (QMessageBox::question(this, tr("Confirm"), tr("Are sure you want to delete \"%1\"?").arg(fileName),
- QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
- return;
- }
- } else {
- if (QMessageBox::question(this, tr("Confirm"), tr("Are sure you want to delete the selected files?"),
- QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
- return;
- }
+
+void ModInfoDialog::deleteTriggered()
+{
+ if (m_FileSelection.count() == 0) {
+ return;
+ } else if (m_FileSelection.count() == 1) {
+ QString fileName = m_FileSystemModel->fileName(m_FileSelection.at(0));
+ if (QMessageBox::question(this, tr("Confirm"), tr("Are sure you want to delete \"%1\"?").arg(fileName),
+ QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
+ return;
+ }
+ } else {
+ if (QMessageBox::question(this, tr("Confirm"), tr("Are sure you want to delete the selected files?"),
+ QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
+ return;
}
+ }
- foreach (QModelIndex index, m_FileSelection) { deleteFile(index); }
+ foreach(QModelIndex index, m_FileSelection) {
+ deleteFile(index);
+ }
}
-void ModInfoDialog::renameTriggered() {
- QModelIndex selection = m_FileSelection.at(0);
- QModelIndex index = selection.sibling(selection.row(), 0);
- if (!index.isValid() || m_FileSystemModel->isReadOnly()) {
- return;
- }
- ui->fileTree->edit(index);
+void ModInfoDialog::renameTriggered()
+{
+ QModelIndex selection = m_FileSelection.at(0);
+ QModelIndex index = selection.sibling(selection.row(), 0);
+ if (!index.isValid() || m_FileSystemModel->isReadOnly()) {
+ return;
+ }
+
+ ui->fileTree->edit(index);
}
-void ModInfoDialog::hideTriggered() {
- for (QModelIndexList::const_iterator iter = m_FileSelection.constBegin(); iter != m_FileSelection.constEnd();
- ++iter) {
- QString path = m_FileSystemModel->filePath(*iter);
- if (!path.endsWith(ModInfo::s_HiddenExt)) {
- hideFile(path);
- }
+
+void ModInfoDialog::hideTriggered()
+{
+ for (QModelIndexList::const_iterator iter = m_FileSelection.constBegin();
+ iter != m_FileSelection.constEnd(); ++iter) {
+ QString path = m_FileSystemModel->filePath(*iter);
+ if (!path.endsWith(ModInfo::s_HiddenExt)) {
+ hideFile(path);
}
+ }
}
-void ModInfoDialog::unhideTriggered() {
- for (QModelIndexList::const_iterator iter = m_FileSelection.constBegin(); iter != m_FileSelection.constEnd();
- ++iter) {
- QString path = m_FileSystemModel->filePath(*iter);
- if (path.endsWith(ModInfo::s_HiddenExt)) {
- unhideFile(path);
- }
+
+void ModInfoDialog::unhideTriggered()
+{
+ for (QModelIndexList::const_iterator iter = m_FileSelection.constBegin();
+ iter != m_FileSelection.constEnd(); ++iter) {
+ QString path = m_FileSystemModel->filePath(*iter);
+ if (path.endsWith(ModInfo::s_HiddenExt)) {
+ unhideFile(path);
}
+ }
}
-void ModInfoDialog::openFile(const QModelIndex& index) {
- QString fileName = m_FileSystemModel->filePath(index);
- HINSTANCE res = ::ShellExecuteW(nullptr, L"open", ToWString(fileName).c_str(), nullptr, nullptr, SW_SHOW);
- if ((int)res <= 32) {
- qCritical("failed to invoke %s: %d", fileName.toUtf8().constData(), res);
- }
+void ModInfoDialog::openFile(const QModelIndex &index)
+{
+ QString fileName = m_FileSystemModel->filePath(index);
+
+ HINSTANCE res = ::ShellExecuteW(nullptr, L"open", ToWString(fileName).c_str(), nullptr, nullptr, SW_SHOW);
+ if ((int)res <= 32) {
+ qCritical("failed to invoke %s: %d", fileName.toUtf8().constData(), res);
+ }
}
-void ModInfoDialog::openTriggered() {
- foreach (QModelIndex idx, m_FileSelection) { openFile(idx); }
+
+void ModInfoDialog::openTriggered()
+{
+ foreach(QModelIndex idx, m_FileSelection) {
+ openFile(idx);
+ }
}
-void ModInfoDialog::createDirectoryTriggered() {
- QModelIndex selection = m_FileSelection.at(0);
+void ModInfoDialog::createDirectoryTriggered()
+{
+ QModelIndex selection = m_FileSelection.at(0);
- QModelIndex index = m_FileSystemModel->isDir(selection) ? selection : selection.parent();
- index = index.sibling(index.row(), 0);
+ QModelIndex index = m_FileSystemModel->isDir(selection) ? selection
+ : selection.parent();
+ index = index.sibling(index.row(), 0);
- QString name = tr("New Folder");
- QString path = m_FileSystemModel->filePath(index).append("/");
+ QString name = tr("New Folder");
+ QString path = m_FileSystemModel->filePath(index).append("/");
- QModelIndex existingIndex = m_FileSystemModel->index(path + name);
- int suffix = 1;
- while (existingIndex.isValid()) {
- name = tr("New Folder") + QString::number(suffix++);
- existingIndex = m_FileSystemModel->index(path + name);
- }
+ QModelIndex existingIndex = m_FileSystemModel->index(path + name);
+ int suffix = 1;
+ while (existingIndex.isValid()) {
+ name = tr("New Folder") + QString::number(suffix++);
+ existingIndex = m_FileSystemModel->index(path + name);
+ }
- QModelIndex newIndex = m_FileSystemModel->mkdir(index, name);
- if (!newIndex.isValid()) {
- reportError(tr("Failed to create \"%1\"").arg(name));
- return;
- }
+ QModelIndex newIndex = m_FileSystemModel->mkdir(index, name);
+ if (!newIndex.isValid()) {
+ reportError(tr("Failed to create \"%1\"").arg(name));
+ return;
+ }
- ui->fileTree->setCurrentIndex(newIndex);
- ui->fileTree->edit(newIndex);
+ ui->fileTree->setCurrentIndex(newIndex);
+ ui->fileTree->edit(newIndex);
}
-void ModInfoDialog::on_fileTree_customContextMenuRequested(const QPoint& pos) {
- QItemSelectionModel* selectionModel = ui->fileTree->selectionModel();
- m_FileSelection = selectionModel->selectedRows(0);
- // m_FileSelection = ui->fileTree->indexAt(pos);
- QMenu menu(ui->fileTree);
+void ModInfoDialog::on_fileTree_customContextMenuRequested(const QPoint &pos)
+{
+ QItemSelectionModel *selectionModel = ui->fileTree->selectionModel();
+ m_FileSelection = selectionModel->selectedRows(0);
+
+// m_FileSelection = ui->fileTree->indexAt(pos);
+ QMenu menu(ui->fileTree);
- menu.addAction(m_NewFolderAction);
+ menu.addAction(m_NewFolderAction);
- bool hasFiles = false;
+ bool hasFiles = false;
- foreach (QModelIndex idx, m_FileSelection) {
- if (m_FileSystemModel->fileInfo(idx).isFile()) {
- hasFiles = true;
- break;
- }
+ foreach(QModelIndex idx, m_FileSelection) {
+ if (m_FileSystemModel->fileInfo(idx).isFile()) {
+ hasFiles = true;
+ break;
}
+ }
- if (selectionModel->hasSelection()) {
- if (hasFiles) {
- menu.addAction(m_OpenAction);
- }
- menu.addAction(m_RenameAction);
- menu.addAction(m_DeleteAction);
- if (m_FileSystemModel->fileName(m_FileSelection.at(0)).endsWith(ModInfo::s_HiddenExt)) {
- menu.addAction(m_UnhideAction);
- } else {
- menu.addAction(m_HideAction);
- }
+ if (selectionModel->hasSelection()) {
+ if (hasFiles) {
+ menu.addAction(m_OpenAction);
+ }
+ menu.addAction(m_RenameAction);
+ menu.addAction(m_DeleteAction);
+ if (m_FileSystemModel->fileName(m_FileSelection.at(0)).endsWith(ModInfo::s_HiddenExt)) {
+ menu.addAction(m_UnhideAction);
} else {
- m_FileSelection.clear();
- m_FileSelection.append(m_FileSystemModel->index(m_FileSystemModel->rootPath(), 0));
+ menu.addAction(m_HideAction);
}
- menu.exec(ui->fileTree->mapToGlobal(pos));
+ } else {
+ m_FileSelection.clear();
+ m_FileSelection.append(m_FileSystemModel->index(m_FileSystemModel->rootPath(), 0));
+ }
+ menu.exec(ui->fileTree->mapToGlobal(pos));
}
-void ModInfoDialog::on_categoriesTree_itemChanged(QTreeWidgetItem* item, int) {
- QTreeWidgetItem* parent = item->parent();
- while ((parent != nullptr) && ((parent->flags() & Qt::ItemIsUserCheckable) != 0) &&
- (parent->checkState(0) == Qt::Unchecked)) {
- parent->setCheckState(0, Qt::Checked);
- parent = parent->parent();
- }
- refreshPrimaryCategoriesBox();
+
+void ModInfoDialog::on_categoriesTree_itemChanged(QTreeWidgetItem *item, int)
+{
+ QTreeWidgetItem *parent = item->parent();
+ while ((parent != nullptr) && ((parent->flags() & Qt::ItemIsUserCheckable) != 0) && (parent->checkState(0) == Qt::Unchecked)) {
+ parent->setCheckState(0, Qt::Checked);
+ parent = parent->parent();
+ }
+ refreshPrimaryCategoriesBox();
}
-void ModInfoDialog::addCheckedCategories(QTreeWidgetItem* tree) {
- for (int i = 0; i < tree->childCount(); ++i) {
- QTreeWidgetItem* child = tree->child(i);
- if (child->checkState(0) == Qt::Checked) {
- ui->primaryCategoryBox->addItem(child->text(0), child->data(0, Qt::UserRole));
- addCheckedCategories(child);
- }
+
+void ModInfoDialog::addCheckedCategories(QTreeWidgetItem *tree)
+{
+ for (int i = 0; i < tree->childCount(); ++i) {
+ QTreeWidgetItem *child = tree->child(i);
+ if (child->checkState(0) == Qt::Checked) {
+ ui->primaryCategoryBox->addItem(child->text(0), child->data(0, Qt::UserRole));
+ addCheckedCategories(child);
}
+ }
}
-void ModInfoDialog::refreshPrimaryCategoriesBox() {
- ui->primaryCategoryBox->clear();
- int primaryCategory = m_ModInfo->getPrimaryCategory();
- addCheckedCategories(ui->categoriesTree->invisibleRootItem());
- for (int i = 0; i < ui->primaryCategoryBox->count(); ++i) {
- if (ui->primaryCategoryBox->itemData(i).toInt() == primaryCategory) {
- ui->primaryCategoryBox->setCurrentIndex(i);
- break;
- }
+
+void ModInfoDialog::refreshPrimaryCategoriesBox()
+{
+ ui->primaryCategoryBox->clear();
+ int primaryCategory = m_ModInfo->getPrimaryCategory();
+ addCheckedCategories(ui->categoriesTree->invisibleRootItem());
+ for (int i = 0; i < ui->primaryCategoryBox->count(); ++i) {
+ if (ui->primaryCategoryBox->itemData(i).toInt() == primaryCategory) {
+ ui->primaryCategoryBox->setCurrentIndex(i);
+ break;
}
+ }
}
-void ModInfoDialog::on_primaryCategoryBox_currentIndexChanged(int index) {
- if (index != -1) {
- m_ModInfo->setPrimaryCategory(ui->primaryCategoryBox->itemData(index).toInt());
- }
+
+void ModInfoDialog::on_primaryCategoryBox_currentIndexChanged(int index)
+{
+ if (index != -1) {
+ m_ModInfo->setPrimaryCategory(ui->primaryCategoryBox->itemData(index).toInt());
+ }
}
-void ModInfoDialog::on_overwriteTree_itemDoubleClicked(QTreeWidgetItem* item, int) {
- this->close();
- emit modOpen(item->data(1, Qt::UserRole).toString(), TAB_CONFLICTS);
+
+void ModInfoDialog::on_overwriteTree_itemDoubleClicked(QTreeWidgetItem *item, int)
+{
+ this->close();
+ emit modOpen(item->data(1, Qt::UserRole).toString(), TAB_CONFLICTS);
}
-bool ModInfoDialog::hideFile(const QString& oldName) {
- QString newName = oldName + ModInfo::s_HiddenExt;
- if (QFileInfo(newName).exists()) {
- if (QMessageBox::question(this, tr("Replace file?"),
- tr("There already is a hidden version of this file. Replace it?"),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- if (!QFile(newName).remove()) {
- QMessageBox::critical(
- this, tr("File operation failed"),
- tr("Failed to remove \"%1\". Maybe you lack the required file permissions?").arg(newName));
- return false;
- }
- } else {
- return false;
- }
- }
+bool ModInfoDialog::hideFile(const QString &oldName)
+{
+ QString newName = oldName + ModInfo::s_HiddenExt;
- if (QFile::rename(oldName, newName)) {
- return true;
- } else {
- reportError(tr("failed to rename %1 to %2").arg(oldName).arg(QDir::toNativeSeparators(newName)));
+ if (QFileInfo(newName).exists()) {
+ if (QMessageBox::question(this, tr("Replace file?"), tr("There already is a hidden version of this file. Replace it?"),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ if (!QFile(newName).remove()) {
+ QMessageBox::critical(this, tr("File operation failed"), tr("Failed to remove \"%1\". Maybe you lack the required file permissions?").arg(newName));
return false;
+ }
+ } else {
+ return false;
}
+ }
+
+ if (QFile::rename(oldName, newName)) {
+ return true;
+ } else {
+ reportError(tr("failed to rename %1 to %2").arg(oldName).arg(QDir::toNativeSeparators(newName)));
+ return false;
+ }
}
-bool ModInfoDialog::unhideFile(const QString& oldName) {
- QString newName = oldName.left(oldName.length() - ModInfo::s_HiddenExt.length());
- if (QFileInfo(newName).exists()) {
- if (QMessageBox::question(this, tr("Replace file?"),
- tr("There already is a visible version of this file. Replace it?"),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- if (!QFile(newName).remove()) {
- QMessageBox::critical(
- this, tr("File operation failed"),
- tr("Failed to remove \"%1\". Maybe you lack the required file permissions?").arg(newName));
- return false;
- }
- } else {
- return false;
- }
- }
- if (QFile::rename(oldName, newName)) {
- return true;
- } else {
- reportError(tr("failed to rename %1 to %2")
- .arg(QDir::toNativeSeparators(oldName))
- .arg(QDir::toNativeSeparators(newName)));
+
+bool ModInfoDialog::unhideFile(const QString &oldName)
+{
+ QString newName = oldName.left(oldName.length() - ModInfo::s_HiddenExt.length());
+ if (QFileInfo(newName).exists()) {
+ if (QMessageBox::question(this, tr("Replace file?"), tr("There already is a visible version of this file. Replace it?"),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ if (!QFile(newName).remove()) {
+ QMessageBox::critical(this, tr("File operation failed"), tr("Failed to remove \"%1\". Maybe you lack the required file permissions?").arg(newName));
return false;
+ }
+ } else {
+ return false;
}
+ }
+ if (QFile::rename(oldName, newName)) {
+ return true;
+ } else {
+ reportError(tr("failed to rename %1 to %2").arg(QDir::toNativeSeparators(oldName)).arg(QDir::toNativeSeparators(newName)));
+ return false;
+ }
}
-void ModInfoDialog::hideConflictFile() {
- if (hideFile(m_ConflictsContextItem->data(0, Qt::UserRole).toString())) {
- emit originModified(m_Origin->getID());
- refreshLists();
- }
+
+void ModInfoDialog::hideConflictFile()
+{
+ if (hideFile(m_ConflictsContextItem->data(0, Qt::UserRole).toString())) {
+ emit originModified(m_Origin->getID());
+ refreshLists();
+ }
}
-void ModInfoDialog::unhideConflictFile() {
- if (unhideFile(m_ConflictsContextItem->data(0, Qt::UserRole).toString())) {
- emit originModified(m_Origin->getID());
- refreshLists();
- }
+
+void ModInfoDialog::unhideConflictFile()
+{
+ if (unhideFile(m_ConflictsContextItem->data(0, Qt::UserRole).toString())) {
+ emit originModified(m_Origin->getID());
+ refreshLists();
+ }
}
-void ModInfoDialog::on_overwriteTree_customContextMenuRequested(const QPoint& pos) {
- m_ConflictsContextItem = ui->overwriteTree->itemAt(pos.x(), pos.y());
- if (m_ConflictsContextItem != nullptr) {
- // offer to hide/unhide file, but not for files from archives
- if (!m_ConflictsContextItem->data(1, Qt::UserRole + 2).toBool()) {
- QMenu menu;
- if (m_ConflictsContextItem->text(0).endsWith(ModInfo::s_HiddenExt)) {
- menu.addAction(tr("Un-Hide"), this, SLOT(unhideConflictFile()));
- } else {
- menu.addAction(tr("Hide"), this, SLOT(hideConflictFile()));
- }
- menu.exec(ui->overwriteTree->mapToGlobal(pos));
- }
+void ModInfoDialog::on_overwriteTree_customContextMenuRequested(const QPoint &pos)
+{
+ m_ConflictsContextItem = ui->overwriteTree->itemAt(pos.x(), pos.y());
+
+ if (m_ConflictsContextItem != nullptr) {
+ // offer to hide/unhide file, but not for files from archives
+ if (!m_ConflictsContextItem->data(1, Qt::UserRole + 2).toBool()) {
+ QMenu menu;
+ if (m_ConflictsContextItem->text(0).endsWith(ModInfo::s_HiddenExt)) {
+ menu.addAction(tr("Un-Hide"), this, SLOT(unhideConflictFile()));
+ } else {
+ menu.addAction(tr("Hide"), this, SLOT(hideConflictFile()));
+ }
+ menu.exec(ui->overwriteTree->mapToGlobal(pos));
}
+ }
}
-void ModInfoDialog::on_overwrittenTree_itemDoubleClicked(QTreeWidgetItem* item, int) {
- emit modOpen(item->data(1, Qt::UserRole).toString(), TAB_CONFLICTS);
- this->accept();
+
+void ModInfoDialog::on_overwrittenTree_itemDoubleClicked(QTreeWidgetItem *item, int)
+{
+ emit modOpen(item->data(1, Qt::UserRole).toString(), TAB_CONFLICTS);
+ this->accept();
}
-void ModInfoDialog::on_refreshButton_clicked() {
- m_ModInfo->updateNXMInfo();
+void ModInfoDialog::on_refreshButton_clicked()
+{
+ m_ModInfo->updateNXMInfo();
- MessageDialog::showMessage(tr("Info requested, please wait"), this);
+ MessageDialog::showMessage(tr("Info requested, please wait"), this);
}
-void ModInfoDialog::on_endorseBtn_clicked() { emit endorseMod(m_ModInfo); }
+void ModInfoDialog::on_endorseBtn_clicked()
+{
+ emit endorseMod(m_ModInfo);
+}
-void ModInfoDialog::on_nextButton_clicked() {
- emit modOpenNext();
- this->accept();
+void ModInfoDialog::on_nextButton_clicked()
+{
+ emit modOpenNext();
+ this->accept();
}
-void ModInfoDialog::on_prevButton_clicked() {
- emit modOpenPrev();
- this->accept();
+void ModInfoDialog::on_prevButton_clicked()
+{
+ emit modOpenPrev();
+ this->accept();
}
-void ModInfoDialog::createTweak() {
- QString name = QInputDialog::getText(this, tr("Name"), tr("Please enter a name"));
- if (name.isNull()) {
- return;
- } else if (!fixDirectoryName(name)) {
- QMessageBox::critical(this, tr("Error"), tr("Invalid name. Must be a valid file name"));
- return;
- } else if (ui->iniTweaksList->findItems(name, Qt::MatchFixedString).count() != 0) {
- QMessageBox::critical(this, tr("Error"), tr("A tweak by that name exists"));
- return;
- }
- QListWidgetItem* newTweak = new QListWidgetItem(name + ".ini");
- newTweak->setData(Qt::UserRole, "INI Tweaks/" + name + ".ini");
- newTweak->setFlags(newTweak->flags() | Qt::ItemIsUserCheckable);
- newTweak->setCheckState(Qt::Unchecked);
- ui->iniTweaksList->addItem(newTweak);
+void ModInfoDialog::createTweak()
+{
+ QString name = QInputDialog::getText(this, tr("Name"), tr("Please enter a name"));
+ if (name.isNull()) {
+ return;
+ } else if (!fixDirectoryName(name)) {
+ QMessageBox::critical(this, tr("Error"), tr("Invalid name. Must be a valid file name"));
+ return;
+ } else if (ui->iniTweaksList->findItems(name, Qt::MatchFixedString).count() != 0) {
+ QMessageBox::critical(this, tr("Error"), tr("A tweak by that name exists"));
+ return;
+ }
+
+ QListWidgetItem *newTweak = new QListWidgetItem(name + ".ini");
+ newTweak->setData(Qt::UserRole, "INI Tweaks/" + name + ".ini");
+ newTweak->setFlags(newTweak->flags() | Qt::ItemIsUserCheckable);
+ newTweak->setCheckState(Qt::Unchecked);
+ ui->iniTweaksList->addItem(newTweak);
}
-void ModInfoDialog::on_iniTweaksList_customContextMenuRequested(const QPoint& pos) {
- QMenu menu;
- menu.addAction(tr("Create Tweak"), this, SLOT(createTweak()));
- menu.exec(ui->iniTweaksList->mapToGlobal(pos));
+void ModInfoDialog::on_iniTweaksList_customContextMenuRequested(const QPoint &pos)
+{
+ QMenu menu;
+ menu.addAction(tr("Create Tweak"), this, SLOT(createTweak()));
+ menu.exec(ui->iniTweaksList->mapToGlobal(pos));
}
diff --git a/src/modinfodialog.h b/src/modinfodialog.h
index 514ef331..312ff99e 100644
--- a/src/modinfodialog.h
+++ b/src/modinfodialog.h
@@ -20,24 +20,26 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef MODINFODIALOG_H
#define MODINFODIALOG_H
+
#include "modinfo.h"
#include "tutorabledialog.h"
-#include <QAction>
#include <QDialog>
-#include <QListWidgetItem>
-#include <QModelIndex>
+#include <QSignalMapper>
+#include <QSettings>
#include <QNetworkAccessManager>
#include <QNetworkReply>
-#include <QSettings>
-#include <QSignalMapper>
-#include <QTextCodec>
+#include <QModelIndex>
+#include <QAction>
+#include <QListWidgetItem>
#include <QTreeWidgetItem>
-#include <directoryentry.h>
+#include <QTextCodec>
#include <set>
+#include <directoryentry.h>
+
namespace Ui {
-class ModInfoDialog;
+ class ModInfoDialog;
}
class QFileSystemModel;
@@ -48,184 +50,187 @@ class CategoryFactory;
* this is a larger dialog used to visualise information abount the mod.
* @todo this would probably a good place for a plugin-system
**/
-class ModInfoDialog : public MOBase::TutorableDialog {
+class ModInfoDialog : public MOBase::TutorableDialog
+{
Q_OBJECT
public:
- enum ETabs {
- TAB_TEXTFILES,
- TAB_INIFILES,
- TAB_IMAGES,
- TAB_ESPS,
- TAB_CONFLICTS,
- TAB_CATEGORIES,
- TAB_NEXUS,
- TAB_NOTES,
- TAB_FILETREE
- };
+
+ enum ETabs {
+ TAB_TEXTFILES,
+ TAB_INIFILES,
+ TAB_IMAGES,
+ TAB_ESPS,
+ TAB_CONFLICTS,
+ TAB_CATEGORIES,
+ TAB_NEXUS,
+ TAB_NOTES,
+ TAB_FILETREE
+ };
public:
- /**
- * @brief constructor
- *
- * @param modInfo info structure about the mod to display
- * @param parent parend widget
- **/
- explicit ModInfoDialog(ModInfo::Ptr modInfo, const MOShared::DirectoryEntry* directory, bool unmanaged,
- QWidget* parent = 0);
- ~ModInfoDialog();
- /**
- * @brief retrieve the (user-modified) version of the mod
- *
- * @return the (user-modified) version of the mod
- **/
- QString getModVersion() const;
+ /**
+ * @brief constructor
+ *
+ * @param modInfo info structure about the mod to display
+ * @param parent parend widget
+ **/
+ explicit ModInfoDialog(ModInfo::Ptr modInfo, const MOShared::DirectoryEntry *directory, bool unmanaged, QWidget *parent = 0);
+ ~ModInfoDialog();
- /**
- * @brief retrieve the (user-modified) mod id
- *
- * @return the (user-modified) id of the mod
- **/
- const int getModID() const;
+ /**
+ * @brief retrieve the (user-modified) version of the mod
+ *
+ * @return the (user-modified) version of the mod
+ **/
+ QString getModVersion() const;
- /**
- * @brief open the specified tab in the dialog if it's enabled
- *
- * @param tab the tab to activate
- **/
- void openTab(int tab);
+ /**
+ * @brief retrieve the (user-modified) mod id
+ *
+ * @return the (user-modified) id of the mod
+ **/
+ const int getModID() const;
- void restoreTabState(const QByteArray& state);
+ /**
+ * @brief open the specified tab in the dialog if it's enabled
+ *
+ * @param tab the tab to activate
+ **/
+ void openTab(int tab);
- QByteArray saveTabState() const;
+ void restoreTabState(const QByteArray &state);
+
+ QByteArray saveTabState() const;
signals:
- void thumbnailClickedSignal(const QString& filename);
- void nexusLinkActivated(const QString& link);
- void downloadRequest(const QString& link);
- void modOpen(const QString& modName, int tab);
- void modOpenNext();
- void modOpenPrev();
- void originModified(int originID);
- void endorseMod(ModInfo::Ptr nexusID);
+ void thumbnailClickedSignal(const QString &filename);
+ void nexusLinkActivated(const QString &link);
+ void downloadRequest(const QString &link);
+ void modOpen(const QString &modName, int tab);
+ void modOpenNext();
+ void modOpenPrev();
+ void originModified(int originID);
+ void endorseMod(ModInfo::Ptr nexusID);
public slots:
- void modDetailsUpdated(bool success);
+ void modDetailsUpdated(bool success);
private:
- void initFiletree(ModInfo::Ptr modInfo);
- void initINITweaks();
- void refreshLists();
+ void initFiletree(ModInfo::Ptr modInfo);
+ void initINITweaks();
- void addCategories(const CategoryFactory& factory, const std::set<int>& enabledCategories, QTreeWidgetItem* root,
- int rootLevel);
+ void refreshLists();
- void updateVersionColor();
+ void addCategories(const CategoryFactory &factory, const std::set<int> &enabledCategories, QTreeWidgetItem *root, int rootLevel);
- void refreshNexusData(int modID);
- void activateNexusTab();
- QString getFileCategory(int categoryID);
- bool recursiveDelete(const QModelIndex& index);
- void deleteFile(const QModelIndex& index);
- void openFile(const QModelIndex& index);
- void saveIniTweaks();
- void saveCategories(QTreeWidgetItem* currentNode);
- void saveCurrentTextFile();
- void saveCurrentIniFile();
- void openTextFile(const QString& fileName);
- void openIniFile(const QString& fileName);
- bool allowNavigateFromTXT();
- bool allowNavigateFromINI();
- bool hideFile(const QString& oldName);
- bool unhideFile(const QString& oldName);
- void addCheckedCategories(QTreeWidgetItem* tree);
- void refreshPrimaryCategoriesBox();
+ void updateVersionColor();
- int tabIndex(const QString& tabId);
+ void refreshNexusData(int modID);
+ void activateNexusTab();
+ QString getFileCategory(int categoryID);
+ bool recursiveDelete(const QModelIndex &index);
+ void deleteFile(const QModelIndex &index);
+ void openFile(const QModelIndex &index);
+ void saveIniTweaks();
+ void saveCategories(QTreeWidgetItem *currentNode);
+ void saveCurrentTextFile();
+ void saveCurrentIniFile();
+ void openTextFile(const QString &fileName);
+ void openIniFile(const QString &fileName);
+ bool allowNavigateFromTXT();
+ bool allowNavigateFromINI();
+ bool hideFile(const QString &oldName);
+ bool unhideFile(const QString &oldName);
+ void addCheckedCategories(QTreeWidgetItem *tree);
+ void refreshPrimaryCategoriesBox();
-private slots:
+ int tabIndex(const QString &tabId);
- void hideConflictFile();
- void unhideConflictFile();
+private slots:
- void thumbnailClicked(const QString& fileName);
- void linkClicked(const QUrl& url);
+ void hideConflictFile();
+ void unhideConflictFile();
- void deleteTriggered();
- void renameTriggered();
- void openTriggered();
- void createDirectoryTriggered();
- void hideTriggered();
- void unhideTriggered();
+ void thumbnailClicked(const QString &fileName);
+ void linkClicked(const QUrl &url);
- void on_closeButton_clicked();
- void on_saveButton_clicked();
- void on_activateESP_clicked();
- void on_deactivateESP_clicked();
- void on_saveTXTButton_clicked();
- void on_visitNexusLabel_linkActivated(const QString& link);
- void on_modIDEdit_editingFinished();
- void on_versionEdit_editingFinished();
- void on_iniFileView_textChanged();
- void on_textFileView_textChanged();
- void on_tabWidget_currentChanged(int index);
- void on_primaryCategoryBox_currentIndexChanged(int index);
- void on_categoriesTree_itemChanged(QTreeWidgetItem* item, int column);
- void on_textFileList_currentItemChanged(QListWidgetItem* current, QListWidgetItem* previous);
- void on_iniFileList_currentItemChanged(QListWidgetItem* current, QListWidgetItem* previous);
- void on_iniTweaksList_currentItemChanged(QListWidgetItem* current, QListWidgetItem* previous);
- void on_overwriteTree_itemDoubleClicked(QTreeWidgetItem* item, int column);
- void on_overwrittenTree_itemDoubleClicked(QTreeWidgetItem* item, int column);
- void on_overwriteTree_customContextMenuRequested(const QPoint& pos);
- void on_fileTree_customContextMenuRequested(const QPoint& pos);
+ void deleteTriggered();
+ void renameTriggered();
+ void openTriggered();
+ void createDirectoryTriggered();
+ void hideTriggered();
+ void unhideTriggered();
- void on_refreshButton_clicked();
+ void on_closeButton_clicked();
+ void on_saveButton_clicked();
+ void on_activateESP_clicked();
+ void on_deactivateESP_clicked();
+ void on_saveTXTButton_clicked();
+ void on_visitNexusLabel_linkActivated(const QString &link);
+ void on_modIDEdit_editingFinished();
+ void on_versionEdit_editingFinished();
+ void on_iniFileView_textChanged();
+ void on_textFileView_textChanged();
+ void on_tabWidget_currentChanged(int index);
+ void on_primaryCategoryBox_currentIndexChanged(int index);
+ void on_categoriesTree_itemChanged(QTreeWidgetItem *item, int column);
+ void on_textFileList_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous);
+ void on_iniFileList_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous);
+ void on_iniTweaksList_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous);
+ void on_overwriteTree_itemDoubleClicked(QTreeWidgetItem *item, int column);
+ void on_overwrittenTree_itemDoubleClicked(QTreeWidgetItem *item, int column);
+ void on_overwriteTree_customContextMenuRequested(const QPoint &pos);
+ void on_fileTree_customContextMenuRequested(const QPoint &pos);
- void on_endorseBtn_clicked();
+ void on_refreshButton_clicked();
- void on_nextButton_clicked();
+ void on_endorseBtn_clicked();
- void on_prevButton_clicked();
+ void on_nextButton_clicked();
- void on_iniTweaksList_customContextMenuRequested(const QPoint& pos);
+ void on_prevButton_clicked();
- void createTweak();
+ void on_iniTweaksList_customContextMenuRequested(const QPoint &pos);
+ void createTweak();
private:
- Ui::ModInfoDialog* ui;
- ModInfo::Ptr m_ModInfo;
- int m_OriginID;
+ Ui::ModInfoDialog *ui;
+
+ ModInfo::Ptr m_ModInfo;
+ int m_OriginID;
+
+ QSignalMapper m_ThumbnailMapper;
+ QString m_RootPath;
- QSignalMapper m_ThumbnailMapper;
- QString m_RootPath;
+ QFileSystemModel *m_FileSystemModel;
+ QTreeView *m_FileTree;
+ QModelIndexList m_FileSelection;
- QFileSystemModel* m_FileSystemModel;
- QTreeView* m_FileTree;
- QModelIndexList m_FileSelection;
+ QSettings *m_Settings;
- QSettings* m_Settings;
+ std::set<int> m_RequestIDs;
+ bool m_RequestStarted;
- std::set<int> m_RequestIDs;
- bool m_RequestStarted;
+ QAction *m_DeleteAction;
+ QAction *m_RenameAction;
+ QAction *m_OpenAction;
+ QAction *m_NewFolderAction;
+ QAction *m_HideAction;
+ QAction *m_UnhideAction;
- QAction* m_DeleteAction;
- QAction* m_RenameAction;
- QAction* m_OpenAction;
- QAction* m_NewFolderAction;
- QAction* m_HideAction;
- QAction* m_UnhideAction;
+ QTreeWidgetItem *m_ConflictsContextItem;
- QTreeWidgetItem* m_ConflictsContextItem;
+ const MOShared::DirectoryEntry *m_Directory;
+ MOShared::FilesOrigin *m_Origin;
- const MOShared::DirectoryEntry* m_Directory;
- MOShared::FilesOrigin* m_Origin;
+ std::map<int, int> m_RealTabPos;
- std::map<int, int> m_RealTabPos;
};
#endif // MODINFODIALOG_H
diff --git a/src/modinfoforeign.cpp b/src/modinfoforeign.cpp
index 187ae576..0bde2c30 100644
--- a/src/modinfoforeign.cpp
+++ b/src/modinfoforeign.cpp
@@ -8,47 +8,61 @@
using namespace MOBase;
using namespace MOShared;
-QString ModInfoForeign::name() const { return m_Name; }
+QString ModInfoForeign::name() const
+{
+ return m_Name;
+}
-QDateTime ModInfoForeign::creationTime() const { return m_CreationTime; }
+QDateTime ModInfoForeign::creationTime() const
+{
+ return m_CreationTime;
+}
-QString ModInfoForeign::absolutePath() const {
- // I ought to store this, it's used elsewhere
- IPluginGame const* game = qApp->property("managed_game").value<IPluginGame*>();
- return game->dataDirectory().absolutePath();
+QString ModInfoForeign::absolutePath() const
+{
+ //I ought to store this, it's used elsewhere
+ IPluginGame const *game = qApp->property("managed_game").value<IPluginGame *>();
+ return game->dataDirectory().absolutePath();
}
-std::vector<ModInfo::EFlag> ModInfoForeign::getFlags() const {
- std::vector<ModInfo::EFlag> result = ModInfoWithConflictInfo::getFlags();
- result.push_back(FLAG_FOREIGN);
+std::vector<ModInfo::EFlag> ModInfoForeign::getFlags() const
+{
+ std::vector<ModInfo::EFlag> result = ModInfoWithConflictInfo::getFlags();
+ result.push_back(FLAG_FOREIGN);
- if (m_PluginSelected) {
- result.push_back(ModInfo::FLAG_PLUGIN_SELECTED);
- }
+ if (m_PluginSelected) {
+ result.push_back(ModInfo::FLAG_PLUGIN_SELECTED);
+ }
- return result;
+ return result;
}
-int ModInfoForeign::getHighlight() const {
- return m_PluginSelected ? ModInfo::HIGHLIGHT_PLUGIN : ModInfo::HIGHLIGHT_NONE;
+int ModInfoForeign::getHighlight() const
+{
+ return m_PluginSelected ? ModInfo::HIGHLIGHT_PLUGIN : ModInfo::HIGHLIGHT_NONE;
}
-QString ModInfoForeign::getDescription() const {
- return tr("This pseudo mod represents content managed outside MO. It isn't modified by MO.");
+QString ModInfoForeign::getDescription() const
+{
+ return tr("This pseudo mod represents content managed outside MO. It isn't modified by MO.");
}
-ModInfoForeign::ModInfoForeign(const QString& modName, const QString& referenceFile, const QStringList& archives,
- ModInfo::EModType modType, DirectoryEntry** directoryStructure)
- : ModInfoWithConflictInfo(directoryStructure), m_ReferenceFile(referenceFile), m_Archives(archives) {
- m_CreationTime = QFileInfo(referenceFile).created();
- switch (modType) {
- case ModInfo::EModType::MOD_DLC:
- m_Name = "DLC: " + modName;
- break;
- case ModInfo::EModType::MOD_CC:
- m_Name = "Creation Club: " + modName;
- break;
- default:
- m_Name = "Unmanaged: " + modName;
- }
+ModInfoForeign::ModInfoForeign(const QString &modName,
+ const QString &referenceFile,
+ const QStringList &archives,
+ ModInfo::EModType modType,
+ DirectoryEntry **directoryStructure)
+ : ModInfoWithConflictInfo(directoryStructure),
+ m_ReferenceFile(referenceFile), m_Archives(archives) {
+ m_CreationTime = QFileInfo(referenceFile).created();
+ switch (modType) {
+ case ModInfo::EModType::MOD_DLC:
+ m_Name = "DLC: " + modName;
+ break;
+ case ModInfo::EModType::MOD_CC:
+ m_Name = "Creation Club: " + modName;
+ break;
+ default:
+ m_Name = "Unmanaged: " + modName;
+ }
}
diff --git a/src/modinfoforeign.h b/src/modinfoforeign.h
index c7d50365..d60064f0 100644
--- a/src/modinfoforeign.h
+++ b/src/modinfoforeign.h
@@ -3,61 +3,65 @@
#include "modinfowithconflictinfo.h"
-class ModInfoForeign : public ModInfoWithConflictInfo {
+class ModInfoForeign : public ModInfoWithConflictInfo
+{
- Q_OBJECT
+ Q_OBJECT
- friend class ModInfo;
+ friend class ModInfo;
public:
- virtual bool updateAvailable() const { return false; }
- virtual bool updateIgnored() const { return false; }
- virtual bool downgradeAvailable() const { return false; }
- virtual bool updateNXMInfo() { return false; }
- virtual void setCategory(int, bool) {}
- virtual bool setName(const QString&) { return false; }
- virtual void setNotes(const QString&) {}
- virtual void setNexusID(int) {}
- virtual void setNewestVersion(const MOBase::VersionInfo&) {}
- virtual void ignoreUpdate(bool) {}
- virtual void setNexusDescription(const QString&) {}
- virtual void setInstallationFile(const QString&) {}
- virtual void addNexusCategory(int) {}
- virtual void setIsEndorsed(bool) {}
- virtual void setNeverEndorse() {}
- virtual bool remove() { return false; }
- virtual void endorse(bool) {}
- virtual bool isEmpty() const { return false; }
- virtual QString name() const;
- virtual QString internalName() const { return name(); }
- virtual QString notes() const { return ""; }
- virtual QDateTime creationTime() const;
- virtual QString absolutePath() const;
- virtual MOBase::VersionInfo getNewestVersion() const { return QString(); }
- virtual QString getInstallationFile() const { return ""; }
- virtual int getNexusID() const { return -1; }
- virtual std::vector<QString> getIniTweaks() const { return std::vector<QString>(); }
- virtual std::vector<ModInfo::EFlag> getFlags() const;
- virtual int getHighlight() const;
- virtual QString getDescription() const;
- virtual QDateTime getLastNexusQuery() const { return QDateTime(); }
- virtual QString getNexusDescription() const { return QString(); }
- virtual int getFixedPriority() const { return INT_MIN; }
- virtual QStringList archives() const { return m_Archives; }
- virtual QStringList stealFiles() const { return m_Archives + QStringList(m_ReferenceFile); }
- virtual bool alwaysEnabled() const { return true; }
- virtual void addInstalledFile(int, int) {}
-protected:
- ModInfoForeign(const QString& modName, const QString& referenceFile, const QStringList& archives,
- ModInfo::EModType modType, MOShared::DirectoryEntry** directoryStructure);
+ virtual bool updateAvailable() const { return false; }
+ virtual bool updateIgnored() const { return false; }
+ virtual bool downgradeAvailable() const { return false; }
+ virtual bool updateNXMInfo() { return false; }
+ virtual void setCategory(int, bool) {}
+ virtual bool setName(const QString&) { return false; }
+ virtual void setNotes(const QString&) {}
+ virtual void setNexusID(int) {}
+ virtual void setNewestVersion(const MOBase::VersionInfo&) {}
+ virtual void ignoreUpdate(bool) {}
+ virtual void setNexusDescription(const QString&) {}
+ virtual void setInstallationFile(const QString&) {}
+ virtual void addNexusCategory(int) {}
+ virtual void setIsEndorsed(bool) {}
+ virtual void setNeverEndorse() {}
+ virtual bool remove() { return false; }
+ virtual void endorse(bool) {}
+ virtual bool isEmpty() const { return false; }
+ virtual QString name() const;
+ virtual QString internalName() const { return name(); }
+ virtual QString notes() const { return ""; }
+ virtual QDateTime creationTime() const;
+ virtual QString absolutePath() const;
+ virtual MOBase::VersionInfo getNewestVersion() const { return QString(); }
+ virtual QString getInstallationFile() const { return ""; }
+ virtual int getNexusID() const { return -1; }
+ virtual std::vector<QString> getIniTweaks() const { return std::vector<QString>(); }
+ virtual std::vector<ModInfo::EFlag> getFlags() const;
+ virtual int getHighlight() const;
+ virtual QString getDescription() const;
+ virtual QDateTime getLastNexusQuery() const { return QDateTime(); }
+ virtual QString getNexusDescription() const { return QString(); }
+ virtual int getFixedPriority() const { return INT_MIN; }
+ virtual QStringList archives() const { return m_Archives; }
+ virtual QStringList stealFiles() const { return m_Archives + QStringList(m_ReferenceFile); }
+ virtual bool alwaysEnabled() const { return true; }
+ virtual void addInstalledFile(int, int) {}
+protected:
+ ModInfoForeign(const QString &modName, const QString &referenceFile,
+ const QStringList &archives, ModInfo::EModType modType,
+ MOShared::DirectoryEntry **directoryStructure);
private:
- QString m_Name;
- QString m_ReferenceFile;
- QStringList m_Archives;
- QDateTime m_CreationTime;
- int m_Priority;
+
+ QString m_Name;
+ QString m_ReferenceFile;
+ QStringList m_Archives;
+ QDateTime m_CreationTime;
+ int m_Priority;
+
};
#endif // MODINFOFOREIGN_H
diff --git a/src/modinfooverwrite.cpp b/src/modinfooverwrite.cpp
index c02211be..360212c0 100644
--- a/src/modinfooverwrite.cpp
+++ b/src/modinfooverwrite.cpp
@@ -6,46 +6,55 @@
#include <QApplication>
#include <QDirIterator>
-ModInfoOverwrite::ModInfoOverwrite() { testValid(); }
+ModInfoOverwrite::ModInfoOverwrite()
+{
+ testValid();
+}
-bool ModInfoOverwrite::isEmpty() const {
- QDirIterator iter(absolutePath(), QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs);
- if (!iter.hasNext())
- return true;
- iter.next();
- if ((iter.fileName() == "meta.ini") && !iter.hasNext())
- return true;
- return false;
+bool ModInfoOverwrite::isEmpty() const
+{
+ QDirIterator iter(absolutePath(), QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs);
+ if (!iter.hasNext()) return true;
+ iter.next();
+ if ((iter.fileName() == "meta.ini") && !iter.hasNext()) return true;
+ return false;
}
-QString ModInfoOverwrite::absolutePath() const { return Settings::instance().getOverwriteDirectory(); }
+QString ModInfoOverwrite::absolutePath() const
+{
+ return Settings::instance().getOverwriteDirectory();
+}
-std::vector<ModInfo::EFlag> ModInfoOverwrite::getFlags() const {
- std::vector<ModInfo::EFlag> result;
- result.push_back(FLAG_OVERWRITE);
- if (m_PluginSelected)
- result.push_back(FLAG_PLUGIN_SELECTED);
- return result;
+std::vector<ModInfo::EFlag> ModInfoOverwrite::getFlags() const
+{
+ std::vector<ModInfo::EFlag> result;
+ result.push_back(FLAG_OVERWRITE);
+ if (m_PluginSelected)
+ result.push_back(FLAG_PLUGIN_SELECTED);
+ return result;
}
-int ModInfoOverwrite::getHighlight() const {
- int highlight = (isValid() ? HIGHLIGHT_IMPORTANT : HIGHLIGHT_INVALID) | HIGHLIGHT_CENTER;
- auto flags = getFlags();
- if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_PLUGIN_SELECTED) != flags.end())
- highlight |= HIGHLIGHT_PLUGIN;
- return highlight;
+int ModInfoOverwrite::getHighlight() const
+{
+ int highlight = (isValid() ? HIGHLIGHT_IMPORTANT : HIGHLIGHT_INVALID) | HIGHLIGHT_CENTER;
+ auto flags = getFlags();
+ if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_PLUGIN_SELECTED) != flags.end())
+ highlight |= HIGHLIGHT_PLUGIN;
+ return highlight;
}
-QString ModInfoOverwrite::getDescription() const {
- return tr("This pseudo mod contains files from the virtual data tree that got "
- "modified (i.e. by the construction kit)");
+QString ModInfoOverwrite::getDescription() const
+{
+ return tr("This pseudo mod contains files from the virtual data tree that got "
+ "modified (i.e. by the construction kit)");
}
-QStringList ModInfoOverwrite::archives() const {
- QStringList result;
- QDir dir(this->absolutePath());
- for (const QString& archive : dir.entryList(QStringList({"*.bsa", "*.ba2"}))) {
- result.append(this->absolutePath() + "/" + archive);
- }
- return result;
+QStringList ModInfoOverwrite::archives() const
+{
+ QStringList result;
+ QDir dir(this->absolutePath());
+ for (const QString &archive : dir.entryList(QStringList({ "*.bsa", "*.ba2" }))) {
+ result.append(this->absolutePath() + "/" + archive);
+ }
+ return result;
}
diff --git a/src/modinfooverwrite.h b/src/modinfooverwrite.h
index 276e5b6e..b6cdfb43 100644
--- a/src/modinfooverwrite.h
+++ b/src/modinfooverwrite.h
@@ -5,51 +5,55 @@
#include <QDateTime>
-class ModInfoOverwrite : public ModInfo {
+class ModInfoOverwrite : public ModInfo
+{
- Q_OBJECT
+ Q_OBJECT
- friend class ModInfo;
+ friend class ModInfo;
public:
- virtual bool updateAvailable() const { return false; }
- virtual bool updateIgnored() const { return false; }
- virtual bool downgradeAvailable() const { return false; }
- virtual bool updateNXMInfo() { return false; }
- virtual void setCategory(int, bool) {}
- virtual bool setName(const QString&) { return false; }
- virtual void setNotes(const QString&) {}
- virtual void setNexusID(int) {}
- virtual void setNewestVersion(const MOBase::VersionInfo&) {}
- virtual void ignoreUpdate(bool) {}
- virtual void setNexusDescription(const QString&) {}
- virtual void setInstallationFile(const QString&) {}
- virtual void addNexusCategory(int) {}
- virtual void setIsEndorsed(bool) {}
- virtual void setNeverEndorse() {}
- virtual bool remove() { return false; }
- virtual void endorse(bool) {}
- virtual bool alwaysEnabled() const { return true; }
- virtual bool isEmpty() const;
- virtual QString name() const { return "Overwrite"; }
- virtual QString notes() const { return ""; }
- virtual QDateTime creationTime() const { return QDateTime(); }
- virtual QString absolutePath() const;
- virtual MOBase::VersionInfo getNewestVersion() const { return QString(); }
- virtual QString getInstallationFile() const { return ""; }
- virtual int getFixedPriority() const { return INT_MAX; }
- virtual int getNexusID() const { return -1; }
- virtual std::vector<QString> getIniTweaks() const { return std::vector<QString>(); }
- virtual std::vector<ModInfo::EFlag> getFlags() const;
- virtual int getHighlight() const;
- virtual QString getDescription() const;
- virtual QDateTime getLastNexusQuery() const { return QDateTime(); }
- virtual QString getNexusDescription() const { return QString(); }
- virtual QStringList archives() const;
- virtual void addInstalledFile(int, int) {}
+
+ virtual bool updateAvailable() const { return false; }
+ virtual bool updateIgnored() const { return false; }
+ virtual bool downgradeAvailable() const { return false; }
+ virtual bool updateNXMInfo() { return false; }
+ virtual void setCategory(int, bool) {}
+ virtual bool setName(const QString&) { return false; }
+ virtual void setNotes(const QString&) {}
+ virtual void setNexusID(int) {}
+ virtual void setNewestVersion(const MOBase::VersionInfo&) {}
+ virtual void ignoreUpdate(bool) {}
+ virtual void setNexusDescription(const QString&) {}
+ virtual void setInstallationFile(const QString&) {}
+ virtual void addNexusCategory(int) {}
+ virtual void setIsEndorsed(bool) {}
+ virtual void setNeverEndorse() {}
+ virtual bool remove() { return false; }
+ virtual void endorse(bool) {}
+ virtual bool alwaysEnabled() const { return true; }
+ virtual bool isEmpty() const;
+ virtual QString name() const { return "Overwrite"; }
+ virtual QString notes() const { return ""; }
+ virtual QDateTime creationTime() const { return QDateTime(); }
+ virtual QString absolutePath() const;
+ virtual MOBase::VersionInfo getNewestVersion() const { return QString(); }
+ virtual QString getInstallationFile() const { return ""; }
+ virtual int getFixedPriority() const { return INT_MAX; }
+ virtual int getNexusID() const { return -1; }
+ virtual std::vector<QString> getIniTweaks() const { return std::vector<QString>(); }
+ virtual std::vector<ModInfo::EFlag> getFlags() const;
+ virtual int getHighlight() const;
+ virtual QString getDescription() const;
+ virtual QDateTime getLastNexusQuery() const { return QDateTime(); }
+ virtual QString getNexusDescription() const { return QString(); }
+ virtual QStringList archives() const;
+ virtual void addInstalledFile(int, int) {}
private:
- ModInfoOverwrite();
+
+ ModInfoOverwrite();
+
};
#endif // MODINFOOVERWRITE_H
diff --git a/src/modinforegular.cpp b/src/modinforegular.cpp
index b3b0c2a6..5486bb2c 100644
--- a/src/modinforegular.cpp
+++ b/src/modinforegular.cpp
@@ -16,500 +16,572 @@ using namespace MOBase;
using namespace MOShared;
namespace {
-// Arguably this should be a class static or we should be using FileString rather
-// than QString for the names. Or both.
-static bool ByName(const ModInfo::Ptr& LHS, const ModInfo::Ptr& RHS) {
+ //Arguably this should be a class static or we should be using FileString rather
+ //than QString for the names. Or both.
+ static bool ByName(const ModInfo::Ptr &LHS, const ModInfo::Ptr &RHS)
+ {
return QString::compare(LHS->name(), RHS->name(), Qt::CaseInsensitive) < 0;
+ }
}
-} // namespace
-ModInfoRegular::ModInfoRegular(const QDir& path, DirectoryEntry** directoryStructure)
- : ModInfoWithConflictInfo(directoryStructure), m_Name(path.dirName()), m_Path(path.absolutePath()), m_Repository(),
- m_MetaInfoChanged(false), m_EndorsedState(ENDORSED_UNKNOWN), m_NexusBridge() {
- testValid();
- m_CreationTime = QFileInfo(path.absolutePath()).created();
- // read out the meta-file for information
- readMeta();
+ModInfoRegular::ModInfoRegular(const QDir &path, DirectoryEntry **directoryStructure)
+ : ModInfoWithConflictInfo(directoryStructure)
+ , m_Name(path.dirName())
+ , m_Path(path.absolutePath())
+ , m_Repository()
+ , m_MetaInfoChanged(false)
+ , m_EndorsedState(ENDORSED_UNKNOWN)
+ , m_NexusBridge()
+{
+ testValid();
+ m_CreationTime = QFileInfo(path.absolutePath()).created();
+ // read out the meta-file for information
+ readMeta();
- connect(&m_NexusBridge, SIGNAL(descriptionAvailable(int, QVariant, QVariant)), this,
- SLOT(nxmDescriptionAvailable(int, QVariant, QVariant)));
- connect(&m_NexusBridge, SIGNAL(endorsementToggled(int, QVariant, QVariant)), this,
- SLOT(nxmEndorsementToggled(int, QVariant, QVariant)));
- connect(&m_NexusBridge, SIGNAL(requestFailed(int, int, QVariant, QString)), this,
- SLOT(nxmRequestFailed(int, int, QVariant, QString)));
+ connect(&m_NexusBridge, SIGNAL(descriptionAvailable(int,QVariant,QVariant))
+ , this, SLOT(nxmDescriptionAvailable(int,QVariant,QVariant)));
+ connect(&m_NexusBridge, SIGNAL(endorsementToggled(int,QVariant,QVariant))
+ , this, SLOT(nxmEndorsementToggled(int,QVariant,QVariant)));
+ connect(&m_NexusBridge, SIGNAL(requestFailed(int,int,QVariant,QString))
+ , this, SLOT(nxmRequestFailed(int,int,QVariant,QString)));
}
-ModInfoRegular::~ModInfoRegular() {
- try {
- saveMeta();
- } catch (const std::exception& e) {
- qCritical("failed to save meta information for \"%s\": %s", m_Name.toUtf8().constData(), e.what());
- }
+
+ModInfoRegular::~ModInfoRegular()
+{
+ try {
+ saveMeta();
+ } catch (const std::exception &e) {
+ qCritical("failed to save meta information for \"%s\": %s",
+ m_Name.toUtf8().constData(), e.what());
+ }
}
-bool ModInfoRegular::isEmpty() const {
- QDirIterator iter(m_Path, QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs);
- if (!iter.hasNext())
- return true;
- iter.next();
- if ((iter.fileName() == "meta.ini") && !iter.hasNext())
- return true;
- return false;
+bool ModInfoRegular::isEmpty() const
+{
+ QDirIterator iter(m_Path, QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs);
+ if (!iter.hasNext()) return true;
+ iter.next();
+ if ((iter.fileName() == "meta.ini") && !iter.hasNext()) return true;
+ return false;
}
-void ModInfoRegular::readMeta() {
- QSettings metaFile(m_Path + "/meta.ini", QSettings::IniFormat);
- m_Notes = metaFile.value("notes", "").toString();
- m_NexusID = metaFile.value("modid", -1).toInt();
- m_Version.parse(metaFile.value("version", "").toString());
- m_NewestVersion = metaFile.value("newestVersion", "").toString();
- m_IgnoredVersion = metaFile.value("ignoredVersion", "").toString();
- m_InstallationFile = metaFile.value("installationFile", "").toString();
- m_NexusDescription = metaFile.value("nexusDescription", "").toString();
- m_Repository = metaFile.value("repository", "Nexus").toString();
- m_URL = metaFile.value("url", "").toString();
- m_LastNexusQuery = QDateTime::fromString(metaFile.value("lastNexusQuery", "").toString(), Qt::ISODate);
- if (metaFile.contains("endorsed")) {
- if (metaFile.value("endorsed").canConvert<int>()) {
- switch (metaFile.value("endorsed").toInt()) {
- case ENDORSED_FALSE:
- m_EndorsedState = ENDORSED_FALSE;
- break;
- case ENDORSED_TRUE:
- m_EndorsedState = ENDORSED_TRUE;
- break;
- case ENDORSED_NEVER:
- m_EndorsedState = ENDORSED_NEVER;
- break;
- default:
- m_EndorsedState = ENDORSED_UNKNOWN;
- break;
- }
- } else {
- m_EndorsedState = metaFile.value("endorsed", false).toBool() ? ENDORSED_TRUE : ENDORSED_FALSE;
- }
+
+void ModInfoRegular::readMeta()
+{
+ QSettings metaFile(m_Path + "/meta.ini", QSettings::IniFormat);
+ m_Notes = metaFile.value("notes", "").toString();
+ m_NexusID = metaFile.value("modid", -1).toInt();
+ m_Version.parse(metaFile.value("version", "").toString());
+ m_NewestVersion = metaFile.value("newestVersion", "").toString();
+ m_IgnoredVersion = metaFile.value("ignoredVersion", "").toString();
+ m_InstallationFile = metaFile.value("installationFile", "").toString();
+ m_NexusDescription = metaFile.value("nexusDescription", "").toString();
+ m_Repository = metaFile.value("repository", "Nexus").toString();
+ m_URL = metaFile.value("url", "").toString();
+ m_LastNexusQuery = QDateTime::fromString(metaFile.value("lastNexusQuery", "").toString(), Qt::ISODate);
+ if (metaFile.contains("endorsed")) {
+ if (metaFile.value("endorsed").canConvert<int>()) {
+ switch (metaFile.value("endorsed").toInt()) {
+ case ENDORSED_FALSE: m_EndorsedState = ENDORSED_FALSE; break;
+ case ENDORSED_TRUE: m_EndorsedState = ENDORSED_TRUE; break;
+ case ENDORSED_NEVER: m_EndorsedState = ENDORSED_NEVER; break;
+ default: m_EndorsedState = ENDORSED_UNKNOWN; break;
+ }
+ } else {
+ m_EndorsedState = metaFile.value("endorsed", false).toBool() ? ENDORSED_TRUE : ENDORSED_FALSE;
}
+ }
- QString categoriesString = metaFile.value("category", "").toString();
+ QString categoriesString = metaFile.value("category", "").toString();
- QStringList categories = categoriesString.split(',', QString::SkipEmptyParts);
- for (QStringList::iterator iter = categories.begin(); iter != categories.end(); ++iter) {
- bool ok = false;
- int categoryID = iter->toInt(&ok);
- if (categoryID < 0) {
- // ignore invalid id
- continue;
- }
- if (ok && (categoryID != 0) && (CategoryFactory::instance().categoryExists(categoryID))) {
- m_Categories.insert(categoryID);
- if (iter == categories.begin()) {
- m_PrimaryCategory = categoryID;
- }
- }
+ QStringList categories = categoriesString.split(',', QString::SkipEmptyParts);
+ for (QStringList::iterator iter = categories.begin(); iter != categories.end(); ++iter) {
+ bool ok = false;
+ int categoryID = iter->toInt(&ok);
+ if (categoryID < 0) {
+ // ignore invalid id
+ continue;
}
-
- int numFiles = metaFile.beginReadArray("installedFiles");
- for (int i = 0; i < numFiles; ++i) {
- metaFile.setArrayIndex(i);
- m_InstalledFileIDs.insert(std::make_pair(metaFile.value("modid").toInt(), metaFile.value("fileid").toInt()));
+ if (ok && (categoryID != 0) && (CategoryFactory::instance().categoryExists(categoryID))) {
+ m_Categories.insert(categoryID);
+ if (iter == categories.begin()) {
+ m_PrimaryCategory = categoryID;
+ }
}
- metaFile.endArray();
+ }
+
+ int numFiles = metaFile.beginReadArray("installedFiles");
+ for (int i = 0; i < numFiles; ++i) {
+ metaFile.setArrayIndex(i);
+ m_InstalledFileIDs.insert(std::make_pair(metaFile.value("modid").toInt(), metaFile.value("fileid").toInt()));
+ }
+ metaFile.endArray();
- m_MetaInfoChanged = false;
+ m_MetaInfoChanged = false;
}
-void ModInfoRegular::saveMeta() {
- // only write meta data if the mod directory exists
- if (m_MetaInfoChanged && QFile::exists(absolutePath())) {
- QSettings metaFile(absolutePath().append("/meta.ini"), QSettings::IniFormat);
- if (metaFile.status() == QSettings::NoError) {
- std::set<int> temp = m_Categories;
- temp.erase(m_PrimaryCategory);
- metaFile.setValue("category", QString("%1").arg(m_PrimaryCategory) + "," + SetJoin(temp, ","));
- metaFile.setValue("newestVersion", m_NewestVersion.canonicalString());
- metaFile.setValue("ignoredVersion", m_IgnoredVersion.canonicalString());
- metaFile.setValue("version", m_Version.canonicalString());
- metaFile.setValue("installationFile", m_InstallationFile);
- metaFile.setValue("repository", m_Repository);
- metaFile.setValue("modid", m_NexusID);
- metaFile.setValue("notes", m_Notes);
- metaFile.setValue("nexusDescription", m_NexusDescription);
- metaFile.setValue("url", m_URL);
- metaFile.setValue("lastNexusQuery", m_LastNexusQuery.toString(Qt::ISODate));
- if (m_EndorsedState != ENDORSED_UNKNOWN) {
- metaFile.setValue("endorsed", m_EndorsedState);
- }
+void ModInfoRegular::saveMeta()
+{
+ // only write meta data if the mod directory exists
+ if (m_MetaInfoChanged && QFile::exists(absolutePath())) {
+ QSettings metaFile(absolutePath().append("/meta.ini"), QSettings::IniFormat);
+ if (metaFile.status() == QSettings::NoError) {
+ std::set<int> temp = m_Categories;
+ temp.erase(m_PrimaryCategory);
+ metaFile.setValue("category", QString("%1").arg(m_PrimaryCategory) + "," + SetJoin(temp, ","));
+ metaFile.setValue("newestVersion", m_NewestVersion.canonicalString());
+ metaFile.setValue("ignoredVersion", m_IgnoredVersion.canonicalString());
+ metaFile.setValue("version", m_Version.canonicalString());
+ metaFile.setValue("installationFile", m_InstallationFile);
+ metaFile.setValue("repository", m_Repository);
+ metaFile.setValue("modid", m_NexusID);
+ metaFile.setValue("notes", m_Notes);
+ metaFile.setValue("nexusDescription", m_NexusDescription);
+ metaFile.setValue("url", m_URL);
+ metaFile.setValue("lastNexusQuery", m_LastNexusQuery.toString(Qt::ISODate));
+ if (m_EndorsedState != ENDORSED_UNKNOWN) {
+ metaFile.setValue("endorsed", m_EndorsedState);
+ }
- metaFile.beginWriteArray("installedFiles");
- int idx = 0;
- for (auto iter = m_InstalledFileIDs.begin(); iter != m_InstalledFileIDs.end(); ++iter) {
- metaFile.setArrayIndex(idx++);
- metaFile.setValue("modid", iter->first);
- metaFile.setValue("fileid", iter->second);
- }
- metaFile.endArray();
+ metaFile.beginWriteArray("installedFiles");
+ int idx = 0;
+ for (auto iter = m_InstalledFileIDs.begin(); iter != m_InstalledFileIDs.end(); ++iter) {
+ metaFile.setArrayIndex(idx++);
+ metaFile.setValue("modid", iter->first);
+ metaFile.setValue("fileid", iter->second);
+ }
+ metaFile.endArray();
- metaFile.sync(); // sync needs to be called to ensure the file is created
+ metaFile.sync(); // sync needs to be called to ensure the file is created
- if (metaFile.status() == QSettings::NoError) {
- m_MetaInfoChanged = false;
- } else {
- reportError(tr("failed to write %1/meta.ini: error %2").arg(absolutePath()).arg(metaFile.status()));
- }
- } else {
- reportError(tr("failed to write %1/meta.ini: error %2").arg(absolutePath()).arg(metaFile.status()));
- }
+ if (metaFile.status() == QSettings::NoError) {
+ m_MetaInfoChanged = false;
+ } else {
+ reportError(tr("failed to write %1/meta.ini: error %2").arg(absolutePath()).arg(metaFile.status()));
+ }
+ } else {
+ reportError(tr("failed to write %1/meta.ini: error %2").arg(absolutePath()).arg(metaFile.status()));
}
+ }
}
-bool ModInfoRegular::updateAvailable() const {
- if (m_IgnoredVersion.isValid() && (m_IgnoredVersion == m_NewestVersion)) {
- return false;
- }
- return m_NewestVersion.isValid() && (m_Version < m_NewestVersion);
+
+bool ModInfoRegular::updateAvailable() const
+{
+ if (m_IgnoredVersion.isValid() && (m_IgnoredVersion == m_NewestVersion)) {
+ return false;
+ }
+ return m_NewestVersion.isValid() && (m_Version < m_NewestVersion);
}
-bool ModInfoRegular::downgradeAvailable() const {
- if (m_IgnoredVersion.isValid() && (m_IgnoredVersion == m_NewestVersion)) {
- return false;
- }
- return m_NewestVersion.isValid() && (m_NewestVersion < m_Version);
+
+bool ModInfoRegular::downgradeAvailable() const
+{
+ if (m_IgnoredVersion.isValid() && (m_IgnoredVersion == m_NewestVersion)) {
+ return false;
+ }
+ return m_NewestVersion.isValid() && (m_NewestVersion < m_Version);
}
-void ModInfoRegular::nxmDescriptionAvailable(int, QVariant, QVariant resultData) {
- QVariantMap result = resultData.toMap();
- setNewestVersion(VersionInfo(result["version"].toString()));
- setNexusDescription(result["description"].toString());
- if ((m_EndorsedState != ENDORSED_NEVER) && (result.contains("voted_by_user"))) {
- setEndorsedState(result["voted_by_user"].toBool() ? ENDORSED_TRUE : ENDORSED_FALSE);
- }
- m_LastNexusQuery = QDateTime::currentDateTime();
- // m_MetaInfoChanged = true;
- saveMeta();
- emit modDetailsUpdated(true);
+void ModInfoRegular::nxmDescriptionAvailable(int, QVariant, QVariant resultData)
+{
+ QVariantMap result = resultData.toMap();
+ setNewestVersion(VersionInfo(result["version"].toString()));
+ setNexusDescription(result["description"].toString());
+
+ if ((m_EndorsedState != ENDORSED_NEVER) && (result.contains("voted_by_user"))) {
+ setEndorsedState(result["voted_by_user"].toBool() ? ENDORSED_TRUE : ENDORSED_FALSE);
+ }
+ m_LastNexusQuery = QDateTime::currentDateTime();
+ //m_MetaInfoChanged = true;
+ saveMeta();
+ emit modDetailsUpdated(true);
}
-void ModInfoRegular::nxmEndorsementToggled(int, QVariant, QVariant resultData) {
- m_EndorsedState = resultData.toBool() ? ENDORSED_TRUE : ENDORSED_FALSE;
- m_MetaInfoChanged = true;
- saveMeta();
- emit modDetailsUpdated(true);
+
+void ModInfoRegular::nxmEndorsementToggled(int, QVariant, QVariant resultData)
+{
+ m_EndorsedState = resultData.toBool() ? ENDORSED_TRUE : ENDORSED_FALSE;
+ m_MetaInfoChanged = true;
+ saveMeta();
+ emit modDetailsUpdated(true);
}
-void ModInfoRegular::nxmRequestFailed(int, int, QVariant userData, const QString& errorMessage) {
- QString fullMessage = errorMessage;
- if (userData.canConvert<int>() && (userData.toInt() == 1)) {
- fullMessage += "\nNexus will reject endorsements within 15 Minutes of a failed attempt, the error message may "
- "be misleading.";
- }
- if (QApplication::activeWindow() != nullptr) {
- MessageDialog::showMessage(fullMessage, QApplication::activeWindow());
- }
- emit modDetailsUpdated(false);
+
+void ModInfoRegular::nxmRequestFailed(int, int, QVariant userData, const QString &errorMessage)
+{
+ QString fullMessage = errorMessage;
+ if (userData.canConvert<int>() && (userData.toInt() == 1)) {
+ fullMessage += "\nNexus will reject endorsements within 15 Minutes of a failed attempt, the error message may be misleading.";
+ }
+ if (QApplication::activeWindow() != nullptr) {
+ MessageDialog::showMessage(fullMessage, QApplication::activeWindow());
+ }
+ emit modDetailsUpdated(false);
}
-bool ModInfoRegular::updateNXMInfo() {
- if (m_NexusID > 0) {
- m_NexusBridge.requestDescription(m_NexusID, QVariant());
- return true;
- }
- return false;
+
+bool ModInfoRegular::updateNXMInfo()
+{
+ if (m_NexusID > 0) {
+ m_NexusBridge.requestDescription(m_NexusID, QVariant());
+ return true;
+ }
+ return false;
}
-void ModInfoRegular::setCategory(int categoryID, bool active) {
- m_MetaInfoChanged = true;
- if (active) {
- m_Categories.insert(categoryID);
- if (m_PrimaryCategory == -1) {
- m_PrimaryCategory = categoryID;
- }
- } else {
- std::set<int>::iterator iter = m_Categories.find(categoryID);
- if (iter != m_Categories.end()) {
- m_Categories.erase(iter);
- }
- if (categoryID == m_PrimaryCategory) {
- if (m_Categories.size() == 0) {
- m_PrimaryCategory = -1;
- } else {
- m_PrimaryCategory = *(m_Categories.begin());
- }
- }
+void ModInfoRegular::setCategory(int categoryID, bool active)
+{
+ m_MetaInfoChanged = true;
+
+ if (active) {
+ m_Categories.insert(categoryID);
+ if (m_PrimaryCategory == -1) {
+ m_PrimaryCategory = categoryID;
+ }
+ } else {
+ std::set<int>::iterator iter = m_Categories.find(categoryID);
+ if (iter != m_Categories.end()) {
+ m_Categories.erase(iter);
}
+ if (categoryID == m_PrimaryCategory) {
+ if (m_Categories.size() == 0) {
+ m_PrimaryCategory = -1;
+ } else {
+ m_PrimaryCategory = *(m_Categories.begin());
+ }
+ }
+ }
}
-bool ModInfoRegular::setName(const QString& name) {
- if (name.contains('/') || name.contains('\\')) {
- return false;
- }
- QString newPath = m_Path.mid(0).replace(m_Path.length() - m_Name.length(), m_Name.length(), name);
- QDir modDir(m_Path.mid(0, m_Path.length() - m_Name.length()));
+bool ModInfoRegular::setName(const QString &name)
+{
+ if (name.contains('/') || name.contains('\\')) {
+ return false;
+ }
- if (m_Name.compare(name, Qt::CaseInsensitive) == 0) {
- QString tempName = name;
- tempName.append("_temp");
- while (modDir.exists(tempName)) {
- tempName.append("_");
- }
- if (!modDir.rename(m_Name, tempName)) {
- return false;
- }
- if (!modDir.rename(tempName, name)) {
- qCritical("rename to final name failed after successful rename to intermediate name");
- modDir.rename(tempName, m_Name);
- return false;
- }
- } else {
- if (!shellRename(modDir.absoluteFilePath(m_Name), modDir.absoluteFilePath(name))) {
- qCritical("failed to rename mod %s (errorcode %d)", qPrintable(name), ::GetLastError());
- return false;
- }
+ QString newPath = m_Path.mid(0).replace(m_Path.length() - m_Name.length(), m_Name.length(), name);
+ QDir modDir(m_Path.mid(0, m_Path.length() - m_Name.length()));
+
+ if (m_Name.compare(name, Qt::CaseInsensitive) == 0) {
+ QString tempName = name;
+ tempName.append("_temp");
+ while (modDir.exists(tempName)) {
+ tempName.append("_");
}
+ if (!modDir.rename(m_Name, tempName)) {
+ return false;
+ }
+ if (!modDir.rename(tempName, name)) {
+ qCritical("rename to final name failed after successful rename to intermediate name");
+ modDir.rename(tempName, m_Name);
+ return false;
+ }
+ } else {
+ if (!shellRename(modDir.absoluteFilePath(m_Name), modDir.absoluteFilePath(name))) {
+ qCritical("failed to rename mod %s (errorcode %d)",
+ qPrintable(name), ::GetLastError());
+ return false;
+ }
+ }
- std::map<QString, unsigned int>::iterator nameIter = s_ModsByName.find(m_Name);
- if (nameIter != s_ModsByName.end()) {
- unsigned int index = nameIter->second;
- s_ModsByName.erase(nameIter);
+ std::map<QString, unsigned int>::iterator nameIter = s_ModsByName.find(m_Name);
+ if (nameIter != s_ModsByName.end()) {
+ unsigned int index = nameIter->second;
+ s_ModsByName.erase(nameIter);
- m_Name = name;
- m_Path = newPath;
+ m_Name = name;
+ m_Path = newPath;
- s_ModsByName[m_Name] = index;
+ s_ModsByName[m_Name] = index;
- std::sort(s_Collection.begin(), s_Collection.end(), ByName);
- updateIndices();
- } else { // otherwise mod isn't registered yet?
- m_Name = name;
- m_Path = newPath;
- }
+ std::sort(s_Collection.begin(), s_Collection.end(), ByName);
+ updateIndices();
+ } else { // otherwise mod isn't registered yet?
+ m_Name = name;
+ m_Path = newPath;
+ }
- return true;
+ return true;
}
-void ModInfoRegular::setNotes(const QString& notes) {
- m_Notes = notes;
- m_MetaInfoChanged = true;
+void ModInfoRegular::setNotes(const QString &notes)
+{
+ m_Notes = notes;
+ m_MetaInfoChanged = true;
+}
+
+void ModInfoRegular::setNexusID(int modID)
+{
+ m_NexusID = modID;
+ m_MetaInfoChanged = true;
}
-void ModInfoRegular::setNexusID(int modID) {
- m_NexusID = modID;
+void ModInfoRegular::setVersion(const VersionInfo &version)
+{
+ m_Version = version;
+ m_MetaInfoChanged = true;
+}
+
+void ModInfoRegular::setNewestVersion(const VersionInfo &version)
+{
+ if (version != m_NewestVersion) {
+ m_NewestVersion = version;
m_MetaInfoChanged = true;
+ }
}
-void ModInfoRegular::setVersion(const VersionInfo& version) {
- m_Version = version;
+void ModInfoRegular::setNexusDescription(const QString &description)
+{
+ if (qHash(description) != qHash(m_NexusDescription)) {
+ m_NexusDescription = description;
m_MetaInfoChanged = true;
+ }
}
-void ModInfoRegular::setNewestVersion(const VersionInfo& version) {
- if (version != m_NewestVersion) {
- m_NewestVersion = version;
- m_MetaInfoChanged = true;
- }
+void ModInfoRegular::setEndorsedState(EEndorsedState endorsedState)
+{
+ if (endorsedState != m_EndorsedState) {
+ m_EndorsedState = endorsedState;
+ m_MetaInfoChanged = true;
+ }
}
-void ModInfoRegular::setNexusDescription(const QString& description) {
- if (qHash(description) != qHash(m_NexusDescription)) {
- m_NexusDescription = description;
- m_MetaInfoChanged = true;
- }
+void ModInfoRegular::setInstallationFile(const QString &fileName)
+{
+ m_InstallationFile = fileName;
+ m_MetaInfoChanged = true;
}
-void ModInfoRegular::setEndorsedState(EEndorsedState endorsedState) {
- if (endorsedState != m_EndorsedState) {
- m_EndorsedState = endorsedState;
- m_MetaInfoChanged = true;
- }
+void ModInfoRegular::addNexusCategory(int categoryID)
+{
+ m_Categories.insert(CategoryFactory::instance().resolveNexusID(categoryID));
}
-void ModInfoRegular::setInstallationFile(const QString& fileName) {
- m_InstallationFile = fileName;
+void ModInfoRegular::setIsEndorsed(bool endorsed)
+{
+ if (m_EndorsedState != ENDORSED_NEVER) {
+ m_EndorsedState = endorsed ? ENDORSED_TRUE : ENDORSED_FALSE;
m_MetaInfoChanged = true;
+ }
}
-void ModInfoRegular::addNexusCategory(int categoryID) {
- m_Categories.insert(CategoryFactory::instance().resolveNexusID(categoryID));
+
+void ModInfoRegular::setNeverEndorse()
+{
+ m_EndorsedState = ENDORSED_NEVER;
+ m_MetaInfoChanged = true;
}
-void ModInfoRegular::setIsEndorsed(bool endorsed) {
- if (m_EndorsedState != ENDORSED_NEVER) {
- m_EndorsedState = endorsed ? ENDORSED_TRUE : ENDORSED_FALSE;
- m_MetaInfoChanged = true;
- }
+
+bool ModInfoRegular::remove()
+{
+ m_MetaInfoChanged = false;
+ return shellDelete(QStringList(absolutePath()), true);
}
-void ModInfoRegular::setNeverEndorse() {
- m_EndorsedState = ENDORSED_NEVER;
- m_MetaInfoChanged = true;
+void ModInfoRegular::endorse(bool doEndorse)
+{
+ if (doEndorse != (m_EndorsedState == ENDORSED_TRUE)) {
+ m_NexusBridge.requestToggleEndorsement(getNexusID(), doEndorse, QVariant(1));
+ }
}
-bool ModInfoRegular::remove() {
- m_MetaInfoChanged = false;
- return shellDelete(QStringList(absolutePath()), true);
+
+QString ModInfoRegular::absolutePath() const
+{
+ return m_Path;
}
-void ModInfoRegular::endorse(bool doEndorse) {
- if (doEndorse != (m_EndorsedState == ENDORSED_TRUE)) {
- m_NexusBridge.requestToggleEndorsement(getNexusID(), doEndorse, QVariant(1));
- }
+void ModInfoRegular::ignoreUpdate(bool ignore)
+{
+ if (ignore) {
+ m_IgnoredVersion = m_NewestVersion;
+ } else {
+ m_IgnoredVersion.clear();
+ }
+ m_MetaInfoChanged = true;
}
-QString ModInfoRegular::absolutePath() const { return m_Path; }
-void ModInfoRegular::ignoreUpdate(bool ignore) {
- if (ignore) {
- m_IgnoredVersion = m_NewestVersion;
- } else {
- m_IgnoredVersion.clear();
- }
- m_MetaInfoChanged = true;
+std::vector<ModInfo::EFlag> ModInfoRegular::getFlags() const
+{
+ std::vector<ModInfo::EFlag> result = ModInfoWithConflictInfo::getFlags();
+ if ((m_NexusID > 0) && (endorsedState() == ENDORSED_FALSE)) {
+ result.push_back(ModInfo::FLAG_NOTENDORSED);
+ }
+ if (!isValid()) {
+ result.push_back(ModInfo::FLAG_INVALID);
+ }
+ if (m_Notes.length() != 0) {
+ result.push_back(ModInfo::FLAG_NOTES);
+ }
+ if (m_PluginSelected) {
+ result.push_back(ModInfo::FLAG_PLUGIN_SELECTED);
+ }
+ return result;
}
-std::vector<ModInfo::EFlag> ModInfoRegular::getFlags() const {
- std::vector<ModInfo::EFlag> result = ModInfoWithConflictInfo::getFlags();
- if ((m_NexusID > 0) && (endorsedState() == ENDORSED_FALSE)) {
- result.push_back(ModInfo::FLAG_NOTENDORSED);
- }
- if (!isValid()) {
- result.push_back(ModInfo::FLAG_INVALID);
- }
- if (m_Notes.length() != 0) {
- result.push_back(ModInfo::FLAG_NOTES);
+
+std::vector<ModInfo::EContent> ModInfoRegular::getContents() const
+{
+ QTime now = QTime::currentTime();
+ if (m_LastContentCheck.isNull() || (m_LastContentCheck.secsTo(now) > 60)) {
+ m_CachedContent.clear();
+ QDir dir(absolutePath());
+ if (dir.entryList(QStringList() << "*.esp" << "*.esm" << "*.esl").size() > 0) {
+ m_CachedContent.push_back(CONTENT_PLUGIN);
}
- if (m_PluginSelected) {
- result.push_back(ModInfo::FLAG_PLUGIN_SELECTED);
+ if (dir.entryList(QStringList() << "*.bsa" << "*.ba2").size() > 0) {
+ m_CachedContent.push_back(CONTENT_BSA);
}
- return result;
-}
-std::vector<ModInfo::EContent> ModInfoRegular::getContents() const {
- QTime now = QTime::currentTime();
- if (m_LastContentCheck.isNull() || (m_LastContentCheck.secsTo(now) > 60)) {
- m_CachedContent.clear();
- QDir dir(absolutePath());
- if (dir.entryList(QStringList() << "*.esp"
- << "*.esm"
- << "*.esl")
- .size() > 0) {
- m_CachedContent.push_back(CONTENT_PLUGIN);
- }
- if (dir.entryList(QStringList() << "*.bsa"
- << "*.ba2")
- .size() > 0) {
- m_CachedContent.push_back(CONTENT_BSA);
- }
+ ScriptExtender *extender = qApp->property("managed_game")
+ .value<IPluginGame *>()
+ ->feature<ScriptExtender>();
- ScriptExtender* extender = qApp->property("managed_game").value<IPluginGame*>()->feature<ScriptExtender>();
+ if (extender != nullptr) {
+ QString sePluginPath = extender->PluginPath();
+ if (dir.exists(sePluginPath))
+ m_CachedContent.push_back(CONTENT_SKSE);
+ }
+ if (dir.exists("textures"))
+ m_CachedContent.push_back(CONTENT_TEXTURE);
+ if (dir.exists("meshes"))
+ m_CachedContent.push_back(CONTENT_MESH);
+ if (dir.exists("interface") || dir.exists("menus"))
+ m_CachedContent.push_back(CONTENT_INTERFACE);
+ if (dir.exists("music") || dir.exists("sound"))
+ m_CachedContent.push_back(CONTENT_SOUND);
+ if (dir.exists("scripts"))
+ m_CachedContent.push_back(CONTENT_SCRIPT);
+ if (dir.exists("SkyProc Patchers"))
+ m_CachedContent.push_back(CONTENT_SKYPROC);
+ if (dir.exists("MCM"))
+ m_CachedContent.push_back(CONTENT_MCM);
- if (extender != nullptr) {
- QString sePluginPath = extender->PluginPath();
- if (dir.exists(sePluginPath))
- m_CachedContent.push_back(CONTENT_SKSE);
- }
- if (dir.exists("textures"))
- m_CachedContent.push_back(CONTENT_TEXTURE);
- if (dir.exists("meshes"))
- m_CachedContent.push_back(CONTENT_MESH);
- if (dir.exists("interface") || dir.exists("menus"))
- m_CachedContent.push_back(CONTENT_INTERFACE);
- if (dir.exists("music") || dir.exists("sound"))
- m_CachedContent.push_back(CONTENT_SOUND);
- if (dir.exists("scripts"))
- m_CachedContent.push_back(CONTENT_SCRIPT);
- if (dir.exists("SkyProc Patchers"))
- m_CachedContent.push_back(CONTENT_SKYPROC);
- if (dir.exists("MCM"))
- m_CachedContent.push_back(CONTENT_MCM);
+ m_LastContentCheck = QTime::currentTime();
+ }
- m_LastContentCheck = QTime::currentTime();
- }
+ return m_CachedContent;
- return m_CachedContent;
}
-int ModInfoRegular::getHighlight() const {
- if (!isValid())
- return HIGHLIGHT_INVALID;
- auto flags = getFlags();
- if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_PLUGIN_SELECTED) != flags.end())
- return HIGHLIGHT_PLUGIN;
- return HIGHLIGHT_NONE;
+
+int ModInfoRegular::getHighlight() const
+{
+ if (!isValid())
+ return HIGHLIGHT_INVALID;
+ auto flags = getFlags();
+ if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_PLUGIN_SELECTED) != flags.end())
+ return HIGHLIGHT_PLUGIN;
+ return HIGHLIGHT_NONE;
}
-QString ModInfoRegular::getDescription() const {
- if (!isValid()) {
- return tr("%1 contains no esp/esm/esl and no asset (textures, meshes, interface, ...) directory").arg(name());
- } else {
- const std::set<int>& categories = getCategories();
- std::wostringstream categoryString;
- categoryString << ToWString(tr("Categories: <br>"));
- CategoryFactory& categoryFactory = CategoryFactory::instance();
- for (std::set<int>::const_iterator catIter = categories.begin(); catIter != categories.end(); ++catIter) {
- if (catIter != categories.begin()) {
- categoryString << " , ";
- }
- categoryString << "<span style=\"white-space: nowrap;\"><i>"
- << ToWString(categoryFactory.getCategoryName(categoryFactory.getCategoryIndex(*catIter)))
- << "</font></span>";
- }
- return ToQString(categoryString.str());
+QString ModInfoRegular::getDescription() const
+{
+ if (!isValid()) {
+ return tr("%1 contains no esp/esm/esl and no asset (textures, meshes, interface, ...) directory").arg(name());
+ } else {
+ const std::set<int> &categories = getCategories();
+ std::wostringstream categoryString;
+ categoryString << ToWString(tr("Categories: <br>"));
+ CategoryFactory &categoryFactory = CategoryFactory::instance();
+ for (std::set<int>::const_iterator catIter = categories.begin();
+ catIter != categories.end(); ++catIter) {
+ if (catIter != categories.begin()) {
+ categoryString << " , ";
+ }
+ categoryString << "<span style=\"white-space: nowrap;\"><i>" << ToWString(categoryFactory.getCategoryName(categoryFactory.getCategoryIndex(*catIter))) << "</font></span>";
}
+
+ return ToQString(categoryString.str());
+ }
}
-QString ModInfoRegular::notes() const { return m_Notes; }
+QString ModInfoRegular::notes() const
+{
+ return m_Notes;
+}
-QDateTime ModInfoRegular::creationTime() const { return m_CreationTime; }
+QDateTime ModInfoRegular::creationTime() const
+{
+ return m_CreationTime;
+}
+
+QString ModInfoRegular::getNexusDescription() const
+{
+ return m_NexusDescription;
+}
-QString ModInfoRegular::getNexusDescription() const { return m_NexusDescription; }
+QString ModInfoRegular::repository() const
+{
+ return m_Repository;
+}
-QString ModInfoRegular::repository() const { return m_Repository; }
+ModInfoRegular::EEndorsedState ModInfoRegular::endorsedState() const
+{
+ return m_EndorsedState;
+}
-ModInfoRegular::EEndorsedState ModInfoRegular::endorsedState() const { return m_EndorsedState; }
+QDateTime ModInfoRegular::getLastNexusQuery() const
+{
+ return m_LastNexusQuery;
+}
-QDateTime ModInfoRegular::getLastNexusQuery() const { return m_LastNexusQuery; }
+void ModInfoRegular::setURL(QString const &url)
+{
+ m_URL = url;
+ m_MetaInfoChanged = true;
+}
-void ModInfoRegular::setURL(QString const& url) {
- m_URL = url;
- m_MetaInfoChanged = true;
+QString ModInfoRegular::getURL() const
+{
+ return m_URL;
}
-QString ModInfoRegular::getURL() const { return m_URL; }
-QStringList ModInfoRegular::archives() const {
- QStringList result;
- QDir dir(this->absolutePath());
- for (const QString& archive : dir.entryList(QStringList({"*.bsa", "*.ba2"}))) {
- result.append(this->absolutePath() + "/" + archive);
- }
- return result;
+
+QStringList ModInfoRegular::archives() const
+{
+ QStringList result;
+ QDir dir(this->absolutePath());
+ for (const QString &archive : dir.entryList(QStringList({ "*.bsa", "*.ba2" }))) {
+ result.append(this->absolutePath() + "/" + archive);
+ }
+ return result;
}
-void ModInfoRegular::addInstalledFile(int modId, int fileId) {
- m_InstalledFileIDs.insert(std::make_pair(modId, fileId));
- m_MetaInfoChanged = true;
+void ModInfoRegular::addInstalledFile(int modId, int fileId)
+{
+ m_InstalledFileIDs.insert(std::make_pair(modId, fileId));
+ m_MetaInfoChanged = true;
}
-std::vector<QString> ModInfoRegular::getIniTweaks() const {
- QString metaFileName = absolutePath().append("/meta.ini");
- QSettings metaFile(metaFileName, QSettings::IniFormat);
+std::vector<QString> ModInfoRegular::getIniTweaks() const
+{
+ QString metaFileName = absolutePath().append("/meta.ini");
+ QSettings metaFile(metaFileName, QSettings::IniFormat);
- std::vector<QString> result;
+ std::vector<QString> result;
- int numTweaks = metaFile.beginReadArray("INI Tweaks");
+ int numTweaks = metaFile.beginReadArray("INI Tweaks");
- if (numTweaks != 0) {
- qDebug("%d active ini tweaks in %s", numTweaks, QDir::toNativeSeparators(metaFileName).toUtf8().constData());
- }
+ if (numTweaks != 0) {
+ qDebug("%d active ini tweaks in %s",
+ numTweaks, QDir::toNativeSeparators(metaFileName).toUtf8().constData());
+ }
- for (int i = 0; i < numTweaks; ++i) {
- metaFile.setArrayIndex(i);
- QString filename = absolutePath().append("/INI Tweaks/").append(metaFile.value("name").toString());
- result.push_back(filename);
- }
- metaFile.endArray();
- return result;
+ for (int i = 0; i < numTweaks; ++i) {
+ metaFile.setArrayIndex(i);
+ QString filename = absolutePath().append("/INI Tweaks/").append(metaFile.value("name").toString());
+ result.push_back(filename);
+ }
+ metaFile.endArray();
+ return result;
}
diff --git a/src/modinforegular.h b/src/modinforegular.h
index 616e2fbe..a94d0363 100644
--- a/src/modinforegular.h
+++ b/src/modinforegular.h
@@ -12,334 +12,338 @@
* to manage the mod collection
*
**/
-class ModInfoRegular : public ModInfoWithConflictInfo {
+class ModInfoRegular : public ModInfoWithConflictInfo
+{
- Q_OBJECT
+ Q_OBJECT
- friend class ModInfo;
+ friend class ModInfo;
public:
- ~ModInfoRegular();
- virtual bool isRegular() const { return true; }
+ ~ModInfoRegular();
- virtual bool isEmpty() const;
+ virtual bool isRegular() const { return true; }
- /**
- * @brief test if there is a newer version of the mod
- *
- * test if there is a newer version of the mod. This does NOT cause
- * information to be retrieved from the nexus, it will only test version information already
- * available locally. Use checkAllForUpdate() to update this version information
- *
- * @return true if there is a newer version
- **/
- bool updateAvailable() const;
+ virtual bool isEmpty() const;
- /**
- * @return true if the current update is being ignored
- */
- virtual bool updateIgnored() const { return m_IgnoredVersion == m_NewestVersion; }
+ /**
+ * @brief test if there is a newer version of the mod
+ *
+ * test if there is a newer version of the mod. This does NOT cause
+ * information to be retrieved from the nexus, it will only test version information already
+ * available locally. Use checkAllForUpdate() to update this version information
+ *
+ * @return true if there is a newer version
+ **/
+ bool updateAvailable() const;
- /**
- * @brief test if there is a newer version of the mod
- *
- * test if there is a newer version of the mod. This does NOT cause
- * information to be retrieved from the nexus, it will only test version information already
- * available locally. Use checkAllForUpdate() to update this version information
- *
- * @return true if there is a newer version
- **/
- bool downgradeAvailable() const;
+ /**
+ * @return true if the current update is being ignored
+ */
+ virtual bool updateIgnored() const { return m_IgnoredVersion == m_NewestVersion; }
- /**
- * @brief request an update of nexus description for this mod.
- *
- * This requests mod information from the nexus. This is an asynchronous request,
- * so there is no immediate effect of this call.
- *
- * @return returns true if information for this mod will be updated, false if there is no nexus mod id to use
- **/
- bool updateNXMInfo();
+ /**
+ * @brief test if there is a newer version of the mod
+ *
+ * test if there is a newer version of the mod. This does NOT cause
+ * information to be retrieved from the nexus, it will only test version information already
+ * available locally. Use checkAllForUpdate() to update this version information
+ *
+ * @return true if there is a newer version
+ **/
+ bool downgradeAvailable() const;
- /**
- * @brief assign or unassign the specified category
- *
- * Every mod can have an arbitrary number of categories assigned to it
- *
- * @param categoryID id of the category to set
- * @param active determines wheter the category is assigned or unassigned
- * @note this function does not test whether categoryID actually identifies a valid category
- **/
- void setCategory(int categoryID, bool active);
+ /**
+ * @brief request an update of nexus description for this mod.
+ *
+ * This requests mod information from the nexus. This is an asynchronous request,
+ * so there is no immediate effect of this call.
+ *
+ * @return returns true if information for this mod will be updated, false if there is no nexus mod id to use
+ **/
+ bool updateNXMInfo();
- /**
- * @brief set the name of this mod
- *
- * set the name of this mod. This will also update the name of the
- * directory that contains this mod
- *
- * @param name new name of the mod
- * @return true on success, false if the new name can't be used (i.e. because the new
- * directory name wouldn't be valid)
- **/
- bool setName(const QString& name);
+ /**
+ * @brief assign or unassign the specified category
+ *
+ * Every mod can have an arbitrary number of categories assigned to it
+ *
+ * @param categoryID id of the category to set
+ * @param active determines wheter the category is assigned or unassigned
+ * @note this function does not test whether categoryID actually identifies a valid category
+ **/
+ void setCategory(int categoryID, bool active);
- /**
- * @brief change the notes (manually set information) for this mod
- * @param notes new notes
- */
- void setNotes(const QString& notes);
+ /**
+ * @brief set the name of this mod
+ *
+ * set the name of this mod. This will also update the name of the
+ * directory that contains this mod
+ *
+ * @param name new name of the mod
+ * @return true on success, false if the new name can't be used (i.e. because the new
+ * directory name wouldn't be valid)
+ **/
+ bool setName(const QString &name);
- /**
- * @brief set/change the nexus mod id of this mod
- *
- * @param modID the nexus mod id
- **/
- void setNexusID(int modID);
+ /**
+ * @brief change the notes (manually set information) for this mod
+ * @param notes new notes
+ */
+ void setNotes(const QString &notes);
- /**
- * @brief set the version of this mod
- *
- * this can be used to overwrite the version of a mod without actually
- * updating the mod
- *
- * @param version the new version to use
- **/
- void setVersion(const MOBase::VersionInfo& version);
+ /**
+ * @brief set/change the nexus mod id of this mod
+ *
+ * @param modID the nexus mod id
+ **/
+ void setNexusID(int modID);
- /**
- * @brief set the newest version of this mod on the nexus
- *
- * this can be used to overwrite the version of a mod without actually
- * updating the mod
- *
- * @param version the new version to use
- * @todo this function should be made obsolete. All queries for mod information should go through
- * this class so no public function for this change is required
- **/
- void setNewestVersion(const MOBase::VersionInfo& version);
+ /**
+ * @brief set the version of this mod
+ *
+ * this can be used to overwrite the version of a mod without actually
+ * updating the mod
+ *
+ * @param version the new version to use
+ **/
+ void setVersion(const MOBase::VersionInfo &version);
- /**
- * @brief changes/updates the nexus description text
- * @param description the current description text
- */
- virtual void setNexusDescription(const QString& description);
+ /**
+ * @brief set the newest version of this mod on the nexus
+ *
+ * this can be used to overwrite the version of a mod without actually
+ * updating the mod
+ *
+ * @param version the new version to use
+ * @todo this function should be made obsolete. All queries for mod information should go through
+ * this class so no public function for this change is required
+ **/
+ void setNewestVersion(const MOBase::VersionInfo &version);
- virtual void setInstallationFile(const QString& fileName);
+ /**
+ * @brief changes/updates the nexus description text
+ * @param description the current description text
+ */
+ virtual void setNexusDescription(const QString &description);
- /**
- * @brief sets the category id from a nexus category id. Conversion to MO id happens internally
- * @param categoryID the nexus category id
- * @note if a mapping is not possible, the category is set to the default value
- */
- virtual void addNexusCategory(int categoryID);
+ virtual void setInstallationFile(const QString &fileName);
- /**
- * @brief sets the new primary category of the mod
- * @param categoryID the category to set
- */
- virtual void setPrimaryCategory(int categoryID) {
- m_PrimaryCategory = categoryID;
- m_MetaInfoChanged = true;
- }
+ /**
+ * @brief sets the category id from a nexus category id. Conversion to MO id happens internally
+ * @param categoryID the nexus category id
+ * @note if a mapping is not possible, the category is set to the default value
+ */
+ virtual void addNexusCategory(int categoryID);
- /**
- * @brief sets the download repository
- * @param repository
- */
- virtual void setRepository(const QString& repository) { m_Repository = repository; }
+ /**
+ * @brief sets the new primary category of the mod
+ * @param categoryID the category to set
+ */
+ virtual void setPrimaryCategory(int categoryID) { m_PrimaryCategory = categoryID; m_MetaInfoChanged = true; }
- /**
- * update the endorsement state for the mod. This only changes the
- * buffered state, it does not sync with Nexus
- * @param endorsed the new endorsement state
- */
- virtual void setIsEndorsed(bool endorsed);
+ /**
+ * @brief sets the download repository
+ * @param repository
+ */
+ virtual void setRepository(const QString &repository) { m_Repository = repository; }
- /**
- * set the mod to "i don't intend to endorse". The mod will not show as unendorsed but can still be endorsed
- */
- virtual void setNeverEndorse();
+ /**
+ * update the endorsement state for the mod. This only changes the
+ * buffered state, it does not sync with Nexus
+ * @param endorsed the new endorsement state
+ */
+ virtual void setIsEndorsed(bool endorsed);
- /**
- * @brief delete the mod from the disc. This does not update the global ModInfo structure or indices
- * @return true if the mod was successfully removed
- **/
- bool remove();
+ /**
+ * set the mod to "i don't intend to endorse". The mod will not show as unendorsed but can still be endorsed
+ */
+ virtual void setNeverEndorse();
- /**
- * @brief endorse or un-endorse the mod
- * @param doEndorse if true, the mod is endorsed, if false, it's un-endorsed.
- * @note if doEndorse doesn't differ from the current value, nothing happens.
- */
- virtual void endorse(bool doEndorse);
+ /**
+ * @brief delete the mod from the disc. This does not update the global ModInfo structure or indices
+ * @return true if the mod was successfully removed
+ **/
+ bool remove();
- /**
- * @brief getter for the mod name
- *
- * @return the mod name
- **/
- QString name() const { return m_Name; }
+ /**
+ * @brief endorse or un-endorse the mod
+ * @param doEndorse if true, the mod is endorsed, if false, it's un-endorsed.
+ * @note if doEndorse doesn't differ from the current value, nothing happens.
+ */
+ virtual void endorse(bool doEndorse);
- /**
- * @brief getter for the mod path
- *
- * @return the (absolute) path to the mod
- **/
- QString absolutePath() const;
+ /**
+ * @brief getter for the mod name
+ *
+ * @return the mod name
+ **/
+ QString name() const { return m_Name; }
- /**
- * @brief getter for the newest version number of this mod
- *
- * @return newest version of the mod
- **/
- MOBase::VersionInfo getNewestVersion() const { return m_NewestVersion; }
+ /**
+ * @brief getter for the mod path
+ *
+ * @return the (absolute) path to the mod
+ **/
+ QString absolutePath() const;
- /**
- * @brief ignore the newest version for updates
- */
- void ignoreUpdate(bool ignore);
+ /**
+ * @brief getter for the newest version number of this mod
+ *
+ * @return newest version of the mod
+ **/
+ MOBase::VersionInfo getNewestVersion() const { return m_NewestVersion; }
- /**
- * @brief getter for the installation file
- *
- * @return file used to install this mod from
- */
- virtual QString getInstallationFile() const { return m_InstallationFile; }
- /**
- * @brief getter for the nexus mod id
- *
- * @return the nexus mod id. may be 0 if the mod id isn't known or doesn't exist
- **/
- int getNexusID() const { return m_NexusID; }
+ /**
+ * @brief ignore the newest version for updates
+ */
+ void ignoreUpdate(bool ignore);
- /**
- * @return the fixed priority of mods of this type or INT_MIN if the priority of mods
- * needs to be user-modifiable
- */
- virtual int getFixedPriority() const { return INT_MIN; }
+ /**
+ * @brief getter for the installation file
+ *
+ * @return file used to install this mod from
+ */
+ virtual QString getInstallationFile() const { return m_InstallationFile; }
+ /**
+ * @brief getter for the nexus mod id
+ *
+ * @return the nexus mod id. may be 0 if the mod id isn't known or doesn't exist
+ **/
+ int getNexusID() const { return m_NexusID; }
- /**
- * @return true if the mod can be updated
- */
- virtual bool canBeUpdated() const { return m_NexusID > 0; }
+ /**
+ * @return the fixed priority of mods of this type or INT_MIN if the priority of mods
+ * needs to be user-modifiable
+ */
+ virtual int getFixedPriority() const { return INT_MIN; }
- /**
- * @return true if the mod can be enabled/disabled
- */
- virtual bool canBeEnabled() const { return true; }
+ /**
+ * @return true if the mod can be updated
+ */
+ virtual bool canBeUpdated() const { return m_NexusID > 0; }
- /**
- * @return a list of flags for this mod
- */
- virtual std::vector<EFlag> getFlags() const;
+ /**
+ * @return true if the mod can be enabled/disabled
+ */
+ virtual bool canBeEnabled() const { return true; }
- virtual std::vector<EContent> getContents() const;
+ /**
+ * @return a list of flags for this mod
+ */
+ virtual std::vector<EFlag> getFlags() const;
- /**
- * @return an indicator if and how this mod should be highlighted by the UI
- */
- virtual int getHighlight() const;
+ virtual std::vector<EContent> getContents() const;
- /**
- * @return list of names of ini tweaks
- **/
- std::vector<QString> getIniTweaks() const;
+ /**
+ * @return an indicator if and how this mod should be highlighted by the UI
+ */
+ virtual int getHighlight() const;
- /**
- * @return a description about the mod, to be displayed in the ui
- */
- virtual QString getDescription() const;
+ /**
+ * @return list of names of ini tweaks
+ **/
+ std::vector<QString> getIniTweaks() const;
- /**
- * @return manually set notes for this mod
- */
- virtual QString notes() const;
+ /**
+ * @return a description about the mod, to be displayed in the ui
+ */
+ virtual QString getDescription() const;
- /**
- * @return time this mod was created (file time of the directory)
- */
- virtual QDateTime creationTime() const;
+ /**
+ * @return manually set notes for this mod
+ */
+ virtual QString notes() const;
- /**
- * @return nexus description of the mod (html)
- */
- QString getNexusDescription() const;
+ /**
+ * @return time this mod was created (file time of the directory)
+ */
+ virtual QDateTime creationTime() const;
- /**
- * @return repository from which the file was downloaded
- */
- virtual QString repository() const;
+ /**
+ * @return nexus description of the mod (html)
+ */
+ QString getNexusDescription() const;
- /**
- * @return true if the file has been endorsed on nexus
- */
- virtual EEndorsedState endorsedState() const;
+ /**
+ * @return repository from which the file was downloaded
+ */
+ virtual QString repository() const;
- /**
- * @return last time nexus was queried for infos on this mod
- */
- virtual QDateTime getLastNexusQuery() const;
+ /**
+ * @return true if the file has been endorsed on nexus
+ */
+ virtual EEndorsedState endorsedState() const;
- virtual QStringList archives() const;
+ /**
+ * @return last time nexus was queried for infos on this mod
+ */
+ virtual QDateTime getLastNexusQuery() const;
- virtual void addInstalledFile(int modId, int fileId);
+ virtual QStringList archives() const;
- /**
- * @brief stores meta information back to disk
- */
- virtual void saveMeta();
+ virtual void addInstalledFile(int modId, int fileId);
- void readMeta();
+ /**
+ * @brief stores meta information back to disk
+ */
+ virtual void saveMeta();
- /**
- * @brief set the URL for a mod
- */
- virtual void setURL(QString const&);
+ void readMeta();
- /**
- * @returns the URL for a mod
- */
- virtual QString getURL() const;
+ /**
+ * @brief set the URL for a mod
+ */
+ virtual void setURL(QString const &);
+
+ /**
+ * @returns the URL for a mod
+ */
+ virtual QString getURL() const;
private:
- void setEndorsedState(EEndorsedState endorsedState);
+
+ void setEndorsedState(EEndorsedState endorsedState);
private slots:
- void nxmDescriptionAvailable(int modID, QVariant userData, QVariant resultData);
- void nxmEndorsementToggled(int, QVariant userData, QVariant resultData);
- void nxmRequestFailed(int modID, int fileID, QVariant userData, const QString& errorMessage);
+ void nxmDescriptionAvailable(int modID, QVariant userData, QVariant resultData);
+ void nxmEndorsementToggled(int, QVariant userData, QVariant resultData);
+ void nxmRequestFailed(int modID, int fileID, QVariant userData, const QString &errorMessage);
protected:
- ModInfoRegular(const QDir& path, MOShared::DirectoryEntry** directoryStructure);
+
+ ModInfoRegular(const QDir &path, MOShared::DirectoryEntry **directoryStructure);
private:
- QString m_Name;
- QString m_Path;
- QString m_InstallationFile;
- QString m_Notes;
- QString m_NexusDescription;
- QString m_Repository;
- QString m_URL;
- QDateTime m_CreationTime;
- QDateTime m_LastNexusQuery;
+ QString m_Name;
+ QString m_Path;
+ QString m_InstallationFile;
+ QString m_Notes;
+ QString m_NexusDescription;
+ QString m_Repository;
+ QString m_URL;
- int m_NexusID;
- std::set<std::pair<int, int>> m_InstalledFileIDs;
+ QDateTime m_CreationTime;
+ QDateTime m_LastNexusQuery;
- bool m_MetaInfoChanged;
- MOBase::VersionInfo m_NewestVersion;
- MOBase::VersionInfo m_IgnoredVersion;
+ int m_NexusID;
+ std::set<std::pair<int, int>> m_InstalledFileIDs;
- EEndorsedState m_EndorsedState;
+ bool m_MetaInfoChanged;
+ MOBase::VersionInfo m_NewestVersion;
+ MOBase::VersionInfo m_IgnoredVersion;
- NexusBridge m_NexusBridge;
+ EEndorsedState m_EndorsedState;
+
+ NexusBridge m_NexusBridge;
+
+ mutable std::vector<ModInfo::EContent> m_CachedContent;
+ mutable QTime m_LastContentCheck;
- mutable std::vector<ModInfo::EContent> m_CachedContent;
- mutable QTime m_LastContentCheck;
};
+
#endif // MODINFOREGULAR_H
diff --git a/src/modinfowithconflictinfo.cpp b/src/modinfowithconflictinfo.cpp
index 74a208e9..b8ece783 100644
--- a/src/modinfowithconflictinfo.cpp
+++ b/src/modinfowithconflictinfo.cpp
@@ -6,117 +6,125 @@
using namespace MOBase;
using namespace MOShared;
-ModInfoWithConflictInfo::ModInfoWithConflictInfo(DirectoryEntry** directoryStructure)
- : m_DirectoryStructure(directoryStructure) {}
+ModInfoWithConflictInfo::ModInfoWithConflictInfo(DirectoryEntry **directoryStructure)
+ : m_DirectoryStructure(directoryStructure) {}
-void ModInfoWithConflictInfo::clearCaches() { m_LastConflictCheck = QTime(); }
+void ModInfoWithConflictInfo::clearCaches()
+{
+ m_LastConflictCheck = QTime();
+}
-std::vector<ModInfo::EFlag> ModInfoWithConflictInfo::getFlags() const {
- std::vector<ModInfo::EFlag> result;
- switch (isConflicted()) {
+std::vector<ModInfo::EFlag> ModInfoWithConflictInfo::getFlags() const
+{
+ std::vector<ModInfo::EFlag> result;
+ switch (isConflicted()) {
case CONFLICT_MIXED: {
- result.push_back(ModInfo::FLAG_CONFLICT_MIXED);
+ result.push_back(ModInfo::FLAG_CONFLICT_MIXED);
} break;
case CONFLICT_OVERWRITE: {
- result.push_back(ModInfo::FLAG_CONFLICT_OVERWRITE);
+ result.push_back(ModInfo::FLAG_CONFLICT_OVERWRITE);
} break;
case CONFLICT_OVERWRITTEN: {
- result.push_back(ModInfo::FLAG_CONFLICT_OVERWRITTEN);
+ result.push_back(ModInfo::FLAG_CONFLICT_OVERWRITTEN);
} break;
case CONFLICT_REDUNDANT: {
- result.push_back(ModInfo::FLAG_CONFLICT_REDUNDANT);
+ result.push_back(ModInfo::FLAG_CONFLICT_REDUNDANT);
} break;
- default: { /* NOP */
- }
- }
- return result;
+ default: { /* NOP */ }
+ }
+ return result;
}
-void ModInfoWithConflictInfo::doConflictCheck() const {
- m_OverwriteList.clear();
- m_OverwrittenList.clear();
- bool providesAnything = false;
+void ModInfoWithConflictInfo::doConflictCheck() const
+{
+ m_OverwriteList.clear();
+ m_OverwrittenList.clear();
- int dataID = 0;
- if ((*m_DirectoryStructure)->originExists(L"data")) {
- dataID = (*m_DirectoryStructure)->getOriginByName(L"data").getID();
- }
+ bool providesAnything = false;
- std::wstring name = ToWString(this->name());
+ int dataID = 0;
+ if ((*m_DirectoryStructure)->originExists(L"data")) {
+ dataID = (*m_DirectoryStructure)->getOriginByName(L"data").getID();
+ }
- m_CurrentConflictState = CONFLICT_NONE;
+ std::wstring name = ToWString(this->name());
- if ((*m_DirectoryStructure)->originExists(name)) {
- FilesOrigin& origin = (*m_DirectoryStructure)->getOriginByName(name);
- std::vector<FileEntry::Ptr> files = origin.getFiles();
- // for all files in this origin
- for (FileEntry::Ptr file : files) {
- const std::vector<std::pair<int, std::wstring>>& alternatives = file->getAlternatives();
- if ((alternatives.size() == 0) || (alternatives.begin()->first == dataID)) {
- // no alternatives -> no conflict
- providesAnything = true;
- } else {
- if (file->getOrigin() != origin.getID()) {
- FilesOrigin& altOrigin = (*m_DirectoryStructure)->getOriginByID(file->getOrigin());
- unsigned int altIndex = ModInfo::getIndex(ToQString(altOrigin.getName()));
- m_OverwrittenList.insert(altIndex);
- } else {
- providesAnything = true;
- }
+ m_CurrentConflictState = CONFLICT_NONE;
- // for all non-providing alternative origins
- for (auto altInfo : alternatives) {
- if ((altInfo.first != dataID) && (altInfo.first != origin.getID())) {
- FilesOrigin& altOrigin = (*m_DirectoryStructure)->getOriginByID(altInfo.first);
- unsigned int altIndex = ModInfo::getIndex(ToQString(altOrigin.getName()));
- if (origin.getPriority() > altOrigin.getPriority()) {
- m_OverwriteList.insert(altIndex);
- } else {
- m_OverwrittenList.insert(altIndex);
- }
- }
- }
- }
+ if ((*m_DirectoryStructure)->originExists(name)) {
+ FilesOrigin &origin = (*m_DirectoryStructure)->getOriginByName(name);
+ std::vector<FileEntry::Ptr> files = origin.getFiles();
+ // for all files in this origin
+ for (FileEntry::Ptr file : files) {
+ const std::vector<std::pair<int, std::wstring>> &alternatives = file->getAlternatives();
+ if ((alternatives.size() == 0) || (alternatives.begin()->first == dataID)) {
+ // no alternatives -> no conflict
+ providesAnything = true;
+ } else {
+ if (file->getOrigin() != origin.getID()) {
+ FilesOrigin &altOrigin = (*m_DirectoryStructure)->getOriginByID(file->getOrigin());
+ unsigned int altIndex = ModInfo::getIndex(ToQString(altOrigin.getName()));
+ m_OverwrittenList.insert(altIndex);
+ } else {
+ providesAnything = true;
}
- m_LastConflictCheck = QTime::currentTime();
- if (files.size() != 0) {
- if (!providesAnything)
- m_CurrentConflictState = CONFLICT_REDUNDANT;
- else if (!m_OverwriteList.empty() && !m_OverwrittenList.empty())
- m_CurrentConflictState = CONFLICT_MIXED;
- else if (!m_OverwriteList.empty())
- m_CurrentConflictState = CONFLICT_OVERWRITE;
- else if (!m_OverwrittenList.empty())
- m_CurrentConflictState = CONFLICT_OVERWRITTEN;
+ // for all non-providing alternative origins
+ for (auto altInfo : alternatives) {
+ if ((altInfo.first != dataID) && (altInfo.first != origin.getID())) {
+ FilesOrigin &altOrigin = (*m_DirectoryStructure)->getOriginByID(altInfo.first);
+ unsigned int altIndex = ModInfo::getIndex(ToQString(altOrigin.getName()));
+ if (origin.getPriority() > altOrigin.getPriority()) {
+ m_OverwriteList.insert(altIndex);
+ } else {
+ m_OverwrittenList.insert(altIndex);
+ }
+ }
}
+ }
}
-}
+ m_LastConflictCheck = QTime::currentTime();
-ModInfoWithConflictInfo::EConflictType ModInfoWithConflictInfo::isConflicted() const {
- // this is costy so cache the result
- QTime now = QTime::currentTime();
- if (m_LastConflictCheck.isNull() || (m_LastConflictCheck.secsTo(now) > 10)) {
- doConflictCheck();
+ if (files.size() != 0) {
+ if (!providesAnything)
+ m_CurrentConflictState = CONFLICT_REDUNDANT;
+ else if (!m_OverwriteList.empty() && !m_OverwrittenList.empty())
+ m_CurrentConflictState = CONFLICT_MIXED;
+ else if (!m_OverwriteList.empty())
+ m_CurrentConflictState = CONFLICT_OVERWRITE;
+ else if (!m_OverwrittenList.empty())
+ m_CurrentConflictState = CONFLICT_OVERWRITTEN;
}
+ }
+}
+
+ModInfoWithConflictInfo::EConflictType ModInfoWithConflictInfo::isConflicted() const
+{
+ // this is costy so cache the result
+ QTime now = QTime::currentTime();
+ if (m_LastConflictCheck.isNull() || (m_LastConflictCheck.secsTo(now) > 10)) {
+ doConflictCheck();
+ }
- return m_CurrentConflictState;
+ return m_CurrentConflictState;
}
-bool ModInfoWithConflictInfo::isRedundant() const {
- std::wstring name = ToWString(this->name());
- if ((*m_DirectoryStructure)->originExists(name)) {
- FilesOrigin& origin = (*m_DirectoryStructure)->getOriginByName(name);
- std::vector<FileEntry::Ptr> files = origin.getFiles();
- bool ignore = false;
- for (auto iter = files.begin(); iter != files.end(); ++iter) {
- if ((*iter)->getOrigin(ignore) == origin.getID()) {
- return false;
- }
- }
- return true;
- } else {
+
+bool ModInfoWithConflictInfo::isRedundant() const
+{
+ std::wstring name = ToWString(this->name());
+ if ((*m_DirectoryStructure)->originExists(name)) {
+ FilesOrigin &origin = (*m_DirectoryStructure)->getOriginByName(name);
+ std::vector<FileEntry::Ptr> files = origin.getFiles();
+ bool ignore = false;
+ for (auto iter = files.begin(); iter != files.end(); ++iter) {
+ if ((*iter)->getOrigin(ignore) == origin.getID()) {
return false;
+ }
}
+ return true;
+ } else {
+ return false;
+ }
}
diff --git a/src/modinfowithconflictinfo.h b/src/modinfowithconflictinfo.h
index 05ee6ee1..be31f20f 100644
--- a/src/modinfowithconflictinfo.h
+++ b/src/modinfowithconflictinfo.h
@@ -5,46 +5,60 @@
#include <QTime>
-class ModInfoWithConflictInfo : public ModInfo {
+class ModInfoWithConflictInfo : public ModInfo
+{
public:
- ModInfoWithConflictInfo(MOShared::DirectoryEntry** directoryStructure);
- std::vector<ModInfo::EFlag> getFlags() const;
+ ModInfoWithConflictInfo(MOShared::DirectoryEntry **directoryStructure);
- /**
- * @brief clear all caches held for this mod
- */
- virtual void clearCaches();
+ std::vector<ModInfo::EFlag> getFlags() const;
- virtual std::set<unsigned int> getModOverwrite() { return m_OverwriteList; }
+ /**
+ * @brief clear all caches held for this mod
+ */
+ virtual void clearCaches();
- virtual std::set<unsigned int> getModOverwritten() { return m_OverwrittenList; }
+ virtual std::set<unsigned int> getModOverwrite() { return m_OverwriteList; }
- virtual void doConflictCheck() const;
+ virtual std::set<unsigned int> getModOverwritten() { return m_OverwrittenList; }
+
+ virtual void doConflictCheck() const;
private:
- enum EConflictType { CONFLICT_NONE, CONFLICT_OVERWRITE, CONFLICT_OVERWRITTEN, CONFLICT_MIXED, CONFLICT_REDUNDANT };
+
+ enum EConflictType {
+ CONFLICT_NONE,
+ CONFLICT_OVERWRITE,
+ CONFLICT_OVERWRITTEN,
+ CONFLICT_MIXED,
+ CONFLICT_REDUNDANT
+ };
private:
- /**
- * @return true if there is a conflict for files in this mod
- */
- EConflictType isConflicted() const;
- /**
- * @return true if this mod is completely replaced by others
- */
- bool isRedundant() const;
+ /**
+ * @return true if there is a conflict for files in this mod
+ */
+ EConflictType isConflicted() const;
+
+ /**
+ * @return true if this mod is completely replaced by others
+ */
+ bool isRedundant() const;
private:
- MOShared::DirectoryEntry** m_DirectoryStructure;
- mutable EConflictType m_CurrentConflictState;
- mutable QTime m_LastConflictCheck;
+ MOShared::DirectoryEntry **m_DirectoryStructure;
+
+ mutable EConflictType m_CurrentConflictState;
+ mutable QTime m_LastConflictCheck;
+
+ mutable std::set<unsigned int> m_OverwriteList; // indices of mods overritten by this mod
+ mutable std::set<unsigned int> m_OverwrittenList; // indices of mods overwriting this mod
- mutable std::set<unsigned int> m_OverwriteList; // indices of mods overritten by this mod
- mutable std::set<unsigned int> m_OverwrittenList; // indices of mods overwriting this mod
};
+
+
#endif // MODINFOWITHCONFLICTINFO_H
diff --git a/src/modlist.cpp b/src/modlist.cpp
index 20d1a9cb..4002a424 100644
--- a/src/modlist.cpp
+++ b/src/modlist.cpp
@@ -19,1138 +19,1173 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "modlist.h"
-#include "installationtester.h"
#include "messagedialog.h"
-#include "modlistsortproxy.h"
+#include "installationtester.h"
#include "qtgroupingproxy.h"
-#include "settings.h"
#include "viewmarkingscrollbar.h"
+#include "modlistsortproxy.h"
+#include "settings.h"
#include <appconfig.h>
-#include <report.h>
#include <utility.h>
+#include <report.h>
-#include <QAbstractItemView>
-#include <QApplication>
-#include <QCheckBox>
-#include <QContextMenuEvent>
+#include <QFileInfo>
#include <QDir>
#include <QDirIterator>
-#include <QEvent>
-#include <QFileInfo>
-#include <QMenu>
-#include <QMessageBox>
#include <QMimeData>
-#include <QSortFilterProxyModel>
#include <QStandardItemModel>
+#include <QMessageBox>
#include <QStringList>
+#include <QEvent>
+#include <QContextMenuEvent>
+#include <QMenu>
+#include <QCheckBox>
#include <QWidgetAction>
+#include <QAbstractItemView>
+#include <QSortFilterProxyModel>
+#include <QApplication>
-#include <algorithm>
#include <sstream>
#include <stdexcept>
+#include <algorithm>
+
using namespace MOBase;
-ModList::ModList(QObject* parent)
- : QAbstractItemModel(parent), m_Profile(nullptr), m_NexusInterface(nullptr), m_Modified(false),
- m_FontMetrics(QFont()), m_DropOnItems(false) {
- m_ContentIcons[ModInfo::CONTENT_PLUGIN] =
- std::make_tuple(":/MO/gui/content/plugin", tr("Game Plugins (ESP/ESM/ESL)"));
- m_ContentIcons[ModInfo::CONTENT_INTERFACE] = std::make_tuple(":/MO/gui/content/interface", tr("Interface"));
- m_ContentIcons[ModInfo::CONTENT_MESH] = std::make_tuple(":/MO/gui/content/mesh", tr("Meshes"));
- m_ContentIcons[ModInfo::CONTENT_BSA] = std::make_tuple(":/MO/gui/content/bsa", tr("Bethesda Archive"));
- m_ContentIcons[ModInfo::CONTENT_SCRIPT] = std::make_tuple(":/MO/gui/content/script", tr("Scripts (Papyrus)"));
- m_ContentIcons[ModInfo::CONTENT_SKSE] = std::make_tuple(":/MO/gui/content/skse", tr("Script Extender Plugin"));
- m_ContentIcons[ModInfo::CONTENT_SKYPROC] = std::make_tuple(":/MO/gui/content/skyproc", tr("SkyProc Patcher"));
- m_ContentIcons[ModInfo::CONTENT_SOUND] = std::make_tuple(":/MO/gui/content/sound", tr("Sound or Music"));
- m_ContentIcons[ModInfo::CONTENT_TEXTURE] = std::make_tuple(":/MO/gui/content/texture", tr("Textures"));
- m_ContentIcons[ModInfo::CONTENT_MCM] = std::make_tuple(":/MO/gui/content/menu", tr("MCM Configuration"));
- m_LastCheck.start();
+ModList::ModList(QObject *parent)
+ : QAbstractItemModel(parent)
+ , m_Profile(nullptr)
+ , m_NexusInterface(nullptr)
+ , m_Modified(false)
+ , m_FontMetrics(QFont())
+ , m_DropOnItems(false)
+{
+ m_ContentIcons[ModInfo::CONTENT_PLUGIN] = std::make_tuple(":/MO/gui/content/plugin", tr("Game Plugins (ESP/ESM/ESL)"));
+ m_ContentIcons[ModInfo::CONTENT_INTERFACE] = std::make_tuple(":/MO/gui/content/interface", tr("Interface"));
+ m_ContentIcons[ModInfo::CONTENT_MESH] = std::make_tuple(":/MO/gui/content/mesh", tr("Meshes"));
+ m_ContentIcons[ModInfo::CONTENT_BSA] = std::make_tuple(":/MO/gui/content/bsa", tr("Bethesda Archive"));
+ m_ContentIcons[ModInfo::CONTENT_SCRIPT] = std::make_tuple(":/MO/gui/content/script", tr("Scripts (Papyrus)"));
+ m_ContentIcons[ModInfo::CONTENT_SKSE] = std::make_tuple(":/MO/gui/content/skse", tr("Script Extender Plugin"));
+ m_ContentIcons[ModInfo::CONTENT_SKYPROC] = std::make_tuple(":/MO/gui/content/skyproc", tr("SkyProc Patcher"));
+ m_ContentIcons[ModInfo::CONTENT_SOUND] = std::make_tuple(":/MO/gui/content/sound", tr("Sound or Music"));
+ m_ContentIcons[ModInfo::CONTENT_TEXTURE] = std::make_tuple(":/MO/gui/content/texture", tr("Textures"));
+ m_ContentIcons[ModInfo::CONTENT_MCM] = std::make_tuple(":/MO/gui/content/menu", tr("MCM Configuration"));
+
+ m_LastCheck.start();
}
-ModList::~ModList() {
- m_ModStateChanged.disconnect_all_slots();
- m_ModMoved.disconnect_all_slots();
+ModList::~ModList()
+{
+ m_ModStateChanged.disconnect_all_slots();
+ m_ModMoved.disconnect_all_slots();
}
-void ModList::setProfile(Profile* profile) { m_Profile = profile; }
+void ModList::setProfile(Profile *profile)
+{
+ m_Profile = profile;
+}
-int ModList::rowCount(const QModelIndex& parent) const {
- if (!parent.isValid()) {
- return ModInfo::getNumMods();
- } else {
- return 0;
- }
+int ModList::rowCount(const QModelIndex &parent) const
+{
+ if (!parent.isValid()) {
+ return ModInfo::getNumMods();
+ } else {
+ return 0;
+ }
}
-bool ModList::hasChildren(const QModelIndex& parent) const {
- if (!parent.isValid()) {
- return ModInfo::getNumMods() > 0;
- } else {
- return false;
- }
+bool ModList::hasChildren(const QModelIndex &parent) const
+{
+ if (!parent.isValid()) {
+ return ModInfo::getNumMods() > 0;
+ } else {
+ return false;
+ }
}
-int ModList::columnCount(const QModelIndex&) const { return COL_LASTCOLUMN + 1; }
-QVariant ModList::getOverwriteData(int column, int role) const {
- switch (role) {
+int ModList::columnCount(const QModelIndex &) const
+{
+ return COL_LASTCOLUMN + 1;
+}
+
+
+QVariant ModList::getOverwriteData(int column, int role) const
+{
+ switch (role) {
case Qt::DisplayRole: {
- if (column == 0) {
- return "Overwrite";
- } else {
- return QVariant();
- }
+ if (column == 0) {
+ return "Overwrite";
+ } else {
+ return QVariant();
+ }
} break;
case Qt::CheckStateRole: {
- if (column == 0) {
- return Qt::Checked;
- } else {
- return QVariant();
- }
- } break;
- case Qt::TextAlignmentRole:
- return QVariant(Qt::AlignCenter | Qt::AlignVCenter);
- case Qt::UserRole:
- return -1;
- case Qt::ForegroundRole:
- return QBrush(Qt::red);
- case Qt::ToolTipRole:
- return tr("This entry contains files that have been created inside the virtual data tree (i.e. by the "
- "construction kit)");
- default:
+ if (column == 0) {
+ return Qt::Checked;
+ } else {
return QVariant();
- }
+ }
+ } break;
+ case Qt::TextAlignmentRole: return QVariant(Qt::AlignCenter | Qt::AlignVCenter);
+ case Qt::UserRole: return -1;
+ case Qt::ForegroundRole: return QBrush(Qt::red);
+ case Qt::ToolTipRole: return tr("This entry contains files that have been created inside the virtual data tree (i.e. by the construction kit)");
+ default: return QVariant();
+ }
}
-QString ModList::getFlagText(ModInfo::EFlag flag, ModInfo::Ptr modInfo) const {
- switch (flag) {
- case ModInfo::FLAG_BACKUP:
- return tr("Backup");
- case ModInfo::FLAG_INVALID:
- return tr("No valid game data");
- case ModInfo::FLAG_NOTENDORSED:
- return tr("Not endorsed yet");
- case ModInfo::FLAG_NOTES:
- return QString("<i>%1</i>").arg(modInfo->notes().replace("\n", "<br>"));
- case ModInfo::FLAG_CONFLICT_OVERWRITE:
- return tr("Overwrites files");
- case ModInfo::FLAG_CONFLICT_OVERWRITTEN:
- return tr("Overwritten files");
- case ModInfo::FLAG_CONFLICT_MIXED:
- return tr("Overwrites & Overwritten");
- case ModInfo::FLAG_CONFLICT_REDUNDANT:
- return tr("Redundant");
- default:
- return "";
- }
+
+QString ModList::getFlagText(ModInfo::EFlag flag, ModInfo::Ptr modInfo) const
+{
+ switch (flag) {
+ case ModInfo::FLAG_BACKUP: return tr("Backup");
+ case ModInfo::FLAG_INVALID: return tr("No valid game data");
+ case ModInfo::FLAG_NOTENDORSED: return tr("Not endorsed yet");
+ case ModInfo::FLAG_NOTES: return QString("<i>%1</i>").arg(modInfo->notes().replace("\n", "<br>"));
+ case ModInfo::FLAG_CONFLICT_OVERWRITE: return tr("Overwrites files");
+ case ModInfo::FLAG_CONFLICT_OVERWRITTEN: return tr("Overwritten files");
+ case ModInfo::FLAG_CONFLICT_MIXED: return tr("Overwrites & Overwritten");
+ case ModInfo::FLAG_CONFLICT_REDUNDANT: return tr("Redundant");
+ default: return "";
+ }
}
-QVariantList ModList::contentsToIcons(const std::vector<ModInfo::EContent>& contents) const {
- QVariantList result;
- std::set<ModInfo::EContent> contentsSet(contents.begin(), contents.end());
- for (auto iter = m_ContentIcons.begin(); iter != m_ContentIcons.end(); ++iter) {
- if (contentsSet.find(iter->first) != contentsSet.end()) {
- result.append(std::get<0>(iter->second));
- } else {
- result.append(QString());
- }
+
+QVariantList ModList::contentsToIcons(const std::vector<ModInfo::EContent> &contents) const
+{
+ QVariantList result;
+ std::set<ModInfo::EContent> contentsSet(contents.begin(), contents.end());
+ for (auto iter = m_ContentIcons.begin(); iter != m_ContentIcons.end(); ++iter) {
+ if (contentsSet.find(iter->first) != contentsSet.end()) {
+ result.append(std::get<0>(iter->second));
+ } else {
+ result.append(QString());
}
- return result;
+ }
+ return result;
}
-QString ModList::contentsToToolTip(const std::vector<ModInfo::EContent>& contents) const {
- QString result("<table cellspacing=7>");
+QString ModList::contentsToToolTip(const std::vector<ModInfo::EContent> &contents) const
+{
+ QString result("<table cellspacing=7>");
- std::set<ModInfo::EContent> contentsSet(contents.begin(), contents.end());
- for (auto iter = m_ContentIcons.begin(); iter != m_ContentIcons.end(); ++iter) {
- if (contentsSet.find(iter->first) != contentsSet.end()) {
- result.append(QString("<tr><td><img src=\"%1\" width=32/></td>"
- "<td valign=\"middle\">%2</td></tr>")
- .arg(std::get<0>(iter->second))
- .arg(std::get<1>(iter->second)));
- }
+ std::set<ModInfo::EContent> contentsSet(contents.begin(), contents.end());
+ for (auto iter = m_ContentIcons.begin(); iter != m_ContentIcons.end(); ++iter) {
+ if (contentsSet.find(iter->first) != contentsSet.end()) {
+ result.append(QString("<tr><td><img src=\"%1\" width=32/></td>"
+ "<td valign=\"middle\">%2</td></tr>")
+ .arg(std::get<0>(iter->second)).arg(std::get<1>(iter->second)));
}
- result.append("</table>");
- return result;
+ }
+ result.append("</table>");
+ return result;
}
-QVariant ModList::data(const QModelIndex& modelIndex, int role) const {
- if (m_Profile == nullptr)
- return QVariant();
- if (!modelIndex.isValid())
- return QVariant();
- unsigned int modIndex = modelIndex.row();
- int column = modelIndex.column();
- ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex);
- if ((role == Qt::DisplayRole) || (role == Qt::EditRole)) {
- if ((column == COL_FLAGS) || (column == COL_CONTENT)) {
- return QVariant();
- } else if (column == COL_NAME) {
- return modInfo->name();
- } else if (column == COL_VERSION) {
- VersionInfo verInfo = modInfo->getVersion();
- QString version = verInfo.displayString();
- if (role != Qt::EditRole) {
- if (version.isEmpty() && modInfo->canBeUpdated()) {
- version = "?";
- }
- }
- return version;
- } else if (column == COL_PRIORITY) {
- int priority = modInfo->getFixedPriority();
- if (priority != INT_MIN) {
- return QVariant(); // hide priority for mods where it's fixed
- } else {
- return m_Profile->getModPriority(modIndex);
- }
- } else if (column == COL_MODID) {
- int modID = modInfo->getNexusID();
- if (modID >= 0) {
- return modID;
- } else {
- return QVariant();
- }
- } else if (column == COL_CATEGORY) {
- if (modInfo->hasFlag(ModInfo::FLAG_FOREIGN)) {
- return tr("Non-MO");
- } else {
- int category = modInfo->getPrimaryCategory();
- if (category != -1) {
- CategoryFactory& categoryFactory = CategoryFactory::instance();
- if (categoryFactory.categoryExists(category)) {
- try {
- int categoryIdx = categoryFactory.getCategoryIndex(category);
- return categoryFactory.getCategoryName(categoryIdx);
- } catch (const std::exception& e) {
- qCritical("failed to retrieve category name: %s", e.what());
- return QString();
- }
- } else {
- qWarning("category %d doesn't exist (may have been removed)", category);
- modInfo->setCategory(category, false);
- return QString();
- }
- } else {
- return QVariant();
- }
- }
- } else if (column == COL_INSTALLTIME) {
- // display installation time for mods that can be updated
- if (modInfo->creationTime().isValid()) {
- return modInfo->creationTime();
- } else {
- return QVariant();
- }
- } else {
- return tr("invalid");
- }
- } else if ((role == Qt::CheckStateRole) && (column == 0)) {
- if (modInfo->canBeEnabled()) {
- return m_Profile->modEnabled(modIndex) ? Qt::Checked : Qt::Unchecked;
- } else {
- return QVariant();
- }
- } else if (role == Qt::TextAlignmentRole) {
- if (column == COL_NAME) {
- if (modInfo->getHighlight() & ModInfo::HIGHLIGHT_CENTER) {
- return QVariant(Qt::AlignCenter | Qt::AlignVCenter);
- } else {
- return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
- }
- } else if (column == COL_VERSION) {
- return QVariant(Qt::AlignRight | Qt::AlignVCenter);
- } else {
- return QVariant(Qt::AlignCenter | Qt::AlignVCenter);
+QVariant ModList::data(const QModelIndex &modelIndex, int role) const
+{
+ if (m_Profile == nullptr) return QVariant();
+ if (!modelIndex.isValid()) return QVariant();
+ unsigned int modIndex = modelIndex.row();
+ int column = modelIndex.column();
+
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex);
+ if ((role == Qt::DisplayRole) ||
+ (role == Qt::EditRole)) {
+ if ((column == COL_FLAGS)
+ || (column == COL_CONTENT)) {
+ return QVariant();
+ } else if (column == COL_NAME) {
+ return modInfo->name();
+ } else if (column == COL_VERSION) {
+ VersionInfo verInfo = modInfo->getVersion();
+ QString version = verInfo.displayString();
+ if (role != Qt::EditRole) {
+ if (version.isEmpty() && modInfo->canBeUpdated()) {
+ version = "?";
}
- } else if (role == Qt::UserRole) {
- if (column == COL_CATEGORY) {
- QVariantList categoryNames;
- std::set<int> categories = modInfo->getCategories();
- CategoryFactory& categoryFactory = CategoryFactory::instance();
- for (auto iter = categories.begin(); iter != categories.end(); ++iter) {
- categoryNames.append(categoryFactory.getCategoryName(categoryFactory.getCategoryIndex(*iter)));
- }
- if (categoryNames.count() != 0) {
- return categoryNames;
- } else {
- return QVariant();
- }
- } else if (column == COL_PRIORITY) {
- int priority = modInfo->getFixedPriority();
- if (priority != INT_MIN) {
- return priority;
- } else {
- return m_Profile->getModPriority(modIndex);
+ }
+ return version;
+ } else if (column == COL_PRIORITY) {
+ int priority = modInfo->getFixedPriority();
+ if (priority != INT_MIN) {
+ return QVariant(); // hide priority for mods where it's fixed
+ } else {
+ return m_Profile->getModPriority(modIndex);
+ }
+ } else if (column == COL_MODID) {
+ int modID = modInfo->getNexusID();
+ if (modID >= 0) {
+ return modID;
+ } else {
+ return QVariant();
+ }
+ } else if (column == COL_CATEGORY) {
+ if (modInfo->hasFlag(ModInfo::FLAG_FOREIGN)) {
+ return tr("Non-MO");
+ } else {
+ int category = modInfo->getPrimaryCategory();
+ if (category != -1) {
+ CategoryFactory &categoryFactory = CategoryFactory::instance();
+ if (categoryFactory.categoryExists(category)) {
+ try {
+ int categoryIdx = categoryFactory.getCategoryIndex(category);
+ return categoryFactory.getCategoryName(categoryIdx);
+ } catch (const std::exception &e) {
+ qCritical("failed to retrieve category name: %s", e.what());
+ return QString();
}
+ } else {
+ qWarning("category %d doesn't exist (may have been removed)", category);
+ modInfo->setCategory(category, false);
+ return QString();
+ }
} else {
- return modInfo->getNexusID();
- }
- } else if (role == Qt::UserRole + 1) {
- return modIndex;
- } else if (role == Qt::UserRole + 2) {
- switch (column) {
- case COL_MODID:
- return QtGroupingProxy::AGGR_FIRST;
- case COL_VERSION:
- return QtGroupingProxy::AGGR_MAX;
- case COL_CATEGORY:
- return QtGroupingProxy::AGGR_FIRST;
- case COL_PRIORITY:
- return QtGroupingProxy::AGGR_MIN;
- default:
- return QtGroupingProxy::AGGR_NONE;
- }
- } else if (role == Qt::UserRole + 3) {
- return contentsToIcons(modInfo->getContents());
- } else if (role == Qt::FontRole) {
- QFont result;
- if (column == COL_NAME) {
- if (modInfo->getHighlight() & ModInfo::HIGHLIGHT_INVALID) {
- result.setItalic(true);
- }
- } else if ((column == COL_CATEGORY) && (modInfo->hasFlag(ModInfo::FLAG_FOREIGN))) {
- result.setItalic(true);
- } else if (column == COL_VERSION) {
- if (modInfo->updateAvailable() || modInfo->downgradeAvailable()) {
- result.setWeight(QFont::Bold);
- }
- }
- return result;
- } else if (role == Qt::DecorationRole) {
- if (column == COL_VERSION) {
- if (modInfo->updateAvailable()) {
- return QIcon(":/MO/gui/update_available");
- } else if (modInfo->downgradeAvailable()) {
- return QIcon(":/MO/gui/warning");
- } else if (modInfo->getVersion().scheme() == VersionInfo::SCHEME_DATE) {
- return QIcon(":/MO/gui/version_date");
- }
+ return QVariant();
}
+ }
+ } else if (column == COL_INSTALLTIME) {
+ // display installation time for mods that can be updated
+ if (modInfo->creationTime().isValid()) {
+ return modInfo->creationTime();
+ } else {
return QVariant();
- } else if (role == Qt::ForegroundRole) {
- if (column == COL_NAME) {
- int highlight = modInfo->getHighlight();
- if (highlight & ModInfo::HIGHLIGHT_IMPORTANT)
- return QBrush(Qt::darkRed);
- else if (highlight & ModInfo::HIGHLIGHT_INVALID)
- return QBrush(Qt::darkGray);
- else if (highlight & ModInfo::HIGHLIGHT_PLUGIN)
- return QBrush(Qt::darkBlue);
- } else if (column == COL_VERSION) {
- if (!modInfo->getNewestVersion().isValid()) {
- return QVariant();
- } else if (modInfo->updateAvailable() || modInfo->downgradeAvailable()) {
- return QBrush(Qt::red);
- } else {
- return QBrush(Qt::darkGreen);
- }
- }
+ }
+ } else {
+ return tr("invalid");
+ }
+ } else if ((role == Qt::CheckStateRole) && (column == 0)) {
+ if (modInfo->canBeEnabled()) {
+ return m_Profile->modEnabled(modIndex) ? Qt::Checked : Qt::Unchecked;
+ } else {
+ return QVariant();
+ }
+ } else if (role == Qt::TextAlignmentRole) {
+ if (column == COL_NAME) {
+ if (modInfo->getHighlight() & ModInfo::HIGHLIGHT_CENTER) {
+ return QVariant(Qt::AlignCenter | Qt::AlignVCenter);
+ } else {
+ return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
+ }
+ } else if (column == COL_VERSION) {
+ return QVariant(Qt::AlignRight | Qt::AlignVCenter);
+ } else {
+ return QVariant(Qt::AlignCenter | Qt::AlignVCenter);
+ }
+ } else if (role == Qt::UserRole) {
+ if (column == COL_CATEGORY) {
+ QVariantList categoryNames;
+ std::set<int> categories = modInfo->getCategories();
+ CategoryFactory &categoryFactory = CategoryFactory::instance();
+ for (auto iter = categories.begin(); iter != categories.end(); ++iter) {
+ categoryNames.append(categoryFactory.getCategoryName(categoryFactory.getCategoryIndex(*iter)));
+ }
+ if (categoryNames.count() != 0) {
+ return categoryNames;
+ } else {
return QVariant();
- } else if ((role == Qt::BackgroundRole) || (role == ViewMarkingScrollBar::DEFAULT_ROLE)) {
- if (modInfo->getHighlight() & ModInfo::HIGHLIGHT_PLUGIN) {
- return QColor(0, 0, 255, 32);
- } else if (m_Overwrite.find(modIndex) != m_Overwrite.end()) {
- return QColor(0, 255, 0, 32);
- } else if (m_Overwritten.find(modIndex) != m_Overwritten.end()) {
- return QColor(255, 0, 0, 32);
- } else {
- return QVariant();
- }
- } else if (role == Qt::ToolTipRole) {
- if (column == COL_FLAGS) {
- QString result;
-
- for (ModInfo::EFlag flag : modInfo->getFlags()) {
- if (result.length() != 0)
- result += "<br>";
- result += getFlagText(flag, modInfo);
- }
+ }
+ } else if (column == COL_PRIORITY) {
+ int priority = modInfo->getFixedPriority();
+ if (priority != INT_MIN) {
+ return priority;
+ } else {
+ return m_Profile->getModPriority(modIndex);
+ }
+ } else {
+ return modInfo->getNexusID();
+ }
+ } else if (role == Qt::UserRole + 1) {
+ return modIndex;
+ } else if (role == Qt::UserRole + 2) {
+ switch (column) {
+ case COL_MODID: return QtGroupingProxy::AGGR_FIRST;
+ case COL_VERSION: return QtGroupingProxy::AGGR_MAX;
+ case COL_CATEGORY: return QtGroupingProxy::AGGR_FIRST;
+ case COL_PRIORITY: return QtGroupingProxy::AGGR_MIN;
+ default: return QtGroupingProxy::AGGR_NONE;
+ }
+ } else if (role == Qt::UserRole + 3) {
+ return contentsToIcons(modInfo->getContents());
+ } else if (role == Qt::FontRole) {
+ QFont result;
+ if (column == COL_NAME) {
+ if (modInfo->getHighlight() & ModInfo::HIGHLIGHT_INVALID) {
+ result.setItalic(true);
+ }
+ } else if ((column == COL_CATEGORY) && (modInfo->hasFlag(ModInfo::FLAG_FOREIGN))) {
+ result.setItalic(true);
+ } else if (column == COL_VERSION) {
+ if (modInfo->updateAvailable() || modInfo->downgradeAvailable()) {
+ result.setWeight(QFont::Bold);
+ }
+ }
+ return result;
+ } else if (role == Qt::DecorationRole) {
+ if (column == COL_VERSION) {
+ if (modInfo->updateAvailable()) {
+ return QIcon(":/MO/gui/update_available");
+ } else if (modInfo->downgradeAvailable()) {
+ return QIcon(":/MO/gui/warning");
+ } else if (modInfo->getVersion().scheme() == VersionInfo::SCHEME_DATE) {
+ return QIcon(":/MO/gui/version_date");
+ }
+ }
+ return QVariant();
+ } else if (role == Qt::ForegroundRole) {
+ if (column == COL_NAME) {
+ int highlight = modInfo->getHighlight();
+ if (highlight & ModInfo::HIGHLIGHT_IMPORTANT) return QBrush(Qt::darkRed);
+ else if (highlight & ModInfo::HIGHLIGHT_INVALID) return QBrush(Qt::darkGray);
+ else if (highlight & ModInfo::HIGHLIGHT_PLUGIN) return QBrush(Qt::darkBlue);
+ } else if (column == COL_VERSION) {
+ if (!modInfo->getNewestVersion().isValid()) {
+ return QVariant();
+ } else if (modInfo->updateAvailable() || modInfo->downgradeAvailable()) {
+ return QBrush(Qt::red);
+ } else {
+ return QBrush(Qt::darkGreen);
+ }
+ }
+ return QVariant();
+ } else if ((role == Qt::BackgroundRole)
+ || (role == ViewMarkingScrollBar::DEFAULT_ROLE)) {
+ if (modInfo->getHighlight() & ModInfo::HIGHLIGHT_PLUGIN) {
+ return QColor(0, 0, 255, 32);
+ } else if (m_Overwrite.find(modIndex) != m_Overwrite.end()) {
+ return QColor(0, 255, 0, 32);
+ } else if (m_Overwritten.find(modIndex) != m_Overwritten.end()) {
+ return QColor(255, 0, 0, 32);
+ } else {
+ return QVariant();
+ }
+ } else if (role == Qt::ToolTipRole) {
+ if (column == COL_FLAGS) {
+ QString result;
- return result;
- } else if (column == COL_CONTENT) {
- return contentsToToolTip(modInfo->getContents());
- } else if (column == COL_NAME) {
- try {
- return modInfo->getDescription();
- } catch (const std::exception& e) {
- qCritical("invalid mod description: %s", e.what());
- return QString();
- }
- } else if (column == COL_VERSION) {
- QString text = tr("installed version: \"%1\", newest version: \"%2\"")
- .arg(modInfo->getVersion().displayString())
- .arg(modInfo->getNewestVersion().displayString());
- if (modInfo->downgradeAvailable()) {
- text += "<br>" + tr("The newest version on Nexus seems to be older than the one you have installed. "
- "This could either mean the version you have has been withdrawn "
- "(i.e. due to a bug) or the author uses a non-standard versioning scheme and that "
- "newest version is actually newer. "
- "Either way you may want to \"upgrade\".");
- }
- return text;
- } else if (column == COL_CATEGORY) {
- const std::set<int>& categories = modInfo->getCategories();
- std::wostringstream categoryString;
- categoryString << ToWString(tr("Categories: <br>"));
- CategoryFactory& categoryFactory = CategoryFactory::instance();
- for (std::set<int>::const_iterator catIter = categories.begin(); catIter != categories.end(); ++catIter) {
- if (catIter != categories.begin()) {
- categoryString << " , ";
- }
- try {
- categoryString << "<span style=\"white-space: nowrap;\"><i>"
- << ToWString(
- categoryFactory.getCategoryName(categoryFactory.getCategoryIndex(*catIter)))
- << "</font></span>";
- } catch (const std::exception& e) {
- qCritical("failed to generate tooltip: %s", e.what());
- return QString();
- }
- }
+ for (ModInfo::EFlag flag : modInfo->getFlags()) {
+ if (result.length() != 0) result += "<br>";
+ result += getFlagText(flag, modInfo);
+ }
- return ToQString(categoryString.str());
- } else {
- return QVariant();
+ return result;
+ } else if (column == COL_CONTENT) {
+ return contentsToToolTip(modInfo->getContents());
+ } else if (column == COL_NAME) {
+ try {
+ return modInfo->getDescription();
+ } catch (const std::exception &e) {
+ qCritical("invalid mod description: %s", e.what());
+ return QString();
+ }
+ } else if (column == COL_VERSION) {
+ QString text = tr("installed version: \"%1\", newest version: \"%2\"").arg(modInfo->getVersion().displayString()).arg(modInfo->getNewestVersion().displayString());
+ if (modInfo->downgradeAvailable()) {
+ text += "<br>" + tr("The newest version on Nexus seems to be older than the one you have installed. This could either mean the version you have has been withdrawn "
+ "(i.e. due to a bug) or the author uses a non-standard versioning scheme and that newest version is actually newer. "
+ "Either way you may want to \"upgrade\".");
+ }
+ return text;
+ } else if (column == COL_CATEGORY) {
+ const std::set<int> &categories = modInfo->getCategories();
+ std::wostringstream categoryString;
+ categoryString << ToWString(tr("Categories: <br>"));
+ CategoryFactory &categoryFactory = CategoryFactory::instance();
+ for (std::set<int>::const_iterator catIter = categories.begin();
+ catIter != categories.end(); ++catIter) {
+ if (catIter != categories.begin()) {
+ categoryString << " , ";
+ }
+ try {
+ categoryString << "<span style=\"white-space: nowrap;\"><i>" << ToWString(categoryFactory.getCategoryName(categoryFactory.getCategoryIndex(*catIter))) << "</font></span>";
+ } catch (const std::exception &e) {
+ qCritical("failed to generate tooltip: %s", e.what());
+ return QString();
}
+ }
+
+ return ToQString(categoryString.str());
} else {
- return QVariant();
+ return QVariant();
}
+ } else {
+ return QVariant();
+ }
}
-bool ModList::renameMod(int index, const QString& newName) {
- QString nameFixed = newName;
- if (!fixDirectoryName(nameFixed) || nameFixed.isEmpty()) {
- MessageDialog::showMessage(tr("Invalid name"), nullptr);
- return false;
- }
- ModInfo::Ptr modInfo = ModInfo::getByIndex(index);
- QString oldName = modInfo->name();
- if (newName != oldName) {
- // before we rename, ensure there is no scheduled asynchronous to rewrite
- m_Profile->cancelModlistWrite();
+bool ModList::renameMod(int index, const QString &newName)
+{
+ QString nameFixed = newName;
+ if (!fixDirectoryName(nameFixed) || nameFixed.isEmpty()) {
+ MessageDialog::showMessage(tr("Invalid name"), nullptr);
+ return false;
+ }
- if (modInfo->setName(nameFixed))
- // Notice there is a good chance that setName() updated the modinfo indexes
- // the modRenamed() call will refresh the indexes in the current profile
- // and update the modlists in all profiles
- emit modRenamed(oldName, nameFixed);
- }
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(index);
+ QString oldName = modInfo->name();
+ if (newName != oldName) {
+ // before we rename, ensure there is no scheduled asynchronous to rewrite
+ m_Profile->cancelModlistWrite();
- // invalidate the currently displayed state of this list
- notifyChange(-1);
- return true;
+
+ if (modInfo->setName(nameFixed))
+ // Notice there is a good chance that setName() updated the modinfo indexes
+ // the modRenamed() call will refresh the indexes in the current profile
+ // and update the modlists in all profiles
+ emit modRenamed(oldName, nameFixed);
+ }
+
+ // invalidate the currently displayed state of this list
+ notifyChange(-1);
+ return true;
}
-bool ModList::setData(const QModelIndex& index, const QVariant& value, int role) {
- if (m_Profile == nullptr)
- return false;
+bool ModList::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ if (m_Profile == nullptr) return false;
- if (static_cast<unsigned int>(index.row()) >= ModInfo::getNumMods()) {
- return false;
- }
+ if (static_cast<unsigned int>(index.row()) >= ModInfo::getNumMods()) {
+ return false;
+ }
- int modID = index.row();
+ int modID = index.row();
- ModInfo::Ptr info = ModInfo::getByIndex(modID);
- IModList::ModStates oldState = state(modID);
+ ModInfo::Ptr info = ModInfo::getByIndex(modID);
+ IModList::ModStates oldState = state(modID);
- bool result = false;
+ bool result = false;
- emit aboutToChangeData();
+ emit aboutToChangeData();
- if (role == Qt::CheckStateRole) {
- bool enabled = value.toInt() == Qt::Checked;
- if (m_Profile->modEnabled(modID) != enabled) {
- m_Profile->setModEnabled(modID, enabled);
- m_Modified = true;
- m_LastCheck.restart();
- emit modlist_changed(index, role);
- }
- result = true;
- emit dataChanged(index, index);
- } else if (role == Qt::EditRole) {
- switch (index.column()) {
- case COL_NAME: {
- result = renameMod(modID, value.toString());
- } break;
- case COL_PRIORITY: {
- bool ok = false;
- int newPriority = value.toInt(&ok);
- if (ok) {
- m_Profile->setModPriority(modID, newPriority);
+ if (role == Qt::CheckStateRole) {
+ bool enabled = value.toInt() == Qt::Checked;
+ if (m_Profile->modEnabled(modID) != enabled) {
+ m_Profile->setModEnabled(modID, enabled);
+ m_Modified = true;
+ m_LastCheck.restart();
+ emit modlist_changed(index, role);
+ }
+ result = true;
+ emit dataChanged(index, index);
+ } else if (role == Qt::EditRole) {
+ switch (index.column()) {
+ case COL_NAME: {
+ result = renameMod(modID, value.toString());
+ } break;
+ case COL_PRIORITY: {
+ bool ok = false;
+ int newPriority = value.toInt(&ok);
+ if (ok) {
+ m_Profile->setModPriority(modID, newPriority);
- emit modorder_changed();
- result = true;
- } else {
- result = false;
- }
- } break;
- case COL_MODID: {
- bool ok = false;
- int newID = value.toInt(&ok);
- if (ok) {
- info->setNexusID(newID);
- emit modlist_changed(index, role);
- result = true;
- } else {
- result = false;
- }
- } break;
- case COL_VERSION: {
- VersionInfo::VersionScheme scheme = info->getVersion().scheme();
- VersionInfo version(value.toString(), scheme, true);
- if (version.isValid()) {
- info->setVersion(version);
- result = true;
- } else {
- result = false;
- }
- } break;
- default: {
- qWarning("edit on column \"%s\" not supported", getColumnName(index.column()).toUtf8().constData());
- result = false;
- } break;
+ emit modorder_changed();
+ result = true;
+ } else {
+ result = false;
}
- if (result) {
- emit dataChanged(index, index);
+ } break;
+ case COL_MODID: {
+ bool ok = false;
+ int newID = value.toInt(&ok);
+ if (ok) {
+ info->setNexusID(newID);
+ emit modlist_changed(index, role);
+ result = true;
+ } else {
+ result = false;
}
+ } break;
+ case COL_VERSION: {
+ VersionInfo::VersionScheme scheme = info->getVersion().scheme();
+ VersionInfo version(value.toString(), scheme, true);
+ if (version.isValid()) {
+ info->setVersion(version);
+ result = true;
+ } else {
+ result = false;
+ }
+ } break;
+ default: {
+ qWarning("edit on column \"%s\" not supported",
+ getColumnName(index.column()).toUtf8().constData());
+ result = false;
+ } break;
+ }
+ if (result) {
+ emit dataChanged(index, index);
}
+ }
- emit postDataChanged();
+ emit postDataChanged();
- IModList::ModStates newState = state(modID);
- if (oldState != newState) {
- try {
- m_ModStateChanged(info->name(), newState);
- } catch (const std::exception& e) {
- qCritical("failed to invoke state changed notification: %s", e.what());
- } catch (...) {
- qCritical("failed to invoke state changed notification: unknown exception");
- }
+ IModList::ModStates newState = state(modID);
+ if (oldState != newState) {
+ try {
+ m_ModStateChanged(info->name(), newState);
+ } catch (const std::exception &e) {
+ qCritical("failed to invoke state changed notification: %s", e.what());
+ } catch (...) {
+ qCritical("failed to invoke state changed notification: unknown exception");
}
+ }
- return result;
+ return result;
}
-QVariant ModList::headerData(int section, Qt::Orientation orientation, int role) const {
- if (orientation == Qt::Horizontal) {
- if (role == Qt::DisplayRole) {
- return getColumnName(section);
- } else if (role == Qt::ToolTipRole) {
- return getColumnToolTip(section);
- } else if (role == Qt::TextAlignmentRole) {
- return QVariant(Qt::AlignCenter);
- } else if (role == Qt::SizeHintRole) {
- QSize temp = m_FontMetrics.size(Qt::TextSingleLine, getColumnName(section));
- temp.rwidth() += 20;
- temp.rheight() += 12;
- return temp;
- }
+
+QVariant ModList::headerData(int section, Qt::Orientation orientation,
+ int role) const
+{
+ if (orientation == Qt::Horizontal) {
+ if (role == Qt::DisplayRole) {
+ return getColumnName(section);
+ } else if (role == Qt::ToolTipRole) {
+ return getColumnToolTip(section);
+ } else if (role == Qt::TextAlignmentRole) {
+ return QVariant(Qt::AlignCenter);
+ } else if (role == Qt::SizeHintRole) {
+ QSize temp = m_FontMetrics.size(Qt::TextSingleLine, getColumnName(section));
+ temp.rwidth() += 20;
+ temp.rheight() += 12;
+ return temp;
}
- return QAbstractItemModel::headerData(section, orientation, role);
+ }
+ return QAbstractItemModel::headerData(section, orientation, role);
}
-Qt::ItemFlags ModList::flags(const QModelIndex& modelIndex) const {
- Qt::ItemFlags result = QAbstractItemModel::flags(modelIndex);
- if (modelIndex.internalId() < 0) {
- return Qt::ItemIsEnabled;
+
+Qt::ItemFlags ModList::flags(const QModelIndex &modelIndex) const
+{
+ Qt::ItemFlags result = QAbstractItemModel::flags(modelIndex);
+ if (modelIndex.internalId() < 0) {
+ return Qt::ItemIsEnabled;
+ }
+ if (modelIndex.isValid()) {
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(modelIndex.row());
+ if (modInfo->getFixedPriority() == INT_MIN) {
+ result |= Qt::ItemIsDragEnabled;
+ result |= Qt::ItemIsUserCheckable;
+ if ((modelIndex.column() == COL_NAME) ||
+ (modelIndex.column() == COL_PRIORITY) ||
+ (modelIndex.column() == COL_VERSION) ||
+ (modelIndex.column() == COL_MODID)) {
+ result |= Qt::ItemIsEditable;
+ }
}
- if (modelIndex.isValid()) {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(modelIndex.row());
- if (modInfo->getFixedPriority() == INT_MIN) {
- result |= Qt::ItemIsDragEnabled;
- result |= Qt::ItemIsUserCheckable;
- if ((modelIndex.column() == COL_NAME) || (modelIndex.column() == COL_PRIORITY) ||
- (modelIndex.column() == COL_VERSION) || (modelIndex.column() == COL_MODID)) {
- result |= Qt::ItemIsEditable;
- }
- }
- std::vector<ModInfo::EFlag> flags = modInfo->getFlags();
- if (m_DropOnItems && (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) == flags.end())) {
- result |= Qt::ItemIsDropEnabled;
- }
- } else {
- if (!m_DropOnItems)
- result |= Qt::ItemIsDropEnabled;
+ std::vector<ModInfo::EFlag> flags = modInfo->getFlags();
+ if (m_DropOnItems
+ && (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) == flags.end())) {
+ result |= Qt::ItemIsDropEnabled;
}
- return result;
+ } else {
+ if (!m_DropOnItems) result |= Qt::ItemIsDropEnabled;
+ }
+ return result;
}
-QStringList ModList::mimeTypes() const {
- QStringList result = QAbstractItemModel::mimeTypes();
- result.append("text/uri-list");
- return result;
+
+QStringList ModList::mimeTypes() const
+{
+ QStringList result = QAbstractItemModel::mimeTypes();
+ result.append("text/uri-list");
+ return result;
}
-QMimeData* ModList::mimeData(const QModelIndexList& indexes) const {
- QMimeData* result = QAbstractItemModel::mimeData(indexes);
- result->setData("text/plain", "mod");
- return result;
+QMimeData *ModList::mimeData(const QModelIndexList &indexes) const
+{
+ QMimeData *result = QAbstractItemModel::mimeData(indexes);
+ result->setData("text/plain", "mod");
+ return result;
}
-void ModList::changeModPriority(std::vector<int> sourceIndices, int newPriority) {
- if (m_Profile == nullptr)
- return;
+void ModList::changeModPriority(std::vector<int> sourceIndices, int newPriority)
+{
+ if (m_Profile == nullptr) return;
- emit layoutAboutToBeChanged();
- Profile* profile = m_Profile;
- // sort rows to insert by their old priority (ascending) and insert them move them in that order
- std::sort(sourceIndices.begin(), sourceIndices.end(), [profile](const int& LHS, const int& RHS) {
- return profile->getModPriority(LHS) < profile->getModPriority(RHS);
- });
+ emit layoutAboutToBeChanged();
+ Profile *profile = m_Profile;
+ // sort rows to insert by their old priority (ascending) and insert them move them in that order
+ std::sort(sourceIndices.begin(), sourceIndices.end(),
+ [profile](const int &LHS, const int &RHS) {
+ return profile->getModPriority(LHS) < profile->getModPriority(RHS);
+ });
- // odd stuff: if any of the dragged sources has priority lower than the destination then the
- // target idx is that of the row BELOW the dropped location, otherwise it's the one above. why?
- for (std::vector<int>::const_iterator iter = sourceIndices.begin(); iter != sourceIndices.end(); ++iter) {
- if (profile->getModPriority(*iter) < newPriority) {
- --newPriority;
- break;
- }
- }
- for (std::vector<int>::const_iterator iter = sourceIndices.begin(); iter != sourceIndices.end(); ++iter) {
- int oldPriority = m_Profile->getModPriority(*iter);
- m_Profile->setModPriority(*iter, newPriority);
- m_ModMoved(ModInfo::getByIndex(*iter)->name(), oldPriority, newPriority);
+ // odd stuff: if any of the dragged sources has priority lower than the destination then the
+ // target idx is that of the row BELOW the dropped location, otherwise it's the one above. why?
+ for (std::vector<int>::const_iterator iter = sourceIndices.begin();
+ iter != sourceIndices.end(); ++iter) {
+ if (profile->getModPriority(*iter) < newPriority) {
+ --newPriority;
+ break;
}
+ }
+ for (std::vector<int>::const_iterator iter = sourceIndices.begin();
+ iter != sourceIndices.end(); ++iter) {
+ int oldPriority = m_Profile->getModPriority(*iter);
+ m_Profile->setModPriority(*iter, newPriority);
+ m_ModMoved(ModInfo::getByIndex(*iter)->name(), oldPriority, newPriority);
+ }
- emit layoutChanged();
+ emit layoutChanged();
- emit modorder_changed();
+ emit modorder_changed();
}
-void ModList::changeModPriority(int sourceIndex, int newPriority) {
- if (m_Profile == nullptr)
- return;
- emit layoutAboutToBeChanged();
- m_Profile->setModPriority(sourceIndex, newPriority);
+void ModList::changeModPriority(int sourceIndex, int newPriority)
+{
+ if (m_Profile == nullptr) return;
+ emit layoutAboutToBeChanged();
- emit layoutChanged();
+ m_Profile->setModPriority(sourceIndex, newPriority);
- emit modorder_changed();
-}
+ emit layoutChanged();
-void ModList::setOverwriteMarkers(const std::set<unsigned int>& overwrite, const std::set<unsigned int>& overwritten) {
- m_Overwrite = overwrite;
- m_Overwritten = overwritten;
- notifyChange(0, rowCount() - 1);
+ emit modorder_changed();
}
-bool ModList::modInfoAboutToChange(ModInfo::Ptr info) {
- if (m_ChangeInfo.name.isEmpty()) {
- m_ChangeInfo.name = info->name();
- m_ChangeInfo.state = state(info->name());
- return true;
- } else {
- return false;
- }
+void ModList::setOverwriteMarkers(const std::set<unsigned int> &overwrite, const std::set<unsigned int> &overwritten)
+{
+ m_Overwrite = overwrite;
+ m_Overwritten = overwritten;
+ notifyChange(0, rowCount() - 1);
}
-void ModList::modInfoChanged(ModInfo::Ptr info) {
- if (info->name() == m_ChangeInfo.name) {
- IModList::ModStates newState = state(info->name());
- if (m_ChangeInfo.state != newState) {
- m_ModStateChanged(info->name(), newState);
- }
+bool ModList::modInfoAboutToChange(ModInfo::Ptr info)
+{
+ if (m_ChangeInfo.name.isEmpty()) {
+ m_ChangeInfo.name = info->name();
+ m_ChangeInfo.state = state(info->name());
+ return true;
+ } else {
+ return false;
+ }
+}
- int row = ModInfo::getIndex(info->name());
- info->testValid();
- emit dataChanged(index(row, 0), index(row, columnCount()));
- } else {
- qCritical("modInfoChanged not called after modInfoAboutToChange");
+void ModList::modInfoChanged(ModInfo::Ptr info)
+{
+ if (info->name() == m_ChangeInfo.name) {
+ IModList::ModStates newState = state(info->name());
+ if (m_ChangeInfo.state != newState) {
+ m_ModStateChanged(info->name(), newState);
}
- m_ChangeInfo.name = QString();
+
+ int row = ModInfo::getIndex(info->name());
+ info->testValid();
+ emit dataChanged(index(row, 0), index(row, columnCount()));
+ } else {
+ qCritical("modInfoChanged not called after modInfoAboutToChange");
+ }
+ m_ChangeInfo.name = QString();
}
void ModList::disconnectSlots() {
- m_ModMoved.disconnect_all_slots();
- m_ModStateChanged.disconnect_all_slots();
+ m_ModMoved.disconnect_all_slots();
+ m_ModStateChanged.disconnect_all_slots();
}
-int ModList::timeElapsedSinceLastChecked() const { return m_LastCheck.elapsed(); }
+int ModList::timeElapsedSinceLastChecked() const
+{
+ return m_LastCheck.elapsed();
+}
-void ModList::highlightMods(const QItemSelection& selected, const MOShared::DirectoryEntry& directoryEntry) {
- for (unsigned int i = 0; i < ModInfo::getNumMods(); ++i) {
- ModInfo::getByIndex(i)->setPluginSelected(false);
- }
- for (QModelIndex idx : selected.indexes()) {
- QString modName = idx.data().toString();
+void ModList::highlightMods(const QItemSelection &selected, const MOShared::DirectoryEntry &directoryEntry)
+{
+ for (unsigned int i = 0; i < ModInfo::getNumMods(); ++i) {
+ ModInfo::getByIndex(i)->setPluginSelected(false);
+ }
+ for (QModelIndex idx : selected.indexes()) {
+ QString modName = idx.data().toString();
- const MOShared::FileEntry::Ptr fileEntry = directoryEntry.findFile(modName.toStdWString());
- if (fileEntry.get() != nullptr) {
- QString fileName;
- bool archive = false;
- std::vector<std::pair<int, std::wstring>> origins;
- {
- std::vector<std::pair<int, std::wstring>> alternatives = fileEntry->getAlternatives();
- origins.insert(origins.end(),
- std::pair<int, std::wstring>(fileEntry->getOrigin(archive), fileEntry->getArchive()));
- }
- for (auto originInfo : origins) {
- MOShared::FilesOrigin& origin = directoryEntry.getOriginByID(originInfo.first);
- for (unsigned int i = 0; i < ModInfo::getNumMods(); ++i) {
- if (ModInfo::getByIndex(i)->internalName() == QString::fromStdWString(origin.getName())) {
- ModInfo::getByIndex(i)->setPluginSelected(true);
- break;
- }
- }
- }
+ const MOShared::FileEntry::Ptr fileEntry = directoryEntry.findFile(modName.toStdWString());
+ if (fileEntry.get() != nullptr) {
+ QString fileName;
+ bool archive = false;
+ std::vector<std::pair<int, std::wstring>> origins;
+ {
+ std::vector<std::pair<int, std::wstring>> alternatives = fileEntry->getAlternatives();
+ origins.insert(origins.end(), std::pair<int, std::wstring>(fileEntry->getOrigin(archive), fileEntry->getArchive()));
+ }
+ for (auto originInfo : origins) {
+ MOShared::FilesOrigin &origin = directoryEntry.getOriginByID(originInfo.first);
+ for (unsigned int i = 0; i < ModInfo::getNumMods(); ++i) {
+ if (ModInfo::getByIndex(i)->internalName() == QString::fromStdWString(origin.getName())) {
+ ModInfo::getByIndex(i)->setPluginSelected(true);
+ break;
+ }
}
+ }
}
- notifyChange(0, rowCount() - 1);
+ }
+ notifyChange(0, rowCount() - 1);
}
-IModList::ModStates ModList::state(unsigned int modIndex) const {
- IModList::ModStates result;
- if (modIndex != UINT_MAX) {
- result |= IModList::STATE_EXISTS;
- ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex);
- if (modInfo->isEmpty()) {
- result |= IModList::STATE_EMPTY;
- }
- if (modInfo->endorsedState() == ModInfo::ENDORSED_TRUE) {
- result |= IModList::STATE_ENDORSED;
- }
- if (modInfo->isValid()) {
- result |= IModList::STATE_VALID;
- }
- if (modInfo->canBeEnabled()) {
- if (m_Profile->modEnabled(modIndex)) {
- result |= IModList::STATE_ACTIVE;
- }
- } else {
- result |= IModList::STATE_ESSENTIAL;
- }
+IModList::ModStates ModList::state(unsigned int modIndex) const
+{
+ IModList::ModStates result;
+ if (modIndex != UINT_MAX) {
+ result |= IModList::STATE_EXISTS;
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex);
+ if (modInfo->isEmpty()) {
+ result |= IModList::STATE_EMPTY;
}
- return result;
-}
-
-QString ModList::displayName(const QString& internalName) const {
- unsigned int modIndex = ModInfo::getIndex(internalName);
- if (modIndex == UINT_MAX) {
- // might be better to throw an exception?
- return internalName;
+ if (modInfo->endorsedState() == ModInfo::ENDORSED_TRUE) {
+ result |= IModList::STATE_ENDORSED;
+ }
+ if (modInfo->isValid()) {
+ result |= IModList::STATE_VALID;
+ }
+ if (modInfo->canBeEnabled()) {
+ if (m_Profile->modEnabled(modIndex)) {
+ result |= IModList::STATE_ACTIVE;
+ }
} else {
- return ModInfo::getByIndex(modIndex)->name();
+ result |= IModList::STATE_ESSENTIAL;
}
+ }
+ return result;
}
-QStringList ModList::allMods() const {
- QStringList result;
- for (unsigned int i = 0; i < ModInfo::getNumMods(); ++i) {
- result.append(ModInfo::getByIndex(i)->internalName());
- }
- return result;
+QString ModList::displayName(const QString &internalName) const
+{
+ unsigned int modIndex = ModInfo::getIndex(internalName);
+ if (modIndex == UINT_MAX) {
+ // might be better to throw an exception?
+ return internalName;
+ } else {
+ return ModInfo::getByIndex(modIndex)->name();
+ }
}
-IModList::ModStates ModList::state(const QString& name) const {
- unsigned int modIndex = ModInfo::getIndex(name);
+QStringList ModList::allMods() const
+{
+ QStringList result;
+ for (unsigned int i = 0; i < ModInfo::getNumMods(); ++i) {
+ result.append(ModInfo::getByIndex(i)->internalName());
+ }
+ return result;
+}
+
+IModList::ModStates ModList::state(const QString &name) const
+{
+ unsigned int modIndex = ModInfo::getIndex(name);
- return state(modIndex);
+ return state(modIndex);
}
-bool ModList::setActive(const QString& name, bool active) {
- unsigned int modIndex = ModInfo::getIndex(name);
- if (modIndex == UINT_MAX) {
- return false;
- } else {
- m_Profile->setModEnabled(modIndex, active);
+bool ModList::setActive(const QString &name, bool active)
+{
+ unsigned int modIndex = ModInfo::getIndex(name);
+ if (modIndex == UINT_MAX) {
+ return false;
+ } else {
+ m_Profile->setModEnabled(modIndex, active);
- IModList::ModStates newState = state(modIndex);
- m_ModStateChanged(name, newState);
- return true;
- }
+ IModList::ModStates newState = state(modIndex);
+ m_ModStateChanged(name, newState);
+ return true;
+ }
}
-int ModList::priority(const QString& name) const {
- unsigned int modIndex = ModInfo::getIndex(name);
- if (modIndex == UINT_MAX) {
- return -1;
- } else {
- return m_Profile->getModPriority(modIndex);
- }
+int ModList::priority(const QString &name) const
+{
+ unsigned int modIndex = ModInfo::getIndex(name);
+ if (modIndex == UINT_MAX) {
+ return -1;
+ } else {
+ return m_Profile->getModPriority(modIndex);
+ }
}
-bool ModList::setPriority(const QString& name, int newPriority) {
- if ((newPriority < 0) || (newPriority >= static_cast<int>(m_Profile->numRegularMods()))) {
- return false;
- }
+bool ModList::setPriority(const QString &name, int newPriority)
+{
+ if ((newPriority < 0) || (newPriority >= static_cast<int>(m_Profile->numRegularMods()))) {
+ return false;
+ }
- unsigned int modIndex = ModInfo::getIndex(name);
- if (modIndex == UINT_MAX) {
- return false;
- } else {
- m_Profile->setModPriority(modIndex, newPriority);
- notifyChange(modIndex);
- return true;
- }
+ unsigned int modIndex = ModInfo::getIndex(name);
+ if (modIndex == UINT_MAX) {
+ return false;
+ } else {
+ m_Profile->setModPriority(modIndex, newPriority);
+ notifyChange(modIndex);
+ return true;
+ }
}
-bool ModList::onModStateChanged(const std::function<void(const QString&, IModList::ModStates)>& func) {
- auto conn = m_ModStateChanged.connect(func);
- return conn.connected();
+bool ModList::onModStateChanged(const std::function<void (const QString &, IModList::ModStates)> &func)
+{
+ auto conn = m_ModStateChanged.connect(func);
+ return conn.connected();
}
-bool ModList::onModMoved(const std::function<void(const QString&, int, int)>& func) {
- auto conn = m_ModMoved.connect(func);
- return conn.connected();
+bool ModList::onModMoved(const std::function<void (const QString &, int, int)> &func)
+{
+ auto conn = m_ModMoved.connect(func);
+ return conn.connected();
}
-bool ModList::dropURLs(const QMimeData* mimeData, int row, const QModelIndex& parent) {
- QStringList source;
- QStringList target;
+bool ModList::dropURLs(const QMimeData *mimeData, int row, const QModelIndex &parent)
+{
+ QStringList source;
+ QStringList target;
- if (row == -1) {
- row = parent.row();
- }
+ if (row == -1) {
+ row = parent.row();
+ }
- ModInfo::Ptr modInfo = ModInfo::getByIndex(row);
- QDir modDirectory(modInfo->absolutePath());
- QDir gameDirectory(Settings::instance().getOverwriteDirectory());
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(row);
+ QDir modDirectory(modInfo->absolutePath());
+ QDir gameDirectory(Settings::instance().getOverwriteDirectory());
- unsigned int overwriteIndex = ModInfo::findMod([](ModInfo::Ptr mod) -> bool {
- std::vector<ModInfo::EFlag> flags = mod->getFlags();
- return std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end();
- });
+ unsigned int overwriteIndex = ModInfo::findMod([] (ModInfo::Ptr mod) -> bool {
+ std::vector<ModInfo::EFlag> flags = mod->getFlags();
+ return std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end(); });
- QString overwriteName = ModInfo::getByIndex(overwriteIndex)->name();
+ QString overwriteName = ModInfo::getByIndex(overwriteIndex)->name();
- for (const QUrl& url : mimeData->urls()) {
- if (!url.isLocalFile()) {
- continue;
- }
- QString relativePath = gameDirectory.relativeFilePath(url.toLocalFile());
- if (relativePath.startsWith("..")) {
- qDebug("%s drop ignored", qPrintable(url.toLocalFile()));
- continue;
- }
- source.append(url.toLocalFile());
- target.append(modDirectory.absoluteFilePath(relativePath));
- emit fileMoved(relativePath, overwriteName, modInfo->name());
+ for (const QUrl &url : mimeData->urls()) {
+ if (!url.isLocalFile()) {
+ continue;
}
-
- if (source.count() != 0) {
- shellMove(source, target);
+ QString relativePath = gameDirectory.relativeFilePath(url.toLocalFile());
+ if (relativePath.startsWith("..")) {
+ qDebug("%s drop ignored", qPrintable(url.toLocalFile()));
+ continue;
}
+ source.append(url.toLocalFile());
+ target.append(modDirectory.absoluteFilePath(relativePath));
+ emit fileMoved(relativePath, overwriteName, modInfo->name());
+ }
- return true;
+ if (source.count() != 0) {
+ shellMove(source, target);
+ }
+
+ return true;
}
-bool ModList::dropMod(const QMimeData* mimeData, int row, const QModelIndex& parent) {
+bool ModList::dropMod(const QMimeData *mimeData, int row, const QModelIndex &parent)
+{
- try {
- QByteArray encoded = mimeData->data("application/x-qabstractitemmodeldatalist");
- QDataStream stream(&encoded, QIODevice::ReadOnly);
- std::vector<int> sourceRows;
+ try {
+ QByteArray encoded = mimeData->data("application/x-qabstractitemmodeldatalist");
+ QDataStream stream(&encoded, QIODevice::ReadOnly);
+ std::vector<int> sourceRows;
- while (!stream.atEnd()) {
- int sourceRow, col;
- QMap<int, QVariant> roleDataMap;
- stream >> sourceRow >> col >> roleDataMap;
- if (col == 0) {
- sourceRows.push_back(sourceRow);
- }
- }
+ while (!stream.atEnd()) {
+ int sourceRow, col;
+ QMap<int, QVariant> roleDataMap;
+ stream >> sourceRow >> col >> roleDataMap;
+ if (col == 0) {
+ sourceRows.push_back(sourceRow);
+ }
+ }
- if (row == -1) {
- row = parent.row();
- }
+ if (row == -1) {
+ row = parent.row();
+ }
- if ((row < 0) || (static_cast<unsigned int>(row) >= ModInfo::getNumMods())) {
- return false;
- }
+ if ((row < 0) || (static_cast<unsigned int>(row) >= ModInfo::getNumMods())) {
+ return false;
+ }
- int newPriority = 0;
- {
- if ((row < 0) || (row > static_cast<int>(m_Profile->numRegularMods()))) {
- newPriority = m_Profile->numRegularMods() + 1;
- } else {
- newPriority = m_Profile->getModPriority(row);
- }
- if (newPriority == -1) {
- newPriority = m_Profile->numRegularMods() + 1;
- }
- }
- changeModPriority(sourceRows, newPriority);
- } catch (const std::exception& e) {
- reportError(tr("drag&drop failed: %1").arg(e.what()));
+ int newPriority = 0;
+ {
+ if ((row < 0) || (row > static_cast<int>(m_Profile->numRegularMods()))) {
+ newPriority = m_Profile->numRegularMods() + 1;
+ } else {
+ newPriority = m_Profile->getModPriority(row);
+ }
+ if (newPriority == -1) {
+ newPriority = m_Profile->numRegularMods() + 1;
+ }
}
+ changeModPriority(sourceRows, newPriority);
+ } catch (const std::exception &e) {
+ reportError(tr("drag&drop failed: %1").arg(e.what()));
+ }
- return false;
+ return false;
}
-bool ModList::dropMimeData(const QMimeData* mimeData, Qt::DropAction action, int row, int, const QModelIndex& parent) {
- if (action == Qt::IgnoreAction) {
- return true;
- }
- if (m_Profile == nullptr)
- return false;
+bool ModList::dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int, const QModelIndex &parent)
+{
+ if (action == Qt::IgnoreAction) {
+ return true;
+ }
- if (mimeData->hasUrls()) {
- return dropURLs(mimeData, row, parent);
- } else if (mimeData->hasText()) {
- return dropMod(mimeData, row, parent);
- } else {
- return false;
- }
+ if (m_Profile == nullptr) return false;
+
+ if (mimeData->hasUrls()) {
+ return dropURLs(mimeData, row, parent);
+ } else if (mimeData->hasText()) {
+ return dropMod(mimeData, row, parent);
+ } else {
+ return false;
+ }
}
-void ModList::removeRowForce(int row, const QModelIndex& parent) {
- if (static_cast<unsigned int>(row) >= ModInfo::getNumMods()) {
- return;
- }
- if (m_Profile == nullptr)
- return;
+void ModList::removeRowForce(int row, const QModelIndex &parent)
+{
+ if (static_cast<unsigned int>(row) >= ModInfo::getNumMods()) {
+ return;
+ }
+ if (m_Profile == nullptr) return;
- ModInfo::Ptr modInfo = ModInfo::getByIndex(row);
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(row);
- bool wasEnabled = m_Profile->modEnabled(row);
+ bool wasEnabled = m_Profile->modEnabled(row);
- m_Profile->setModEnabled(row, false);
+ m_Profile->setModEnabled(row, false);
- m_Profile->cancelModlistWrite();
- beginRemoveRows(parent, row, row);
- ModInfo::removeMod(row);
- endRemoveRows();
- m_Profile->refreshModStatus(); // removes the mod from the status list
- m_Profile->writeModlist(); // this ensures the modified list gets written back before new mods can be installed
+ m_Profile->cancelModlistWrite();
+ beginRemoveRows(parent, row, row);
+ ModInfo::removeMod(row);
+ endRemoveRows();
+ m_Profile->refreshModStatus(); // removes the mod from the status list
+ m_Profile->writeModlist(); // this ensures the modified list gets written back before new mods can be installed
- if (wasEnabled) {
- emit removeOrigin(modInfo->name());
- }
+ if (wasEnabled) {
+ emit removeOrigin(modInfo->name());
+ }
- emit modUninstalled(modInfo->getInstallationFile());
+ emit modUninstalled(modInfo->getInstallationFile());
}
-bool ModList::removeRows(int row, int count, const QModelIndex& parent) {
- if (static_cast<unsigned int>(row) >= ModInfo::getNumMods()) {
- return false;
- }
- if (m_Profile == nullptr) {
- return false;
- }
+bool ModList::removeRows(int row, int count, const QModelIndex &parent)
+{
+ if (static_cast<unsigned int>(row) >= ModInfo::getNumMods()) {
+ return false;
+ }
+ if (m_Profile == nullptr) {
+ return false;
+ }
- bool success = false;
+ bool success = false;
- for (int i = 0; i < count; ++i) {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(row + i);
- if (!modInfo->isRegular()) {
- continue;
- }
+ for (int i = 0; i < count; ++i) {
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(row + i);
+ if (!modInfo->isRegular()) {
+ continue;
+ }
- success = true;
+ success = true;
- QMessageBox confirmBox(QMessageBox::Question, tr("Confirm"),
- tr("Are you sure you want to remove \"%1\"?").arg(modInfo->name()),
- QMessageBox::Yes | QMessageBox::No);
+ QMessageBox confirmBox(QMessageBox::Question, tr("Confirm"),
+ tr("Are you sure you want to remove \"%1\"?").arg(modInfo->name()),
+ QMessageBox::Yes | QMessageBox::No);
- if (confirmBox.exec() == QMessageBox::Yes) {
- m_Profile->setModEnabled(row + i, false);
- removeRowForce(row + i, parent);
- }
+ if (confirmBox.exec() == QMessageBox::Yes) {
+ m_Profile->setModEnabled(row + i, false);
+ removeRowForce(row + i, parent);
}
+ }
- return success;
+ return success;
}
-void ModList::notifyChange(int rowStart, int rowEnd) {
- if (rowStart < 0) {
- m_Overwrite.clear();
- m_Overwritten.clear();
- beginResetModel();
- endResetModel();
- } else {
- if (rowEnd == -1) {
- rowEnd = rowStart;
- }
- emit dataChanged(this->index(rowStart, 0), this->index(rowEnd, this->columnCount() - 1));
+
+void ModList::notifyChange(int rowStart, int rowEnd)
+{
+ if (rowStart < 0) {
+ m_Overwrite.clear();
+ m_Overwritten.clear();
+ beginResetModel();
+ endResetModel();
+ } else {
+ if (rowEnd == -1) {
+ rowEnd = rowStart;
}
+ emit dataChanged(this->index(rowStart, 0), this->index(rowEnd, this->columnCount() - 1));
+ }
}
-QModelIndex ModList::index(int row, int column, const QModelIndex&) const {
- if ((row < 0) || (row >= rowCount()) || (column < 0) || (column >= columnCount())) {
- return QModelIndex();
- }
- QModelIndex res = createIndex(row, column, row);
- return res;
+
+QModelIndex ModList::index(int row, int column, const QModelIndex&) const
+{
+ if ((row < 0) || (row >= rowCount()) || (column < 0) || (column >= columnCount())) {
+ return QModelIndex();
+ }
+ QModelIndex res = createIndex(row, column, row);
+ return res;
}
-QModelIndex ModList::parent(const QModelIndex&) const { return QModelIndex(); }
-QMap<int, QVariant> ModList::itemData(const QModelIndex& index) const {
- QMap<int, QVariant> result = QAbstractItemModel::itemData(index);
- result[Qt::UserRole] = data(index, Qt::UserRole);
- return result;
+QModelIndex ModList::parent(const QModelIndex&) const
+{
+ return QModelIndex();
}
-void ModList::dropModeUpdate(bool dropOnItems) {
- if (m_DropOnItems != dropOnItems) {
- m_DropOnItems = dropOnItems;
- }
+QMap<int, QVariant> ModList::itemData(const QModelIndex &index) const
+{
+ QMap<int, QVariant> result = QAbstractItemModel::itemData(index);
+ result[Qt::UserRole] = data(index, Qt::UserRole);
+ return result;
}
-QString ModList::getColumnName(int column) {
- switch (column) {
- case COL_FLAGS:
- return tr("Flags");
- case COL_CONTENT:
- return tr("Content");
- case COL_NAME:
- return tr("Mod Name");
- case COL_VERSION:
- return tr("Version");
- case COL_PRIORITY:
- return tr("Priority");
- case COL_CATEGORY:
- return tr("Category");
- case COL_MODID:
- return tr("Nexus ID");
- case COL_INSTALLTIME:
- return tr("Installation");
- default:
- return tr("unknown");
- }
+
+void ModList::dropModeUpdate(bool dropOnItems)
+{
+ if (m_DropOnItems != dropOnItems) {
+ m_DropOnItems = dropOnItems;
+ }
}
-QString ModList::getColumnToolTip(int column) {
- switch (column) {
- case COL_NAME:
- return tr("Name of your mods");
- case COL_VERSION:
- return tr("Version of the mod (if available)");
- case COL_PRIORITY:
- return tr("Installation priority of your mod. The higher, the more \"important\" it is and thus "
- "overwrites files from mods with lower priority.");
- case COL_CATEGORY:
- return tr("Category of the mod.");
- case COL_MODID:
- return tr("Id of the mod as used on Nexus.");
- case COL_FLAGS:
- return tr("Emblemes to highlight things that might require attention.");
- case COL_CONTENT:
- return tr("Depicts the content of the mod:<br>"
- "<table cellspacing=7>"
- "<tr><td><img src=\":/MO/gui/content/plugin\" width=32/></td><td>Game plugins (esp/esm/esl)</td></tr>"
- "<tr><td><img src=\":/MO/gui/content/interface\" width=32/></td><td>Interface</td></tr>"
- "<tr><td><img src=\":/MO/gui/content/mesh\" width=32/></td><td>Meshes</td></tr>"
- "<tr><td><img src=\":/MO/gui/content/bsa\" width=32/></td><td>BSA</td></tr>"
- "<tr><td><img src=\":/MO/gui/content/texture\" width=32/></td><td>Textures</td></tr>"
- "<tr><td><img src=\":/MO/gui/content/sound\" width=32/></td><td>Sounds</td></tr>"
- "<tr><td><img src=\":/MO/gui/content/music\" width=32/></td><td>Music</td></tr>"
- "<tr><td><img src=\":/MO/gui/content/string\" width=32/></td><td>Strings</td></tr>"
- "<tr><td><img src=\":/MO/gui/content/script\" width=32/></td><td>Scripts (Papyrus)</td></tr>"
- "<tr><td><img src=\":/MO/gui/content/skse\" width=32/></td><td>Script Extender plugins</td></tr>"
- "<tr><td><img src=\":/MO/gui/content/skyproc\" width=32/></td><td>SkyProc Patcher</td></tr>"
- "<tr><td><img src=\":/MO/gui/content/menu\" width=32/></td><td>Mod Configuration Menu</td></tr>"
- "</table>");
- case COL_INSTALLTIME:
- return tr("Time this mod was installed");
- default:
- return tr("unknown");
- }
+
+QString ModList::getColumnName(int column)
+{
+ switch (column) {
+ case COL_FLAGS: return tr("Flags");
+ case COL_CONTENT: return tr("Content");
+ case COL_NAME: return tr("Mod Name");
+ case COL_VERSION: return tr("Version");
+ case COL_PRIORITY: return tr("Priority");
+ case COL_CATEGORY: return tr("Category");
+ case COL_MODID: return tr("Nexus ID");
+ case COL_INSTALLTIME: return tr("Installation");
+ default: return tr("unknown");
+ }
}
-bool ModList::moveSelection(QAbstractItemView* itemView, int direction) {
- QItemSelectionModel* selectionModel = itemView->selectionModel();
- const QAbstractProxyModel* proxyModel = qobject_cast<const QAbstractProxyModel*>(selectionModel->model());
- const QSortFilterProxyModel* filterModel = nullptr;
+QString ModList::getColumnToolTip(int column)
+{
+ switch (column) {
+ case COL_NAME: return tr("Name of your mods");
+ case COL_VERSION: return tr("Version of the mod (if available)");
+ case COL_PRIORITY: return tr("Installation priority of your mod. The higher, the more \"important\" it is and thus "
+ "overwrites files from mods with lower priority.");
+ case COL_CATEGORY: return tr("Category of the mod.");
+ case COL_MODID: return tr("Id of the mod as used on Nexus.");
+ case COL_FLAGS: return tr("Emblemes to highlight things that might require attention.");
+ case COL_CONTENT: return tr("Depicts the content of the mod:<br>"
+ "<table cellspacing=7>"
+ "<tr><td><img src=\":/MO/gui/content/plugin\" width=32/></td><td>Game plugins (esp/esm/esl)</td></tr>"
+ "<tr><td><img src=\":/MO/gui/content/interface\" width=32/></td><td>Interface</td></tr>"
+ "<tr><td><img src=\":/MO/gui/content/mesh\" width=32/></td><td>Meshes</td></tr>"
+ "<tr><td><img src=\":/MO/gui/content/bsa\" width=32/></td><td>BSA</td></tr>"
+ "<tr><td><img src=\":/MO/gui/content/texture\" width=32/></td><td>Textures</td></tr>"
+ "<tr><td><img src=\":/MO/gui/content/sound\" width=32/></td><td>Sounds</td></tr>"
+ "<tr><td><img src=\":/MO/gui/content/music\" width=32/></td><td>Music</td></tr>"
+ "<tr><td><img src=\":/MO/gui/content/string\" width=32/></td><td>Strings</td></tr>"
+ "<tr><td><img src=\":/MO/gui/content/script\" width=32/></td><td>Scripts (Papyrus)</td></tr>"
+ "<tr><td><img src=\":/MO/gui/content/skse\" width=32/></td><td>Script Extender plugins</td></tr>"
+ "<tr><td><img src=\":/MO/gui/content/skyproc\" width=32/></td><td>SkyProc Patcher</td></tr>"
+ "<tr><td><img src=\":/MO/gui/content/menu\" width=32/></td><td>Mod Configuration Menu</td></tr>"
+ "</table>");
+ case COL_INSTALLTIME: return tr("Time this mod was installed");
+ default: return tr("unknown");
+ }
+}
- while ((filterModel == nullptr) && (proxyModel != nullptr)) {
- filterModel = qobject_cast<const QSortFilterProxyModel*>(proxyModel);
- if (filterModel == nullptr) {
- proxyModel = qobject_cast<const QAbstractProxyModel*>(proxyModel->sourceModel());
- }
- }
+
+bool ModList::moveSelection(QAbstractItemView *itemView, int direction)
+{
+ QItemSelectionModel *selectionModel = itemView->selectionModel();
+
+ const QAbstractProxyModel *proxyModel = qobject_cast<const QAbstractProxyModel*>(selectionModel->model());
+ const QSortFilterProxyModel *filterModel = nullptr;
+
+ while ((filterModel == nullptr) && (proxyModel != nullptr)) {
+ filterModel = qobject_cast<const QSortFilterProxyModel*>(proxyModel);
if (filterModel == nullptr) {
- return true;
+ proxyModel = qobject_cast<const QAbstractProxyModel*>(proxyModel->sourceModel());
}
+ }
+ if (filterModel == nullptr) {
+ return true;
+ }
- int offset = -1;
- if (((direction < 0) && (filterModel->sortOrder() == Qt::DescendingOrder)) ||
- ((direction > 0) && (filterModel->sortOrder() == Qt::AscendingOrder))) {
- offset = 1;
- }
+ int offset = -1;
+ if (((direction < 0) && (filterModel->sortOrder() == Qt::DescendingOrder)) ||
+ ((direction > 0) && (filterModel->sortOrder() == Qt::AscendingOrder))) {
+ offset = 1;
+ }
- QModelIndexList rows = selectionModel->selectedRows();
- if (direction > 0) {
- for (int i = 0; i < rows.size() / 2; ++i) {
- rows.swap(i, rows.size() - i - 1);
- }
+ QModelIndexList rows = selectionModel->selectedRows();
+ if (direction > 0) {
+ for (int i = 0; i < rows.size() / 2; ++i) {
+ rows.swap(i, rows.size() - i - 1);
}
- for (QModelIndex idx : rows) {
- if (filterModel != nullptr) {
- idx = filterModel->mapToSource(idx);
- }
- int newPriority = m_Profile->getModPriority(idx.row()) + offset;
- if ((newPriority >= 0) && (newPriority < static_cast<int>(m_Profile->numRegularMods()))) {
- m_Profile->setModPriority(idx.row(), newPriority);
- notifyChange(idx.row());
- }
+ }
+ for (QModelIndex idx : rows) {
+ if (filterModel != nullptr) {
+ idx = filterModel->mapToSource(idx);
}
- emit modorder_changed();
- return true;
+ int newPriority = m_Profile->getModPriority(idx.row()) + offset;
+ if ((newPriority >= 0) && (newPriority < static_cast<int>(m_Profile->numRegularMods()))) {
+ m_Profile->setModPriority(idx.row(), newPriority);
+ notifyChange(idx.row());
+ }
+ }
+ emit modorder_changed();
+ return true;
}
-bool ModList::deleteSelection(QAbstractItemView* itemView) {
- QItemSelectionModel* selectionModel = itemView->selectionModel();
+bool ModList::deleteSelection(QAbstractItemView *itemView)
+{
+ QItemSelectionModel *selectionModel = itemView->selectionModel();
- QModelIndexList rows = selectionModel->selectedRows();
- if (rows.count() > 1) {
- emit removeSelectedMods();
- } else if (rows.count() == 1) {
- removeRow(rows[0].data(Qt::UserRole + 1).toInt(), QModelIndex());
- }
- return true;
+ QModelIndexList rows = selectionModel->selectedRows();
+ if (rows.count() > 1) {
+ emit removeSelectedMods();
+ } else if (rows.count() == 1) {
+ removeRow(rows[0].data(Qt::UserRole + 1).toInt(), QModelIndex());
+ }
+ return true;
}
-bool ModList::toggleSelection(QAbstractItemView* itemView) {
- emit aboutToChangeData();
+bool ModList::toggleSelection(QAbstractItemView *itemView)
+{
+ emit aboutToChangeData();
- QItemSelectionModel* selectionModel = itemView->selectionModel();
+ QItemSelectionModel *selectionModel = itemView->selectionModel();
- for (QModelIndex idx : selectionModel->selectedRows()) {
- int modId = idx.data(Qt::UserRole + 1).toInt();
- m_Profile->setModEnabled(modId, !m_Profile->modEnabled(modId));
- emit modlist_changed(idx, 0);
- }
+ for (QModelIndex idx : selectionModel->selectedRows()) {
+ int modId = idx.data(Qt::UserRole + 1).toInt();
+ m_Profile->setModEnabled(modId, !m_Profile->modEnabled(modId));
+ emit modlist_changed(idx, 0);
+ }
- m_Modified = true;
- m_LastCheck.restart();
+ m_Modified = true;
+ m_LastCheck.restart();
- emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
+ emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
- emit postDataChanged();
+ emit postDataChanged();
- return true;
+ return true;
}
-bool ModList::eventFilter(QObject* obj, QEvent* event) {
- if (event->type() == QEvent::ContextMenu) {
- QContextMenuEvent* contextEvent = static_cast<QContextMenuEvent*>(event);
- QWidget* object = qobject_cast<QWidget*>(obj);
- if ((object != nullptr) && (contextEvent->reason() == QContextMenuEvent::Mouse)) {
- emit requestColumnSelect(object->mapToGlobal(contextEvent->pos()));
+bool ModList::eventFilter(QObject *obj, QEvent *event)
+{
+ if (event->type() == QEvent::ContextMenu) {
+ QContextMenuEvent *contextEvent = static_cast<QContextMenuEvent*>(event);
+ QWidget *object = qobject_cast<QWidget*>(obj);
+ if ((object != nullptr) && (contextEvent->reason() == QContextMenuEvent::Mouse)) {
+ emit requestColumnSelect(object->mapToGlobal(contextEvent->pos()));
- return true;
- }
- } else if ((event->type() == QEvent::KeyPress) && (m_Profile != nullptr)) {
- QAbstractItemView* itemView = qobject_cast<QAbstractItemView*>(obj);
- QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
+ return true;
+ }
+ } else if ((event->type() == QEvent::KeyPress) && (m_Profile != nullptr)) {
+ QAbstractItemView *itemView = qobject_cast<QAbstractItemView*>(obj);
+ QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
- if ((itemView != nullptr) && (keyEvent->modifiers() == Qt::ControlModifier) &&
- ((keyEvent->key() == Qt::Key_Up) || (keyEvent->key() == Qt::Key_Down))) {
- return moveSelection(itemView, keyEvent->key() == Qt::Key_Up ? -1 : 1);
- } else if (keyEvent->key() == Qt::Key_Delete) {
- return deleteSelection(itemView);
- } else if (keyEvent->key() == Qt::Key_Space) {
- return toggleSelection(itemView);
- }
+ if ((itemView != nullptr)
+ && (keyEvent->modifiers() == Qt::ControlModifier)
+ && ((keyEvent->key() == Qt::Key_Up) || (keyEvent->key() == Qt::Key_Down))) {
+ return moveSelection(itemView, keyEvent->key() == Qt::Key_Up ? -1 : 1);
+ } else if (keyEvent->key() == Qt::Key_Delete) {
+ return deleteSelection(itemView);
+ } else if (keyEvent->key() == Qt::Key_Space) {
+ return toggleSelection(itemView);
}
- return QAbstractItemModel::eventFilter(obj, event);
+ }
+ return QAbstractItemModel::eventFilter(obj, event);
}
+
diff --git a/src/modlist.h b/src/modlist.h
index 4cdfe294..bd715107 100644
--- a/src/modlist.h
+++ b/src/modlist.h
@@ -20,24 +20,26 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef MODLIST_H
#define MODLIST_H
+
#include "categories.h"
-#include "modinfo.h"
#include "nexusinterface.h"
+#include "modinfo.h"
#include "profile.h"
-#include <directoryentry.h>
#include <imodlist.h>
+#include <directoryentry.h>
#include <QFile>
#include <QListWidget>
-#include <QNetworkAccessManager>
#include <QNetworkReply>
+#include <QNetworkAccessManager>
#ifndef Q_MOC_RUN
#include <boost/signals2.hpp>
#endif
-#include <QVector>
#include <set>
#include <vector>
+#include <QVector>
+
class QSortFilterProxyModel;
@@ -46,278 +48,288 @@ class QSortFilterProxyModel;
* This is used in a view in the main window of MO. It combines general information about
* the mods from ModInfo with status information from the Profile
**/
-class ModList : public QAbstractItemModel, public MOBase::IModList {
- Q_OBJECT
+class ModList : public QAbstractItemModel, public MOBase::IModList
+{
+ Q_OBJECT
public:
- enum EColumn {
- COL_NAME,
- COL_FLAGS,
- COL_CONTENT,
- COL_CATEGORY,
- COL_MODID,
- COL_VERSION,
- COL_INSTALLTIME,
- COL_PRIORITY,
- COL_LASTCOLUMN = COL_PRIORITY
- };
+ enum EColumn {
+ COL_NAME,
+ COL_FLAGS,
+ COL_CONTENT,
+ COL_CATEGORY,
+ COL_MODID,
+ COL_VERSION,
+ COL_INSTALLTIME,
+ COL_PRIORITY,
- typedef boost::signals2::signal<void(const QString&, ModStates)> SignalModStateChanged;
- typedef boost::signals2::signal<void(const QString&, int, int)> SignalModMoved;
+ COL_LASTCOLUMN = COL_PRIORITY
+ };
+
+ typedef boost::signals2::signal<void (const QString &, ModStates)> SignalModStateChanged;
+ typedef boost::signals2::signal<void (const QString &, int, int)> SignalModMoved;
public:
- /**
- * @brief constructor
- * @todo ensure this view works without a profile set, otherwise there are intransparent dependencies on the
- *initialisation order
- **/
- ModList(QObject* parent = nullptr);
- ~ModList();
+ /**
+ * @brief constructor
+ * @todo ensure this view works without a profile set, otherwise there are intransparent dependencies on the initialisation order
+ **/
+ ModList(QObject *parent = nullptr);
+
+ ~ModList();
- /**
- * @brief set the profile used for status information
- *
- * @param profile the profile to use
- **/
- void setProfile(Profile* profile);
+ /**
+ * @brief set the profile used for status information
+ *
+ * @param profile the profile to use
+ **/
+ void setProfile(Profile *profile);
- /**
- * @brief retrieve the current sorting mode
- * @note this is used to store the sorting mode between sessions
- * @return current sorting mode, encoded to be compatible to previous versions
- **/
- int getCurrentSortingMode() const;
+ /**
+ * @brief retrieve the current sorting mode
+ * @note this is used to store the sorting mode between sessions
+ * @return current sorting mode, encoded to be compatible to previous versions
+ **/
+ int getCurrentSortingMode() const;
- /**
- * @brief remove the specified mod without asking for confirmation
- * @param row the row to remove
- */
- void removeRowForce(int row, const QModelIndex& parent);
+ /**
+ * @brief remove the specified mod without asking for confirmation
+ * @param row the row to remove
+ */
+ void removeRowForce(int row, const QModelIndex &parent);
- void notifyChange(int rowStart, int rowEnd = -1);
- static QString getColumnName(int column);
+ void notifyChange(int rowStart, int rowEnd = -1);
+ static QString getColumnName(int column);
- void changeModPriority(int sourceIndex, int newPriority);
+ void changeModPriority(int sourceIndex, int newPriority);
- void setOverwriteMarkers(const std::set<unsigned int>& overwrite, const std::set<unsigned int>& overwritten);
+ void setOverwriteMarkers(const std::set<unsigned int> &overwrite, const std::set<unsigned int> &overwritten);
- bool modInfoAboutToChange(ModInfo::Ptr info);
- void modInfoChanged(ModInfo::Ptr info);
+ bool modInfoAboutToChange(ModInfo::Ptr info);
+ void modInfoChanged(ModInfo::Ptr info);
- void disconnectSlots();
+ void disconnectSlots();
- int timeElapsedSinceLastChecked() const;
+ int timeElapsedSinceLastChecked() const;
- void highlightMods(const QItemSelection& selected, const MOShared::DirectoryEntry& directoryEntry);
+ void highlightMods(const QItemSelection &selected, const MOShared::DirectoryEntry &directoryEntry);
public:
- /// \copydoc MOBase::IModList::displayName
- virtual QString displayName(const QString& internalName) const override;
- /// \copydoc MOBase::IModList::allMods
- virtual QStringList allMods() const override;
+ /// \copydoc MOBase::IModList::displayName
+ virtual QString displayName(const QString &internalName) const override;
+
+ /// \copydoc MOBase::IModList::allMods
+ virtual QStringList allMods() const override;
- /// \copydoc MOBase::IModList::state
- virtual ModStates state(const QString& name) const override;
+ /// \copydoc MOBase::IModList::state
+ virtual ModStates state(const QString &name) const override;
- /// \copydoc MOBase::IModList::setActive
- virtual bool setActive(const QString& name, bool active) override;
+ /// \copydoc MOBase::IModList::setActive
+ virtual bool setActive(const QString &name, bool active) override;
- /// \copydoc MOBase::IModList::priority
- virtual int priority(const QString& name) const override;
+ /// \copydoc MOBase::IModList::priority
+ virtual int priority(const QString &name) const override;
- /// \copydoc MOBase::IModList::setPriority
- virtual bool setPriority(const QString& name, int newPriority) override;
+ /// \copydoc MOBase::IModList::setPriority
+ virtual bool setPriority(const QString &name, int newPriority) override;
- /// \copydoc MOBase::IModList::onModStateChanged
- virtual bool onModStateChanged(const std::function<void(const QString&, ModStates)>& func) override;
+ /// \copydoc MOBase::IModList::onModStateChanged
+ virtual bool onModStateChanged(const std::function<void (const QString &, ModStates)> &func) override;
- /// \copydoc MOBase::IModList::onModMoved
- virtual bool onModMoved(const std::function<void(const QString&, int, int)>& func) override;
+ /// \copydoc MOBase::IModList::onModMoved
+ virtual bool onModMoved(const std::function<void (const QString &, int, int)> &func) override;
public: // implementation of virtual functions of QAbstractItemModel
- virtual int rowCount(const QModelIndex& parent = QModelIndex()) const;
- virtual bool hasChildren(const QModelIndex& parent = QModelIndex()) const;
- virtual int columnCount(const QModelIndex& parent = QModelIndex()) const;
- virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
- virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
- virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
- virtual Qt::ItemFlags flags(const QModelIndex& modelIndex) const;
- virtual Qt::DropActions supportedDropActions() const { return Qt::MoveAction | Qt::CopyAction; }
- virtual QStringList mimeTypes() const;
- virtual QMimeData* mimeData(const QModelIndexList& indexes) const;
- virtual bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column,
- const QModelIndex& parent);
- virtual bool removeRows(int row, int count, const QModelIndex& parent);
- virtual QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const;
- virtual QModelIndex parent(const QModelIndex& child) const;
+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ virtual bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
+ virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+ virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+ virtual Qt::ItemFlags flags(const QModelIndex &modelIndex) const;
+ virtual Qt::DropActions supportedDropActions() const { return Qt::MoveAction | Qt::CopyAction; }
+ virtual QStringList mimeTypes() const;
+ virtual QMimeData *mimeData(const QModelIndexList &indexes) const;
+ virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
+ virtual bool removeRows(int row, int count, const QModelIndex &parent);
- virtual QMap<int, QVariant> itemData(const QModelIndex& index) const;
+ virtual QModelIndex index(int row, int column,
+ const QModelIndex &parent = QModelIndex()) const;
+ virtual QModelIndex parent(const QModelIndex &child) const;
+
+ virtual QMap<int, QVariant> itemData(const QModelIndex &index) const;
public slots:
- void dropModeUpdate(bool dropOnItems);
+ void dropModeUpdate(bool dropOnItems);
signals:
- /**
- * @brief emitted whenever the sorting in the list was changed by the user
- *
- * the sorting of the list can only be manually changed if the list is sorted by priority
- * in which case the move is intended to change the priority of a mod
- **/
- void modorder_changed();
+ /**
+ * @brief emitted whenever the sorting in the list was changed by the user
+ *
+ * the sorting of the list can only be manually changed if the list is sorted by priority
+ * in which case the move is intended to change the priority of a mod
+ **/
+ void modorder_changed();
- /**
- * @brief emitted when the model wants a text to be displayed by the UI
- *
- * @param message the message to display
- **/
- void showMessage(const QString& message);
+ /**
+ * @brief emitted when the model wants a text to be displayed by the UI
+ *
+ * @param message the message to display
+ **/
+ void showMessage(const QString &message);
- /**
- * @brief signals change to the count of headers
- */
- void resizeHeaders();
+ /**
+ * @brief signals change to the count of headers
+ */
+ void resizeHeaders();
- /**
- * @brief requestColumnSelect is emitted whenever the user requested a menu to select visible columns
- * @param pos the position to display the menu at
- */
- void requestColumnSelect(QPoint pos);
+ /**
+ * @brief requestColumnSelect is emitted whenever the user requested a menu to select visible columns
+ * @param pos the position to display the menu at
+ */
+ void requestColumnSelect(QPoint pos);
- /**
- * @brief emitted to remove a file origin
- * @param name name of the orign to remove
- */
- void removeOrigin(const QString& name);
+ /**
+ * @brief emitted to remove a file origin
+ * @param name name of the orign to remove
+ */
+ void removeOrigin(const QString &name);
- /**
- * @brief emitted after a mod has been renamed
- * This signal MUST be used to fix the mod names in profiles (except the active one) and to invalidate/refresh other
- * structures that may have become invalid with the rename
- *
- * @param oldName the old name of the mod
- * @param newName new name of the mod
- */
- void modRenamed(const QString& oldName, const QString& newName);
+ /**
+ * @brief emitted after a mod has been renamed
+ * This signal MUST be used to fix the mod names in profiles (except the active one) and to invalidate/refresh other
+ * structures that may have become invalid with the rename
+ *
+ * @param oldName the old name of the mod
+ * @param newName new name of the mod
+ */
+ void modRenamed(const QString &oldName, const QString &newName);
- /**
- * @brief emitted after a mod has been uninstalled
- * @param fileName filename of the mod being uninstalled
- */
- void modUninstalled(const QString& fileName);
+ /**
+ * @brief emitted after a mod has been uninstalled
+ * @param fileName filename of the mod being uninstalled
+ */
+ void modUninstalled(const QString &fileName);
- /**
- * @brief emitted whenever a row in the list has changed
- *
- * @param index the index of the changed field
- * @param role role of the field that changed
- * @note this signal must only be emitted if the row really did change.
- * Slots handling this signal therefore do not have to verify that a change has happened
- * @note this signal is currently only used in tutorials
- **/
- void modlist_changed(const QModelIndex& index, int role);
+ /**
+ * @brief emitted whenever a row in the list has changed
+ *
+ * @param index the index of the changed field
+ * @param role role of the field that changed
+ * @note this signal must only be emitted if the row really did change.
+ * Slots handling this signal therefore do not have to verify that a change has happened
+ * @note this signal is currently only used in tutorials
+ **/
+ void modlist_changed(const QModelIndex &index, int role);
- /**
- * @brief emitted to have all selected mods deleted
- */
- void removeSelectedMods();
+ /**
+ * @brief emitted to have all selected mods deleted
+ */
+ void removeSelectedMods();
- /**
- * @brief fileMoved emitted when a file is moved from one mod to another
- * @param relativePath relative path of the file moved
- * @param oldOriginName name of the origin that previously contained the file
- * @param newOriginName name of the origin that now contains the file
- */
- void fileMoved(const QString& relativePath, const QString& oldOriginName, const QString& newOriginName);
+ /**
+ * @brief fileMoved emitted when a file is moved from one mod to another
+ * @param relativePath relative path of the file moved
+ * @param oldOriginName name of the origin that previously contained the file
+ * @param newOriginName name of the origin that now contains the file
+ */
+ void fileMoved(const QString &relativePath, const QString &oldOriginName, const QString &newOriginName);
- void aboutToChangeData();
+ void aboutToChangeData();
- void postDataChanged();
+ void postDataChanged();
protected:
- // event filter, handles event from the header and the tree view itself
- bool eventFilter(QObject* obj, QEvent* event);
+
+ // event filter, handles event from the header and the tree view itself
+ bool eventFilter(QObject *obj, QEvent *event);
private:
- bool testValid(const QString& modDir);
- void changeModPriority(std::vector<int> sourceIndices, int newPriority);
+ bool testValid(const QString &modDir);
- QVariant getOverwriteData(int column, int role) const;
+ void changeModPriority(std::vector<int> sourceIndices, int newPriority);
- QString getFlagText(ModInfo::EFlag flag, ModInfo::Ptr modInfo) const;
+ QVariant getOverwriteData(int column, int role) const;
- static QString getColumnToolTip(int column);
+ QString getFlagText(ModInfo::EFlag flag, ModInfo::Ptr modInfo) const;
- QVariantList contentsToIcons(const std::vector<ModInfo::EContent>& content) const;
+ static QString getColumnToolTip(int column);
- QString contentsToToolTip(const std::vector<ModInfo::EContent>& contents) const;
+ QVariantList contentsToIcons(const std::vector<ModInfo::EContent> &content) const;
- ModList::EColumn getEnabledColumn(int index) const;
+ QString contentsToToolTip(const std::vector<ModInfo::EContent> &contents) const;
- QVariant categoryData(int categoryID, int column, int role) const;
- QVariant modData(int modID, int modelColumn, int role) const;
+ ModList::EColumn getEnabledColumn(int index) const;
- bool renameMod(int index, const QString& newName);
+ QVariant categoryData(int categoryID, int column, int role) const;
+ QVariant modData(int modID, int modelColumn, int role) const;
- bool dropURLs(const QMimeData* mimeData, int row, const QModelIndex& parent);
+ bool renameMod(int index, const QString &newName);
- bool dropMod(const QMimeData* mimeData, int row, const QModelIndex& parent);
+ bool dropURLs(const QMimeData *mimeData, int row, const QModelIndex &parent);
- ModStates state(unsigned int modIndex) const;
+ bool dropMod(const QMimeData *mimeData, int row, const QModelIndex &parent);
- bool moveSelection(QAbstractItemView* itemView, int direction);
+ ModStates state(unsigned int modIndex) const;
- bool deleteSelection(QAbstractItemView* itemView);
+ bool moveSelection(QAbstractItemView *itemView, int direction);
- bool toggleSelection(QAbstractItemView* itemView);
+ bool deleteSelection(QAbstractItemView *itemView);
+
+ bool toggleSelection(QAbstractItemView *itemView);
private slots:
private:
- struct TModInfo {
- TModInfo(unsigned int index, ModInfo::Ptr modInfo)
- : modInfo(modInfo), nameOrder(index), priorityOrder(0), modIDOrder(0), categoryOrder(0) {}
- ModInfo::Ptr modInfo;
- unsigned int nameOrder;
- unsigned int priorityOrder;
- unsigned int modIDOrder;
- unsigned int categoryOrder;
- };
- struct TModInfoChange {
- QString name;
- QFlags<IModList::ModState> state;
- };
+ struct TModInfo {
+ TModInfo(unsigned int index, ModInfo::Ptr modInfo)
+ : modInfo(modInfo), nameOrder(index), priorityOrder(0), modIDOrder(0), categoryOrder(0) {}
+ ModInfo::Ptr modInfo;
+ unsigned int nameOrder;
+ unsigned int priorityOrder;
+ unsigned int modIDOrder;
+ unsigned int categoryOrder;
+ };
+
+ struct TModInfoChange {
+ QString name;
+ QFlags<IModList::ModState> state;
+ };
private:
- Profile* m_Profile;
- NexusInterface* m_NexusInterface;
- std::set<int> m_RequestIDs;
+ Profile *m_Profile;
+
+ NexusInterface *m_NexusInterface;
+ std::set<int> m_RequestIDs;
- mutable bool m_Modified;
+ mutable bool m_Modified;
- QFontMetrics m_FontMetrics;
+ QFontMetrics m_FontMetrics;
- bool m_DropOnItems;
+ bool m_DropOnItems;
- std::set<unsigned int> m_Overwrite;
- std::set<unsigned int> m_Overwritten;
+ std::set<unsigned int> m_Overwrite;
+ std::set<unsigned int> m_Overwritten;
- TModInfoChange m_ChangeInfo;
+ TModInfoChange m_ChangeInfo;
- SignalModStateChanged m_ModStateChanged;
- SignalModMoved m_ModMoved;
+ SignalModStateChanged m_ModStateChanged;
+ SignalModMoved m_ModMoved;
- std::map<ModInfo::EContent, std::tuple<QString, QString>> m_ContentIcons;
+ std::map<ModInfo::EContent, std::tuple<QString, QString> > m_ContentIcons;
+
+ QTime m_LastCheck;
- QTime m_LastCheck;
};
#endif // MODLIST_H
+
diff --git a/src/modlistsortproxy.cpp b/src/modlistsortproxy.cpp
index 775b3d97..435967c9 100644
--- a/src/modlistsortproxy.cpp
+++ b/src/modlistsortproxy.cpp
@@ -18,408 +18,416 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "modlistsortproxy.h"
-#include "messagedialog.h"
#include "modinfo.h"
#include "profile.h"
+#include "messagedialog.h"
#include "qtgroupingproxy.h"
-#include <QApplication>
-#include <QCheckBox>
-#include <QDebug>
#include <QMenu>
+#include <QCheckBox>
+#include <QWidgetAction>
+#include <QApplication>
#include <QMimeData>
+#include <QDebug>
#include <QTreeView>
-#include <QWidgetAction>
-ModListSortProxy::ModListSortProxy(Profile* profile, QObject* parent)
- : QSortFilterProxyModel(parent), m_Profile(profile), m_CategoryFilter(), m_CurrentFilter(), m_FilterActive(false),
- m_FilterMode(FILTER_AND) {
- m_EnabledColumns.set(ModList::COL_FLAGS);
- m_EnabledColumns.set(ModList::COL_NAME);
- m_EnabledColumns.set(ModList::COL_VERSION);
- m_EnabledColumns.set(ModList::COL_PRIORITY);
- setDynamicSortFilter(true); // this seems to work without dynamicsortfilter
- // but I don't know why. This should be necessary
+
+ModListSortProxy::ModListSortProxy(Profile* profile, QObject *parent)
+ : QSortFilterProxyModel(parent)
+ , m_Profile(profile)
+ , m_CategoryFilter()
+ , m_CurrentFilter()
+ , m_FilterActive(false)
+ , m_FilterMode(FILTER_AND)
+{
+ m_EnabledColumns.set(ModList::COL_FLAGS);
+ m_EnabledColumns.set(ModList::COL_NAME);
+ m_EnabledColumns.set(ModList::COL_VERSION);
+ m_EnabledColumns.set(ModList::COL_PRIORITY);
+ setDynamicSortFilter(true); // this seems to work without dynamicsortfilter
+ // but I don't know why. This should be necessary
}
-void ModListSortProxy::setProfile(Profile* profile) { m_Profile = profile; }
+void ModListSortProxy::setProfile(Profile *profile)
+{
+ m_Profile = profile;
+}
-void ModListSortProxy::updateFilterActive() {
- m_FilterActive = ((m_CategoryFilter.size() > 0) || (m_ContentFilter.size() > 0) || !m_CurrentFilter.isEmpty());
- emit filterActive(m_FilterActive);
+void ModListSortProxy::updateFilterActive()
+{
+ m_FilterActive = ((m_CategoryFilter.size() > 0)
+ || (m_ContentFilter.size() > 0)
+ || !m_CurrentFilter.isEmpty());
+ emit filterActive(m_FilterActive);
}
-void ModListSortProxy::setCategoryFilter(const std::vector<int>& categories) {
- m_CategoryFilter = categories;
- updateFilterActive();
- invalidate();
+void ModListSortProxy::setCategoryFilter(const std::vector<int> &categories)
+{
+ m_CategoryFilter = categories;
+ updateFilterActive();
+ invalidate();
}
-void ModListSortProxy::setContentFilter(const std::vector<int>& content) {
- m_ContentFilter = content;
- updateFilterActive();
- invalidate();
+void ModListSortProxy::setContentFilter(const std::vector<int> &content)
+{
+ m_ContentFilter = content;
+ updateFilterActive();
+ invalidate();
}
-Qt::ItemFlags ModListSortProxy::flags(const QModelIndex& modelIndex) const {
- Qt::ItemFlags flags = sourceModel()->flags(mapToSource(modelIndex));
+Qt::ItemFlags ModListSortProxy::flags(const QModelIndex &modelIndex) const
+{
+ Qt::ItemFlags flags = sourceModel()->flags(mapToSource(modelIndex));
- return flags;
+ return flags;
}
-void ModListSortProxy::enableAllVisible() {
- if (m_Profile == nullptr)
- return;
+void ModListSortProxy::enableAllVisible()
+{
+ if (m_Profile == nullptr) return;
- for (int i = 0; i < this->rowCount(); ++i) {
- int modID = mapToSource(index(i, 0)).data(Qt::UserRole + 1).toInt();
- m_Profile->setModEnabled(modID, true);
- }
- invalidate();
+ for (int i = 0; i < this->rowCount(); ++i) {
+ int modID = mapToSource(index(i, 0)).data(Qt::UserRole + 1).toInt();
+ m_Profile->setModEnabled(modID, true);
+ }
+ invalidate();
}
-void ModListSortProxy::disableAllVisible() {
- if (m_Profile == nullptr)
- return;
+void ModListSortProxy::disableAllVisible()
+{
+ if (m_Profile == nullptr) return;
- for (int i = 0; i < this->rowCount(); ++i) {
- int modID = mapToSource(index(i, 0)).data(Qt::UserRole + 1).toInt();
- m_Profile->setModEnabled(modID, false);
- }
- invalidate();
+ for (int i = 0; i < this->rowCount(); ++i) {
+ int modID = mapToSource(index(i, 0)).data(Qt::UserRole + 1).toInt();
+ m_Profile->setModEnabled(modID, false);
+ }
+ invalidate();
}
-unsigned long ModListSortProxy::flagsId(const std::vector<ModInfo::EFlag>& flags) const {
- unsigned long result = 0;
- for (ModInfo::EFlag flag : flags) {
- if ((flag != ModInfo::FLAG_FOREIGN) && (flag != ModInfo::FLAG_OVERWRITE)) {
- result += 1 << (int)flag;
- }
+unsigned long ModListSortProxy::flagsId(const std::vector<ModInfo::EFlag> &flags) const
+{
+ unsigned long result = 0;
+ for (ModInfo::EFlag flag : flags) {
+ if ((flag != ModInfo::FLAG_FOREIGN)
+ && (flag != ModInfo::FLAG_OVERWRITE)) {
+ result += 1 << (int)flag;
}
- return result;
+ }
+ return result;
}
-bool ModListSortProxy::lessThan(const QModelIndex& left, const QModelIndex& right) const {
- if (sourceModel()->hasChildren(left) || sourceModel()->hasChildren(right)) {
- return QSortFilterProxyModel::lessThan(left, right);
- }
+bool ModListSortProxy::lessThan(const QModelIndex &left,
+ const QModelIndex &right) const
+{
+ if (sourceModel()->hasChildren(left) || sourceModel()->hasChildren(right)) {
+ return QSortFilterProxyModel::lessThan(left, right);
+ }
- bool lOk, rOk;
- int leftIndex = left.data(Qt::UserRole + 1).toInt(&lOk);
- int rightIndex = right.data(Qt::UserRole + 1).toInt(&rOk);
- if (!lOk || !rOk) {
- return false;
- }
+ bool lOk, rOk;
+ int leftIndex = left.data(Qt::UserRole + 1).toInt(&lOk);
+ int rightIndex = right.data(Qt::UserRole + 1).toInt(&rOk);
+ if (!lOk || !rOk) {
+ return false;
+ }
- ModInfo::Ptr leftMod = ModInfo::getByIndex(leftIndex);
- ModInfo::Ptr rightMod = ModInfo::getByIndex(rightIndex);
+ ModInfo::Ptr leftMod = ModInfo::getByIndex(leftIndex);
+ ModInfo::Ptr rightMod = ModInfo::getByIndex(rightIndex);
- bool lt = false;
+ bool lt = false;
- {
- QModelIndex leftPrioIdx = left.sibling(left.row(), ModList::COL_PRIORITY);
- QVariant leftPrio = leftPrioIdx.data();
- if (!leftPrio.isValid())
- leftPrio = left.data(Qt::UserRole);
- QModelIndex rightPrioIdx = right.sibling(right.row(), ModList::COL_PRIORITY);
- QVariant rightPrio = rightPrioIdx.data();
- if (!rightPrio.isValid())
- rightPrio = right.data(Qt::UserRole);
+ {
+ QModelIndex leftPrioIdx = left.sibling(left.row(), ModList::COL_PRIORITY);
+ QVariant leftPrio = leftPrioIdx.data();
+ if (!leftPrio.isValid()) leftPrio = left.data(Qt::UserRole);
+ QModelIndex rightPrioIdx = right.sibling(right.row(), ModList::COL_PRIORITY);
+ QVariant rightPrio = rightPrioIdx.data();
+ if (!rightPrio.isValid()) rightPrio = right.data(Qt::UserRole);
- lt = leftPrio.toInt() < rightPrio.toInt();
- }
+ lt = leftPrio.toInt() < rightPrio.toInt();
+ }
- switch (left.column()) {
+ switch (left.column()) {
case ModList::COL_FLAGS: {
- std::vector<ModInfo::EFlag> leftFlags = leftMod->getFlags();
- std::vector<ModInfo::EFlag> rightFlags = rightMod->getFlags();
- if (leftFlags.size() != rightFlags.size()) {
- lt = leftFlags.size() < rightFlags.size();
- } else {
- lt = flagsId(leftFlags) < flagsId(rightFlags);
- }
+ std::vector<ModInfo::EFlag> leftFlags = leftMod->getFlags();
+ std::vector<ModInfo::EFlag> rightFlags = rightMod->getFlags();
+ if (leftFlags.size() != rightFlags.size()) {
+ lt = leftFlags.size() < rightFlags.size();
+ } else {
+ lt = flagsId(leftFlags) < flagsId(rightFlags);
+ }
} break;
case ModList::COL_CONTENT: {
- std::vector<ModInfo::EContent> lContent = leftMod->getContents();
- std::vector<ModInfo::EContent> rContent = rightMod->getContents();
- if (lContent.size() != rContent.size()) {
- lt = lContent.size() < rContent.size();
- }
+ std::vector<ModInfo::EContent> lContent = leftMod->getContents();
+ std::vector<ModInfo::EContent> rContent = rightMod->getContents();
+ if (lContent.size() != rContent.size()) {
+ lt = lContent.size() < rContent.size();
+ }
- int lValue = 0;
- int rValue = 0;
- for (ModInfo::EContent content : lContent) {
- lValue += 2 << (unsigned int)content;
- }
- for (ModInfo::EContent content : rContent) {
- rValue += 2 << (unsigned int)content;
- }
+ int lValue = 0;
+ int rValue = 0;
+ for (ModInfo::EContent content : lContent) {
+ lValue += 2 << (unsigned int)content;
+ }
+ for (ModInfo::EContent content : rContent) {
+ rValue += 2 << (unsigned int)content;
+ }
- lt = lValue < rValue;
+ lt = lValue < rValue;
} break;
case ModList::COL_NAME: {
- int comp = QString::compare(leftMod->name(), rightMod->name(), Qt::CaseInsensitive);
- if (comp != 0)
- lt = comp < 0;
+ int comp = QString::compare(leftMod->name(), rightMod->name(), Qt::CaseInsensitive);
+ if (comp != 0)
+ lt = comp < 0;
} break;
case ModList::COL_CATEGORY: {
- if (leftMod->getPrimaryCategory() != rightMod->getPrimaryCategory()) {
- if (leftMod->getPrimaryCategory() < 0)
- lt = false;
- else if (rightMod->getPrimaryCategory() < 0)
- lt = true;
- else {
- try {
- CategoryFactory& categories = CategoryFactory::instance();
- QString leftCatName =
- categories.getCategoryName(categories.getCategoryIndex(leftMod->getPrimaryCategory()));
- QString rightCatName =
- categories.getCategoryName(categories.getCategoryIndex(rightMod->getPrimaryCategory()));
- lt = leftCatName < rightCatName;
- } catch (const std::exception& e) {
- qCritical("failed to compare categories: %s", e.what());
- }
- }
+ if (leftMod->getPrimaryCategory() != rightMod->getPrimaryCategory()) {
+ if (leftMod->getPrimaryCategory() < 0) lt = false;
+ else if (rightMod->getPrimaryCategory() < 0) lt = true;
+ else {
+ try {
+ CategoryFactory &categories = CategoryFactory::instance();
+ QString leftCatName = categories.getCategoryName(categories.getCategoryIndex(leftMod->getPrimaryCategory()));
+ QString rightCatName = categories.getCategoryName(categories.getCategoryIndex(rightMod->getPrimaryCategory()));
+ lt = leftCatName < rightCatName;
+ } catch (const std::exception &e) {
+ qCritical("failed to compare categories: %s", e.what());
+ }
}
+ }
} break;
case ModList::COL_MODID: {
- if (leftMod->getNexusID() != rightMod->getNexusID())
- lt = leftMod->getNexusID() < rightMod->getNexusID();
+ if (leftMod->getNexusID() != rightMod->getNexusID())
+ lt = leftMod->getNexusID() < rightMod->getNexusID();
} break;
case ModList::COL_VERSION: {
- if (leftMod->getVersion() != rightMod->getVersion())
- lt = leftMod->getVersion() < rightMod->getVersion();
+ if (leftMod->getVersion() != rightMod->getVersion())
+ lt = leftMod->getVersion() < rightMod->getVersion();
} break;
case ModList::COL_INSTALLTIME: {
- QDateTime leftTime = left.data().toDateTime();
- QDateTime rightTime = right.data().toDateTime();
- if (leftTime != rightTime)
- return leftTime < rightTime;
+ QDateTime leftTime = left.data().toDateTime();
+ QDateTime rightTime = right.data().toDateTime();
+ if (leftTime != rightTime)
+ return leftTime < rightTime;
} break;
case ModList::COL_PRIORITY: {
- // nop, already compared by priority
+ // nop, already compared by priority
} break;
- }
- return lt;
+ }
+ return lt;
}
-void ModListSortProxy::updateFilter(const QString& filter) {
- m_CurrentFilter = filter;
- updateFilterActive();
- // using invalidateFilter here should be enough but that crashes the application? WTF?
- // invalidateFilter();
- invalidate();
+void ModListSortProxy::updateFilter(const QString &filter)
+{
+ m_CurrentFilter = filter;
+ updateFilterActive();
+ // using invalidateFilter here should be enough but that crashes the application? WTF?
+ // invalidateFilter();
+ invalidate();
}
-bool ModListSortProxy::hasConflictFlag(const std::vector<ModInfo::EFlag>& flags) const {
- for (ModInfo::EFlag flag : flags) {
- if ((flag == ModInfo::FLAG_CONFLICT_MIXED) || (flag == ModInfo::FLAG_CONFLICT_OVERWRITE) ||
- (flag == ModInfo::FLAG_CONFLICT_OVERWRITTEN) || (flag == ModInfo::FLAG_CONFLICT_REDUNDANT)) {
- return true;
- }
+bool ModListSortProxy::hasConflictFlag(const std::vector<ModInfo::EFlag> &flags) const
+{
+ for (ModInfo::EFlag flag : flags) {
+ if ((flag == ModInfo::FLAG_CONFLICT_MIXED) ||
+ (flag == ModInfo::FLAG_CONFLICT_OVERWRITE) ||
+ (flag == ModInfo::FLAG_CONFLICT_OVERWRITTEN) ||
+ (flag == ModInfo::FLAG_CONFLICT_REDUNDANT)) {
+ return true;
}
+ }
- return false;
+ return false;
}
-bool ModListSortProxy::filterMatchesModAnd(ModInfo::Ptr info, bool enabled) const {
- for (auto iter = m_CategoryFilter.begin(); iter != m_CategoryFilter.end(); ++iter) {
- switch (*iter) {
- case CategoryFactory::CATEGORY_SPECIAL_CHECKED: {
- if (!enabled && !info->alwaysEnabled())
- return false;
- } break;
- case CategoryFactory::CATEGORY_SPECIAL_UNCHECKED: {
- if (enabled || info->alwaysEnabled())
- return false;
- } break;
- case CategoryFactory::CATEGORY_SPECIAL_UPDATEAVAILABLE: {
- if (!info->updateAvailable() && !info->downgradeAvailable())
- return false;
- } break;
- case CategoryFactory::CATEGORY_SPECIAL_NOCATEGORY: {
- if (info->getCategories().size() > 0)
- return false;
- } break;
- case CategoryFactory::CATEGORY_SPECIAL_CONFLICT: {
- if (!hasConflictFlag(info->getFlags()))
- return false;
- } break;
- case CategoryFactory::CATEGORY_SPECIAL_NOTENDORSED: {
- ModInfo::EEndorsedState state = info->endorsedState();
- if (state != ModInfo::ENDORSED_FALSE)
- return false;
- } break;
- case CategoryFactory::CATEGORY_SPECIAL_MANAGED: {
- if (info->hasFlag(ModInfo::FLAG_FOREIGN))
- return false;
- } break;
- case CategoryFactory::CATEGORY_SPECIAL_UNMANAGED: {
- if (!info->hasFlag(ModInfo::FLAG_FOREIGN))
- return false;
- } break;
- default: {
- if (!info->categorySet(*iter))
- return false;
- } break;
- }
+bool ModListSortProxy::filterMatchesModAnd(ModInfo::Ptr info, bool enabled) const
+{
+ for (auto iter = m_CategoryFilter.begin(); iter != m_CategoryFilter.end(); ++iter) {
+ switch (*iter) {
+ case CategoryFactory::CATEGORY_SPECIAL_CHECKED: {
+ if (!enabled && !info->alwaysEnabled()) return false;
+ } break;
+ case CategoryFactory::CATEGORY_SPECIAL_UNCHECKED: {
+ if (enabled || info->alwaysEnabled()) return false;
+ } break;
+ case CategoryFactory::CATEGORY_SPECIAL_UPDATEAVAILABLE: {
+ if (!info->updateAvailable() && !info->downgradeAvailable()) return false;
+ } break;
+ case CategoryFactory::CATEGORY_SPECIAL_NOCATEGORY: {
+ if (info->getCategories().size() > 0) return false;
+ } break;
+ case CategoryFactory::CATEGORY_SPECIAL_CONFLICT: {
+ if (!hasConflictFlag(info->getFlags())) return false;
+ } break;
+ case CategoryFactory::CATEGORY_SPECIAL_NOTENDORSED: {
+ ModInfo::EEndorsedState state = info->endorsedState();
+ if (state != ModInfo::ENDORSED_FALSE) return false;
+ } break;
+ case CategoryFactory::CATEGORY_SPECIAL_MANAGED: {
+ if (info->hasFlag(ModInfo::FLAG_FOREIGN)) return false;
+ } break;
+ case CategoryFactory::CATEGORY_SPECIAL_UNMANAGED: {
+ if (!info->hasFlag(ModInfo::FLAG_FOREIGN)) return false;
+ } break;
+ default: {
+ if (!info->categorySet(*iter)) return false;
+ } break;
}
+ }
- foreach (int content, m_ContentFilter) {
- if (!info->hasContent(static_cast<ModInfo::EContent>(content)))
- return false;
- }
+ foreach (int content, m_ContentFilter) {
+ if (!info->hasContent(static_cast<ModInfo::EContent>(content))) return false;
+ }
- return true;
+ return true;
}
-bool ModListSortProxy::filterMatchesModOr(ModInfo::Ptr info, bool enabled) const {
- for (auto iter = m_CategoryFilter.begin(); iter != m_CategoryFilter.end(); ++iter) {
- switch (*iter) {
- case CategoryFactory::CATEGORY_SPECIAL_CHECKED: {
- if (enabled || info->alwaysEnabled())
- return true;
- } break;
- case CategoryFactory::CATEGORY_SPECIAL_UNCHECKED: {
- if (!enabled && !info->alwaysEnabled())
- return true;
- } break;
- case CategoryFactory::CATEGORY_SPECIAL_UPDATEAVAILABLE: {
- if (info->updateAvailable() || info->downgradeAvailable())
- return true;
- } break;
- case CategoryFactory::CATEGORY_SPECIAL_NOCATEGORY: {
- if (info->getCategories().size() == 0)
- return true;
- } break;
- case CategoryFactory::CATEGORY_SPECIAL_CONFLICT: {
- if (hasConflictFlag(info->getFlags()))
- return true;
- } break;
- case CategoryFactory::CATEGORY_SPECIAL_NOTENDORSED: {
- ModInfo::EEndorsedState state = info->endorsedState();
- if ((state == ModInfo::ENDORSED_FALSE) || (state == ModInfo::ENDORSED_NEVER))
- return true;
- } break;
- case CategoryFactory::CATEGORY_SPECIAL_MANAGED: {
- if (!info->hasFlag(ModInfo::FLAG_FOREIGN))
- return true;
- } break;
- case CategoryFactory::CATEGORY_SPECIAL_UNMANAGED: {
- if (info->hasFlag(ModInfo::FLAG_FOREIGN))
- return true;
- } break;
- default: {
- if (info->categorySet(*iter))
- return true;
- } break;
- }
+bool ModListSortProxy::filterMatchesModOr(ModInfo::Ptr info, bool enabled) const
+{
+ for (auto iter = m_CategoryFilter.begin(); iter != m_CategoryFilter.end(); ++iter) {
+ switch (*iter) {
+ case CategoryFactory::CATEGORY_SPECIAL_CHECKED: {
+ if (enabled || info->alwaysEnabled()) return true;
+ } break;
+ case CategoryFactory::CATEGORY_SPECIAL_UNCHECKED: {
+ if (!enabled && !info->alwaysEnabled()) return true;
+ } break;
+ case CategoryFactory::CATEGORY_SPECIAL_UPDATEAVAILABLE: {
+ if (info->updateAvailable() || info->downgradeAvailable()) return true;
+ } break;
+ case CategoryFactory::CATEGORY_SPECIAL_NOCATEGORY: {
+ if (info->getCategories().size() == 0) return true;
+ } break;
+ case CategoryFactory::CATEGORY_SPECIAL_CONFLICT: {
+ if (hasConflictFlag(info->getFlags())) return true;
+ } break;
+ case CategoryFactory::CATEGORY_SPECIAL_NOTENDORSED: {
+ ModInfo::EEndorsedState state = info->endorsedState();
+ if ((state == ModInfo::ENDORSED_FALSE) || (state == ModInfo::ENDORSED_NEVER)) return true;
+ } break;
+ case CategoryFactory::CATEGORY_SPECIAL_MANAGED: {
+ if (!info->hasFlag(ModInfo::FLAG_FOREIGN)) return true;
+ } break;
+ case CategoryFactory::CATEGORY_SPECIAL_UNMANAGED: {
+ if (info->hasFlag(ModInfo::FLAG_FOREIGN)) return true;
+ } break;
+ default: {
+ if (info->categorySet(*iter)) return true;
+ } break;
}
+ }
- foreach (int content, m_ContentFilter) {
- if (info->hasContent(static_cast<ModInfo::EContent>(content)))
- return true;
- }
+ foreach (int content, m_ContentFilter) {
+ if (info->hasContent(static_cast<ModInfo::EContent>(content))) return true;
+ }
- return false;
+ return false;
}
-bool ModListSortProxy::filterMatchesMod(ModInfo::Ptr info, bool enabled) const {
- if (!m_CurrentFilter.isEmpty() && !info->name().contains(m_CurrentFilter, Qt::CaseInsensitive)) {
- return false;
- }
+bool ModListSortProxy::filterMatchesMod(ModInfo::Ptr info, bool enabled) const
+{
+ if (!m_CurrentFilter.isEmpty() &&
+ !info->name().contains(m_CurrentFilter, Qt::CaseInsensitive)) {
+ return false;
+ }
- if (m_FilterMode == FILTER_AND) {
- return filterMatchesModAnd(info, enabled);
- } else {
- return filterMatchesModOr(info, enabled);
- }
+ if (m_FilterMode == FILTER_AND) {
+ return filterMatchesModAnd(info, enabled);
+ } else {
+ return filterMatchesModOr(info, enabled);
+ }
}
-void ModListSortProxy::setFilterMode(ModListSortProxy::FilterMode mode) {
- if (m_FilterMode != mode) {
- m_FilterMode = mode;
- this->invalidate();
- }
+void ModListSortProxy::setFilterMode(ModListSortProxy::FilterMode mode)
+{
+ if (m_FilterMode != mode) {
+ m_FilterMode = mode;
+ this->invalidate();
+ }
}
-bool ModListSortProxy::filterAcceptsRow(int row, const QModelIndex& parent) const {
- if (m_Profile == nullptr) {
- return false;
- }
+bool ModListSortProxy::filterAcceptsRow(int row, const QModelIndex &parent) const
+{
+ if (m_Profile == nullptr) {
+ return false;
+ }
- if (row >= static_cast<int>(m_Profile->numMods())) {
- qWarning("invalid row idx %d", row);
- return false;
- }
+ if (row >= static_cast<int>(m_Profile->numMods())) {
+ qWarning("invalid row idx %d", row);
+ return false;
+ }
- QModelIndex idx = sourceModel()->index(row, 0, parent);
- if (!idx.isValid()) {
- qDebug("invalid index");
- return false;
+ QModelIndex idx = sourceModel()->index(row, 0, parent);
+ if (!idx.isValid()) {
+ qDebug("invalid index");
+ return false;
+ }
+ if (sourceModel()->hasChildren(idx)) {
+ for (int i = 0; i < sourceModel()->rowCount(idx); ++i) {
+ if (filterAcceptsRow(i, idx)) {
+ return true;
+ }
}
- if (sourceModel()->hasChildren(idx)) {
- for (int i = 0; i < sourceModel()->rowCount(idx); ++i) {
- if (filterAcceptsRow(i, idx)) {
- return true;
- }
- }
- return false;
- } else {
- bool modEnabled = idx.sibling(row, 0).data(Qt::CheckStateRole).toInt() == Qt::Checked;
- unsigned int index = idx.data(Qt::UserRole + 1).toInt();
- return filterMatchesMod(ModInfo::getByIndex(index), modEnabled);
- }
+ return false;
+ } else {
+ bool modEnabled = idx.sibling(row, 0).data(Qt::CheckStateRole).toInt() == Qt::Checked;
+ unsigned int index = idx.data(Qt::UserRole + 1).toInt();
+ return filterMatchesMod(ModInfo::getByIndex(index), modEnabled);
+ }
}
-bool ModListSortProxy::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column,
- const QModelIndex& parent) {
- if (!data->hasUrls() && (sortColumn() != ModList::COL_PRIORITY)) {
- QWidget* wid = qApp->activeWindow()->findChild<QTreeView*>("modList");
- MessageDialog::showMessage(tr("Drag&Drop is only supported when sorting by priority"), wid);
- return false;
- }
- if ((row == -1) && (column == -1)) {
- return sourceModel()->dropMimeData(data, action, -1, -1, mapToSource(parent));
- }
- // in the regular model, when dropping between rows, the row-value passed to
- // the sourceModel is inconsistent between ascending and descending ordering.
- // This should fix that
- if (sortOrder() == Qt::DescendingOrder) {
- --row;
- }
+bool ModListSortProxy::dropMimeData(const QMimeData *data, Qt::DropAction action,
+ int row, int column, const QModelIndex &parent)
+{
+ if (!data->hasUrls() && (sortColumn() != ModList::COL_PRIORITY)) {
+ QWidget *wid = qApp->activeWindow()->findChild<QTreeView*>("modList");
+ MessageDialog::showMessage(tr("Drag&Drop is only supported when sorting by priority"), wid);
+ return false;
+ }
+ if ((row == -1) && (column == -1)) {
+ return sourceModel()->dropMimeData(data, action, -1, -1, mapToSource(parent));
+ }
+ // in the regular model, when dropping between rows, the row-value passed to
+ // the sourceModel is inconsistent between ascending and descending ordering.
+ // This should fix that
+ if (sortOrder() == Qt::DescendingOrder) {
+ --row;
+ }
- QModelIndex proxyIndex = index(row, column, parent);
- QModelIndex sourceIndex = mapToSource(proxyIndex);
- return this->sourceModel()->dropMimeData(data, action, sourceIndex.row(), sourceIndex.column(),
- sourceIndex.parent());
+ QModelIndex proxyIndex = index(row, column, parent);
+ QModelIndex sourceIndex = mapToSource(proxyIndex);
+ return this->sourceModel()->dropMimeData(data, action, sourceIndex.row(), sourceIndex.column(),
+ sourceIndex.parent());
}
-void ModListSortProxy::setSourceModel(QAbstractItemModel* sourceModel) {
- QSortFilterProxyModel::setSourceModel(sourceModel);
- QtGroupingProxy* proxy = qobject_cast<QtGroupingProxy*>(sourceModel);
- if (proxy != nullptr) {
- sourceModel = proxy->sourceModel();
- }
- connect(sourceModel, SIGNAL(aboutToChangeData()), this, SLOT(aboutToChangeData()), Qt::UniqueConnection);
- connect(sourceModel, SIGNAL(postDataChanged()), this, SLOT(postDataChanged()), Qt::UniqueConnection);
+void ModListSortProxy::setSourceModel(QAbstractItemModel *sourceModel)
+{
+ QSortFilterProxyModel::setSourceModel(sourceModel);
+ QtGroupingProxy *proxy = qobject_cast<QtGroupingProxy*>(sourceModel);
+ if (proxy != nullptr) {
+ sourceModel = proxy->sourceModel();
+ }
+ connect(sourceModel, SIGNAL(aboutToChangeData()), this, SLOT(aboutToChangeData()), Qt::UniqueConnection);
+ connect(sourceModel, SIGNAL(postDataChanged()), this, SLOT(postDataChanged()), Qt::UniqueConnection);
}
-void ModListSortProxy::aboutToChangeData() {
- // having a filter active when dataChanged is called caused a crash
- // (at least with some Qt versions)
- // this may be related to the fact that the item being edited may disappear from the view as a
- // result of the edit
- m_PreChangeFilters = categoryFilter();
- setCategoryFilter(std::vector<int>());
+void ModListSortProxy::aboutToChangeData()
+{
+ // having a filter active when dataChanged is called caused a crash
+ // (at least with some Qt versions)
+ // this may be related to the fact that the item being edited may disappear from the view as a
+ // result of the edit
+ m_PreChangeFilters = categoryFilter();
+ setCategoryFilter(std::vector<int>());
}
-void ModListSortProxy::postDataChanged() {
- // if the filter is re-activated right away the editor can't be deleted but becomes invisible
- // or at least the view continues to think it's being edited. As a result no new editor can be
- // opened
- QTimer::singleShot(10, [this]() {
- setCategoryFilter(m_PreChangeFilters);
- m_PreChangeFilters.clear();
- });
+void ModListSortProxy::postDataChanged()
+{
+ // if the filter is re-activated right away the editor can't be deleted but becomes invisible
+ // or at least the view continues to think it's being edited. As a result no new editor can be
+ // opened
+ QTimer::singleShot(10, [this] () {
+ setCategoryFilter(m_PreChangeFilters);
+ m_PreChangeFilters.clear();
+ });
}
+
diff --git a/src/modlistsortproxy.h b/src/modlistsortproxy.h
index 157889f0..b3c01fea 100644
--- a/src/modlistsortproxy.h
+++ b/src/modlistsortproxy.h
@@ -20,104 +20,120 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef MODLISTSORTPROXY_H
#define MODLISTSORTPROXY_H
-#include "modlist.h"
#include <QSortFilterProxyModel>
#include <bitset>
+#include "modlist.h"
class Profile;
-class ModListSortProxy : public QSortFilterProxyModel {
- Q_OBJECT
+class ModListSortProxy : public QSortFilterProxyModel
+{
+ Q_OBJECT
public:
- enum FilterMode { FILTER_AND, FILTER_OR };
- enum FilterType { TYPE_SPECIAL, TYPE_CATEGORY, TYPE_CONTENT };
+ enum FilterMode {
+ FILTER_AND,
+ FILTER_OR
+ };
+
+ enum FilterType {
+ TYPE_SPECIAL,
+ TYPE_CATEGORY,
+ TYPE_CONTENT
+ };
public:
- explicit ModListSortProxy(Profile* profile, QObject* parent = 0);
- void setProfile(Profile* profile);
+ explicit ModListSortProxy(Profile *profile, QObject *parent = 0);
+
+ void setProfile(Profile *profile);
- void setCategoryFilter(const std::vector<int>& categories);
- std::vector<int> categoryFilter() const { return m_CategoryFilter; }
+ void setCategoryFilter(const std::vector<int> &categories);
+ std::vector<int> categoryFilter() const { return m_CategoryFilter; }
- void setContentFilter(const std::vector<int>& content);
+ void setContentFilter(const std::vector<int> &content);
- virtual Qt::ItemFlags flags(const QModelIndex& modelIndex) const;
- virtual bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column,
- const QModelIndex& parent);
+ virtual Qt::ItemFlags flags(const QModelIndex &modelIndex) const;
+ virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action,
+ int row, int column, const QModelIndex &parent);
- virtual void setSourceModel(QAbstractItemModel* sourceModel) override;
+ virtual void setSourceModel(QAbstractItemModel *sourceModel) override;
- /**
- * @brief enable all mods visible under the current filter
- **/
- void enableAllVisible();
+ /**
+ * @brief enable all mods visible under the current filter
+ **/
+ void enableAllVisible();
- /**
- * @brief disable all mods visible under the current filter
- **/
- void disableAllVisible();
+ /**
+ * @brief disable all mods visible under the current filter
+ **/
+ void disableAllVisible();
- /**
- * @brief tests if a filtere matches for a mod
- * @param info mod information
- * @param enabled true if the mod is currently active
- * @return true if current active filters match for the specified mod
- */
- bool filterMatchesMod(ModInfo::Ptr info, bool enabled) const;
+ /**
+ * @brief tests if a filtere matches for a mod
+ * @param info mod information
+ * @param enabled true if the mod is currently active
+ * @return true if current active filters match for the specified mod
+ */
+ bool filterMatchesMod(ModInfo::Ptr info, bool enabled) const;
- /**
- * @return true if a filter is currently active
- */
- bool isFilterActive() const { return m_FilterActive; }
+ /**
+ * @return true if a filter is currently active
+ */
+ bool isFilterActive() const { return m_FilterActive; }
- void setFilterMode(FilterMode mode);
+ void setFilterMode(FilterMode mode);
- /**
- * @brief tests if the specified index has child nodes
- * @param parent the node to test
- * @return true if there are child nodes
- */
- virtual bool hasChildren(const QModelIndex& parent = QModelIndex()) const { return rowCount(parent) > 0; }
+ /**
+ * @brief tests if the specified index has child nodes
+ * @param parent the node to test
+ * @return true if there are child nodes
+ */
+ virtual bool hasChildren ( const QModelIndex & parent = QModelIndex() ) const {
+ return rowCount(parent) > 0;
+ }
public slots:
- void updateFilter(const QString& filter);
+ void updateFilter(const QString &filter);
signals:
- void filterActive(bool active);
+ void filterActive(bool active);
protected:
- virtual bool lessThan(const QModelIndex& left, const QModelIndex& right) const;
- virtual bool filterAcceptsRow(int row, const QModelIndex& parent) const;
+
+ virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
+ virtual bool filterAcceptsRow(int row, const QModelIndex &parent) const;
private:
- unsigned long flagsId(const std::vector<ModInfo::EFlag>& flags) const;
- bool hasConflictFlag(const std::vector<ModInfo::EFlag>& flags) const;
- void updateFilterActive();
- bool filterMatchesModAnd(ModInfo::Ptr info, bool enabled) const;
- bool filterMatchesModOr(ModInfo::Ptr info, bool enabled) const;
+
+ unsigned long flagsId(const std::vector<ModInfo::EFlag> &flags) const;
+ bool hasConflictFlag(const std::vector<ModInfo::EFlag> &flags) const;
+ void updateFilterActive();
+ bool filterMatchesModAnd(ModInfo::Ptr info, bool enabled) const;
+ bool filterMatchesModOr(ModInfo::Ptr info, bool enabled) const;
private slots:
- void aboutToChangeData();
- void postDataChanged();
+ void aboutToChangeData();
+ void postDataChanged();
private:
- Profile* m_Profile;
- std::vector<int> m_CategoryFilter;
- std::vector<int> m_ContentFilter;
- std::bitset<ModList::COL_LASTCOLUMN + 1> m_EnabledColumns;
- QString m_CurrentFilter;
+ Profile *m_Profile;
+
+ std::vector<int> m_CategoryFilter;
+ std::vector<int> m_ContentFilter;
+ std::bitset<ModList::COL_LASTCOLUMN + 1> m_EnabledColumns;
+ QString m_CurrentFilter;
+
+ bool m_FilterActive;
+ FilterMode m_FilterMode;
- bool m_FilterActive;
- FilterMode m_FilterMode;
+ std::vector<int> m_PreChangeFilters;
- std::vector<int> m_PreChangeFilters;
};
#endif // MODLISTSORTPROXY_H
diff --git a/src/modlistview.cpp b/src/modlistview.cpp
index 9b98a3b7..fe2d3e57 100644
--- a/src/modlistview.cpp
+++ b/src/modlistview.cpp
@@ -1,47 +1,56 @@
#include "modlistview.h"
+#include <QUrl>
#include <QMimeData>
#include <QProxyStyle>
-#include <QUrl>
-class ModListViewStyle : public QProxyStyle {
-public:
- ModListViewStyle(QStyle* style, int indentation);
- void drawPrimitive(PrimitiveElement element, const QStyleOption* option, QPainter* painter,
- const QWidget* widget = 0) const;
+class ModListViewStyle: public QProxyStyle {
+public:
+ ModListViewStyle(QStyle *style, int indentation);
+ void drawPrimitive (PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget = 0) const;
private:
- int m_Indentation;
+ int m_Indentation;
};
-ModListViewStyle::ModListViewStyle(QStyle* style, int indentation) : QProxyStyle(style), m_Indentation(indentation) {}
+ModListViewStyle::ModListViewStyle(QStyle *style, int indentation)
+ : QProxyStyle(style), m_Indentation(indentation)
+{
+}
-void ModListViewStyle::drawPrimitive(PrimitiveElement element, const QStyleOption* option, QPainter* painter,
- const QWidget* widget) const {
- if (element == QStyle::PE_IndicatorItemViewItemDrop && !option->rect.isNull()) {
- QStyleOption opt(*option);
- opt.rect.setLeft(m_Indentation);
- if (widget) {
- opt.rect.setRight(widget->width() - 5); // 5 is an arbitrary value that seems to work ok
- }
- QProxyStyle::drawPrimitive(element, &opt, painter, widget);
- } else {
- QProxyStyle::drawPrimitive(element, option, painter, widget);
+void ModListViewStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const
+{
+ if (element == QStyle::PE_IndicatorItemViewItemDrop && !option->rect.isNull()) {
+ QStyleOption opt(*option);
+ opt.rect.setLeft(m_Indentation);
+ if (widget) {
+ opt.rect.setRight(widget->width() - 5); // 5 is an arbitrary value that seems to work ok
}
+ QProxyStyle::drawPrimitive(element, &opt, painter, widget);
+ } else {
+ QProxyStyle::drawPrimitive(element, option, painter, widget);
+ }
}
-ModListView::ModListView(QWidget* parent)
- : QTreeView(parent), m_Scrollbar(new ViewMarkingScrollBar(this->model(), this)) {
- setVerticalScrollBar(m_Scrollbar);
+ModListView::ModListView(QWidget *parent)
+ : QTreeView(parent)
+ , m_Scrollbar(new ViewMarkingScrollBar(this->model(), this))
+{
+ setVerticalScrollBar(m_Scrollbar);
}
-void ModListView::dragEnterEvent(QDragEnterEvent* event) {
- emit dropModeUpdate(event->mimeData()->hasUrls());
+void ModListView::dragEnterEvent(QDragEnterEvent *event)
+{
+ emit dropModeUpdate(event->mimeData()->hasUrls());
- QTreeView::dragEnterEvent(event);
+ QTreeView::dragEnterEvent(event);
}
-void ModListView::setModel(QAbstractItemModel* model) {
- QTreeView::setModel(model);
- setVerticalScrollBar(new ViewMarkingScrollBar(model, this));
+void ModListView::setModel(QAbstractItemModel *model)
+{
+ QTreeView::setModel(model);
+ setVerticalScrollBar(new ViewMarkingScrollBar(model, this));
}
+
diff --git a/src/modlistview.h b/src/modlistview.h
index a4f56efc..6cd114b0 100644
--- a/src/modlistview.h
+++ b/src/modlistview.h
@@ -1,22 +1,24 @@
#ifndef MODLISTVIEW_H
#define MODLISTVIEW_H
-#include "viewmarkingscrollbar.h"
-#include <QDragEnterEvent>
#include <QTreeView>
+#include <QDragEnterEvent>
+#include "viewmarkingscrollbar.h"
-class ModListView : public QTreeView {
- Q_OBJECT
+class ModListView : public QTreeView
+{
+ Q_OBJECT
public:
- explicit ModListView(QWidget* parent = 0);
- virtual void dragEnterEvent(QDragEnterEvent* event);
- virtual void setModel(QAbstractItemModel* model);
+ explicit ModListView(QWidget *parent = 0);
+ virtual void dragEnterEvent(QDragEnterEvent *event);
+ virtual void setModel(QAbstractItemModel *model);
signals:
- void dropModeUpdate(bool dropOnRows);
-
+ void dropModeUpdate(bool dropOnRows);
+
public slots:
private:
- ViewMarkingScrollBar* m_Scrollbar;
+
+ ViewMarkingScrollBar *m_Scrollbar;
};
#endif // MODLISTVIEW_H
diff --git a/src/moshortcut.cpp b/src/moshortcut.cpp
index 75157c1d..c8c2ef6f 100644
--- a/src/moshortcut.cpp
+++ b/src/moshortcut.cpp
@@ -17,17 +17,23 @@ You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
+
#include "moshortcut.h"
-MOShortcut::MOShortcut(const QString& link) : m_valid(link.startsWith("moshortcut://")), m_hasInstance(false) {
- if (m_valid) {
- int start = (int)strlen("moshortcut://");
- int sep = link.indexOf(':', start);
- if (sep >= 0) {
- m_hasInstance = true;
- m_instance = link.mid(start, sep - start);
- m_executable = link.mid(sep + 1);
- } else
- m_executable = link.mid(start);
+
+MOShortcut::MOShortcut(const QString& link)
+ : m_valid(link.startsWith("moshortcut://"))
+ , m_hasInstance(false)
+{
+ if (m_valid) {
+ int start = (int)strlen("moshortcut://");
+ int sep = link.indexOf(':', start);
+ if (sep >= 0) {
+ m_hasInstance = true;
+ m_instance = link.mid(start, sep - start);
+ m_executable = link.mid(sep + 1);
}
+ else
+ m_executable = link.mid(start);
+ }
}
diff --git a/src/moshortcut.h b/src/moshortcut.h
index 8ae5bb24..7b7574b9 100644
--- a/src/moshortcut.h
+++ b/src/moshortcut.h
@@ -17,27 +17,30 @@ You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
+
#pragma once
+
#include <QString>
+
class MOShortcut {
public:
- MOShortcut(const QString& link);
+ MOShortcut(const QString& link);
- /// true iff intialized using a valid moshortcut link
- operator bool() const { return m_valid; }
+ /// true iff intialized using a valid moshortcut link
+ operator bool() const { return m_valid; }
- bool hasInstance() const { return m_hasInstance; }
+ bool hasInstance() const { return m_hasInstance; }
- const QString& instance() const { return m_instance; }
+ const QString& instance() const { return m_instance; }
- const QString& executable() const { return m_executable; }
+ const QString& executable() const { return m_executable; }
private:
- QString m_instance;
- QString m_executable;
- bool m_valid;
- bool m_hasInstance;
+ QString m_instance;
+ QString m_executable;
+ bool m_valid;
+ bool m_hasInstance;
};
diff --git a/src/motddialog.cpp b/src/motddialog.cpp
index a03bdf75..96d88542 100644
--- a/src/motddialog.cpp
+++ b/src/motddialog.cpp
@@ -19,20 +19,29 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "motddialog.h"
#include "bbcode.h"
-#include "ui_motddialog.h"
#include "utility.h"
+#include "ui_motddialog.h"
#include <Shlwapi.h>
-MotDDialog::MotDDialog(const QString& message, QWidget* parent) : QDialog(parent), ui(new Ui::MotDDialog) {
- ui->setupUi(this);
- ui->motdView->setHtml(BBCode::convertToHTML(message));
- connect(ui->motdView, SIGNAL(anchorClicked(QUrl)), this, SLOT(linkClicked(QUrl)));
+MotDDialog::MotDDialog(const QString &message, QWidget *parent)
+ : QDialog(parent), ui(new Ui::MotDDialog)
+{
+ ui->setupUi(this);
+ ui->motdView->setHtml(BBCode::convertToHTML(message));
+ connect(ui->motdView, SIGNAL(anchorClicked(QUrl)), this, SLOT(linkClicked(QUrl)));
}
-MotDDialog::~MotDDialog() { delete ui; }
+MotDDialog::~MotDDialog()
+{
+ delete ui;
+}
-void MotDDialog::on_okButton_clicked() { this->close(); }
+void MotDDialog::on_okButton_clicked()
+{
+ this->close();
+}
-void MotDDialog::linkClicked(const QUrl& url) {
- ::ShellExecuteW(nullptr, L"open", MOBase::ToWString(url.toString()).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
+void MotDDialog::linkClicked(const QUrl &url)
+{
+ ::ShellExecuteW(nullptr, L"open", MOBase::ToWString(url.toString()).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
}
diff --git a/src/motddialog.h b/src/motddialog.h
index 17636584..5791321f 100644
--- a/src/motddialog.h
+++ b/src/motddialog.h
@@ -27,19 +27,20 @@ namespace Ui {
class MotDDialog;
}
-class MotDDialog : public QDialog {
- Q_OBJECT
-
+class MotDDialog : public QDialog
+{
+ Q_OBJECT
+
public:
- explicit MotDDialog(const QString& message, QWidget* parent = 0);
- ~MotDDialog();
-
+ explicit MotDDialog(const QString &message, QWidget *parent = 0);
+ ~MotDDialog();
+
private slots:
- void on_okButton_clicked();
- void linkClicked(const QUrl& url);
+ void on_okButton_clicked();
+ void linkClicked(const QUrl &url);
private:
- Ui::MotDDialog* ui;
+ Ui::MotDDialog *ui;
};
#endif // MOTDDIALOG_H
diff --git a/src/nexusinterface.cpp b/src/nexusinterface.cpp
index cadcc663..eba02a6f 100644
--- a/src/nexusinterface.cpp
+++ b/src/nexusinterface.cpp
@@ -20,530 +20,647 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "nexusinterface.h"
#include "iplugingame.h"
-#include "json.h"
#include "nxmaccessmanager.h"
+#include "json.h"
#include "selectiondialog.h"
-#include <util.h>
#include <utility.h>
+#include <util.h>
#include <QApplication>
#include <QNetworkCookieJar>
#include <regex>
+
using namespace MOBase;
using namespace MOShared;
-NexusBridge::NexusBridge(const QString& subModule) : m_Interface(NexusInterface::instance()), m_SubModule(subModule) {}
-void NexusBridge::requestDescription(int modID, QVariant userData) {
- m_RequestIDs.insert(m_Interface->requestDescription(modID, this, userData, m_SubModule));
+NexusBridge::NexusBridge(const QString &subModule)
+ : m_Interface(NexusInterface::instance())
+ , m_SubModule(subModule)
+{
}
-void NexusBridge::requestFiles(int modID, QVariant userData) {
- m_RequestIDs.insert(m_Interface->requestFiles(modID, this, userData, m_SubModule));
+void NexusBridge::requestDescription(int modID, QVariant userData)
+{
+ m_RequestIDs.insert(m_Interface->requestDescription(modID, this, userData, m_SubModule));
}
-void NexusBridge::requestFileInfo(int modID, int fileID, QVariant userData) {
- m_RequestIDs.insert(m_Interface->requestFileInfo(modID, fileID, this, userData, m_SubModule));
+void NexusBridge::requestFiles(int modID, QVariant userData)
+{
+ m_RequestIDs.insert(m_Interface->requestFiles(modID, this, userData, m_SubModule));
}
-void NexusBridge::requestDownloadURL(int modID, int fileID, QVariant userData) {
- m_RequestIDs.insert(m_Interface->requestDownloadURL(modID, fileID, this, userData, m_SubModule));
+void NexusBridge::requestFileInfo(int modID, int fileID, QVariant userData)
+{
+ m_RequestIDs.insert(m_Interface->requestFileInfo(modID, fileID, this, userData, m_SubModule));
}
-void NexusBridge::requestToggleEndorsement(int modID, bool endorse, QVariant userData) {
- m_RequestIDs.insert(m_Interface->requestToggleEndorsement(modID, endorse, this, userData, m_SubModule));
+void NexusBridge::requestDownloadURL(int modID, int fileID, QVariant userData)
+{
+ m_RequestIDs.insert(m_Interface->requestDownloadURL(modID, fileID, this, userData, m_SubModule));
}
-void NexusBridge::nxmDescriptionAvailable(int modID, QVariant userData, QVariant resultData, int requestID) {
- std::set<int>::iterator iter = m_RequestIDs.find(requestID);
- if (iter != m_RequestIDs.end()) {
- m_RequestIDs.erase(iter);
-
- emit descriptionAvailable(modID, userData, resultData);
- }
+void NexusBridge::requestToggleEndorsement(int modID, bool endorse, QVariant userData)
+{
+ m_RequestIDs.insert(m_Interface->requestToggleEndorsement(modID, endorse, this, userData, m_SubModule));
}
-void NexusBridge::nxmFilesAvailable(int modID, QVariant userData, QVariant resultData, int requestID) {
- std::set<int>::iterator iter = m_RequestIDs.find(requestID);
- if (iter != m_RequestIDs.end()) {
- m_RequestIDs.erase(iter);
+void NexusBridge::nxmDescriptionAvailable(int modID, QVariant userData, QVariant resultData, int requestID)
+{
+ std::set<int>::iterator iter = m_RequestIDs.find(requestID);
+ if (iter != m_RequestIDs.end()) {
+ m_RequestIDs.erase(iter);
- QList<ModRepositoryFileInfo> fileInfoList;
+ emit descriptionAvailable(modID, userData, resultData);
+ }
+}
- QVariantList resultList = resultData.toList();
+void NexusBridge::nxmFilesAvailable(int modID, QVariant userData, QVariant resultData, int requestID)
+{
+ std::set<int>::iterator iter = m_RequestIDs.find(requestID);
+ if (iter != m_RequestIDs.end()) {
+ m_RequestIDs.erase(iter);
- for (const QVariant& file : resultList) {
- ModRepositoryFileInfo temp;
- QVariantMap fileInfo = file.toMap();
- temp.uri = fileInfo["uri"].toString();
- temp.name = fileInfo["name"].toString();
- temp.description = fileInfo["description"].toString();
- temp.version = VersionInfo(fileInfo["version"].toString());
- temp.categoryID = fileInfo["category_id"].toInt();
- temp.fileID = fileInfo["id"].toInt();
- temp.fileSize = fileInfo["size"].toInt();
- fileInfoList.append(temp);
- }
+ QList<ModRepositoryFileInfo> fileInfoList;
+
+ QVariantList resultList = resultData.toList();
- emit filesAvailable(modID, userData, fileInfoList);
+ for (const QVariant &file : resultList) {
+ ModRepositoryFileInfo temp;
+ QVariantMap fileInfo = file.toMap();
+ temp.uri = fileInfo["uri"].toString();
+ temp.name = fileInfo["name"].toString();
+ temp.description = fileInfo["description"].toString();
+ temp.version = VersionInfo(fileInfo["version"].toString());
+ temp.categoryID = fileInfo["category_id"].toInt();
+ temp.fileID = fileInfo["id"].toInt();
+ temp.fileSize = fileInfo["size"].toInt();
+ fileInfoList.append(temp);
}
+
+ emit filesAvailable(modID, userData, fileInfoList);
+ }
}
-void NexusBridge::nxmFileInfoAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID) {
- std::set<int>::iterator iter = m_RequestIDs.find(requestID);
- if (iter != m_RequestIDs.end()) {
- m_RequestIDs.erase(iter);
- emit fileInfoAvailable(modID, fileID, userData, resultData);
- }
+void NexusBridge::nxmFileInfoAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID)
+{
+ std::set<int>::iterator iter = m_RequestIDs.find(requestID);
+ if (iter != m_RequestIDs.end()) {
+ m_RequestIDs.erase(iter);
+ emit fileInfoAvailable(modID, fileID, userData, resultData);
+ }
}
-void NexusBridge::nxmDownloadURLsAvailable(int modID, int fileID, QVariant userData, QVariant resultData,
- int requestID) {
- std::set<int>::iterator iter = m_RequestIDs.find(requestID);
- if (iter != m_RequestIDs.end()) {
- m_RequestIDs.erase(iter);
- emit downloadURLsAvailable(modID, fileID, userData, resultData);
- }
+void NexusBridge::nxmDownloadURLsAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID)
+{
+ std::set<int>::iterator iter = m_RequestIDs.find(requestID);
+ if (iter != m_RequestIDs.end()) {
+ m_RequestIDs.erase(iter);
+ emit downloadURLsAvailable(modID, fileID, userData, resultData);
+ }
}
-void NexusBridge::nxmEndorsementToggled(int modID, QVariant userData, QVariant resultData, int requestID) {
- std::set<int>::iterator iter = m_RequestIDs.find(requestID);
- if (iter != m_RequestIDs.end()) {
- m_RequestIDs.erase(iter);
- emit endorsementToggled(modID, userData, resultData);
- }
+void NexusBridge::nxmEndorsementToggled(int modID, QVariant userData, QVariant resultData, int requestID)
+{
+ std::set<int>::iterator iter = m_RequestIDs.find(requestID);
+ if (iter != m_RequestIDs.end()) {
+ m_RequestIDs.erase(iter);
+ emit endorsementToggled(modID, userData, resultData);
+ }
}
-void NexusBridge::nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID,
- const QString& errorMessage) {
- std::set<int>::iterator iter = m_RequestIDs.find(requestID);
- if (iter != m_RequestIDs.end()) {
- m_RequestIDs.erase(iter);
- emit requestFailed(modID, fileID, userData, errorMessage);
- }
+void NexusBridge::nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorMessage)
+{
+ std::set<int>::iterator iter = m_RequestIDs.find(requestID);
+ if (iter != m_RequestIDs.end()) {
+ m_RequestIDs.erase(iter);
+ emit requestFailed(modID, fileID, userData, errorMessage);
+ }
}
+
QAtomicInt NexusInterface::NXMRequestInfo::s_NextID(0);
-NexusInterface::NexusInterface() : m_NMMVersion() {
- VS_FIXEDFILEINFO version = GetFileVersion(ToWString(QApplication::applicationFilePath()));
- m_MOVersion =
- VersionInfo(version.dwFileVersionMS >> 16, version.dwFileVersionMS & 0xFFFF, version.dwFileVersionLS >> 16);
- m_AccessManager = new NXMAccessManager(this, m_MOVersion.displayString());
- m_DiskCache = new QNetworkDiskCache(this);
- connect(m_AccessManager, SIGNAL(requestNXMDownload(QString)), this, SLOT(downloadRequestedNXM(QString)));
+NexusInterface::NexusInterface()
+ : m_NMMVersion()
+{
+ VS_FIXEDFILEINFO version = GetFileVersion(ToWString(QApplication::applicationFilePath()));
+ m_MOVersion = VersionInfo(version.dwFileVersionMS >> 16,
+ version.dwFileVersionMS & 0xFFFF,
+ version.dwFileVersionLS >> 16);
+
+ m_AccessManager = new NXMAccessManager(this, m_MOVersion.displayString());
+ m_DiskCache = new QNetworkDiskCache(this);
+ connect(m_AccessManager, SIGNAL(requestNXMDownload(QString)), this, SLOT(downloadRequestedNXM(QString)));
}
-NXMAccessManager* NexusInterface::getAccessManager() { return m_AccessManager; }
+NXMAccessManager *NexusInterface::getAccessManager()
+{
+ return m_AccessManager;
+}
-NexusInterface::~NexusInterface() { cleanup(); }
+NexusInterface::~NexusInterface()
+{
+ cleanup();
+}
-NexusInterface* NexusInterface::instance() {
- static NexusInterface s_Instance;
- return &s_Instance;
+NexusInterface *NexusInterface::instance()
+{
+ static NexusInterface s_Instance;
+ return &s_Instance;
}
-void NexusInterface::setCacheDirectory(const QString& directory) {
- m_DiskCache->setCacheDirectory(directory);
- m_AccessManager->setCache(m_DiskCache);
+void NexusInterface::setCacheDirectory(const QString &directory)
+{
+ m_DiskCache->setCacheDirectory(directory);
+ m_AccessManager->setCache(m_DiskCache);
}
-void NexusInterface::setNMMVersion(const QString& nmmVersion) {
- m_NMMVersion = nmmVersion;
- m_AccessManager->setNMMVersion(nmmVersion);
+void NexusInterface::setNMMVersion(const QString &nmmVersion)
+{
+ m_NMMVersion = nmmVersion;
+ m_AccessManager->setNMMVersion(nmmVersion);
}
-void NexusInterface::loginCompleted() { nextRequest(); }
+void NexusInterface::loginCompleted()
+{
+ nextRequest();
+}
-void NexusInterface::interpretNexusFileName(const QString& fileName, QString& modName, int& modID, bool query) {
- // Look for something along the lines of modulename-Vn-m + any old rubbish.
- static std::regex exp(R"exp(^([a-zA-Z0-9_'"\-.() ]*?)([-_ ][VvRr]?[0-9_]+)?-([1-9][0-9]*).*\.(zip|rar|7z))exp");
- static std::regex simpleexp("^([a-zA-Z0-9_]+)");
- QByteArray fileNameUTF8 = fileName.toUtf8();
- std::cmatch result;
- if (std::regex_search(fileNameUTF8.constData(), result, exp)) {
- modName = QString::fromUtf8(result[1].str().c_str());
- modName = modName.replace('_', ' ').trimmed();
+void NexusInterface::interpretNexusFileName(const QString &fileName, QString &modName, int &modID, bool query)
+{
+ //Look for something along the lines of modulename-Vn-m + any old rubbish.
+ static std::regex exp(R"exp(^([a-zA-Z0-9_'"\-.() ]*?)([-_ ][VvRr]?[0-9_]+)?-([1-9][0-9]*).*\.(zip|rar|7z))exp");
+ static std::regex simpleexp("^([a-zA-Z0-9_]+)");
- std::string candidate = result[3].str();
- std::string candidate2 = result[2].str();
- if (candidate2.length() != 0 && (candidate2.find_last_of("VvRr") == std::string::npos)) {
- // well, that second match might be an id too...
- size_t offset = strspn(candidate2.c_str(), "-_ ");
- if (offset < candidate2.length() && query) {
- SelectionDialog selection(
- tr("Failed to guess mod id for \"%1\", please pick the correct one").arg(fileName));
- QString r2Highlight(fileName);
- r2Highlight.insert(result.position(2) + result.length(2), "* ")
- .insert(result.position(2) + static_cast<int>(offset), " *");
- QString r3Highlight(fileName);
- r3Highlight.insert(result.position(3) + result.length(3), "* ").insert(result.position(3), " *");
+ QByteArray fileNameUTF8 = fileName.toUtf8();
+ std::cmatch result;
+ if (std::regex_search(fileNameUTF8.constData(), result, exp)) {
+ modName = QString::fromUtf8(result[1].str().c_str());
+ modName = modName.replace('_', ' ').trimmed();
- selection.addChoice(candidate.c_str(), r3Highlight,
- static_cast<int>(strtol(candidate.c_str(), nullptr, 10)));
- selection.addChoice(candidate2.c_str() + offset, r2Highlight,
- static_cast<int>(abs(strtol(candidate2.c_str() + offset, nullptr, 10))));
- if (selection.exec() == QDialog::Accepted) {
- modID = selection.getChoiceData().toInt();
- } else {
- modID = -1;
- }
- } else {
- modID = -1;
- }
+ std::string candidate = result[3].str();
+ std::string candidate2 = result[2].str();
+ if (candidate2.length() != 0 && (candidate2.find_last_of("VvRr") == std::string::npos)) {
+ // well, that second match might be an id too...
+ size_t offset = strspn(candidate2.c_str(), "-_ ");
+ if (offset < candidate2.length() && query) {
+ SelectionDialog selection(tr("Failed to guess mod id for \"%1\", please pick the correct one").arg(fileName));
+ QString r2Highlight(fileName);
+ r2Highlight.insert(result.position(2) + result.length(2), "* ")
+ .insert(result.position(2) + static_cast<int>(offset), " *");
+ QString r3Highlight(fileName);
+ r3Highlight.insert(result.position(3) + result.length(3), "* ").insert(result.position(3), " *");
+
+ selection.addChoice(candidate.c_str(), r3Highlight, static_cast<int>(strtol(candidate.c_str(), nullptr, 10)));
+ selection.addChoice(candidate2.c_str() + offset, r2Highlight, static_cast<int>(abs(strtol(candidate2.c_str() + offset, nullptr, 10))));
+ if (selection.exec() == QDialog::Accepted) {
+ modID = selection.getChoiceData().toInt();
} else {
- modID = strtol(candidate.c_str(), nullptr, 10);
+ modID = -1;
}
- qDebug("mod id guessed: %s -> %d", qPrintable(fileName), modID);
- } else if (std::regex_search(fileNameUTF8.constData(), result, simpleexp)) {
- qDebug("simple expression matched, using name only");
- modName = QString::fromUtf8(result[1].str().c_str());
- modName = modName.replace('_', ' ').trimmed();
-
+ } else {
modID = -1;
+ }
} else {
- qDebug("no expression matched!");
- modName.clear();
- modID = -1;
+ modID = strtol(candidate.c_str(), nullptr, 10);
}
+ qDebug("mod id guessed: %s -> %d", qPrintable(fileName), modID);
+ } else if (std::regex_search(fileNameUTF8.constData(), result, simpleexp)) {
+ qDebug("simple expression matched, using name only");
+ modName = QString::fromUtf8(result[1].str().c_str());
+ modName = modName.replace('_', ' ').trimmed();
+
+ modID = -1;
+ } else {
+ qDebug("no expression matched!");
+ modName.clear();
+ modID = -1;
+ }
}
-bool NexusInterface::isURLGameRelated(const QUrl& url) const {
- QString const name(url.toString());
- return name.startsWith(getGameURL() + "/") || name.startsWith(getOldModsURL() + "/");
+bool NexusInterface::isURLGameRelated(const QUrl &url) const
+{
+ QString const name(url.toString());
+ return name.startsWith(getGameURL() + "/") ||
+ name.startsWith(getOldModsURL() + "/");
}
-QString NexusInterface::getGameURL() const { return "http://www.nexusmods.com/" + m_Game->gameNexusName().toLower(); }
+QString NexusInterface::getGameURL() const
+{
+ return "http://www.nexusmods.com/" + m_Game->gameNexusName().toLower();
+}
-QString NexusInterface::getOldModsURL() const {
- return "http://" + m_Game->gameNexusName().toLower() + ".nexusmods.com/mods";
+QString NexusInterface::getOldModsURL() const
+{
+ return "http://" + m_Game->gameNexusName().toLower() + ".nexusmods.com/mods";
}
-QString NexusInterface::getModURL(int modID) const { return QString("%1/mods/%2").arg(getGameURL()).arg(modID); }
-bool NexusInterface::isModURL(int modID, const QString& url) const {
- if (QUrl(url) == QUrl(getModURL(modID))) {
- return true;
- }
- // Try the alternate (old style) mod name
- QString alt = QString("%1/%2").arg(getOldModsURL()).arg(modID);
- return QUrl(alt) == QUrl(url);
+QString NexusInterface::getModURL(int modID) const
+{
+ return QString("%1/mods/%2").arg(getGameURL()).arg(modID);
}
-int NexusInterface::requestDescription(int modID, QObject* receiver, QVariant userData, const QString& subModule,
- MOBase::IPluginGame const* game) {
- NXMRequestInfo requestInfo(modID, NXMRequestInfo::TYPE_DESCRIPTION, userData, subModule, game);
- m_RequestQueue.enqueue(requestInfo);
+bool NexusInterface::isModURL(int modID, const QString &url) const
+{
+ if (QUrl(url) == QUrl(getModURL(modID))) {
+ return true;
+ }
+ //Try the alternate (old style) mod name
+ QString alt = QString("%1/%2").arg(getOldModsURL()).arg(modID);
+ return QUrl(alt) == QUrl(url);
+}
+
+int NexusInterface::requestDescription(int modID, QObject *receiver, QVariant userData,
+ const QString &subModule, MOBase::IPluginGame const *game)
+{
+ NXMRequestInfo requestInfo(modID, NXMRequestInfo::TYPE_DESCRIPTION, userData, subModule, game);
+ m_RequestQueue.enqueue(requestInfo);
- connect(this, SIGNAL(nxmDescriptionAvailable(int, QVariant, QVariant, int)), receiver,
- SLOT(nxmDescriptionAvailable(int, QVariant, QVariant, int)), Qt::UniqueConnection);
+ connect(this, SIGNAL(nxmDescriptionAvailable(int,QVariant,QVariant,int)),
+ receiver, SLOT(nxmDescriptionAvailable(int,QVariant,QVariant,int)), Qt::UniqueConnection);
- connect(this, SIGNAL(nxmRequestFailed(int, int, QVariant, int, QString)), receiver,
- SLOT(nxmRequestFailed(int, int, QVariant, int, QString)), Qt::UniqueConnection);
+ connect(this, SIGNAL(nxmRequestFailed(int,int,QVariant,int,QString)),
+ receiver, SLOT(nxmRequestFailed(int,int,QVariant,int,QString)), Qt::UniqueConnection);
- nextRequest();
- return requestInfo.m_ID;
+ nextRequest();
+ return requestInfo.m_ID;
}
-int NexusInterface::requestUpdates(const std::vector<int>& modIDs, QObject* receiver, QVariant userData,
- const QString& subModule, MOBase::IPluginGame const* game) {
- NXMRequestInfo requestInfo(modIDs, NXMRequestInfo::TYPE_GETUPDATES, userData, subModule, game);
- m_RequestQueue.enqueue(requestInfo);
- connect(this, SIGNAL(nxmUpdatesAvailable(std::vector<int>, QVariant, QVariant, int)), receiver,
- SLOT(nxmUpdatesAvailable(std::vector<int>, QVariant, QVariant, int)), Qt::UniqueConnection);
+int NexusInterface::requestUpdates(const std::vector<int> &modIDs, QObject *receiver, QVariant userData,
+ const QString &subModule, MOBase::IPluginGame const *game)
+{
+ NXMRequestInfo requestInfo(modIDs, NXMRequestInfo::TYPE_GETUPDATES, userData, subModule, game);
+ m_RequestQueue.enqueue(requestInfo);
- connect(this, SIGNAL(nxmRequestFailed(int, int, QVariant, int, QString)), receiver,
- SLOT(nxmRequestFailed(int, int, QVariant, int, QString)), Qt::UniqueConnection);
+ connect(this, SIGNAL(nxmUpdatesAvailable(std::vector<int>,QVariant,QVariant,int)),
+ receiver, SLOT(nxmUpdatesAvailable(std::vector<int>,QVariant,QVariant,int)), Qt::UniqueConnection);
- nextRequest();
- return requestInfo.m_ID;
+ connect(this, SIGNAL(nxmRequestFailed(int,int,QVariant,int,QString)),
+ receiver, SLOT(nxmRequestFailed(int,int,QVariant,int,QString)), Qt::UniqueConnection);
+
+ nextRequest();
+ return requestInfo.m_ID;
}
-void NexusInterface::fakeFiles() {
- static int id = 42;
- QVariantList result;
- QVariantMap fileMap;
- fileMap["uri"] = "fakeURI";
- fileMap["name"] = "fakeName";
- fileMap["description"] = "fakeDescription";
- fileMap["version"] = "1.0.0";
- fileMap["category_id"] = "1";
- fileMap["id"] = "1";
- fileMap["size"] = "512";
- result.append(fileMap);
+void NexusInterface::fakeFiles()
+{
+ static int id = 42;
+
+ QVariantList result;
+ QVariantMap fileMap;
+ fileMap["uri"] = "fakeURI";
+ fileMap["name"] = "fakeName";
+ fileMap["description"] = "fakeDescription";
+ fileMap["version"] = "1.0.0";
+ fileMap["category_id"] = "1";
+ fileMap["id"] = "1";
+ fileMap["size"] = "512";
+ result.append(fileMap);
- emit nxmFilesAvailable(1234, "fake", result, id++);
+ emit nxmFilesAvailable(1234, "fake", result, id++);
}
-int NexusInterface::requestFiles(int modID, QObject* receiver, QVariant userData, const QString& subModule,
- MOBase::IPluginGame const* game) {
- NXMRequestInfo requestInfo(modID, NXMRequestInfo::TYPE_FILES, userData, subModule, game);
- m_RequestQueue.enqueue(requestInfo);
- connect(this, SIGNAL(nxmFilesAvailable(int, QVariant, QVariant, int)), receiver,
- SLOT(nxmFilesAvailable(int, QVariant, QVariant, int)), Qt::UniqueConnection);
- connect(this, SIGNAL(nxmRequestFailed(int, int, QVariant, int, QString)), receiver,
- SLOT(nxmRequestFailed(int, int, QVariant, int, QString)), Qt::UniqueConnection);
+int NexusInterface::requestFiles(int modID, QObject *receiver, QVariant userData,
+ const QString &subModule, MOBase::IPluginGame const *game)
+{
+ NXMRequestInfo requestInfo(modID, NXMRequestInfo::TYPE_FILES, userData, subModule, game);
+ m_RequestQueue.enqueue(requestInfo);
+ connect(this, SIGNAL(nxmFilesAvailable(int,QVariant,QVariant,int)),
+ receiver, SLOT(nxmFilesAvailable(int,QVariant,QVariant,int)), Qt::UniqueConnection);
- nextRequest();
- return requestInfo.m_ID;
+ connect(this, SIGNAL(nxmRequestFailed(int,int,QVariant,int,QString)),
+ receiver, SLOT(nxmRequestFailed(int,int,QVariant,int,QString)), Qt::UniqueConnection);
+
+ nextRequest();
+ return requestInfo.m_ID;
}
-int NexusInterface::requestFileInfo(int modID, int fileID, QObject* receiver, QVariant userData,
- const QString& subModule, MOBase::IPluginGame const* game) {
- NXMRequestInfo requestInfo(modID, fileID, NXMRequestInfo::TYPE_FILEINFO, userData, subModule, game);
- m_RequestQueue.enqueue(requestInfo);
- connect(this, SIGNAL(nxmFileInfoAvailable(int, int, QVariant, QVariant, int)), receiver,
- SLOT(nxmFileInfoAvailable(int, int, QVariant, QVariant, int)), Qt::UniqueConnection);
+int NexusInterface::requestFileInfo(int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule,
+ MOBase::IPluginGame const *game)
+{
+ NXMRequestInfo requestInfo(modID, fileID, NXMRequestInfo::TYPE_FILEINFO, userData, subModule, game);
+ m_RequestQueue.enqueue(requestInfo);
+
+ connect(this, SIGNAL(nxmFileInfoAvailable(int,int,QVariant,QVariant,int)),
+ receiver, SLOT(nxmFileInfoAvailable(int,int,QVariant,QVariant,int)), Qt::UniqueConnection);
- connect(this, SIGNAL(nxmRequestFailed(int, int, QVariant, int, QString)), receiver,
- SLOT(nxmRequestFailed(int, int, QVariant, int, QString)), Qt::UniqueConnection);
+ connect(this, SIGNAL(nxmRequestFailed(int,int,QVariant,int,QString)),
+ receiver, SLOT(nxmRequestFailed(int,int,QVariant,int,QString)), Qt::UniqueConnection);
- nextRequest();
- return requestInfo.m_ID;
+ nextRequest();
+ return requestInfo.m_ID;
}
-int NexusInterface::requestDownloadURL(int modID, int fileID, QObject* receiver, QVariant userData,
- const QString& subModule, MOBase::IPluginGame const* game) {
- NXMRequestInfo requestInfo(modID, fileID, NXMRequestInfo::TYPE_DOWNLOADURL, userData, subModule, game);
- m_RequestQueue.enqueue(requestInfo);
- connect(this, SIGNAL(nxmDownloadURLsAvailable(int, int, QVariant, QVariant, int)), receiver,
- SLOT(nxmDownloadURLsAvailable(int, int, QVariant, QVariant, int)), Qt::UniqueConnection);
+int NexusInterface::requestDownloadURL(int modID, int fileID, QObject *receiver, QVariant userData,
+ const QString &subModule, MOBase::IPluginGame const *game)
+{
+ NXMRequestInfo requestInfo(modID, fileID, NXMRequestInfo::TYPE_DOWNLOADURL, userData, subModule, game);
+ m_RequestQueue.enqueue(requestInfo);
+
+ connect(this, SIGNAL(nxmDownloadURLsAvailable(int,int,QVariant,QVariant,int)),
+ receiver, SLOT(nxmDownloadURLsAvailable(int,int,QVariant,QVariant,int)), Qt::UniqueConnection);
- connect(this, SIGNAL(nxmRequestFailed(int, int, QVariant, int, QString)), receiver,
- SLOT(nxmRequestFailed(int, int, QVariant, int, QString)), Qt::UniqueConnection);
+ connect(this, SIGNAL(nxmRequestFailed(int,int,QVariant,int,QString)),
+ receiver, SLOT(nxmRequestFailed(int,int,QVariant,int,QString)), Qt::UniqueConnection);
- nextRequest();
- return requestInfo.m_ID;
+ nextRequest();
+ return requestInfo.m_ID;
}
-int NexusInterface::requestToggleEndorsement(int modID, bool endorse, QObject* receiver, QVariant userData,
- const QString& subModule, MOBase::IPluginGame const* game) {
- NXMRequestInfo requestInfo(modID, NXMRequestInfo::TYPE_TOGGLEENDORSEMENT, userData, subModule, game);
- requestInfo.m_Endorse = endorse;
- m_RequestQueue.enqueue(requestInfo);
- connect(this, SIGNAL(nxmEndorsementToggled(int, QVariant, QVariant, int)), receiver,
- SLOT(nxmEndorsementToggled(int, QVariant, QVariant, int)), Qt::UniqueConnection);
+int NexusInterface::requestToggleEndorsement(int modID, bool endorse, QObject *receiver, QVariant userData,
+ const QString &subModule, MOBase::IPluginGame const *game)
+{
+ NXMRequestInfo requestInfo(modID, NXMRequestInfo::TYPE_TOGGLEENDORSEMENT, userData, subModule, game);
+ requestInfo.m_Endorse = endorse;
+ m_RequestQueue.enqueue(requestInfo);
- connect(this, SIGNAL(nxmRequestFailed(int, int, QVariant, int, QString)), receiver,
- SLOT(nxmRequestFailed(int, int, QVariant, int, QString)), Qt::UniqueConnection);
+ connect(this, SIGNAL(nxmEndorsementToggled(int,QVariant,QVariant,int)),
+ receiver, SLOT(nxmEndorsementToggled(int,QVariant,QVariant,int)), Qt::UniqueConnection);
- nextRequest();
- return requestInfo.m_ID;
+ connect(this, SIGNAL(nxmRequestFailed(int,int,QVariant,int,QString)),
+ receiver, SLOT(nxmRequestFailed(int,int,QVariant,int,QString)), Qt::UniqueConnection);
+
+ nextRequest();
+ return requestInfo.m_ID;
}
-bool NexusInterface::requiresLogin(const NXMRequestInfo& info) {
- return (info.m_Type == NXMRequestInfo::TYPE_TOGGLEENDORSEMENT) || (info.m_Type == NXMRequestInfo::TYPE_DOWNLOADURL);
+bool NexusInterface::requiresLogin(const NXMRequestInfo &info)
+{
+ return (info.m_Type == NXMRequestInfo::TYPE_TOGGLEENDORSEMENT)
+ || (info.m_Type == NXMRequestInfo::TYPE_DOWNLOADURL);
}
-void NexusInterface::cleanup() {
- // delete m_AccessManager;
- // delete m_DiskCache;
- m_AccessManager = nullptr;
- m_DiskCache = nullptr;
+void NexusInterface::cleanup()
+{
+// delete m_AccessManager;
+// delete m_DiskCache;
+ m_AccessManager = nullptr;
+ m_DiskCache = nullptr;
}
-void NexusInterface::clearCache() {
- m_DiskCache->clear();
- m_AccessManager->clearCookies();
+void NexusInterface::clearCache()
+{
+ m_DiskCache->clear();
+ m_AccessManager->clearCookies();
}
-void NexusInterface::nextRequest() {
- if ((m_ActiveRequest.size() >= MAX_ACTIVE_DOWNLOADS) || m_RequestQueue.isEmpty()) {
- return;
- }
+void NexusInterface::nextRequest()
+{
+ if ((m_ActiveRequest.size() >= MAX_ACTIVE_DOWNLOADS)
+ || m_RequestQueue.isEmpty()) {
+ return;
+ }
- if (requiresLogin(m_RequestQueue.head()) && !getAccessManager()->loggedIn()) {
- if (!getAccessManager()->loginAttempted()) {
- emit needLogin();
- return;
- } else if (getAccessManager()->loginWaiting()) {
- return;
- }
+ if (requiresLogin(m_RequestQueue.head()) && !getAccessManager()->loggedIn()) {
+ if (!getAccessManager()->loginAttempted()) {
+ emit needLogin();
+ return;
+ } else if (getAccessManager()->loginWaiting()) {
+ return;
}
+ }
- NXMRequestInfo info = m_RequestQueue.dequeue();
- info.m_Timeout = new QTimer(this);
- info.m_Timeout->setInterval(60000);
+ NXMRequestInfo info = m_RequestQueue.dequeue();
+ info.m_Timeout = new QTimer(this);
+ info.m_Timeout->setInterval(60000);
- QString url;
- if (!info.m_Reroute) {
- bool hasParams = false;
- switch (info.m_Type) {
- case NXMRequestInfo::TYPE_DESCRIPTION: {
- url = QString("%1/Mods/%2/").arg(info.m_URL).arg(info.m_ModID);
- } break;
- case NXMRequestInfo::TYPE_FILES: {
- url = QString("%1/Files/indexfrommod/%2/").arg(info.m_URL).arg(info.m_ModID);
- } break;
- case NXMRequestInfo::TYPE_FILEINFO: {
- url = QString("%1/Files/%2/").arg(info.m_URL).arg(info.m_FileID);
- } break;
- case NXMRequestInfo::TYPE_DOWNLOADURL: {
- url = QString("%1/Files/download/%2").arg(info.m_URL).arg(info.m_FileID);
- } break;
- case NXMRequestInfo::TYPE_TOGGLEENDORSEMENT: {
- url =
- QString("%1/Mods/toggleendorsement/%2?lvote=%3").arg(info.m_URL).arg(info.m_ModID).arg(!info.m_Endorse);
- hasParams = true;
- } break;
- case NXMRequestInfo::TYPE_GETUPDATES: {
- QString modIDList = VectorJoin<int>(info.m_ModIDList, ",");
- modIDList = "[" + modIDList + "]";
- url = QString("%1/Mods/GetUpdates?ModList=%2").arg(info.m_URL).arg(modIDList);
- hasParams = true;
- } break;
- }
- url.append(QString("%1game_id=%2").arg(hasParams ? '&' : '?').arg(info.m_NexusGameID));
- } else {
- url = info.m_URL;
+ QString url;
+ if (!info.m_Reroute) {
+ bool hasParams = false;
+ switch (info.m_Type) {
+ case NXMRequestInfo::TYPE_DESCRIPTION: {
+ url = QString("%1/Mods/%2/").arg(info.m_URL).arg(info.m_ModID);
+ } break;
+ case NXMRequestInfo::TYPE_FILES: {
+ url = QString("%1/Files/indexfrommod/%2/").arg(info.m_URL).arg(info.m_ModID);
+ } break;
+ case NXMRequestInfo::TYPE_FILEINFO: {
+ url = QString("%1/Files/%2/").arg(info.m_URL).arg(info.m_FileID);
+ } break;
+ case NXMRequestInfo::TYPE_DOWNLOADURL: {
+ url = QString("%1/Files/download/%2").arg(info.m_URL).arg(info.m_FileID);
+ } break;
+ case NXMRequestInfo::TYPE_TOGGLEENDORSEMENT: {
+ url = QString("%1/Mods/toggleendorsement/%2?lvote=%3").arg(info.m_URL).arg(info.m_ModID).arg(!info.m_Endorse);
+ hasParams = true;
+ } break;
+ case NXMRequestInfo::TYPE_GETUPDATES: {
+ QString modIDList = VectorJoin<int>(info.m_ModIDList, ",");
+ modIDList = "[" + modIDList + "]";
+ url = QString("%1/Mods/GetUpdates?ModList=%2").arg(info.m_URL).arg(modIDList);
+ hasParams = true;
+ } break;
}
- QNetworkRequest request(url);
- request.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml");
- request.setRawHeader("User-Agent", m_AccessManager->userAgent(info.m_SubModule).toUtf8());
+ url.append(QString("%1game_id=%2").arg(hasParams ? '&' : '?').arg(info.m_NexusGameID));
+ } else {
+ url = info.m_URL;
+ }
+ QNetworkRequest request(url);
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml");
+ request.setRawHeader("User-Agent", m_AccessManager->userAgent(info.m_SubModule).toUtf8());
- info.m_Reply = m_AccessManager->get(request);
+ info.m_Reply = m_AccessManager->get(request);
- connect(info.m_Reply, SIGNAL(finished()), this, SLOT(requestFinished()));
- connect(info.m_Reply, SIGNAL(error(QNetworkReply::NetworkError)), this,
- SLOT(requestError(QNetworkReply::NetworkError)));
- connect(info.m_Timeout, SIGNAL(timeout()), this, SLOT(requestTimeout()));
- info.m_Timeout->start();
- m_ActiveRequest.push_back(info);
+ connect(info.m_Reply, SIGNAL(finished()), this, SLOT(requestFinished()));
+ connect(info.m_Reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestError(QNetworkReply::NetworkError)));
+ connect(info.m_Timeout, SIGNAL(timeout()), this, SLOT(requestTimeout()));
+ info.m_Timeout->start();
+ m_ActiveRequest.push_back(info);
}
-void NexusInterface::downloadRequestedNXM(const QString& url) { emit requestNXMDownload(url); }
-void NexusInterface::requestFinished(std::list<NXMRequestInfo>::iterator iter) {
- QNetworkReply* reply = iter->m_Reply;
+void NexusInterface::downloadRequestedNXM(const QString &url)
+{
+ emit requestNXMDownload(url);
+}
- if (reply->error() != QNetworkReply::NoError) {
- qWarning("request failed: %s", reply->errorString().toUtf8().constData());
- emit nxmRequestFailed(iter->m_ModID, iter->m_FileID, iter->m_UserData, iter->m_ID, reply->errorString());
+void NexusInterface::requestFinished(std::list<NXMRequestInfo>::iterator iter)
+{
+ QNetworkReply *reply = iter->m_Reply;
+
+ if (reply->error() != QNetworkReply::NoError) {
+ qWarning("request failed: %s", reply->errorString().toUtf8().constData());
+ emit nxmRequestFailed(iter->m_ModID, iter->m_FileID, iter->m_UserData, iter->m_ID, reply->errorString());
+ } else {
+ int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+ if (statusCode == 301) {
+ // redirect request, return request to queue
+ iter->m_URL = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toString();
+ iter->m_Reroute = true;
+ m_RequestQueue.enqueue(*iter);
+ nextRequest();
+ return;
+ }
+ QByteArray data = reply->readAll();
+ if (data.isNull() || data.isEmpty() || (strcmp(data.constData(), "null") == 0)) {
+ QString nexusError(reply->rawHeader("NexusErrorInfo"));
+ if (nexusError.length() == 0) {
+ nexusError = tr("empty response");
+ }
+ qDebug("nexus error: %s", qPrintable(nexusError));
+ emit nxmRequestFailed(iter->m_ModID, iter->m_FileID, iter->m_UserData, iter->m_ID, nexusError);
} else {
- int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
- if (statusCode == 301) {
- // redirect request, return request to queue
- iter->m_URL = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toString();
- iter->m_Reroute = true;
- m_RequestQueue.enqueue(*iter);
- nextRequest();
- return;
- }
- QByteArray data = reply->readAll();
- if (data.isNull() || data.isEmpty() || (strcmp(data.constData(), "null") == 0)) {
- QString nexusError(reply->rawHeader("NexusErrorInfo"));
- if (nexusError.length() == 0) {
- nexusError = tr("empty response");
- }
- qDebug("nexus error: %s", qPrintable(nexusError));
- emit nxmRequestFailed(iter->m_ModID, iter->m_FileID, iter->m_UserData, iter->m_ID, nexusError);
- } else {
- bool ok;
- QVariant result = QtJson::parse(data, ok);
- if (result.isValid() && ok) {
- switch (iter->m_Type) {
- case NXMRequestInfo::TYPE_DESCRIPTION: {
- emit nxmDescriptionAvailable(iter->m_ModID, iter->m_UserData, result, iter->m_ID);
- } break;
- case NXMRequestInfo::TYPE_FILES: {
- emit nxmFilesAvailable(iter->m_ModID, iter->m_UserData, result, iter->m_ID);
- } break;
- case NXMRequestInfo::TYPE_FILEINFO: {
- emit nxmFileInfoAvailable(iter->m_ModID, iter->m_FileID, iter->m_UserData, result, iter->m_ID);
- } break;
- case NXMRequestInfo::TYPE_DOWNLOADURL: {
- emit nxmDownloadURLsAvailable(iter->m_ModID, iter->m_FileID, iter->m_UserData, result, iter->m_ID);
- } break;
- case NXMRequestInfo::TYPE_GETUPDATES: {
- emit nxmUpdatesAvailable(iter->m_ModIDList, iter->m_UserData, result, iter->m_ID);
- } break;
- case NXMRequestInfo::TYPE_TOGGLEENDORSEMENT: {
- emit nxmEndorsementToggled(iter->m_ModID, iter->m_UserData, result, iter->m_ID);
- } break;
- }
- } else {
- emit nxmRequestFailed(iter->m_ModID, iter->m_FileID, iter->m_UserData, iter->m_ID,
- tr("invalid response"));
- }
+ bool ok;
+ QVariant result = QtJson::parse(data, ok);
+ if (result.isValid() && ok) {
+ switch (iter->m_Type) {
+ case NXMRequestInfo::TYPE_DESCRIPTION: {
+ emit nxmDescriptionAvailable(iter->m_ModID, iter->m_UserData, result, iter->m_ID);
+ } break;
+ case NXMRequestInfo::TYPE_FILES: {
+ emit nxmFilesAvailable(iter->m_ModID, iter->m_UserData, result, iter->m_ID);
+ } break;
+ case NXMRequestInfo::TYPE_FILEINFO: {
+ emit nxmFileInfoAvailable(iter->m_ModID, iter->m_FileID, iter->m_UserData, result, iter->m_ID);
+ } break;
+ case NXMRequestInfo::TYPE_DOWNLOADURL: {
+ emit nxmDownloadURLsAvailable(iter->m_ModID, iter->m_FileID, iter->m_UserData, result, iter->m_ID);
+ } break;
+ case NXMRequestInfo::TYPE_GETUPDATES: {
+ emit nxmUpdatesAvailable(iter->m_ModIDList, iter->m_UserData, result, iter->m_ID);
+ } break;
+ case NXMRequestInfo::TYPE_TOGGLEENDORSEMENT: {
+ emit nxmEndorsementToggled(iter->m_ModID, iter->m_UserData, result, iter->m_ID);
+ } break;
}
+ } else {
+ emit nxmRequestFailed(iter->m_ModID, iter->m_FileID, iter->m_UserData, iter->m_ID, tr("invalid response"));
+ }
}
+ }
}
-void NexusInterface::requestFinished() {
- QNetworkReply* reply = static_cast<QNetworkReply*>(sender());
- for (std::list<NXMRequestInfo>::iterator iter = m_ActiveRequest.begin(); iter != m_ActiveRequest.end(); ++iter) {
- if (iter->m_Reply == reply) {
- iter->m_Timeout->stop();
- iter->m_Timeout->deleteLater();
- requestFinished(iter);
- iter->m_Reply->deleteLater();
- m_ActiveRequest.erase(iter);
- nextRequest();
- return;
- }
+
+void NexusInterface::requestFinished()
+{
+ QNetworkReply *reply = static_cast<QNetworkReply*>(sender());
+ for (std::list<NXMRequestInfo>::iterator iter = m_ActiveRequest.begin(); iter != m_ActiveRequest.end(); ++iter) {
+ if (iter->m_Reply == reply) {
+ iter->m_Timeout->stop();
+ iter->m_Timeout->deleteLater();
+ requestFinished(iter);
+ iter->m_Reply->deleteLater();
+ m_ActiveRequest.erase(iter);
+ nextRequest();
+ return;
}
+ }
}
-void NexusInterface::requestError(QNetworkReply::NetworkError) {
- QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
- if (reply == nullptr) {
- qWarning("invalid sender type");
- return;
- }
- qCritical("request (%s) error: %s (%d)", qPrintable(reply->url().toString()), qPrintable(reply->errorString()),
- reply->error());
+void NexusInterface::requestError(QNetworkReply::NetworkError)
+{
+ QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
+ if (reply == nullptr) {
+ qWarning("invalid sender type");
+ return;
+ }
+
+ qCritical("request (%s) error: %s (%d)",
+ qPrintable(reply->url().toString()),
+ qPrintable(reply->errorString()),
+ reply->error());
}
-void NexusInterface::requestTimeout() {
- QTimer* timer = qobject_cast<QTimer*>(sender());
- if (timer == nullptr) {
- qWarning("invalid sender type");
- return;
- }
- for (std::list<NXMRequestInfo>::iterator iter = m_ActiveRequest.begin(); iter != m_ActiveRequest.end(); ++iter) {
- if (iter->m_Timeout == timer) {
- // this abort causes a "request failed" which cleans up the rest
- iter->m_Reply->abort();
- return;
- }
+
+void NexusInterface::requestTimeout()
+{
+ QTimer *timer = qobject_cast<QTimer*>(sender());
+ if (timer == nullptr) {
+ qWarning("invalid sender type");
+ return;
+ }
+ for (std::list<NXMRequestInfo>::iterator iter = m_ActiveRequest.begin(); iter != m_ActiveRequest.end(); ++iter) {
+ if (iter->m_Timeout == timer) {
+ // this abort causes a "request failed" which cleans up the rest
+ iter->m_Reply->abort();
+ return;
}
+ }
}
-void NexusInterface::managedGameChanged(IPluginGame const* game) { m_Game = game; }
+void NexusInterface::managedGameChanged(IPluginGame const *game)
+{
+ m_Game = game;
+}
namespace {
-QString get_management_url(MOBase::IPluginGame const* game) {
+ QString get_management_url(MOBase::IPluginGame const *game)
+ {
return "http://nmm.nexusmods.com/" + game->gameNexusName().toLower();
+ }
}
-} // namespace
-NexusInterface::NXMRequestInfo::NXMRequestInfo(int modID, NexusInterface::NXMRequestInfo::Type type, QVariant userData,
- const QString& subModule, MOBase::IPluginGame const* game)
- : m_ModID(modID), m_FileID(0), m_Reply(nullptr), m_Type(type), m_UserData(userData), m_Timeout(nullptr),
- m_Reroute(false), m_ID(s_NextID.fetchAndAddAcquire(1)), m_URL(get_management_url(game)), m_SubModule(subModule),
- m_NexusGameID(game->nexusGameID()), m_Endorse(false) {}
+NexusInterface::NXMRequestInfo::NXMRequestInfo(int modID
+ , NexusInterface::NXMRequestInfo::Type type
+ , QVariant userData
+ , const QString &subModule
+ , MOBase::IPluginGame const *game
+ )
+ : m_ModID(modID)
+ , m_FileID(0)
+ , m_Reply(nullptr)
+ , m_Type(type)
+ , m_UserData(userData)
+ , m_Timeout(nullptr)
+ , m_Reroute(false)
+ , m_ID(s_NextID.fetchAndAddAcquire(1))
+ , m_URL(get_management_url(game))
+ , m_SubModule(subModule)
+ , m_NexusGameID(game->nexusGameID())
+ , m_Endorse(false)
+{}
-NexusInterface::NXMRequestInfo::NXMRequestInfo(std::vector<int> modIDList, NexusInterface::NXMRequestInfo::Type type,
- QVariant userData, const QString& subModule,
- MOBase::IPluginGame const* game)
- : m_ModID(-1), m_ModIDList(modIDList), m_FileID(0), m_Reply(nullptr), m_Type(type), m_UserData(userData),
- m_Timeout(nullptr), m_Reroute(false), m_ID(s_NextID.fetchAndAddAcquire(1)), m_URL(get_management_url(game)),
- m_SubModule(subModule), m_NexusGameID(game->nexusGameID()), m_Endorse(false) {}
+NexusInterface::NXMRequestInfo::NXMRequestInfo(std::vector<int> modIDList
+ , NexusInterface::NXMRequestInfo::Type type
+ , QVariant userData
+ , const QString &subModule
+ , MOBase::IPluginGame const *game
+ )
+ : m_ModID(-1)
+ , m_ModIDList(modIDList)
+ , m_FileID(0)
+ , m_Reply(nullptr)
+ , m_Type(type)
+ , m_UserData(userData)
+ , m_Timeout(nullptr)
+ , m_Reroute(false)
+ , m_ID(s_NextID.fetchAndAddAcquire(1))
+ , m_URL(get_management_url(game))
+ , m_SubModule(subModule)
+ , m_NexusGameID(game->nexusGameID())
+ , m_Endorse(false)
+{}
-NexusInterface::NXMRequestInfo::NXMRequestInfo(int modID, int fileID, NexusInterface::NXMRequestInfo::Type type,
- QVariant userData, const QString& subModule,
- MOBase::IPluginGame const* game)
- : m_ModID(modID), m_FileID(fileID), m_Reply(nullptr), m_Type(type), m_UserData(userData), m_Timeout(nullptr),
- m_Reroute(false), m_ID(s_NextID.fetchAndAddAcquire(1)), m_URL(get_management_url(game)), m_SubModule(subModule),
- m_NexusGameID(game->nexusGameID()), m_Endorse(false) {}
+NexusInterface::NXMRequestInfo::NXMRequestInfo(int modID
+ , int fileID
+ , NexusInterface::NXMRequestInfo::Type type
+ , QVariant userData
+ , const QString &subModule
+ , MOBase::IPluginGame const *game
+ )
+ : m_ModID(modID)
+ , m_FileID(fileID)
+ , m_Reply(nullptr)
+ , m_Type(type)
+ , m_UserData(userData)
+ , m_Timeout(nullptr)
+ , m_Reroute(false)
+ , m_ID(s_NextID.fetchAndAddAcquire(1))
+ , m_URL(get_management_url(game))
+ , m_SubModule(subModule)
+ , m_NexusGameID(game->nexusGameID())
+ , m_Endorse(false)
+{}
diff --git a/src/nexusinterface.h b/src/nexusinterface.h
index ad0d40bf..9e7f3642 100644
--- a/src/nexusinterface.h
+++ b/src/nexusinterface.h
@@ -20,22 +20,20 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef NEXUSINTERFACE_H
#define NEXUSINTERFACE_H
-#include <imodrepositorybridge.h>
#include <utility.h>
#include <versioninfo.h>
+#include <imodrepositorybridge.h>
-#include <QNetworkDiskCache>
#include <QNetworkReply>
+#include <QNetworkDiskCache>
#include <QQueue>
-#include <QTimer>
#include <QVariant>
+#include <QTimer>
#include <list>
#include <set>
-namespace MOBase {
-class IPluginGame;
-}
+namespace MOBase { class IPluginGame; }
class NexusInterface;
class NXMAccessManager;
@@ -48,70 +46,75 @@ class NXMAccessManager;
* NexusBridge does this automatically. Users connect to the signals of NexusBridge they intend
* to handle and only receive the signals the caused
**/
-class NexusBridge : public MOBase::IModRepositoryBridge {
+class NexusBridge : public MOBase::IModRepositoryBridge
+{
- Q_OBJECT
+ Q_OBJECT
public:
- NexusBridge(const QString& subModule = "");
- /**
- * @brief request description for a mod
- *
- * @param modID id of the mod caller is interested in
- * @param userData user data to be returned with the result
- * @param url the url to request from
- **/
- virtual void requestDescription(int modID, QVariant userData);
+ NexusBridge(const QString &subModule = "");
+
+ /**
+ * @brief request description for a mod
+ *
+ * @param modID id of the mod caller is interested in
+ * @param userData user data to be returned with the result
+ * @param url the url to request from
+ **/
+ virtual void requestDescription(int modID, QVariant userData);
- /**
- * @brief request a list of the files belonging to a mod
- *
- * @param modID id of the mod caller is interested in
- * @param userData user data to be returned with the result
- **/
- virtual void requestFiles(int modID, QVariant userData);
+ /**
+ * @brief request a list of the files belonging to a mod
+ *
+ * @param modID id of the mod caller is interested in
+ * @param userData user data to be returned with the result
+ **/
+ virtual void requestFiles(int modID, QVariant userData);
- /**
- * @brief request info about a single file of a mod
- *
- * @param modID id of the mod caller is interested in
- * @param fileID id of the file the caller is interested in
- * @param userData user data to be returned with the result
- **/
- virtual void requestFileInfo(int modID, int fileID, QVariant userData);
+ /**
+ * @brief request info about a single file of a mod
+ *
+ * @param modID id of the mod caller is interested in
+ * @param fileID id of the file the caller is interested in
+ * @param userData user data to be returned with the result
+ **/
+ virtual void requestFileInfo(int modID, int fileID, QVariant userData);
- /**
- * @brief request the download url of a file
- *
- * @param modID id of the mod caller is interested in
- * @param fileID id of the file the caller is interested in
- * @param userData user data to be returned with the result
- **/
- virtual void requestDownloadURL(int modID, int fileID, QVariant userData);
+ /**
+ * @brief request the download url of a file
+ *
+ * @param modID id of the mod caller is interested in
+ * @param fileID id of the file the caller is interested in
+ * @param userData user data to be returned with the result
+ **/
+ virtual void requestDownloadURL(int modID, int fileID, QVariant userData);
- /**
- * @brief requestToggleEndorsement
- * @param modID id of the mod caller is interested in
- * @param userData user data to be returned with the result
- */
- virtual void requestToggleEndorsement(int modID, bool endorse, QVariant userData);
+ /**
+ * @brief requestToggleEndorsement
+ * @param modID id of the mod caller is interested in
+ * @param userData user data to be returned with the result
+ */
+ virtual void requestToggleEndorsement(int modID, bool endorse, QVariant userData);
public slots:
- void nxmDescriptionAvailable(int modID, QVariant userData, QVariant resultData, int requestID);
- void nxmFilesAvailable(int modID, QVariant userData, QVariant resultData, int requestID);
- void nxmFileInfoAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
- void nxmDownloadURLsAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
- void nxmEndorsementToggled(int modID, QVariant userData, QVariant resultData, int requestID);
- void nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString& errorMessage);
+ void nxmDescriptionAvailable(int modID, QVariant userData, QVariant resultData, int requestID);
+ void nxmFilesAvailable(int modID, QVariant userData, QVariant resultData, int requestID);
+ void nxmFileInfoAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
+ void nxmDownloadURLsAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
+ void nxmEndorsementToggled(int modID, QVariant userData, QVariant resultData, int requestID);
+ void nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorMessage);
private:
- NexusInterface* m_Interface;
- QString m_SubModule;
- std::set<int> m_RequestIDs;
+
+ NexusInterface *m_Interface;
+ QString m_SubModule;
+ std::set<int> m_RequestIDs;
+
};
+
/**
* @brief Makes asynchronous requests to the nexus API
*
@@ -119,316 +122,325 @@ private:
* Currently, responses are sent to all receivers that have sent a request of the relevant type, so the
* recipient has to filter the response by the id returned when making the request
**/
-class NexusInterface : public QObject {
- Q_OBJECT
+class NexusInterface : public QObject
+{
+ Q_OBJECT
public:
- ~NexusInterface();
- static NexusInterface* instance();
+ ~NexusInterface();
+
+ static NexusInterface *instance();
+
+ /**
+ * @return the access manager object used to connect to nexus
+ **/
+ NXMAccessManager *getAccessManager();
- /**
- * @return the access manager object used to connect to nexus
- **/
- NXMAccessManager* getAccessManager();
+ /**
+ * @brief cleanup this interface. this is destructive, afterwards it can't be used again
+ */
+ void cleanup();
- /**
- * @brief cleanup this interface. this is destructive, afterwards it can't be used again
- */
- void cleanup();
+ /**
+ * @brief clear webcache and cookies associated with this access manager
+ */
+ void clearCache();
- /**
- * @brief clear webcache and cookies associated with this access manager
- */
- void clearCache();
+ /**
+ * @brief request description for a mod
+ *
+ * @param modID id of the mod caller is interested in (assumed to be for the current game)
+ * @param receiver the object to receive the result asynchronously via a signal (nxmDescriptionAvailable)
+ * @param userData user data to be returned with the result
+ * @return int an id to identify the request
+ **/
+ int requestDescription(int modID, QObject *receiver, QVariant userData, const QString &subModule)
+ {
+ return requestDescription(modID, receiver, userData, subModule, m_Game);
+ }
- /**
- * @brief request description for a mod
- *
- * @param modID id of the mod caller is interested in (assumed to be for the current game)
- * @param receiver the object to receive the result asynchronously via a signal (nxmDescriptionAvailable)
- * @param userData user data to be returned with the result
- * @return int an id to identify the request
- **/
- int requestDescription(int modID, QObject* receiver, QVariant userData, const QString& subModule) {
- return requestDescription(modID, receiver, userData, subModule, m_Game);
- }
+ /**
+ * @brief request description for a mod
+ *
+ * @param modID id of the mod caller is interested in
+ * @param receiver the object to receive the result asynchronously via a signal (nxmDescriptionAvailable)
+ * @param userData user data to be returned with the result
+ * @param game Game with which the mod is associated
+ * @return int an id to identify the request
+ **/
+ int requestDescription(int modID, QObject *receiver, QVariant userData, const QString &subModule,
+ MOBase::IPluginGame const *game);
- /**
- * @brief request description for a mod
- *
- * @param modID id of the mod caller is interested in
- * @param receiver the object to receive the result asynchronously via a signal (nxmDescriptionAvailable)
- * @param userData user data to be returned with the result
- * @param game Game with which the mod is associated
- * @return int an id to identify the request
- **/
- int requestDescription(int modID, QObject* receiver, QVariant userData, const QString& subModule,
- MOBase::IPluginGame const* game);
+ /**
+ * @brief request nexus descriptions for multiple mods at once
+ * @param modIDs a list of ids of mods the caller is interested in (assumed to be for the current game)
+ * @param receiver the object to receive the result asynchronously via a signal (nxmDescriptionAvailable)
+ * @param userData user data to be returned with the result
+ * @return int an id to identify the request
+ */
+ int requestUpdates(const std::vector<int> &modIDs, QObject *receiver, QVariant userData, const QString &subModule)
+ {
+ return requestUpdates(modIDs, receiver, userData, subModule, m_Game);
+ }
- /**
- * @brief request nexus descriptions for multiple mods at once
- * @param modIDs a list of ids of mods the caller is interested in (assumed to be for the current game)
- * @param receiver the object to receive the result asynchronously via a signal (nxmDescriptionAvailable)
- * @param userData user data to be returned with the result
- * @return int an id to identify the request
- */
- int requestUpdates(const std::vector<int>& modIDs, QObject* receiver, QVariant userData, const QString& subModule) {
- return requestUpdates(modIDs, receiver, userData, subModule, m_Game);
- }
+ /**
+ * @brief request nexus descriptions for multiple mods at once
+ * @param modIDs a list of ids of mods the caller is interested in
+ * @param receiver the object to receive the result asynchronously via a signal (nxmDescriptionAvailable)
+ * @param userData user data to be returned with the result
+ * @param game the game with which the mods are associated
+ * @return int an id to identify the request
+ */
+ int requestUpdates(const std::vector<int> &modIDs, QObject *receiver, QVariant userData, const QString &subModule,
+ MOBase::IPluginGame const *game);
- /**
- * @brief request nexus descriptions for multiple mods at once
- * @param modIDs a list of ids of mods the caller is interested in
- * @param receiver the object to receive the result asynchronously via a signal (nxmDescriptionAvailable)
- * @param userData user data to be returned with the result
- * @param game the game with which the mods are associated
- * @return int an id to identify the request
- */
- int requestUpdates(const std::vector<int>& modIDs, QObject* receiver, QVariant userData, const QString& subModule,
- MOBase::IPluginGame const* game);
+ /**
+ * @brief request a list of the files belonging to a mod
+ *
+ * @param modID id of the mod caller is interested in (assumed to be for the current game)
+ * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable)
+ * @param userData user data to be returned with the result
+ * @return int an id to identify the request
+ **/
+ int requestFiles(int modID, QObject *receiver, QVariant userData, const QString &subModule)
+ {
+ return requestFiles(modID, receiver, userData, subModule, m_Game);
+ }
- /**
- * @brief request a list of the files belonging to a mod
- *
- * @param modID id of the mod caller is interested in (assumed to be for the current game)
- * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable)
- * @param userData user data to be returned with the result
- * @return int an id to identify the request
- **/
- int requestFiles(int modID, QObject* receiver, QVariant userData, const QString& subModule) {
- return requestFiles(modID, receiver, userData, subModule, m_Game);
- }
- /**
- * @brief request a list of the files belonging to a mod
- *
- * @param modID id of the mod caller is interested in
- * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable)
- * @param userData user data to be returned with the result
- * @param game the game with which the mods are associated
- * @return int an id to identify the request
- **/
- int requestFiles(int modID, QObject* receiver, QVariant userData, const QString& subModule,
- MOBase::IPluginGame const* game);
+ /**
+ * @brief request a list of the files belonging to a mod
+ *
+ * @param modID id of the mod caller is interested in
+ * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable)
+ * @param userData user data to be returned with the result
+ * @param game the game with which the mods are associated
+ * @return int an id to identify the request
+ **/
+ int requestFiles(int modID, QObject *receiver, QVariant userData, const QString &subModule,
+ MOBase::IPluginGame const *game);
- /**
- * @brief request info about a single file of a mod
- *
- * @param modID id of the mod caller is interested in (assumed to be for the current game)
- * @param fileID id of the file the caller is interested in
- * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable)
- * @param userData user data to be returned with the result
- * @return int an id to identify the request
- **/
- int requestFileInfo(int modID, int fileID, QObject* receiver, QVariant userData, const QString& subModule) {
- return requestFileInfo(modID, fileID, receiver, userData, subModule, m_Game);
- }
+ /**
+ * @brief request info about a single file of a mod
+ *
+ * @param modID id of the mod caller is interested in (assumed to be for the current game)
+ * @param fileID id of the file the caller is interested in
+ * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable)
+ * @param userData user data to be returned with the result
+ * @return int an id to identify the request
+ **/
+ int requestFileInfo(int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule)
+ {
+ return requestFileInfo(modID, fileID, receiver, userData, subModule, m_Game);
+ }
- /**
- * @brief request info about a single file of a mod
- *
- * @param modID id of the mod caller is interested in (assumed to be for the current game)
- * @param fileID id of the file the caller is interested in
- * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable)
- * @param userData user data to be returned with the result
- * @param game the game with which the mods are associated
- * @return int an id to identify the request
- **/
- int requestFileInfo(int modID, int fileID, QObject* receiver, QVariant userData, const QString& subModule,
- MOBase::IPluginGame const* game);
+ /**
+ * @brief request info about a single file of a mod
+ *
+ * @param modID id of the mod caller is interested in (assumed to be for the current game)
+ * @param fileID id of the file the caller is interested in
+ * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable)
+ * @param userData user data to be returned with the result
+ * @param game the game with which the mods are associated
+ * @return int an id to identify the request
+ **/
+ int requestFileInfo(int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule,
+ MOBase::IPluginGame const *game);
- /**
- * @brief request the download url of a file
- *
- * @param modID id of the mod caller is interested in (assumed to be for the current game)
- * @param fileID id of the file the caller is interested in
- * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable)
- * @param userData user data to be returned with the result
- * @return int an id to identify the request
- **/
- int requestDownloadURL(int modID, int fileID, QObject* receiver, QVariant userData, const QString& subModule) {
- return requestDownloadURL(modID, fileID, receiver, userData, subModule, m_Game);
- }
+ /**
+ * @brief request the download url of a file
+ *
+ * @param modID id of the mod caller is interested in (assumed to be for the current game)
+ * @param fileID id of the file the caller is interested in
+ * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable)
+ * @param userData user data to be returned with the result
+ * @return int an id to identify the request
+ **/
+ int requestDownloadURL(int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule)
+ {
+ return requestDownloadURL(modID, fileID, receiver, userData, subModule, m_Game);
+ }
- /**
- * @brief request the download url of a file
- *
- * @param modID id of the mod caller is interested in
- * @param fileID id of the file the caller is interested in
- * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable)
- * @param userData user data to be returned with the result
- * @param game the game with which the mods are associated
- * @return int an id to identify the request
- **/
- int requestDownloadURL(int modID, int fileID, QObject* receiver, QVariant userData, const QString& subModule,
- MOBase::IPluginGame const* game);
+ /**
+ * @brief request the download url of a file
+ *
+ * @param modID id of the mod caller is interested in
+ * @param fileID id of the file the caller is interested in
+ * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable)
+ * @param userData user data to be returned with the result
+ * @param game the game with which the mods are associated
+ * @return int an id to identify the request
+ **/
+ int requestDownloadURL(int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game);
- /**
- * @brief toggle endorsement state of the mod
- * @param modID id of the mod (assumed to be for the current game)
- * @param endorse true if the mod should be endorsed, false for un-endorse
- * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable)
- * @param userData user data to be returned with the result
- * @return int an id to identify the request
- */
- int requestToggleEndorsement(int modID, bool endorse, QObject* receiver, QVariant userData,
- const QString& subModule) {
- return requestToggleEndorsement(modID, endorse, receiver, userData, subModule, m_Game);
- }
+ /**
+ * @brief toggle endorsement state of the mod
+ * @param modID id of the mod (assumed to be for the current game)
+ * @param endorse true if the mod should be endorsed, false for un-endorse
+ * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable)
+ * @param userData user data to be returned with the result
+ * @return int an id to identify the request
+ */
+ int requestToggleEndorsement(int modID, bool endorse, QObject *receiver, QVariant userData, const QString &subModule)
+ {
+ return requestToggleEndorsement(modID, endorse, receiver, userData, subModule, m_Game);
+ }
- /**
- * @brief toggle endorsement state of the mod
- * @param modID id of the mod
- * @param endorse true if the mod should be endorsed, false for un-endorse
- * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable)
- * @param userData user data to be returned with the result
- * @param game the game with which the mods are associated
- * @return int an id to identify the request
- */
- int requestToggleEndorsement(int modID, bool endorse, QObject* receiver, QVariant userData,
- const QString& subModule, MOBase::IPluginGame const* game);
+ /**
+ * @brief toggle endorsement state of the mod
+ * @param modID id of the mod
+ * @param endorse true if the mod should be endorsed, false for un-endorse
+ * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable)
+ * @param userData user data to be returned with the result
+ * @param game the game with which the mods are associated
+ * @return int an id to identify the request
+ */
+ int requestToggleEndorsement(int modID, bool endorse, QObject *receiver, QVariant userData, const QString &subModule,
+ MOBase::IPluginGame const *game);
- /**
- * @param directory the directory to store cache files
- **/
- void setCacheDirectory(const QString& directory);
+ /**
+ * @param directory the directory to store cache files
+ **/
+ void setCacheDirectory(const QString &directory);
- /**
- * MO has to send a "Nexus Client Vx.y.z" as part of the user agent to be allowed to use the API
- * @param nmmVersion the version of nmm to impersonate
- **/
- void setNMMVersion(const QString& nmmVersion);
+ /**
+ * MO has to send a "Nexus Client Vx.y.z" as part of the user agent to be allowed to use the API
+ * @param nmmVersion the version of nmm to impersonate
+ **/
+ void setNMMVersion(const QString &nmmVersion);
- /**
- * @brief called when the log-in completes. This was, requests waiting for the log-in can be run
- */
- void loginCompleted();
+ /**
+ * @brief called when the log-in completes. This was, requests waiting for the log-in can be run
+ */
+ void loginCompleted();
public:
- /**
- * @brief guess the mod id from a filename as delivered by Nexus
- * @param fileName name of the file
- * @return the guessed mod id
- * @note this currently doesn't fit well with the remaining interface but this is the best place for the function
- */
- static void interpretNexusFileName(const QString& fileName, QString& modName, int& modID, bool query);
- /**
- * @brief get the currently managed game
- */
- MOBase::IPluginGame const* managedGame() const;
+ /**
+ * @brief guess the mod id from a filename as delivered by Nexus
+ * @param fileName name of the file
+ * @return the guessed mod id
+ * @note this currently doesn't fit well with the remaining interface but this is the best place for the function
+ */
+ static void interpretNexusFileName(const QString &fileName, QString &modName, int &modID, bool query);
- /**
- * @brief see if the passed URL is related to the current game
- *
- * Arguably, this should optionally take a gameplugin pointer
- */
- bool isURLGameRelated(QUrl const& url) const;
+ /**
+ * @brief get the currently managed game
+ */
+ MOBase::IPluginGame const *managedGame() const;
- /**
- * @brief Get the nexus page for the current game
- *
- * Arguably, this should optionally take a gameplugin pointer
- */
- QString getGameURL() const;
+ /**
+ * @brief see if the passed URL is related to the current game
+ *
+ * Arguably, this should optionally take a gameplugin pointer
+ */
+ bool isURLGameRelated(QUrl const &url) const;
- /**
- * @brief Get the URL for the mod web page
- * @param modID
- */
- QString getModURL(int modID) const;
+ /**
+ * @brief Get the nexus page for the current game
+ *
+ * Arguably, this should optionally take a gameplugin pointer
+ */
+ QString getGameURL() const;
- /**
- * @brief Checks if the specified URL might correspond to a nexus mod
- * @param modID
- * @param url
- * @return
- */
- bool isModURL(int modID, QString const& url) const;
+ /**
+ * @brief Get the URL for the mod web page
+ * @param modID
+ */
+ QString getModURL(int modID) const;
+
+ /**
+ * @brief Checks if the specified URL might correspond to a nexus mod
+ * @param modID
+ * @param url
+ * @return
+ */
+ bool isModURL(int modID, QString const &url) const;
signals:
- void requestNXMDownload(const QString& url);
+ void requestNXMDownload(const QString &url);
- void needLogin();
+ void needLogin();
- void nxmDescriptionAvailable(int modID, QVariant userData, QVariant resultData, int requestID);
- void nxmUpdatesAvailable(const std::vector<int>& modIDs, QVariant userData, QVariant resultData, int requestID);
- void nxmFilesAvailable(int modID, QVariant userData, QVariant resultData, int requestID);
- void nxmFileInfoAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
- void nxmDownloadURLsAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
- void nxmEndorsementToggled(int modID, QVariant userData, QVariant resultData, int requestID);
- void nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString& errorString);
+ void nxmDescriptionAvailable(int modID, QVariant userData, QVariant resultData, int requestID);
+ void nxmUpdatesAvailable(const std::vector<int> &modIDs, QVariant userData, QVariant resultData, int requestID);
+ void nxmFilesAvailable(int modID, QVariant userData, QVariant resultData, int requestID);
+ void nxmFileInfoAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
+ void nxmDownloadURLsAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
+ void nxmEndorsementToggled(int modID, QVariant userData, QVariant resultData, int requestID);
+ void nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorString);
public slots:
- void managedGameChanged(MOBase::IPluginGame const* game);
+ void managedGameChanged(MOBase::IPluginGame const *game);
private slots:
- void requestFinished();
- void requestError(QNetworkReply::NetworkError error);
- void requestTimeout();
+ void requestFinished();
+ void requestError(QNetworkReply::NetworkError error);
+ void requestTimeout();
- void downloadRequestedNXM(const QString& url);
+ void downloadRequestedNXM(const QString &url);
- void fakeFiles();
+ void fakeFiles();
private:
- struct NXMRequestInfo {
- int m_ModID;
- std::vector<int> m_ModIDList;
- int m_FileID;
- QNetworkReply* m_Reply;
- enum Type {
- TYPE_DESCRIPTION,
- TYPE_FILES,
- TYPE_FILEINFO,
- TYPE_DOWNLOADURL,
- TYPE_TOGGLEENDORSEMENT,
- TYPE_GETUPDATES
- } m_Type;
- QVariant m_UserData;
- QTimer* m_Timeout;
- QString m_URL;
- QString m_SubModule;
- int m_NexusGameID;
- bool m_Reroute;
- int m_ID;
- int m_Endorse;
- NXMRequestInfo(int modID, Type type, QVariant userData, const QString& subModule,
- MOBase::IPluginGame const* game);
- NXMRequestInfo(std::vector<int> modIDList, Type type, QVariant userData, const QString& subModule,
- MOBase::IPluginGame const* game);
- NXMRequestInfo(int modID, int fileID, Type type, QVariant userData, const QString& subModule,
- MOBase::IPluginGame const* game);
+ struct NXMRequestInfo {
+ int m_ModID;
+ std::vector<int> m_ModIDList;
+ int m_FileID;
+ QNetworkReply *m_Reply;
+ enum Type {
+ TYPE_DESCRIPTION,
+ TYPE_FILES,
+ TYPE_FILEINFO,
+ TYPE_DOWNLOADURL,
+ TYPE_TOGGLEENDORSEMENT,
+ TYPE_GETUPDATES
+ } m_Type;
+ QVariant m_UserData;
+ QTimer *m_Timeout;
+ QString m_URL;
+ QString m_SubModule;
+ int m_NexusGameID;
+ bool m_Reroute;
+ int m_ID;
+ int m_Endorse;
- private:
- static QAtomicInt s_NextID;
- };
+ NXMRequestInfo(int modID, Type type, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game);
+ NXMRequestInfo(std::vector<int> modIDList, Type type, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game);
+ NXMRequestInfo(int modID, int fileID, Type type, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game);
- static const int MAX_ACTIVE_DOWNLOADS = 2;
+ private:
+ static QAtomicInt s_NextID;
+ };
+
+ static const int MAX_ACTIVE_DOWNLOADS = 2;
private:
- NexusInterface();
- void nextRequest();
- void requestFinished(std::list<NXMRequestInfo>::iterator iter);
- bool requiresLogin(const NXMRequestInfo& info);
- QString getOldModsURL() const;
+
+ NexusInterface();
+ void nextRequest();
+ void requestFinished(std::list<NXMRequestInfo>::iterator iter);
+ bool requiresLogin(const NXMRequestInfo &info);
+ QString getOldModsURL() const;
private:
- QNetworkDiskCache* m_DiskCache;
- NXMAccessManager* m_AccessManager;
+ QNetworkDiskCache *m_DiskCache;
+
+ NXMAccessManager *m_AccessManager;
+
+ std::list<NXMRequestInfo> m_ActiveRequest;
+ QQueue<NXMRequestInfo> m_RequestQueue;
- std::list<NXMRequestInfo> m_ActiveRequest;
- QQueue<NXMRequestInfo> m_RequestQueue;
+ MOBase::VersionInfo m_MOVersion;
+ QString m_NMMVersion;
- MOBase::VersionInfo m_MOVersion;
- QString m_NMMVersion;
+ MOBase::IPluginGame const *m_Game;
- MOBase::IPluginGame const* m_Game;
};
#endif // NEXUSINTERFACE_H
diff --git a/src/noeditdelegate.cpp b/src/noeditdelegate.cpp
index ad7a378a..d5147b9f 100644
--- a/src/noeditdelegate.cpp
+++ b/src/noeditdelegate.cpp
@@ -1,7 +1,10 @@
#include "noeditdelegate.h"
-NoEditDelegate::NoEditDelegate(QObject* parent) : QStyledItemDelegate(parent) {}
+NoEditDelegate::NoEditDelegate(QObject *parent)
+ : QStyledItemDelegate(parent)
+{
+}
-QWidget* NoEditDelegate::createEditor(QWidget*, const QStyleOptionViewItem&, const QModelIndex&) const {
- return nullptr;
+QWidget *NoEditDelegate::createEditor(QWidget*, const QStyleOptionViewItem&, const QModelIndex&) const {
+ return nullptr;
}
diff --git a/src/noeditdelegate.h b/src/noeditdelegate.h
index c269a4de..6fd5ba76 100644
--- a/src/noeditdelegate.h
+++ b/src/noeditdelegate.h
@@ -3,10 +3,10 @@
#include <QStyledItemDelegate>
-class NoEditDelegate : public QStyledItemDelegate {
+class NoEditDelegate: public QStyledItemDelegate {
public:
- NoEditDelegate(QObject* parent = nullptr);
- virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;
+ NoEditDelegate(QObject *parent = nullptr);
+ virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
};
#endif // NOEDITDELEGATE_H
diff --git a/src/nxmaccessmanager.cpp b/src/nxmaccessmanager.cpp
index b299db84..17c50e35 100644
--- a/src/nxmaccessmanager.cpp
+++ b/src/nxmaccessmanager.cpp
@@ -21,283 +21,331 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "iplugingame.h"
#include "nxmurl.h"
-#include "persistentcookiejar.h"
#include "report.h"
+#include "utility.h"
#include "selfupdater.h"
+#include "persistentcookiejar.h"
#include "settings.h"
-#include "utility.h"
-#include <QCoreApplication>
-#include <QDir>
-#include <QJsonArray>
-#include <QJsonDocument>
#include <QMessageBox>
-#include <QNetworkCookie>
-#include <QNetworkCookieJar>
+#include <QPushButton>
#include <QNetworkProxy>
#include <QNetworkRequest>
-#include <QPushButton>
-#include <QThread>
+#include <QNetworkCookie>
+#include <QNetworkCookieJar>
+#include <QCoreApplication>
+#include <QDir>
#include <QUrlQuery>
+#include <QThread>
+#include <QJsonDocument>
+#include <QJsonArray>
using namespace MOBase;
namespace {
-QString const Nexus_Management_URL("http://nmm.nexusmods.com");
+ QString const Nexus_Management_URL("http://nmm.nexusmods.com");
}
// unfortunately Nexus doesn't seem to document these states, all I know is all these listed
// are considered premium (27 should be lifetime premium)
-const std::set<int> NXMAccessManager::s_PremiumAccountStates{4, 6, 13, 27, 31, 32};
+const std::set<int> NXMAccessManager::s_PremiumAccountStates { 4, 6, 13, 27, 31, 32 };
-NXMAccessManager::NXMAccessManager(QObject* parent, const QString& moVersion)
- : QNetworkAccessManager(parent), m_LoginReply(nullptr), m_MOVersion(moVersion) {
- m_LoginTimeout.setSingleShot(true);
- m_LoginTimeout.setInterval(30000);
- setCookieJar(new PersistentCookieJar(
- QDir::fromNativeSeparators(Settings::instance().getCacheDirectory() + "/nexus_cookies.dat")));
- if (networkAccessible() == QNetworkAccessManager::UnknownAccessibility) {
- // why is this necessary all of a sudden?
- setNetworkAccessible(QNetworkAccessManager::Accessible);
- }
+NXMAccessManager::NXMAccessManager(QObject *parent, const QString &moVersion)
+ : QNetworkAccessManager(parent)
+ , m_LoginReply(nullptr)
+ , m_MOVersion(moVersion)
+{
+ m_LoginTimeout.setSingleShot(true);
+ m_LoginTimeout.setInterval(30000);
+ setCookieJar(new PersistentCookieJar(
+ QDir::fromNativeSeparators(Settings::instance().getCacheDirectory() + "/nexus_cookies.dat")));
+
+ if (networkAccessible() == QNetworkAccessManager::UnknownAccessibility) {
+ // why is this necessary all of a sudden?
+ setNetworkAccessible(QNetworkAccessManager::Accessible);
+ }
}
-NXMAccessManager::~NXMAccessManager() {
- if (m_LoginReply != nullptr) {
- m_LoginReply->deleteLater();
- m_LoginReply = nullptr;
- }
+NXMAccessManager::~NXMAccessManager()
+{
+ if (m_LoginReply != nullptr) {
+ m_LoginReply->deleteLater();
+ m_LoginReply = nullptr;
+ }
}
-void NXMAccessManager::setNMMVersion(const QString& nmmVersion) { m_NMMVersion = nmmVersion; }
+void NXMAccessManager::setNMMVersion(const QString &nmmVersion)
+{
+ m_NMMVersion = nmmVersion;
+}
-QNetworkReply* NXMAccessManager::createRequest(QNetworkAccessManager::Operation operation,
- const QNetworkRequest& request, QIODevice* device) {
- if (request.url().scheme() != "nxm") {
- return QNetworkAccessManager::createRequest(operation, request, device);
- }
- if (operation == GetOperation) {
- emit requestNXMDownload(request.url().toString());
+QNetworkReply *NXMAccessManager::createRequest(
+ QNetworkAccessManager::Operation operation, const QNetworkRequest &request,
+ QIODevice *device)
+{
+ if (request.url().scheme() != "nxm") {
+ return QNetworkAccessManager::createRequest(operation, request, device);
+ }
+ if (operation == GetOperation) {
+ emit requestNXMDownload(request.url().toString());
- // eat the request, everything else will be done by the download manager
- return QNetworkAccessManager::createRequest(QNetworkAccessManager::GetOperation, QNetworkRequest(QUrl()));
- } else if (operation == PostOperation) {
- return QNetworkAccessManager::createRequest(operation, request, device);
- ;
- } else {
- return QNetworkAccessManager::createRequest(operation, request, device);
- }
+ // eat the request, everything else will be done by the download manager
+ return QNetworkAccessManager::createRequest(QNetworkAccessManager::GetOperation,
+ QNetworkRequest(QUrl()));
+ } else if (operation == PostOperation) {
+ return QNetworkAccessManager::createRequest(operation, request, device);;
+ } else {
+ return QNetworkAccessManager::createRequest(operation, request, device);
+ }
}
-void NXMAccessManager::showCookies() const {
- QUrl url(Nexus_Management_URL + "/");
- for (const QNetworkCookie& cookie : cookieJar()->cookiesForUrl(url)) {
- qDebug("%s - %s (expires: %s)", cookie.name().constData(), cookie.value().constData(),
- qPrintable(cookie.expirationDate().toString()));
- }
+
+void NXMAccessManager::showCookies() const
+{
+ QUrl url(Nexus_Management_URL + "/");
+ for (const QNetworkCookie &cookie : cookieJar()->cookiesForUrl(url)) {
+ qDebug("%s - %s (expires: %s)",
+ cookie.name().constData(), cookie.value().constData(),
+ qPrintable(cookie.expirationDate().toString()));
+ }
}
-void NXMAccessManager::clearCookies() {
- PersistentCookieJar* jar = qobject_cast<PersistentCookieJar*>(cookieJar());
- if (jar != nullptr) {
- jar->clear();
- } else {
- qWarning("failed to clear cookies, invalid cookie jar");
- }
+void NXMAccessManager::clearCookies()
+{
+ PersistentCookieJar *jar = qobject_cast<PersistentCookieJar*>(cookieJar());
+ if (jar != nullptr) {
+ jar->clear();
+ } else {
+ qWarning("failed to clear cookies, invalid cookie jar");
+ }
}
-void NXMAccessManager::startLoginCheck() {
- if (hasLoginCookies()) {
- qDebug("validating login cookies");
- QNetworkRequest request(Nexus_Management_URL + "/Sessions/?Validate");
- request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
- request.setRawHeader("User-Agent", userAgent().toUtf8());
+void NXMAccessManager::startLoginCheck()
+{
+ if (hasLoginCookies()) {
+ qDebug("validating login cookies");
+ QNetworkRequest request(Nexus_Management_URL + "/Sessions/?Validate");
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
+ request.setRawHeader("User-Agent", userAgent().toUtf8());
- m_LoginReply = get(request);
- m_LoginTimeout.start();
- m_LoginState = LOGIN_CHECKING;
- connect(m_LoginReply, SIGNAL(finished()), this, SLOT(loginChecked()));
- connect(m_LoginReply, SIGNAL(error(QNetworkReply::NetworkError)), this,
- SLOT(loginError(QNetworkReply::NetworkError)));
- }
+ m_LoginReply = get(request);
+ m_LoginTimeout.start();
+ m_LoginState = LOGIN_CHECKING;
+ connect(m_LoginReply, SIGNAL(finished()), this, SLOT(loginChecked()));
+ connect(m_LoginReply, SIGNAL(error(QNetworkReply::NetworkError)),
+ this, SLOT(loginError(QNetworkReply::NetworkError)));
+ }
}
-void NXMAccessManager::retrieveCredentials() {
- qDebug("retrieving credentials");
- QNetworkRequest request(Nexus_Management_URL + "/Core/Libs/Flamework/Entities/User?GetCredentials");
- request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
- request.setRawHeader("User-Agent", userAgent().toUtf8());
+void NXMAccessManager::retrieveCredentials()
+{
+ qDebug("retrieving credentials");
+
+ QNetworkRequest request(Nexus_Management_URL + "/Core/Libs/Flamework/Entities/User?GetCredentials");
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
+ request.setRawHeader("User-Agent", userAgent().toUtf8());
- QNetworkReply* reply = get(request);
- QTimer timeout;
- connect(&timeout, &QTimer::timeout, [reply]() { reply->deleteLater(); });
- timeout.start();
+ QNetworkReply *reply = get(request);
+ QTimer timeout;
+ connect(&timeout, &QTimer::timeout, [reply] () {
+ reply->deleteLater();
+ });
+ timeout.start();
- connect(reply, &QNetworkReply::finished, [reply, this]() {
- QJsonDocument jdoc = QJsonDocument::fromJson(reply->readAll());
- QJsonArray credentialsData = jdoc.array();
- emit credentialsReceived(credentialsData.at(2).toString(),
- s_PremiumAccountStates.find(credentialsData.at(1).toInt()) !=
- s_PremiumAccountStates.end());
- reply->deleteLater();
- });
+ connect(reply, &QNetworkReply::finished, [reply, this] () {
+ QJsonDocument jdoc = QJsonDocument::fromJson(reply->readAll());
+ QJsonArray credentialsData = jdoc.array();
+ emit credentialsReceived(credentialsData.at(2).toString(),
+ s_PremiumAccountStates.find(credentialsData.at(1).toInt())
+ != s_PremiumAccountStates.end());
+ reply->deleteLater();
+ });
- connect(reply, static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error),
- [=](QNetworkReply::NetworkError) {
- qDebug("failed to retrieve account credentials: %s", qPrintable(reply->errorString()));
- reply->deleteLater();
- });
+ connect(reply, static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error),
+ [=] (QNetworkReply::NetworkError) {
+ qDebug("failed to retrieve account credentials: %s", qPrintable(reply->errorString()));
+ reply->deleteLater();
+ });
}
-bool NXMAccessManager::loggedIn() const {
- if (m_LoginState == LOGIN_CHECKING) {
- QProgressDialog progress;
- progress.setLabelText(tr("Verifying Nexus login"));
- progress.show();
- while (m_LoginState == LOGIN_CHECKING) {
- QCoreApplication::processEvents();
- QThread::msleep(100);
- }
- progress.hide();
+
+bool NXMAccessManager::loggedIn() const
+{
+ if (m_LoginState == LOGIN_CHECKING) {
+ QProgressDialog progress;
+ progress.setLabelText(tr("Verifying Nexus login"));
+ progress.show();
+ while (m_LoginState == LOGIN_CHECKING) {
+ QCoreApplication::processEvents();
+ QThread::msleep(100);
}
+ progress.hide();
+ }
- return m_LoginState == LOGIN_VALID;
+ return m_LoginState == LOGIN_VALID;
}
-void NXMAccessManager::refuseLogin() { m_LoginState = LOGIN_REFUSED; }
-bool NXMAccessManager::loginAttempted() const { return m_LoginState != LOGIN_NOT_CHECKED; }
+void NXMAccessManager::refuseLogin()
+{
+ m_LoginState = LOGIN_REFUSED;
+}
-bool NXMAccessManager::loginWaiting() const { return m_LoginReply != nullptr; }
-void NXMAccessManager::login(const QString& username, const QString& password) {
- if (m_LoginReply != nullptr) {
- return;
- }
-
- if (m_LoginState == LOGIN_VALID) {
- emit loginSuccessful(false);
- return;
- }
- m_Username = username;
- m_Password = password;
- pageLogin();
+bool NXMAccessManager::loginAttempted() const
+{
+ return m_LoginState != LOGIN_NOT_CHECKED;
}
-QString NXMAccessManager::userAgent(const QString& subModule) const {
- QStringList comments;
- comments << "compatible to Nexus Client v" + m_NMMVersion;
- if (!subModule.isEmpty()) {
- comments << "module: " + subModule;
- }
- return QString("Mod Organizer v%1 (%2)").arg(m_MOVersion, comments.join("; "));
+bool NXMAccessManager::loginWaiting() const
+{
+ return m_LoginReply != nullptr;
}
-void NXMAccessManager::pageLogin() {
- qDebug("logging %s in on Nexus", qPrintable(m_Username));
- QString requestString =
- (Nexus_Management_URL + "/Sessions/?Login&uri=%1").arg(QString(QUrl::toPercentEncoding(Nexus_Management_URL)));
- QNetworkRequest request(requestString);
- request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
+void NXMAccessManager::login(const QString &username, const QString &password)
+{
+ if (m_LoginReply != nullptr) {
+ return;
+ }
- QByteArray postDataQuery;
- QUrlQuery postData;
- postData.addQueryItem("username", m_Username);
- postData.addQueryItem("password", QUrl::toPercentEncoding(m_Password));
- postDataQuery = postData.query(QUrl::EncodeReserved).toUtf8();
+ if (m_LoginState == LOGIN_VALID) {
+ emit loginSuccessful(false);
+ return;
+ }
+ m_Username = username;
+ m_Password = password;
+ pageLogin();
+}
- request.setRawHeader("User-Agent", userAgent().toUtf8());
- m_ProgressDialog = new QProgressDialog(nullptr);
- m_ProgressDialog->setLabelText(tr("Logging into Nexus"));
- QList<QPushButton*> buttons = m_ProgressDialog->findChildren<QPushButton*>();
- buttons.at(0)->setEnabled(false);
- m_ProgressDialog->show();
- QCoreApplication::processEvents(); // for some reason the whole app hangs during the login. This way the user has at
- // least a little feedback
+QString NXMAccessManager::userAgent(const QString &subModule) const
+{
+ QStringList comments;
+ comments << "compatible to Nexus Client v" + m_NMMVersion;
+ if (!subModule.isEmpty()) {
+ comments << "module: " + subModule;
+ }
- m_LoginReply = post(request, postDataQuery);
- m_LoginTimeout.start();
- m_LoginState = LOGIN_CHECKING;
- connect(m_LoginReply, SIGNAL(finished()), this, SLOT(loginFinished()));
- connect(m_LoginReply, SIGNAL(error(QNetworkReply::NetworkError)), this,
- SLOT(loginError(QNetworkReply::NetworkError)));
+ return QString("Mod Organizer v%1 (%2)").arg(m_MOVersion, comments.join("; "));
}
-void NXMAccessManager::loginTimeout() {
- m_LoginReply->deleteLater();
- m_LoginReply = nullptr;
- m_LoginAttempted = false; // this usually means we might have success later
- m_Username.clear();
- m_Password.clear();
- m_LoginState = LOGIN_NOT_VALID;
- emit loginFailed(tr("timeout"));
-}
+void NXMAccessManager::pageLogin()
+{
+ qDebug("logging %s in on Nexus", qPrintable(m_Username));
+ QString requestString = (Nexus_Management_URL + "/Sessions/?Login&uri=%1")
+ .arg(QString(QUrl::toPercentEncoding(Nexus_Management_URL)));
-void NXMAccessManager::loginError(QNetworkReply::NetworkError) {
- qDebug("login error");
- if (m_ProgressDialog != nullptr) {
- m_ProgressDialog->deleteLater();
- m_ProgressDialog = nullptr;
- }
- m_Username.clear();
- m_Password.clear();
- m_LoginState = LOGIN_NOT_VALID;
+ QNetworkRequest request(requestString);
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
- if (m_LoginReply != nullptr) {
- emit loginFailed(m_LoginReply->errorString());
- m_LoginReply->deleteLater();
- m_LoginReply = nullptr;
- } else {
- emit loginFailed(tr("Unknown error"));
- }
+ QByteArray postDataQuery;
+ QUrlQuery postData;
+ postData.addQueryItem("username", m_Username);
+ postData.addQueryItem("password", QUrl::toPercentEncoding(m_Password));
+ postDataQuery = postData.query(QUrl::EncodeReserved).toUtf8();
+
+ request.setRawHeader("User-Agent", userAgent().toUtf8());
+
+ m_ProgressDialog = new QProgressDialog(nullptr);
+ m_ProgressDialog->setLabelText(tr("Logging into Nexus"));
+ QList<QPushButton*> buttons = m_ProgressDialog->findChildren<QPushButton*>();
+ buttons.at(0)->setEnabled(false);
+ m_ProgressDialog->show();
+ QCoreApplication::processEvents(); // for some reason the whole app hangs during the login. This way the user has at least a little feedback
+
+ m_LoginReply = post(request, postDataQuery);
+ m_LoginTimeout.start();
+ m_LoginState = LOGIN_CHECKING;
+ connect(m_LoginReply, SIGNAL(finished()), this, SLOT(loginFinished()));
+ connect(m_LoginReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(loginError(QNetworkReply::NetworkError)));
}
-bool NXMAccessManager::hasLoginCookies() const {
- QUrl url(Nexus_Management_URL + "/");
- QList<QNetworkCookie> cookies = cookieJar()->cookiesForUrl(url);
- for (const QNetworkCookie& cookie : cookies) {
- if (cookie.name() == "sid") {
- return true;
- }
- }
- return false;
+
+void NXMAccessManager::loginTimeout()
+{
+ m_LoginReply->deleteLater();
+ m_LoginReply = nullptr;
+ m_LoginAttempted = false; // this usually means we might have success later
+ m_Username.clear();
+ m_Password.clear();
+ m_LoginState = LOGIN_NOT_VALID;
+
+ emit loginFailed(tr("timeout"));
}
-void NXMAccessManager::loginFinished() {
- if (m_ProgressDialog != nullptr) {
- m_ProgressDialog->deleteLater();
- m_ProgressDialog = nullptr;
- }
+void NXMAccessManager::loginError(QNetworkReply::NetworkError)
+{
+ qDebug("login error");
+ if (m_ProgressDialog != nullptr) {
+ m_ProgressDialog->deleteLater();
+ m_ProgressDialog = nullptr;
+ }
+ m_Username.clear();
+ m_Password.clear();
+ m_LoginState = LOGIN_NOT_VALID;
+
+ if (m_LoginReply != nullptr) {
+ emit loginFailed(m_LoginReply->errorString());
m_LoginReply->deleteLater();
m_LoginReply = nullptr;
- m_Username.clear();
- m_Password.clear();
+ } else {
+ emit loginFailed(tr("Unknown error"));
+ }
+}
- if (hasLoginCookies()) {
- m_LoginState = LOGIN_VALID;
- retrieveCredentials();
- emit loginSuccessful(true);
- } else {
- m_LoginState = LOGIN_NOT_VALID;
- emit loginFailed(tr("Please check your password"));
+
+bool NXMAccessManager::hasLoginCookies() const
+{
+ QUrl url(Nexus_Management_URL + "/");
+ QList<QNetworkCookie> cookies = cookieJar()->cookiesForUrl(url);
+ for (const QNetworkCookie &cookie : cookies) {
+ if (cookie.name() == "sid") {
+ return true;
}
+ }
+ return false;
}
-void NXMAccessManager::loginChecked() {
- QNetworkReply* reply = static_cast<QNetworkReply*>(sender());
- QByteArray data = reply->readAll();
- m_LoginState = data == "null" ? LOGIN_NOT_VALID : LOGIN_VALID;
- if (m_LoginState == LOGIN_VALID) {
- retrieveCredentials();
- } else {
- qDebug("cookies seem to be invalid");
- }
- m_LoginReply->deleteLater();
- m_LoginReply = nullptr;
+
+void NXMAccessManager::loginFinished()
+{
+ if (m_ProgressDialog != nullptr) {
+ m_ProgressDialog->deleteLater();
+ m_ProgressDialog = nullptr;
+ }
+
+ m_LoginReply->deleteLater();
+ m_LoginReply = nullptr;
+ m_Username.clear();
+ m_Password.clear();
+
+ if (hasLoginCookies()) {
+ m_LoginState = LOGIN_VALID;
+ retrieveCredentials();
+ emit loginSuccessful(true);
+ } else {
+ m_LoginState = LOGIN_NOT_VALID;
+ emit loginFailed(tr("Please check your password"));
+ }
+}
+
+
+void NXMAccessManager::loginChecked()
+{
+ QNetworkReply *reply = static_cast<QNetworkReply*>(sender());
+ QByteArray data = reply->readAll();
+ m_LoginState = data == "null" ? LOGIN_NOT_VALID
+ : LOGIN_VALID;
+ if (m_LoginState == LOGIN_VALID) {
+ retrieveCredentials();
+ } else {
+ qDebug("cookies seem to be invalid");
+ }
+ m_LoginReply->deleteLater();
+ m_LoginReply = nullptr;
}
diff --git a/src/nxmaccessmanager.h b/src/nxmaccessmanager.h
index e9c026f0..c58c4cc3 100644
--- a/src/nxmaccessmanager.h
+++ b/src/nxmaccessmanager.h
@@ -20,107 +20,114 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef NXMACCESSMANAGER_H
#define NXMACCESSMANAGER_H
+
#include <QNetworkAccessManager>
+#include <QTimer>
#include <QNetworkReply>
#include <QProgressDialog>
-#include <QTimer>
#include <set>
-namespace MOBase {
-class IPluginGame;
-}
+namespace MOBase { class IPluginGame; }
/**
* @brief access manager extended to handle nxm links
**/
-class NXMAccessManager : public QNetworkAccessManager {
- Q_OBJECT
+class NXMAccessManager : public QNetworkAccessManager
+{
+ Q_OBJECT
public:
- explicit NXMAccessManager(QObject* parent, const QString& moVersion);
- ~NXMAccessManager();
+ explicit NXMAccessManager(QObject *parent, const QString &moVersion);
- void setNMMVersion(const QString& nmmVersion);
+ ~NXMAccessManager();
- bool loggedIn() const;
+ void setNMMVersion(const QString &nmmVersion);
- bool loginAttempted() const;
- bool loginWaiting() const;
+ bool loggedIn() const;
- void login(const QString& username, const QString& password);
+ bool loginAttempted() const;
+ bool loginWaiting() const;
- void showCookies() const;
+ void login(const QString &username, const QString &password);
- void clearCookies();
+ void showCookies() const;
- QString userAgent(const QString& subModule = QString()) const;
+ void clearCookies();
- void startLoginCheck();
+ QString userAgent(const QString &subModule = QString()) const;
- void refuseLogin();
+ void startLoginCheck();
+
+ void refuseLogin();
signals:
- /**
- * @brief emitted when a nxm:// link is opened
- *
- * @param url the nxm-link
- **/
- void requestNXMDownload(const QString& url);
+ /**
+ * @brief emitted when a nxm:// link is opened
+ *
+ * @param url the nxm-link
+ **/
+ void requestNXMDownload(const QString &url);
- /**
- * @brief emitted after a successful login or if login was not necessary
- *
- * @param necessary true if a login was necessary and succeeded, false if the user is still logged in
- **/
- void loginSuccessful(bool necessary);
+ /**
+ * @brief emitted after a successful login or if login was not necessary
+ *
+ * @param necessary true if a login was necessary and succeeded, false if the user is still logged in
+ **/
+ void loginSuccessful(bool necessary);
- void loginFailed(const QString& message);
+ void loginFailed(const QString &message);
- void credentialsReceived(const QString& userName, bool premium);
+ void credentialsReceived(const QString &userName, bool premium);
private slots:
- void loginChecked();
- void loginFinished();
- void loginError(QNetworkReply::NetworkError errorCode);
- void loginTimeout();
+ void loginChecked();
+ void loginFinished();
+ void loginError(QNetworkReply::NetworkError errorCode);
+ void loginTimeout();
protected:
- virtual QNetworkReply* createRequest(QNetworkAccessManager::Operation operation, const QNetworkRequest& request,
- QIODevice* device);
+
+ virtual QNetworkReply *createRequest(
+ QNetworkAccessManager::Operation operation, const QNetworkRequest &request,
+ QIODevice *device);
private:
- void pageLogin();
- // void dlLogin();
- bool hasLoginCookies() const;
+ void pageLogin();
+// void dlLogin();
- void retrieveCredentials();
+ bool hasLoginCookies() const;
+
+ void retrieveCredentials();
private:
- static const std::set<int> s_PremiumAccountStates;
+
+ static const std::set<int> s_PremiumAccountStates;
private:
- QTimer m_LoginTimeout;
- QNetworkReply* m_LoginReply;
- QProgressDialog* m_ProgressDialog{nullptr};
- QString m_MOVersion;
- QString m_NMMVersion;
+ QTimer m_LoginTimeout;
+ QNetworkReply *m_LoginReply;
+ QProgressDialog *m_ProgressDialog { nullptr };
+
+ QString m_MOVersion;
+ QString m_NMMVersion;
+
+ QString m_Username;
+ QString m_Password;
- QString m_Username;
- QString m_Password;
+ bool m_LoginAttempted;
+ enum {
+ LOGIN_NOT_CHECKED,
+ LOGIN_CHECKING,
+ LOGIN_NOT_VALID,
+ LOGIN_ATTEMPT_FAILED,
+ LOGIN_REFUSED,
+ LOGIN_VALID
+ } m_LoginState = LOGIN_NOT_CHECKED;
- bool m_LoginAttempted;
- enum {
- LOGIN_NOT_CHECKED,
- LOGIN_CHECKING,
- LOGIN_NOT_VALID,
- LOGIN_ATTEMPT_FAILED,
- LOGIN_REFUSED,
- LOGIN_VALID
- } m_LoginState = LOGIN_NOT_CHECKED;
};
#endif // NXMACCESSMANAGER_H
diff --git a/src/organizercore.cpp b/src/organizercore.cpp
index 4b6567c5..b84488da 100644
--- a/src/organizercore.cpp
+++ b/src/organizercore.cpp
@@ -1,39 +1,39 @@
#include "organizercore.h"
-#include "appconfig.h"
-#include "credentialsdialog.h"
#include "delayedfilewriter.h"
-#include "filedialogmemory.h"
#include "guessedvalue.h"
#include "imodinterface.h"
#include "imoinfo.h"
-#include "instancemanager.h"
#include "iplugingame.h"
#include "iuserinterface.h"
#include "loadmechanism.h"
-#include "lockeddialog.h"
-#include "logbuffer.h"
#include "messagedialog.h"
-#include "modinfodialog.h"
#include "modlistsortproxy.h"
#include "modrepositoryfileinfo.h"
#include "nexusinterface.h"
-#include "nxmaccessmanager.h"
#include "plugincontainer.h"
#include "pluginlistsortproxy.h"
#include "profile.h"
+#include "logbuffer.h"
+#include "credentialsdialog.h"
+#include "filedialogmemory.h"
+#include "modinfodialog.h"
#include "spawn.h"
#include "syncoverwritedialog.h"
-#include <dataarchives.h>
-#include <directoryentry.h>
+#include "nxmaccessmanager.h"
#include <ipluginmodpage.h>
+#include <dataarchives.h>
#include <localsavegames.h>
-#include <questionboxmemory.h>
-#include <report.h>
+#include <directoryentry.h>
#include <scopeguard.h>
-#include <scriptextender.h>
-#include <usvfs.h>
#include <utility.h>
+#include <usvfs.h>
+#include "appconfig.h"
+#include <report.h>
+#include <questionboxmemory.h>
+#include "lockeddialog.h"
+#include "instancemanager.h"
+#include <scriptextender.h>
#include <QApplication>
#include <QCoreApplication>
@@ -51,1834 +51,2129 @@
#include <Psapi.h>
#include <Shlobj.h>
-#include <tchar.h> // for _tcsicmp
#include <tlhelp32.h>
+#include <tchar.h> // for _tcsicmp
#include <limits.h>
#include <stddef.h>
#include <string.h> // for memset, wcsrchr
-#include <boost/algorithm/string/predicate.hpp>
#include <exception>
#include <functional>
+#include <boost/algorithm/string/predicate.hpp>
#include <memory>
#include <set>
#include <string> //for wstring
#include <tuple>
#include <utility>
+
using namespace MOShared;
using namespace MOBase;
-// static
+//static
CrashDumpsType OrganizerCore::m_globalCrashDumpsType = CrashDumpsType::None;
-static bool isOnline() {
- QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
+static bool isOnline()
+{
+ QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
- bool connected = false;
- for (auto iter = interfaces.begin(); iter != interfaces.end() && !connected; ++iter) {
- if ((iter->flags() & QNetworkInterface::IsUp) && (iter->flags() & QNetworkInterface::IsRunning) &&
- !(iter->flags() & QNetworkInterface::IsLoopBack)) {
- auto addresses = iter->addressEntries();
- if (addresses.count() == 0) {
- continue;
- }
- qDebug("interface %s seems to be up (address: %s)", qPrintable(iter->humanReadableName()),
- qPrintable(addresses[0].ip().toString()));
- connected = true;
- }
+ bool connected = false;
+ for (auto iter = interfaces.begin(); iter != interfaces.end() && !connected;
+ ++iter) {
+ if ((iter->flags() & QNetworkInterface::IsUp)
+ && (iter->flags() & QNetworkInterface::IsRunning)
+ && !(iter->flags() & QNetworkInterface::IsLoopBack)) {
+ auto addresses = iter->addressEntries();
+ if (addresses.count() == 0) {
+ continue;
+ }
+ qDebug("interface %s seems to be up (address: %s)",
+ qPrintable(iter->humanReadableName()),
+ qPrintable(addresses[0].ip().toString()));
+ connected = true;
}
+ }
- return connected;
+ return connected;
}
-static bool renameFile(const QString& oldName, const QString& newName, bool overwrite = true) {
- if (overwrite && QFile::exists(newName)) {
- QFile::remove(newName);
- }
- return QFile::rename(oldName, newName);
+static bool renameFile(const QString &oldName, const QString &newName,
+ bool overwrite = true)
+{
+ if (overwrite && QFile::exists(newName)) {
+ QFile::remove(newName);
+ }
+ return QFile::rename(oldName, newName);
}
-static std::wstring getProcessName(HANDLE process) {
- wchar_t buffer[MAX_PATH];
- wchar_t* fileName = L"unknown";
+static std::wstring getProcessName(HANDLE process)
+{
+ wchar_t buffer[MAX_PATH];
+ wchar_t *fileName = L"unknown";
- if (process == nullptr)
- return fileName;
+ if (process == nullptr) return fileName;
- if (::GetProcessImageFileNameW(process, buffer, MAX_PATH) != 0) {
- fileName = wcsrchr(buffer, L'\\');
- if (fileName == nullptr) {
- fileName = buffer;
- } else {
- fileName += 1;
- }
- }
+ if (::GetProcessImageFileNameW(process, buffer, MAX_PATH) != 0) {
+ fileName = wcsrchr(buffer, L'\\');
+ if (fileName == nullptr) {
+ fileName = buffer;
+ }
+ else {
+ fileName += 1;
+ }
+ }
- return fileName;
+ return fileName;
}
// Get parent PID for the given process, return 0 on failure
-static DWORD getProcessParentID(DWORD pid) {
- HANDLE th = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- PROCESSENTRY32 pe = {0};
- pe.dwSize = sizeof(PROCESSENTRY32);
+static DWORD getProcessParentID(DWORD pid)
+{
+ HANDLE th = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ PROCESSENTRY32 pe = { 0 };
+ pe.dwSize = sizeof(PROCESSENTRY32);
- DWORD res = 0;
- if (Process32First(th, &pe))
- do {
- if (pe.th32ProcessID == pid) {
- res = pe.th32ParentProcessID;
- break;
- }
- } while (Process32Next(th, &pe));
+ DWORD res = 0;
+ if (Process32First(th, &pe))
+ do {
+ if (pe.th32ProcessID == pid) {
+ res = pe.th32ParentProcessID;
+ break;
+ }
+ } while (Process32Next(th, &pe));
- CloseHandle(th);
+ CloseHandle(th);
- return res;
+ return res;
}
-static void startSteam(QWidget* widget) {
- QSettings steamSettings("HKEY_CURRENT_USER\\Software\\Valve\\Steam", QSettings::NativeFormat);
- QString exe = steamSettings.value("SteamExe", "").toString();
- if (!exe.isEmpty()) {
- exe = QString("\"%1\"").arg(exe);
- // See if username and password supplied. If so, pass them into steam.
- QStringList args;
- QString username;
- QString password;
- if (Settings::instance().getSteamLogin(username, password)) {
- args << "-login";
- args << username;
- if (password != "") {
- args << password;
- }
- }
- if (!QProcess::startDetached(exe, args)) {
- reportError(QObject::tr("Failed to start \"%1\"").arg(exe));
- } else {
- QMessageBox::information(widget, QObject::tr("Waiting"),
- QObject::tr("Please press OK once you're logged into steam."));
- }
+static void startSteam(QWidget *widget)
+{
+ QSettings steamSettings("HKEY_CURRENT_USER\\Software\\Valve\\Steam",
+ QSettings::NativeFormat);
+ QString exe = steamSettings.value("SteamExe", "").toString();
+ if (!exe.isEmpty()) {
+ exe = QString("\"%1\"").arg(exe);
+ // See if username and password supplied. If so, pass them into steam.
+ QStringList args;
+ QString username;
+ QString password;
+ if (Settings::instance().getSteamLogin(username, password)) {
+ args << "-login";
+ args << username;
+ if (password != "") {
+ args << password;
+ }
+ }
+ if (!QProcess::startDetached(exe, args)) {
+ reportError(QObject::tr("Failed to start \"%1\"").arg(exe));
+ } else {
+ QMessageBox::information(
+ widget, QObject::tr("Waiting"),
+ QObject::tr("Please press OK once you're logged into steam."));
}
+ }
}
template <typename InputIterator>
-QStringList toStringList(InputIterator current, InputIterator end) {
- QStringList result;
- for (; current != end; ++current) {
- result.append(*current);
- }
- return result;
+QStringList toStringList(InputIterator current, InputIterator end)
+{
+ QStringList result;
+ for (; current != end; ++current) {
+ result.append(*current);
+ }
+ return result;
}
-OrganizerCore::OrganizerCore(const QSettings& initSettings)
- : m_UserInterface(nullptr), m_PluginContainer(nullptr), m_GameName(), m_CurrentProfile(nullptr),
- m_Settings(initSettings), m_Updater(NexusInterface::instance()), m_AboutToRun(), m_FinishedRun(),
- m_ModInstalled(), m_ModList(this), m_PluginList(this), m_DirectoryRefresher(),
- m_DirectoryStructure(new DirectoryEntry(L"data", nullptr, 0)),
- m_DownloadManager(NexusInterface::instance(), this), m_InstallationManager(), m_RefresherThread(),
- m_AskForNexusPW(false), m_DirectoryUpdate(false), m_ArchivesInit(false),
- m_PluginListsWriter(std::bind(&OrganizerCore::savePluginList, this)) {
- m_DownloadManager.setOutputDirectory(m_Settings.getDownloadDirectory());
- m_DownloadManager.setPreferredServers(m_Settings.getPreferredServers());
+OrganizerCore::OrganizerCore(const QSettings &initSettings)
+ : m_UserInterface(nullptr)
+ , m_PluginContainer(nullptr)
+ , m_GameName()
+ , m_CurrentProfile(nullptr)
+ , m_Settings(initSettings)
+ , m_Updater(NexusInterface::instance())
+ , m_AboutToRun()
+ , m_FinishedRun()
+ , m_ModInstalled()
+ , m_ModList(this)
+ , m_PluginList(this)
+ , m_DirectoryRefresher()
+ , m_DirectoryStructure(new DirectoryEntry(L"data", nullptr, 0))
+ , m_DownloadManager(NexusInterface::instance(), this)
+ , m_InstallationManager()
+ , m_RefresherThread()
+ , m_AskForNexusPW(false)
+ , m_DirectoryUpdate(false)
+ , m_ArchivesInit(false)
+ , m_PluginListsWriter(std::bind(&OrganizerCore::savePluginList, this))
+{
+ m_DownloadManager.setOutputDirectory(m_Settings.getDownloadDirectory());
+ m_DownloadManager.setPreferredServers(m_Settings.getPreferredServers());
- NexusInterface::instance()->setCacheDirectory(m_Settings.getCacheDirectory());
- NexusInterface::instance()->setNMMVersion(m_Settings.getNMMVersion());
+ NexusInterface::instance()->setCacheDirectory(m_Settings.getCacheDirectory());
+ NexusInterface::instance()->setNMMVersion(m_Settings.getNMMVersion());
- MOBase::QuestionBoxMemory::init(initSettings.fileName());
+ MOBase::QuestionBoxMemory::init(initSettings.fileName());
- m_InstallationManager.setModsDirectory(m_Settings.getModDirectory());
- m_InstallationManager.setDownloadDirectory(m_Settings.getDownloadDirectory());
+ m_InstallationManager.setModsDirectory(m_Settings.getModDirectory());
+ m_InstallationManager.setDownloadDirectory(m_Settings.getDownloadDirectory());
- connect(&m_DownloadManager, SIGNAL(downloadSpeed(QString, int)), this, SLOT(downloadSpeed(QString, int)));
- connect(&m_DirectoryRefresher, SIGNAL(refreshed()), this, SLOT(directory_refreshed()));
+ connect(&m_DownloadManager, SIGNAL(downloadSpeed(QString, int)), this,
+ SLOT(downloadSpeed(QString, int)));
+ connect(&m_DirectoryRefresher, SIGNAL(refreshed()), this,
+ SLOT(directory_refreshed()));
- connect(&m_ModList, SIGNAL(removeOrigin(QString)), this, SLOT(removeOrigin(QString)));
+ connect(&m_ModList, SIGNAL(removeOrigin(QString)), this,
+ SLOT(removeOrigin(QString)));
- connect(NexusInterface::instance()->getAccessManager(), SIGNAL(loginSuccessful(bool)), this,
- SLOT(loginSuccessful(bool)));
- connect(NexusInterface::instance()->getAccessManager(), SIGNAL(loginFailed(QString)), this,
- SLOT(loginFailed(QString)));
+ connect(NexusInterface::instance()->getAccessManager(),
+ SIGNAL(loginSuccessful(bool)), this, SLOT(loginSuccessful(bool)));
+ connect(NexusInterface::instance()->getAccessManager(),
+ SIGNAL(loginFailed(QString)), this, SLOT(loginFailed(QString)));
- // This seems awfully imperative
- connect(this, SIGNAL(managedGameChanged(MOBase::IPluginGame const*)), &m_Settings,
- SLOT(managedGameChanged(MOBase::IPluginGame const*)));
- connect(this, SIGNAL(managedGameChanged(MOBase::IPluginGame const*)), &m_DownloadManager,
- SLOT(managedGameChanged(MOBase::IPluginGame const*)));
- connect(this, SIGNAL(managedGameChanged(MOBase::IPluginGame const*)), &m_PluginList,
- SLOT(managedGameChanged(MOBase::IPluginGame const*)));
- connect(this, SIGNAL(managedGameChanged(MOBase::IPluginGame const*)), NexusInterface::instance(),
- SLOT(managedGameChanged(MOBase::IPluginGame const*)));
+ // This seems awfully imperative
+ connect(this, SIGNAL(managedGameChanged(MOBase::IPluginGame const *)),
+ &m_Settings, SLOT(managedGameChanged(MOBase::IPluginGame const *)));
+ connect(this, SIGNAL(managedGameChanged(MOBase::IPluginGame const *)),
+ &m_DownloadManager,
+ SLOT(managedGameChanged(MOBase::IPluginGame const *)));
+ connect(this, SIGNAL(managedGameChanged(MOBase::IPluginGame const *)),
+ &m_PluginList, SLOT(managedGameChanged(MOBase::IPluginGame const *)));
+ connect(this, SIGNAL(managedGameChanged(MOBase::IPluginGame const *)),
+ NexusInterface::instance(),
+ SLOT(managedGameChanged(MOBase::IPluginGame const *)));
- connect(&m_PluginList, &PluginList::writePluginsList, &m_PluginListsWriter, &DelayedFileWriterBase::write);
+ connect(&m_PluginList, &PluginList::writePluginsList, &m_PluginListsWriter,
+ &DelayedFileWriterBase::write);
- // make directory refresher run in a separate thread
- m_RefresherThread.start();
- m_DirectoryRefresher.moveToThread(&m_RefresherThread);
+ // make directory refresher run in a separate thread
+ m_RefresherThread.start();
+ m_DirectoryRefresher.moveToThread(&m_RefresherThread);
- m_AskForNexusPW = initSettings.value("ask_for_nexuspw", true).toBool();
+ m_AskForNexusPW = initSettings.value("ask_for_nexuspw", true).toBool();
}
-OrganizerCore::~OrganizerCore() {
- m_RefresherThread.exit();
- m_RefresherThread.wait();
+OrganizerCore::~OrganizerCore()
+{
+ m_RefresherThread.exit();
+ m_RefresherThread.wait();
- prepareStart();
+ prepareStart();
- // profile has to be cleaned up before the modinfo-buffer is cleared
- delete m_CurrentProfile;
- m_CurrentProfile = nullptr;
+ // profile has to be cleaned up before the modinfo-buffer is cleared
+ delete m_CurrentProfile;
+ m_CurrentProfile = nullptr;
- ModInfo::clear();
- LogBuffer::cleanQuit();
- m_ModList.setProfile(nullptr);
- // NexusInterface::instance()->cleanup();
+ ModInfo::clear();
+ LogBuffer::cleanQuit();
+ m_ModList.setProfile(nullptr);
+ // NexusInterface::instance()->cleanup();
- delete m_DirectoryStructure;
+ delete m_DirectoryStructure;
}
-QString OrganizerCore::commitSettings(const QString& iniFile) {
- if (!shellRename(iniFile + ".new", iniFile, true, qApp->activeWindow())) {
- DWORD err = ::GetLastError();
- // make a second attempt using qt functions but if that fails print the
- // error from the first attempt
- if (!renameFile(iniFile + ".new", iniFile)) {
- return windowsErrorString(err);
- }
+QString OrganizerCore::commitSettings(const QString &iniFile)
+{
+ if (!shellRename(iniFile + ".new", iniFile, true, qApp->activeWindow())) {
+ DWORD err = ::GetLastError();
+ // make a second attempt using qt functions but if that fails print the
+ // error from the first attempt
+ if (!renameFile(iniFile + ".new", iniFile)) {
+ return windowsErrorString(err);
}
- return QString();
+ }
+ return QString();
}
-QSettings::Status OrganizerCore::storeSettings(const QString& fileName) {
- QSettings settings(fileName, QSettings::IniFormat);
- if (m_UserInterface != nullptr) {
- m_UserInterface->storeSettings(settings);
- }
- if (m_CurrentProfile != nullptr) {
- settings.setValue("selected_profile", m_CurrentProfile->name().toUtf8().constData());
- }
- settings.setValue("ask_for_nexuspw", m_AskForNexusPW);
+QSettings::Status OrganizerCore::storeSettings(const QString &fileName)
+{
+ QSettings settings(fileName, QSettings::IniFormat);
+ if (m_UserInterface != nullptr) {
+ m_UserInterface->storeSettings(settings);
+ }
+ if (m_CurrentProfile != nullptr) {
+ settings.setValue("selected_profile",
+ m_CurrentProfile->name().toUtf8().constData());
+ }
+ settings.setValue("ask_for_nexuspw", m_AskForNexusPW);
- settings.remove("customExecutables");
- settings.beginWriteArray("customExecutables");
- std::vector<Executable>::const_iterator current, end;
- m_ExecutablesList.getExecutables(current, end);
- int count = 0;
- for (; current != end; ++current) {
- const Executable& item = *current;
- settings.setArrayIndex(count++);
- settings.setValue("title", item.m_Title);
- settings.setValue("custom", item.isCustom());
- settings.setValue("toolbar", item.isShownOnToolbar());
- settings.setValue("ownicon", item.usesOwnIcon());
- if (item.isCustom()) {
- settings.setValue("binary", item.m_BinaryInfo.absoluteFilePath());
- settings.setValue("arguments", item.m_Arguments);
- settings.setValue("workingDirectory", item.m_WorkingDirectory);
- settings.setValue("steamAppID", item.m_SteamAppID);
- }
+ settings.remove("customExecutables");
+ settings.beginWriteArray("customExecutables");
+ std::vector<Executable>::const_iterator current, end;
+ m_ExecutablesList.getExecutables(current, end);
+ int count = 0;
+ for (; current != end; ++current) {
+ const Executable &item = *current;
+ settings.setArrayIndex(count++);
+ settings.setValue("title", item.m_Title);
+ settings.setValue("custom", item.isCustom());
+ settings.setValue("toolbar", item.isShownOnToolbar());
+ settings.setValue("ownicon", item.usesOwnIcon());
+ if (item.isCustom()) {
+ settings.setValue("binary", item.m_BinaryInfo.absoluteFilePath());
+ settings.setValue("arguments", item.m_Arguments);
+ settings.setValue("workingDirectory", item.m_WorkingDirectory);
+ settings.setValue("steamAppID", item.m_SteamAppID);
}
- settings.endArray();
+ }
+ settings.endArray();
- FileDialogMemory::save(settings);
+ FileDialogMemory::save(settings);
- settings.sync();
- return settings.status();
+ settings.sync();
+ return settings.status();
}
-void OrganizerCore::storeSettings() {
- QString iniFile = qApp->property("dataPath").toString() + "/" + QString::fromStdWString(AppConfig::iniFileName());
- if (QFileInfo(iniFile).exists()) {
- if (!shellCopy(iniFile, iniFile + ".new", true, qApp->activeWindow())) {
- QMessageBox::critical(qApp->activeWindow(), tr("Failed to write settings"),
- tr("An error occured trying to update MO settings to %1: %2")
- .arg(iniFile, windowsErrorString(::GetLastError())));
- return;
- }
+void OrganizerCore::storeSettings()
+{
+ QString iniFile = qApp->property("dataPath").toString() + "/"
+ + QString::fromStdWString(AppConfig::iniFileName());
+ if (QFileInfo(iniFile).exists()) {
+ if (!shellCopy(iniFile, iniFile + ".new", true, qApp->activeWindow())) {
+ QMessageBox::critical(
+ qApp->activeWindow(), tr("Failed to write settings"),
+ tr("An error occured trying to update MO settings to %1: %2")
+ .arg(iniFile, windowsErrorString(::GetLastError())));
+ return;
}
+ }
- QString writeTarget = iniFile + ".new";
+ QString writeTarget = iniFile + ".new";
- QSettings::Status result = storeSettings(writeTarget);
+ QSettings::Status result = storeSettings(writeTarget);
- if (result == QSettings::NoError) {
- QString errMsg = commitSettings(iniFile);
- if (!errMsg.isEmpty()) {
- qWarning("settings file not writable, may be locked by another "
- "application, trying direct write");
- writeTarget = iniFile;
- result = storeSettings(iniFile);
- }
- }
- if (result != QSettings::NoError) {
- QString reason = result == QSettings::AccessError
- ? tr("File is write protected")
- : result == QSettings::FormatError ? tr("Invalid file format (probably a bug)")
- : tr("Unknown error %1").arg(result);
- QMessageBox::critical(
- qApp->activeWindow(), tr("Failed to write settings"),
- tr("An error occured trying to write back MO settings to %1: %2").arg(writeTarget, reason));
+ if (result == QSettings::NoError) {
+ QString errMsg = commitSettings(iniFile);
+ if (!errMsg.isEmpty()) {
+ qWarning("settings file not writable, may be locked by another "
+ "application, trying direct write");
+ writeTarget = iniFile;
+ result = storeSettings(iniFile);
}
+ }
+ if (result != QSettings::NoError) {
+ QString reason = result == QSettings::AccessError
+ ? tr("File is write protected")
+ : result == QSettings::FormatError
+ ? tr("Invalid file format (probably a bug)")
+ : tr("Unknown error %1").arg(result);
+ QMessageBox::critical(
+ qApp->activeWindow(), tr("Failed to write settings"),
+ tr("An error occured trying to write back MO settings to %1: %2")
+ .arg(writeTarget, reason));
+ }
}
-bool OrganizerCore::testForSteam() {
- size_t currentSize = 1024;
- std::unique_ptr<DWORD[]> processIDs;
- DWORD bytesReturned;
- bool success = false;
- while (!success) {
- processIDs.reset(new DWORD[currentSize]);
- if (!::EnumProcesses(processIDs.get(), static_cast<DWORD>(currentSize) * sizeof(DWORD), &bytesReturned)) {
- qWarning("failed to determine if steam is running");
- return true;
- }
- if (bytesReturned == (currentSize * sizeof(DWORD))) {
- // maximum size used, list probably truncated
- currentSize *= 2;
- } else {
- success = true;
- }
+bool OrganizerCore::testForSteam()
+{
+ size_t currentSize = 1024;
+ std::unique_ptr<DWORD[]> processIDs;
+ DWORD bytesReturned;
+ bool success = false;
+ while (!success) {
+ processIDs.reset(new DWORD[currentSize]);
+ if (!::EnumProcesses(processIDs.get(),
+ static_cast<DWORD>(currentSize) * sizeof(DWORD),
+ &bytesReturned)) {
+ qWarning("failed to determine if steam is running");
+ return true;
+ }
+ if (bytesReturned == (currentSize * sizeof(DWORD))) {
+ // maximum size used, list probably truncated
+ currentSize *= 2;
+ } else {
+ success = true;
}
- TCHAR processName[MAX_PATH];
- for (unsigned int i = 0; i < bytesReturned / sizeof(DWORD); ++i) {
- memset(processName, '\0', sizeof(TCHAR) * MAX_PATH);
- if (processIDs[i] != 0) {
- HANDLE process = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processIDs[i]);
+ }
+ TCHAR processName[MAX_PATH];
+ for (unsigned int i = 0; i < bytesReturned / sizeof(DWORD); ++i) {
+ memset(processName, '\0', sizeof(TCHAR) * MAX_PATH);
+ if (processIDs[i] != 0) {
+ HANDLE process = ::OpenProcess(
+ PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processIDs[i]);
- if (process != nullptr) {
+ if (process != nullptr) {
- ON_BLOCK_EXIT([&]() {
- if (process != INVALID_HANDLE_VALUE)
- ::CloseHandle(process);
- });
+ ON_BLOCK_EXIT([&]() {
+ if (process != INVALID_HANDLE_VALUE)
+ ::CloseHandle(process);
+ });
- HMODULE module;
- DWORD ignore;
+ HMODULE module;
+ DWORD ignore;
- // first module in a process is always the binary
- if (EnumProcessModules(process, &module, sizeof(HMODULE) * 1, &ignore)) {
- ::GetModuleBaseName(process, module, processName, MAX_PATH);
- if ((_tcsicmp(processName, TEXT("steam.exe")) == 0) ||
- (_tcsicmp(processName, TEXT("steamservice.exe")) == 0)) {
- return true;
- }
- }
- }
+ // first module in a process is always the binary
+ if (EnumProcessModules(process, &module, sizeof(HMODULE) * 1,
+ &ignore)) {
+ ::GetModuleBaseName(process, module, processName, MAX_PATH);
+ if ((_tcsicmp(processName, TEXT("steam.exe")) == 0)
+ || (_tcsicmp(processName, TEXT("steamservice.exe")) == 0)) {
+ return true;
+ }
}
+ }
}
+ }
- return false;
+ return false;
}
-void OrganizerCore::updateExecutablesList(QSettings& settings) {
- if (m_PluginContainer == nullptr) {
- qCritical("can't update executables list now");
- return;
- }
+void OrganizerCore::updateExecutablesList(QSettings &settings)
+{
+ if (m_PluginContainer == nullptr) {
+ qCritical("can't update executables list now");
+ return;
+ }
- m_ExecutablesList.init(managedGame());
+ m_ExecutablesList.init(managedGame());
- qDebug("setting up configured executables");
+ qDebug("setting up configured executables");
- int numCustomExecutables = settings.beginReadArray("customExecutables");
- for (int i = 0; i < numCustomExecutables; ++i) {
- settings.setArrayIndex(i);
+ int numCustomExecutables = settings.beginReadArray("customExecutables");
+ for (int i = 0; i < numCustomExecutables; ++i) {
+ settings.setArrayIndex(i);
- Executable::Flags flags;
- if (settings.value("custom", true).toBool())
- flags |= Executable::CustomExecutable;
- if (settings.value("toolbar", false).toBool())
- flags |= Executable::ShowInToolbar;
- if (settings.value("ownicon", false).toBool())
- flags |= Executable::UseApplicationIcon;
+ Executable::Flags flags;
+ if (settings.value("custom", true).toBool())
+ flags |= Executable::CustomExecutable;
+ if (settings.value("toolbar", false).toBool())
+ flags |= Executable::ShowInToolbar;
+ if (settings.value("ownicon", false).toBool())
+ flags |= Executable::UseApplicationIcon;
- m_ExecutablesList.addExecutable(settings.value("title").toString(), settings.value("binary").toString(),
- settings.value("arguments").toString(),
- settings.value("workingDirectory", "").toString(),
- settings.value("steamAppID", "").toString(), flags);
- }
+ m_ExecutablesList.addExecutable(
+ settings.value("title").toString(), settings.value("binary").toString(),
+ settings.value("arguments").toString(),
+ settings.value("workingDirectory", "").toString(),
+ settings.value("steamAppID", "").toString(), flags);
+ }
- settings.endArray();
+ settings.endArray();
- // TODO this has nothing to do with executables list move to an appropriate
- // function!
- ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, m_Settings.displayForeign(),
- managedGame());
+ // TODO this has nothing to do with executables list move to an appropriate
+ // function!
+ ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure,
+ m_Settings.displayForeign(), managedGame());
}
-void OrganizerCore::setUserInterface(IUserInterface* userInterface, QWidget* widget) {
- storeSettings();
+void OrganizerCore::setUserInterface(IUserInterface *userInterface,
+ QWidget *widget)
+{
+ storeSettings();
- m_UserInterface = userInterface;
+ m_UserInterface = userInterface;
- if (widget != nullptr) {
- connect(&m_ModList, SIGNAL(modlist_changed(QModelIndex, int)), widget, SLOT(modlistChanged(QModelIndex, int)));
- connect(&m_ModList, SIGNAL(showMessage(QString)), widget, SLOT(showMessage(QString)));
- connect(&m_ModList, SIGNAL(modRenamed(QString, QString)), widget, SLOT(modRenamed(QString, QString)));
- connect(&m_ModList, SIGNAL(modUninstalled(QString)), widget, SLOT(modRemoved(QString)));
- connect(&m_ModList, SIGNAL(removeSelectedMods()), widget, SLOT(removeMod_clicked()));
- connect(&m_ModList, SIGNAL(requestColumnSelect(QPoint)), widget, SLOT(displayColumnSelection(QPoint)));
- connect(&m_ModList, SIGNAL(fileMoved(QString, QString, QString)), widget,
- SLOT(fileMoved(QString, QString, QString)));
- connect(&m_ModList, SIGNAL(modorder_changed()), widget, SLOT(modorder_changed()));
- connect(&m_DownloadManager, SIGNAL(showMessage(QString)), widget, SLOT(showMessage(QString)));
- }
+ if (widget != nullptr) {
+ connect(&m_ModList, SIGNAL(modlist_changed(QModelIndex, int)), widget,
+ SLOT(modlistChanged(QModelIndex, int)));
+ connect(&m_ModList, SIGNAL(showMessage(QString)), widget,
+ SLOT(showMessage(QString)));
+ connect(&m_ModList, SIGNAL(modRenamed(QString, QString)), widget,
+ SLOT(modRenamed(QString, QString)));
+ connect(&m_ModList, SIGNAL(modUninstalled(QString)), widget,
+ SLOT(modRemoved(QString)));
+ connect(&m_ModList, SIGNAL(removeSelectedMods()), widget,
+ SLOT(removeMod_clicked()));
+ connect(&m_ModList, SIGNAL(requestColumnSelect(QPoint)), widget,
+ SLOT(displayColumnSelection(QPoint)));
+ connect(&m_ModList, SIGNAL(fileMoved(QString, QString, QString)), widget,
+ SLOT(fileMoved(QString, QString, QString)));
+ connect(&m_ModList, SIGNAL(modorder_changed()), widget,
+ SLOT(modorder_changed()));
+ connect(&m_DownloadManager, SIGNAL(showMessage(QString)), widget,
+ SLOT(showMessage(QString)));
+ }
- m_InstallationManager.setParentWidget(widget);
- m_Updater.setUserInterface(widget);
+ m_InstallationManager.setParentWidget(widget);
+ m_Updater.setUserInterface(widget);
- if (userInterface != nullptr) {
- // this currently wouldn't work reliably if the ui isn't initialized yet to
- // display the result
- if (isOnline() && !m_Settings.offlineMode()) {
- m_Updater.testForUpdate();
- } else {
- qDebug("user doesn't seem to be connected to the internet");
- }
+ if (userInterface != nullptr) {
+ // this currently wouldn't work reliably if the ui isn't initialized yet to
+ // display the result
+ if (isOnline() && !m_Settings.offlineMode()) {
+ m_Updater.testForUpdate();
+ } else {
+ qDebug("user doesn't seem to be connected to the internet");
}
+ }
}
-void OrganizerCore::connectPlugins(PluginContainer* container) {
- m_DownloadManager.setSupportedExtensions(m_InstallationManager.getSupportedExtensions());
- m_PluginContainer = container;
+void OrganizerCore::connectPlugins(PluginContainer *container)
+{
+ m_DownloadManager.setSupportedExtensions(
+ m_InstallationManager.getSupportedExtensions());
+ m_PluginContainer = container;
- if (!m_GameName.isEmpty()) {
- m_GamePlugin = m_PluginContainer->managedGame(m_GameName);
- emit managedGameChanged(m_GamePlugin);
- }
+ if (!m_GameName.isEmpty()) {
+ m_GamePlugin = m_PluginContainer->managedGame(m_GameName);
+ emit managedGameChanged(m_GamePlugin);
+ }
}
-void OrganizerCore::disconnectPlugins() {
- m_AboutToRun.disconnect_all_slots();
- m_FinishedRun.disconnect_all_slots();
- m_ModInstalled.disconnect_all_slots();
- m_ModList.disconnectSlots();
- m_PluginList.disconnectSlots();
+void OrganizerCore::disconnectPlugins()
+{
+ m_AboutToRun.disconnect_all_slots();
+ m_FinishedRun.disconnect_all_slots();
+ m_ModInstalled.disconnect_all_slots();
+ m_ModList.disconnectSlots();
+ m_PluginList.disconnectSlots();
- m_Settings.clearPlugins();
- m_GamePlugin = nullptr;
- m_PluginContainer = nullptr;
+ m_Settings.clearPlugins();
+ m_GamePlugin = nullptr;
+ m_PluginContainer = nullptr;
}
-void OrganizerCore::setManagedGame(MOBase::IPluginGame* game) {
- m_GameName = game->gameName();
- m_GamePlugin = game;
- qApp->setProperty("managed_game", QVariant::fromValue(m_GamePlugin));
- emit managedGameChanged(m_GamePlugin);
+void OrganizerCore::setManagedGame(MOBase::IPluginGame *game)
+{
+ m_GameName = game->gameName();
+ m_GamePlugin = game;
+ qApp->setProperty("managed_game", QVariant::fromValue(m_GamePlugin));
+ emit managedGameChanged(m_GamePlugin);
}
-Settings& OrganizerCore::settings() { return m_Settings; }
+Settings &OrganizerCore::settings()
+{
+ return m_Settings;
+}
-bool OrganizerCore::nexusLogin(bool retry) {
- NXMAccessManager* accessManager = NexusInterface::instance()->getAccessManager();
+bool OrganizerCore::nexusLogin(bool retry)
+{
+ NXMAccessManager *accessManager
+ = NexusInterface::instance()->getAccessManager();
- if ((accessManager->loginAttempted() || accessManager->loggedIn()) && !retry) {
- // previous attempt, maybe even successful
- return false;
+ if ((accessManager->loginAttempted() || accessManager->loggedIn())
+ && !retry) {
+ // previous attempt, maybe even successful
+ return false;
+ } else {
+ QString username, password;
+ if ((!retry && m_Settings.getNexusLogin(username, password))
+ || (m_AskForNexusPW && queryLogin(username, password))) {
+ // credentials stored or user entered them manually
+ qDebug("attempt login with username %s", qPrintable(username));
+ accessManager->login(username, password);
+ return true;
} else {
- QString username, password;
- if ((!retry && m_Settings.getNexusLogin(username, password)) ||
- (m_AskForNexusPW && queryLogin(username, password))) {
- // credentials stored or user entered them manually
- qDebug("attempt login with username %s", qPrintable(username));
- accessManager->login(username, password);
- return true;
- } else {
- // no credentials stored and user didn't enter them
- accessManager->refuseLogin();
- return false;
- }
+ // no credentials stored and user didn't enter them
+ accessManager->refuseLogin();
+ return false;
}
+ }
}
-bool OrganizerCore::queryLogin(QString& username, QString& password) {
- CredentialsDialog dialog(qApp->activeWindow());
- int res = dialog.exec();
- if (dialog.neverAsk()) {
- m_AskForNexusPW = false;
- }
- if (res == QDialog::Accepted) {
- username = dialog.username();
- password = dialog.password();
- if (dialog.store()) {
- m_Settings.setNexusLogin(username, password);
- }
- return true;
- } else {
- return false;
+bool OrganizerCore::queryLogin(QString &username, QString &password)
+{
+ CredentialsDialog dialog(qApp->activeWindow());
+ int res = dialog.exec();
+ if (dialog.neverAsk()) {
+ m_AskForNexusPW = false;
+ }
+ if (res == QDialog::Accepted) {
+ username = dialog.username();
+ password = dialog.password();
+ if (dialog.store()) {
+ m_Settings.setNexusLogin(username, password);
}
+ return true;
+ } else {
+ return false;
+ }
}
-void OrganizerCore::startMOUpdate() {
- if (nexusLogin()) {
- m_PostLoginTasks.append([&]() { m_Updater.startUpdate(); });
- } else {
- m_Updater.startUpdate();
- }
+void OrganizerCore::startMOUpdate()
+{
+ if (nexusLogin()) {
+ m_PostLoginTasks.append([&]() { m_Updater.startUpdate(); });
+ } else {
+ m_Updater.startUpdate();
+ }
}
-void OrganizerCore::downloadRequestedNXM(const QString& url) {
- qDebug("download requested: %s", qPrintable(url));
- if (nexusLogin()) {
- m_PendingDownloads.append(url);
- } else {
- m_DownloadManager.addNXMDownload(url);
- }
+void OrganizerCore::downloadRequestedNXM(const QString &url)
+{
+ qDebug("download requested: %s", qPrintable(url));
+ if (nexusLogin()) {
+ m_PendingDownloads.append(url);
+ } else {
+ m_DownloadManager.addNXMDownload(url);
+ }
}
-void OrganizerCore::externalMessage(const QString& message) {
- if (MOShortcut moshortcut{message}) {
- runShortcut(moshortcut);
- } else if (isNxmLink(message)) {
- MessageDialog::showMessage(tr("Download started"), qApp->activeWindow());
- downloadRequestedNXM(message);
- }
+void OrganizerCore::externalMessage(const QString &message)
+{
+ if (MOShortcut moshortcut{ message }) {
+ runShortcut(moshortcut);
+ }
+ else if (isNxmLink(message)) {
+ MessageDialog::showMessage(tr("Download started"), qApp->activeWindow());
+ downloadRequestedNXM(message);
+ }
}
-void OrganizerCore::downloadRequested(QNetworkReply* reply, int modID, const QString& fileName) {
- try {
- if (m_DownloadManager.addDownload(reply, QStringList(), fileName, modID, 0, new ModRepositoryFileInfo(modID))) {
- MessageDialog::showMessage(tr("Download started"), qApp->activeWindow());
- }
- } catch (const std::exception& e) {
- MessageDialog::showMessage(tr("Download failed"), qApp->activeWindow());
- qCritical("exception starting download: %s", e.what());
+void OrganizerCore::downloadRequested(QNetworkReply *reply, int modID,
+ const QString &fileName)
+{
+ try {
+ if (m_DownloadManager.addDownload(reply, QStringList(), fileName, modID, 0,
+ new ModRepositoryFileInfo(modID))) {
+ MessageDialog::showMessage(tr("Download started"), qApp->activeWindow());
}
+ } catch (const std::exception &e) {
+ MessageDialog::showMessage(tr("Download failed"), qApp->activeWindow());
+ qCritical("exception starting download: %s", e.what());
+ }
}
-void OrganizerCore::removeOrigin(const QString& name) {
- FilesOrigin& origin = m_DirectoryStructure->getOriginByName(ToWString(name));
- origin.enable(false);
- refreshLists();
+void OrganizerCore::removeOrigin(const QString &name)
+{
+ FilesOrigin &origin = m_DirectoryStructure->getOriginByName(ToWString(name));
+ origin.enable(false);
+ refreshLists();
}
-void OrganizerCore::downloadSpeed(const QString& serverName, int bytesPerSecond) {
- m_Settings.setDownloadSpeed(serverName, bytesPerSecond);
+void OrganizerCore::downloadSpeed(const QString &serverName, int bytesPerSecond)
+{
+ m_Settings.setDownloadSpeed(serverName, bytesPerSecond);
}
-InstallationManager* OrganizerCore::installationManager() { return &m_InstallationManager; }
+InstallationManager *OrganizerCore::installationManager()
+{
+ return &m_InstallationManager;
+}
-bool OrganizerCore::createDirectory(const QString& path) {
- if (!QDir(path).exists() && !QDir().mkpath(path)) {
- QMessageBox::critical(nullptr, QObject::tr("Error"),
- QObject::tr("Failed to create \"%1\". Your user "
- "account probably lacks permission.")
- .arg(QDir::toNativeSeparators(path)));
- return false;
- } else {
- return true;
- }
+bool OrganizerCore::createDirectory(const QString &path) {
+ if (!QDir(path).exists() && !QDir().mkpath(path)) {
+ QMessageBox::critical(nullptr, QObject::tr("Error"),
+ QObject::tr("Failed to create \"%1\". Your user "
+ "account probably lacks permission.")
+ .arg(QDir::toNativeSeparators(path)));
+ return false;
+ } else {
+ return true;
+ }
}
bool OrganizerCore::bootstrap() {
- return createDirectory(m_Settings.getProfileDirectory()) && createDirectory(m_Settings.getModDirectory()) &&
- createDirectory(m_Settings.getDownloadDirectory()) && createDirectory(m_Settings.getOverwriteDirectory()) &&
- createDirectory(QString::fromStdWString(crashDumpsPath())) && cycleDiagnostics();
+ return createDirectory(m_Settings.getProfileDirectory()) &&
+ createDirectory(m_Settings.getModDirectory()) &&
+ createDirectory(m_Settings.getDownloadDirectory()) &&
+ createDirectory(m_Settings.getOverwriteDirectory()) &&
+ createDirectory(QString::fromStdWString(crashDumpsPath())) && cycleDiagnostics();
}
-void OrganizerCore::createDefaultProfile() {
- QString profilesPath = settings().getProfileDirectory();
- if (QDir(profilesPath).entryList(QDir::AllDirs | QDir::NoDotAndDotDot).size() == 0) {
- Profile newProf("Default", managedGame(), false);
- }
+void OrganizerCore::createDefaultProfile()
+{
+ QString profilesPath = settings().getProfileDirectory();
+ if (QDir(profilesPath).entryList(QDir::AllDirs | QDir::NoDotAndDotDot).size()
+ == 0) {
+ Profile newProf("Default", managedGame(), false);
+ }
}
-void OrganizerCore::prepareVFS() { m_USVFS.updateMapping(fileMapping(m_CurrentProfile->name(), QString())); }
+void OrganizerCore::prepareVFS()
+{
+ m_USVFS.updateMapping(fileMapping(m_CurrentProfile->name(), QString()));
+}
void OrganizerCore::updateVFSParams(int logLevel, int crashDumpsType) {
- setGlobalCrashDumpsType(crashDumpsType);
- m_USVFS.updateParams(logLevel, crashDumpsType);
+ setGlobalCrashDumpsType(crashDumpsType);
+ m_USVFS.updateParams(logLevel, crashDumpsType);
}
bool OrganizerCore::cycleDiagnostics() {
- if (int maxDumps = settings().crashDumpsMax())
- removeOldFiles(QString::fromStdWString(crashDumpsPath()), "*.dmp", maxDumps, QDir::Time | QDir::Reversed);
- return true;
+ if (int maxDumps = settings().crashDumpsMax())
+ removeOldFiles(QString::fromStdWString(crashDumpsPath()), "*.dmp", maxDumps, QDir::Time|QDir::Reversed);
+ return true;
}
-// static
+//static
void OrganizerCore::setGlobalCrashDumpsType(int crashDumpsType) {
- m_globalCrashDumpsType = ::crashDumpsType(crashDumpsType);
+ m_globalCrashDumpsType = ::crashDumpsType(crashDumpsType);
}
-// static
+//static
std::wstring OrganizerCore::crashDumpsPath() {
- return (qApp->property("dataPath").toString() + "/" + QString::fromStdWString(AppConfig::dumpsDir()))
- .toStdWString();
+ return (
+ qApp->property("dataPath").toString() + "/"
+ + QString::fromStdWString(AppConfig::dumpsDir())
+ ).toStdWString();
}
-void OrganizerCore::setCurrentProfile(const QString& profileName) {
- if ((m_CurrentProfile != nullptr) && (profileName == m_CurrentProfile->name())) {
- return;
- }
+void OrganizerCore::setCurrentProfile(const QString &profileName)
+{
+ if ((m_CurrentProfile != nullptr)
+ && (profileName == m_CurrentProfile->name())) {
+ return;
+ }
- QDir profileBaseDir(settings().getProfileDirectory());
- QString profileDir = profileBaseDir.absoluteFilePath(profileName);
+ QDir profileBaseDir(settings().getProfileDirectory());
+ QString profileDir = profileBaseDir.absoluteFilePath(profileName);
- if (!QDir(profileDir).exists()) {
- // selected profile doesn't exist. Ensure there is at least one profile,
- // then pick any one
- createDefaultProfile();
+ if (!QDir(profileDir).exists()) {
+ // selected profile doesn't exist. Ensure there is at least one profile,
+ // then pick any one
+ createDefaultProfile();
- profileDir =
- profileBaseDir.absoluteFilePath(profileBaseDir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot).at(0));
- }
+ profileDir = profileBaseDir.absoluteFilePath(
+ profileBaseDir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot).at(0));
+ }
- Profile* newProfile = new Profile(QDir(profileDir), managedGame());
+ Profile *newProfile = new Profile(QDir(profileDir), managedGame());
- delete m_CurrentProfile;
- m_CurrentProfile = newProfile;
- m_ModList.setProfile(newProfile);
+ delete m_CurrentProfile;
+ m_CurrentProfile = newProfile;
+ m_ModList.setProfile(newProfile);
- if (m_CurrentProfile->invalidationActive(nullptr)) {
- m_CurrentProfile->activateInvalidation();
- } else {
- m_CurrentProfile->deactivateInvalidation();
- }
+ if (m_CurrentProfile->invalidationActive(nullptr)) {
+ m_CurrentProfile->activateInvalidation();
+ } else {
+ m_CurrentProfile->deactivateInvalidation();
+ }
- connect(m_CurrentProfile, SIGNAL(modStatusChanged(uint)), this, SLOT(modStatusChanged(uint)));
- refreshDirectoryStructure();
+ connect(m_CurrentProfile, SIGNAL(modStatusChanged(uint)), this,
+ SLOT(modStatusChanged(uint)));
+ refreshDirectoryStructure();
}
-MOBase::IModRepositoryBridge* OrganizerCore::createNexusBridge() const { return new NexusBridge(); }
+MOBase::IModRepositoryBridge *OrganizerCore::createNexusBridge() const
+{
+ return new NexusBridge();
+}
-QString OrganizerCore::profileName() const {
- if (m_CurrentProfile != nullptr) {
- return m_CurrentProfile->name();
- } else {
- return "";
- }
+QString OrganizerCore::profileName() const
+{
+ if (m_CurrentProfile != nullptr) {
+ return m_CurrentProfile->name();
+ } else {
+ return "";
+ }
}
-QString OrganizerCore::profilePath() const {
- if (m_CurrentProfile != nullptr) {
- return m_CurrentProfile->absolutePath();
- } else {
- return "";
- }
+QString OrganizerCore::profilePath() const
+{
+ if (m_CurrentProfile != nullptr) {
+ return m_CurrentProfile->absolutePath();
+ } else {
+ return "";
+ }
}
-QString OrganizerCore::downloadsPath() const { return QDir::fromNativeSeparators(m_Settings.getDownloadDirectory()); }
+QString OrganizerCore::downloadsPath() const
+{
+ return QDir::fromNativeSeparators(m_Settings.getDownloadDirectory());
+}
-QString OrganizerCore::overwritePath() const { return QDir::fromNativeSeparators(m_Settings.getOverwriteDirectory()); }
+QString OrganizerCore::overwritePath() const
+{
+ return QDir::fromNativeSeparators(m_Settings.getOverwriteDirectory());
+}
-QString OrganizerCore::basePath() const { return QDir::fromNativeSeparators(m_Settings.getBaseDirectory()); }
+QString OrganizerCore::basePath() const
+{
+ return QDir::fromNativeSeparators(m_Settings.getBaseDirectory());
+}
-MOBase::VersionInfo OrganizerCore::appVersion() const { return m_Updater.getVersion(); }
+MOBase::VersionInfo OrganizerCore::appVersion() const
+{
+ return m_Updater.getVersion();
+}
-MOBase::IModInterface* OrganizerCore::getMod(const QString& name) const {
- unsigned int index = ModInfo::getIndex(name);
- return index == UINT_MAX ? nullptr : ModInfo::getByIndex(index).data();
+MOBase::IModInterface *OrganizerCore::getMod(const QString &name) const
+{
+ unsigned int index = ModInfo::getIndex(name);
+ return index == UINT_MAX ? nullptr : ModInfo::getByIndex(index).data();
}
-MOBase::IModInterface* OrganizerCore::createMod(GuessedValue<QString>& name) {
- bool merge = false;
- if (!m_InstallationManager.testOverwrite(name, &merge)) {
- return nullptr;
- }
+MOBase::IModInterface *OrganizerCore::createMod(GuessedValue<QString> &name)
+{
+ bool merge = false;
+ if (!m_InstallationManager.testOverwrite(name, &merge)) {
+ return nullptr;
+ }
- m_InstallationManager.setModsDirectory(m_Settings.getModDirectory());
+ m_InstallationManager.setModsDirectory(m_Settings.getModDirectory());
- QString targetDirectory = QDir::fromNativeSeparators(m_Settings.getModDirectory()).append("/").append(name);
+ QString targetDirectory
+ = QDir::fromNativeSeparators(m_Settings.getModDirectory())
+ .append("/")
+ .append(name);
- QSettings settingsFile(targetDirectory + "/meta.ini", QSettings::IniFormat);
+ QSettings settingsFile(targetDirectory + "/meta.ini", QSettings::IniFormat);
- if (!merge) {
- settingsFile.setValue("modid", 0);
- settingsFile.setValue("version", "");
- settingsFile.setValue("newestVersion", "");
- settingsFile.setValue("category", 0);
- settingsFile.setValue("installationFile", "");
+ if (!merge) {
+ settingsFile.setValue("modid", 0);
+ settingsFile.setValue("version", "");
+ settingsFile.setValue("newestVersion", "");
+ settingsFile.setValue("category", 0);
+ settingsFile.setValue("installationFile", "");
- settingsFile.beginWriteArray("installedFiles", 0);
- settingsFile.endArray();
- }
+ settingsFile.beginWriteArray("installedFiles", 0);
+ settingsFile.endArray();
+ }
- return ModInfo::createFrom(QDir(targetDirectory), &m_DirectoryStructure).data();
+ return ModInfo::createFrom(QDir(targetDirectory), &m_DirectoryStructure)
+ .data();
}
-bool OrganizerCore::removeMod(MOBase::IModInterface* mod) {
- unsigned int index = ModInfo::getIndex(mod->name());
- if (index == UINT_MAX) {
- return mod->remove();
- } else {
- return ModInfo::removeMod(index);
- }
+bool OrganizerCore::removeMod(MOBase::IModInterface *mod)
+{
+ unsigned int index = ModInfo::getIndex(mod->name());
+ if (index == UINT_MAX) {
+ return mod->remove();
+ } else {
+ return ModInfo::removeMod(index);
+ }
}
-void OrganizerCore::modDataChanged(MOBase::IModInterface*) { refreshModList(false); }
+void OrganizerCore::modDataChanged(MOBase::IModInterface *)
+{
+ refreshModList(false);
+}
-QVariant OrganizerCore::pluginSetting(const QString& pluginName, const QString& key) const {
- return m_Settings.pluginSetting(pluginName, key);
+QVariant OrganizerCore::pluginSetting(const QString &pluginName,
+ const QString &key) const
+{
+ return m_Settings.pluginSetting(pluginName, key);
}
-void OrganizerCore::setPluginSetting(const QString& pluginName, const QString& key, const QVariant& value) {
- m_Settings.setPluginSetting(pluginName, key, value);
+void OrganizerCore::setPluginSetting(const QString &pluginName,
+ const QString &key, const QVariant &value)
+{
+ m_Settings.setPluginSetting(pluginName, key, value);
}
-QVariant OrganizerCore::persistent(const QString& pluginName, const QString& key, const QVariant& def) const {
- return m_Settings.pluginPersistent(pluginName, key, def);
+QVariant OrganizerCore::persistent(const QString &pluginName,
+ const QString &key,
+ const QVariant &def) const
+{
+ return m_Settings.pluginPersistent(pluginName, key, def);
}
-void OrganizerCore::setPersistent(const QString& pluginName, const QString& key, const QVariant& value, bool sync) {
- m_Settings.setPluginPersistent(pluginName, key, value, sync);
+void OrganizerCore::setPersistent(const QString &pluginName, const QString &key,
+ const QVariant &value, bool sync)
+{
+ m_Settings.setPluginPersistent(pluginName, key, value, sync);
}
-QString OrganizerCore::pluginDataPath() const {
- return qApp->applicationDirPath() + "/" + ToQString(AppConfig::pluginPath()) + "/data";
+QString OrganizerCore::pluginDataPath() const
+{
+ return qApp->applicationDirPath() + "/" + ToQString(AppConfig::pluginPath())
+ + "/data";
}
-MOBase::IModInterface* OrganizerCore::installMod(const QString& fileName, const QString& initModName) {
- if (m_CurrentProfile == nullptr) {
- return nullptr;
- }
+MOBase::IModInterface *OrganizerCore::installMod(const QString &fileName,
+ const QString &initModName)
+{
+ if (m_CurrentProfile == nullptr) {
+ return nullptr;
+ }
- bool hasIniTweaks = false;
- GuessedValue<QString> modName;
- if (!initModName.isEmpty()) {
- modName.update(initModName, GUESS_USER);
- }
- m_CurrentProfile->writeModlistNow();
- m_InstallationManager.setModsDirectory(m_Settings.getModDirectory());
- if (m_InstallationManager.install(fileName, modName, hasIniTweaks)) {
- MessageDialog::showMessage(tr("Installation successful"), qApp->activeWindow());
- refreshModList();
+ bool hasIniTweaks = false;
+ GuessedValue<QString> modName;
+ if (!initModName.isEmpty()) {
+ modName.update(initModName, GUESS_USER);
+ }
+ m_CurrentProfile->writeModlistNow();
+ m_InstallationManager.setModsDirectory(m_Settings.getModDirectory());
+ if (m_InstallationManager.install(fileName, modName, hasIniTweaks)) {
+ MessageDialog::showMessage(tr("Installation successful"),
+ qApp->activeWindow());
+ refreshModList();
- int modIndex = ModInfo::getIndex(modName);
- if (modIndex != UINT_MAX) {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex);
- if (hasIniTweaks && (m_UserInterface != nullptr) &&
- (QMessageBox::question(qApp->activeWindow(), tr("Configure Mod"),
- tr("This mod contains ini tweaks. Do you "
- "want to configure them now?"),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)) {
- m_UserInterface->displayModInformation(modInfo, modIndex, ModInfoDialog::TAB_INIFILES);
- }
- m_ModInstalled(modName);
- return modInfo.data();
- } else {
- reportError(tr("mod \"%1\" not found").arg(modName));
- }
- } else if (m_InstallationManager.wasCancelled()) {
- QMessageBox::information(qApp->activeWindow(), tr("Installation cancelled"),
- tr("The mod was not installed completely."), QMessageBox::Ok);
+ int modIndex = ModInfo::getIndex(modName);
+ if (modIndex != UINT_MAX) {
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex);
+ if (hasIniTweaks && (m_UserInterface != nullptr)
+ && (QMessageBox::question(qApp->activeWindow(), tr("Configure Mod"),
+ tr("This mod contains ini tweaks. Do you "
+ "want to configure them now?"),
+ QMessageBox::Yes | QMessageBox::No)
+ == QMessageBox::Yes)) {
+ m_UserInterface->displayModInformation(modInfo, modIndex,
+ ModInfoDialog::TAB_INIFILES);
+ }
+ m_ModInstalled(modName);
+ return modInfo.data();
+ } else {
+ reportError(tr("mod \"%1\" not found").arg(modName));
}
- return nullptr;
+ } else if (m_InstallationManager.wasCancelled()) {
+ QMessageBox::information(qApp->activeWindow(), tr("Installation cancelled"),
+ tr("The mod was not installed completely."),
+ QMessageBox::Ok);
+ }
+ return nullptr;
}
-void OrganizerCore::installDownload(int index) {
- try {
- QString fileName = m_DownloadManager.getFilePath(index);
- int modID = m_DownloadManager.getModID(index);
- int fileID = m_DownloadManager.getFileInfo(index)->fileID;
- GuessedValue<QString> modName;
+void OrganizerCore::installDownload(int index)
+{
+ try {
+ QString fileName = m_DownloadManager.getFilePath(index);
+ int modID = m_DownloadManager.getModID(index);
+ int fileID = m_DownloadManager.getFileInfo(index)->fileID;
+ GuessedValue<QString> modName;
- // see if there already are mods with the specified mod id
- if (modID != 0) {
- std::vector<ModInfo::Ptr> modInfo = ModInfo::getByModID(modID);
- for (auto iter = modInfo.begin(); iter != modInfo.end(); ++iter) {
- std::vector<ModInfo::EFlag> flags = (*iter)->getFlags();
- if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP) == flags.end()) {
- modName.update((*iter)->name(), GUESS_PRESET);
- (*iter)->saveMeta();
- }
- }
+ // see if there already are mods with the specified mod id
+ if (modID != 0) {
+ std::vector<ModInfo::Ptr> modInfo = ModInfo::getByModID(modID);
+ for (auto iter = modInfo.begin(); iter != modInfo.end(); ++iter) {
+ std::vector<ModInfo::EFlag> flags = (*iter)->getFlags();
+ if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP)
+ == flags.end()) {
+ modName.update((*iter)->name(), GUESS_PRESET);
+ (*iter)->saveMeta();
}
+ }
+ }
- m_CurrentProfile->writeModlistNow();
+ m_CurrentProfile->writeModlistNow();
- bool hasIniTweaks = false;
- m_InstallationManager.setModsDirectory(m_Settings.getModDirectory());
- if (m_InstallationManager.install(fileName, modName, hasIniTweaks)) {
- MessageDialog::showMessage(tr("Installation successful"), qApp->activeWindow());
- refreshModList();
+ bool hasIniTweaks = false;
+ m_InstallationManager.setModsDirectory(m_Settings.getModDirectory());
+ if (m_InstallationManager.install(fileName, modName, hasIniTweaks)) {
+ MessageDialog::showMessage(tr("Installation successful"),
+ qApp->activeWindow());
+ refreshModList();
- int modIndex = ModInfo::getIndex(modName);
- if (modIndex != UINT_MAX) {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex);
- modInfo->addInstalledFile(modID, fileID);
+ int modIndex = ModInfo::getIndex(modName);
+ if (modIndex != UINT_MAX) {
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex);
+ modInfo->addInstalledFile(modID, fileID);
- if (hasIniTweaks && m_UserInterface != nullptr &&
- (QMessageBox::question(qApp->activeWindow(), tr("Configure Mod"),
- tr("This mod contains ini tweaks. Do you "
- "want to configure them now?"),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)) {
- m_UserInterface->displayModInformation(modInfo, modIndex, ModInfoDialog::TAB_INIFILES);
- }
+ if (hasIniTweaks && m_UserInterface != nullptr
+ && (QMessageBox::question(qApp->activeWindow(), tr("Configure Mod"),
+ tr("This mod contains ini tweaks. Do you "
+ "want to configure them now?"),
+ QMessageBox::Yes | QMessageBox::No)
+ == QMessageBox::Yes)) {
+ m_UserInterface->displayModInformation(modInfo, modIndex,
+ ModInfoDialog::TAB_INIFILES);
+ }
- m_ModInstalled(modName);
- } else {
- reportError(tr("mod \"%1\" not found").arg(modName));
- }
- m_DownloadManager.markInstalled(index);
+ m_ModInstalled(modName);
+ } else {
+ reportError(tr("mod \"%1\" not found").arg(modName));
+ }
+ m_DownloadManager.markInstalled(index);
- emit modInstalled(modName);
- } else if (m_InstallationManager.wasCancelled()) {
- QMessageBox::information(qApp->activeWindow(), tr("Installation cancelled"),
- tr("The mod was not installed completely."), QMessageBox::Ok);
- }
- } catch (const std::exception& e) {
- reportError(e.what());
+ emit modInstalled(modName);
+ } else if (m_InstallationManager.wasCancelled()) {
+ QMessageBox::information(
+ qApp->activeWindow(), tr("Installation cancelled"),
+ tr("The mod was not installed completely."), QMessageBox::Ok);
}
+ } catch (const std::exception &e) {
+ reportError(e.what());
+ }
}
-QString OrganizerCore::resolvePath(const QString& fileName) const {
- if (m_DirectoryStructure == nullptr) {
- return QString();
- }
- const FileEntry::Ptr file = m_DirectoryStructure->searchFile(ToWString(fileName), nullptr);
- if (file.get() != nullptr) {
- return ToQString(file->getFullPath());
- } else {
- return QString();
- }
+QString OrganizerCore::resolvePath(const QString &fileName) const
+{
+ if (m_DirectoryStructure == nullptr) {
+ return QString();
+ }
+ const FileEntry::Ptr file
+ = m_DirectoryStructure->searchFile(ToWString(fileName), nullptr);
+ if (file.get() != nullptr) {
+ return ToQString(file->getFullPath());
+ } else {
+ return QString();
+ }
}
-QStringList OrganizerCore::listDirectories(const QString& directoryName) const {
- QStringList result;
- DirectoryEntry* dir = m_DirectoryStructure->findSubDirectoryRecursive(ToWString(directoryName));
- if (dir != nullptr) {
- std::vector<DirectoryEntry*>::iterator current, end;
- dir->getSubDirectories(current, end);
- for (; current != end; ++current) {
- result.append(ToQString((*current)->getName()));
- }
+QStringList OrganizerCore::listDirectories(const QString &directoryName) const
+{
+ QStringList result;
+ DirectoryEntry *dir = m_DirectoryStructure->findSubDirectoryRecursive(
+ ToWString(directoryName));
+ if (dir != nullptr) {
+ std::vector<DirectoryEntry *>::iterator current, end;
+ dir->getSubDirectories(current, end);
+ for (; current != end; ++current) {
+ result.append(ToQString((*current)->getName()));
}
- return result;
+ }
+ return result;
}
-QStringList OrganizerCore::findFiles(const QString& path, const std::function<bool(const QString&)>& filter) const {
- QStringList result;
- DirectoryEntry* dir = m_DirectoryStructure->findSubDirectoryRecursive(ToWString(path));
- if (dir != nullptr) {
- std::vector<FileEntry::Ptr> files = dir->getFiles();
- foreach (FileEntry::Ptr file, files) {
- if (filter(ToQString(file->getFullPath()))) {
- result.append(ToQString(file->getFullPath()));
- }
- }
- } else {
- qWarning("directory %s not found", qPrintable(path));
+QStringList OrganizerCore::findFiles(
+ const QString &path,
+ const std::function<bool(const QString &)> &filter) const
+{
+ QStringList result;
+ DirectoryEntry *dir
+ = m_DirectoryStructure->findSubDirectoryRecursive(ToWString(path));
+ if (dir != nullptr) {
+ std::vector<FileEntry::Ptr> files = dir->getFiles();
+ foreach (FileEntry::Ptr file, files) {
+ if (filter(ToQString(file->getFullPath()))) {
+ result.append(ToQString(file->getFullPath()));
+ }
}
- return result;
+ } else {
+ qWarning("directory %s not found", qPrintable(path));
+ }
+ return result;
}
-QStringList OrganizerCore::getFileOrigins(const QString& fileName) const {
- QStringList result;
- const FileEntry::Ptr file = m_DirectoryStructure->searchFile(ToWString(QFileInfo(fileName).fileName()), nullptr);
+QStringList OrganizerCore::getFileOrigins(const QString &fileName) const
+{
+ QStringList result;
+ const FileEntry::Ptr file = m_DirectoryStructure->searchFile(
+ ToWString(QFileInfo(fileName).fileName()), nullptr);
- if (file.get() != nullptr) {
- result.append(ToQString(m_DirectoryStructure->getOriginByID(file->getOrigin()).getName()));
- foreach (auto i, file->getAlternatives()) {
- result.append(ToQString(m_DirectoryStructure->getOriginByID(i.first).getName()));
- }
- } else {
- qDebug("%s not found", qPrintable(fileName));
+ if (file.get() != nullptr) {
+ result.append(ToQString(
+ m_DirectoryStructure->getOriginByID(file->getOrigin()).getName()));
+ foreach (auto i, file->getAlternatives()) {
+ result.append(
+ ToQString(m_DirectoryStructure->getOriginByID(i.first).getName()));
}
- return result;
+ } else {
+ qDebug("%s not found", qPrintable(fileName));
+ }
+ return result;
}
-QList<MOBase::IOrganizer::FileInfo>
-OrganizerCore::findFileInfos(const QString& path,
- const std::function<bool(const MOBase::IOrganizer::FileInfo&)>& filter) const {
- QList<IOrganizer::FileInfo> result;
- DirectoryEntry* dir = m_DirectoryStructure->findSubDirectoryRecursive(ToWString(path));
- if (dir != nullptr) {
- std::vector<FileEntry::Ptr> files = dir->getFiles();
- foreach (FileEntry::Ptr file, files) {
- IOrganizer::FileInfo info;
- info.filePath = ToQString(file->getFullPath());
- bool fromArchive = false;
- info.origins.append(ToQString(m_DirectoryStructure->getOriginByID(file->getOrigin(fromArchive)).getName()));
- info.archive = fromArchive ? ToQString(file->getArchive()) : "";
- foreach (auto idx, file->getAlternatives()) {
- info.origins.append(ToQString(m_DirectoryStructure->getOriginByID(idx.first).getName()));
- }
+QList<MOBase::IOrganizer::FileInfo> OrganizerCore::findFileInfos(
+ const QString &path,
+ const std::function<bool(const MOBase::IOrganizer::FileInfo &)> &filter)
+ const
+{
+ QList<IOrganizer::FileInfo> result;
+ DirectoryEntry *dir
+ = m_DirectoryStructure->findSubDirectoryRecursive(ToWString(path));
+ if (dir != nullptr) {
+ std::vector<FileEntry::Ptr> files = dir->getFiles();
+ foreach (FileEntry::Ptr file, files) {
+ IOrganizer::FileInfo info;
+ info.filePath = ToQString(file->getFullPath());
+ bool fromArchive = false;
+ info.origins.append(ToQString(
+ m_DirectoryStructure->getOriginByID(file->getOrigin(fromArchive))
+ .getName()));
+ info.archive = fromArchive ? ToQString(file->getArchive()) : "";
+ foreach (auto idx, file->getAlternatives()) {
+ info.origins.append(
+ ToQString(m_DirectoryStructure->getOriginByID(idx.first).getName()));
+ }
- if (filter(info)) {
- result.append(info);
- }
- }
+ if (filter(info)) {
+ result.append(info);
+ }
}
- return result;
+ }
+ return result;
}
-DownloadManager* OrganizerCore::downloadManager() { return &m_DownloadManager; }
+DownloadManager *OrganizerCore::downloadManager()
+{
+ return &m_DownloadManager;
+}
-PluginList* OrganizerCore::pluginList() { return &m_PluginList; }
+PluginList *OrganizerCore::pluginList()
+{
+ return &m_PluginList;
+}
-ModList* OrganizerCore::modList() { return &m_ModList; }
+ModList *OrganizerCore::modList()
+{
+ return &m_ModList;
+}
-QStringList OrganizerCore::modsSortedByProfilePriority() const {
- QStringList res;
- for (unsigned int i = 0; i < currentProfile()->numRegularMods(); ++i) {
- int modIndex = currentProfile()->modIndexByPriority(i);
- res.push_back(ModInfo::getByIndex(modIndex)->name());
- }
- return res;
+QStringList OrganizerCore::modsSortedByProfilePriority() const
+{
+ QStringList res;
+ for (unsigned int i = 0; i < currentProfile()->numRegularMods(); ++i) {
+ int modIndex = currentProfile()->modIndexByPriority(i);
+ res.push_back(ModInfo::getByIndex(modIndex)->name());
+ }
+ return res;
}
-void OrganizerCore::spawnBinary(const QFileInfo& binary, const QString& arguments, const QDir& currentDirectory,
- const QString& steamAppID, const QString& customOverwrite) {
- DWORD processExitCode = 0;
- HANDLE processHandle = spawnBinaryDirect(binary, arguments, m_CurrentProfile->name(), currentDirectory, steamAppID,
- customOverwrite, &processExitCode);
- if (processHandle != INVALID_HANDLE_VALUE) {
- refreshDirectoryStructure();
- // need to remove our stored load order because it may be outdated if a foreign tool changed the
- // file time. After removing that file, refreshESPList will use the file time as the order
- if (managedGame()->loadOrderMechanism() == IPluginGame::LoadOrderMechanism::FileTime) {
- qDebug("removing loadorder.txt");
- QFile::remove(m_CurrentProfile->getLoadOrderFileName());
- }
- refreshDirectoryStructure();
+void OrganizerCore::spawnBinary(const QFileInfo &binary, const QString &arguments, const QDir &currentDirectory, const QString &steamAppID, const QString &customOverwrite)
+{
+ DWORD processExitCode = 0;
+ HANDLE processHandle = spawnBinaryDirect(binary, arguments, m_CurrentProfile->name(), currentDirectory, steamAppID, customOverwrite, &processExitCode);
+ if (processHandle != INVALID_HANDLE_VALUE) {
+ refreshDirectoryStructure();
+ // need to remove our stored load order because it may be outdated if a foreign tool changed the
+ // file time. After removing that file, refreshESPList will use the file time as the order
+ if (managedGame()->loadOrderMechanism() == IPluginGame::LoadOrderMechanism::FileTime) {
+ qDebug("removing loadorder.txt");
+ QFile::remove(m_CurrentProfile->getLoadOrderFileName());
+ }
+ refreshDirectoryStructure();
- refreshESPList();
- savePluginList();
+ refreshESPList();
+ savePluginList();
- // These callbacks should not fiddle with directoy structure and ESPs.
- m_FinishedRun(binary.absoluteFilePath(), processExitCode);
- }
+ //These callbacks should not fiddle with directoy structure and ESPs.
+ m_FinishedRun(binary.absoluteFilePath(), processExitCode);
+ }
}
-HANDLE OrganizerCore::spawnBinaryDirect(const QFileInfo& binary, const QString& arguments, const QString& profileName,
- const QDir& currentDirectory, const QString& steamAppID,
- const QString& customOverwrite, LPDWORD exitCode) {
- HANDLE processHandle =
- spawnBinaryProcess(binary, arguments, profileName, currentDirectory, steamAppID, customOverwrite);
- if (processHandle != INVALID_HANDLE_VALUE) {
- std::unique_ptr<LockedDialog> dlg;
- ILockedWaitingForProcess* uilock = nullptr;
+HANDLE OrganizerCore::spawnBinaryDirect(const QFileInfo &binary,
+ const QString &arguments,
+ const QString &profileName,
+ const QDir &currentDirectory,
+ const QString &steamAppID,
+ const QString &customOverwrite,
+ LPDWORD exitCode)
+{
+ HANDLE processHandle = spawnBinaryProcess(binary, arguments, profileName, currentDirectory, steamAppID, customOverwrite);
+ if (processHandle != INVALID_HANDLE_VALUE) {
+ std::unique_ptr<LockedDialog> dlg;
+ ILockedWaitingForProcess* uilock = nullptr;
- if (m_UserInterface != nullptr) {
- uilock = m_UserInterface->lock();
- } else {
- // i.e. when running command line shortcuts there is no m_UserInterface
- dlg.reset(new LockedDialog);
- dlg->show();
- dlg->setEnabled(true);
- uilock = dlg.get();
- }
+ if (m_UserInterface != nullptr) {
+ uilock = m_UserInterface->lock();
+ }
+ else {
+ // i.e. when running command line shortcuts there is no m_UserInterface
+ dlg.reset(new LockedDialog);
+ dlg->show();
+ dlg->setEnabled(true);
+ uilock = dlg.get();
+ }
- ON_BLOCK_EXIT([&]() {
- if (m_UserInterface != nullptr) {
- m_UserInterface->unlock();
- }
- });
+ ON_BLOCK_EXIT([&]() {
+ if (m_UserInterface != nullptr) {
+ m_UserInterface->unlock();
+ } });
- DWORD ignoreExitCode;
- waitForProcessCompletion(processHandle, exitCode ? exitCode : &ignoreExitCode, uilock);
- cycleDiagnostics();
- }
+ DWORD ignoreExitCode;
+ waitForProcessCompletion(processHandle, exitCode ? exitCode : &ignoreExitCode, uilock);
+ cycleDiagnostics();
+ }
- return processHandle;
+ return processHandle;
}
-HANDLE OrganizerCore::spawnBinaryProcess(const QFileInfo& binary, const QString& arguments, const QString& profileName,
- const QDir& currentDirectory, const QString& steamAppID,
- const QString& customOverwrite) {
- prepareStart();
- if (!binary.exists()) {
- reportError(tr("Executable \"%1\" not found").arg(binary.absoluteFilePath()));
- return INVALID_HANDLE_VALUE;
- }
+HANDLE OrganizerCore::spawnBinaryProcess(const QFileInfo &binary,
+ const QString &arguments,
+ const QString &profileName,
+ const QDir &currentDirectory,
+ const QString &steamAppID,
+ const QString &customOverwrite)
+{
+ prepareStart();
- if (!steamAppID.isEmpty()) {
- ::SetEnvironmentVariableW(L"SteamAPPId", ToWString(steamAppID).c_str());
- } else {
- ::SetEnvironmentVariableW(L"SteamAPPId", ToWString(m_Settings.getSteamAppID()).c_str());
- }
+ if (!binary.exists()) {
+ reportError(
+ tr("Executable \"%1\" not found").arg(binary.absoluteFilePath()));
+ return INVALID_HANDLE_VALUE;
+ }
- // This could possibly be extracted somewhere else but it's probably for when
- // we have more than one provider of game registration.
- if ((QFileInfo(managedGame()->gameDirectory().absoluteFilePath("steam_api.dll")).exists() ||
- QFileInfo(managedGame()->gameDirectory().absoluteFilePath("steam_api64.dll")).exists()) &&
- (m_Settings.getLoadMechanism() == LoadMechanism::LOAD_MODORGANIZER)) {
- if (!testForSteam()) {
- QWidget* window = qApp->activeWindow();
- if ((window != nullptr) && (!window->isVisible())) {
- window = nullptr;
- }
- if (QuestionBoxMemory::query(window, "steamQuery", binary.fileName(), tr("Start Steam?"),
- tr("Steam is required to be running already to correctly start the game. "
- "Should MO try to start steam now?"),
- QDialogButtonBox::Yes | QDialogButtonBox::No) == QDialogButtonBox::Yes) {
- startSteam(qApp->activeWindow());
- }
- }
- }
+ if (!steamAppID.isEmpty()) {
+ ::SetEnvironmentVariableW(L"SteamAPPId", ToWString(steamAppID).c_str());
+ } else {
+ ::SetEnvironmentVariableW(L"SteamAPPId",
+ ToWString(m_Settings.getSteamAppID()).c_str());
+ }
- while (m_DirectoryUpdate) {
- ::Sleep(100);
- QCoreApplication::processEvents();
+ // This could possibly be extracted somewhere else but it's probably for when
+ // we have more than one provider of game registration.
+ if ((QFileInfo(
+ managedGame()->gameDirectory().absoluteFilePath("steam_api.dll"))
+ .exists()
+ || QFileInfo(managedGame()->gameDirectory().absoluteFilePath(
+ "steam_api64.dll"))
+ .exists())
+ && (m_Settings.getLoadMechanism() == LoadMechanism::LOAD_MODORGANIZER)) {
+ if (!testForSteam()) {
+ QWidget *window = qApp->activeWindow();
+ if ((window != nullptr) && (!window->isVisible())) {
+ window = nullptr;
+ }
+ if (QuestionBoxMemory::query(window, "steamQuery", binary.fileName(),
+ tr("Start Steam?"),
+ tr("Steam is required to be running already to correctly start the game. "
+ "Should MO try to start steam now?"),
+ QDialogButtonBox::Yes | QDialogButtonBox::No) == QDialogButtonBox::Yes) {
+ startSteam(qApp->activeWindow());
+ }
}
+ }
- // need to make sure all data is saved before we start the application
- if (m_CurrentProfile != nullptr) {
- m_CurrentProfile->writeModlistNow(true);
- }
+ while (m_DirectoryUpdate) {
+ ::Sleep(100);
+ QCoreApplication::processEvents();
+ }
- // TODO: should also pass arguments
- if (m_AboutToRun(binary.absoluteFilePath())) {
- try {
- m_USVFS.updateMapping(fileMapping(profileName, customOverwrite));
- } catch (const std::exception& e) {
- QMessageBox::warning(qApp->activeWindow(), tr("Error"), e.what());
- return INVALID_HANDLE_VALUE;
- }
+ // need to make sure all data is saved before we start the application
+ if (m_CurrentProfile != nullptr) {
+ m_CurrentProfile->writeModlistNow(true);
+ }
+
+ // TODO: should also pass arguments
+ if (m_AboutToRun(binary.absoluteFilePath())) {
+ try {
+ m_USVFS.updateMapping(fileMapping(profileName, customOverwrite));
+ } catch (const std::exception &e) {
+ QMessageBox::warning(qApp->activeWindow(), tr("Error"), e.what());
+ return INVALID_HANDLE_VALUE;
+ }
- QString modsPath = settings().getModDirectory();
+ QString modsPath = settings().getModDirectory();
- // Check if this a request with either an executable or a working directory under our mods folder
- // then will start the processs in a virtualized "environment" with the appropriate paths fixed:
- // (i.e. mods\FNIS\path\exe => game\data\path\exe)
- QString cwdPath = currentDirectory.absolutePath();
- bool virtualizedCwd = cwdPath.startsWith(modsPath, Qt::CaseInsensitive);
- QString binPath = binary.absoluteFilePath();
- bool virtualizedBin = binPath.startsWith(modsPath, Qt::CaseInsensitive);
- if (virtualizedCwd || virtualizedBin) {
- if (virtualizedCwd) {
- int cwdOffset = cwdPath.indexOf('/', modsPath.length() + 1);
- cwdPath = m_GamePlugin->dataDirectory().absolutePath() + cwdPath.mid(cwdOffset, -1);
- }
+ // Check if this a request with either an executable or a working directory under our mods folder
+ // then will start the processs in a virtualized "environment" with the appropriate paths fixed:
+ // (i.e. mods\FNIS\path\exe => game\data\path\exe)
+ QString cwdPath = currentDirectory.absolutePath();
+ bool virtualizedCwd = cwdPath.startsWith(modsPath, Qt::CaseInsensitive);
+ QString binPath = binary.absoluteFilePath();
+ bool virtualizedBin = binPath.startsWith(modsPath, Qt::CaseInsensitive);
+ if (virtualizedCwd || virtualizedBin) {
+ if (virtualizedCwd) {
+ int cwdOffset = cwdPath.indexOf('/', modsPath.length() + 1);
+ cwdPath = m_GamePlugin->dataDirectory().absolutePath() + cwdPath.mid(cwdOffset, -1);
+ }
- if (virtualizedBin) {
- int binOffset = binPath.indexOf('/', modsPath.length() + 1);
- binPath = m_GamePlugin->dataDirectory().absolutePath() + binPath.mid(binOffset, -1);
- }
+ if (virtualizedBin) {
+ int binOffset = binPath.indexOf('/', modsPath.length() + 1);
+ binPath = m_GamePlugin->dataDirectory().absolutePath() + binPath.mid(binOffset, -1);
+ }
- QString cmdline = QString("launch \"%1\" \"%2\" %3")
- .arg(QDir::toNativeSeparators(cwdPath), QDir::toNativeSeparators(binPath), arguments);
+ QString cmdline
+ = QString("launch \"%1\" \"%2\" %3")
+ .arg(QDir::toNativeSeparators(cwdPath),
+ QDir::toNativeSeparators(binPath), arguments);
- qDebug() << "Spawning proxyed process <" << cmdline << ">";
+ qDebug() << "Spawning proxyed process <" << cmdline << ">";
- return startBinary(QFileInfo(QCoreApplication::applicationFilePath()), cmdline,
- QCoreApplication::applicationDirPath(), true);
- } else {
- qDebug() << "Spawning direct process <" << binPath << "," << arguments << "," << cwdPath << ">";
- return startBinary(binary, arguments, currentDirectory, true);
- }
+ return startBinary(QFileInfo(QCoreApplication::applicationFilePath()),
+ cmdline, QCoreApplication::applicationDirPath(), true);
} else {
- qDebug("start of \"%s\" canceled by plugin", qPrintable(binary.absoluteFilePath()));
- return INVALID_HANDLE_VALUE;
+ qDebug() << "Spawning direct process <" << binPath << "," << arguments << "," << cwdPath << ">";
+ return startBinary(binary, arguments, currentDirectory, true);
}
+ } else {
+ qDebug("start of \"%s\" canceled by plugin",
+ qPrintable(binary.absoluteFilePath()));
+ return INVALID_HANDLE_VALUE;
+ }
}
-HANDLE OrganizerCore::runShortcut(const MOShortcut& shortcut) {
- if (shortcut.hasInstance() && shortcut.instance() != InstanceManager::instance().currentInstance())
- throw std::runtime_error(QString("Refusing to run executable from different instance %1:%2")
- .arg(shortcut.instance(), shortcut.executable())
- .toLocal8Bit()
- .constData());
+HANDLE OrganizerCore::runShortcut(const MOShortcut& shortcut)
+{
+ if (shortcut.hasInstance() && shortcut.instance() != InstanceManager::instance().currentInstance())
+ throw std::runtime_error(
+ QString("Refusing to run executable from different instance %1:%2")
+ .arg(shortcut.instance(),shortcut.executable())
+ .toLocal8Bit().constData());
- Executable& exe = m_ExecutablesList.find(shortcut.executable());
+ Executable& exe = m_ExecutablesList.find(shortcut.executable());
- return spawnBinaryDirect(exe.m_BinaryInfo, exe.m_Arguments, m_CurrentProfile->name(),
- exe.m_WorkingDirectory.length() != 0 ? exe.m_WorkingDirectory
- : exe.m_BinaryInfo.absolutePath(),
- exe.m_SteamAppID, "");
+ return spawnBinaryDirect(
+ exe.m_BinaryInfo, exe.m_Arguments,
+ m_CurrentProfile->name(),
+ exe.m_WorkingDirectory.length() != 0
+ ? exe.m_WorkingDirectory
+ : exe.m_BinaryInfo.absolutePath(),
+ exe.m_SteamAppID, "");
}
-HANDLE OrganizerCore::startApplication(const QString& executable, const QStringList& args, const QString& cwd,
- const QString& profile) {
- QFileInfo binary;
- QString arguments = args.join(" ");
- QString currentDirectory = cwd;
- QString profileName = profile;
- if (profile.length() == 0) {
- if (m_CurrentProfile != nullptr) {
- profileName = m_CurrentProfile->name();
- } else {
- throw MyException(tr("No profile set"));
- }
+HANDLE OrganizerCore::startApplication(const QString &executable,
+ const QStringList &args,
+ const QString &cwd,
+ const QString &profile)
+{
+ QFileInfo binary;
+ QString arguments = args.join(" ");
+ QString currentDirectory = cwd;
+ QString profileName = profile;
+ if (profile.length() == 0) {
+ if (m_CurrentProfile != nullptr) {
+ profileName = m_CurrentProfile->name();
+ } else {
+ throw MyException(tr("No profile set"));
}
- QString steamAppID;
- QString customOverwrite;
- if (executable.contains('\\') || executable.contains('/')) {
- // file path
+ }
+ QString steamAppID;
+ QString customOverwrite;
+ if (executable.contains('\\') || executable.contains('/')) {
+ // file path
- binary = QFileInfo(executable);
- if (binary.isRelative()) {
- // relative path, should be relative to game directory
- binary = QFileInfo(managedGame()->gameDirectory().absoluteFilePath(executable));
- }
- if (cwd.length() == 0) {
- currentDirectory = binary.absolutePath();
- }
- try {
- const Executable& exe = m_ExecutablesList.findByBinary(binary);
- steamAppID = exe.m_SteamAppID;
- customOverwrite = m_CurrentProfile->setting("custom_overwrites", exe.m_Title).toString();
- } catch (const std::runtime_error&) {
- // nop
- }
- } else {
- // only a file name, search executables list
- try {
- const Executable& exe = m_ExecutablesList.find(executable);
- steamAppID = exe.m_SteamAppID;
- customOverwrite = m_CurrentProfile->setting("custom_overwrites", exe.m_Title).toString();
- if (arguments == "") {
- arguments = exe.m_Arguments;
- }
- binary = exe.m_BinaryInfo;
- if (cwd.length() == 0) {
- currentDirectory = exe.m_WorkingDirectory;
- }
- } catch (const std::runtime_error&) {
- qWarning("\"%s\" not set up as executable", executable.toUtf8().constData());
- binary = QFileInfo(executable);
- }
+ binary = QFileInfo(executable);
+ if (binary.isRelative()) {
+ // relative path, should be relative to game directory
+ binary = QFileInfo(
+ managedGame()->gameDirectory().absoluteFilePath(executable));
}
+ if (cwd.length() == 0) {
+ currentDirectory = binary.absolutePath();
+ }
+ try {
+ const Executable &exe = m_ExecutablesList.findByBinary(binary);
+ steamAppID = exe.m_SteamAppID;
+ customOverwrite
+ = m_CurrentProfile->setting("custom_overwrites", exe.m_Title)
+ .toString();
+ } catch (const std::runtime_error &) {
+ // nop
+ }
+ } else {
+ // only a file name, search executables list
+ try {
+ const Executable &exe = m_ExecutablesList.find(executable);
+ steamAppID = exe.m_SteamAppID;
+ customOverwrite
+ = m_CurrentProfile->setting("custom_overwrites", exe.m_Title)
+ .toString();
+ if (arguments == "") {
+ arguments = exe.m_Arguments;
+ }
+ binary = exe.m_BinaryInfo;
+ if (cwd.length() == 0) {
+ currentDirectory = exe.m_WorkingDirectory;
+ }
+ } catch (const std::runtime_error &) {
+ qWarning("\"%s\" not set up as executable",
+ executable.toUtf8().constData());
+ binary = QFileInfo(executable);
+ }
+ }
- return spawnBinaryDirect(binary, arguments, profileName, currentDirectory, steamAppID, customOverwrite);
+ return spawnBinaryDirect(binary, arguments, profileName, currentDirectory, steamAppID, customOverwrite);
}
-bool OrganizerCore::waitForApplication(HANDLE handle, LPDWORD exitCode) {
- ILockedWaitingForProcess* uilock = nullptr;
- if (m_UserInterface != nullptr) {
- uilock = m_UserInterface->lock();
- }
+bool OrganizerCore::waitForApplication(HANDLE handle, LPDWORD exitCode)
+{
+ ILockedWaitingForProcess* uilock = nullptr;
+ if (m_UserInterface != nullptr) {
+ uilock = m_UserInterface->lock();
+ }
- ON_BLOCK_EXIT([&]() {
- if (m_UserInterface != nullptr) {
- m_UserInterface->unlock();
- }
- });
- return waitForProcessCompletion(handle, exitCode, uilock);
+ ON_BLOCK_EXIT([&] () {
+ if (m_UserInterface != nullptr) {
+ m_UserInterface->unlock();
+ } });
+ return waitForProcessCompletion(handle, exitCode, uilock);
}
-bool OrganizerCore::waitForProcessCompletion(HANDLE handle, LPDWORD exitCode, ILockedWaitingForProcess* uilock) {
- bool originalHandle = true;
- bool newHandle = true;
- bool uiunlocked = false;
+bool OrganizerCore::waitForProcessCompletion(HANDLE handle, LPDWORD exitCode, ILockedWaitingForProcess* uilock)
+{
+ bool originalHandle = true;
+ bool newHandle = true;
+ bool uiunlocked = false;
- DWORD currentPID = 0;
- QString processName;
- auto waitForChildUntil = GetTickCount64();
- if (handle != INVALID_HANDLE_VALUE) {
- currentPID = GetProcessId(handle);
- processName = QString::fromStdWString(getProcessName(handle));
- }
+ DWORD currentPID = 0;
+ QString processName;
+ auto waitForChildUntil = GetTickCount64();
+ if (handle != INVALID_HANDLE_VALUE) {
+ currentPID = GetProcessId(handle);
+ processName = QString::fromStdWString(getProcessName(handle));
+ }
- // Certain process names we wish to "hide" for aesthetic reason:
- bool waitingOnHidden = false;
- std::vector<QString> hiddenList;
- hiddenList.push_back(QFileInfo(QCoreApplication::applicationFilePath()).fileName());
- for (QString hide : hiddenList)
- if (processName.contains(hide, Qt::CaseInsensitive))
- waitingOnHidden = true;
- // The main reason for adding the hidden list is to hide the MO proxy we use to spawn virtualized processes.
- // On the one hand we want to display the real executable without it feeling laggy, on the other we don't want
- // to requery processes all the time if for some reason we are waiting on hidden processes and find no "unhidden"
- // process. For this reason we use exponential backoff and also start with a delibrately low value to improve
- // the responsiveness of the initial update
- DWORD64 nextHiddenCheck = GetTickCount64();
- DWORD64 nextHiddenCheckDelay = 50;
+ // Certain process names we wish to "hide" for aesthetic reason:
+ bool waitingOnHidden = false;
+ std::vector<QString> hiddenList;
+ hiddenList.push_back(QFileInfo(QCoreApplication::applicationFilePath()).fileName());
+ for (QString hide : hiddenList)
+ if (processName.contains(hide, Qt::CaseInsensitive))
+ waitingOnHidden = true;
+ // The main reason for adding the hidden list is to hide the MO proxy we use to spawn virtualized processes.
+ // On the one hand we want to display the real executable without it feeling laggy, on the other we don't want
+ // to requery processes all the time if for some reason we are waiting on hidden processes and find no "unhidden"
+ // process. For this reason we use exponential backoff and also start with a delibrately low value to improve
+ // the responsiveness of the initial update
+ DWORD64 nextHiddenCheck = GetTickCount64();
+ DWORD64 nextHiddenCheckDelay = 50;
- constexpr DWORD INPUT_EVENT = WAIT_OBJECT_0 + 1;
- DWORD res = WAIT_TIMEOUT;
- while (handle != INVALID_HANDLE_VALUE && (newHandle || res == WAIT_TIMEOUT || res == INPUT_EVENT)) {
- if (newHandle) {
- processName += QString(" (%1)").arg(currentPID);
- if (uilock)
- uilock->setProcessName(processName);
- qDebug() << "Waiting for" << (originalHandle ? "spawned" : "usvfs")
- << "process completion :" << processName.toUtf8().constData();
- newHandle = false;
- }
+ constexpr DWORD INPUT_EVENT = WAIT_OBJECT_0 + 1;
+ DWORD res = WAIT_TIMEOUT;
+ while (handle != INVALID_HANDLE_VALUE && (newHandle || res == WAIT_TIMEOUT || res == INPUT_EVENT))
+ {
+ if (newHandle) {
+ processName += QString(" (%1)").arg(currentPID);
+ if (uilock)
+ uilock->setProcessName(processName);
+ qDebug() << "Waiting for"
+ << (originalHandle ? "spawned" : "usvfs")
+ << "process completion :" << processName.toUtf8().constData();
+ newHandle = false;
+ }
- // Wait for a an event on the handle, a key press, mouse click or timeout
- res = MsgWaitForMultipleObjects(1, &handle, FALSE, 200, QS_KEY | QS_MOUSEBUTTON);
- if (res == WAIT_FAILED) {
- qWarning() << "Failed waiting for process completion : MsgWaitForMultipleObjects WAIT_FAILED"
- << GetLastError();
- break;
- }
+ // Wait for a an event on the handle, a key press, mouse click or timeout
+ res = MsgWaitForMultipleObjects(1, &handle, FALSE, 200, QS_KEY | QS_MOUSEBUTTON);
+ if (res == WAIT_FAILED) {
+ qWarning() << "Failed waiting for process completion : MsgWaitForMultipleObjects WAIT_FAILED" << GetLastError();
+ break;
+ }
- // keep processing events so the app doesn't appear dead
- QCoreApplication::sendPostedEvents();
- QCoreApplication::processEvents();
+ // keep processing events so the app doesn't appear dead
+ QCoreApplication::sendPostedEvents();
+ QCoreApplication::processEvents();
- if (uilock && uilock->unlockForced()) {
- uiunlocked = true;
- break;
- }
+ if (uilock && uilock->unlockForced()) {
+ uiunlocked = true;
+ break;
+ }
- if (res == WAIT_OBJECT_0) {
- // process we were waiting on has completed
- if (originalHandle && exitCode && !::GetExitCodeProcess(handle, exitCode))
- qWarning() << "Failed getting exit code of complete process :" << GetLastError();
- CloseHandle(handle);
- handle = INVALID_HANDLE_VALUE;
- originalHandle = false;
- // if the previous process spawned a child process and immediately exits we may miss it if we check
- // immediately
- waitForChildUntil = GetTickCount64() + 800;
- }
+ if (res == WAIT_OBJECT_0) {
+ // process we were waiting on has completed
+ if (originalHandle && exitCode && !::GetExitCodeProcess(handle, exitCode))
+ qWarning() << "Failed getting exit code of complete process :" << GetLastError();
+ CloseHandle(handle);
+ handle = INVALID_HANDLE_VALUE;
+ originalHandle = false;
+ // if the previous process spawned a child process and immediately exits we may miss it if we check immediately
+ waitForChildUntil = GetTickCount64() + 800;
+ }
- // search for another process to wait on if either:
- // 1. we just completed waiting for a process and need to find/wait for an inject child
- // 2. we are currently waiting on a hidden process so periodically check if there is a non-hidden process to
- // wait on
- bool firstIteration = true;
- while ((handle == INVALID_HANDLE_VALUE && GetTickCount64() <= waitForChildUntil) ||
- (waitingOnHidden && GetTickCount64() >= nextHiddenCheck)) {
- if (firstIteration)
- firstIteration = false;
- else {
- QThread::msleep(200);
- QCoreApplication::sendPostedEvents();
- QCoreApplication::processEvents();
- }
+ // search for another process to wait on if either:
+ // 1. we just completed waiting for a process and need to find/wait for an inject child
+ // 2. we are currently waiting on a hidden process so periodically check if there is a non-hidden process to wait on
+ bool firstIteration = true;
+ while ((handle == INVALID_HANDLE_VALUE && GetTickCount64() <= waitForChildUntil)
+ || (waitingOnHidden && GetTickCount64() >= nextHiddenCheck))
+ {
+ if (firstIteration)
+ firstIteration = false;
+ else {
+ QThread::msleep(200);
+ QCoreApplication::sendPostedEvents();
+ QCoreApplication::processEvents();
+ }
- // search if there is another usvfs process active
- handle = findAndOpenAUSVFSProcess(hiddenList, currentPID);
- waitingOnHidden = false;
- newHandle = handle != INVALID_HANDLE_VALUE;
- if (newHandle) {
- currentPID = GetProcessId(handle);
- processName = QString::fromStdWString(getProcessName(handle));
- for (QString hide : hiddenList)
- if (processName.contains(hide, Qt::CaseInsensitive))
- waitingOnHidden = true;
- }
- if (waitingOnHidden) {
- nextHiddenCheck = GetTickCount64() + nextHiddenCheckDelay;
- nextHiddenCheckDelay = std::min(nextHiddenCheckDelay * 2, (DWORD64)2000);
- } else {
- nextHiddenCheck = GetTickCount64();
- nextHiddenCheckDelay = 200;
- }
- }
+ // search if there is another usvfs process active
+ handle = findAndOpenAUSVFSProcess(hiddenList, currentPID);
+ waitingOnHidden = false;
+ newHandle = handle != INVALID_HANDLE_VALUE;
+ if (newHandle) {
+ currentPID = GetProcessId(handle);
+ processName = QString::fromStdWString(getProcessName(handle));
+ for (QString hide : hiddenList)
+ if (processName.contains(hide, Qt::CaseInsensitive))
+ waitingOnHidden = true;
+ }
+ if (waitingOnHidden) {
+ nextHiddenCheck = GetTickCount64() + nextHiddenCheckDelay;
+ nextHiddenCheckDelay = std::min(nextHiddenCheckDelay * 2, (DWORD64) 2000);
+ }
+ else {
+ nextHiddenCheck = GetTickCount64();
+ nextHiddenCheckDelay = 200;
+ }
}
+ }
- if (res == WAIT_OBJECT_0)
- qDebug() << "Waiting for process completion successfull";
- else if (uiunlocked)
- qDebug() << "Waiting for process completion aborted by UI";
- else
- qDebug() << "Waiting for process completion not successfull :" << res;
+ if (res == WAIT_OBJECT_0)
+ qDebug() << "Waiting for process completion successfull";
+ else if (uiunlocked)
+ qDebug() << "Waiting for process completion aborted by UI";
+ else
+ qDebug() << "Waiting for process completion not successfull :" << res;
- if (handle != INVALID_HANDLE_VALUE)
- ::CloseHandle(handle);
+ if (handle != INVALID_HANDLE_VALUE)
+ ::CloseHandle(handle);
- return res == WAIT_OBJECT_0;
+ return res == WAIT_OBJECT_0;
}
HANDLE OrganizerCore::findAndOpenAUSVFSProcess(const std::vector<QString>& hiddenList, DWORD preferedParentPid) {
- // for practical reasons a querySize of 1 is probably enough, we use a larger query as a heuristics
- // to find a more "aesthetic injected processes (attempting to comply to hiddenList and preferedParentPid)
- constexpr size_t querySize = 100;
- DWORD pids[querySize];
- size_t found = querySize;
- if (!::GetVFSProcessList(&found, pids)) {
- qWarning() << "Failed seeking USVFS processes : GetVFSProcessList failed?!";
- return INVALID_HANDLE_VALUE;
- }
-
- HANDLE best_match = INVALID_HANDLE_VALUE;
- bool best_match_hidden = true;
- for (size_t i = 0; i < found; ++i) {
- if (pids[i] == GetCurrentProcessId())
- continue; // obviously don't wait for MO process
+ // for practical reasons a querySize of 1 is probably enough, we use a larger query as a heuristics
+ // to find a more "aesthetic injected processes (attempting to comply to hiddenList and preferedParentPid)
+ constexpr size_t querySize = 100;
+ DWORD pids[querySize];
+ size_t found = querySize;
+ if (!::GetVFSProcessList(&found, pids)) {
+ qWarning() << "Failed seeking USVFS processes : GetVFSProcessList failed?!";
+ return INVALID_HANDLE_VALUE;
+ }
- HANDLE handle = ::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | SYNCHRONIZE, FALSE, pids[i]);
- if (handle == INVALID_HANDLE_VALUE) {
- qWarning() << "Failed openning USVFS process " << pids[i] << " : OpenProcess failed" << GetLastError();
- continue;
- }
+ HANDLE best_match = INVALID_HANDLE_VALUE;
+ bool best_match_hidden = true;
+ for (size_t i = 0; i < found; ++i) {
+ if (pids[i] == GetCurrentProcessId())
+ continue; // obviously don't wait for MO process
- QString pname = QString::fromStdWString(getProcessName(handle));
- bool phidden = false;
- for (auto hide : hiddenList)
- if (pname.contains(hide, Qt::CaseInsensitive))
- phidden = true;
+ HANDLE handle = ::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | SYNCHRONIZE, FALSE, pids[i]);
+ if (handle == INVALID_HANDLE_VALUE) {
+ qWarning() << "Failed openning USVFS process " << pids[i] << " : OpenProcess failed" << GetLastError();
+ continue;
+ }
- bool pprefered = preferedParentPid && getProcessParentID(pids[i]) == preferedParentPid;
+ QString pname = QString::fromStdWString(getProcessName(handle));
+ bool phidden = false;
+ for (auto hide : hiddenList)
+ if (pname.contains(hide, Qt::CaseInsensitive))
+ phidden = true;
- if (best_match == INVALID_HANDLE_VALUE || best_match_hidden || (!phidden && pprefered)) {
- if (best_match != INVALID_HANDLE_VALUE)
- CloseHandle(best_match);
- best_match = handle;
- best_match_hidden = phidden;
- } else
- CloseHandle(handle);
+ bool pprefered = preferedParentPid && getProcessParentID(pids[i]) == preferedParentPid;
- if (!phidden && pprefered)
- return best_match;
+ if (best_match == INVALID_HANDLE_VALUE || best_match_hidden || (!phidden && pprefered)) {
+ if (best_match != INVALID_HANDLE_VALUE)
+ CloseHandle(best_match);
+ best_match = handle;
+ best_match_hidden = phidden;
}
+ else
+ CloseHandle(handle);
+
+ if (!phidden && pprefered)
+ return best_match;
+ }
- return best_match;
+ return best_match;
}
-bool OrganizerCore::onAboutToRun(const std::function<bool(const QString&)>& func) {
- auto conn = m_AboutToRun.connect(func);
- return conn.connected();
+bool OrganizerCore::onAboutToRun(
+ const std::function<bool(const QString &)> &func)
+{
+ auto conn = m_AboutToRun.connect(func);
+ return conn.connected();
}
-bool OrganizerCore::onFinishedRun(const std::function<void(const QString&, unsigned int)>& func) {
- auto conn = m_FinishedRun.connect(func);
- return conn.connected();
+bool OrganizerCore::onFinishedRun(
+ const std::function<void(const QString &, unsigned int)> &func)
+{
+ auto conn = m_FinishedRun.connect(func);
+ return conn.connected();
}
-bool OrganizerCore::onModInstalled(const std::function<void(const QString&)>& func) {
- auto conn = m_ModInstalled.connect(func);
- return conn.connected();
+bool OrganizerCore::onModInstalled(
+ const std::function<void(const QString &)> &func)
+{
+ auto conn = m_ModInstalled.connect(func);
+ return conn.connected();
}
-void OrganizerCore::refreshModList(bool saveChanges) {
- // don't lose changes!
- if (saveChanges) {
- m_CurrentProfile->writeModlistNow(true);
- }
- ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, m_Settings.displayForeign(),
- managedGame());
+void OrganizerCore::refreshModList(bool saveChanges)
+{
+ // don't lose changes!
+ if (saveChanges) {
+ m_CurrentProfile->writeModlistNow(true);
+ }
+ ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure,
+ m_Settings.displayForeign(), managedGame());
- m_CurrentProfile->refreshModStatus();
+ m_CurrentProfile->refreshModStatus();
- m_ModList.notifyChange(-1);
+ m_ModList.notifyChange(-1);
- refreshDirectoryStructure();
+ refreshDirectoryStructure();
}
-void OrganizerCore::refreshESPList() {
- if (m_DirectoryUpdate) {
- // don't mess up the esp list if we're currently updating the directory
- // structure
- m_PostRefreshTasks.append([this]() { this->refreshESPList(); });
- return;
- }
- m_CurrentProfile->writeModlist();
+void OrganizerCore::refreshESPList()
+{
+ if (m_DirectoryUpdate) {
+ // don't mess up the esp list if we're currently updating the directory
+ // structure
+ m_PostRefreshTasks.append([this]() {
+ this->refreshESPList();
+ });
+ return;
+ }
+ m_CurrentProfile->writeModlist();
- // clear list
- try {
- m_PluginList.refresh(m_CurrentProfile->name(), *m_DirectoryStructure,
- m_CurrentProfile->getLockedOrderFileName());
- } catch (const std::exception& e) {
- reportError(tr("Failed to refresh list of esps: %1").arg(e.what()));
- }
+ // clear list
+ try {
+ m_PluginList.refresh(m_CurrentProfile->name(), *m_DirectoryStructure,
+ m_CurrentProfile->getLockedOrderFileName());
+ } catch (const std::exception &e) {
+ reportError(tr("Failed to refresh list of esps: %1").arg(e.what()));
+ }
}
-void OrganizerCore::refreshBSAList() {
- DataArchives* archives = m_GamePlugin->feature<DataArchives>();
-
- if (archives != nullptr) {
- m_ArchivesInit = false;
+void OrganizerCore::refreshBSAList()
+{
+ DataArchives *archives = m_GamePlugin->feature<DataArchives>();
- // default archives are the ones enabled outside MO. if the list can't be
- // found (which might
- // happen if ini files are missing) use hard-coded defaults (preferrably the
- // same the game would use)
- m_DefaultArchives = archives->archives(m_CurrentProfile);
- if (m_DefaultArchives.length() == 0) {
- m_DefaultArchives = archives->vanillaArchives();
- }
-
- m_ActiveArchives.clear();
+ if (archives != nullptr) {
+ m_ArchivesInit = false;
- auto iter = enabledArchives();
- m_ActiveArchives = toStringList(iter.begin(), iter.end());
- if (m_ActiveArchives.isEmpty()) {
- m_ActiveArchives = m_DefaultArchives;
- }
+ // default archives are the ones enabled outside MO. if the list can't be
+ // found (which might
+ // happen if ini files are missing) use hard-coded defaults (preferrably the
+ // same the game would use)
+ m_DefaultArchives = archives->archives(m_CurrentProfile);
+ if (m_DefaultArchives.length() == 0) {
+ m_DefaultArchives = archives->vanillaArchives();
+ }
- if (m_UserInterface != nullptr) {
- m_UserInterface->updateBSAList(m_DefaultArchives, m_ActiveArchives);
- }
+ m_ActiveArchives.clear();
- m_ArchivesInit = true;
+ auto iter = enabledArchives();
+ m_ActiveArchives = toStringList(iter.begin(), iter.end());
+ if (m_ActiveArchives.isEmpty()) {
+ m_ActiveArchives = m_DefaultArchives;
}
+
+ if (m_UserInterface != nullptr) {
+ m_UserInterface->updateBSAList(m_DefaultArchives, m_ActiveArchives);
+ }
+
+ m_ArchivesInit = true;
+ }
}
-void OrganizerCore::refreshLists() {
- if ((m_CurrentProfile != nullptr) && m_DirectoryStructure->isPopulated()) {
- refreshESPList();
- refreshBSAList();
- } // no point in refreshing lists if no files have been added to the directory
- // tree
+void OrganizerCore::refreshLists()
+{
+ if ((m_CurrentProfile != nullptr) && m_DirectoryStructure->isPopulated()) {
+ refreshESPList();
+ refreshBSAList();
+ } // no point in refreshing lists if no files have been added to the directory
+ // tree
}
-void OrganizerCore::updateModActiveState(int index, bool active) {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(index);
- QDir dir(modInfo->absolutePath());
- for (const QString& esm : dir.entryList(QStringList() << "*.esm", QDir::Files)) {
- m_PluginList.enableESP(esm, active);
+void OrganizerCore::updateModActiveState(int index, bool active)
+{
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(index);
+ QDir dir(modInfo->absolutePath());
+ for (const QString &esm :
+ dir.entryList(QStringList() << "*.esm", QDir::Files)) {
+ m_PluginList.enableESP(esm, active);
+ }
+ int enabled = 0;
+ for (const QString &esl :
+ dir.entryList(QStringList() << "*.esl", QDir::Files)) {
+ const FileEntry::Ptr file = m_DirectoryStructure->findFile(ToWString(esl));
+ if (file.get() == nullptr) {
+ qWarning("failed to activate %s", qPrintable(esl));
+ continue;
}
- int enabled = 0;
- for (const QString& esl : dir.entryList(QStringList() << "*.esl", QDir::Files)) {
- const FileEntry::Ptr file = m_DirectoryStructure->findFile(ToWString(esl));
- if (file.get() == nullptr) {
- qWarning("failed to activate %s", qPrintable(esl));
- continue;
- }
- if (active != m_PluginList.isEnabled(esl) && file->getAlternatives().empty()) {
- m_PluginList.enableESP(esl, active);
- ++enabled;
- }
+ if (active != m_PluginList.isEnabled(esl)
+ && file->getAlternatives().empty()) {
+ m_PluginList.enableESP(esl, active);
+ ++enabled;
}
- QStringList esps = dir.entryList(QStringList() << "*.esp", QDir::Files);
- for (const QString& esp : esps) {
- const FileEntry::Ptr file = m_DirectoryStructure->findFile(ToWString(esp));
- if (file.get() == nullptr) {
- qWarning("failed to activate %s", qPrintable(esp));
- continue;
- }
-
- if (active != m_PluginList.isEnabled(esp) && file->getAlternatives().empty()) {
- m_PluginList.enableESP(esp, active);
- ++enabled;
- }
+ }
+ QStringList esps = dir.entryList(QStringList() << "*.esp", QDir::Files);
+ for (const QString &esp : esps) {
+ const FileEntry::Ptr file = m_DirectoryStructure->findFile(ToWString(esp));
+ if (file.get() == nullptr) {
+ qWarning("failed to activate %s", qPrintable(esp));
+ continue;
}
- if (active && (enabled > 1)) {
- MessageDialog::showMessage(tr("Multiple esps/esls activated, please check that they don't conflict."),
- qApp->activeWindow());
+
+ if (active != m_PluginList.isEnabled(esp)
+ && file->getAlternatives().empty()) {
+ m_PluginList.enableESP(esp, active);
+ ++enabled;
}
- m_PluginList.refreshLoadOrder();
- // immediately save affected lists
- m_PluginListsWriter.writeImmediately(false);
+ }
+ if (active && (enabled > 1)) {
+ MessageDialog::showMessage(
+ tr("Multiple esps/esls activated, please check that they don't conflict."),
+ qApp->activeWindow());
+ }
+ m_PluginList.refreshLoadOrder();
+ // immediately save affected lists
+ m_PluginListsWriter.writeImmediately(false);
}
-void OrganizerCore::updateModInDirectoryStructure(unsigned int index, ModInfo::Ptr modInfo) {
- // add files of the bsa to the directory structure
- m_DirectoryRefresher.addModFilesToStructure(m_DirectoryStructure, modInfo->name(),
- m_CurrentProfile->getModPriority(index), modInfo->absolutePath(),
- modInfo->stealFiles());
- DirectoryRefresher::cleanStructure(m_DirectoryStructure);
- // need to refresh plugin list now so we can activate esps
- refreshESPList();
- // activate all esps of the specified mod so the bsas get activated along with
- // it
- updateModActiveState(index, true);
- // now we need to refresh the bsa list and save it so there is no confusion
- // about what archives are avaiable and active
- refreshBSAList();
- if (m_UserInterface != nullptr) {
- m_UserInterface->archivesWriter().writeImmediately(false);
- }
+void OrganizerCore::updateModInDirectoryStructure(unsigned int index,
+ ModInfo::Ptr modInfo)
+{
+ // add files of the bsa to the directory structure
+ m_DirectoryRefresher.addModFilesToStructure(
+ m_DirectoryStructure, modInfo->name(),
+ m_CurrentProfile->getModPriority(index), modInfo->absolutePath(),
+ modInfo->stealFiles());
+ DirectoryRefresher::cleanStructure(m_DirectoryStructure);
+ // need to refresh plugin list now so we can activate esps
+ refreshESPList();
+ // activate all esps of the specified mod so the bsas get activated along with
+ // it
+ updateModActiveState(index, true);
+ // now we need to refresh the bsa list and save it so there is no confusion
+ // about what archives are avaiable and active
+ refreshBSAList();
+ if (m_UserInterface != nullptr) {
+ m_UserInterface->archivesWriter().writeImmediately(false);
+ }
- std::vector<QString> archives = enabledArchives();
- m_DirectoryRefresher.setMods(m_CurrentProfile->getActiveMods(),
- std::set<QString>(archives.begin(), archives.end()));
+ std::vector<QString> archives = enabledArchives();
+ m_DirectoryRefresher.setMods(
+ m_CurrentProfile->getActiveMods(),
+ std::set<QString>(archives.begin(), archives.end()));
- // finally also add files from bsas to the directory structure
- m_DirectoryRefresher.addModBSAToStructure(m_DirectoryStructure, modInfo->name(),
- m_CurrentProfile->getModPriority(index), modInfo->absolutePath(),
- modInfo->archives());
+ // finally also add files from bsas to the directory structure
+ m_DirectoryRefresher.addModBSAToStructure(
+ m_DirectoryStructure, modInfo->name(),
+ m_CurrentProfile->getModPriority(index), modInfo->absolutePath(),
+ modInfo->archives());
}
-void OrganizerCore::requestDownload(const QUrl& url, QNetworkReply* reply) {
- if (m_PluginContainer != nullptr) {
- for (IPluginModPage* modPage : m_PluginContainer->plugins<MOBase::IPluginModPage>()) {
- ModRepositoryFileInfo* fileInfo = new ModRepositoryFileInfo();
- if (modPage->handlesDownload(url, reply->url(), *fileInfo)) {
- fileInfo->repository = modPage->name();
- m_DownloadManager.addDownload(reply, fileInfo);
- return;
- }
- }
+void OrganizerCore::requestDownload(const QUrl &url, QNetworkReply *reply)
+{
+ if (m_PluginContainer != nullptr) {
+ for (IPluginModPage *modPage :
+ m_PluginContainer->plugins<MOBase::IPluginModPage>()) {
+ ModRepositoryFileInfo *fileInfo = new ModRepositoryFileInfo();
+ if (modPage->handlesDownload(url, reply->url(), *fileInfo)) {
+ fileInfo->repository = modPage->name();
+ m_DownloadManager.addDownload(reply, fileInfo);
+ return;
+ }
}
+ }
- // no mod found that could handle the download. Is it a nexus mod?
- if (url.host() == "www.nexusmods.com") {
- int modID = 0;
- int fileID = 0;
- QRegExp modExp("mods/(\\d+)");
- if (modExp.indexIn(url.toString()) != -1) {
- modID = modExp.cap(1).toInt();
- }
- QRegExp fileExp("fid=(\\d+)");
- if (fileExp.indexIn(reply->url().toString()) != -1) {
- fileID = fileExp.cap(1).toInt();
- }
- m_DownloadManager.addDownload(reply, new ModRepositoryFileInfo(modID, fileID));
- } else {
- if (QMessageBox::question(qApp->activeWindow(), tr("Download?"),
- tr("A download has been started but no installed "
- "page plugin recognizes it.\n"
- "If you download anyway no information (i.e. "
- "version) will be associated with the "
- "download.\n"
- "Continue?"),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- m_DownloadManager.addDownload(reply, new ModRepositoryFileInfo());
- }
+ // no mod found that could handle the download. Is it a nexus mod?
+ if (url.host() == "www.nexusmods.com") {
+ int modID = 0;
+ int fileID = 0;
+ QRegExp modExp("mods/(\\d+)");
+ if (modExp.indexIn(url.toString()) != -1) {
+ modID = modExp.cap(1).toInt();
+ }
+ QRegExp fileExp("fid=(\\d+)");
+ if (fileExp.indexIn(reply->url().toString()) != -1) {
+ fileID = fileExp.cap(1).toInt();
}
+ m_DownloadManager.addDownload(reply,
+ new ModRepositoryFileInfo(modID, fileID));
+ } else {
+ if (QMessageBox::question(qApp->activeWindow(), tr("Download?"),
+ tr("A download has been started but no installed "
+ "page plugin recognizes it.\n"
+ "If you download anyway no information (i.e. "
+ "version) will be associated with the "
+ "download.\n"
+ "Continue?"),
+ QMessageBox::Yes | QMessageBox::No)
+ == QMessageBox::Yes) {
+ m_DownloadManager.addDownload(reply, new ModRepositoryFileInfo());
+ }
+ }
}
-ModListSortProxy* OrganizerCore::createModListProxyModel() {
- ModListSortProxy* result = new ModListSortProxy(m_CurrentProfile, this);
- result->setSourceModel(&m_ModList);
- return result;
+ModListSortProxy *OrganizerCore::createModListProxyModel()
+{
+ ModListSortProxy *result = new ModListSortProxy(m_CurrentProfile, this);
+ result->setSourceModel(&m_ModList);
+ return result;
}
-PluginListSortProxy* OrganizerCore::createPluginListProxyModel() {
- PluginListSortProxy* result = new PluginListSortProxy(this);
- result->setSourceModel(&m_PluginList);
- return result;
+PluginListSortProxy *OrganizerCore::createPluginListProxyModel()
+{
+ PluginListSortProxy *result = new PluginListSortProxy(this);
+ result->setSourceModel(&m_PluginList);
+ return result;
}
-IPluginGame const* OrganizerCore::managedGame() const { return m_GamePlugin; }
+IPluginGame const *OrganizerCore::managedGame() const
+{
+ return m_GamePlugin;
+}
-std::vector<QString> OrganizerCore::enabledArchives() {
- std::vector<QString> result;
- QFile archiveFile(m_CurrentProfile->getArchivesFileName());
- if (archiveFile.open(QIODevice::ReadOnly)) {
- while (!archiveFile.atEnd()) {
- result.push_back(QString::fromUtf8(archiveFile.readLine()).trimmed());
- }
- archiveFile.close();
+std::vector<QString> OrganizerCore::enabledArchives()
+{
+ std::vector<QString> result;
+ QFile archiveFile(m_CurrentProfile->getArchivesFileName());
+ if (archiveFile.open(QIODevice::ReadOnly)) {
+ while (!archiveFile.atEnd()) {
+ result.push_back(QString::fromUtf8(archiveFile.readLine()).trimmed());
}
- return result;
+ archiveFile.close();
+ }
+ return result;
}
-void OrganizerCore::refreshDirectoryStructure() {
- if (!m_DirectoryUpdate) {
- m_CurrentProfile->writeModlistNow(true);
+void OrganizerCore::refreshDirectoryStructure()
+{
+ if (!m_DirectoryUpdate) {
+ m_CurrentProfile->writeModlistNow(true);
- m_DirectoryUpdate = true;
- std::vector<std::tuple<QString, QString, int>> activeModList = m_CurrentProfile->getActiveMods();
- auto archives = enabledArchives();
- m_DirectoryRefresher.setMods(activeModList, std::set<QString>(archives.begin(), archives.end()));
+ m_DirectoryUpdate = true;
+ std::vector<std::tuple<QString, QString, int>> activeModList
+ = m_CurrentProfile->getActiveMods();
+ auto archives = enabledArchives();
+ m_DirectoryRefresher.setMods(
+ activeModList, std::set<QString>(archives.begin(), archives.end()));
- QTimer::singleShot(0, &m_DirectoryRefresher, SLOT(refresh()));
- }
+ QTimer::singleShot(0, &m_DirectoryRefresher, SLOT(refresh()));
+ }
}
-void OrganizerCore::directory_refreshed() {
- DirectoryEntry* newStructure = m_DirectoryRefresher.getDirectoryStructure();
- Q_ASSERT(newStructure != m_DirectoryStructure);
- if (newStructure != nullptr) {
- std::swap(m_DirectoryStructure, newStructure);
- delete newStructure;
- } else {
- // TODO: don't know why this happens, this slot seems to get called twice
- // with only one emit
- return;
- }
- m_DirectoryUpdate = false;
+void OrganizerCore::directory_refreshed()
+{
+ DirectoryEntry *newStructure = m_DirectoryRefresher.getDirectoryStructure();
+ Q_ASSERT(newStructure != m_DirectoryStructure);
+ if (newStructure != nullptr) {
+ std::swap(m_DirectoryStructure, newStructure);
+ delete newStructure;
+ } else {
+ // TODO: don't know why this happens, this slot seems to get called twice
+ // with only one emit
+ return;
+ }
+ m_DirectoryUpdate = false;
- for (int i = 0; i < m_ModList.rowCount(); ++i) {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(i);
- modInfo->clearCaches();
- }
- for (auto task : m_PostRefreshTasks) {
- task();
- }
- m_PostRefreshTasks.clear();
+ for (int i = 0; i < m_ModList.rowCount(); ++i) {
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(i);
+ modInfo->clearCaches();
+ }
+ for (auto task : m_PostRefreshTasks) {
+ task();
+ }
+ m_PostRefreshTasks.clear();
- if (m_CurrentProfile != nullptr) {
- refreshLists();
- }
+ if (m_CurrentProfile != nullptr) {
+ refreshLists();
+ }
}
-void OrganizerCore::profileRefresh() {
- // have to refresh mods twice (again in refreshModList), otherwise the refresh
- // isn't complete. Not sure why
- ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, m_Settings.displayForeign(),
- managedGame());
- m_CurrentProfile->refreshModStatus();
+void OrganizerCore::profileRefresh()
+{
+ // have to refresh mods twice (again in refreshModList), otherwise the refresh
+ // isn't complete. Not sure why
+ ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure,
+ m_Settings.displayForeign(), managedGame());
+ m_CurrentProfile->refreshModStatus();
- refreshModList();
+ refreshModList();
}
-void OrganizerCore::modStatusChanged(unsigned int index) {
- try {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(index);
- if (m_CurrentProfile->modEnabled(index)) {
- updateModInDirectoryStructure(index, modInfo);
- } else {
- updateModActiveState(index, false);
- refreshESPList();
- if (m_DirectoryStructure->originExists(ToWString(modInfo->name()))) {
- FilesOrigin& origin = m_DirectoryStructure->getOriginByName(ToWString(modInfo->name()));
- origin.enable(false);
- }
- if (m_UserInterface != nullptr) {
- m_UserInterface->archivesWriter().write();
- }
- }
- modInfo->clearCaches();
-
- for (unsigned int i = 0; i < m_CurrentProfile->numMods(); ++i) {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(i);
- int priority = m_CurrentProfile->getModPriority(i);
- if (m_DirectoryStructure->originExists(ToWString(modInfo->name()))) {
- // priorities in the directory structure are one higher because data is
- // 0
- m_DirectoryStructure->getOriginByName(ToWString(modInfo->name())).setPriority(priority + 1);
- }
- }
- m_DirectoryStructure->getFileRegister()->sortOrigins();
+void OrganizerCore::modStatusChanged(unsigned int index)
+{
+ try {
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(index);
+ if (m_CurrentProfile->modEnabled(index)) {
+ updateModInDirectoryStructure(index, modInfo);
+ } else {
+ updateModActiveState(index, false);
+ refreshESPList();
+ if (m_DirectoryStructure->originExists(ToWString(modInfo->name()))) {
+ FilesOrigin &origin
+ = m_DirectoryStructure->getOriginByName(ToWString(modInfo->name()));
+ origin.enable(false);
+ }
+ if (m_UserInterface != nullptr) {
+ m_UserInterface->archivesWriter().write();
+ }
+ }
+ modInfo->clearCaches();
- refreshLists();
- } catch (const std::exception& e) {
- reportError(tr("failed to update mod list: %1").arg(e.what()));
+ for (unsigned int i = 0; i < m_CurrentProfile->numMods(); ++i) {
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(i);
+ int priority = m_CurrentProfile->getModPriority(i);
+ if (m_DirectoryStructure->originExists(ToWString(modInfo->name()))) {
+ // priorities in the directory structure are one higher because data is
+ // 0
+ m_DirectoryStructure->getOriginByName(ToWString(modInfo->name()))
+ .setPriority(priority + 1);
+ }
}
+ m_DirectoryStructure->getFileRegister()->sortOrigins();
+
+ refreshLists();
+ } catch (const std::exception &e) {
+ reportError(tr("failed to update mod list: %1").arg(e.what()));
+ }
}
-void OrganizerCore::loginSuccessful(bool necessary) {
- if (necessary) {
- MessageDialog::showMessage(tr("login successful"), qApp->activeWindow());
- }
- for (QString url : m_PendingDownloads) {
- downloadRequestedNXM(url);
- }
- m_PendingDownloads.clear();
- for (auto task : m_PostLoginTasks) {
- task();
- }
+void OrganizerCore::loginSuccessful(bool necessary)
+{
+ if (necessary) {
+ MessageDialog::showMessage(tr("login successful"), qApp->activeWindow());
+ }
+ for (QString url : m_PendingDownloads) {
+ downloadRequestedNXM(url);
+ }
+ m_PendingDownloads.clear();
+ for (auto task : m_PostLoginTasks) {
+ task();
+ }
- m_PostLoginTasks.clear();
- NexusInterface::instance()->loginCompleted();
+ m_PostLoginTasks.clear();
+ NexusInterface::instance()->loginCompleted();
}
-void OrganizerCore::loginSuccessfulUpdate(bool necessary) {
- if (necessary) {
- MessageDialog::showMessage(tr("login successful"), qApp->activeWindow());
- }
- m_Updater.startUpdate();
+void OrganizerCore::loginSuccessfulUpdate(bool necessary)
+{
+ if (necessary) {
+ MessageDialog::showMessage(tr("login successful"), qApp->activeWindow());
+ }
+ m_Updater.startUpdate();
}
-void OrganizerCore::loginFailed(const QString& message) {
- if (QMessageBox::question(qApp->activeWindow(), tr("Login failed"), tr("Login failed, try again?")) ==
- QMessageBox::Yes) {
- if (nexusLogin(true)) {
- return;
- }
+void OrganizerCore::loginFailed(const QString &message)
+{
+ if (QMessageBox::question(qApp->activeWindow(), tr("Login failed"),
+ tr("Login failed, try again?"))
+ == QMessageBox::Yes) {
+ if (nexusLogin(true)) {
+ return;
}
+ }
- if (!m_PendingDownloads.isEmpty()) {
- MessageDialog::showMessage(tr("login failed: %1. Download will not be associated with an account").arg(message),
- qApp->activeWindow());
- for (QString url : m_PendingDownloads) {
- downloadRequestedNXM(url);
- }
- m_PendingDownloads.clear();
- } else {
- MessageDialog::showMessage(tr("login failed: %1").arg(message), qApp->activeWindow());
- m_PostLoginTasks.clear();
+ if (!m_PendingDownloads.isEmpty()) {
+ MessageDialog::showMessage(
+ tr("login failed: %1. Download will not be associated with an account")
+ .arg(message),
+ qApp->activeWindow());
+ for (QString url : m_PendingDownloads) {
+ downloadRequestedNXM(url);
}
- NexusInterface::instance()->loginCompleted();
+ m_PendingDownloads.clear();
+ } else {
+ MessageDialog::showMessage(tr("login failed: %1").arg(message),
+ qApp->activeWindow());
+ m_PostLoginTasks.clear();
+ }
+ NexusInterface::instance()->loginCompleted();
}
-void OrganizerCore::loginFailedUpdate(const QString& message) {
- MessageDialog::showMessage(tr("login failed: %1. You need to log-in with Nexus to update MO.").arg(message),
- qApp->activeWindow());
+void OrganizerCore::loginFailedUpdate(const QString &message)
+{
+ MessageDialog::showMessage(
+ tr("login failed: %1. You need to log-in with Nexus to update MO.")
+ .arg(message),
+ qApp->activeWindow());
}
-void OrganizerCore::syncOverwrite() {
- unsigned int overwriteIndex = ModInfo::findMod([](ModInfo::Ptr mod) -> bool {
- std::vector<ModInfo::EFlag> flags = mod->getFlags();
- return std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end();
- });
+void OrganizerCore::syncOverwrite()
+{
+ unsigned int overwriteIndex = ModInfo::findMod([](ModInfo::Ptr mod) -> bool {
+ std::vector<ModInfo::EFlag> flags = mod->getFlags();
+ return std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE)
+ != flags.end();
+ });
- ModInfo::Ptr modInfo = ModInfo::getByIndex(overwriteIndex);
- SyncOverwriteDialog syncDialog(modInfo->absolutePath(), m_DirectoryStructure, qApp->activeWindow());
- if (syncDialog.exec() == QDialog::Accepted) {
- syncDialog.apply(QDir::fromNativeSeparators(m_Settings.getModDirectory()));
- modInfo->testValid();
- refreshDirectoryStructure();
- }
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(overwriteIndex);
+ SyncOverwriteDialog syncDialog(modInfo->absolutePath(), m_DirectoryStructure,
+ qApp->activeWindow());
+ if (syncDialog.exec() == QDialog::Accepted) {
+ syncDialog.apply(QDir::fromNativeSeparators(m_Settings.getModDirectory()));
+ modInfo->testValid();
+ refreshDirectoryStructure();
+ }
}
-QString OrganizerCore::oldMO1HookDll() const {
- if (auto extender = managedGame()->feature<ScriptExtender>()) {
- QString hookdll = QDir::toNativeSeparators(
- managedGame()->dataDirectory().absoluteFilePath(extender->PluginPath() + "/hook.dll"));
- if (QFile(hookdll).exists())
- return hookdll;
- }
- return QString();
+QString OrganizerCore::oldMO1HookDll() const
+{
+ if (auto extender = managedGame()->feature<ScriptExtender>()) {
+ QString hookdll = QDir::toNativeSeparators(
+ managedGame()->dataDirectory().absoluteFilePath(extender->PluginPath() + "/hook.dll"));
+ if (QFile(hookdll).exists())
+ return hookdll;
+ }
+ return QString();
}
-std::vector<unsigned int> OrganizerCore::activeProblems() const {
- std::vector<unsigned int> problems;
- const auto& hookdll = oldMO1HookDll();
- if (!hookdll.isEmpty()) {
- // This warning will now be shown every time the problems are checked, which is a bit
- // of a "log spam". But since this is a sevre error which will most likely make the
- // game crash/freeze/etc. and is very hard to diagnose, this "log spam" will make it
- // easier for the user to notice the warning.
- qWarning("hook.dll found in game folder: %s", qPrintable(hookdll));
- problems.push_back(PROBLEM_MO1SCRIPTEXTENDERWORKAROUND);
- }
- return problems;
+std::vector<unsigned int> OrganizerCore::activeProblems() const
+{
+ std::vector<unsigned int> problems;
+ const auto& hookdll = oldMO1HookDll();
+ if (!hookdll.isEmpty()) {
+ // This warning will now be shown every time the problems are checked, which is a bit
+ // of a "log spam". But since this is a sevre error which will most likely make the
+ // game crash/freeze/etc. and is very hard to diagnose, this "log spam" will make it
+ // easier for the user to notice the warning.
+ qWarning("hook.dll found in game folder: %s", qPrintable(hookdll));
+ problems.push_back(PROBLEM_MO1SCRIPTEXTENDERWORKAROUND);
+ }
+ return problems;
}
-QString OrganizerCore::shortDescription(unsigned int key) const {
- switch (key) {
+QString OrganizerCore::shortDescription(unsigned int key) const
+{
+ switch (key) {
case PROBLEM_MO1SCRIPTEXTENDERWORKAROUND: {
- return tr("MO1 \"Script Extender\" load mechanism has left hook.dll in your game folder");
+ return tr("MO1 \"Script Extender\" load mechanism has left hook.dll in your game folder");
} break;
- default: { return tr("Description missing"); } break;
- }
+ default: {
+ return tr("Description missing");
+ } break;
+ }
}
-QString OrganizerCore::fullDescription(unsigned int key) const {
- switch (key) {
+QString OrganizerCore::fullDescription(unsigned int key) const
+{
+ switch (key) {
case PROBLEM_MO1SCRIPTEXTENDERWORKAROUND: {
- return tr("<a href=\"%1\">hook.dll</a> has been found in your game folder (right click to copy the full path). "
- "This is most likely a leftover of setting the ModOrganizer 1 load mechanism to \"Script Extender\", "
- "in which case you must remove this file either by changing the load mechanism in ModOrganizer 1 or "
- "manually removing the file, otherwise the game is likely to crash and burn.")
- .arg(oldMO1HookDll());
- break;
- }
- default: { return tr("Description missing"); } break;
+ return tr("<a href=\"%1\">hook.dll</a> has been found in your game folder (right click to copy the full path). "
+ "This is most likely a leftover of setting the ModOrganizer 1 load mechanism to \"Script Extender\", "
+ "in which case you must remove this file either by changing the load mechanism in ModOrganizer 1 or "
+ "manually removing the file, otherwise the game is likely to crash and burn.").arg(oldMO1HookDll());
+ break;
}
+ default: {
+ return tr("Description missing");
+ } break;
+ }
}
-bool OrganizerCore::hasGuidedFix(unsigned int) const { return false; }
+bool OrganizerCore::hasGuidedFix(unsigned int) const
+{
+ return false;
+}
-void OrganizerCore::startGuidedFix(unsigned int) const {}
+void OrganizerCore::startGuidedFix(unsigned int) const
+{
+}
-bool OrganizerCore::saveCurrentLists() {
- if (m_DirectoryUpdate) {
- qWarning("not saving lists during directory update");
- return false;
- }
+bool OrganizerCore::saveCurrentLists()
+{
+ if (m_DirectoryUpdate) {
+ qWarning("not saving lists during directory update");
+ return false;
+ }
- try {
- savePluginList();
- if (m_UserInterface != nullptr) {
- m_UserInterface->archivesWriter().write();
- }
- } catch (const std::exception& e) {
- reportError(tr("failed to save load order: %1").arg(e.what()));
+ try {
+ savePluginList();
+ if (m_UserInterface != nullptr) {
+ m_UserInterface->archivesWriter().write();
}
+ } catch (const std::exception &e) {
+ reportError(tr("failed to save load order: %1").arg(e.what()));
+ }
- return true;
+ return true;
}
-void OrganizerCore::savePluginList() {
- if (m_DirectoryUpdate) {
- // delay save till after directory update
- m_PostRefreshTasks.append([this]() { this->savePluginList(); });
- return;
- }
- m_PluginList.saveTo(m_CurrentProfile->getLockedOrderFileName(), m_CurrentProfile->getDeleterFileName(),
- m_Settings.hideUncheckedPlugins());
- m_PluginList.saveLoadOrder(*m_DirectoryStructure);
+void OrganizerCore::savePluginList()
+{
+ if (m_DirectoryUpdate) {
+ // delay save till after directory update
+ m_PostRefreshTasks.append([this]() {
+ this->savePluginList();
+ });
+ return;
+ }
+ m_PluginList.saveTo(m_CurrentProfile->getLockedOrderFileName(),
+ m_CurrentProfile->getDeleterFileName(),
+ m_Settings.hideUncheckedPlugins());
+ m_PluginList.saveLoadOrder(*m_DirectoryStructure);
}
-void OrganizerCore::prepareStart() {
- if (m_CurrentProfile == nullptr) {
- return;
- }
- m_CurrentProfile->writeModlist();
- m_CurrentProfile->createTweakedIniFile();
- saveCurrentLists();
- m_Settings.setupLoadMechanism();
- storeSettings();
+void OrganizerCore::prepareStart()
+{
+ if (m_CurrentProfile == nullptr) {
+ return;
+ }
+ m_CurrentProfile->writeModlist();
+ m_CurrentProfile->createTweakedIniFile();
+ saveCurrentLists();
+ m_Settings.setupLoadMechanism();
+ storeSettings();
}
-std::vector<Mapping> OrganizerCore::fileMapping(const QString& profileName, const QString& customOverwrite) {
- // need to wait until directory structure
- while (m_DirectoryUpdate) {
- ::Sleep(100);
- QCoreApplication::processEvents();
- }
+std::vector<Mapping> OrganizerCore::fileMapping(const QString &profileName,
+ const QString &customOverwrite)
+{
+ // need to wait until directory structure
+ while (m_DirectoryUpdate) {
+ ::Sleep(100);
+ QCoreApplication::processEvents();
+ }
- IPluginGame* game = qApp->property("managed_game").value<IPluginGame*>();
- Profile profile(QDir(m_Settings.getProfileDirectory() + "/" + profileName), game);
+ IPluginGame *game = qApp->property("managed_game").value<IPluginGame *>();
+ Profile profile(QDir(m_Settings.getProfileDirectory() + "/" + profileName),
+ game);
- MappingType result;
+ MappingType result;
- QString dataPath = QDir::toNativeSeparators(game->dataDirectory().absolutePath());
+ QString dataPath
+ = QDir::toNativeSeparators(game->dataDirectory().absolutePath());
- bool overwriteActive = false;
+ bool overwriteActive = false;
- for (auto mod : profile.getActiveMods()) {
- if (std::get<0>(mod).compare("overwrite", Qt::CaseInsensitive) == 0) {
- continue;
- }
+ for (auto mod : profile.getActiveMods()) {
+ if (std::get<0>(mod).compare("overwrite", Qt::CaseInsensitive) == 0) {
+ continue;
+ }
- unsigned int modIndex = ModInfo::getIndex(std::get<0>(mod));
- ModInfo::Ptr modPtr = ModInfo::getByIndex(modIndex);
+ unsigned int modIndex = ModInfo::getIndex(std::get<0>(mod));
+ ModInfo::Ptr modPtr = ModInfo::getByIndex(modIndex);
- bool createTarget = customOverwrite == std::get<0>(mod);
+ bool createTarget = customOverwrite == std::get<0>(mod);
- overwriteActive |= createTarget;
+ overwriteActive |= createTarget;
- if (modPtr->isRegular()) {
- result.insert(result.end(), {QDir::toNativeSeparators(std::get<1>(mod)), dataPath, true, createTarget});
- }
+ if (modPtr->isRegular()) {
+ result.insert(result.end(), {QDir::toNativeSeparators(std::get<1>(mod)),
+ dataPath, true, createTarget});
}
+ }
- if (!overwriteActive && !customOverwrite.isEmpty()) {
- throw MyException(tr("The designated write target \"%1\" is not enabled.").arg(customOverwrite));
- }
+ if (!overwriteActive && !customOverwrite.isEmpty()) {
+ throw MyException(tr("The designated write target \"%1\" is not enabled.")
+ .arg(customOverwrite));
+ }
- if (m_CurrentProfile->localSavesEnabled()) {
- LocalSavegames* localSaves = game->feature<LocalSavegames>();
- if (localSaves != nullptr) {
- MappingType saveMap = localSaves->mappings(currentProfile()->absolutePath() + "/saves");
- result.reserve(result.size() + saveMap.size());
- result.insert(result.end(), saveMap.begin(), saveMap.end());
- } else {
- qWarning("local save games not supported by this game plugin");
- }
+ if (m_CurrentProfile->localSavesEnabled()) {
+ LocalSavegames *localSaves = game->feature<LocalSavegames>();
+ if (localSaves != nullptr) {
+ MappingType saveMap
+ = localSaves->mappings(currentProfile()->absolutePath() + "/saves");
+ result.reserve(result.size() + saveMap.size());
+ result.insert(result.end(), saveMap.begin(), saveMap.end());
+ } else {
+ qWarning("local save games not supported by this game plugin");
}
+ }
- result.insert(result.end(), {QDir::toNativeSeparators(m_Settings.getOverwriteDirectory()), dataPath, true,
- customOverwrite.isEmpty()});
+ result.insert(result.end(), {
+ QDir::toNativeSeparators(m_Settings.getOverwriteDirectory()),
+ dataPath,
+ true,
+ customOverwrite.isEmpty()
+ });
- for (MOBase::IPluginFileMapper* mapper : m_PluginContainer->plugins<MOBase::IPluginFileMapper>()) {
- IPlugin* plugin = dynamic_cast<IPlugin*>(mapper);
- if (plugin->isActive()) {
- MappingType pluginMap = mapper->mappings();
- result.reserve(result.size() + pluginMap.size());
- result.insert(result.end(), pluginMap.begin(), pluginMap.end());
- }
+ for (MOBase::IPluginFileMapper *mapper :
+ m_PluginContainer->plugins<MOBase::IPluginFileMapper>()) {
+ IPlugin *plugin = dynamic_cast<IPlugin *>(mapper);
+ if (plugin->isActive()) {
+ MappingType pluginMap = mapper->mappings();
+ result.reserve(result.size() + pluginMap.size());
+ result.insert(result.end(), pluginMap.begin(), pluginMap.end());
}
+ }
- return result;
+ return result;
}
-std::vector<Mapping> OrganizerCore::fileMapping(const QString& dataPath, const QString& relPath,
- const DirectoryEntry* base, const DirectoryEntry* directoryEntry,
- int createDestination) {
- std::vector<Mapping> result;
- for (FileEntry::Ptr current : directoryEntry->getFiles()) {
- bool isArchive = false;
- int origin = current->getOrigin(isArchive);
- if (isArchive || (origin == 0)) {
- continue;
- }
+std::vector<Mapping> OrganizerCore::fileMapping(
+ const QString &dataPath, const QString &relPath, const DirectoryEntry *base,
+ const DirectoryEntry *directoryEntry, int createDestination)
+{
+ std::vector<Mapping> result;
- QString originPath = QString::fromStdWString(base->getOriginByID(origin).getPath());
- QString fileName = QString::fromStdWString(current->getName());
- // QString fileName = ToQString(current->getName());
- QString source = originPath + relPath + fileName;
- QString target = dataPath + relPath + fileName;
- if (source != target) {
- result.push_back({source, target, false, false});
- }
+ for (FileEntry::Ptr current : directoryEntry->getFiles()) {
+ bool isArchive = false;
+ int origin = current->getOrigin(isArchive);
+ if (isArchive || (origin == 0)) {
+ continue;
}
- // recurse into subdirectories
- std::vector<DirectoryEntry*>::const_iterator current, end;
- directoryEntry->getSubDirectories(current, end);
- for (; current != end; ++current) {
- int origin = (*current)->anyOrigin();
+ QString originPath
+ = QString::fromStdWString(base->getOriginByID(origin).getPath());
+ QString fileName = QString::fromStdWString(current->getName());
+// QString fileName = ToQString(current->getName());
+ QString source = originPath + relPath + fileName;
+ QString target = dataPath + relPath + fileName;
+ if (source != target) {
+ result.push_back({source, target, false, false});
+ }
+ }
- QString originPath = QString::fromStdWString(base->getOriginByID(origin).getPath());
- QString dirName = QString::fromStdWString((*current)->getName());
- QString source = originPath + relPath + dirName;
- QString target = dataPath + relPath + dirName;
+ // recurse into subdirectories
+ std::vector<DirectoryEntry *>::const_iterator current, end;
+ directoryEntry->getSubDirectories(current, end);
+ for (; current != end; ++current) {
+ int origin = (*current)->anyOrigin();
- bool writeDestination = (base == directoryEntry) && (origin == createDestination);
+ QString originPath
+ = QString::fromStdWString(base->getOriginByID(origin).getPath());
+ QString dirName = QString::fromStdWString((*current)->getName());
+ QString source = originPath + relPath + dirName;
+ QString target = dataPath + relPath + dirName;
- result.push_back({source, target, true, writeDestination});
- std::vector<Mapping> subRes =
- fileMapping(dataPath, relPath + dirName + "\\", base, *current, createDestination);
- result.insert(result.end(), subRes.begin(), subRes.end());
- }
- return result;
+ bool writeDestination
+ = (base == directoryEntry) && (origin == createDestination);
+
+ result.push_back({source, target, true, writeDestination});
+ std::vector<Mapping> subRes = fileMapping(
+ dataPath, relPath + dirName + "\\", base, *current, createDestination);
+ result.insert(result.end(), subRes.begin(), subRes.end());
+ }
+ return result;
}
diff --git a/src/organizercore.h b/src/organizercore.h
index ad6608f2..9e81f0c3 100644
--- a/src/organizercore.h
+++ b/src/organizercore.h
@@ -1,36 +1,34 @@
#ifndef ORGANIZERCORE_H
#define ORGANIZERCORE_H
-#include "directoryrefresher.h"
-#include "downloadmanager.h"
-#include "executableslist.h"
-#include "installationmanager.h"
+
+#include "selfupdater.h"
#include "iuserinterface.h" //should be class IUserInterface;
-#include "modinfo.h"
+#include "settings.h"
#include "modlist.h"
-#include "moshortcut.h"
+#include "modinfo.h"
#include "pluginlist.h"
-#include "selfupdater.h"
-#include "settings.h"
+#include "directoryrefresher.h"
+#include "installationmanager.h"
+#include "downloadmanager.h"
+#include "executableslist.h"
#include "usvfsconnector.h"
-#include <boost/signals2.hpp>
-#include <delayedfilewriter.h>
+#include "moshortcut.h"
#include <directoryentry.h>
#include <imoinfo.h>
#include <iplugindiagnose.h>
#include <versioninfo.h>
+#include <delayedfilewriter.h>
+#include <boost/signals2.hpp>
class ModListSortProxy;
class PluginListSortProxy;
class Profile;
namespace MOBase {
-template <typename T>
-class GuessedValue;
-class IModInterface;
-} // namespace MOBase
-namespace MOShared {
-class DirectoryEntry;
+ template <typename T> class GuessedValue;
+ class IModInterface;
}
+namespace MOShared { class DirectoryEntry; }
#include <QDir>
#include <QFileInfo>
@@ -54,273 +52,293 @@ class QWidget;
class PluginContainer;
namespace MOBase {
-class IPluginGame;
+ class IPluginGame;
}
-class OrganizerCore : public QObject, public MOBase::IPluginDiagnose {
+class OrganizerCore : public QObject, public MOBase::IPluginDiagnose
+{
- Q_OBJECT
- Q_INTERFACES(MOBase::IPluginDiagnose)
+ Q_OBJECT
+ Q_INTERFACES(MOBase::IPluginDiagnose)
private:
- struct SignalCombinerAnd {
- typedef bool result_type;
- template <typename InputIterator>
- bool operator()(InputIterator first, InputIterator last) const {
- while (first != last) {
- if (!(*first)) {
- return false;
- }
- ++first;
- }
- return true;
+
+ struct SignalCombinerAnd
+ {
+ typedef bool result_type;
+ template<typename InputIterator>
+ bool operator()(InputIterator first, InputIterator last) const
+ {
+ while (first != last) {
+ if (!(*first)) {
+ return false;
}
- };
+ ++first;
+ }
+ return true;
+ }
+ };
private:
- typedef boost::signals2::signal<bool(const QString&), SignalCombinerAnd> SignalAboutToRunApplication;
- typedef boost::signals2::signal<void(const QString&, unsigned int)> SignalFinishedRunApplication;
- typedef boost::signals2::signal<void(const QString&)> SignalModInstalled;
+
+ typedef boost::signals2::signal<bool (const QString&), SignalCombinerAnd> SignalAboutToRunApplication;
+ typedef boost::signals2::signal<void (const QString&, unsigned int)> SignalFinishedRunApplication;
+ typedef boost::signals2::signal<void (const QString&)> SignalModInstalled;
public:
- static bool isNxmLink(const QString& link) { return link.startsWith("nxm://", Qt::CaseInsensitive); }
+ static bool isNxmLink(const QString &link) { return link.startsWith("nxm://", Qt::CaseInsensitive); }
- OrganizerCore(const QSettings& initSettings);
+ OrganizerCore(const QSettings &initSettings);
- ~OrganizerCore();
+ ~OrganizerCore();
- void setUserInterface(IUserInterface* userInterface, QWidget* widget);
- void connectPlugins(PluginContainer* container);
- void disconnectPlugins();
+ void setUserInterface(IUserInterface *userInterface, QWidget *widget);
+ void connectPlugins(PluginContainer *container);
+ void disconnectPlugins();
- void setManagedGame(MOBase::IPluginGame* game);
+ void setManagedGame(MOBase::IPluginGame *game);
- void updateExecutablesList(QSettings& settings);
+ void updateExecutablesList(QSettings &settings);
- void startMOUpdate();
+ void startMOUpdate();
- Settings& settings();
- SelfUpdater* updater() { return &m_Updater; }
- InstallationManager* installationManager();
- MOShared::DirectoryEntry* directoryStructure() { return m_DirectoryStructure; }
- DirectoryRefresher* directoryRefresher() { return &m_DirectoryRefresher; }
- ExecutablesList* executablesList() { return &m_ExecutablesList; }
- void setExecutablesList(const ExecutablesList& executablesList) { m_ExecutablesList = executablesList; }
+ Settings &settings();
+ SelfUpdater *updater() { return &m_Updater; }
+ InstallationManager *installationManager();
+ MOShared::DirectoryEntry *directoryStructure() { return m_DirectoryStructure; }
+ DirectoryRefresher *directoryRefresher() { return &m_DirectoryRefresher; }
+ ExecutablesList *executablesList() { return &m_ExecutablesList; }
+ void setExecutablesList(const ExecutablesList &executablesList) {
+ m_ExecutablesList = executablesList;
+ }
- Profile* currentProfile() const { return m_CurrentProfile; }
- void setCurrentProfile(const QString& profileName);
+ Profile *currentProfile() const { return m_CurrentProfile; }
+ void setCurrentProfile(const QString &profileName);
- std::vector<QString> enabledArchives();
+ std::vector<QString> enabledArchives();
- MOBase::VersionInfo getVersion() const { return m_Updater.getVersion(); }
+ MOBase::VersionInfo getVersion() const { return m_Updater.getVersion(); }
- ModListSortProxy* createModListProxyModel();
- PluginListSortProxy* createPluginListProxyModel();
+ ModListSortProxy *createModListProxyModel();
+ PluginListSortProxy *createPluginListProxyModel();
- MOBase::IPluginGame const* managedGame() const;
+ MOBase::IPluginGame const *managedGame() const;
- bool isArchivesInit() const { return m_ArchivesInit; }
+ bool isArchivesInit() const { return m_ArchivesInit; }
- bool saveCurrentLists();
+ bool saveCurrentLists();
- void prepareStart();
+ void prepareStart();
- void refreshESPList();
- void refreshBSAList();
+ void refreshESPList();
+ void refreshBSAList();
- void refreshDirectoryStructure();
- void updateModInDirectoryStructure(unsigned int index, ModInfo::Ptr modInfo);
+ void refreshDirectoryStructure();
+ void updateModInDirectoryStructure(unsigned int index, ModInfo::Ptr modInfo);
- void doAfterLogin(const std::function<void()>& function) { m_PostLoginTasks.append(function); }
+ void doAfterLogin(const std::function<void()> &function) { m_PostLoginTasks.append(function); }
- void spawnBinary(const QFileInfo& binary, const QString& arguments = "", const QDir& currentDirectory = QDir(),
- const QString& steamAppID = "", const QString& customOverwrite = "");
+ void spawnBinary(const QFileInfo &binary, const QString &arguments = "",
+ const QDir &currentDirectory = QDir(),
+ const QString &steamAppID = "",
+ const QString &customOverwrite = "");
- HANDLE spawnBinaryDirect(const QFileInfo& binary, const QString& arguments, const QString& profileName,
- const QDir& currentDirectory, const QString& steamAppID, const QString& customOverwrite,
- LPDWORD exitCode = nullptr);
+ HANDLE spawnBinaryDirect(const QFileInfo &binary, const QString &arguments,
+ const QString &profileName,
+ const QDir &currentDirectory,
+ const QString &steamAppID,
+ const QString &customOverwrite,
+ LPDWORD exitCode = nullptr);
- HANDLE spawnBinaryProcess(const QFileInfo& binary, const QString& arguments, const QString& profileName,
- const QDir& currentDirectory, const QString& steamAppID, const QString& customOverwrite);
+ HANDLE spawnBinaryProcess(const QFileInfo &binary, const QString &arguments,
+ const QString &profileName,
+ const QDir &currentDirectory,
+ const QString &steamAppID,
+ const QString &customOverwrite);
- void loginSuccessfulUpdate(bool necessary);
- void loginFailedUpdate(const QString& message);
+ void loginSuccessfulUpdate(bool necessary);
+ void loginFailedUpdate(const QString &message);
- static bool createAndMakeWritable(const QString& path);
- bool bootstrap();
- void createDefaultProfile();
+ static bool createAndMakeWritable(const QString &path);
+ bool bootstrap();
+ void createDefaultProfile();
- MOBase::DelayedFileWriter& pluginsWriter() { return m_PluginListsWriter; }
+ MOBase::DelayedFileWriter &pluginsWriter() { return m_PluginListsWriter; }
- void prepareVFS();
+ void prepareVFS();
- void updateVFSParams(int logLevel, int crashDumpsType);
+ void updateVFSParams(int logLevel, int crashDumpsType);
- bool cycleDiagnostics();
+ bool cycleDiagnostics();
- static CrashDumpsType getGlobalCrashDumpsType() { return m_globalCrashDumpsType; }
- static void setGlobalCrashDumpsType(int crashDumpsType);
- static std::wstring crashDumpsPath();
+ static CrashDumpsType getGlobalCrashDumpsType() { return m_globalCrashDumpsType; }
+ static void setGlobalCrashDumpsType(int crashDumpsType);
+ static std::wstring crashDumpsPath();
public:
- MOBase::IModRepositoryBridge* createNexusBridge() const;
- QString profileName() const;
- QString profilePath() const;
- QString downloadsPath() const;
- QString overwritePath() const;
- QString basePath() const;
- MOBase::VersionInfo appVersion() const;
- MOBase::IModInterface* getMod(const QString& name) const;
- MOBase::IModInterface* createMod(MOBase::GuessedValue<QString>& name);
- bool removeMod(MOBase::IModInterface* mod);
- void modDataChanged(MOBase::IModInterface* mod);
- QVariant pluginSetting(const QString& pluginName, const QString& key) const;
- void setPluginSetting(const QString& pluginName, const QString& key, const QVariant& value);
- QVariant persistent(const QString& pluginName, const QString& key, const QVariant& def) const;
- void setPersistent(const QString& pluginName, const QString& key, const QVariant& value, bool sync);
- QString pluginDataPath() const;
- virtual MOBase::IModInterface* installMod(const QString& fileName, const QString& initModName);
- QString resolvePath(const QString& fileName) const;
- QStringList listDirectories(const QString& directoryName) const;
- QStringList findFiles(const QString& path, const std::function<bool(const QString&)>& filter) const;
- QStringList getFileOrigins(const QString& fileName) const;
- QList<MOBase::IOrganizer::FileInfo>
- findFileInfos(const QString& path, const std::function<bool(const MOBase::IOrganizer::FileInfo&)>& filter) const;
- DownloadManager* downloadManager();
- PluginList* pluginList();
- ModList* modList();
- HANDLE runShortcut(const MOShortcut& shortcut);
- HANDLE startApplication(const QString& executable, const QStringList& args, const QString& cwd,
- const QString& profile);
- bool waitForApplication(HANDLE processHandle, LPDWORD exitCode = nullptr);
- HANDLE findAndOpenAUSVFSProcess(const std::vector<QString>& hiddenList, DWORD preferedParentPid);
- bool onModInstalled(const std::function<void(const QString&)>& func);
- bool onAboutToRun(const std::function<bool(const QString&)>& func);
- bool onFinishedRun(const std::function<void(const QString&, unsigned int)>& func);
- void refreshModList(bool saveChanges = true);
- QStringList modsSortedByProfilePriority() const;
+ MOBase::IModRepositoryBridge *createNexusBridge() const;
+ QString profileName() const;
+ QString profilePath() const;
+ QString downloadsPath() const;
+ QString overwritePath() const;
+ QString basePath() const;
+ MOBase::VersionInfo appVersion() const;
+ MOBase::IModInterface *getMod(const QString &name) const;
+ MOBase::IModInterface *createMod(MOBase::GuessedValue<QString> &name);
+ bool removeMod(MOBase::IModInterface *mod);
+ void modDataChanged(MOBase::IModInterface *mod);
+ QVariant pluginSetting(const QString &pluginName, const QString &key) const;
+ void setPluginSetting(const QString &pluginName, const QString &key, const QVariant &value);
+ QVariant persistent(const QString &pluginName, const QString &key, const QVariant &def) const;
+ void setPersistent(const QString &pluginName, const QString &key, const QVariant &value, bool sync);
+ QString pluginDataPath() const;
+ virtual MOBase::IModInterface *installMod(const QString &fileName, const QString &initModName);
+ QString resolvePath(const QString &fileName) const;
+ QStringList listDirectories(const QString &directoryName) const;
+ QStringList findFiles(const QString &path, const std::function<bool (const QString &)> &filter) const;
+ QStringList getFileOrigins(const QString &fileName) const;
+ QList<MOBase::IOrganizer::FileInfo> findFileInfos(const QString &path, const std::function<bool (const MOBase::IOrganizer::FileInfo &)> &filter) const;
+ DownloadManager *downloadManager();
+ PluginList *pluginList();
+ ModList *modList();
+ HANDLE runShortcut(const MOShortcut& shortcut);
+ HANDLE startApplication(const QString &executable, const QStringList &args, const QString &cwd, const QString &profile);
+ bool waitForApplication(HANDLE processHandle, LPDWORD exitCode = nullptr);
+ HANDLE findAndOpenAUSVFSProcess(const std::vector<QString>& hiddenList, DWORD preferedParentPid);
+ bool onModInstalled(const std::function<void (const QString &)> &func);
+ bool onAboutToRun(const std::function<bool (const QString &)> &func);
+ bool onFinishedRun(const std::function<void (const QString &, unsigned int)> &func);
+ void refreshModList(bool saveChanges = true);
+ QStringList modsSortedByProfilePriority() const;
public: // IPluginDiagnose interface
- virtual std::vector<unsigned int> activeProblems() const;
- virtual QString shortDescription(unsigned int key) const;
- virtual QString fullDescription(unsigned int key) const;
- virtual bool hasGuidedFix(unsigned int key) const;
- virtual void startGuidedFix(unsigned int key) const;
+
+ virtual std::vector<unsigned int> activeProblems() const;
+ virtual QString shortDescription(unsigned int key) const;
+ virtual QString fullDescription(unsigned int key) const;
+ virtual bool hasGuidedFix(unsigned int key) const;
+ virtual void startGuidedFix(unsigned int key) const;
public slots:
- void profileRefresh();
- void externalMessage(const QString& message);
+ void profileRefresh();
+ void externalMessage(const QString &message);
- void syncOverwrite();
+ void syncOverwrite();
- void savePluginList();
+ void savePluginList();
- void refreshLists();
+ void refreshLists();
- void installDownload(int downloadIndex);
+ void installDownload(int downloadIndex);
- void modStatusChanged(unsigned int index);
- void requestDownload(const QUrl& url, QNetworkReply* reply);
- void downloadRequestedNXM(const QString& url);
+ void modStatusChanged(unsigned int index);
+ void requestDownload(const QUrl &url, QNetworkReply *reply);
+ void downloadRequestedNXM(const QString &url);
- bool nexusLogin(bool retry = false);
+ bool nexusLogin(bool retry = false);
signals:
- /**
- * @brief emitted after a mod has been installed
- * @node this is currently only used for tutorials
- */
- void modInstalled(const QString& modName);
+ /**
+ * @brief emitted after a mod has been installed
+ * @node this is currently only used for tutorials
+ */
+ void modInstalled(const QString &modName);
- void managedGameChanged(MOBase::IPluginGame const* gamePlugin);
+ void managedGameChanged(MOBase::IPluginGame const *gamePlugin);
- void close();
+ void close();
private:
- void storeSettings();
- QSettings::Status storeSettings(const QString& fileName);
+ void storeSettings();
- QString commitSettings(const QString& iniFile);
+ QSettings::Status storeSettings(const QString &fileName);
- bool queryLogin(QString& username, QString& password);
+ QString commitSettings(const QString &iniFile);
- void updateModActiveState(int index, bool active);
+ bool queryLogin(QString &username, QString &password);
- bool testForSteam();
+ void updateModActiveState(int index, bool active);
- bool createDirectory(const QString& path);
+ bool testForSteam();
- QString oldMO1HookDll() const;
+ bool createDirectory(const QString &path);
- /**
- * @brief return a descriptor of the mappings real file->virtual file
- */
- std::vector<Mapping> fileMapping(const QString& profile, const QString& customOverwrite);
+ QString oldMO1HookDll() const;
- std::vector<Mapping> fileMapping(const QString& dataPath, const QString& relPath,
- const MOShared::DirectoryEntry* base,
- const MOShared::DirectoryEntry* directoryEntry, int createDestination);
+ /**
+ * @brief return a descriptor of the mappings real file->virtual file
+ */
+ std::vector<Mapping> fileMapping(const QString &profile,
+ const QString &customOverwrite);
- bool waitForProcessCompletion(HANDLE handle, LPDWORD exitCode, ILockedWaitingForProcess* uilock);
+ std::vector<Mapping>
+ fileMapping(const QString &dataPath, const QString &relPath,
+ const MOShared::DirectoryEntry *base,
+ const MOShared::DirectoryEntry *directoryEntry,
+ int createDestination);
+
+ bool waitForProcessCompletion(HANDLE handle, LPDWORD exitCode, ILockedWaitingForProcess* uilock);
private slots:
- void directory_refreshed();
- void downloadRequested(QNetworkReply* reply, int modID, const QString& fileName);
- void removeOrigin(const QString& name);
- void downloadSpeed(const QString& serverName, int bytesPerSecond);
- void loginSuccessful(bool necessary);
- void loginFailed(const QString& message);
+ void directory_refreshed();
+ void downloadRequested(QNetworkReply *reply, int modID, const QString &fileName);
+ void removeOrigin(const QString &name);
+ void downloadSpeed(const QString &serverName, int bytesPerSecond);
+ void loginSuccessful(bool necessary);
+ void loginFailed(const QString &message);
private:
- static const unsigned int PROBLEM_MO1SCRIPTEXTENDERWORKAROUND = 1;
+ static const unsigned int PROBLEM_MO1SCRIPTEXTENDERWORKAROUND = 1;
private:
- IUserInterface* m_UserInterface;
- PluginContainer* m_PluginContainer;
- QString m_GameName;
- MOBase::IPluginGame* m_GamePlugin;
- Profile* m_CurrentProfile;
+ IUserInterface *m_UserInterface;
+ PluginContainer *m_PluginContainer;
+ QString m_GameName;
+ MOBase::IPluginGame *m_GamePlugin;
+
+ Profile *m_CurrentProfile;
+
+ Settings m_Settings;
- Settings m_Settings;
+ SelfUpdater m_Updater;
- SelfUpdater m_Updater;
+ SignalAboutToRunApplication m_AboutToRun;
+ SignalFinishedRunApplication m_FinishedRun;
+ SignalModInstalled m_ModInstalled;
- SignalAboutToRunApplication m_AboutToRun;
- SignalFinishedRunApplication m_FinishedRun;
- SignalModInstalled m_ModInstalled;
+ ModList m_ModList;
+ PluginList m_PluginList;
- ModList m_ModList;
- PluginList m_PluginList;
- QList<std::function<void()>> m_PostLoginTasks;
- QList<std::function<void()>> m_PostRefreshTasks;
+ QList<std::function<void()>> m_PostLoginTasks;
+ QList<std::function<void()>> m_PostRefreshTasks;
- ExecutablesList m_ExecutablesList;
- QStringList m_PendingDownloads;
- QStringList m_DefaultArchives;
- QStringList m_ActiveArchives;
+ ExecutablesList m_ExecutablesList;
+ QStringList m_PendingDownloads;
+ QStringList m_DefaultArchives;
+ QStringList m_ActiveArchives;
- DirectoryRefresher m_DirectoryRefresher;
- MOShared::DirectoryEntry* m_DirectoryStructure;
+ DirectoryRefresher m_DirectoryRefresher;
+ MOShared::DirectoryEntry *m_DirectoryStructure;
- DownloadManager m_DownloadManager;
- InstallationManager m_InstallationManager;
+ DownloadManager m_DownloadManager;
+ InstallationManager m_InstallationManager;
- QThread m_RefresherThread;
+ QThread m_RefresherThread;
- bool m_AskForNexusPW;
- bool m_DirectoryUpdate;
- bool m_ArchivesInit;
+ bool m_AskForNexusPW;
+ bool m_DirectoryUpdate;
+ bool m_ArchivesInit;
- MOBase::DelayedFileWriter m_PluginListsWriter;
- UsvfsConnector m_USVFS;
+ MOBase::DelayedFileWriter m_PluginListsWriter;
+ UsvfsConnector m_USVFS;
- static CrashDumpsType m_globalCrashDumpsType;
+ static CrashDumpsType m_globalCrashDumpsType;
};
#endif // ORGANIZERCORE_H
diff --git a/src/organizerproxy.cpp b/src/organizerproxy.cpp
index bfb712af..cf2e29e3 100644
--- a/src/organizerproxy.cpp
+++ b/src/organizerproxy.cpp
@@ -8,109 +8,182 @@
using namespace MOBase;
using namespace MOShared;
-OrganizerProxy::OrganizerProxy(OrganizerCore* organizer, const QString& pluginName)
- : m_Proxied(organizer), m_PluginName(pluginName) {}
-IModRepositoryBridge* OrganizerProxy::createNexusBridge() const { return new NexusBridge(m_PluginName); }
+OrganizerProxy::OrganizerProxy(OrganizerCore *organizer, const QString &pluginName)
+ : m_Proxied(organizer)
+ , m_PluginName(pluginName)
+{
+}
-QString OrganizerProxy::profileName() const { return m_Proxied->profileName(); }
+IModRepositoryBridge *OrganizerProxy::createNexusBridge() const
+{
+ return new NexusBridge(m_PluginName);
+}
-QString OrganizerProxy::profilePath() const { return m_Proxied->profilePath(); }
+QString OrganizerProxy::profileName() const
+{
+ return m_Proxied->profileName();
+}
-QString OrganizerProxy::downloadsPath() const { return m_Proxied->downloadsPath(); }
+QString OrganizerProxy::profilePath() const
+{
+ return m_Proxied->profilePath();
+}
-QString OrganizerProxy::overwritePath() const {
- /*return QDir::fromNativeSeparators(qApp->property("dataPath").toString())
- + "/"
- + ToQString(AppConfig::overwritePath());*/
- return m_Proxied->overwritePath();
+QString OrganizerProxy::downloadsPath() const
+{
+ return m_Proxied->downloadsPath();
}
-QString OrganizerProxy::basePath() const { return m_Proxied->basePath(); }
+QString OrganizerProxy::overwritePath() const
+{
+ /*return QDir::fromNativeSeparators(qApp->property("dataPath").toString())
+ + "/"
+ + ToQString(AppConfig::overwritePath());*/
+ return m_Proxied->overwritePath();
+}
-VersionInfo OrganizerProxy::appVersion() const { return m_Proxied->appVersion(); }
+QString OrganizerProxy::basePath() const
+{
+ return m_Proxied->basePath();
+}
-IModInterface* OrganizerProxy::getMod(const QString& name) const { return m_Proxied->getMod(name); }
+VersionInfo OrganizerProxy::appVersion() const
+{
+ return m_Proxied->appVersion();
+}
-IModInterface* OrganizerProxy::createMod(MOBase::GuessedValue<QString>& name) { return m_Proxied->createMod(name); }
+IModInterface *OrganizerProxy::getMod(const QString &name) const
+{
+ return m_Proxied->getMod(name);
+}
-bool OrganizerProxy::removeMod(IModInterface* mod) { return m_Proxied->removeMod(mod); }
+IModInterface *OrganizerProxy::createMod(MOBase::GuessedValue<QString> &name)
+{
+ return m_Proxied->createMod(name);
+}
-void OrganizerProxy::modDataChanged(IModInterface* mod) { m_Proxied->modDataChanged(mod); }
+bool OrganizerProxy::removeMod(IModInterface *mod)
+{
+ return m_Proxied->removeMod(mod);
+}
-QVariant OrganizerProxy::pluginSetting(const QString& pluginName, const QString& key) const {
- return m_Proxied->pluginSetting(pluginName, key);
+void OrganizerProxy::modDataChanged(IModInterface *mod)
+{
+ m_Proxied->modDataChanged(mod);
}
-void OrganizerProxy::setPluginSetting(const QString& pluginName, const QString& key, const QVariant& value) {
- m_Proxied->setPluginSetting(pluginName, key, value);
+QVariant OrganizerProxy::pluginSetting(const QString &pluginName, const QString &key) const
+{
+ return m_Proxied->pluginSetting(pluginName, key);
}
-QVariant OrganizerProxy::persistent(const QString& pluginName, const QString& key, const QVariant& def) const {
- return m_Proxied->persistent(pluginName, key, def);
+void OrganizerProxy::setPluginSetting(const QString &pluginName, const QString &key, const QVariant &value)
+{
+ m_Proxied->setPluginSetting(pluginName, key, value);
}
-void OrganizerProxy::setPersistent(const QString& pluginName, const QString& key, const QVariant& value, bool sync) {
- m_Proxied->setPersistent(pluginName, key, value, sync);
+QVariant OrganizerProxy::persistent(const QString &pluginName, const QString &key, const QVariant &def) const
+{
+ return m_Proxied->persistent(pluginName, key, def);
}
-QString OrganizerProxy::pluginDataPath() const { return m_Proxied->pluginDataPath(); }
+void OrganizerProxy::setPersistent(const QString &pluginName, const QString &key, const QVariant &value, bool sync)
+{
+ m_Proxied->setPersistent(pluginName, key, value, sync);
+}
-HANDLE OrganizerProxy::startApplication(const QString& executable, const QStringList& args, const QString& cwd,
- const QString& profile) {
- return m_Proxied->startApplication(executable, args, cwd, profile);
+QString OrganizerProxy::pluginDataPath() const
+{
+ return m_Proxied->pluginDataPath();
}
-bool OrganizerProxy::waitForApplication(HANDLE handle, LPDWORD exitCode) const {
- return m_Proxied->waitForApplication(handle, exitCode);
+HANDLE OrganizerProxy::startApplication(const QString &executable, const QStringList &args, const QString &cwd, const QString &profile)
+{
+ return m_Proxied->startApplication(executable, args, cwd, profile);
}
-bool OrganizerProxy::onAboutToRun(const std::function<bool(const QString&)>& func) {
- return m_Proxied->onAboutToRun(func);
+bool OrganizerProxy::waitForApplication(HANDLE handle, LPDWORD exitCode) const
+{
+ return m_Proxied->waitForApplication(handle, exitCode);
}
-bool OrganizerProxy::onFinishedRun(const std::function<void(const QString&, unsigned int)>& func) {
- return m_Proxied->onFinishedRun(func);
+bool OrganizerProxy::onAboutToRun(const std::function<bool (const QString &)> &func)
+{
+ return m_Proxied->onAboutToRun(func);
}
-bool OrganizerProxy::onModInstalled(const std::function<void(const QString&)>& func) {
- return m_Proxied->onModInstalled(func);
+bool OrganizerProxy::onFinishedRun(const std::function<void (const QString &, unsigned int)> &func)
+{
+ return m_Proxied->onFinishedRun(func);
}
-void OrganizerProxy::refreshModList(bool saveChanges) { m_Proxied->refreshModList(saveChanges); }
+bool OrganizerProxy::onModInstalled(const std::function<void (const QString &)> &func)
+{
+ return m_Proxied->onModInstalled(func);
+}
-IModInterface* OrganizerProxy::installMod(const QString& fileName, const QString& nameSuggestion) {
- return m_Proxied->installMod(fileName, nameSuggestion);
+void OrganizerProxy::refreshModList(bool saveChanges)
+{
+ m_Proxied->refreshModList(saveChanges);
}
-QString OrganizerProxy::resolvePath(const QString& fileName) const { return m_Proxied->resolvePath(fileName); }
+IModInterface *OrganizerProxy::installMod(const QString &fileName, const QString &nameSuggestion)
+{
+ return m_Proxied->installMod(fileName, nameSuggestion);
+}
-QStringList OrganizerProxy::listDirectories(const QString& directoryName) const {
- return m_Proxied->listDirectories(directoryName);
+QString OrganizerProxy::resolvePath(const QString &fileName) const
+{
+ return m_Proxied->resolvePath(fileName);
}
-QStringList OrganizerProxy::findFiles(const QString& path, const std::function<bool(const QString&)>& filter) const {
- return m_Proxied->findFiles(path, filter);
+QStringList OrganizerProxy::listDirectories(const QString &directoryName) const
+{
+ return m_Proxied->listDirectories(directoryName);
}
-QStringList OrganizerProxy::getFileOrigins(const QString& fileName) const {
- return m_Proxied->getFileOrigins(fileName);
+QStringList OrganizerProxy::findFiles(const QString &path, const std::function<bool(const QString&)> &filter) const
+{
+ return m_Proxied->findFiles(path, filter);
}
-QList<MOBase::IOrganizer::FileInfo>
-OrganizerProxy::findFileInfos(const QString& path,
- const std::function<bool(const MOBase::IOrganizer::FileInfo&)>& filter) const {
- return m_Proxied->findFileInfos(path, filter);
+QStringList OrganizerProxy::getFileOrigins(const QString &fileName) const
+{
+ return m_Proxied->getFileOrigins(fileName);
}
-MOBase::IDownloadManager* OrganizerProxy::downloadManager() const { return m_Proxied->downloadManager(); }
+QList<MOBase::IOrganizer::FileInfo> OrganizerProxy::findFileInfos(const QString &path, const std::function<bool (const MOBase::IOrganizer::FileInfo &)> &filter) const
+{
+ return m_Proxied->findFileInfos(path, filter);
+}
+
+MOBase::IDownloadManager *OrganizerProxy::downloadManager() const
+{
+ return m_Proxied->downloadManager();
+}
-MOBase::IPluginList* OrganizerProxy::pluginList() const { return m_Proxied->pluginList(); }
+MOBase::IPluginList *OrganizerProxy::pluginList() const
+{
+ return m_Proxied->pluginList();
+}
-MOBase::IModList* OrganizerProxy::modList() const { return m_Proxied->modList(); }
+MOBase::IModList *OrganizerProxy::modList() const
+{
+ return m_Proxied->modList();
+}
-MOBase::IProfile* OrganizerProxy::profile() const { return m_Proxied->currentProfile(); }
+MOBase::IProfile *OrganizerProxy::profile() const
+{
+ return m_Proxied->currentProfile();
+}
-MOBase::IPluginGame const* OrganizerProxy::managedGame() const { return m_Proxied->managedGame(); }
+MOBase::IPluginGame const *OrganizerProxy::managedGame() const
+{
+ return m_Proxied->managedGame();
+}
-QStringList OrganizerProxy::modsSortedByProfilePriority() const { return m_Proxied->modsSortedByProfilePriority(); }
+QStringList OrganizerProxy::modsSortedByProfilePriority() const
+{
+ return m_Proxied->modsSortedByProfilePriority();
+}
diff --git a/src/organizerproxy.h b/src/organizerproxy.h
index cb14a838..7004db14 100644
--- a/src/organizerproxy.h
+++ b/src/organizerproxy.h
@@ -1,60 +1,63 @@
#ifndef ORGANIZERPROXY_H
#define ORGANIZERPROXY_H
+
#include <imoinfo.h>
class OrganizerCore;
-class OrganizerProxy : public MOBase::IOrganizer {
+class OrganizerProxy : public MOBase::IOrganizer
+{
public:
- OrganizerProxy(OrganizerCore* organizer, const QString& pluginName);
- virtual MOBase::IModRepositoryBridge* createNexusBridge() const;
- virtual QString profileName() const;
- virtual QString profilePath() const;
- virtual QString downloadsPath() const;
- virtual QString overwritePath() const;
- virtual QString basePath() const;
- virtual MOBase::VersionInfo appVersion() const;
- virtual MOBase::IModInterface* getMod(const QString& name) const;
- virtual MOBase::IModInterface* createMod(MOBase::GuessedValue<QString>& name);
- virtual bool removeMod(MOBase::IModInterface* mod);
- virtual void modDataChanged(MOBase::IModInterface* mod);
- virtual QVariant pluginSetting(const QString& pluginName, const QString& key) const;
- virtual void setPluginSetting(const QString& pluginName, const QString& key, const QVariant& value);
- virtual QVariant persistent(const QString& pluginName, const QString& key, const QVariant& def = QVariant()) const;
- virtual void setPersistent(const QString& pluginName, const QString& key, const QVariant& value, bool sync = true);
- virtual QString pluginDataPath() const;
- virtual MOBase::IModInterface* installMod(const QString& fileName, const QString& nameSuggestion = QString());
- virtual QString resolvePath(const QString& fileName) const;
- virtual QStringList listDirectories(const QString& directoryName) const;
- virtual QStringList findFiles(const QString& path, const std::function<bool(const QString&)>& filter) const;
- virtual QStringList getFileOrigins(const QString& fileName) const;
- virtual QList<FileInfo> findFileInfos(const QString& path,
- const std::function<bool(const FileInfo&)>& filter) const;
+ OrganizerProxy(OrganizerCore *organizer, const QString &pluginName);
+
+ virtual MOBase::IModRepositoryBridge *createNexusBridge() const;
+ virtual QString profileName() const;
+ virtual QString profilePath() const;
+ virtual QString downloadsPath() const;
+ virtual QString overwritePath() const;
+ virtual QString basePath() const;
+ virtual MOBase::VersionInfo appVersion() const;
+ virtual MOBase::IModInterface *getMod(const QString &name) const;
+ virtual MOBase::IModInterface *createMod(MOBase::GuessedValue<QString> &name);
+ virtual bool removeMod(MOBase::IModInterface *mod);
+ virtual void modDataChanged(MOBase::IModInterface *mod);
+ virtual QVariant pluginSetting(const QString &pluginName, const QString &key) const;
+ virtual void setPluginSetting(const QString &pluginName, const QString &key, const QVariant &value);
+ virtual QVariant persistent(const QString &pluginName, const QString &key, const QVariant &def = QVariant()) const;
+ virtual void setPersistent(const QString &pluginName, const QString &key, const QVariant &value, bool sync = true);
+ virtual QString pluginDataPath() const;
+ virtual MOBase::IModInterface *installMod(const QString &fileName, const QString &nameSuggestion = QString());
+ virtual QString resolvePath(const QString &fileName) const;
+ virtual QStringList listDirectories(const QString &directoryName) const;
+ virtual QStringList findFiles(const QString &path, const std::function<bool(const QString &)> &filter) const;
+ virtual QStringList getFileOrigins(const QString &fileName) const;
+ virtual QList<FileInfo> findFileInfos(const QString &path, const std::function<bool(const FileInfo&)> &filter) const;
- virtual MOBase::IDownloadManager* downloadManager() const;
- virtual MOBase::IPluginList* pluginList() const;
- virtual MOBase::IModList* modList() const;
- virtual MOBase::IProfile* profile() const override;
- virtual HANDLE startApplication(const QString& executable, const QStringList& args = QStringList(),
- const QString& cwd = "", const QString& profile = "");
- virtual bool waitForApplication(HANDLE handle, LPDWORD exitCode = nullptr) const;
- virtual void refreshModList(bool saveChanges);
+ virtual MOBase::IDownloadManager *downloadManager() const;
+ virtual MOBase::IPluginList *pluginList() const;
+ virtual MOBase::IModList *modList() const;
+ virtual MOBase::IProfile *profile() const override;
+ virtual HANDLE startApplication(const QString &executable, const QStringList &args = QStringList(), const QString &cwd = "", const QString &profile = "");
+ virtual bool waitForApplication(HANDLE handle, LPDWORD exitCode = nullptr) const;
+ virtual void refreshModList(bool saveChanges);
- virtual bool onAboutToRun(const std::function<bool(const QString&)>& func);
- virtual bool onFinishedRun(const std::function<void(const QString&, unsigned int)>& func);
- virtual bool onModInstalled(const std::function<void(const QString&)>& func);
+ virtual bool onAboutToRun(const std::function<bool(const QString&)> &func);
+ virtual bool onFinishedRun(const std::function<void (const QString&, unsigned int)> &func);
+ virtual bool onModInstalled(const std::function<void (const QString&)> &func);
- virtual MOBase::IPluginGame const* managedGame() const;
+ virtual MOBase::IPluginGame const *managedGame() const;
- virtual QStringList modsSortedByProfilePriority() const;
+ virtual QStringList modsSortedByProfilePriority() const;
private:
- OrganizerCore* m_Proxied;
- const QString& m_PluginName;
+ OrganizerCore *m_Proxied;
+
+ const QString &m_PluginName;
+
};
#endif // ORGANIZERPROXY_H
diff --git a/src/overwriteinfodialog.cpp b/src/overwriteinfodialog.cpp
index b2b1710b..e956b025 100644
--- a/src/overwriteinfodialog.cpp
+++ b/src/overwriteinfodialog.cpp
@@ -18,213 +18,243 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "overwriteinfodialog.h"
-#include "report.h"
#include "ui_overwriteinfodialog.h"
+#include "report.h"
#include "utility.h"
-#include <QMenu>
#include <QMessageBox>
+#include <QMenu>
#include <Shlwapi.h>
+
using namespace MOBase;
+
class MyFileSystemModel : public QFileSystemModel {
public:
- MyFileSystemModel(QObject* parent) : QFileSystemModel(parent), m_RegularColumnCount(0) {}
+ MyFileSystemModel(QObject *parent)
+ : QFileSystemModel(parent), m_RegularColumnCount(0) {}
- virtual int columnCount(const QModelIndex& parent) const {
- m_RegularColumnCount = QFileSystemModel::columnCount(parent);
- return m_RegularColumnCount;
- }
+ virtual int columnCount(const QModelIndex &parent) const {
+ m_RegularColumnCount = QFileSystemModel::columnCount(parent);
+ return m_RegularColumnCount;
+ }
- virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const {
- if ((orientation == Qt::Horizontal) && (section >= m_RegularColumnCount)) {
- if (role == Qt::DisplayRole) {
- return tr("Overwrites");
- } else {
- return QVariant();
- }
- } else {
- return QFileSystemModel::headerData(section, orientation, role);
- }
+ virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const {
+ if ((orientation == Qt::Horizontal) &&
+ (section >= m_RegularColumnCount)) {
+ if (role == Qt::DisplayRole) {
+ return tr("Overwrites");
+ } else {
+ return QVariant();
+ }
+ } else {
+ return QFileSystemModel::headerData(section, orientation, role);
}
+ }
- virtual QVariant data(const QModelIndex& index, int role) const {
- if (index.column() == m_RegularColumnCount + 0) {
- if (role == Qt::DisplayRole) {
- return tr("not implemented");
- } else {
- return QVariant();
- }
- } else {
- return QFileSystemModel::data(index, role);
- }
+ virtual QVariant data(const QModelIndex &index, int role) const {
+ if (index.column() == m_RegularColumnCount + 0) {
+ if (role == Qt::DisplayRole) {
+ return tr("not implemented");
+ } else {
+ return QVariant();
+ }
+ } else {
+ return QFileSystemModel::data(index, role);
}
+ }
private:
- mutable int m_RegularColumnCount;
+ mutable int m_RegularColumnCount;
};
-OverwriteInfoDialog::OverwriteInfoDialog(ModInfo::Ptr modInfo, QWidget* parent)
- : QDialog(parent), ui(new Ui::OverwriteInfoDialog), m_FileSystemModel(nullptr), m_DeleteAction(nullptr),
- m_RenameAction(nullptr), m_OpenAction(nullptr) {
- ui->setupUi(this);
- this->setWindowModality(Qt::NonModal);
+OverwriteInfoDialog::OverwriteInfoDialog(ModInfo::Ptr modInfo, QWidget *parent)
+ : QDialog(parent), ui(new Ui::OverwriteInfoDialog), m_FileSystemModel(nullptr),
+ m_DeleteAction(nullptr), m_RenameAction(nullptr), m_OpenAction(nullptr)
+{
+ ui->setupUi(this);
+
+ this->setWindowModality(Qt::NonModal);
- m_FileSystemModel = new MyFileSystemModel(this);
- m_FileSystemModel->setReadOnly(false);
- setModInfo(modInfo);
- ui->filesView->setModel(m_FileSystemModel);
- ui->filesView->setRootIndex(m_FileSystemModel->index(modInfo->absolutePath()));
- ui->filesView->setColumnWidth(0, 250);
+ m_FileSystemModel = new MyFileSystemModel(this);
+ m_FileSystemModel->setReadOnly(false);
+ setModInfo(modInfo);
+ ui->filesView->setModel(m_FileSystemModel);
+ ui->filesView->setRootIndex(m_FileSystemModel->index(modInfo->absolutePath()));
+ ui->filesView->setColumnWidth(0, 250);
- m_DeleteAction = new QAction(tr("&Delete"), ui->filesView);
- m_RenameAction = new QAction(tr("&Rename"), ui->filesView);
- m_OpenAction = new QAction(tr("&Open"), ui->filesView);
- m_NewFolderAction = new QAction(tr("&New Folder"), ui->filesView);
- QObject::connect(m_DeleteAction, SIGNAL(triggered()), this, SLOT(deleteTriggered()));
- QObject::connect(m_RenameAction, SIGNAL(triggered()), this, SLOT(renameTriggered()));
- QObject::connect(m_OpenAction, SIGNAL(triggered()), this, SLOT(openTriggered()));
- QObject::connect(m_NewFolderAction, SIGNAL(triggered()), this, SLOT(createDirectoryTriggered()));
+ m_DeleteAction = new QAction(tr("&Delete"), ui->filesView);
+ m_RenameAction = new QAction(tr("&Rename"), ui->filesView);
+ m_OpenAction = new QAction(tr("&Open"), ui->filesView);
+ m_NewFolderAction = new QAction(tr("&New Folder"), ui->filesView);
+ QObject::connect(m_DeleteAction, SIGNAL(triggered()), this, SLOT(deleteTriggered()));
+ QObject::connect(m_RenameAction, SIGNAL(triggered()), this, SLOT(renameTriggered()));
+ QObject::connect(m_OpenAction, SIGNAL(triggered()), this, SLOT(openTriggered()));
+ QObject::connect(m_NewFolderAction, SIGNAL(triggered()), this, SLOT(createDirectoryTriggered()));
}
-OverwriteInfoDialog::~OverwriteInfoDialog() { delete ui; }
+OverwriteInfoDialog::~OverwriteInfoDialog()
+{
+ delete ui;
+}
-void OverwriteInfoDialog::setModInfo(ModInfo::Ptr modInfo) {
- m_ModInfo = modInfo;
- if (QDir(modInfo->absolutePath()).exists()) {
- m_FileSystemModel->setRootPath(modInfo->absolutePath());
- } else {
- throw MyException(tr("%1 not found").arg(modInfo->absolutePath()));
- }
+void OverwriteInfoDialog::setModInfo(ModInfo::Ptr modInfo)
+{
+ m_ModInfo = modInfo;
+ if (QDir(modInfo->absolutePath()).exists()) {
+ m_FileSystemModel->setRootPath(modInfo->absolutePath());
+ } else {
+ throw MyException(tr("%1 not found").arg(modInfo->absolutePath()));
+ }
}
-bool OverwriteInfoDialog::recursiveDelete(const QModelIndex& index) {
- for (int childRow = 0; childRow < m_FileSystemModel->rowCount(index); ++childRow) {
- QModelIndex childIndex = m_FileSystemModel->index(childRow, 0, index);
- if (m_FileSystemModel->isDir(childIndex)) {
- if (!recursiveDelete(childIndex)) {
- qCritical("failed to delete %s", m_FileSystemModel->fileName(childIndex).toUtf8().constData());
- return false;
- }
- } else {
- if (!m_FileSystemModel->remove(childIndex)) {
- qCritical("failed to delete %s", m_FileSystemModel->fileName(childIndex).toUtf8().constData());
- return false;
- }
- }
- }
- if (!m_FileSystemModel->remove(index)) {
- qCritical("failed to delete %s", m_FileSystemModel->fileName(index).toUtf8().constData());
+bool OverwriteInfoDialog::recursiveDelete(const QModelIndex &index)
+{
+ for (int childRow = 0; childRow < m_FileSystemModel->rowCount(index); ++childRow) {
+ QModelIndex childIndex = m_FileSystemModel->index(childRow, 0, index);
+ if (m_FileSystemModel->isDir(childIndex)) {
+ if (!recursiveDelete(childIndex)) {
+ qCritical("failed to delete %s", m_FileSystemModel->fileName(childIndex).toUtf8().constData());
+ return false;
+ }
+ } else {
+ if (!m_FileSystemModel->remove(childIndex)) {
+ qCritical("failed to delete %s", m_FileSystemModel->fileName(childIndex).toUtf8().constData());
return false;
+ }
}
- return true;
+ }
+ if (!m_FileSystemModel->remove(index)) {
+ qCritical("failed to delete %s", m_FileSystemModel->fileName(index).toUtf8().constData());
+ return false;
+ }
+ return true;
}
-void OverwriteInfoDialog::deleteFile(const QModelIndex& index) {
- bool res = m_FileSystemModel->isDir(index) ? recursiveDelete(index) : m_FileSystemModel->remove(index);
- if (!res) {
- QString fileName = m_FileSystemModel->fileName(index);
- reportError(tr("Failed to delete \"%1\"").arg(fileName));
- }
+void OverwriteInfoDialog::deleteFile(const QModelIndex &index)
+{
+
+ bool res = m_FileSystemModel->isDir(index) ? recursiveDelete(index)
+ : m_FileSystemModel->remove(index);
+ if (!res) {
+ QString fileName = m_FileSystemModel->fileName(index);
+ reportError(tr("Failed to delete \"%1\"").arg(fileName));
+ }
}
-void OverwriteInfoDialog::deleteTriggered() {
- if (m_FileSelection.count() == 0) {
- return;
- } else if (m_FileSelection.count() == 1) {
- QString fileName = m_FileSystemModel->fileName(m_FileSelection.at(0));
- if (QMessageBox::question(this, tr("Confirm"), tr("Are sure you want to delete \"%1\"?").arg(fileName),
- QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
- return;
- }
- } else {
- if (QMessageBox::question(this, tr("Confirm"), tr("Are sure you want to delete the selected files?"),
- QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
- return;
- }
+
+void OverwriteInfoDialog::deleteTriggered()
+{
+ if (m_FileSelection.count() == 0) {
+ return;
+ } else if (m_FileSelection.count() == 1) {
+ QString fileName = m_FileSystemModel->fileName(m_FileSelection.at(0));
+ if (QMessageBox::question(this, tr("Confirm"), tr("Are sure you want to delete \"%1\"?").arg(fileName),
+ QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
+ return;
+ }
+ } else {
+ if (QMessageBox::question(this, tr("Confirm"), tr("Are sure you want to delete the selected files?"),
+ QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
+ return;
}
+ }
- foreach (QModelIndex index, m_FileSelection) { deleteFile(index); }
+ foreach(QModelIndex index, m_FileSelection) {
+ deleteFile(index);
+ }
}
-void OverwriteInfoDialog::renameTriggered() {
- QModelIndex selection = m_FileSelection.at(0);
- QModelIndex index = selection.sibling(selection.row(), 0);
- if (!index.isValid() || m_FileSystemModel->isReadOnly()) {
- return;
- }
- ui->filesView->edit(index);
+void OverwriteInfoDialog::renameTriggered()
+{
+ QModelIndex selection = m_FileSelection.at(0);
+ QModelIndex index = selection.sibling(selection.row(), 0);
+ if (!index.isValid() || m_FileSystemModel->isReadOnly()) {
+ return;
+ }
+
+ ui->filesView->edit(index);
}
-void OverwriteInfoDialog::openFile(const QModelIndex& index) {
- QString fileName = m_FileSystemModel->filePath(index);
- HINSTANCE res = ::ShellExecuteW(nullptr, L"open", ToWString(fileName).c_str(), nullptr, nullptr, SW_SHOW);
- if ((int)res <= 32) {
- qCritical("failed to invoke %s: %d", fileName.toUtf8().constData(), res);
- }
+void OverwriteInfoDialog::openFile(const QModelIndex &index)
+{
+ QString fileName = m_FileSystemModel->filePath(index);
+
+ HINSTANCE res = ::ShellExecuteW(nullptr, L"open", ToWString(fileName).c_str(), nullptr, nullptr, SW_SHOW);
+ if ((int)res <= 32) {
+ qCritical("failed to invoke %s: %d", fileName.toUtf8().constData(), res);
+ }
}
-void OverwriteInfoDialog::openTriggered() {
- foreach (QModelIndex idx, m_FileSelection) { openFile(idx); }
+
+void OverwriteInfoDialog::openTriggered()
+{
+ foreach(QModelIndex idx, m_FileSelection) {
+ openFile(idx);
+ }
}
-void OverwriteInfoDialog::createDirectoryTriggered() {
- QModelIndex selection = m_FileSelection.at(0);
+void OverwriteInfoDialog::createDirectoryTriggered()
+{
+ QModelIndex selection = m_FileSelection.at(0);
- QModelIndex index = m_FileSystemModel->isDir(selection) ? selection : selection.parent();
- index = index.sibling(index.row(), 0);
+ QModelIndex index = m_FileSystemModel->isDir(selection) ? selection
+ : selection.parent();
+ index = index.sibling(index.row(), 0);
- QString name = tr("New Folder");
- QString path = m_FileSystemModel->filePath(index).append("/");
+ QString name = tr("New Folder");
+ QString path = m_FileSystemModel->filePath(index).append("/");
- QModelIndex existingIndex = m_FileSystemModel->index(path + name);
- int suffix = 1;
- while (existingIndex.isValid()) {
- name = tr("New Folder") + QString::number(suffix++);
- existingIndex = m_FileSystemModel->index(path + name);
- }
+ QModelIndex existingIndex = m_FileSystemModel->index(path + name);
+ int suffix = 1;
+ while (existingIndex.isValid()) {
+ name = tr("New Folder") + QString::number(suffix++);
+ existingIndex = m_FileSystemModel->index(path + name);
+ }
- QModelIndex newIndex = m_FileSystemModel->mkdir(index, name);
- if (!newIndex.isValid()) {
- reportError(tr("Failed to create \"%1\"").arg(name));
- return;
- }
+ QModelIndex newIndex = m_FileSystemModel->mkdir(index, name);
+ if (!newIndex.isValid()) {
+ reportError(tr("Failed to create \"%1\"").arg(name));
+ return;
+ }
- ui->filesView->setCurrentIndex(newIndex);
- ui->filesView->edit(newIndex);
+ ui->filesView->setCurrentIndex(newIndex);
+ ui->filesView->edit(newIndex);
}
-void OverwriteInfoDialog::on_filesView_customContextMenuRequested(const QPoint& pos) {
- QItemSelectionModel* selectionModel = ui->filesView->selectionModel();
- m_FileSelection = selectionModel->selectedRows(0);
- QMenu menu(ui->filesView);
+void OverwriteInfoDialog::on_filesView_customContextMenuRequested(const QPoint &pos)
+{
+ QItemSelectionModel *selectionModel = ui->filesView->selectionModel();
+ m_FileSelection = selectionModel->selectedRows(0);
+
+ QMenu menu(ui->filesView);
- menu.addAction(m_NewFolderAction);
+ menu.addAction(m_NewFolderAction);
- bool hasFiles = false;
+ bool hasFiles = false;
- foreach (QModelIndex idx, m_FileSelection) {
- if (m_FileSystemModel->fileInfo(idx).isFile()) {
- hasFiles = true;
- break;
- }
+ foreach(QModelIndex idx, m_FileSelection) {
+ if (m_FileSystemModel->fileInfo(idx).isFile()) {
+ hasFiles = true;
+ break;
}
+ }
- if (selectionModel->hasSelection()) {
- if (hasFiles) {
- menu.addAction(m_OpenAction);
- }
- menu.addAction(m_RenameAction);
- menu.addAction(m_DeleteAction);
- } else {
- m_FileSelection.clear();
- m_FileSelection.append(m_FileSystemModel->index(m_FileSystemModel->rootPath(), 0));
+ if (selectionModel->hasSelection()) {
+ if (hasFiles) {
+ menu.addAction(m_OpenAction);
}
- menu.exec(ui->filesView->mapToGlobal(pos));
+ menu.addAction(m_RenameAction);
+ menu.addAction(m_DeleteAction);
+ } else {
+ m_FileSelection.clear();
+ m_FileSelection.append(m_FileSystemModel->index(m_FileSystemModel->rootPath(), 0));
+ }
+ menu.exec(ui->filesView->mapToGlobal(pos));
}
diff --git a/src/overwriteinfodialog.h b/src/overwriteinfodialog.h
index 110601dc..eb182292 100644
--- a/src/overwriteinfodialog.h
+++ b/src/overwriteinfodialog.h
@@ -28,41 +28,46 @@ namespace Ui {
class OverwriteInfoDialog;
}
-class OverwriteInfoDialog : public QDialog {
- Q_OBJECT
-
+class OverwriteInfoDialog : public QDialog
+{
+ Q_OBJECT
+
public:
- explicit OverwriteInfoDialog(ModInfo::Ptr modInfo, QWidget* parent = 0);
- ~OverwriteInfoDialog();
- ModInfo::Ptr modInfo() const { return m_ModInfo; }
+ explicit OverwriteInfoDialog(ModInfo::Ptr modInfo, QWidget *parent = 0);
+ ~OverwriteInfoDialog();
+
+ ModInfo::Ptr modInfo() const { return m_ModInfo; }
- void setModInfo(ModInfo::Ptr modInfo);
+ void setModInfo(ModInfo::Ptr modInfo);
private:
- void openFile(const QModelIndex& index);
- bool recursiveDelete(const QModelIndex& index);
- void deleteFile(const QModelIndex& index);
+
+ void openFile(const QModelIndex &index);
+ bool recursiveDelete(const QModelIndex &index);
+ void deleteFile(const QModelIndex &index);
private slots:
- void deleteTriggered();
- void renameTriggered();
- void openTriggered();
- void createDirectoryTriggered();
+ void deleteTriggered();
+ void renameTriggered();
+ void openTriggered();
+ void createDirectoryTriggered();
- void on_filesView_customContextMenuRequested(const QPoint& pos);
+ void on_filesView_customContextMenuRequested(const QPoint &pos);
private:
- Ui::OverwriteInfoDialog* ui;
- QFileSystemModel* m_FileSystemModel;
- QModelIndexList m_FileSelection;
- QAction* m_DeleteAction;
- QAction* m_RenameAction;
- QAction* m_OpenAction;
- QAction* m_NewFolderAction;
- ModInfo::Ptr m_ModInfo;
+ Ui::OverwriteInfoDialog *ui;
+ QFileSystemModel *m_FileSystemModel;
+ QModelIndexList m_FileSelection;
+ QAction *m_DeleteAction;
+ QAction *m_RenameAction;
+ QAction *m_OpenAction;
+ QAction *m_NewFolderAction;
+
+ ModInfo::Ptr m_ModInfo;
+
};
#endif // OVERWRITEINFODIALOG_H
diff --git a/src/persistentcookiejar.cpp b/src/persistentcookiejar.cpp
index 0e17d5b7..a6eb78fa 100644
--- a/src/persistentcookiejar.cpp
+++ b/src/persistentcookiejar.cpp
@@ -1,70 +1,72 @@
#include "persistentcookiejar.h"
+#include <QTemporaryFile>
#include <QDataStream>
#include <QNetworkCookie>
-#include <QTemporaryFile>
-PersistentCookieJar::PersistentCookieJar(const QString& fileName, QObject* parent)
- : QNetworkCookieJar(parent), m_FileName(fileName) {
- restore();
+
+PersistentCookieJar::PersistentCookieJar(const QString &fileName, QObject *parent)
+: QNetworkCookieJar(parent), m_FileName(fileName)
+{
+ restore();
}
PersistentCookieJar::~PersistentCookieJar() {
- qDebug("save %s", qPrintable(m_FileName));
- save();
+ qDebug("save %s", qPrintable(m_FileName));
+ save();
}
void PersistentCookieJar::clear() {
- for (const QNetworkCookie& cookie : allCookies()) {
- deleteCookie(cookie);
- }
+ for (const QNetworkCookie &cookie : allCookies()) {
+ deleteCookie(cookie);
+ }
}
void PersistentCookieJar::save() {
- QTemporaryFile file;
- if (!file.open()) {
- qCritical("failed to save cookies: couldn't create temporary file");
- return;
- }
- QDataStream data(&file);
+ QTemporaryFile file;
+ if (!file.open()) {
+ qCritical("failed to save cookies: couldn't create temporary file");
+ return;
+ }
+ QDataStream data(&file);
- QList<QNetworkCookie> cookies = allCookies();
- data << static_cast<quint32>(cookies.size());
+ QList<QNetworkCookie> cookies = allCookies();
+ data << static_cast<quint32>(cookies.size());
- for (const QNetworkCookie& cookie : allCookies()) {
- data << cookie.toRawForm();
- }
+ for (const QNetworkCookie &cookie : allCookies()) {
+ data << cookie.toRawForm();
+ }
- {
- QFile oldCookies(m_FileName);
- if (oldCookies.exists()) {
- if (!oldCookies.remove()) {
- qCritical("failed to save cookies: failed to remove %s", qPrintable(m_FileName));
- return;
- }
- } // if it doesn't exists that's fine
- }
+ {
+ QFile oldCookies(m_FileName);
+ if (oldCookies.exists()) {
+ if (!oldCookies.remove()) {
+ qCritical("failed to save cookies: failed to remove %s", qPrintable(m_FileName));
+ return;
+ }
+ } // if it doesn't exists that's fine
+ }
- if (!file.copy(m_FileName)) {
- qCritical("failed to save cookies: failed to write %s", qPrintable(m_FileName));
- }
+ if (!file.copy(m_FileName)) {
+ qCritical("failed to save cookies: failed to write %s", qPrintable(m_FileName));
+ }
}
void PersistentCookieJar::restore() {
- QFile file(m_FileName);
- if (!file.open(QIODevice::ReadOnly)) {
- // not necessarily a problem, the file may just not exist (yet)
- return;
- }
+ QFile file(m_FileName);
+ if (!file.open(QIODevice::ReadOnly)) {
+ // not necessarily a problem, the file may just not exist (yet)
+ return;
+ }
- QList<QNetworkCookie> allCookies;
+ QList<QNetworkCookie> allCookies;
- QDataStream data(&file);
- quint32 count;
- data >> count;
- for (quint32 i = 0; i < count; ++i) {
- QByteArray cookieRaw;
- data >> cookieRaw;
- allCookies.append(QNetworkCookie::parseCookies(cookieRaw));
- }
- setAllCookies(allCookies);
+ QDataStream data(&file);
+ quint32 count;
+ data >> count;
+ for (quint32 i = 0; i < count; ++i) {
+ QByteArray cookieRaw;
+ data >> cookieRaw;
+ allCookies.append(QNetworkCookie::parseCookies(cookieRaw));
+ }
+ setAllCookies(allCookies);
}
diff --git a/src/persistentcookiejar.h b/src/persistentcookiejar.h
index 82426ef9..0ff747ee 100644
--- a/src/persistentcookiejar.h
+++ b/src/persistentcookiejar.h
@@ -3,23 +3,28 @@
#include <QNetworkCookieJar>
+
class PersistentCookieJar : public QNetworkCookieJar {
- Q_OBJECT
+ Q_OBJECT
public:
- PersistentCookieJar(const QString& fileName, QObject* parent = 0);
- virtual ~PersistentCookieJar();
+ PersistentCookieJar(const QString &fileName, QObject *parent = 0);
+ virtual ~PersistentCookieJar();
- void clear();
+ void clear();
private:
- void save();
- void restore();
+ void save();
+
+ void restore();
private:
- QString m_FileName;
+
+ QString m_FileName;
+
};
+
#endif // PERSISTENTCOOKIEJAR_H
diff --git a/src/plugincontainer.cpp b/src/plugincontainer.cpp
index 39c49deb..c980c0a1 100644
--- a/src/plugincontainer.cpp
+++ b/src/plugincontainer.cpp
@@ -1,312 +1,348 @@
#include "plugincontainer.h"
#include "organizerproxy.h"
#include "report.h"
+#include <ipluginproxy.h>
+#include <idownloadmanager.h>
+#include <appconfig.h>
#include <QAction>
+#include <QToolButton>
#include <QCoreApplication>
-#include <QDirIterator>
#include <QMessageBox>
-#include <QToolButton>
-#include <appconfig.h>
-#include <boost/fusion/algorithm/iteration/for_each.hpp>
+#include <QDirIterator>
+#include <boost/fusion/sequence/intrinsic/at_key.hpp>
#include <boost/fusion/include/at_key.hpp>
+#include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/fusion/include/for_each.hpp>
-#include <boost/fusion/sequence/intrinsic/at_key.hpp>
-#include <idownloadmanager.h>
-#include <ipluginproxy.h>
using namespace MOBase;
using namespace MOShared;
namespace bf = boost::fusion;
-PluginContainer::PluginContainer(OrganizerCore* organizer) : m_Organizer(organizer), m_UserInterface(nullptr) {}
-void PluginContainer::setUserInterface(IUserInterface* userInterface, QWidget* widget) {
- for (IPluginProxy* proxy : bf::at_key<IPluginProxy>(m_Plugins)) {
- proxy->setParentWidget(widget);
- }
+PluginContainer::PluginContainer(OrganizerCore *organizer)
+ : m_Organizer(organizer)
+ , m_UserInterface(nullptr)
+{
+}
- if (userInterface != nullptr) {
- for (IPluginModPage* modPage : bf::at_key<IPluginModPage>(m_Plugins)) {
- userInterface->registerModPage(modPage);
- }
- for (IPluginTool* tool : bf::at_key<IPluginTool>(m_Plugins)) {
- userInterface->registerPluginTool(tool);
- }
+void PluginContainer::setUserInterface(IUserInterface *userInterface, QWidget *widget)
+{
+ for (IPluginProxy *proxy : bf::at_key<IPluginProxy>(m_Plugins)) {
+ proxy->setParentWidget(widget);
+ }
+
+ if (userInterface != nullptr) {
+ for (IPluginModPage *modPage : bf::at_key<IPluginModPage>(m_Plugins)) {
+ userInterface->registerModPage(modPage);
+ }
+
+ for (IPluginTool *tool : bf::at_key<IPluginTool>(m_Plugins)) {
+ userInterface->registerPluginTool(tool);
}
+ }
- m_UserInterface = userInterface;
+ m_UserInterface = userInterface;
}
-QStringList PluginContainer::pluginFileNames() const {
- QStringList result;
- for (QPluginLoader* loader : m_PluginLoaders) {
- result.append(loader->fileName());
- }
- return result;
+
+QStringList PluginContainer::pluginFileNames() const
+{
+ QStringList result;
+ for (QPluginLoader *loader : m_PluginLoaders) {
+ result.append(loader->fileName());
+ }
+ return result;
}
-bool PluginContainer::verifyPlugin(IPlugin* plugin) {
- if (plugin == nullptr) {
- return false;
- } else if (!plugin->init(new OrganizerProxy(m_Organizer, plugin->name()))) {
- qWarning("plugin failed to initialize");
- return false;
- }
- return true;
+
+bool PluginContainer::verifyPlugin(IPlugin *plugin)
+{
+ if (plugin == nullptr) {
+ return false;
+ } else if (!plugin->init(new OrganizerProxy(m_Organizer, plugin->name()))) {
+ qWarning("plugin failed to initialize");
+ return false;
+ }
+ return true;
}
-void PluginContainer::registerGame(IPluginGame* game) { m_SupportedGames.insert({game->gameName(), game}); }
-bool PluginContainer::registerPlugin(QObject* plugin, const QString& fileName) {
- { // generic treatment for all plugins
- IPlugin* pluginObj = qobject_cast<IPlugin*>(plugin);
- if (pluginObj == nullptr) {
- qDebug("not an IPlugin");
- return false;
- }
- plugin->setProperty("filename", fileName);
- m_Organizer->settings().registerPlugin(pluginObj);
+void PluginContainer::registerGame(IPluginGame *game)
+{
+ m_SupportedGames.insert({ game->gameName(), game });
+}
+
+
+bool PluginContainer::registerPlugin(QObject *plugin, const QString &fileName)
+{
+ { // generic treatment for all plugins
+ IPlugin *pluginObj = qobject_cast<IPlugin*>(plugin);
+ if (pluginObj == nullptr) {
+ qDebug("not an IPlugin");
+ return false;
}
+ plugin->setProperty("filename", fileName);
+ m_Organizer->settings().registerPlugin(pluginObj);
+ }
- { // diagnosis plugin
- IPluginDiagnose* diagnose = qobject_cast<IPluginDiagnose*>(plugin);
- if (diagnose != nullptr) {
- bf::at_key<IPluginDiagnose>(m_Plugins).push_back(diagnose);
- m_DiagnosisConnections.push_back(diagnose->onInvalidated([&]() { emit diagnosisUpdate(); }));
- }
+ { // diagnosis plugin
+ IPluginDiagnose *diagnose = qobject_cast<IPluginDiagnose*>(plugin);
+ if (diagnose != nullptr) {
+ bf::at_key<IPluginDiagnose>(m_Plugins).push_back(diagnose);
+ m_DiagnosisConnections.push_back(
+ diagnose->onInvalidated([&] () { emit diagnosisUpdate(); })
+ );
}
- { // file mapper plugin
- IPluginFileMapper* mapper = qobject_cast<IPluginFileMapper*>(plugin);
- if (mapper != nullptr) {
- bf::at_key<IPluginFileMapper>(m_Plugins).push_back(mapper);
- }
+ }
+ { // file mapper plugin
+ IPluginFileMapper *mapper = qobject_cast<IPluginFileMapper*>(plugin);
+ if (mapper != nullptr) {
+ bf::at_key<IPluginFileMapper>(m_Plugins).push_back(mapper);
}
- { // mod page plugin
- IPluginModPage* modPage = qobject_cast<IPluginModPage*>(plugin);
- if (verifyPlugin(modPage)) {
- bf::at_key<IPluginModPage>(m_Plugins).push_back(modPage);
- return true;
- }
+ }
+ { // mod page plugin
+ IPluginModPage *modPage = qobject_cast<IPluginModPage*>(plugin);
+ if (verifyPlugin(modPage)) {
+ bf::at_key<IPluginModPage>(m_Plugins).push_back(modPage);
+ return true;
}
- { // game plugin
- IPluginGame* game = qobject_cast<IPluginGame*>(plugin);
- if (verifyPlugin(game)) {
- bf::at_key<IPluginGame>(m_Plugins).push_back(game);
- registerGame(game);
- return true;
- }
+ }
+ { // game plugin
+ IPluginGame *game = qobject_cast<IPluginGame*>(plugin);
+ if (verifyPlugin(game)) {
+ bf::at_key<IPluginGame>(m_Plugins).push_back(game);
+ registerGame(game);
+ return true;
}
- { // tool plugins
- IPluginTool* tool = qobject_cast<IPluginTool*>(plugin);
- if (verifyPlugin(tool)) {
- bf::at_key<IPluginTool>(m_Plugins).push_back(tool);
- return true;
- }
+ }
+ { // tool plugins
+ IPluginTool *tool = qobject_cast<IPluginTool*>(plugin);
+ if (verifyPlugin(tool)) {
+ bf::at_key<IPluginTool>(m_Plugins).push_back(tool);
+ return true;
}
- { // installer plugins
- IPluginInstaller* installer = qobject_cast<IPluginInstaller*>(plugin);
- if (verifyPlugin(installer)) {
- bf::at_key<IPluginInstaller>(m_Plugins).push_back(installer);
- m_Organizer->installationManager()->registerInstaller(installer);
- return true;
- }
+ }
+ { // installer plugins
+ IPluginInstaller *installer = qobject_cast<IPluginInstaller*>(plugin);
+ if (verifyPlugin(installer)) {
+ bf::at_key<IPluginInstaller>(m_Plugins).push_back(installer);
+ m_Organizer->installationManager()->registerInstaller(installer);
+ return true;
}
- { // preview plugins
- IPluginPreview* preview = qobject_cast<IPluginPreview*>(plugin);
- if (verifyPlugin(preview)) {
- bf::at_key<IPluginPreview>(m_Plugins).push_back(preview);
- m_PreviewGenerator.registerPlugin(preview);
- return true;
- }
+ }
+ { // preview plugins
+ IPluginPreview *preview = qobject_cast<IPluginPreview*>(plugin);
+ if (verifyPlugin(preview)) {
+ bf::at_key<IPluginPreview>(m_Plugins).push_back(preview);
+ m_PreviewGenerator.registerPlugin(preview);
+ return true;
}
- { // proxy plugins
- IPluginProxy* proxy = qobject_cast<IPluginProxy*>(plugin);
- if (verifyPlugin(proxy)) {
- bf::at_key<IPluginProxy>(m_Plugins).push_back(proxy);
- QStringList pluginNames =
- proxy->pluginList(QCoreApplication::applicationDirPath() + "/" + ToQString(AppConfig::pluginPath()));
- for (const QString& pluginName : pluginNames) {
- try {
- QObject* proxiedPlugin = proxy->instantiate(pluginName);
- if (proxiedPlugin != nullptr) {
- if (registerPlugin(proxiedPlugin, pluginName)) {
- qDebug("loaded plugin \"%s\"", qPrintable(QFileInfo(pluginName).fileName()));
- } else {
- qWarning("plugin \"%s\" failed to load. If this plugin is for an older version of MO "
- "you have to update it or delete it if no update exists.",
- qPrintable(pluginName));
- }
- }
- } catch (const std::exception& e) {
- reportError(QObject::tr("failed to initialize plugin %1: %2").arg(pluginName).arg(e.what()));
- }
+ }
+ { // proxy plugins
+ IPluginProxy *proxy = qobject_cast<IPluginProxy*>(plugin);
+ if (verifyPlugin(proxy)) {
+ bf::at_key<IPluginProxy>(m_Plugins).push_back(proxy);
+ QStringList pluginNames = proxy->pluginList(
+ QCoreApplication::applicationDirPath() + "/" + ToQString(AppConfig::pluginPath()));
+ for (const QString &pluginName : pluginNames) {
+ try {
+ QObject *proxiedPlugin = proxy->instantiate(pluginName);
+ if (proxiedPlugin != nullptr) {
+ if (registerPlugin(proxiedPlugin, pluginName)) {
+ qDebug("loaded plugin \"%s\"", qPrintable(QFileInfo(pluginName).fileName()));
+ } else {
+ qWarning("plugin \"%s\" failed to load. If this plugin is for an older version of MO "
+ "you have to update it or delete it if no update exists.",
+ qPrintable(pluginName));
}
- return true;
+ }
+ } catch (const std::exception &e) {
+ reportError(QObject::tr("failed to initialize plugin %1: %2").arg(pluginName).arg(e.what()));
}
+ }
+ return true;
}
+ }
- { // dummy plugins
- // only initialize these, no processing otherwise
- IPlugin* dummy = qobject_cast<IPlugin*>(plugin);
- if (verifyPlugin(dummy)) {
- bf::at_key<IPlugin>(m_Plugins).push_back(dummy);
- return true;
- }
+ { // dummy plugins
+ // only initialize these, no processing otherwise
+ IPlugin *dummy = qobject_cast<IPlugin*>(plugin);
+ if (verifyPlugin(dummy)) {
+ bf::at_key<IPlugin>(m_Plugins).push_back(dummy);
+ return true;
}
+ }
- qDebug("no matching plugin interface");
+ qDebug("no matching plugin interface");
- return false;
+ return false;
}
-struct clearPlugins {
- template <typename T>
- void operator()(T& t) const {
- t.second.clear();
+struct clearPlugins
+{
+ template<typename T>
+ void operator()(T& t) const
+ {
+ t.second.clear();
}
};
-void PluginContainer::unloadPlugins() {
- if (m_UserInterface != nullptr) {
- m_UserInterface->disconnectPlugins();
- }
+void PluginContainer::unloadPlugins()
+{
+ if (m_UserInterface != nullptr) {
+ m_UserInterface->disconnectPlugins();
+ }
- // disconnect all slots before unloading plugins so plugins don't have to take care of that
- m_Organizer->disconnectPlugins();
+ // disconnect all slots before unloading plugins so plugins don't have to take care of that
+ m_Organizer->disconnectPlugins();
- bf::for_each(m_Plugins, clearPlugins());
+ bf::for_each(m_Plugins, clearPlugins());
- for (const boost::signals2::connection& connection : m_DiagnosisConnections) {
- connection.disconnect();
- }
- m_DiagnosisConnections.clear();
+ for (const boost::signals2::connection &connection : m_DiagnosisConnections) {
+ connection.disconnect();
+ }
+ m_DiagnosisConnections.clear();
- while (!m_PluginLoaders.empty()) {
- QPluginLoader* loader = m_PluginLoaders.back();
- m_PluginLoaders.pop_back();
- if ((loader != nullptr) && !loader->unload()) {
- qDebug("failed to unload %s: %s", qPrintable(loader->fileName()), qPrintable(loader->errorString()));
- }
- delete loader;
+ while (!m_PluginLoaders.empty()) {
+ QPluginLoader *loader = m_PluginLoaders.back();
+ m_PluginLoaders.pop_back();
+ if ((loader != nullptr) && !loader->unload()) {
+ qDebug("failed to unload %s: %s", qPrintable(loader->fileName()), qPrintable(loader->errorString()));
}
+ delete loader;
+ }
}
-IPluginGame* PluginContainer::managedGame(const QString& name) const {
- auto iter = m_SupportedGames.find(name);
- if (iter != m_SupportedGames.end()) {
- return iter->second;
- } else {
- return nullptr;
- }
+IPluginGame *PluginContainer::managedGame(const QString &name) const
+{
+ auto iter = m_SupportedGames.find(name);
+ if (iter != m_SupportedGames.end()) {
+ return iter->second;
+ } else {
+ return nullptr;
+ }
}
-const PreviewGenerator& PluginContainer::previewGenerator() const { return m_PreviewGenerator; }
+const PreviewGenerator &PluginContainer::previewGenerator() const
+{
+ return m_PreviewGenerator;
+}
-void PluginContainer::loadPlugins() {
- unloadPlugins();
+void PluginContainer::loadPlugins()
+{
+ unloadPlugins();
- for (QObject* plugin : QPluginLoader::staticInstances()) {
- registerPlugin(plugin, "");
- }
+ for (QObject *plugin : QPluginLoader::staticInstances()) {
+ registerPlugin(plugin, "");
+ }
- QFile loadCheck(qApp->property("dataPath").toString() + "/plugin_loadcheck.tmp");
- if (loadCheck.exists() && loadCheck.open(QIODevice::ReadOnly)) {
- // oh, there was a failed plugin load last time. Find out which plugin was loaded last
- QString fileName;
- while (!loadCheck.atEnd()) {
- fileName = QString::fromUtf8(loadCheck.readLine().constData()).trimmed();
- }
- if (QMessageBox::question(nullptr, QObject::tr("Plugin error"),
- QObject::tr("It appears the plugin \"%1\" failed to load last startup and caused MO "
- "to crash. Do you want to disable it?\n"
- "(Please note: If this is the first time you see this message for this "
- "plugin you may want to give it another try. "
- "The plugin may be able to recover from the problem)")
- .arg(fileName),
- QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes) {
- m_Organizer->settings().addBlacklistPlugin(fileName);
- }
- loadCheck.close();
+ QFile loadCheck(qApp->property("dataPath").toString() + "/plugin_loadcheck.tmp");
+ if (loadCheck.exists() && loadCheck.open(QIODevice::ReadOnly)) {
+ // oh, there was a failed plugin load last time. Find out which plugin was loaded last
+ QString fileName;
+ while (!loadCheck.atEnd()) {
+ fileName = QString::fromUtf8(loadCheck.readLine().constData()).trimmed();
+ }
+ if (QMessageBox::question(nullptr, QObject::tr("Plugin error"),
+ QObject::tr("It appears the plugin \"%1\" failed to load last startup and caused MO to crash. Do you want to disable it?\n"
+ "(Please note: If this is the first time you see this message for this plugin you may want to give it another try. "
+ "The plugin may be able to recover from the problem)").arg(fileName),
+ QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes) {
+ m_Organizer->settings().addBlacklistPlugin(fileName);
}
+ loadCheck.close();
+ }
- loadCheck.open(QIODevice::WriteOnly);
+ loadCheck.open(QIODevice::WriteOnly);
- QString pluginPath = qApp->applicationDirPath() + "/" + ToQString(AppConfig::pluginPath());
- qDebug("looking for plugins in %s", QDir::toNativeSeparators(pluginPath).toUtf8().constData());
- QDirIterator iter(pluginPath, QDir::Files | QDir::NoDotAndDotDot);
+ QString pluginPath = qApp->applicationDirPath() + "/" + ToQString(AppConfig::pluginPath());
+ qDebug("looking for plugins in %s", QDir::toNativeSeparators(pluginPath).toUtf8().constData());
+ QDirIterator iter(pluginPath, QDir::Files | QDir::NoDotAndDotDot);
- while (iter.hasNext()) {
- iter.next();
- if (m_Organizer->settings().pluginBlacklisted(iter.fileName())) {
- qDebug("plugin \"%s\" blacklisted", qPrintable(iter.fileName()));
- continue;
- }
- loadCheck.write(iter.fileName().toUtf8());
- loadCheck.write("\n");
- loadCheck.flush();
- QString pluginName = iter.filePath();
- if (QLibrary::isLibrary(pluginName)) {
- std::unique_ptr<QPluginLoader> pluginLoader(new QPluginLoader(pluginName, this));
- if (pluginLoader->instance() == nullptr) {
- m_FailedPlugins.push_back(pluginName);
- qCritical("failed to load plugin %s: %s", qPrintable(pluginName),
- qPrintable(pluginLoader->errorString()));
- } else {
- if (registerPlugin(pluginLoader->instance(), pluginName)) {
- qDebug("loaded plugin \"%s\"", qPrintable(QFileInfo(pluginName).fileName()));
- m_PluginLoaders.push_back(pluginLoader.release());
- } else {
- m_FailedPlugins.push_back(pluginName);
- qWarning("plugin \"%s\" failed to load (may be outdated)", qPrintable(pluginName));
- }
- }
+ while (iter.hasNext()) {
+ iter.next();
+ if (m_Organizer->settings().pluginBlacklisted(iter.fileName())) {
+ qDebug("plugin \"%s\" blacklisted", qPrintable(iter.fileName()));
+ continue;
+ }
+ loadCheck.write(iter.fileName().toUtf8());
+ loadCheck.write("\n");
+ loadCheck.flush();
+ QString pluginName = iter.filePath();
+ if (QLibrary::isLibrary(pluginName)) {
+ std::unique_ptr<QPluginLoader> pluginLoader(new QPluginLoader(pluginName, this));
+ if (pluginLoader->instance() == nullptr) {
+ m_FailedPlugins.push_back(pluginName);
+ qCritical("failed to load plugin %s: %s",
+ qPrintable(pluginName), qPrintable(pluginLoader->errorString()));
+ } else {
+ if (registerPlugin(pluginLoader->instance(), pluginName)) {
+ qDebug("loaded plugin \"%s\"", qPrintable(QFileInfo(pluginName).fileName()));
+ m_PluginLoaders.push_back(pluginLoader.release());
+ } else {
+ m_FailedPlugins.push_back(pluginName);
+ qWarning("plugin \"%s\" failed to load (may be outdated)", qPrintable(pluginName));
}
+ }
}
+ }
- // remove the load check file on success
- loadCheck.remove();
+ // remove the load check file on success
+ loadCheck.remove();
- bf::at_key<IPluginDiagnose>(m_Plugins).push_back(m_Organizer);
- bf::at_key<IPluginDiagnose>(m_Plugins).push_back(this);
+ bf::at_key<IPluginDiagnose>(m_Plugins).push_back(m_Organizer);
+ bf::at_key<IPluginDiagnose>(m_Plugins).push_back(this);
- m_Organizer->connectPlugins(this);
+ m_Organizer->connectPlugins(this);
}
-std::vector<unsigned int> PluginContainer::activeProblems() const {
- std::vector<unsigned int> problems;
- if (m_FailedPlugins.size()) {
- problems.push_back(PROBLEM_PLUGINSNOTLOADED);
- }
- return problems;
+
+std::vector<unsigned int> PluginContainer::activeProblems() const
+{
+ std::vector<unsigned int> problems;
+ if (m_FailedPlugins.size()) {
+ problems.push_back(PROBLEM_PLUGINSNOTLOADED);
+ }
+ return problems;
}
-QString PluginContainer::shortDescription(unsigned int key) const {
- switch (key) {
+QString PluginContainer::shortDescription(unsigned int key) const
+{
+ switch (key) {
case PROBLEM_PLUGINSNOTLOADED: {
- return tr("Some plugins could not be loaded");
+ return tr("Some plugins could not be loaded");
} break;
- default: { return tr("Description missing"); } break;
- }
+ default: {
+ return tr("Description missing");
+ } break;
+ }
}
-QString PluginContainer::fullDescription(unsigned int key) const {
- switch (key) {
+QString PluginContainer::fullDescription(unsigned int key) const
+{
+ switch (key) {
case PROBLEM_PLUGINSNOTLOADED: {
- QString result = tr("The following plugins could not be loaded. The reason may be missing "
- "dependencies (i.e. python) or an outdated version:") +
- "<ul>";
- for (const QString& plugin : m_FailedPlugins) {
- result += "<li>" + plugin + "</li>";
- }
- result += "<ul>";
- return result;
+ QString result = tr("The following plugins could not be loaded. The reason may be missing "
+ "dependencies (i.e. python) or an outdated version:") + "<ul>";
+ for (const QString &plugin : m_FailedPlugins) {
+ result += "<li>" + plugin + "</li>";
+ }
+ result += "<ul>";
+ return result;
} break;
- default: { return tr("Description missing"); } break;
- }
+ default: {
+ return tr("Description missing");
+ } break;
+ }
}
-bool PluginContainer::hasGuidedFix(unsigned int) const { return false; }
+bool PluginContainer::hasGuidedFix(unsigned int) const
+{
+ return false;
+}
-void PluginContainer::startGuidedFix(unsigned int) const {}
+void PluginContainer::startGuidedFix(unsigned int) const
+{
+}
diff --git a/src/plugincontainer.h b/src/plugincontainer.h
index e431142e..70392d0b 100644
--- a/src/plugincontainer.h
+++ b/src/plugincontainer.h
@@ -1,94 +1,103 @@
#ifndef PLUGINCONTAINER_H
#define PLUGINCONTAINER_H
+
#include "organizercore.h"
#include "previewgenerator.h"
-#include <QFile>
-#include <QPluginLoader>
-#include <QtPlugin>
#include <iplugindiagnose.h>
-#include <ipluginfilemapper.h>
-#include <iplugingame.h>
-#include <iplugininstaller.h>
#include <ipluginmodpage.h>
-#include <ipluginproxy.h>
+#include <iplugingame.h>
#include <iplugintool.h>
+#include <ipluginproxy.h>
+#include <iplugininstaller.h>
+#include <ipluginfilemapper.h>
+#include <QtPlugin>
+#include <QPluginLoader>
+#include <QFile>
#ifndef Q_MOC_RUN
#include <boost/fusion/container.hpp>
#include <boost/fusion/include/at_key.hpp>
#endif // Q_MOC_RUN
#include <vector>
-class PluginContainer : public QObject, public MOBase::IPluginDiagnose {
- Q_OBJECT
- Q_INTERFACES(MOBase::IPluginDiagnose)
+class PluginContainer : public QObject, public MOBase::IPluginDiagnose
+{
+
+ Q_OBJECT
+ Q_INTERFACES(MOBase::IPluginDiagnose)
private:
- typedef boost::fusion::map<boost::fusion::pair<MOBase::IPlugin, std::vector<MOBase::IPlugin*>>,
- boost::fusion::pair<MOBase::IPluginDiagnose, std::vector<MOBase::IPluginDiagnose*>>,
- boost::fusion::pair<MOBase::IPluginGame, std::vector<MOBase::IPluginGame*>>,
- boost::fusion::pair<MOBase::IPluginInstaller, std::vector<MOBase::IPluginInstaller*>>,
- boost::fusion::pair<MOBase::IPluginModPage, std::vector<MOBase::IPluginModPage*>>,
- boost::fusion::pair<MOBase::IPluginPreview, std::vector<MOBase::IPluginPreview*>>,
- boost::fusion::pair<MOBase::IPluginTool, std::vector<MOBase::IPluginTool*>>,
- boost::fusion::pair<MOBase::IPluginProxy, std::vector<MOBase::IPluginProxy*>>,
- boost::fusion::pair<MOBase::IPluginFileMapper, std::vector<MOBase::IPluginFileMapper*>>>
- PluginMap;
- static const unsigned int PROBLEM_PLUGINSNOTLOADED = 1;
+ typedef boost::fusion::map<
+ boost::fusion::pair<MOBase::IPlugin, std::vector<MOBase::IPlugin*>>,
+ boost::fusion::pair<MOBase::IPluginDiagnose, std::vector<MOBase::IPluginDiagnose*>>,
+ boost::fusion::pair<MOBase::IPluginGame, std::vector<MOBase::IPluginGame*>>,
+ boost::fusion::pair<MOBase::IPluginInstaller, std::vector<MOBase::IPluginInstaller*>>,
+ boost::fusion::pair<MOBase::IPluginModPage, std::vector<MOBase::IPluginModPage*>>,
+ boost::fusion::pair<MOBase::IPluginPreview, std::vector<MOBase::IPluginPreview*>>,
+ boost::fusion::pair<MOBase::IPluginTool, std::vector<MOBase::IPluginTool*>>,
+ boost::fusion::pair<MOBase::IPluginProxy, std::vector<MOBase::IPluginProxy*>>,
+ boost::fusion::pair<MOBase::IPluginFileMapper, std::vector<MOBase::IPluginFileMapper*>>
+ > PluginMap;
+
+ static const unsigned int PROBLEM_PLUGINSNOTLOADED = 1;
public:
- PluginContainer(OrganizerCore* organizer);
- void setUserInterface(IUserInterface* userInterface, QWidget* widget);
+ PluginContainer(OrganizerCore *organizer);
+
+ void setUserInterface(IUserInterface *userInterface, QWidget *widget);
- void loadPlugins();
- void unloadPlugins();
+ void loadPlugins();
+ void unloadPlugins();
- MOBase::IPluginGame* managedGame(const QString& name) const;
+ MOBase::IPluginGame *managedGame(const QString &name) const;
- template <typename T>
- const std::vector<T*>& plugins() const {
- typename boost::fusion::result_of::at_key<const PluginMap, T>::type temp = boost::fusion::at_key<T>(m_Plugins);
- return temp;
- }
+ template <typename T>
+ const std::vector<T*> &plugins() const {
+ typename boost::fusion::result_of::at_key<const PluginMap, T>::type temp = boost::fusion::at_key<T>(m_Plugins);
+ return temp;
+ }
- const PreviewGenerator& previewGenerator() const;
+ const PreviewGenerator &previewGenerator() const;
- QStringList pluginFileNames() const;
+ QStringList pluginFileNames() const;
public: // IPluginDiagnose interface
- virtual std::vector<unsigned int> activeProblems() const;
- virtual QString shortDescription(unsigned int key) const;
- virtual QString fullDescription(unsigned int key) const;
- virtual bool hasGuidedFix(unsigned int key) const;
- virtual void startGuidedFix(unsigned int key) const;
+
+ virtual std::vector<unsigned int> activeProblems() const;
+ virtual QString shortDescription(unsigned int key) const;
+ virtual QString fullDescription(unsigned int key) const;
+ virtual bool hasGuidedFix(unsigned int key) const;
+ virtual void startGuidedFix(unsigned int key) const;
signals:
- void diagnosisUpdate();
+ void diagnosisUpdate();
private:
- bool verifyPlugin(MOBase::IPlugin* plugin);
- void registerGame(MOBase::IPluginGame* game);
- bool registerPlugin(QObject* pluginObj, const QString& fileName);
- bool unregisterPlugin(QObject* pluginObj, const QString& fileName);
- OrganizerCore* m_Organizer;
+ bool verifyPlugin(MOBase::IPlugin *plugin);
+ void registerGame(MOBase::IPluginGame *game);
+ bool registerPlugin(QObject *pluginObj, const QString &fileName);
+ bool unregisterPlugin(QObject *pluginObj, const QString &fileName);
- IUserInterface* m_UserInterface;
+ OrganizerCore *m_Organizer;
- PluginMap m_Plugins;
+ IUserInterface *m_UserInterface;
- std::map<QString, MOBase::IPluginGame*> m_SupportedGames;
- std::vector<boost::signals2::connection> m_DiagnosisConnections;
- QStringList m_FailedPlugins;
- std::vector<QPluginLoader*> m_PluginLoaders;
+ PluginMap m_Plugins;
- PreviewGenerator m_PreviewGenerator;
+ std::map<QString, MOBase::IPluginGame*> m_SupportedGames;
+ std::vector<boost::signals2::connection> m_DiagnosisConnections;
+ QStringList m_FailedPlugins;
+ std::vector<QPluginLoader*> m_PluginLoaders;
- QFile m_PluginsCheck;
+ PreviewGenerator m_PreviewGenerator;
+
+ QFile m_PluginsCheck;
};
+
#endif // PLUGINCONTAINER_H
diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp
index f1ebac39..775086fd 100644
--- a/src/pluginlist.cpp
+++ b/src/pluginlist.cpp
@@ -18,1129 +18,1205 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "pluginlist.h"
-#include "modinfo.h"
-#include "scopeguard.h"
#include "settings.h"
+#include "scopeguard.h"
+#include "modinfo.h"
#include "viewmarkingscrollbar.h"
-#include <espfile.h>
-#include <gameplugins.h>
+#include <utility.h>
#include <iplugingame.h>
+#include <espfile.h>
#include <report.h>
-#include <safewritefile.h>
-#include <utility.h>
#include <windows_error.h>
+#include <safewritefile.h>
+#include <gameplugins.h>
-#include <QApplication>
+#include <QtDebug>
+#include <QMessageBox>
+#include <QMimeData>
#include <QCoreApplication>
#include <QDateTime>
#include <QDir>
#include <QFile>
+#include <QTextCodec>
#include <QFileInfo>
-#include <QKeyEvent>
#include <QListWidgetItem>
-#include <QMessageBox>
-#include <QMimeData>
-#include <QSortFilterProxyModel>
#include <QString>
-#include <QTextCodec>
-#include <QtDebug>
+#include <QApplication>
+#include <QKeyEvent>
+#include <QSortFilterProxyModel>
-#include <algorithm>
#include <ctime>
+#include <algorithm>
#include <stdexcept>
+
using namespace MOBase;
using namespace MOShared;
+
static bool ByName(const PluginList::ESPInfo& LHS, const PluginList::ESPInfo& RHS) {
- return LHS.m_Name.toUpper() < RHS.m_Name.toUpper();
+ return LHS.m_Name.toUpper() < RHS.m_Name.toUpper();
}
static bool ByPriority(const PluginList::ESPInfo& LHS, const PluginList::ESPInfo& RHS) {
- if (LHS.m_IsMaster && !RHS.m_IsMaster) {
- return true;
- } else if (!LHS.m_IsMaster && RHS.m_IsMaster) {
- return false;
- } else {
- return LHS.m_Priority < RHS.m_Priority;
- }
+ if (LHS.m_IsMaster && !RHS.m_IsMaster) {
+ return true;
+ } else if (!LHS.m_IsMaster && RHS.m_IsMaster) {
+ return false;
+ } else {
+ return LHS.m_Priority < RHS.m_Priority;
+ }
}
static bool ByDate(const PluginList::ESPInfo& LHS, const PluginList::ESPInfo& RHS) {
- return QFileInfo(LHS.m_FullPath).lastModified() < QFileInfo(RHS.m_FullPath).lastModified();
+ return QFileInfo(LHS.m_FullPath).lastModified() < QFileInfo(RHS.m_FullPath).lastModified();
}
-PluginList::PluginList(QObject* parent) : QAbstractItemModel(parent), m_FontMetrics(QFont()) {}
+PluginList::PluginList(QObject *parent)
+ : QAbstractItemModel(parent)
+ , m_FontMetrics(QFont())
+{
+}
-PluginList::~PluginList() {
- m_Refreshed.disconnect_all_slots();
- m_PluginMoved.disconnect_all_slots();
- m_PluginStateChanged.disconnect_all_slots();
+PluginList::~PluginList()
+{
+ m_Refreshed.disconnect_all_slots();
+ m_PluginMoved.disconnect_all_slots();
+ m_PluginStateChanged.disconnect_all_slots();
}
-QString PluginList::getColumnName(int column) {
- switch (column) {
- case COL_NAME:
- return tr("Name");
- case COL_PRIORITY:
- return tr("Priority");
- case COL_MODINDEX:
- return tr("Mod Index");
- case COL_FLAGS:
- return tr("Flags");
- default:
- return tr("unknown");
- }
+QString PluginList::getColumnName(int column)
+{
+ switch (column) {
+ case COL_NAME: return tr("Name");
+ case COL_PRIORITY: return tr("Priority");
+ case COL_MODINDEX: return tr("Mod Index");
+ case COL_FLAGS: return tr("Flags");
+ default: return tr("unknown");
+ }
}
-QString PluginList::getColumnToolTip(int column) {
- switch (column) {
- case COL_NAME:
- return tr("Name of your mods");
- case COL_PRIORITY:
- return tr("Load priority of your mod. The higher, the more \"important\" it is and thus "
- "overwrites data from plugins with lower priority.");
- case COL_MODINDEX:
- return tr("The modindex determines the formids of objects originating from this mods.");
- default:
- return tr("unknown");
- }
+
+QString PluginList::getColumnToolTip(int column)
+{
+ switch (column) {
+ case COL_NAME: return tr("Name of your mods");
+ case COL_PRIORITY: return tr("Load priority of your mod. The higher, the more \"important\" it is and thus "
+ "overwrites data from plugins with lower priority.");
+ case COL_MODINDEX: return tr("The modindex determines the formids of objects originating from this mods.");
+ default: return tr("unknown");
+ }
}
-void PluginList::highlightPlugins(const QItemSelection& selected, const MOShared::DirectoryEntry& directoryEntry,
- const Profile& profile) {
- for (auto& esp : m_ESPs) {
- esp.m_ModSelected = false;
- }
- for (QModelIndex idx : selected.indexes()) {
- ModInfo::Ptr selectedMod = ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt());
- if (!selectedMod.isNull() && profile.modEnabled(idx.data(Qt::UserRole + 1).toInt())) {
- QDir dir(selectedMod->absolutePath());
- QStringList plugins = dir.entryList(QStringList() << "*.esp"
- << "*.esm"
- << "*.esl");
- MOShared::FilesOrigin origin = directoryEntry.getOriginByName(selectedMod->internalName().toStdWString());
- if (plugins.size() > 0) {
- for (auto plugin : plugins) {
- MOShared::FileEntry::Ptr file = directoryEntry.findFile(plugin.toStdWString());
- if (file->getOrigin() != origin.getID()) {
- const std::vector<std::pair<int, std::wstring>> alternatives = file->getAlternatives();
- if (std::find_if(alternatives.begin(), alternatives.end(),
- [&](const std::pair<int, std::wstring>& element) {
- return element.first == origin.getID();
- }) == alternatives.end())
- continue;
- }
- std::map<QString, int>::iterator iter = m_ESPsByName.find(plugin.toLower());
- if (iter != m_ESPsByName.end()) {
- m_ESPs[iter->second].m_ModSelected = true;
- }
- }
- }
+void PluginList::highlightPlugins(const QItemSelection &selected, const MOShared::DirectoryEntry &directoryEntry, const Profile &profile)
+{
+ for (auto &esp : m_ESPs) {
+ esp.m_ModSelected = false;
+ }
+ for (QModelIndex idx : selected.indexes()) {
+ ModInfo::Ptr selectedMod = ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt());
+ if (!selectedMod.isNull() && profile.modEnabled(idx.data(Qt::UserRole + 1).toInt())) {
+ QDir dir(selectedMod->absolutePath());
+ QStringList plugins = dir.entryList(QStringList() << "*.esp" << "*.esm" << "*.esl");
+ MOShared::FilesOrigin origin = directoryEntry.getOriginByName(selectedMod->internalName().toStdWString());
+ if (plugins.size() > 0) {
+ for (auto plugin : plugins) {
+ MOShared::FileEntry::Ptr file = directoryEntry.findFile(plugin.toStdWString());
+ if (file->getOrigin() != origin.getID()) {
+ const std::vector<std::pair<int, std::wstring>> alternatives = file->getAlternatives();
+ if (std::find_if(alternatives.begin(), alternatives.end(), [&](const std::pair<int, std::wstring>& element) { return element.first == origin.getID(); }) == alternatives.end())
+ continue;
+ }
+ std::map<QString, int>::iterator iter = m_ESPsByName.find(plugin.toLower());
+ if (iter != m_ESPsByName.end()) {
+ m_ESPs[iter->second].m_ModSelected = true;
+ }
}
+ }
}
- emit dataChanged(this->index(0, 0), this->index(m_ESPs.size() - 1, this->columnCount() - 1));
+ }
+ emit dataChanged(this->index(0, 0), this->index(m_ESPs.size() - 1, this->columnCount() - 1));
}
-void PluginList::refresh(const QString& profileName, const DirectoryEntry& baseDirectory,
- const QString& lockedOrderFile) {
- ChangeBracket<PluginList> layoutChange(this);
+void PluginList::refresh(const QString &profileName
+ , const DirectoryEntry &baseDirectory
+ , const QString &lockedOrderFile)
+{
+ ChangeBracket<PluginList> layoutChange(this);
- QStringList primaryPlugins = m_GamePlugin->primaryPlugins();
+ QStringList primaryPlugins = m_GamePlugin->primaryPlugins();
- m_CurrentProfile = profileName;
+ m_CurrentProfile = profileName;
- QStringList availablePlugins;
+ QStringList availablePlugins;
- std::vector<FileEntry::Ptr> files = baseDirectory.getFiles();
- for (FileEntry::Ptr current : files) {
- if (current.get() == nullptr) {
- continue;
- }
- QString filename = ToQString(current->getName());
+ std::vector<FileEntry::Ptr> files = baseDirectory.getFiles();
+ for (FileEntry::Ptr current : files) {
+ if (current.get() == nullptr) {
+ continue;
+ }
+ QString filename = ToQString(current->getName());
- availablePlugins.append(filename.toLower());
+ availablePlugins.append(filename.toLower());
- if (m_ESPsByName.find(filename.toLower()) != m_ESPsByName.end()) {
- continue;
- }
-
- QString extension = filename.right(3).toLower();
+ if (m_ESPsByName.find(filename.toLower()) != m_ESPsByName.end()) {
+ continue;
+ }
- if ((extension == "esp") || (extension == "esm") || (extension == "esl")) {
- bool forceEnabled =
- Settings::instance().forceEnableCoreFiles() &&
- std::find(primaryPlugins.begin(), primaryPlugins.end(), filename.toLower()) != primaryPlugins.end();
+ QString extension = filename.right(3).toLower();
- bool archive = false;
- try {
- FilesOrigin& origin = baseDirectory.getOriginByID(current->getOrigin(archive));
+ if ((extension == "esp") || (extension == "esm") || (extension == "esl")) {
+ bool forceEnabled = Settings::instance().forceEnableCoreFiles() &&
+ std::find(primaryPlugins.begin(), primaryPlugins.end(), filename.toLower()) != primaryPlugins.end();
- QString iniPath = QFileInfo(filename).baseName() + ".ini";
- bool hasIni = baseDirectory.findFile(ToWString(iniPath)).get() != nullptr;
+ bool archive = false;
+ try {
+ FilesOrigin &origin = baseDirectory.getOriginByID(current->getOrigin(archive));
- QString originName = ToQString(origin.getName());
- unsigned int modIndex = ModInfo::getIndex(originName);
- if (modIndex != UINT_MAX) {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex);
- originName = modInfo->name();
- }
+ QString iniPath = QFileInfo(filename).baseName() + ".ini";
+ bool hasIni = baseDirectory.findFile(ToWString(iniPath)).get() != nullptr;
- m_ESPs.push_back(
- ESPInfo(filename, forceEnabled, originName, ToQString(current->getFullPath()), hasIni));
- m_ESPs.rbegin()->m_Priority = -1;
- } catch (const std::exception& e) {
- reportError(tr("failed to update esp info for file %1 (source id: %2), error: %3")
- .arg(filename)
- .arg(current->getOrigin(archive))
- .arg(e.what()));
- }
+ QString originName = ToQString(origin.getName());
+ unsigned int modIndex = ModInfo::getIndex(originName);
+ if (modIndex != UINT_MAX) {
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex);
+ originName = modInfo->name();
}
+
+ m_ESPs.push_back(ESPInfo(filename, forceEnabled, originName, ToQString(current->getFullPath()), hasIni));
+ m_ESPs.rbegin()->m_Priority = -1;
+ } catch (const std::exception &e) {
+ reportError(tr("failed to update esp info for file %1 (source id: %2), error: %3").arg(filename).arg(current->getOrigin(archive)).arg(e.what()));
+ }
}
+ }
- for (const auto& espName : m_ESPsByName) {
- if (!availablePlugins.contains(espName.first)) {
- m_ESPs[espName.second].m_Name = "";
- }
+ for (const auto &espName : m_ESPsByName) {
+ if (!availablePlugins.contains(espName.first)) {
+ m_ESPs[espName.second].m_Name = "";
}
+ }
- m_ESPs.erase(
- std::remove_if(m_ESPs.begin(), m_ESPs.end(), [](const ESPInfo& info) -> bool { return info.m_Name.isEmpty(); }),
- m_ESPs.end());
+ m_ESPs.erase(std::remove_if(m_ESPs.begin(), m_ESPs.end(),
+ [](const ESPInfo &info) -> bool {
+ return info.m_Name.isEmpty();
+ }),
+ m_ESPs.end());
- fixPriorities();
+ fixPriorities();
- // functions in GamePlugins will use the IPluginList interface of this, so
- // indices need to work. priority will be off however
- updateIndices();
+ // functions in GamePlugins will use the IPluginList interface of this, so
+ // indices need to work. priority will be off however
+ updateIndices();
- GamePlugins* gamePlugins = m_GamePlugin->feature<GamePlugins>();
- gamePlugins->readPluginLists(this);
+ GamePlugins *gamePlugins = m_GamePlugin->feature<GamePlugins>();
+ gamePlugins->readPluginLists(this);
- testMasters();
+ testMasters();
- updateIndices();
+ updateIndices();
- readLockedOrderFrom(lockedOrderFile);
+ readLockedOrderFrom(lockedOrderFile);
- layoutChange.finish();
+ layoutChange.finish();
- refreshLoadOrder();
- emit dataChanged(this->index(0, 0), this->index(static_cast<int>(m_ESPs.size()), columnCount()));
+ refreshLoadOrder();
+ emit dataChanged(this->index(0, 0),
+ this->index(static_cast<int>(m_ESPs.size()), columnCount()));
- m_Refreshed();
+ m_Refreshed();
}
-void PluginList::fixPriorities() {
- std::vector<std::pair<int, int>> espPrios;
+void PluginList::fixPriorities()
+{
+ std::vector<std::pair<int, int>> espPrios;
- for (int i = 0; i < m_ESPs.size(); ++i) {
- int prio = m_ESPs[i].m_Priority;
- if (prio == -1) {
- prio = INT_MAX;
- }
- espPrios.push_back(std::make_pair(prio, i));
+ for (int i = 0; i < m_ESPs.size(); ++i) {
+ int prio = m_ESPs[i].m_Priority;
+ if (prio == -1) {
+ prio = INT_MAX;
}
+ espPrios.push_back(std::make_pair(prio, i));
+ }
- std::sort(espPrios.begin(), espPrios.end(),
- [](const std::pair<int, int>& lhs, const std::pair<int, int>& rhs) { return lhs.first < rhs.first; });
+ std::sort(espPrios.begin(), espPrios.end(),
+ [](const std::pair<int, int> &lhs, const std::pair<int, int> &rhs) {
+ return lhs.first < rhs.first;
+ });
- for (int i = 0; i < espPrios.size(); ++i) {
- m_ESPs[espPrios[i].second].m_Priority = i;
- }
+ for (int i = 0; i < espPrios.size(); ++i) {
+ m_ESPs[espPrios[i].second].m_Priority = i;
+ }
}
-void PluginList::enableESP(const QString& name, bool enable) {
- std::map<QString, int>::iterator iter = m_ESPsByName.find(name.toLower());
+void PluginList::enableESP(const QString &name, bool enable)
+{
+ std::map<QString, int>::iterator iter = m_ESPsByName.find(name.toLower());
- if (iter != m_ESPsByName.end()) {
- m_ESPs[iter->second].m_Enabled = enable | m_ESPs[iter->second].m_ForceEnabled;
+ if (iter != m_ESPsByName.end()) {
+ m_ESPs[iter->second].m_Enabled =
+ enable | m_ESPs[iter->second].m_ForceEnabled;
- emit writePluginsList();
- } else {
- reportError(tr("esp not found: %1").arg(name));
- }
+ emit writePluginsList();
+ } else {
+ reportError(tr("esp not found: %1").arg(name));
+ }
}
-void PluginList::enableAll() {
- if (QMessageBox::question(nullptr, tr("Confirm"), tr("Really enable all plugins?"),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- for (ESPInfo& info : m_ESPs) {
- info.m_Enabled = true;
- }
- emit writePluginsList();
+
+void PluginList::enableAll()
+{
+ if (QMessageBox::question(nullptr, tr("Confirm"), tr("Really enable all plugins?"),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ for (ESPInfo &info : m_ESPs) {
+ info.m_Enabled = true;
}
+ emit writePluginsList();
+ }
}
-void PluginList::disableAll() {
- if (QMessageBox::question(nullptr, tr("Confirm"), tr("Really disable all plugins?"),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- for (ESPInfo& info : m_ESPs) {
- if (!info.m_ForceEnabled) {
- info.m_Enabled = false;
- }
- }
- emit writePluginsList();
+
+void PluginList::disableAll()
+{
+ if (QMessageBox::question(nullptr, tr("Confirm"), tr("Really disable all plugins?"),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ for (ESPInfo &info : m_ESPs) {
+ if (!info.m_ForceEnabled) {
+ info.m_Enabled = false;
+ }
}
+ emit writePluginsList();
+ }
}
-bool PluginList::isEnabled(const QString& name) {
- std::map<QString, int>::iterator iter = m_ESPsByName.find(name.toLower());
- if (iter != m_ESPsByName.end()) {
- return m_ESPs[iter->second].m_Enabled;
- } else {
- return false;
- }
+bool PluginList::isEnabled(const QString &name)
+{
+ std::map<QString, int>::iterator iter = m_ESPsByName.find(name.toLower());
+
+ if (iter != m_ESPsByName.end()) {
+ return m_ESPs[iter->second].m_Enabled;
+ } else {
+ return false;
+ }
}
-void PluginList::clearInformation(const QString& name) {
- std::map<QString, int>::iterator iter = m_ESPsByName.find(name.toLower());
+void PluginList::clearInformation(const QString &name)
+{
+ std::map<QString, int>::iterator iter = m_ESPsByName.find(name.toLower());
- if (iter != m_ESPsByName.end()) {
- m_AdditionalInfo[name.toLower()].m_Messages.clear();
- }
+ if (iter != m_ESPsByName.end()) {
+ m_AdditionalInfo[name.toLower()].m_Messages.clear();
+ }
}
-void PluginList::clearAdditionalInformation() { m_AdditionalInfo.clear(); }
+void PluginList::clearAdditionalInformation()
+{
+ m_AdditionalInfo.clear();
+}
-void PluginList::addInformation(const QString& name, const QString& message) {
- std::map<QString, int>::iterator iter = m_ESPsByName.find(name.toLower());
+void PluginList::addInformation(const QString &name, const QString &message)
+{
+ std::map<QString, int>::iterator iter = m_ESPsByName.find(name.toLower());
- if (iter != m_ESPsByName.end()) {
- m_AdditionalInfo[name.toLower()].m_Messages.append(message);
- } else {
- qWarning("failed to associate message for \"%s\"", qPrintable(name));
- }
+ if (iter != m_ESPsByName.end()) {
+ m_AdditionalInfo[name.toLower()].m_Messages.append(message);
+ } else {
+ qWarning("failed to associate message for \"%s\"", qPrintable(name));
+ }
}
-bool PluginList::isEnabled(int index) { return m_ESPs.at(index).m_Enabled; }
+bool PluginList::isEnabled(int index)
+{
+ return m_ESPs.at(index).m_Enabled;
+}
-void PluginList::readLockedOrderFrom(const QString& fileName) {
- m_LockedOrder.clear();
+void PluginList::readLockedOrderFrom(const QString &fileName)
+{
+ m_LockedOrder.clear();
- QFile file(fileName);
- if (!file.exists()) {
- // no locked load order, that's ok
- return;
- }
+ QFile file(fileName);
+ if (!file.exists()) {
+ // no locked load order, that's ok
+ return;
+ }
- file.open(QIODevice::ReadOnly);
- while (!file.atEnd()) {
- QByteArray line = file.readLine();
- if ((line.size() > 0) && (line.at(0) != '#')) {
- QList<QByteArray> fields = line.split('|');
- if (fields.count() == 2) {
- int priority = fields.at(1).trimmed().toInt();
- QString name = QString::fromUtf8(fields.at(0));
- // Avoid locking a force-enabled plugin
- if (!m_ESPs[m_ESPsByName.at(name)].m_ForceEnabled) {
- // Is this an open and unclaimed priority?
- if (m_ESPs[m_ESPsByPriority.at(priority)].m_ForceEnabled ||
- std::find_if(m_LockedOrder.begin(), m_LockedOrder.end(), [&](const std::pair<QString, int>& a) {
- return a.second == priority;
- }) != m_LockedOrder.end()) {
- // Attempt to find a priority but step over force-enabled plugins and already-set locks
- int calcPriority = priority;
- do {
- ++calcPriority;
- } while (calcPriority < m_ESPsByPriority.size() ||
- (m_ESPs[m_ESPsByPriority.at(calcPriority)].m_ForceEnabled &&
- std::find_if(m_LockedOrder.begin(), m_LockedOrder.end(),
- [&](const std::pair<QString, int>& a) {
- return a.second == calcPriority;
- }) != m_LockedOrder.end()));
- // If we have a match, we can reassign the priority...
- if (calcPriority < m_ESPsByPriority.size())
- m_LockedOrder[name] = calcPriority;
- } else {
- m_LockedOrder[name] = priority;
- }
- }
- } else {
- reportError(tr("The file containing locked plugin indices is broken"));
- break;
- }
+ file.open(QIODevice::ReadOnly);
+ while (!file.atEnd()) {
+ QByteArray line = file.readLine();
+ if ((line.size() > 0) && (line.at(0) != '#')) {
+ QList<QByteArray> fields = line.split('|');
+ if (fields.count() == 2) {
+ int priority = fields.at(1).trimmed().toInt();
+ QString name = QString::fromUtf8(fields.at(0));
+ // Avoid locking a force-enabled plugin
+ if (!m_ESPs[m_ESPsByName.at(name)].m_ForceEnabled) {
+ // Is this an open and unclaimed priority?
+ if (m_ESPs[m_ESPsByPriority.at(priority)].m_ForceEnabled ||
+ std::find_if(m_LockedOrder.begin(), m_LockedOrder.end(), [&](const std::pair<QString, int> &a) { return a.second == priority; }) != m_LockedOrder.end()) {
+ // Attempt to find a priority but step over force-enabled plugins and already-set locks
+ int calcPriority = priority;
+ do {
+ ++calcPriority;
+ } while (calcPriority < m_ESPsByPriority.size() || (m_ESPs[m_ESPsByPriority.at(calcPriority)].m_ForceEnabled &&
+ std::find_if(m_LockedOrder.begin(), m_LockedOrder.end(), [&](const std::pair<QString, int> &a) { return a.second == calcPriority; }) != m_LockedOrder.end()));
+ // If we have a match, we can reassign the priority...
+ if (calcPriority < m_ESPsByPriority.size())
+ m_LockedOrder[name] = calcPriority;
+ } else {
+ m_LockedOrder[name] = priority;
+ }
}
+ } else {
+ reportError(tr("The file containing locked plugin indices is broken"));
+ break;
+ }
}
- file.close();
+ }
+ file.close();
}
-void PluginList::writeLockedOrder(const QString& fileName) const {
- SafeWriteFile file(fileName);
+void PluginList::writeLockedOrder(const QString &fileName) const
+{
+ SafeWriteFile file(fileName);
- file->resize(0);
- file->write(QString("# This file was automatically generated by Mod Organizer.\r\n").toUtf8());
- for (auto iter = m_LockedOrder.begin(); iter != m_LockedOrder.end(); ++iter) {
- file->write(QString("%1|%2\r\n").arg(iter->first).arg(iter->second).toUtf8());
- }
- file.commit();
- qDebug("%s saved", QDir::toNativeSeparators(fileName).toUtf8().constData());
+ file->resize(0);
+ file->write(QString("# This file was automatically generated by Mod Organizer.\r\n").toUtf8());
+ for (auto iter = m_LockedOrder.begin(); iter != m_LockedOrder.end(); ++iter) {
+ file->write(QString("%1|%2\r\n").arg(iter->first).arg(iter->second).toUtf8());
+ }
+ file.commit();
+ qDebug("%s saved", QDir::toNativeSeparators(fileName).toUtf8().constData());
}
-void PluginList::saveTo(const QString& lockedOrderFileName, const QString& deleterFileName, bool hideUnchecked) const {
- GamePlugins* gamePlugins = m_GamePlugin->feature<GamePlugins>();
- gamePlugins->writePluginLists(this);
- writeLockedOrder(lockedOrderFileName);
+void PluginList::saveTo(const QString &lockedOrderFileName
+ , const QString& deleterFileName
+ , bool hideUnchecked) const
+{
+ GamePlugins *gamePlugins = m_GamePlugin->feature<GamePlugins>();
+ gamePlugins->writePluginLists(this);
- if (hideUnchecked) {
- SafeWriteFile deleterFile(deleterFileName);
- deleterFile->write(QString("# This file was automatically generated by Mod Organizer.\r\n").toUtf8());
+ writeLockedOrder(lockedOrderFileName);
- for (size_t i = 0; i < m_ESPs.size(); ++i) {
- int priority = m_ESPsByPriority[i];
- if (!m_ESPs[priority].m_Enabled) {
- deleterFile->write(m_ESPs[priority].m_Name.toUtf8());
- deleterFile->write("\r\n");
- }
- }
- if (deleterFile.commitIfDifferent(m_LastSaveHash[deleterFileName])) {
- qDebug("%s saved", qPrintable(QDir::toNativeSeparators(deleterFileName)));
- }
- } else if (QFile::exists(deleterFileName)) {
- shellDelete(QStringList() << deleterFileName);
+ if (hideUnchecked) {
+ SafeWriteFile deleterFile(deleterFileName);
+ deleterFile->write(QString("# This file was automatically generated by Mod Organizer.\r\n").toUtf8());
+
+ for (size_t i = 0; i < m_ESPs.size(); ++i) {
+ int priority = m_ESPsByPriority[i];
+ if (!m_ESPs[priority].m_Enabled) {
+ deleterFile->write(m_ESPs[priority].m_Name.toUtf8());
+ deleterFile->write("\r\n");
+ }
+ }
+ if (deleterFile.commitIfDifferent(m_LastSaveHash[deleterFileName])) {
+ qDebug("%s saved", qPrintable(QDir::toNativeSeparators(deleterFileName)));
}
+ } else if (QFile::exists(deleterFileName)) {
+ shellDelete(QStringList() << deleterFileName);
+ }
}
-bool PluginList::saveLoadOrder(DirectoryEntry& directoryStructure) {
- if (m_GamePlugin->loadOrderMechanism() != IPluginGame::LoadOrderMechanism::FileTime) {
- // nothing to do
- return true;
- }
- qDebug("setting file times on esps");
+bool PluginList::saveLoadOrder(DirectoryEntry &directoryStructure)
+{
+ if (m_GamePlugin->loadOrderMechanism() != IPluginGame::LoadOrderMechanism::FileTime) {
+ // nothing to do
+ return true;
+ }
- for (ESPInfo& esp : m_ESPs) {
- std::wstring espName = ToWString(esp.m_Name);
- const FileEntry::Ptr fileEntry = directoryStructure.findFile(espName);
- if (fileEntry.get() != nullptr) {
- QString fileName;
- bool archive = false;
- int originid = fileEntry->getOrigin(archive);
- fileName =
- QString("%1\\%2")
- .arg(QDir::toNativeSeparators(ToQString(directoryStructure.getOriginByID(originid).getPath())))
- .arg(esp.m_Name);
+ qDebug("setting file times on esps");
- HANDLE file = ::CreateFile(ToWString(fileName).c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
- if (file == INVALID_HANDLE_VALUE) {
- if (::GetLastError() == ERROR_SHARING_VIOLATION) {
- // file is locked, probably the game is running
- return false;
- } else {
- throw windows_error(QObject::tr("failed to access %1").arg(fileName).toUtf8().constData());
- }
- }
+ for (ESPInfo &esp : m_ESPs) {
+ std::wstring espName = ToWString(esp.m_Name);
+ const FileEntry::Ptr fileEntry = directoryStructure.findFile(espName);
+ if (fileEntry.get() != nullptr) {
+ QString fileName;
+ bool archive = false;
+ int originid = fileEntry->getOrigin(archive);
+ fileName = QString("%1\\%2").arg(QDir::toNativeSeparators(ToQString(directoryStructure.getOriginByID(originid).getPath()))).arg(esp.m_Name);
- ULONGLONG temp = 0;
- temp = (145731ULL + esp.m_Priority) * 24 * 60 * 60 * 10000000ULL;
+ HANDLE file = ::CreateFile(ToWString(fileName).c_str(), GENERIC_READ | GENERIC_WRITE,
+ 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
+ if (file == INVALID_HANDLE_VALUE) {
+ if (::GetLastError() == ERROR_SHARING_VIOLATION) {
+ // file is locked, probably the game is running
+ return false;
+ } else {
+ throw windows_error(QObject::tr("failed to access %1").arg(fileName).toUtf8().constData());
+ }
+ }
- FILETIME newWriteTime;
+ ULONGLONG temp = 0;
+ temp = (145731ULL + esp.m_Priority) * 24 * 60 * 60 * 10000000ULL;
- newWriteTime.dwLowDateTime = (DWORD)(temp & 0xFFFFFFFF);
- newWriteTime.dwHighDateTime = (DWORD)(temp >> 32);
- esp.m_Time = newWriteTime;
- fileEntry->setFileTime(newWriteTime);
- if (!::SetFileTime(file, nullptr, nullptr, &newWriteTime)) {
- throw windows_error(QObject::tr("failed to set file time %1").arg(fileName).toUtf8().constData());
- }
+ FILETIME newWriteTime;
- CloseHandle(file);
- }
+ newWriteTime.dwLowDateTime = (DWORD)(temp & 0xFFFFFFFF);
+ newWriteTime.dwHighDateTime = (DWORD)(temp >> 32);
+ esp.m_Time = newWriteTime;
+ fileEntry->setFileTime(newWriteTime);
+ if (!::SetFileTime(file, nullptr, nullptr, &newWriteTime)) {
+ throw windows_error(QObject::tr("failed to set file time %1").arg(fileName).toUtf8().constData());
+ }
+
+ CloseHandle(file);
}
- return true;
+ }
+ return true;
}
-int PluginList::enabledCount() const {
- int enabled = 0;
- for (const auto& info : m_ESPs) {
- if (info.m_Enabled) {
- ++enabled;
- }
+int PluginList::enabledCount() const
+{
+ int enabled = 0;
+ for (const auto &info : m_ESPs) {
+ if (info.m_Enabled) {
+ ++enabled;
}
- return enabled;
+ }
+ return enabled;
}
-bool PluginList::isESPLocked(int index) const {
- return m_LockedOrder.find(m_ESPs.at(index).m_Name.toLower()) != m_LockedOrder.end();
+bool PluginList::isESPLocked(int index) const
+{
+ return m_LockedOrder.find(m_ESPs.at(index).m_Name.toLower()) != m_LockedOrder.end();
}
-void PluginList::lockESPIndex(int index, bool lock) {
- if (lock) {
- if (!m_ESPs.at(index).m_ForceEnabled)
- m_LockedOrder[getName(index).toLower()] = m_ESPs.at(index).m_LoadOrder;
- else
- return;
- } else {
- auto iter = m_LockedOrder.find(getName(index).toLower());
- if (iter != m_LockedOrder.end()) {
- m_LockedOrder.erase(iter);
- }
+void PluginList::lockESPIndex(int index, bool lock)
+{
+ if (lock) {
+ if (!m_ESPs.at(index).m_ForceEnabled)
+ m_LockedOrder[getName(index).toLower()] = m_ESPs.at(index).m_LoadOrder;
+ else
+ return;
+ } else {
+ auto iter = m_LockedOrder.find(getName(index).toLower());
+ if (iter != m_LockedOrder.end()) {
+ m_LockedOrder.erase(iter);
}
- emit writePluginsList();
+ }
+ emit writePluginsList();
}
-void PluginList::syncLoadOrder() {
- int loadOrder = 0;
- for (unsigned int i = 0; i < m_ESPs.size(); ++i) {
- int index = m_ESPsByPriority[i];
+void PluginList::syncLoadOrder()
+{
+ int loadOrder = 0;
+ for (unsigned int i = 0; i < m_ESPs.size(); ++i) {
+ int index = m_ESPsByPriority[i];
- if (m_ESPs[index].m_Enabled) {
- m_ESPs[index].m_LoadOrder = loadOrder++;
- } else {
- m_ESPs[index].m_LoadOrder = -1;
- }
+ if (m_ESPs[index].m_Enabled) {
+ m_ESPs[index].m_LoadOrder = loadOrder++;
+ } else {
+ m_ESPs[index].m_LoadOrder = -1;
}
+ }
}
-void PluginList::refreshLoadOrder() {
- ChangeBracket<PluginList> layoutChange(this);
- syncLoadOrder();
- // set priorities according to locked load order
- std::map<int, QString> lockedLoadOrder;
- std::for_each(m_LockedOrder.begin(), m_LockedOrder.end(),
- [&lockedLoadOrder](const std::pair<QString, int>& ele) { lockedLoadOrder[ele.second] = ele.first; });
+void PluginList::refreshLoadOrder()
+{
+ ChangeBracket<PluginList> layoutChange(this);
+ syncLoadOrder();
+ // set priorities according to locked load order
+ std::map<int, QString> lockedLoadOrder;
+ std::for_each(m_LockedOrder.begin(), m_LockedOrder.end(),
+ [&lockedLoadOrder] (const std::pair<QString, int> &ele) {
+ lockedLoadOrder[ele.second] = ele.first; });
- int targetPrio = 0;
- bool savePluginsList = false;
- // this is guaranteed to iterate from lowest key (load order) to highest
- for (auto iter = lockedLoadOrder.begin(); iter != lockedLoadOrder.end(); ++iter) {
- auto nameIter = m_ESPsByName.find(iter->second.toLower());
- if (nameIter != m_ESPsByName.end()) {
- // locked esp exists
+ int targetPrio = 0;
+ bool savePluginsList = false;
+ // this is guaranteed to iterate from lowest key (load order) to highest
+ for (auto iter = lockedLoadOrder.begin(); iter != lockedLoadOrder.end(); ++iter) {
+ auto nameIter = m_ESPsByName.find(iter->second.toLower());
+ if (nameIter != m_ESPsByName.end()) {
+ // locked esp exists
- // find the location to insert at
- while ((targetPrio < static_cast<int>(m_ESPs.size() - 1)) &&
- (m_ESPs[m_ESPsByPriority[targetPrio]].m_LoadOrder < iter->first)) {
- ++targetPrio;
- }
+ // find the location to insert at
+ while ((targetPrio < static_cast<int>(m_ESPs.size() - 1)) &&
+ (m_ESPs[m_ESPsByPriority[targetPrio]].m_LoadOrder < iter->first)) {
+ ++targetPrio;
+ }
- if (static_cast<size_t>(targetPrio) >= m_ESPs.size()) {
- continue;
- }
+ if (static_cast<size_t>(targetPrio) >= m_ESPs.size()) {
+ continue;
+ }
- int temp = targetPrio;
- int index = nameIter->second;
- if (m_ESPs[index].m_Priority != temp) {
- setPluginPriority(index, temp);
- m_ESPs[index].m_LoadOrder = iter->first;
- syncLoadOrder();
- savePluginsList = true;
- }
- }
- }
- if (savePluginsList) {
- emit writePluginsList();
+ int temp = targetPrio;
+ int index = nameIter->second;
+ if (m_ESPs[index].m_Priority != temp) {
+ setPluginPriority(index, temp);
+ m_ESPs[index].m_LoadOrder = iter->first;
+ syncLoadOrder();
+ savePluginsList = true;
+ }
}
+ }
+ if (savePluginsList) {
+ emit writePluginsList();
+ }
}
void PluginList::disconnectSlots() {
- m_PluginMoved.disconnect_all_slots();
- m_Refreshed.disconnect_all_slots();
- m_PluginStateChanged.disconnect_all_slots();
+ m_PluginMoved.disconnect_all_slots();
+ m_Refreshed.disconnect_all_slots();
+ m_PluginStateChanged.disconnect_all_slots();
}
-QStringList PluginList::pluginNames() const {
- QStringList result;
+QStringList PluginList::pluginNames() const
+{
+ QStringList result;
- for (const ESPInfo& info : m_ESPs) {
- result.append(info.m_Name);
- }
+ for (const ESPInfo &info : m_ESPs) {
+ result.append(info.m_Name);
+ }
- return result;
+ return result;
}
-IPluginList::PluginStates PluginList::state(const QString& name) const {
- auto iter = m_ESPsByName.find(name.toLower());
- if (iter == m_ESPsByName.end()) {
- return IPluginList::STATE_MISSING;
- } else {
- return m_ESPs[iter->second].m_Enabled ? IPluginList::STATE_ACTIVE : IPluginList::STATE_INACTIVE;
- }
+IPluginList::PluginStates PluginList::state(const QString &name) const
+{
+ auto iter = m_ESPsByName.find(name.toLower());
+ if (iter == m_ESPsByName.end()) {
+ return IPluginList::STATE_MISSING;
+ } else {
+ return m_ESPs[iter->second].m_Enabled ? IPluginList::STATE_ACTIVE : IPluginList::STATE_INACTIVE;
+ }
}
-void PluginList::setState(const QString& name, PluginStates state) {
- auto iter = m_ESPsByName.find(name.toLower());
- if (iter != m_ESPsByName.end()) {
- m_ESPs[iter->second].m_Enabled = (state == IPluginList::STATE_ACTIVE) || m_ESPs[iter->second].m_ForceEnabled;
- } else {
- qWarning("plugin %s not found", qPrintable(name));
- }
+void PluginList::setState(const QString &name, PluginStates state) {
+ auto iter = m_ESPsByName.find(name.toLower());
+ if (iter != m_ESPsByName.end()) {
+ m_ESPs[iter->second].m_Enabled = (state == IPluginList::STATE_ACTIVE) ||
+ m_ESPs[iter->second].m_ForceEnabled;
+ } else {
+ qWarning("plugin %s not found", qPrintable(name));
+ }
}
-void PluginList::setLoadOrder(const QStringList& pluginList) {
- for (ESPInfo& info : m_ESPs) {
- info.m_Priority = -1;
- }
- int maxPriority = 0;
- for (const QString& plugin : pluginList) {
- auto iter = m_ESPsByName.find(plugin.toLower());
- if (iter != m_ESPsByName.end()) {
- m_ESPs[iter->second].m_Priority = maxPriority++;
- }
+void PluginList::setLoadOrder(const QStringList &pluginList)
+{
+ for (ESPInfo &info : m_ESPs) {
+ info.m_Priority = -1;
+ }
+ int maxPriority = 0;
+ for (const QString &plugin : pluginList) {
+ auto iter = m_ESPsByName.find(plugin.toLower());
+ if (iter !=m_ESPsByName.end()) {
+ m_ESPs[iter->second].m_Priority = maxPriority++;
}
+ }
- // use old priorities
- for (ESPInfo& info : m_ESPs) {
- if (info.m_Priority == -1) {
- info.m_Priority = maxPriority++;
- }
+ // use old priorities
+ for (ESPInfo &info : m_ESPs) {
+ if (info.m_Priority == -1) {
+ info.m_Priority = maxPriority++;
}
- updateIndices();
+ }
+ updateIndices();
}
-int PluginList::priority(const QString& name) const {
- auto iter = m_ESPsByName.find(name.toLower());
- if (iter == m_ESPsByName.end()) {
- return -1;
- } else {
- return m_ESPs[iter->second].m_Priority;
- }
+int PluginList::priority(const QString &name) const
+{
+ auto iter = m_ESPsByName.find(name.toLower());
+ if (iter == m_ESPsByName.end()) {
+ return -1;
+ } else {
+ return m_ESPs[iter->second].m_Priority;
+ }
}
-int PluginList::loadOrder(const QString& name) const {
- auto iter = m_ESPsByName.find(name.toLower());
- if (iter == m_ESPsByName.end()) {
- return -1;
- } else {
- return m_ESPs[iter->second].m_LoadOrder;
- }
+int PluginList::loadOrder(const QString &name) const
+{
+ auto iter = m_ESPsByName.find(name.toLower());
+ if (iter == m_ESPsByName.end()) {
+ return -1;
+ } else {
+ return m_ESPs[iter->second].m_LoadOrder;
+ }
}
-bool PluginList::isMaster(const QString& name) const {
- auto iter = m_ESPsByName.find(name.toLower());
- if (iter == m_ESPsByName.end()) {
- return false;
- } else {
- return m_ESPs[iter->second].m_IsMaster;
- }
+bool PluginList::isMaster(const QString &name) const
+{
+ auto iter = m_ESPsByName.find(name.toLower());
+ if (iter == m_ESPsByName.end()) {
+ return false;
+ } else {
+ return m_ESPs[iter->second].m_IsMaster;
+ }
}
-bool PluginList::isLight(const QString& name) const {
- auto iter = m_ESPsByName.find(name.toLower());
- if (iter == m_ESPsByName.end()) {
- return false;
- } else {
- return m_ESPs[iter->second].m_IsLight;
- }
+bool PluginList::isLight(const QString &name) const
+{
+ auto iter = m_ESPsByName.find(name.toLower());
+ if (iter == m_ESPsByName.end()) {
+ return false;
+ } else {
+ return m_ESPs[iter->second].m_IsLight;
+ }
}
-QStringList PluginList::masters(const QString& name) const {
- auto iter = m_ESPsByName.find(name.toLower());
- if (iter == m_ESPsByName.end()) {
- return QStringList();
- } else {
- QStringList result;
- for (const QString& master : m_ESPs[iter->second].m_Masters) {
- result.append(master);
- }
- return result;
+QStringList PluginList::masters(const QString &name) const
+{
+ auto iter = m_ESPsByName.find(name.toLower());
+ if (iter == m_ESPsByName.end()) {
+ return QStringList();
+ } else {
+ QStringList result;
+ for (const QString &master : m_ESPs[iter->second].m_Masters) {
+ result.append(master);
}
+ return result;
+ }
}
-QString PluginList::origin(const QString& name) const {
- auto iter = m_ESPsByName.find(name.toLower());
- if (iter == m_ESPsByName.end()) {
- return QString();
- } else {
- return m_ESPs[iter->second].m_OriginName;
- }
+QString PluginList::origin(const QString &name) const
+{
+ auto iter = m_ESPsByName.find(name.toLower());
+ if (iter == m_ESPsByName.end()) {
+ return QString();
+ } else {
+ return m_ESPs[iter->second].m_OriginName;
+ }
}
-bool PluginList::onPluginStateChanged(const std::function<void(const QString&, PluginStates)>& func) {
- auto conn = m_PluginStateChanged.connect(func);
- return conn.connected();
+bool PluginList::onPluginStateChanged(const std::function<void (const QString &, PluginStates)> &func)
+{
+ auto conn = m_PluginStateChanged.connect(func);
+ return conn.connected();
}
-bool PluginList::onRefreshed(const std::function<void()>& callback) {
- auto conn = m_Refreshed.connect(callback);
- return conn.connected();
+bool PluginList::onRefreshed(const std::function<void ()> &callback)
+{
+ auto conn = m_Refreshed.connect(callback);
+ return conn.connected();
}
-bool PluginList::onPluginMoved(const std::function<void(const QString&, int, int)>& func) {
- auto conn = m_PluginMoved.connect(func);
- return conn.connected();
+
+bool PluginList::onPluginMoved(const std::function<void (const QString &, int, int)> &func)
+{
+ auto conn = m_PluginMoved.connect(func);
+ return conn.connected();
}
-void PluginList::updateIndices() {
- m_ESPsByName.clear();
- m_ESPsByPriority.clear();
- m_ESPsByPriority.resize(m_ESPs.size());
- for (unsigned int i = 0; i < m_ESPs.size(); ++i) {
- if (m_ESPs[i].m_Priority < 0) {
- continue;
- }
- if (m_ESPs[i].m_Priority >= static_cast<int>(m_ESPs.size())) {
- qCritical("invalid priority %d", m_ESPs[i].m_Priority);
- continue;
- }
- m_ESPsByName[m_ESPs[i].m_Name.toLower()] = i;
- m_ESPsByPriority.at(static_cast<size_t>(m_ESPs[i].m_Priority)) = i;
+
+void PluginList::updateIndices()
+{
+ m_ESPsByName.clear();
+ m_ESPsByPriority.clear();
+ m_ESPsByPriority.resize(m_ESPs.size());
+ for (unsigned int i = 0; i < m_ESPs.size(); ++i) {
+ if (m_ESPs[i].m_Priority < 0) {
+ continue;
}
+ if (m_ESPs[i].m_Priority >= static_cast<int>(m_ESPs.size())) {
+ qCritical("invalid priority %d", m_ESPs[i].m_Priority);
+ continue;
+ }
+ m_ESPsByName[m_ESPs[i].m_Name.toLower()] = i;
+ m_ESPsByPriority.at(static_cast<size_t>(m_ESPs[i].m_Priority)) = i;
+ }
}
-int PluginList::rowCount(const QModelIndex& parent) const {
- if (!parent.isValid()) {
- return static_cast<int>(m_ESPs.size());
- } else {
- return 0;
- }
+
+int PluginList::rowCount(const QModelIndex &parent) const
+{
+ if (!parent.isValid()) {
+ return static_cast<int>(m_ESPs.size());
+ } else {
+ return 0;
+ }
+}
+
+int PluginList::columnCount(const QModelIndex &) const
+{
+ return COL_LASTCOLUMN + 1;
}
-int PluginList::columnCount(const QModelIndex&) const { return COL_LASTCOLUMN + 1; }
-void PluginList::testMasters() {
- // emit layoutAboutToBeChanged();
+void PluginList::testMasters()
+{
+// emit layoutAboutToBeChanged();
- std::set<QString> enabledMasters;
- for (const auto& iter : m_ESPs) {
- if (iter.m_Enabled) {
- enabledMasters.insert(iter.m_Name.toLower());
- }
+ std::set<QString> enabledMasters;
+ for (const auto& iter: m_ESPs) {
+ if (iter.m_Enabled) {
+ enabledMasters.insert(iter.m_Name.toLower());
}
+ }
- for (auto& iter : m_ESPs) {
- iter.m_MasterUnset.clear();
- if (iter.m_Enabled) {
- for (const auto& master : iter.m_Masters) {
- if (enabledMasters.find(master.toLower()) == enabledMasters.end()) {
- iter.m_MasterUnset.insert(master);
- }
- }
+ for (auto& iter: m_ESPs) {
+ iter.m_MasterUnset.clear();
+ if (iter.m_Enabled) {
+ for (const auto& master: iter.m_Masters) {
+ if (enabledMasters.find(master.toLower()) == enabledMasters.end()) {
+ iter.m_MasterUnset.insert(master);
}
+ }
}
+ }
#pragma message("emitting this seems to cause a crash!")
- // emit layoutChanged();
+// emit layoutChanged();
}
-QVariant PluginList::data(const QModelIndex& modelIndex, int role) const {
- int index = modelIndex.row();
- if ((role == Qt::DisplayRole) || (role == Qt::EditRole)) {
- switch (modelIndex.column()) {
- case COL_NAME: {
- return m_ESPs[index].m_Name;
- } break;
- case COL_PRIORITY: {
- return m_ESPs[index].m_Priority;
- } break;
- case COL_MODINDEX: {
- if (m_ESPs[index].m_LoadOrder == -1) {
- return QString();
- } else {
- int numESLs = 0;
- std::vector<ESPInfo> sortESPs(m_ESPs);
- std::sort(sortESPs.begin(), sortESPs.end());
- for (auto sortedESP : sortESPs) {
- if (sortedESP.m_LoadOrder == m_ESPs[index].m_LoadOrder)
- break;
- if (sortedESP.m_IsLight && sortedESP.m_LoadOrder != -1)
- ++numESLs;
- }
- if (m_ESPs[index].m_IsLight) {
- int ESLpos = 254 + ((numESLs + 1) / 4096);
- return QString("%1:%2").arg(ESLpos, 2, 16, QChar('0')).arg((numESLs) % 4096).toUpper();
- } else {
- return QString("%1").arg(m_ESPs[index].m_LoadOrder - numESLs, 2, 16, QChar('0')).toUpper();
- }
- }
- } break;
- default: { return QVariant(); } break;
- }
- } else if ((role == Qt::CheckStateRole) && (modelIndex.column() == 0)) {
- if (m_ESPs[index].m_ForceEnabled) {
- return QVariant();
- } else {
- return m_ESPs[index].m_Enabled ? Qt::Checked : Qt::Unchecked;
- }
- } else if (role == Qt::ForegroundRole) {
- if ((modelIndex.column() == COL_NAME) && m_ESPs[index].m_ForceEnabled) {
- return QBrush(Qt::gray);
- }
- } else if (role == Qt::BackgroundRole || (role == ViewMarkingScrollBar::DEFAULT_ROLE)) {
- if (m_ESPs[index].m_ModSelected) {
- return QColor(0, 0, 255, 32);
- } else {
- return QVariant();
- }
- } else if (role == Qt::FontRole) {
- QFont result;
- if (m_ESPs[index].m_IsMaster) {
- result.setItalic(true);
- result.setWeight(QFont::Bold);
- } else if (m_ESPs[index].m_IsLight) {
- result.setItalic(true);
- }
- return result;
- } else if (role == Qt::TextAlignmentRole) {
- if (modelIndex.column() == 0) {
- return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
- } else {
- return QVariant(Qt::AlignHCenter | Qt::AlignVCenter);
- }
- } else if (role == Qt::ToolTipRole) {
- QString name = m_ESPs[index].m_Name.toLower();
- auto addInfoIter = m_AdditionalInfo.find(name);
- QString toolTip;
- if (addInfoIter != m_AdditionalInfo.end()) {
- if (!addInfoIter->second.m_Messages.isEmpty()) {
- toolTip += addInfoIter->second.m_Messages.join("<br>") + "<br><hr>";
- }
- }
- if (m_ESPs[index].m_ForceEnabled) {
- QString text = tr("<b>Origin</b>: %1").arg(m_ESPs[index].m_OriginName);
- text += tr("<br><b><i>This plugin can't be disabled (enforced by the game).</i></b>");
- toolTip += text;
+QVariant PluginList::data(const QModelIndex &modelIndex, int role) const
+{
+ int index = modelIndex.row();
+ if ((role == Qt::DisplayRole)
+ || (role == Qt::EditRole)) {
+ switch (modelIndex.column()) {
+ case COL_NAME: {
+ return m_ESPs[index].m_Name;
+ } break;
+ case COL_PRIORITY: {
+ return m_ESPs[index].m_Priority;
+ } break;
+ case COL_MODINDEX: {
+ if (m_ESPs[index].m_LoadOrder == -1) {
+ return QString();
} else {
- QString text = tr("<b>Origin</b>: %1").arg(m_ESPs[index].m_OriginName);
- if (m_ESPs[index].m_Author.size() > 0) {
- text += "<br><b>" + tr("Author") + "</b>: " + m_ESPs[index].m_Author;
- }
- if (m_ESPs[index].m_Description.size() > 0) {
- text += "<br><b>" + tr("Description") + "</b>: " + m_ESPs[index].m_Description;
- }
- if (m_ESPs[index].m_MasterUnset.size() > 0) {
- text += "<br><b>" + tr("Missing Masters") + "</b>: <b>" + SetJoin(m_ESPs[index].m_MasterUnset, ", ") +
- "</b>";
- }
- std::set<QString> enabledMasters;
- std::set_difference(m_ESPs[index].m_Masters.begin(), m_ESPs[index].m_Masters.end(),
- m_ESPs[index].m_MasterUnset.begin(), m_ESPs[index].m_MasterUnset.end(),
- std::inserter(enabledMasters, enabledMasters.end()));
- if (!enabledMasters.empty()) {
- text += "<br><b>" + tr("Enabled Masters") + "</b>: " + SetJoin(enabledMasters, ", ");
- }
- if (m_ESPs[index].m_HasIni) {
- text += "<br>There is an ini file connected to this esp. Its settings will be added to your game "
- "settings, overwriting "
- "in case of conflicts.";
- }
- toolTip += text;
- }
- return toolTip;
- } else if (role == Qt::UserRole + 1) {
- QVariantList result;
- QString nameLower = m_ESPs[index].m_Name.toLower();
- if (m_ESPs[index].m_MasterUnset.size() > 0) {
- result.append(":/MO/gui/warning");
- }
- if (m_LockedOrder.find(nameLower) != m_LockedOrder.end()) {
- result.append(":/MO/gui/locked");
+ int numESLs = 0;
+ std::vector<ESPInfo> sortESPs(m_ESPs);
+ std::sort(sortESPs.begin(), sortESPs.end());
+ for (auto sortedESP: sortESPs) {
+ if (sortedESP.m_LoadOrder == m_ESPs[index].m_LoadOrder)
+ break;
+ if (sortedESP.m_IsLight && sortedESP.m_LoadOrder != -1)
+ ++numESLs;
+ }
+ if (m_ESPs[index].m_IsLight) {
+ int ESLpos = 254 + ((numESLs+1) / 4096);
+ return QString("%1:%2").arg(ESLpos, 2, 16, QChar('0')).arg((numESLs)%4096).toUpper();
+ } else {
+ return QString("%1").arg(m_ESPs[index].m_LoadOrder - numESLs, 2, 16, QChar('0')).toUpper();
+ }
}
- auto bossInfoIter = m_AdditionalInfo.find(nameLower);
- if (bossInfoIter != m_AdditionalInfo.end()) {
- if (!bossInfoIter->second.m_Messages.isEmpty()) {
- result.append(":/MO/gui/information");
- }
- }
- if (m_ESPs[index].m_HasIni) {
- result.append(":/MO/gui/attachment");
- }
- return result;
+ } break;
+ default: {
+ return QVariant();
+ } break;
+ }
+ } else if ((role == Qt::CheckStateRole) && (modelIndex.column() == 0)) {
+ if (m_ESPs[index].m_ForceEnabled) {
+ return QVariant();
+ } else {
+ return m_ESPs[index].m_Enabled ? Qt::Checked : Qt::Unchecked;
+ }
+ } else if (role == Qt::ForegroundRole) {
+ if ((modelIndex.column() == COL_NAME) &&
+ m_ESPs[index].m_ForceEnabled) {
+ return QBrush(Qt::gray);
+ }
+ } else if (role == Qt::BackgroundRole
+ || (role == ViewMarkingScrollBar::DEFAULT_ROLE)) {
+ if (m_ESPs[index].m_ModSelected) {
+ return QColor(0, 0, 255, 32);
+ } else {
+ return QVariant();
}
- return QVariant();
+ } else if (role == Qt::FontRole) {
+ QFont result;
+ if (m_ESPs[index].m_IsMaster) {
+ result.setItalic(true);
+ result.setWeight(QFont::Bold);
+ } else if (m_ESPs[index].m_IsLight) {
+ result.setItalic(true);
+ }
+ return result;
+ } else if (role == Qt::TextAlignmentRole) {
+ if (modelIndex.column() == 0) {
+ return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
+ } else {
+ return QVariant(Qt::AlignHCenter | Qt::AlignVCenter);
+ }
+ } else if (role == Qt::ToolTipRole) {
+ QString name = m_ESPs[index].m_Name.toLower();
+ auto addInfoIter = m_AdditionalInfo.find(name);
+ QString toolTip;
+ if (addInfoIter != m_AdditionalInfo.end()) {
+ if (!addInfoIter->second.m_Messages.isEmpty()) {
+ toolTip += addInfoIter->second.m_Messages.join("<br>") + "<br><hr>";
+ }
+ }
+ if (m_ESPs[index].m_ForceEnabled) {
+ QString text = tr("<b>Origin</b>: %1").arg(m_ESPs[index].m_OriginName);
+ text += tr("<br><b><i>This plugin can't be disabled (enforced by the game).</i></b>");
+ toolTip += text;
+ } else {
+ QString text = tr("<b>Origin</b>: %1").arg(m_ESPs[index].m_OriginName);
+ if (m_ESPs[index].m_Author.size() > 0) {
+ text += "<br><b>" + tr("Author") + "</b>: " + m_ESPs[index].m_Author;
+ }
+ if (m_ESPs[index].m_Description.size() > 0) {
+ text += "<br><b>" + tr("Description") + "</b>: " + m_ESPs[index].m_Description;
+ }
+ if (m_ESPs[index].m_MasterUnset.size() > 0) {
+ text += "<br><b>" + tr("Missing Masters") + "</b>: <b>" + SetJoin(m_ESPs[index].m_MasterUnset, ", ") + "</b>";
+ }
+ std::set<QString> enabledMasters;
+ std::set_difference(m_ESPs[index].m_Masters.begin(), m_ESPs[index].m_Masters.end(),
+ m_ESPs[index].m_MasterUnset.begin(), m_ESPs[index].m_MasterUnset.end(),
+ std::inserter(enabledMasters, enabledMasters.end()));
+ if (!enabledMasters.empty()) {
+ text += "<br><b>" + tr("Enabled Masters") + "</b>: " + SetJoin(enabledMasters, ", ");
+ }
+ if (m_ESPs[index].m_HasIni) {
+ text += "<br>There is an ini file connected to this esp. Its settings will be added to your game settings, overwriting "
+ "in case of conflicts.";
+ }
+ toolTip += text;
+ }
+ return toolTip;
+ } else if (role == Qt::UserRole + 1) {
+ QVariantList result;
+ QString nameLower = m_ESPs[index].m_Name.toLower();
+ if (m_ESPs[index].m_MasterUnset.size() > 0) {
+ result.append(":/MO/gui/warning");
+ }
+ if (m_LockedOrder.find(nameLower) != m_LockedOrder.end()) {
+ result.append(":/MO/gui/locked");
+ }
+ auto bossInfoIter = m_AdditionalInfo.find(nameLower);
+ if (bossInfoIter != m_AdditionalInfo.end()) {
+ if (!bossInfoIter->second.m_Messages.isEmpty()) {
+ result.append(":/MO/gui/information");
+ }
+ }
+ if (m_ESPs[index].m_HasIni) {
+ result.append(":/MO/gui/attachment");
+ }
+ return result;
+ }
+ return QVariant();
}
-bool PluginList::setData(const QModelIndex& modIndex, const QVariant& value, int role) {
- QString modName = modIndex.data().toString();
- IPluginList::PluginStates oldState = state(modName);
- bool result = false;
+bool PluginList::setData(const QModelIndex &modIndex, const QVariant &value, int role)
+{
+ QString modName = modIndex.data().toString();
+ IPluginList::PluginStates oldState = state(modName);
- if (role == Qt::CheckStateRole) {
- m_ESPs[modIndex.row()].m_Enabled = value.toInt() == Qt::Checked || m_ESPs[modIndex.row()].m_ForceEnabled;
- emit dataChanged(modIndex, modIndex);
+ bool result = false;
- refreshLoadOrder();
- emit writePluginsList();
+ if (role == Qt::CheckStateRole) {
+ m_ESPs[modIndex.row()].m_Enabled =
+ value.toInt() == Qt::Checked || m_ESPs[modIndex.row()].m_ForceEnabled;
+ emit dataChanged(modIndex, modIndex);
+
+ refreshLoadOrder();
+ emit writePluginsList();
+ result = true;
+ } else if (role == Qt::EditRole) {
+ if (modIndex.column() == COL_PRIORITY) {
+ bool ok = false;
+ int newPriority = value.toInt(&ok);
+ if (ok) {
+ setPluginPriority(modIndex.row(), newPriority);
result = true;
- } else if (role == Qt::EditRole) {
- if (modIndex.column() == COL_PRIORITY) {
- bool ok = false;
- int newPriority = value.toInt(&ok);
- if (ok) {
- setPluginPriority(modIndex.row(), newPriority);
- result = true;
- }
- refreshLoadOrder();
- }
+ }
+ refreshLoadOrder();
}
+ }
- IPluginList::PluginStates newState = state(modName);
- if (oldState != newState) {
- try {
- m_PluginStateChanged(modName, newState);
- testMasters();
- emit dataChanged(this->index(0, 0), this->index(static_cast<int>(m_ESPs.size()), columnCount()));
- } catch (const std::exception& e) {
- qCritical("failed to invoke state changed notification: %s", e.what());
- } catch (...) {
- qCritical("failed to invoke state changed notification: unknown exception");
- }
+ IPluginList::PluginStates newState = state(modName);
+ if (oldState != newState) {
+ try {
+ m_PluginStateChanged(modName, newState);
+ testMasters();
+ emit dataChanged(
+ this->index(0, 0),
+ this->index(static_cast<int>(m_ESPs.size()), columnCount()));
+ } catch (const std::exception &e) {
+ qCritical("failed to invoke state changed notification: %s", e.what());
+ } catch (...) {
+ qCritical("failed to invoke state changed notification: unknown exception");
}
+ }
- return result;
+ return result;
}
-QVariant PluginList::headerData(int section, Qt::Orientation orientation, int role) const {
- if (orientation == Qt::Horizontal) {
- if (role == Qt::DisplayRole) {
- return getColumnName(section);
- } else if (role == Qt::ToolTipRole) {
- return getColumnToolTip(section);
- } else if (role == Qt::SizeHintRole) {
- QSize temp = m_FontMetrics.size(Qt::TextSingleLine, getColumnName(section));
- temp.rwidth() += 25;
- temp.rheight() += 12;
- return temp;
- }
+
+QVariant PluginList::headerData(int section, Qt::Orientation orientation,
+ int role) const
+{
+ if (orientation == Qt::Horizontal) {
+ if (role == Qt::DisplayRole) {
+ return getColumnName(section);
+ } else if (role == Qt::ToolTipRole) {
+ return getColumnToolTip(section);
+ } else if (role == Qt::SizeHintRole) {
+ QSize temp = m_FontMetrics.size(Qt::TextSingleLine, getColumnName(section));
+ temp.rwidth() += 25;
+ temp.rheight() += 12;
+ return temp;
}
- return QAbstractItemModel::headerData(section, orientation, role);
+ }
+ return QAbstractItemModel::headerData(section, orientation, role);
}
-Qt::ItemFlags PluginList::flags(const QModelIndex& modelIndex) const {
- int index = modelIndex.row();
- Qt::ItemFlags result = QAbstractItemModel::flags(modelIndex);
- if (modelIndex.isValid()) {
- if (!m_ESPs[index].m_ForceEnabled) {
- result |= Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled;
- }
- if (modelIndex.column() == COL_PRIORITY) {
- result |= Qt::ItemIsEditable;
- }
- result &= ~Qt::ItemIsDropEnabled;
- } else {
- result |= Qt::ItemIsDropEnabled;
+Qt::ItemFlags PluginList::flags(const QModelIndex &modelIndex) const
+{
+ int index = modelIndex.row();
+ Qt::ItemFlags result = QAbstractItemModel::flags(modelIndex);
+
+ if (modelIndex.isValid()) {
+ if (!m_ESPs[index].m_ForceEnabled) {
+ result |= Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled;
}
+ if (modelIndex.column() == COL_PRIORITY) {
+ result |= Qt::ItemIsEditable;
+ }
+ result &= ~Qt::ItemIsDropEnabled;
+ } else {
+ result |= Qt::ItemIsDropEnabled;
+ }
- return result;
+ return result;
}
-void PluginList::setPluginPriority(int row, int& newPriority) {
- int newPriorityTemp = newPriority;
- if (!m_ESPs[row].m_IsMaster && !m_ESPs[row].m_IsLight) {
- // don't allow esps to be moved above esms
- while ((newPriorityTemp < static_cast<int>(m_ESPsByPriority.size() - 1)) &&
- (m_ESPs.at(m_ESPsByPriority.at(newPriorityTemp)).m_IsMaster ||
- m_ESPs.at(m_ESPsByPriority.at(newPriorityTemp)).m_IsLight)) {
- ++newPriorityTemp;
- }
- } else {
- // don't allow esms to be moved below esps
- while ((newPriorityTemp > 0) && !m_ESPs.at(m_ESPsByPriority.at(newPriorityTemp)).m_IsMaster &&
- !m_ESPs.at(m_ESPsByPriority.at(newPriorityTemp)).m_IsLight) {
- --newPriorityTemp;
- }
- // also don't allow "regular" esms to be moved above primary plugins
- while ((newPriorityTemp < static_cast<int>(m_ESPsByPriority.size() - 1)) &&
- (m_ESPs.at(m_ESPsByPriority.at(newPriorityTemp)).m_ForceEnabled)) {
- ++newPriorityTemp;
- }
+void PluginList::setPluginPriority(int row, int &newPriority)
+{
+ int newPriorityTemp = newPriority;
+
+ if (!m_ESPs[row].m_IsMaster && !m_ESPs[row].m_IsLight) {
+ // don't allow esps to be moved above esms
+ while ((newPriorityTemp < static_cast<int>(m_ESPsByPriority.size() - 1)) &&
+ (m_ESPs.at(m_ESPsByPriority.at(newPriorityTemp)).m_IsMaster ||
+ m_ESPs.at(m_ESPsByPriority.at(newPriorityTemp)).m_IsLight)) {
+ ++newPriorityTemp;
}
+ } else {
+ // don't allow esms to be moved below esps
+ while ((newPriorityTemp > 0) &&
+ !m_ESPs.at(m_ESPsByPriority.at(newPriorityTemp)).m_IsMaster &&
+ !m_ESPs.at(m_ESPsByPriority.at(newPriorityTemp)).m_IsLight) {
+ --newPriorityTemp;
+ }
+ // also don't allow "regular" esms to be moved above primary plugins
+ while ((newPriorityTemp < static_cast<int>(m_ESPsByPriority.size() - 1)) &&
+ (m_ESPs.at(m_ESPsByPriority.at(newPriorityTemp)).m_ForceEnabled)) {
+ ++newPriorityTemp;
+ }
+ }
- // enforce valid range
- if (newPriorityTemp < 0)
- newPriorityTemp = 0;
- else if (newPriorityTemp >= static_cast<int>(m_ESPsByPriority.size()))
- newPriorityTemp = static_cast<int>(m_ESPsByPriority.size()) - 1;
+ // enforce valid range
+ if (newPriorityTemp < 0)
+ newPriorityTemp = 0;
+ else if (newPriorityTemp >= static_cast<int>(m_ESPsByPriority.size()))
+ newPriorityTemp = static_cast<int>(m_ESPsByPriority.size()) - 1;
- try {
- int oldPriority = m_ESPs.at(row).m_Priority;
- if (newPriorityTemp > oldPriority) {
- // priority is higher than the old, so the gap we left is in lower priorities
- for (int i = oldPriority + 1; i <= newPriorityTemp; ++i) {
- --m_ESPs.at(m_ESPsByPriority.at(i)).m_Priority;
- }
- emit dataChanged(index(oldPriority + 1, 0), index(newPriorityTemp, columnCount()));
- } else {
- for (int i = newPriorityTemp; i < oldPriority; ++i) {
- ++m_ESPs.at(m_ESPsByPriority.at(i)).m_Priority;
- }
- emit dataChanged(index(newPriorityTemp, 0), index(oldPriority - 1, columnCount()));
- ++newPriority;
- }
-
- m_ESPs.at(row).m_Priority = newPriorityTemp;
- emit dataChanged(index(row, 0), index(row, columnCount()));
- m_PluginMoved(m_ESPs[row].m_Name, oldPriority, newPriorityTemp);
- } catch (const std::out_of_range&) {
- reportError(tr("failed to restore load order for %1").arg(m_ESPs[row].m_Name));
+ try {
+ int oldPriority = m_ESPs.at(row).m_Priority;
+ if (newPriorityTemp > oldPriority) {
+ // priority is higher than the old, so the gap we left is in lower priorities
+ for (int i = oldPriority + 1; i <= newPriorityTemp; ++i) {
+ --m_ESPs.at(m_ESPsByPriority.at(i)).m_Priority;
+ }
+ emit dataChanged(index(oldPriority + 1, 0), index(newPriorityTemp, columnCount()));
+ } else {
+ for (int i = newPriorityTemp; i < oldPriority; ++i) {
+ ++m_ESPs.at(m_ESPsByPriority.at(i)).m_Priority;
+ }
+ emit dataChanged(index(newPriorityTemp, 0), index(oldPriority - 1, columnCount()));
+ ++newPriority;
}
- updateIndices();
+ m_ESPs.at(row).m_Priority = newPriorityTemp;
+ emit dataChanged(index(row, 0), index(row, columnCount()));
+ m_PluginMoved(m_ESPs[row].m_Name, oldPriority, newPriorityTemp);
+ } catch (const std::out_of_range&) {
+ reportError(tr("failed to restore load order for %1").arg(m_ESPs[row].m_Name));
+ }
+
+ updateIndices();
}
-void PluginList::changePluginPriority(std::vector<int> rows, int newPriority) {
- ChangeBracket<PluginList> layoutChange(this);
- // sort rows to insert by their old priority (ascending) and insert them move them in that order
- const std::vector<ESPInfo>& esp = m_ESPs;
- std::sort(rows.begin(), rows.end(),
- [&esp](const int& LHS, const int& RHS) { return esp[LHS].m_Priority < esp[RHS].m_Priority; });
- // odd stuff: if any of the dragged sources has priority lower than the destination then the
- // target idx is that of the row BELOW the dropped location, otherwise it's the one above. why?
- for (std::vector<int>::const_iterator iter = rows.begin(); iter != rows.end(); ++iter) {
- if (m_ESPs[*iter].m_Priority < newPriority) {
- --newPriority;
- break;
- }
- }
+void PluginList::changePluginPriority(std::vector<int> rows, int newPriority)
+{
+ ChangeBracket<PluginList> layoutChange(this);
+ // sort rows to insert by their old priority (ascending) and insert them move them in that order
+ const std::vector<ESPInfo> &esp = m_ESPs;
+ std::sort(rows.begin(), rows.end(),
+ [&esp](const int &LHS, const int &RHS) {
+ return esp[LHS].m_Priority < esp[RHS].m_Priority;
+ });
- for (std::vector<int>::const_iterator iter = rows.begin(); iter != rows.end(); ++iter) {
- setPluginPriority(*iter, newPriority);
+ // odd stuff: if any of the dragged sources has priority lower than the destination then the
+ // target idx is that of the row BELOW the dropped location, otherwise it's the one above. why?
+ for (std::vector<int>::const_iterator iter = rows.begin();
+ iter != rows.end(); ++iter) {
+ if (m_ESPs[*iter].m_Priority < newPriority) {
+ --newPriority;
+ break;
}
+ }
- layoutChange.finish();
- refreshLoadOrder();
- emit writePluginsList();
+ for (std::vector<int>::const_iterator iter = rows.begin(); iter != rows.end(); ++iter) {
+ setPluginPriority(*iter, newPriority);
+ }
+
+ layoutChange.finish();
+ refreshLoadOrder();
+ emit writePluginsList();
}
-bool PluginList::dropMimeData(const QMimeData* mimeData, Qt::DropAction action, int row, int,
- const QModelIndex& parent) {
- if (action == Qt::IgnoreAction) {
- return true;
- }
+bool PluginList::dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int, const QModelIndex &parent)
+{
+ if (action == Qt::IgnoreAction) {
+ return true;
+ }
- QByteArray encoded = mimeData->data("application/x-qabstractitemmodeldatalist");
- QDataStream stream(&encoded, QIODevice::ReadOnly);
+ QByteArray encoded = mimeData->data("application/x-qabstractitemmodeldatalist");
+ QDataStream stream(&encoded, QIODevice::ReadOnly);
- std::vector<int> sourceRows;
+ std::vector<int> sourceRows;
- while (!stream.atEnd()) {
- int sourceRow, col;
- QMap<int, QVariant> roleDataMap;
- stream >> sourceRow >> col >> roleDataMap;
- if (col == 0) { // only add each row once
- sourceRows.push_back(sourceRow);
- }
+ while (!stream.atEnd()) {
+ int sourceRow, col;
+ QMap<int, QVariant> roleDataMap;
+ stream >> sourceRow >> col >> roleDataMap;
+ if (col == 0) { // only add each row once
+ sourceRows.push_back(sourceRow);
}
+ }
- if (row == -1) {
- row = parent.row();
- }
+ if (row == -1) {
+ row = parent.row();
+ }
- int newPriority;
+ int newPriority;
- if ((row < 0) || (row >= static_cast<int>(m_ESPs.size()))) {
- newPriority = static_cast<int>(m_ESPs.size());
- } else {
- newPriority = m_ESPs[row].m_Priority;
- }
- changePluginPriority(sourceRows, newPriority);
+ if ((row < 0) ||
+ (row >= static_cast<int>(m_ESPs.size()))) {
+ newPriority = static_cast<int>(m_ESPs.size());
+ } else {
+ newPriority = m_ESPs[row].m_Priority;
+ }
+ changePluginPriority(sourceRows, newPriority);
- return false;
+ return false;
}
-QModelIndex PluginList::index(int row, int column, const QModelIndex&) const {
- if ((row < 0) || (row >= rowCount()) || (column < 0) || (column >= columnCount())) {
- return QModelIndex();
- }
- return createIndex(row, column, row);
+QModelIndex PluginList::index(int row, int column, const QModelIndex&) const
+{
+ if ((row < 0) || (row >= rowCount()) || (column < 0) || (column >= columnCount())) {
+ return QModelIndex();
+ }
+ return createIndex(row, column, row);
}
-QModelIndex PluginList::parent(const QModelIndex&) const { return QModelIndex(); }
+QModelIndex PluginList::parent(const QModelIndex&) const
+{
+ return QModelIndex();
+}
-bool PluginList::eventFilter(QObject* obj, QEvent* event) {
- if (event->type() == QEvent::KeyPress) {
- QAbstractItemView* itemView = qobject_cast<QAbstractItemView*>(obj);
- if (itemView == nullptr) {
- return QAbstractItemModel::eventFilter(obj, event);
- }
+bool PluginList::eventFilter(QObject *obj, QEvent *event)
+{
+ if (event->type() == QEvent::KeyPress) {
+ QAbstractItemView *itemView = qobject_cast<QAbstractItemView*>(obj);
- QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
- // ctrl+up and ctrl+down -> increase or decrease priority of selected plugins
- if ((keyEvent->modifiers() == Qt::ControlModifier) &&
- ((keyEvent->key() == Qt::Key_Up) || (keyEvent->key() == Qt::Key_Down))) {
- QItemSelectionModel* selectionModel = itemView->selectionModel();
- const QSortFilterProxyModel* proxyModel =
- qobject_cast<const QSortFilterProxyModel*>(selectionModel->model());
- if (proxyModel != nullptr) {
- int diff = -1;
- if (((keyEvent->key() == Qt::Key_Up) && (proxyModel->sortOrder() == Qt::DescendingOrder)) ||
- ((keyEvent->key() == Qt::Key_Down) && (proxyModel->sortOrder() == Qt::AscendingOrder))) {
- diff = 1;
- }
- QModelIndexList rows = selectionModel->selectedRows();
- // remove elements that aren't supposed to be movable
- QMutableListIterator<QModelIndex> iter(rows);
- while (iter.hasNext()) {
- if ((iter.next().flags() & Qt::ItemIsDragEnabled) == 0) {
- iter.remove();
- }
- }
- if (keyEvent->key() == Qt::Key_Down) {
- for (int i = 0; i < rows.size() / 2; ++i) {
- rows.swap(i, rows.size() - i - 1);
- }
- }
- for (QModelIndex idx : rows) {
- idx = proxyModel->mapToSource(idx);
- int newPriority = m_ESPs[idx.row()].m_Priority + diff;
- if ((newPriority >= 0) && (newPriority < rowCount())) {
- setPluginPriority(idx.row(), newPriority);
- }
- }
- refreshLoadOrder();
- }
- return true;
- } else if (keyEvent->key() == Qt::Key_Space) {
- QItemSelectionModel* selectionModel = itemView->selectionModel();
- const QSortFilterProxyModel* proxyModel =
- qobject_cast<const QSortFilterProxyModel*>(selectionModel->model());
- QList<QPersistentModelIndex> indices;
- for (QModelIndex idx : selectionModel->selectedRows()) {
- indices.append(idx);
- }
+ if (itemView == nullptr) {
+ return QAbstractItemModel::eventFilter(obj, event);
+ }
- QModelIndex minRow, maxRow;
- for (QModelIndex idx : indices) {
- if (proxyModel != nullptr) {
- idx = proxyModel->mapToSource(idx);
- }
- if (!minRow.isValid() || (idx.row() < minRow.row())) {
- minRow = idx;
- }
- if (!maxRow.isValid() || (idx.row() > maxRow.row())) {
- maxRow = idx;
- }
- int oldState = idx.data(Qt::CheckStateRole).toInt();
- setData(idx, oldState == Qt::Unchecked ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
- }
- emit dataChanged(minRow, maxRow);
+ QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
+ // ctrl+up and ctrl+down -> increase or decrease priority of selected plugins
+ if ((keyEvent->modifiers() == Qt::ControlModifier) &&
+ ((keyEvent->key() == Qt::Key_Up) || (keyEvent->key() == Qt::Key_Down))) {
+ QItemSelectionModel *selectionModel = itemView->selectionModel();
+ const QSortFilterProxyModel *proxyModel = qobject_cast<const QSortFilterProxyModel*>(selectionModel->model());
+ if (proxyModel != nullptr) {
+ int diff = -1;
+ if (((keyEvent->key() == Qt::Key_Up) && (proxyModel->sortOrder() == Qt::DescendingOrder)) ||
+ ((keyEvent->key() == Qt::Key_Down) && (proxyModel->sortOrder() == Qt::AscendingOrder))) {
+ diff = 1;
+ }
+ QModelIndexList rows = selectionModel->selectedRows();
+ // remove elements that aren't supposed to be movable
+ QMutableListIterator<QModelIndex> iter(rows);
+ while (iter.hasNext()) {
+ if ((iter.next().flags() & Qt::ItemIsDragEnabled) == 0) {
+ iter.remove();
+ }
+ }
+ if (keyEvent->key() == Qt::Key_Down) {
+ for (int i = 0; i < rows.size() / 2; ++i) {
+ rows.swap(i, rows.size() - i - 1);
+ }
+ }
+ for (QModelIndex idx : rows) {
+ idx = proxyModel->mapToSource(idx);
+ int newPriority = m_ESPs[idx.row()].m_Priority + diff;
+ if ((newPriority >= 0) && (newPriority < rowCount())) {
+ setPluginPriority(idx.row(), newPriority);
+ }
+ }
+ refreshLoadOrder();
+ }
+ return true;
+ } else if (keyEvent->key() == Qt::Key_Space) {
+ QItemSelectionModel *selectionModel = itemView->selectionModel();
+ const QSortFilterProxyModel *proxyModel = qobject_cast<const QSortFilterProxyModel*>(selectionModel->model());
+ QList<QPersistentModelIndex> indices;
+ for (QModelIndex idx : selectionModel->selectedRows()) {
+ indices.append(idx);
+ }
- return true;
+ QModelIndex minRow, maxRow;
+ for (QModelIndex idx : indices) {
+ if (proxyModel != nullptr) {
+ idx = proxyModel->mapToSource(idx);
+ }
+ if (!minRow.isValid() || (idx.row() < minRow.row())) {
+ minRow = idx;
}
+ if (!maxRow.isValid() || (idx.row() > maxRow.row())) {
+ maxRow = idx;
+ }
+ int oldState = idx.data(Qt::CheckStateRole).toInt();
+ setData(idx, oldState == Qt::Unchecked ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
+ }
+ emit dataChanged(minRow, maxRow);
+
+ return true;
}
- return QAbstractItemModel::eventFilter(obj, event);
+ }
+ return QAbstractItemModel::eventFilter(obj, event);
}
-PluginList::ESPInfo::ESPInfo(const QString& name, bool enabled, const QString& originName, const QString& fullPath,
+
+PluginList::ESPInfo::ESPInfo(const QString &name, bool enabled,
+ const QString &originName, const QString &fullPath,
bool hasIni)
- : m_Name(name), m_FullPath(fullPath), m_Enabled(enabled), m_ForceEnabled(enabled), m_Priority(0), m_LoadOrder(-1),
- m_OriginName(originName), m_HasIni(hasIni), m_ModSelected(false) {
- try {
- ESP::File file(ToWString(fullPath));
- m_IsMaster = file.isMaster();
- auto extension = name.right(3).toLower();
- m_IsLight = (extension == "esl"); // The .isLight() header is apparently meaningless.
+ : m_Name(name), m_FullPath(fullPath), m_Enabled(enabled), m_ForceEnabled(enabled),
+ m_Priority(0), m_LoadOrder(-1), m_OriginName(originName), m_HasIni(hasIni), m_ModSelected(false)
+{
+ try {
+ ESP::File file(ToWString(fullPath));
+ m_IsMaster = file.isMaster();
+ auto extension = name.right(3).toLower();
+ m_IsLight = (extension == "esl"); // The .isLight() header is apparently meaningless.
- m_Author = QString::fromLatin1(file.author().c_str());
- m_Description = QString::fromLatin1(file.description().c_str());
- std::set<std::string> masters = file.masters();
- for (auto iter = masters.begin(); iter != masters.end(); ++iter) {
- m_Masters.insert(QString(iter->c_str()));
- }
- } catch (const std::exception& e) {
- qCritical("failed to parse plugin file %s: %s", qPrintable(fullPath), e.what());
- m_IsMaster = false;
- m_IsLight = false;
+ m_Author = QString::fromLatin1(file.author().c_str());
+ m_Description = QString::fromLatin1(file.description().c_str());
+ std::set<std::string> masters = file.masters();
+ for (auto iter = masters.begin(); iter != masters.end(); ++iter) {
+ m_Masters.insert(QString(iter->c_str()));
}
+ } catch (const std::exception &e) {
+ qCritical("failed to parse plugin file %s: %s", qPrintable(fullPath), e.what());
+ m_IsMaster = false;
+ m_IsLight = false;
+ }
}
-void PluginList::managedGameChanged(const IPluginGame* gamePlugin) { m_GamePlugin = gamePlugin; }
+void PluginList::managedGameChanged(const IPluginGame *gamePlugin)
+{
+ m_GamePlugin = gamePlugin;
+}
diff --git a/src/pluginlist.h b/src/pluginlist.h
index 762c4a69..8d1a5491 100644
--- a/src/pluginlist.h
+++ b/src/pluginlist.h
@@ -20,309 +20,324 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef PLUGINLIST_H
#define PLUGINLIST_H
-#include "profile.h"
#include <directoryentry.h>
#include <ipluginlist.h>
-namespace MOBase {
-class IPluginGame;
-}
+#include "profile.h"
+namespace MOBase { class IPluginGame; }
-#include <QListWidget>
#include <QString>
-#include <QTemporaryFile>
+#include <QListWidget>
#include <QTimer>
+#include <QTemporaryFile>
#pragma warning(push)
-#pragma warning(disable : 4100)
+#pragma warning(disable: 4100)
#ifndef Q_MOC_RUN
-#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/signals2.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
#endif
-#include <map>
#include <vector>
+#include <map>
+
template <class C>
class ChangeBracket {
public:
- ChangeBracket(C* model) : m_Model(nullptr) {
- QVariant var = model->property("__aboutToChange");
- bool aboutToChange = var.isValid() && var.toBool();
- if (!aboutToChange) {
- model->layoutAboutToBeChanged();
- model->setProperty("__aboutToChange", true);
- m_Model = model;
- }
+ ChangeBracket(C *model)
+ : m_Model(nullptr)
+ {
+ QVariant var = model->property("__aboutToChange");
+ bool aboutToChange = var.isValid() && var.toBool();
+ if (!aboutToChange) {
+ model->layoutAboutToBeChanged();
+ model->setProperty("__aboutToChange", true);
+ m_Model = model;
}
- ~ChangeBracket() { finish(); }
+ }
+ ~ChangeBracket() {
+ finish();
+ }
- void finish() {
- if (m_Model != nullptr) {
- m_Model->layoutChanged();
- m_Model->setProperty("__aboutToChange", false);
- m_Model = nullptr;
- }
+ void finish() {
+ if (m_Model != nullptr) {
+ m_Model->layoutChanged();
+ m_Model->setProperty("__aboutToChange", false);
+ m_Model = nullptr;
}
+ }
private:
- C* m_Model;
+ C *m_Model;
};
+
+
/**
* @brief model representing the plugins (.esp/.esm) in the current virtual data folder
**/
-class PluginList : public QAbstractItemModel, public MOBase::IPluginList {
- Q_OBJECT
- friend class ChangeBracket<PluginList>;
-
+class PluginList : public QAbstractItemModel, public MOBase::IPluginList
+{
+ Q_OBJECT
+ friend class ChangeBracket<PluginList>;
public:
- enum EColumn {
- COL_NAME,
- COL_FLAGS,
- COL_PRIORITY,
- COL_MODINDEX,
- COL_LASTCOLUMN = COL_MODINDEX
- };
+ enum EColumn {
+ COL_NAME,
+ COL_FLAGS,
+ COL_PRIORITY,
+ COL_MODINDEX,
+
+ COL_LASTCOLUMN = COL_MODINDEX
+ };
- typedef boost::signals2::signal<void()> SignalRefreshed;
- typedef boost::signals2::signal<void(const QString&, int, int)> SignalPluginMoved;
- typedef boost::signals2::signal<void(const QString&, PluginStates)> SignalPluginStateChanged;
+ typedef boost::signals2::signal<void ()> SignalRefreshed;
+ typedef boost::signals2::signal<void (const QString &, int, int)> SignalPluginMoved;
+ typedef boost::signals2::signal<void (const QString &, PluginStates)> SignalPluginStateChanged;
public:
- /**
- * @brief constructor
- *
- * @param parent parent object
- **/
- PluginList(QObject* parent = nullptr);
- ~PluginList();
+ /**
+ * @brief constructor
+ *
+ * @param parent parent object
+ **/
+ PluginList(QObject *parent = nullptr);
- /**
- * @brief does a complete refresh of the list
- *
- * @param profileName name of the current profile
- * @param baseDirectory the root directory structure representing the virtual data directory
- * @param lockedOrderFile list of plugins that shouldn't change load order
- * @todo the profile is not used? If it was, we should pass the Profile-object instead
- **/
- void refresh(const QString& profileName, const MOShared::DirectoryEntry& baseDirectory,
- const QString& lockedOrderFile);
+ ~PluginList();
- /**
- * @brief enable a plugin based on its name
- *
- * @param name name of the plugin to enable
- * @param enable set to true to enable the esp, false to disable it
- **/
- void enableESP(const QString& name, bool enable = true);
+ /**
+ * @brief does a complete refresh of the list
+ *
+ * @param profileName name of the current profile
+ * @param baseDirectory the root directory structure representing the virtual data directory
+ * @param lockedOrderFile list of plugins that shouldn't change load order
+ * @todo the profile is not used? If it was, we should pass the Profile-object instead
+ **/
+ void refresh(const QString &profileName
+ , const MOShared::DirectoryEntry &baseDirectory
+ , const QString &lockedOrderFile);
- /**
- * @brief test if a plugin is enabled
- *
- * @param name name of the plugin to look up
- * @return true if the plugin is enabled, false otherwise
- **/
- bool isEnabled(const QString& name);
+ /**
+ * @brief enable a plugin based on its name
+ *
+ * @param name name of the plugin to enable
+ * @param enable set to true to enable the esp, false to disable it
+ **/
+ void enableESP(const QString &name, bool enable = true);
- /**
- * @brief clear all additional information we stored on plugins
- */
- void clearAdditionalInformation();
+ /**
+ * @brief test if a plugin is enabled
+ *
+ * @param name name of the plugin to look up
+ * @return true if the plugin is enabled, false otherwise
+ **/
+ bool isEnabled(const QString &name);
- /**
- * @brief reset additional information on a mod
- * @param name name of the plugin to clear the information of
- */
- void clearInformation(const QString& name);
+ /**
+ * @brief clear all additional information we stored on plugins
+ */
+ void clearAdditionalInformation();
- /**
- * @brief add additional information on a mod (i.e. from loot)
- * @param name name of the plugin to add information about
- * @param message the message to add to the plugin
- */
- void addInformation(const QString& name, const QString& message);
+ /**
+ * @brief reset additional information on a mod
+ * @param name name of the plugin to clear the information of
+ */
+ void clearInformation(const QString &name);
- /**
- * @brief test if a plugin is enabled
- *
- * @param index index of the plugin to look up
- * @return true if the plugin is enabled, false otherwise
- * @throws std::out_of_range exception is thrown if index is invalid
- **/
- bool isEnabled(int index);
+ /**
+ * @brief add additional information on a mod (i.e. from loot)
+ * @param name name of the plugin to add information about
+ * @param message the message to add to the plugin
+ */
+ void addInformation(const QString &name, const QString &message);
- /**
- * @brief save the plugin status to the specified file
- *
- * @param lockedOrderFileName path of the lockedorder.txt to write to
- * @param deleterFileName file to receive a list of files to hide from the virtual data tree. This is used to hide
- *unchecked plugins if "hideUnchecked" is true
- * @param hideUnchecked if true, plugins that aren't enabled will be hidden from the virtual data directory
- **/
- void saveTo(const QString& lockedOrderFileName, const QString& deleterFileName, bool hideUnchecked) const;
+ /**
+ * @brief test if a plugin is enabled
+ *
+ * @param index index of the plugin to look up
+ * @return true if the plugin is enabled, false otherwise
+ * @throws std::out_of_range exception is thrown if index is invalid
+ **/
+ bool isEnabled(int index);
- /**
- * @brief save the current load order
- *
- * the load order used by the game is defined by the last modification time which this
- * function sets. An exception is newer version of skyrim where the load order is defined
- * by the order of files in plugins.txt
- * @param directoryStructure the root directory structure representing the virtual data directory
- * @return true on success or if there was nothing to save, false if the load order can't be saved, i.e. because
- *files are locked
- * @todo since this works on actual files the load order can't be configured per-profile. Files of the same name
- * in different mods can also have different load orders which makes this very intransparent
- * @note also stores to disk the list of locked esps
- **/
- bool saveLoadOrder(MOShared::DirectoryEntry& directoryStructure);
+ /**
+ * @brief save the plugin status to the specified file
+ *
+ * @param lockedOrderFileName path of the lockedorder.txt to write to
+ * @param deleterFileName file to receive a list of files to hide from the virtual data tree. This is used to hide unchecked plugins if "hideUnchecked" is true
+ * @param hideUnchecked if true, plugins that aren't enabled will be hidden from the virtual data directory
+ **/
+ void saveTo(const QString &lockedOrderFileName
+ , const QString &deleterFileName
+ , bool hideUnchecked) const;
- /**
- * @return number of enabled plugins in the list
- */
- int enabledCount() const;
+ /**
+ * @brief save the current load order
+ *
+ * the load order used by the game is defined by the last modification time which this
+ * function sets. An exception is newer version of skyrim where the load order is defined
+ * by the order of files in plugins.txt
+ * @param directoryStructure the root directory structure representing the virtual data directory
+ * @return true on success or if there was nothing to save, false if the load order can't be saved, i.e. because files are locked
+ * @todo since this works on actual files the load order can't be configured per-profile. Files of the same name
+ * in different mods can also have different load orders which makes this very intransparent
+ * @note also stores to disk the list of locked esps
+ **/
+ bool saveLoadOrder(MOShared::DirectoryEntry &directoryStructure);
- QString getName(int index) const { return m_ESPs.at(index).m_Name; }
- int getPriority(int index) const { return m_ESPs.at(index).m_Priority; }
- bool isESPLocked(int index) const;
- void lockESPIndex(int index, bool lock);
+ /**
+ * @return number of enabled plugins in the list
+ */
+ int enabledCount() const;
- bool eventFilter(QObject* obj, QEvent* event);
+ QString getName(int index) const { return m_ESPs.at(index).m_Name; }
+ int getPriority(int index) const { return m_ESPs.at(index).m_Priority; }
+ bool isESPLocked(int index) const;
+ void lockESPIndex(int index, bool lock);
- static QString getColumnName(int column);
- static QString getColumnToolTip(int column);
+ bool eventFilter(QObject *obj, QEvent *event);
- void highlightPlugins(const QItemSelection& selected, const MOShared::DirectoryEntry& directoryEntry,
- const Profile& profile);
+ static QString getColumnName(int column);
+ static QString getColumnToolTip(int column);
- void refreshLoadOrder();
+ void highlightPlugins(const QItemSelection &selected, const MOShared::DirectoryEntry &directoryEntry, const Profile &profile);
- void disconnectSlots();
+ void refreshLoadOrder();
+
+ void disconnectSlots();
public:
- virtual QStringList pluginNames() const override;
- virtual PluginStates state(const QString& name) const;
- virtual void setState(const QString& name, PluginStates state) override;
- virtual int priority(const QString& name) const;
- virtual int loadOrder(const QString& name) const;
- virtual bool onRefreshed(const std::function<void()>& callback);
- virtual bool isMaster(const QString& name) const;
- virtual bool isLight(const QString& name) const;
- virtual QStringList masters(const QString& name) const;
- virtual QString origin(const QString& name) const;
- virtual void setLoadOrder(const QStringList& pluginList) override;
- virtual bool onPluginMoved(const std::function<void(const QString&, int, int)>& func);
- virtual bool onPluginStateChanged(const std::function<void(const QString&, PluginStates)>& func) override;
+
+ virtual QStringList pluginNames() const override;
+ virtual PluginStates state(const QString &name) const;
+ virtual void setState(const QString &name, PluginStates state) override;
+ virtual int priority(const QString &name) const;
+ virtual int loadOrder(const QString &name) const;
+ virtual bool onRefreshed(const std::function<void()> &callback);
+ virtual bool isMaster(const QString &name) const;
+ virtual bool isLight(const QString &name) const;
+ virtual QStringList masters(const QString &name) const;
+ virtual QString origin(const QString &name) const;
+ virtual void setLoadOrder(const QStringList &pluginList) override;
+ virtual bool onPluginMoved(const std::function<void (const QString &, int, int)> &func);
+ virtual bool onPluginStateChanged(const std::function<void (const QString &, PluginStates)> &func) override;
public: // implementation of the QAbstractTableModel interface
- virtual int rowCount(const QModelIndex& parent = QModelIndex()) const;
- virtual int columnCount(const QModelIndex& parent = QModelIndex()) const;
- virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
- virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
- virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
- virtual Qt::ItemFlags flags(const QModelIndex& index) const;
- virtual Qt::DropActions supportedDropActions() const { return Qt::MoveAction; }
- virtual bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column,
- const QModelIndex& parent);
- virtual QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const;
- virtual QModelIndex parent(const QModelIndex& child) const;
+
+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+ virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+ virtual Qt::ItemFlags flags(const QModelIndex &index) const;
+ virtual Qt::DropActions supportedDropActions() const { return Qt::MoveAction; }
+ virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
+ virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+ virtual QModelIndex parent(const QModelIndex &child) const;
public slots:
- /**
- * @brief enables ALL plugins
- **/
- void enableAll();
+ /**
+ * @brief enables ALL plugins
+ **/
+ void enableAll();
- /**
- * @brief disables ALL plugins
- **/
- void disableAll();
+ /**
+ * @brief disables ALL plugins
+ **/
+ void disableAll();
- /**
- * @brief The currently managed game has changed
- * @param gamePlugin
- */
- void managedGameChanged(MOBase::IPluginGame const* gamePlugin);
+ /**
+ * @brief The currently managed game has changed
+ * @param gamePlugin
+ */
+ void managedGameChanged(MOBase::IPluginGame const *gamePlugin);
signals:
- /**
- * @brief emitted when the plugin list changed, i.e. the load order was modified or a plugin was checked/unchecked
- * @note this is currently only used to signal that there are changes that can be saved, it does
- * not immediately cause anything to be written to disc
- **/
- void esplist_changed();
+ /**
+ * @brief emitted when the plugin list changed, i.e. the load order was modified or a plugin was checked/unchecked
+ * @note this is currently only used to signal that there are changes that can be saved, it does
+ * not immediately cause anything to be written to disc
+ **/
+ void esplist_changed();
- void writePluginsList();
+ void writePluginsList();
private:
- struct ESPInfo {
- ESPInfo(const QString& name, bool enabled, const QString& originName, const QString& fullPath, bool hasIni);
- QString m_Name;
- QString m_FullPath;
- bool m_Enabled;
- bool m_ForceEnabled;
- int m_Priority;
- int m_LoadOrder;
- FILETIME m_Time;
- QString m_OriginName;
- bool m_IsMaster;
- bool m_IsLight;
- bool m_ModSelected;
- QString m_Author;
- QString m_Description;
- bool m_HasIni;
- std::set<QString> m_Masters;
- mutable std::set<QString> m_MasterUnset;
- bool operator<(const ESPInfo& str) const { return (m_LoadOrder < str.m_LoadOrder); }
- };
+ struct ESPInfo {
- struct AdditionalInfo {
- QStringList m_Messages;
- };
+ ESPInfo(const QString &name, bool enabled, const QString &originName, const QString &fullPath, bool hasIni);
+ QString m_Name;
+ QString m_FullPath;
+ bool m_Enabled;
+ bool m_ForceEnabled;
+ int m_Priority;
+ int m_LoadOrder;
+ FILETIME m_Time;
+ QString m_OriginName;
+ bool m_IsMaster;
+ bool m_IsLight;
+ bool m_ModSelected;
+ QString m_Author;
+ QString m_Description;
+ bool m_HasIni;
+ std::set<QString> m_Masters;
+ mutable std::set<QString> m_MasterUnset;
+ bool operator < (const ESPInfo& str) const
+ {
+ return (m_LoadOrder < str.m_LoadOrder);
+ }
+ };
+
+ struct AdditionalInfo {
+ QStringList m_Messages;
+ };
- friend bool ByName(const ESPInfo& LHS, const ESPInfo& RHS);
- friend bool ByDate(const ESPInfo& LHS, const ESPInfo& RHS);
- friend bool ByPriority(const ESPInfo& LHS, const ESPInfo& RHS);
+ friend bool ByName(const ESPInfo& LHS, const ESPInfo& RHS);
+ friend bool ByDate(const ESPInfo& LHS, const ESPInfo& RHS);
+ friend bool ByPriority(const ESPInfo& LHS, const ESPInfo& RHS);
private:
- void syncLoadOrder();
- void updateIndices();
- void writeLockedOrder(const QString& fileName) const;
+ void syncLoadOrder();
+ void updateIndices();
+
+ void writeLockedOrder(const QString &fileName) const;
- void readLockedOrderFrom(const QString& fileName);
- void setPluginPriority(int row, int& newPriority);
- void changePluginPriority(std::vector<int> rows, int newPriority);
+ void readLockedOrderFrom(const QString &fileName);
+ void setPluginPriority(int row, int &newPriority);
+ void changePluginPriority(std::vector<int> rows, int newPriority);
- void testMasters();
+ void testMasters();
- void fixPriorities();
+ void fixPriorities();
private:
- std::vector<ESPInfo> m_ESPs;
- mutable std::map<QString, QByteArray> m_LastSaveHash;
- std::map<QString, int> m_ESPsByName;
- std::vector<int> m_ESPsByPriority;
+ std::vector<ESPInfo> m_ESPs;
+ mutable std::map<QString, QByteArray> m_LastSaveHash;
+
+ std::map<QString, int> m_ESPsByName;
+ std::vector<int> m_ESPsByPriority;
+
+ std::map<QString, int> m_LockedOrder;
- std::map<QString, int> m_LockedOrder;
+ std::map<QString, AdditionalInfo> m_AdditionalInfo; // maps esp names to boss information
- std::map<QString, AdditionalInfo> m_AdditionalInfo; // maps esp names to boss information
+ QString m_CurrentProfile;
+ QFontMetrics m_FontMetrics;
- QString m_CurrentProfile;
- QFontMetrics m_FontMetrics;
+ SignalRefreshed m_Refreshed;
+ SignalPluginMoved m_PluginMoved;
+ SignalPluginStateChanged m_PluginStateChanged;
- SignalRefreshed m_Refreshed;
- SignalPluginMoved m_PluginMoved;
- SignalPluginStateChanged m_PluginStateChanged;
+ QTemporaryFile m_TempFile;
- QTemporaryFile m_TempFile;
+ const MOBase::IPluginGame *m_GamePlugin;
- const MOBase::IPluginGame* m_GamePlugin;
};
#pragma warning(pop)
diff --git a/src/pluginlistsortproxy.cpp b/src/pluginlistsortproxy.cpp
index e6e8f6df..342b3744 100644
--- a/src/pluginlistsortproxy.cpp
+++ b/src/pluginlistsortproxy.cpp
@@ -19,94 +19,116 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "pluginlistsortproxy.h"
#include "messagedialog.h"
-#include <QApplication>
-#include <QCheckBox>
#include <QMenu>
-#include <QTreeView>
+#include <QCheckBox>
+#include <QApplication>
#include <QWidgetAction>
+#include <QTreeView>
-PluginListSortProxy::PluginListSortProxy(QObject* parent)
- : QSortFilterProxyModel(parent), m_SortIndex(0), m_SortOrder(Qt::AscendingOrder) {
- m_EnabledColumns.set(PluginList::COL_NAME);
- m_EnabledColumns.set(PluginList::COL_PRIORITY);
- m_EnabledColumns.set(PluginList::COL_MODINDEX);
- this->setDynamicSortFilter(true);
+
+PluginListSortProxy::PluginListSortProxy(QObject *parent)
+ : QSortFilterProxyModel(parent),
+ m_SortIndex(0), m_SortOrder(Qt::AscendingOrder)
+{
+ m_EnabledColumns.set(PluginList::COL_NAME);
+ m_EnabledColumns.set(PluginList::COL_PRIORITY);
+ m_EnabledColumns.set(PluginList::COL_MODINDEX);
+ this->setDynamicSortFilter(true);
}
-void PluginListSortProxy::setEnabledColumns(unsigned int columns) {
- emit layoutAboutToBeChanged();
- for (int i = 0; i <= PluginList::COL_LASTCOLUMN; ++i) {
- m_EnabledColumns.set(i, (columns & (1 << i)) != 0);
- }
- emit layoutChanged();
+
+
+
+
+void PluginListSortProxy::setEnabledColumns(unsigned int columns)
+{
+ emit layoutAboutToBeChanged();
+ for (int i = 0; i <= PluginList::COL_LASTCOLUMN; ++i) {
+ m_EnabledColumns.set(i, (columns & (1 << i)) != 0);
+ }
+ emit layoutChanged();
}
-Qt::ItemFlags PluginListSortProxy::flags(const QModelIndex& modelIndex) const {
- /* Qt::ItemFlags flags;
- QModelIndex index = mapToSource(modelIndex);
- if (index.isValid()) {
- flags = sourceModel()->flags(index);
- }
- return flags;*/
- return sourceModel()->flags(mapToSource(modelIndex));
+Qt::ItemFlags PluginListSortProxy::flags(const QModelIndex &modelIndex) const
+{
+/* Qt::ItemFlags flags;
+ QModelIndex index = mapToSource(modelIndex);
+ if (index.isValid()) {
+ flags = sourceModel()->flags(index);
+ }
+ return flags;*/
+
+ return sourceModel()->flags(mapToSource(modelIndex));
}
-void PluginListSortProxy::updateFilter(const QString& filter) {
- m_CurrentFilter = filter;
- invalidateFilter();
+
+void PluginListSortProxy::updateFilter(const QString &filter)
+{
+ m_CurrentFilter = filter;
+ invalidateFilter();
}
-bool PluginListSortProxy::filterAcceptsRow(int row, const QModelIndex&) const {
- return m_CurrentFilter.isEmpty() ||
- sourceModel()->data(sourceModel()->index(row, 0)).toString().contains(m_CurrentFilter, Qt::CaseInsensitive);
+
+bool PluginListSortProxy::filterAcceptsRow(int row, const QModelIndex&) const
+{
+ return m_CurrentFilter.isEmpty() ||
+ sourceModel()->data(sourceModel()->index(row, 0)).toString().contains(m_CurrentFilter, Qt::CaseInsensitive);
}
-bool PluginListSortProxy::lessThan(const QModelIndex& left, const QModelIndex& right) const {
- PluginList* plugins = qobject_cast<PluginList*>(sourceModel());
- switch (left.column()) {
+
+bool PluginListSortProxy::lessThan(const QModelIndex &left,
+ const QModelIndex &right) const
+{
+ PluginList *plugins = qobject_cast<PluginList*>(sourceModel());
+ switch (left.column()) {
case PluginList::COL_NAME: {
- return QString::compare(plugins->getName(left.row()), plugins->getName(right.row()), Qt::CaseInsensitive) < 0;
+ return QString::compare(plugins->getName(left.row()), plugins->getName(right.row()), Qt::CaseInsensitive) < 0;
} break;
case PluginList::COL_FLAGS: {
- QVariantList lhsList = left.data(Qt::UserRole + 1).toList();
- QVariantList rhsList = right.data(Qt::UserRole + 1).toList();
- if (lhsList.size() != rhsList.size()) {
- return lhsList.size() < rhsList.size();
- } else {
- for (int i = 0; i < lhsList.size(); ++i) {
- if (lhsList.at(i) != rhsList.at(i)) {
- return lhsList.at(i) < rhsList.at(i);
- }
- }
- return false;
+ QVariantList lhsList = left.data(Qt::UserRole + 1).toList();
+ QVariantList rhsList = right.data(Qt::UserRole + 1).toList();
+ if (lhsList.size() != rhsList.size()) {
+ return lhsList.size() < rhsList.size();
+ } else {
+ for (int i = 0; i < lhsList.size(); ++i) {
+ if (lhsList.at(i) != rhsList.at(i)) {
+ return lhsList.at(i) < rhsList.at(i);
+ }
}
+ return false;
+ }
} break;
case PluginList::COL_MODINDEX: {
- int leftVal = plugins->isEnabled(left.row()) ? plugins->getPriority(left.row()) : -1;
- int rightVal = plugins->isEnabled(right.row()) ? plugins->getPriority(right.row()) : -1;
- return leftVal < rightVal;
+ int leftVal = plugins->isEnabled(left.row()) ? plugins->getPriority(left.row()) : -1;
+ int rightVal = plugins->isEnabled(right.row()) ? plugins->getPriority(right.row()) : -1;
+ return leftVal < rightVal;
} break;
- default: { return plugins->getPriority(left.row()) < plugins->getPriority(right.row()); } break;
- }
+ default: {
+ return plugins->getPriority(left.row()) < plugins->getPriority(right.row());
+ } break;
+ }
}
-bool PluginListSortProxy::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column,
- const QModelIndex& parent) {
- if ((sortColumn() != PluginList::COL_PRIORITY) && (sortColumn() != PluginList::COL_MODINDEX)) {
- QWidget* wid = qApp->activeWindow()->findChild<QTreeView*>("espList");
- MessageDialog::showMessage(tr("Drag&Drop is only supported when sorting by priority or mod index"), wid);
- return false;
+
+bool PluginListSortProxy::dropMimeData(const QMimeData *data, Qt::DropAction action,
+ int row, int column, const QModelIndex &parent)
+{
+ if ((sortColumn() != PluginList::COL_PRIORITY)
+ && (sortColumn() != PluginList::COL_MODINDEX)) {
+ QWidget *wid = qApp->activeWindow()->findChild<QTreeView*>("espList");
+ MessageDialog::showMessage(tr("Drag&Drop is only supported when sorting by priority or mod index"), wid);
+ return false;
}
if ((row == -1) && (column == -1)) {
- return this->sourceModel()->dropMimeData(data, action, -1, -1, mapToSource(parent));
+ return this->sourceModel()->dropMimeData(data, action, -1, -1, mapToSource(parent));
}
// in the regular model, when dropping between rows, the row-value passed to
// the sourceModel is inconsistent between ascending and descending ordering.
// This should fix that
if (sortOrder() == Qt::DescendingOrder) {
- --row;
+ --row;
}
QModelIndex proxyIndex = index(row, column, parent);
@@ -114,3 +136,4 @@ bool PluginListSortProxy::dropMimeData(const QMimeData* data, Qt::DropAction act
return this->sourceModel()->dropMimeData(data, action, sourceIndex.row(), sourceIndex.column(),
sourceIndex.parent());
}
+
diff --git a/src/pluginlistsortproxy.h b/src/pluginlistsortproxy.h
index b9cdd0fa..89f60e70 100644
--- a/src/pluginlistsortproxy.h
+++ b/src/pluginlistsortproxy.h
@@ -20,39 +20,49 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef PLUGINLISTSORTPROXY_H
#define PLUGINLISTSORTPROXY_H
-#include "pluginlist.h"
-#include <QSortFilterProxyModel>
+
#include <bitset>
+#include <QSortFilterProxyModel>
+#include "pluginlist.h"
+
-class PluginListSortProxy : public QSortFilterProxyModel {
- Q_OBJECT
+class PluginListSortProxy : public QSortFilterProxyModel
+{
+ Q_OBJECT
public:
- enum ESorting { SORT_ASCENDING, SORT_DESCENDING };
+
+ enum ESorting {
+ SORT_ASCENDING,
+ SORT_DESCENDING
+ };
public:
- explicit PluginListSortProxy(QObject* parent = 0);
- void setEnabledColumns(unsigned int columns);
+ explicit PluginListSortProxy(QObject *parent = 0);
+
+ void setEnabledColumns(unsigned int columns);
- virtual Qt::ItemFlags flags(const QModelIndex& modelIndex) const;
+ virtual Qt::ItemFlags flags(const QModelIndex &modelIndex) const;
- virtual bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column,
- const QModelIndex& parent);
+ virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
public slots:
- void updateFilter(const QString& filter);
+ void updateFilter(const QString &filter);
protected:
- virtual bool filterAcceptsRow(int row, const QModelIndex& parent) const;
- virtual bool lessThan(const QModelIndex& left, const QModelIndex& right) const;
+
+ virtual bool filterAcceptsRow(int row, const QModelIndex &parent) const;
+ virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
private:
- int m_SortIndex;
- Qt::SortOrder m_SortOrder;
- std::bitset<PluginList::COL_LASTCOLUMN + 1> m_EnabledColumns;
- QString m_CurrentFilter;
+ int m_SortIndex;
+ Qt::SortOrder m_SortOrder;
+
+ std::bitset<PluginList::COL_LASTCOLUMN + 1> m_EnabledColumns;
+ QString m_CurrentFilter;
+
};
#endif // PLUGINLISTSORTPROXY_H
diff --git a/src/pluginlistview.cpp b/src/pluginlistview.cpp
index 9d38af62..0fcf8183 100644
--- a/src/pluginlistview.cpp
+++ b/src/pluginlistview.cpp
@@ -1,50 +1,58 @@
#include "pluginlistview.h"
+#include <QUrl>
#include <QMimeData>
#include <QProxyStyle>
-#include <QUrl>
+
class PluginListViewStyle : public QProxyStyle {
public:
- PluginListViewStyle(QStyle* style, int indentation);
-
- void drawPrimitive(PrimitiveElement element, const QStyleOption* option, QPainter* painter,
- const QWidget* widget = 0) const;
+ PluginListViewStyle(QStyle *style, int indentation);
+ void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget = 0) const;
private:
- int m_Indentation;
+ int m_Indentation;
};
-PluginListViewStyle::PluginListViewStyle(QStyle* style, int indentation)
- : QProxyStyle(style), m_Indentation(indentation) {}
+PluginListViewStyle::PluginListViewStyle(QStyle *style, int indentation)
+ : QProxyStyle(style), m_Indentation(indentation)
+{
+}
-void PluginListViewStyle::drawPrimitive(PrimitiveElement element, const QStyleOption* option, QPainter* painter,
- const QWidget* widget) const {
- if (element == QStyle::PE_IndicatorItemViewItemDrop && !option->rect.isNull()) {
- QStyleOption opt(*option);
- opt.rect.setLeft(m_Indentation);
- if (widget) {
- opt.rect.setRight(widget->width() - 5); // 5 is an arbitrary value that seems to work ok
- }
- QProxyStyle::drawPrimitive(element, &opt, painter, widget);
- } else {
- QProxyStyle::drawPrimitive(element, option, painter, widget);
+void PluginListViewStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const
+{
+ if (element == QStyle::PE_IndicatorItemViewItemDrop && !option->rect.isNull()) {
+ QStyleOption opt(*option);
+ opt.rect.setLeft(m_Indentation);
+ if (widget) {
+ opt.rect.setRight(widget->width() - 5); // 5 is an arbitrary value that seems to work ok
}
+ QProxyStyle::drawPrimitive(element, &opt, painter, widget);
+ }
+ else {
+ QProxyStyle::drawPrimitive(element, option, painter, widget);
+ }
}
-PluginListView::PluginListView(QWidget* parent)
- : QTreeView(parent), m_Scrollbar(new ViewMarkingScrollBar(this->model(), this)) {
- setVerticalScrollBar(m_Scrollbar);
+PluginListView::PluginListView(QWidget *parent)
+ : QTreeView(parent)
+ , m_Scrollbar(new ViewMarkingScrollBar(this->model(), this))
+{
+ setVerticalScrollBar(m_Scrollbar);
}
-void PluginListView::dragEnterEvent(QDragEnterEvent* event) {
- emit dropModeUpdate(event->mimeData()->hasUrls());
+void PluginListView::dragEnterEvent(QDragEnterEvent *event)
+{
+ emit dropModeUpdate(event->mimeData()->hasUrls());
- QTreeView::dragEnterEvent(event);
+ QTreeView::dragEnterEvent(event);
}
-void PluginListView::setModel(QAbstractItemModel* model) {
- QTreeView::setModel(model);
- setVerticalScrollBar(new ViewMarkingScrollBar(model, this));
+void PluginListView::setModel(QAbstractItemModel *model)
+{
+ QTreeView::setModel(model);
+ setVerticalScrollBar(new ViewMarkingScrollBar(model, this));
}
#pragma once
diff --git a/src/pluginlistview.h b/src/pluginlistview.h
index 49e440ab..bdd4ee61 100644
--- a/src/pluginlistview.h
+++ b/src/pluginlistview.h
@@ -1,22 +1,24 @@
#ifndef PLUGINLISTVIEW_H
#define PLUGINLISTVIEW_H
-#include "viewmarkingscrollbar.h"
-#include <QDragEnterEvent>
#include <QTreeView>
+#include <QDragEnterEvent>
+#include "viewmarkingscrollbar.h"
-class PluginListView : public QTreeView {
- Q_OBJECT
+class PluginListView : public QTreeView
+{
+ Q_OBJECT
public:
- explicit PluginListView(QWidget* parent = 0);
- virtual void dragEnterEvent(QDragEnterEvent* event);
- virtual void setModel(QAbstractItemModel* model);
+ explicit PluginListView(QWidget *parent = 0);
+ virtual void dragEnterEvent(QDragEnterEvent *event);
+ virtual void setModel(QAbstractItemModel *model);
signals:
- void dropModeUpdate(bool dropOnRows);
+ void dropModeUpdate(bool dropOnRows);
-public slots:
+ public slots:
private:
- ViewMarkingScrollBar* m_Scrollbar;
+
+ ViewMarkingScrollBar *m_Scrollbar;
};
#endif // PLUGINLISTVIEW_H
diff --git a/src/previewdialog.cpp b/src/previewdialog.cpp
index 4a50ace3..de33cdd0 100644
--- a/src/previewdialog.cpp
+++ b/src/previewdialog.cpp
@@ -2,40 +2,56 @@
#include "ui_previewdialog.h"
#include <QFileInfo>
-PreviewDialog::PreviewDialog(const QString& fileName, QWidget* parent) : QDialog(parent), ui(new Ui::PreviewDialog) {
- ui->setupUi(this);
- ui->nameLabel->setText(QFileInfo(fileName).fileName());
- ui->nextButton->setEnabled(false);
- ui->previousButton->setEnabled(false);
+PreviewDialog::PreviewDialog(const QString &fileName, QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::PreviewDialog)
+{
+ ui->setupUi(this);
+ ui->nameLabel->setText(QFileInfo(fileName).fileName());
+ ui->nextButton->setEnabled(false);
+ ui->previousButton->setEnabled(false);
}
-PreviewDialog::~PreviewDialog() { delete ui; }
+PreviewDialog::~PreviewDialog()
+{
+ delete ui;
+}
-void PreviewDialog::addVariant(const QString& modName, QWidget* widget) {
- widget->setProperty("modName", modName);
- ui->variantsStack->addWidget(widget);
- if (ui->variantsStack->count() > 1) {
- ui->nextButton->setEnabled(true);
- ui->previousButton->setEnabled(true);
- }
+void PreviewDialog::addVariant(const QString &modName, QWidget *widget)
+{
+ widget->setProperty("modName", modName);
+ ui->variantsStack->addWidget(widget);
+ if (ui->variantsStack->count() > 1) {
+ ui->nextButton->setEnabled(true);
+ ui->previousButton->setEnabled(true);
+ }
}
-int PreviewDialog::numVariants() const { return ui->variantsStack->count(); }
+int PreviewDialog::numVariants() const
+{
+ return ui->variantsStack->count();
+}
-void PreviewDialog::on_variantsStack_currentChanged(int index) {
- ui->modLabel->setText(ui->variantsStack->widget(index)->property("modName").toString());
+void PreviewDialog::on_variantsStack_currentChanged(int index)
+{
+ ui->modLabel->setText(ui->variantsStack->widget(index)->property("modName").toString());
}
-void PreviewDialog::on_closeButton_clicked() { this->accept(); }
+void PreviewDialog::on_closeButton_clicked()
+{
+ this->accept();
+}
-void PreviewDialog::on_previousButton_clicked() {
- int i = ui->variantsStack->currentIndex() - 1;
- if (i < 0) {
- i = ui->variantsStack->count() - 1;
- }
- ui->variantsStack->setCurrentIndex(i);
+void PreviewDialog::on_previousButton_clicked()
+{
+ int i = ui->variantsStack->currentIndex() - 1;
+ if (i < 0) {
+ i = ui->variantsStack->count() - 1;
+ }
+ ui->variantsStack->setCurrentIndex(i);
}
-void PreviewDialog::on_nextButton_clicked() {
- ui->variantsStack->setCurrentIndex((ui->variantsStack->currentIndex() + 1) % ui->variantsStack->count());
+void PreviewDialog::on_nextButton_clicked()
+{
+ ui->variantsStack->setCurrentIndex((ui->variantsStack->currentIndex() + 1) % ui->variantsStack->count());
}
diff --git a/src/previewdialog.h b/src/previewdialog.h
index 5dfb2b96..0011bc50 100644
--- a/src/previewdialog.h
+++ b/src/previewdialog.h
@@ -7,28 +7,30 @@ namespace Ui {
class PreviewDialog;
}
-class PreviewDialog : public QDialog {
- Q_OBJECT
+class PreviewDialog : public QDialog
+{
+ Q_OBJECT
public:
- explicit PreviewDialog(const QString& fileName, QWidget* parent = 0);
- ~PreviewDialog();
+ explicit PreviewDialog(const QString &fileName, QWidget *parent = 0);
+ ~PreviewDialog();
- void addVariant(const QString& modName, QWidget* widget);
- int numVariants() const;
+ void addVariant(const QString &modName, QWidget *widget);
+ int numVariants() const;
private slots:
- void on_variantsStack_currentChanged(int arg1);
+ void on_variantsStack_currentChanged(int arg1);
- void on_closeButton_clicked();
+ void on_closeButton_clicked();
- void on_previousButton_clicked();
+ void on_previousButton_clicked();
- void on_nextButton_clicked();
+ void on_nextButton_clicked();
private:
- Ui::PreviewDialog* ui;
+
+ Ui::PreviewDialog *ui;
};
#endif // PREVIEWDIALOG_H
diff --git a/src/previewgenerator.cpp b/src/previewgenerator.cpp
index 93602152..280d69aa 100644
--- a/src/previewgenerator.cpp
+++ b/src/previewgenerator.cpp
@@ -18,34 +18,38 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "previewgenerator.h"
-#include <QDesktopWidget>
#include <QFileInfo>
-#include <QImageReader>
#include <QLabel>
+#include <QImageReader>
#include <QTextEdit>
+#include <QDesktopWidget>
#include <utility.h>
-PreviewGenerator::PreviewGenerator() {
+PreviewGenerator::PreviewGenerator()
+{
- QDesktopWidget desk;
- m_MaxSize = desk.screenGeometry().size() * 0.8;
+ QDesktopWidget desk;
+ m_MaxSize = desk.screenGeometry().size() * 0.8;
}
-void PreviewGenerator::registerPlugin(MOBase::IPluginPreview* plugin) {
- for (const QString& extension : plugin->supportedExtensions()) {
- m_PreviewPlugins.insert(std::make_pair(extension, plugin));
- }
+void PreviewGenerator::registerPlugin(MOBase::IPluginPreview *plugin)
+{
+ for (const QString &extension : plugin->supportedExtensions()) {
+ m_PreviewPlugins.insert(std::make_pair(extension, plugin));
+ }
}
-bool PreviewGenerator::previewSupported(const QString& fileExtension) const {
- return m_PreviewPlugins.find(fileExtension.toLower()) != m_PreviewPlugins.end();
+bool PreviewGenerator::previewSupported(const QString &fileExtension) const
+{
+ return m_PreviewPlugins.find(fileExtension.toLower()) != m_PreviewPlugins.end();
}
-QWidget* PreviewGenerator::genPreview(const QString& fileName) const {
- auto iter = m_PreviewPlugins.find(QFileInfo(fileName).suffix().toLower());
- if (iter != m_PreviewPlugins.end()) {
- return iter->second->genFilePreview(fileName, m_MaxSize);
- } else {
- return nullptr;
- }
+QWidget *PreviewGenerator::genPreview(const QString &fileName) const
+{
+ auto iter = m_PreviewPlugins.find(QFileInfo(fileName).suffix().toLower());
+ if (iter != m_PreviewPlugins.end()) {
+ return iter->second->genFilePreview(fileName, m_MaxSize);
+ } else {
+ return nullptr;
+ }
}
diff --git a/src/previewgenerator.h b/src/previewgenerator.h
index 38cb2979..e872b06b 100644
--- a/src/previewgenerator.h
+++ b/src/previewgenerator.h
@@ -22,28 +22,32 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QString>
#include <QWidget>
+#include <map>
#include <functional>
#include <ipluginpreview.h>
-#include <map>
-class PreviewGenerator {
+class PreviewGenerator
+{
public:
- PreviewGenerator();
+ PreviewGenerator();
- void registerPlugin(MOBase::IPluginPreview* plugin);
+ void registerPlugin(MOBase::IPluginPreview *plugin);
- bool previewSupported(const QString& fileExtension) const;
+ bool previewSupported(const QString &fileExtension) const;
- QWidget* genPreview(const QString& fileName) const;
+ QWidget *genPreview(const QString &fileName) const;
private:
- QWidget* genImagePreview(const QString& fileName) const;
- QWidget* genTxtPreview(const QString& fileName) const;
+
+ QWidget *genImagePreview(const QString &fileName) const;
+ QWidget *genTxtPreview(const QString &fileName) const;
private:
- std::map<QString, MOBase::IPluginPreview*> m_PreviewPlugins;
- QSize m_MaxSize;
+ std::map<QString, MOBase::IPluginPreview*> m_PreviewPlugins;
+
+ QSize m_MaxSize;
+
};
#endif // PREVIEWGENERATOR_H
diff --git a/src/problemsdialog.cpp b/src/problemsdialog.cpp
index 146672ba..60a0b1df 100644
--- a/src/problemsdialog.cpp
+++ b/src/problemsdialog.cpp
@@ -1,68 +1,82 @@
#include "problemsdialog.h"
#include "ui_problemsdialog.h"
+#include <utility.h>
+#include <iplugindiagnose.h>
#include <QPushButton>
#include <Shellapi.h>
-#include <iplugindiagnose.h>
-#include <utility.h>
+
using namespace MOBase;
-ProblemsDialog::ProblemsDialog(std::vector<MOBase::IPluginDiagnose*> diagnosePlugins, QWidget* parent)
- : QDialog(parent), ui(new Ui::ProblemsDialog), m_DiagnosePlugins(diagnosePlugins) {
- ui->setupUi(this);
- runDiagnosis();
+ProblemsDialog::ProblemsDialog(std::vector<MOBase::IPluginDiagnose *> diagnosePlugins, QWidget *parent)
+ : QDialog(parent), ui(new Ui::ProblemsDialog), m_DiagnosePlugins(diagnosePlugins)
+{
+ ui->setupUi(this);
- connect(ui->problemsWidget, SIGNAL(itemSelectionChanged()), this, SLOT(selectionChanged()));
- connect(ui->descriptionText, SIGNAL(anchorClicked(QUrl)), this, SLOT(urlClicked(QUrl)));
+ runDiagnosis();
+
+ connect(ui->problemsWidget, SIGNAL(itemSelectionChanged()), this, SLOT(selectionChanged()));
+ connect(ui->descriptionText, SIGNAL(anchorClicked(QUrl)), this, SLOT(urlClicked(QUrl)));
}
-ProblemsDialog::~ProblemsDialog() { delete ui; }
-void ProblemsDialog::runDiagnosis() {
- ui->problemsWidget->clear();
- foreach (IPluginDiagnose* diagnose, m_DiagnosePlugins) {
- std::vector<unsigned int> activeProblems = diagnose->activeProblems();
- foreach (unsigned int key, activeProblems) {
- QTreeWidgetItem* newItem = new QTreeWidgetItem();
- newItem->setText(0, diagnose->shortDescription(key));
- newItem->setData(0, Qt::UserRole, diagnose->fullDescription(key));
+ProblemsDialog::~ProblemsDialog()
+{
+ delete ui;
+}
+
+void ProblemsDialog::runDiagnosis()
+{
+ ui->problemsWidget->clear();
+ foreach (IPluginDiagnose *diagnose, m_DiagnosePlugins) {
+ std::vector<unsigned int> activeProblems = diagnose->activeProblems();
+ foreach (unsigned int key, activeProblems) {
+ QTreeWidgetItem *newItem = new QTreeWidgetItem();
+ newItem->setText(0, diagnose->shortDescription(key));
+ newItem->setData(0, Qt::UserRole, diagnose->fullDescription(key));
- ui->problemsWidget->addTopLevelItem(newItem);
+ ui->problemsWidget->addTopLevelItem(newItem);
- if (diagnose->hasGuidedFix(key)) {
- newItem->setText(1, tr("Fix"));
- QPushButton* fixButton = new QPushButton(tr("Fix"));
- fixButton->setProperty("fix", qVariantFromValue(reinterpret_cast<void*>(diagnose)));
- fixButton->setProperty("key", key);
- connect(fixButton, SIGNAL(clicked()), this, SLOT(startFix()));
- ui->problemsWidget->setItemWidget(newItem, 1, fixButton);
- } else {
- newItem->setText(1, tr("No guided fix"));
- }
- }
+ if (diagnose->hasGuidedFix(key)) {
+ newItem->setText(1, tr("Fix"));
+ QPushButton *fixButton = new QPushButton(tr("Fix"));
+ fixButton->setProperty("fix", qVariantFromValue(reinterpret_cast<void*>(diagnose)));
+ fixButton->setProperty("key", key);
+ connect(fixButton, SIGNAL(clicked()), this, SLOT(startFix()));
+ ui->problemsWidget->setItemWidget(newItem, 1, fixButton);
+ } else {
+ newItem->setText(1, tr("No guided fix"));
+ }
}
+ }
}
-bool ProblemsDialog::hasProblems() const { return ui->problemsWidget->topLevelItemCount() != 0; }
+bool ProblemsDialog::hasProblems() const
+{
+ return ui->problemsWidget->topLevelItemCount() != 0;
+}
-void ProblemsDialog::selectionChanged() {
- QString text = ui->problemsWidget->currentItem()->data(0, Qt::UserRole).toString();
- ui->descriptionText->setText(text);
- ui->descriptionText->setLineWrapMode(text.contains('\n') ? QTextEdit::NoWrap : QTextEdit::WidgetWidth);
+void ProblemsDialog::selectionChanged()
+{
+ QString text = ui->problemsWidget->currentItem()->data(0, Qt::UserRole).toString();
+ ui->descriptionText->setText(text);
+ ui->descriptionText->setLineWrapMode(text.contains('\n') ? QTextEdit::NoWrap : QTextEdit::WidgetWidth);
}
-void ProblemsDialog::startFix() {
- QObject* fixButton = QObject::sender();
- if (fixButton == NULL) {
- qWarning("no button");
- return;
- }
- IPluginDiagnose* plugin = reinterpret_cast<IPluginDiagnose*>(fixButton->property("fix").value<void*>());
- plugin->startGuidedFix(fixButton->property("key").toUInt());
- runDiagnosis();
+void ProblemsDialog::startFix()
+{
+ QObject *fixButton = QObject::sender();
+ if (fixButton == NULL) {
+ qWarning("no button");
+ return;
+ }
+ IPluginDiagnose *plugin = reinterpret_cast<IPluginDiagnose*>(fixButton ->property("fix").value<void*>());
+ plugin->startGuidedFix(fixButton ->property("key").toUInt());
+ runDiagnosis();
}
-void ProblemsDialog::urlClicked(const QUrl& url) {
- ::ShellExecuteW(nullptr, L"open", ToWString(url.toString()).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
+void ProblemsDialog::urlClicked(const QUrl &url)
+{
+ ::ShellExecuteW(nullptr, L"open", ToWString(url.toString()).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
}
diff --git a/src/problemsdialog.h b/src/problemsdialog.h
index f009d5c9..24a69cdf 100644
--- a/src/problemsdialog.h
+++ b/src/problemsdialog.h
@@ -1,36 +1,40 @@
#ifndef PROBLEMSDIALOG_H
#define PROBLEMSDIALOG_H
+
#include <QDialog>
#include <QUrl>
#include <iplugindiagnose.h>
+
namespace Ui {
class ProblemsDialog;
}
-class ProblemsDialog : public QDialog {
- Q_OBJECT
+class ProblemsDialog : public QDialog
+{
+ Q_OBJECT
+
public:
- explicit ProblemsDialog(std::vector<MOBase::IPluginDiagnose*> diagnosePlugins, QWidget* parent = 0);
- ~ProblemsDialog();
-
- bool hasProblems() const;
+ explicit ProblemsDialog(std::vector<MOBase::IPluginDiagnose*> diagnosePlugins, QWidget *parent = 0);
+ ~ProblemsDialog();
+ bool hasProblems() const;
private:
- void runDiagnosis();
-private slots:
+ void runDiagnosis();
- void selectionChanged();
- void urlClicked(const QUrl& url);
+private slots:
- void startFix();
+ void selectionChanged();
+ void urlClicked(const QUrl &url);
+ void startFix();
private:
- Ui::ProblemsDialog* ui;
- std::vector<MOBase::IPluginDiagnose*> m_DiagnosePlugins;
+
+ Ui::ProblemsDialog *ui;
+ std::vector<MOBase::IPluginDiagnose *> m_DiagnosePlugins;
};
#endif // PROBLEMSDIALOG_H
diff --git a/src/profile.cpp b/src/profile.cpp
index baef4259..bbb5b814 100644
--- a/src/profile.cpp
+++ b/src/profile.cpp
@@ -19,715 +19,823 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "profile.h"
-#include "appconfig.h"
#include "modinfo.h"
#include "settings.h"
-#include <bsainvalidation.h>
-#include <dataarchives.h>
+#include <utility.h>
#include <error_report.h>
+#include "appconfig.h"
#include <iplugingame.h>
#include <report.h>
#include <safewritefile.h>
-#include <utility.h>
+#include <bsainvalidation.h>
+#include <dataarchives.h>
#include <QApplication>
-#include <QBuffer>
-#include <QDirIterator>
-#include <QFile> // for QFile
-#include <QFlags> // for operator|, QFlags
-#include <QIODevice> // for QIODevice, etc
+#include <QFile> // for QFile
+#include <QFlags> // for operator|, QFlags
+#include <QIODevice> // for QIODevice, etc
#include <QMessageBox>
#include <QScopedArrayPointer>
-#include <QStringList> // for QStringList
-#include <QtDebug> // for qDebug, qWarning, etc
-#include <QtGlobal> // for qPrintable
+#include <QStringList> // for QStringList
+#include <QtDebug> // for qDebug, qWarning, etc
+#include <QtGlobal> // for qPrintable
+#include <QBuffer>
+#include <QDirIterator>
#include <Windows.h>
-#include <assert.h> // for assert
-#include <limits.h> // for UINT_MAX, INT_MAX, etc
-#include <stddef.h> // for size_t
-#include <string.h> // for wcslen
+#include <assert.h> // for assert
+#include <limits.h> // for UINT_MAX, INT_MAX, etc
+#include <stddef.h> // for size_t
+#include <string.h> // for wcslen
-#include <algorithm> // for max, min
-#include <exception> // for exception
+#include <algorithm> // for max, min
+#include <exception> // for exception
#include <functional>
-#include <set> // for set
+#include <set> // for set
+#include <utility> // for find
#include <stdexcept>
-#include <utility> // for find
using namespace MOBase;
using namespace MOShared;
-void Profile::touchFile(QString fileName) {
- QFile modList(m_Directory.filePath(fileName));
- if (!modList.open(QIODevice::ReadWrite)) {
- throw std::runtime_error(
- QObject::tr("failed to create %1").arg(m_Directory.filePath(fileName)).toUtf8().constData());
- }
+void Profile::touchFile(QString fileName)
+{
+ QFile modList(m_Directory.filePath(fileName));
+ if (!modList.open(QIODevice::ReadWrite)) {
+ throw std::runtime_error(QObject::tr("failed to create %1").arg(m_Directory.filePath(fileName)).toUtf8().constData());
+ }
}
-Profile::Profile(const QString& name, IPluginGame const* gamePlugin, bool useDefaultSettings)
- : m_ModListWriter(std::bind(&Profile::doWriteModlist, this)), m_GamePlugin(gamePlugin) {
- QString profilesDir = Settings::instance().getProfileDirectory();
- QDir profileBase(profilesDir);
-
- m_Settings = new QSettings(profileBase.absoluteFilePath("settings.ini"));
+Profile::Profile(const QString &name, IPluginGame const *gamePlugin, bool useDefaultSettings)
+ : m_ModListWriter(std::bind(&Profile::doWriteModlist, this))
+ , m_GamePlugin(gamePlugin)
+{
+ QString profilesDir = Settings::instance().getProfileDirectory();
+ QDir profileBase(profilesDir);
- QString fixedName = name;
- if (!fixDirectoryName(fixedName)) {
- throw MyException(tr("invalid profile name %1").arg(name));
- }
+ m_Settings = new QSettings(profileBase.absoluteFilePath("settings.ini"));
- if (!profileBase.exists() || !profileBase.mkdir(fixedName)) {
- throw MyException(tr("failed to create %1").arg(fixedName).toUtf8().constData());
- }
- QString fullPath = profilesDir + "/" + fixedName;
- m_Directory = QDir(fullPath);
+ QString fixedName = name;
+ if (!fixDirectoryName(fixedName)) {
+ throw MyException(tr("invalid profile name %1").arg(name));
+ }
- try {
- // create files. Needs to happen after m_Directory was set!
- touchFile("modlist.txt");
- touchFile("archives.txt");
+ if (!profileBase.exists() || !profileBase.mkdir(fixedName)) {
+ throw MyException(tr("failed to create %1").arg(fixedName).toUtf8().constData());
+ }
+ QString fullPath = profilesDir + "/" + fixedName;
+ m_Directory = QDir(fullPath);
- IPluginGame::ProfileSettings settings = IPluginGame::CONFIGURATION | IPluginGame::MODS | IPluginGame::SAVEGAMES;
+ try {
+ // create files. Needs to happen after m_Directory was set!
+ touchFile("modlist.txt");
+ touchFile("archives.txt");
- if (useDefaultSettings) {
- settings |= IPluginGame::PREFER_DEFAULTS;
- }
+ IPluginGame::ProfileSettings settings = IPluginGame::CONFIGURATION
+ | IPluginGame::MODS
+ | IPluginGame::SAVEGAMES;
- gamePlugin->initializeProfile(fullPath, settings);
- } catch (...) {
- // clean up in case of an error
- shellDelete(QStringList(profileBase.absoluteFilePath(fixedName)));
- throw;
+ if (useDefaultSettings) {
+ settings |= IPluginGame::PREFER_DEFAULTS;
}
- refreshModStatus();
+
+ gamePlugin->initializeProfile(fullPath, settings);
+ } catch (...) {
+ // clean up in case of an error
+ shellDelete(QStringList(profileBase.absoluteFilePath(fixedName)));
+ throw;
+ }
+ refreshModStatus();
}
-Profile::Profile(const QDir& directory, IPluginGame const* gamePlugin)
- : m_Directory(directory), m_GamePlugin(gamePlugin), m_ModListWriter(std::bind(&Profile::doWriteModlist, this)) {
- assert(gamePlugin != nullptr);
- m_Settings = new QSettings(directory.absoluteFilePath("settings.ini"), QSettings::IniFormat);
+Profile::Profile(const QDir &directory, IPluginGame const *gamePlugin)
+ : m_Directory(directory)
+ , m_GamePlugin(gamePlugin)
+ , m_ModListWriter(std::bind(&Profile::doWriteModlist, this))
+{
+ assert(gamePlugin != nullptr);
- if (!QFile::exists(m_Directory.filePath("modlist.txt"))) {
- qWarning("missing modlist.txt in %s", qPrintable(directory.path()));
- touchFile(m_Directory.filePath("modlist.txt"));
- }
+ m_Settings = new QSettings(directory.absoluteFilePath("settings.ini"),
+ QSettings::IniFormat);
- IPluginGame::ProfileSettings settings = IPluginGame::MODS | IPluginGame::SAVEGAMES;
- gamePlugin->initializeProfile(directory, settings);
+ if (!QFile::exists(m_Directory.filePath("modlist.txt"))) {
+ qWarning("missing modlist.txt in %s", qPrintable(directory.path()));
+ touchFile(m_Directory.filePath("modlist.txt"));
+ }
- refreshModStatus();
+ IPluginGame::ProfileSettings settings = IPluginGame::MODS
+ | IPluginGame::SAVEGAMES;
+ gamePlugin->initializeProfile(directory, settings);
+
+ refreshModStatus();
}
-Profile::Profile(const Profile& reference)
- : m_Directory(reference.m_Directory), m_ModListWriter(std::bind(&Profile::doWriteModlist, this)),
- m_GamePlugin(reference.m_GamePlugin)
+
+Profile::Profile(const Profile &reference)
+ : m_Directory(reference.m_Directory)
+ , m_ModListWriter(std::bind(&Profile::doWriteModlist, this))
+ , m_GamePlugin(reference.m_GamePlugin)
{
- m_Settings = new QSettings(m_Directory.absoluteFilePath("settings.ini"), QSettings::IniFormat);
- refreshModStatus();
+ m_Settings = new QSettings(m_Directory.absoluteFilePath("settings.ini"),
+ QSettings::IniFormat);
+ refreshModStatus();
}
-Profile::~Profile() {
- delete m_Settings;
- m_ModListWriter.writeImmediately(true);
+
+Profile::~Profile()
+{
+ delete m_Settings;
+ m_ModListWriter.writeImmediately(true);
}
-bool Profile::exists() const { return m_Directory.exists(); }
+bool Profile::exists() const
+{
+ return m_Directory.exists();
+}
-void Profile::writeModlist() { m_ModListWriter.write(); }
+void Profile::writeModlist()
+{
+ m_ModListWriter.write();
+}
-void Profile::writeModlistNow(bool onlyIfPending) { m_ModListWriter.writeImmediately(onlyIfPending); }
+void Profile::writeModlistNow(bool onlyIfPending)
+{
+ m_ModListWriter.writeImmediately(onlyIfPending);
+}
-void Profile::cancelModlistWrite() { m_ModListWriter.cancel(); }
+void Profile::cancelModlistWrite()
+{
+ m_ModListWriter.cancel();
+}
-void Profile::doWriteModlist() {
- if (!m_Directory.exists())
- return;
+void Profile::doWriteModlist()
+{
+ if (!m_Directory.exists()) return;
- try {
- QString fileName = getModlistFileName();
- SafeWriteFile file(fileName);
+ try {
+ QString fileName = getModlistFileName();
+ SafeWriteFile file(fileName);
- file->write(QString("# This file was automatically generated by Mod Organizer.\r\n").toUtf8());
- if (m_ModStatus.empty()) {
- return;
- }
+ file->write(QString("# This file was automatically generated by Mod Organizer.\r\n").toUtf8());
+ if (m_ModStatus.empty()) {
+ return;
+ }
- for (int i = static_cast<int>(m_ModStatus.size()) - 1; i >= 0; --i) {
- // the priority order was inverted on load so it has to be inverted again
- unsigned int index = m_ModIndexByPriority[i];
- if (index != UINT_MAX) {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(index);
- std::vector<ModInfo::EFlag> flags = modInfo->getFlags();
- if ((modInfo->getFixedPriority() == INT_MIN)) {
- if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_FOREIGN) != flags.end()) {
- file->write("*");
- } else if (m_ModStatus[index].m_Enabled) {
- file->write("+");
- } else {
- file->write("-");
- }
- file->write(modInfo->name().toUtf8());
- file->write("\r\n");
- }
- }
+ for (int i = static_cast<int>(m_ModStatus.size()) - 1; i >= 0; --i) {
+ // the priority order was inverted on load so it has to be inverted again
+ unsigned int index = m_ModIndexByPriority[i];
+ if (index != UINT_MAX) {
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(index);
+ std::vector<ModInfo::EFlag> flags = modInfo->getFlags();
+ if ((modInfo->getFixedPriority() == INT_MIN)) {
+ if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_FOREIGN) != flags.end()) {
+ file->write("*");
+ } else if (m_ModStatus[index].m_Enabled) {
+ file->write("+");
+ } else {
+ file->write("-");
+ }
+ file->write(modInfo->name().toUtf8());
+ file->write("\r\n");
}
+ }
+ }
- if (file.commitIfDifferent(m_LastModlistHash)) {
- qDebug("%s saved", QDir::toNativeSeparators(fileName).toUtf8().constData());
- }
- } catch (const std::exception& e) {
- reportError(tr("failed to write mod list: %1").arg(e.what()));
- return;
+ if (file.commitIfDifferent(m_LastModlistHash)) {
+ qDebug("%s saved", QDir::toNativeSeparators(fileName).toUtf8().constData());
}
+ } catch (const std::exception &e) {
+ reportError(tr("failed to write mod list: %1").arg(e.what()));
+ return;
+ }
}
-void Profile::createTweakedIniFile() {
- QString tweakedIni = m_Directory.absoluteFilePath("initweaks.ini");
- if (QFile::exists(tweakedIni) && !shellDeleteQuiet(tweakedIni)) {
- reportError(tr("failed to update tweaked ini file, wrong settings may be used: %1")
- .arg(windowsErrorString(::GetLastError())));
- return;
- }
+void Profile::createTweakedIniFile()
+{
+ QString tweakedIni = m_Directory.absoluteFilePath("initweaks.ini");
- for (unsigned int i = 0; i < m_ModStatus.size(); ++i) {
- unsigned int idx = modIndexByPriority(i);
- if ((idx != UINT_MAX) && m_ModStatus[idx].m_Enabled) {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(idx);
- mergeTweaks(modInfo, tweakedIni);
- }
+ if (QFile::exists(tweakedIni) && !shellDeleteQuiet(tweakedIni)) {
+ reportError(tr("failed to update tweaked ini file, wrong settings may be used: %1").arg(windowsErrorString(::GetLastError())));
+ return;
+ }
+
+ for (unsigned int i = 0; i < m_ModStatus.size(); ++i) {
+ unsigned int idx = modIndexByPriority(i);
+ if ((idx != UINT_MAX) && m_ModStatus[idx].m_Enabled) {
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(idx);
+ mergeTweaks(modInfo, tweakedIni);
}
+ }
- mergeTweak(getProfileTweaks(), tweakedIni);
+ mergeTweak(getProfileTweaks(), tweakedIni);
- bool error = false;
- if (!::WritePrivateProfileStringW(L"Archive", L"bInvalidateOlderFiles", L"1", ToWString(tweakedIni).c_str())) {
- error = true;
- }
+ bool error = false;
+ if (!::WritePrivateProfileStringW(L"Archive", L"bInvalidateOlderFiles", L"1", ToWString(tweakedIni).c_str())) {
+ error = true;
+ }
- if (error) {
- reportError(tr("failed to create tweaked ini: %1").arg(getCurrentErrorStringA().c_str()));
- }
- qDebug("%s saved", qPrintable(QDir::toNativeSeparators(tweakedIni)));
+ if (error) {
+ reportError(tr("failed to create tweaked ini: %1").arg(getCurrentErrorStringA().c_str()));
+ }
+ qDebug("%s saved", qPrintable(QDir::toNativeSeparators(tweakedIni)));
}
// static
-void Profile::renameModInAllProfiles(const QString& oldName, const QString& newName) {
- QDir profilesDir(Settings::instance().getProfileDirectory());
- profilesDir.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot);
- QDirIterator profileIter(profilesDir);
- while (profileIter.hasNext()) {
- profileIter.next();
- QFile modList(profileIter.filePath() + "/modlist.txt");
- if (modList.exists())
- renameModInList(modList, oldName, newName);
- else
- qWarning("Profile has no modlist.txt : %s", qPrintable(profileIter.filePath()));
- }
+void Profile::renameModInAllProfiles(const QString& oldName, const QString& newName)
+{
+ QDir profilesDir(Settings::instance().getProfileDirectory());
+ profilesDir.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot);
+ QDirIterator profileIter(profilesDir);
+ while (profileIter.hasNext()) {
+ profileIter.next();
+ QFile modList(profileIter.filePath() + "/modlist.txt");
+ if (modList.exists())
+ renameModInList(modList, oldName, newName);
+ else
+ qWarning("Profile has no modlist.txt : %s", qPrintable(profileIter.filePath()));
+ }
}
// static
-void Profile::renameModInList(QFile& modList, const QString& oldName, const QString& newName) {
- if (!modList.open(QIODevice::ReadOnly)) {
- reportError(tr("failed to open %1").arg(modList.fileName()));
- return;
- }
-
- QBuffer outBuffer;
- outBuffer.open(QIODevice::WriteOnly);
+void Profile::renameModInList(QFile &modList, const QString &oldName, const QString &newName)
+{
+ if (!modList.open(QIODevice::ReadOnly)) {
+ reportError(tr("failed to open %1").arg(modList.fileName()));
+ return;
+ }
- int renamed = 0;
- while (!modList.atEnd()) {
- QByteArray line = modList.readLine();
+ QBuffer outBuffer;
+ outBuffer.open(QIODevice::WriteOnly);
- if (line.length() == 0) {
- // ignore empty lines
- qWarning("mod list contained invalid data: empty line");
- continue;
- }
+ int renamed = 0;
+ while (!modList.atEnd()) {
+ QByteArray line = modList.readLine();
- char spec = line.at(0);
- if (spec == '#') {
- // don't touch comments
- outBuffer.write(line);
- continue;
- }
+ if (line.length() == 0) {
+ // ignore empty lines
+ qWarning("mod list contained invalid data: empty line");
+ continue;
+ }
- QString modName = QString::fromUtf8(line).mid(1).trimmed();
+ char spec = line.at(0);
+ if (spec == '#') {
+ // don't touch comments
+ outBuffer.write(line);
+ continue;
+ }
- if (modName.isEmpty()) {
- // file broken?
- qWarning("mod list contained invalid data: missing mod name");
- continue;
- }
+ QString modName = QString::fromUtf8(line).mid(1).trimmed();
- outBuffer.write(QByteArray(1, spec));
- if (modName == oldName) {
- modName = newName;
- ++renamed;
- }
- outBuffer.write(modName.toUtf8().constData());
- outBuffer.write("\r\n");
+ if (modName.isEmpty()) {
+ // file broken?
+ qWarning("mod list contained invalid data: missing mod name");
+ continue;
}
- modList.close();
- if (renamed) {
- modList.open(QIODevice::WriteOnly);
- modList.write(outBuffer.buffer());
- modList.close();
+ outBuffer.write(QByteArray(1, spec));
+ if (modName == oldName) {
+ modName = newName;
+ ++renamed;
}
+ outBuffer.write(modName.toUtf8().constData());
+ outBuffer.write("\r\n");
+ }
+ modList.close();
- if (renamed)
- qDebug("Renamed %d \"%s\" mod to \"%s\" in %s", renamed, qPrintable(oldName), qPrintable(newName),
- qPrintable(modList.fileName()));
+ if (renamed) {
+ modList.open(QIODevice::WriteOnly);
+ modList.write(outBuffer.buffer());
+ modList.close();
+ }
+
+ if (renamed)
+ qDebug("Renamed %d \"%s\" mod to \"%s\" in %s",
+ renamed, qPrintable(oldName), qPrintable(newName), qPrintable(modList.fileName()));
}
-void Profile::refreshModStatus() {
- writeModlistNow(true); // if there are pending changes write them first
+void Profile::refreshModStatus()
+{
+ writeModlistNow(true); // if there are pending changes write them first
- QFile file(getModlistFileName());
- if (!file.open(QIODevice::ReadOnly)) {
- throw MyException(tr("\"%1\" is missing or inaccessible").arg(getModlistFileName()));
- }
+ QFile file(getModlistFileName());
+ if (!file.open(QIODevice::ReadOnly)) {
+ throw MyException(tr("\"%1\" is missing or inaccessible").arg(getModlistFileName()));
+ }
- bool modStatusModified = false;
- m_ModStatus.clear();
- m_ModStatus.resize(ModInfo::getNumMods());
+ bool modStatusModified = false;
+ m_ModStatus.clear();
+ m_ModStatus.resize(ModInfo::getNumMods());
- std::set<QString> namesRead;
+ std::set<QString> namesRead;
- // load mods from file and update enabled state and priority for them
- int index = 0;
- while (!file.atEnd()) {
- QByteArray line = file.readLine().trimmed();
- bool enabled = true;
- QString modName;
- if (line.length() == 0) {
- // empty line
- continue;
- } else if (line.at(0) == '#') {
- // comment line
- continue;
- } else if (line.at(0) == '-') {
- enabled = false;
- modName = QString::fromUtf8(line.mid(1).trimmed().constData());
- } else if ((line.at(0) == '+') || (line.at(0) == '*')) {
- modName = QString::fromUtf8(line.mid(1).trimmed().constData());
- } else {
- modName = QString::fromUtf8(line.trimmed().constData());
- }
- if (modName.size() > 0) {
- QString lookupName = modName;
- if (namesRead.find(lookupName) != namesRead.end()) {
- continue;
- } else {
- namesRead.insert(lookupName);
- }
- unsigned int modIndex = ModInfo::getIndex(lookupName);
- if (modIndex != UINT_MAX) {
- ModInfo::Ptr info = ModInfo::getByIndex(modIndex);
- if ((modIndex < m_ModStatus.size()) && (info->getFixedPriority() == INT_MIN)) {
- m_ModStatus[modIndex].m_Enabled = enabled;
- if (m_ModStatus[modIndex].m_Priority == -1) {
- if (static_cast<size_t>(index) >= m_ModStatus.size()) {
- throw MyException(tr("invalid index %1").arg(index));
- }
- m_ModStatus[modIndex].m_Priority = index++;
- }
- } else {
- qWarning("no mod state for \"%s\" (profile \"%s\")", qPrintable(modName),
- m_Directory.path().toUtf8().constData());
- // need to rewrite the modlist to fix this
- modStatusModified = true;
- }
- } else {
- qDebug("mod \"%s\" (profile \"%s\") not found", qPrintable(modName),
- m_Directory.path().toUtf8().constData());
- // need to rewrite the modlist to fix this
- modStatusModified = true;
+ // load mods from file and update enabled state and priority for them
+ int index = 0;
+ while (!file.atEnd()) {
+ QByteArray line = file.readLine().trimmed();
+ bool enabled = true;
+ QString modName;
+ if (line.length() == 0) {
+ // empty line
+ continue;
+ } else if (line.at(0) == '#') {
+ // comment line
+ continue;
+ } else if (line.at(0) == '-') {
+ enabled = false;
+ modName = QString::fromUtf8(line.mid(1).trimmed().constData());
+ } else if ((line.at(0) == '+')
+ || (line.at(0) == '*')) {
+ modName = QString::fromUtf8(line.mid(1).trimmed().constData());
+ } else {
+ modName = QString::fromUtf8(line.trimmed().constData());
+ }
+ if (modName.size() > 0) {
+ QString lookupName = modName;
+ if (namesRead.find(lookupName) != namesRead.end()) {
+ continue;
+ } else {
+ namesRead.insert(lookupName);
+ }
+ unsigned int modIndex = ModInfo::getIndex(lookupName);
+ if (modIndex != UINT_MAX) {
+ ModInfo::Ptr info = ModInfo::getByIndex(modIndex);
+ if ((modIndex < m_ModStatus.size())
+ && (info->getFixedPriority() == INT_MIN)) {
+ m_ModStatus[modIndex].m_Enabled = enabled;
+ if (m_ModStatus[modIndex].m_Priority == -1) {
+ if (static_cast<size_t>(index) >= m_ModStatus.size()) {
+ throw MyException(tr("invalid index %1").arg(index));
}
+ m_ModStatus[modIndex].m_Priority = index++;
+ }
+ } else {
+ qWarning("no mod state for \"%s\" (profile \"%s\")",
+ qPrintable(modName), m_Directory.path().toUtf8().constData());
+ // need to rewrite the modlist to fix this
+ modStatusModified = true;
}
+ } else {
+ qDebug("mod \"%s\" (profile \"%s\") not found",
+ qPrintable(modName), m_Directory.path().toUtf8().constData());
+ // need to rewrite the modlist to fix this
+ modStatusModified = true;
+ }
}
+ }
- int numKnownMods = index;
-
- int topInsert = 0;
+ int numKnownMods = index;
- // invert priority order to match that of the pluginlist. Also
- // give priorities to mods not referenced in the profile
- for (size_t i = 0; i < m_ModStatus.size(); ++i) {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(static_cast<int>(i));
- if (modInfo->alwaysEnabled()) {
- m_ModStatus[i].m_Enabled = true;
- }
+ int topInsert = 0;
- if (modInfo->getFixedPriority() == INT_MAX) {
- continue;
- }
+ // invert priority order to match that of the pluginlist. Also
+ // give priorities to mods not referenced in the profile
+ for (size_t i = 0; i < m_ModStatus.size(); ++i) {
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(static_cast<int>(i));
+ if (modInfo->alwaysEnabled()) {
+ m_ModStatus[i].m_Enabled = true;
+ }
- if (m_ModStatus[i].m_Priority != -1) {
- m_ModStatus[i].m_Priority = numKnownMods - m_ModStatus[i].m_Priority - 1;
- } else {
- if (static_cast<size_t>(index) >= m_ModStatus.size()) {
- throw MyException(tr("invalid index %1").arg(index));
- }
- if (modInfo->hasFlag(ModInfo::FLAG_FOREIGN)) {
- m_ModStatus[i].m_Priority = --topInsert;
- } else {
- m_ModStatus[i].m_Priority = index++;
- }
- // also, mark the mod-list as changed
- modStatusModified = true;
- }
+ if (modInfo->getFixedPriority() == INT_MAX) {
+ continue;
}
- // to support insertion of new mods at the top we may now have mods with negative priority. shift them all up
- // to align priority with 0
- if (topInsert < 0) {
- int offset = topInsert * -1;
- for (size_t i = 0; i < m_ModStatus.size(); ++i) {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(static_cast<unsigned int>(i));
- if (modInfo->getFixedPriority() == INT_MAX) {
- continue;
- }
- m_ModStatus[i].m_Priority += offset;
- }
+ if (m_ModStatus[i].m_Priority != -1) {
+ m_ModStatus[i].m_Priority = numKnownMods - m_ModStatus[i].m_Priority - 1;
+ } else {
+ if (static_cast<size_t>(index) >= m_ModStatus.size()) {
+ throw MyException(tr("invalid index %1").arg(index));
+ }
+ if (modInfo->hasFlag(ModInfo::FLAG_FOREIGN)) {
+ m_ModStatus[i].m_Priority = --topInsert;
+ } else {
+ m_ModStatus[i].m_Priority = index++;
+ }
+ // also, mark the mod-list as changed
+ modStatusModified = true;
}
+ }
+ // to support insertion of new mods at the top we may now have mods with negative priority. shift them all up
+ // to align priority with 0
+ if (topInsert < 0) {
+ int offset = topInsert * -1;
+ for (size_t i = 0; i < m_ModStatus.size(); ++i) {
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(static_cast<unsigned int>(i));
+ if (modInfo->getFixedPriority() == INT_MAX) {
+ continue;
+ }
- file.close();
- updateIndices();
- if (modStatusModified) {
- m_ModListWriter.write();
+ m_ModStatus[i].m_Priority += offset;
}
+ }
+
+ file.close();
+ updateIndices();
+ if (modStatusModified) {
+ m_ModListWriter.write();
+ }
}
-void Profile::dumpModStatus() const {
- for (unsigned int i = 0; i < m_ModStatus.size(); ++i) {
- ModInfo::Ptr info = ModInfo::getByIndex(i);
- qWarning("%d: %s - %d (%s)", i, info->name().toUtf8().constData(), m_ModStatus[i].m_Priority,
- m_ModStatus[i].m_Enabled ? "enabled" : "disabled");
- }
+
+void Profile::dumpModStatus() const
+{
+ for (unsigned int i = 0; i < m_ModStatus.size(); ++i) {
+ ModInfo::Ptr info = ModInfo::getByIndex(i);
+ qWarning("%d: %s - %d (%s)", i, info->name().toUtf8().constData(), m_ModStatus[i].m_Priority,
+ m_ModStatus[i].m_Enabled ? "enabled" : "disabled");
+ }
}
-void Profile::updateIndices() {
- m_NumRegularMods = 0;
- m_ModIndexByPriority.clear();
- m_ModIndexByPriority.resize(m_ModStatus.size(), UINT_MAX);
- for (unsigned int i = 0; i < m_ModStatus.size(); ++i) {
- int priority = m_ModStatus[i].m_Priority;
- if (priority < 0) {
- // don't assign this to mapping at all, it's probably the overwrite mod
- continue;
- } else if (priority >= static_cast<int>(m_ModIndexByPriority.size())) {
- qCritical("invalid priority %d for mod", priority);
- continue;
- } else {
- ++m_NumRegularMods;
- m_ModIndexByPriority.at(priority) = i;
- }
+
+void Profile::updateIndices()
+{
+ m_NumRegularMods = 0;
+ m_ModIndexByPriority.clear();
+ m_ModIndexByPriority.resize(m_ModStatus.size(), UINT_MAX);
+ for (unsigned int i = 0; i < m_ModStatus.size(); ++i) {
+ int priority = m_ModStatus[i].m_Priority;
+ if (priority < 0) {
+ // don't assign this to mapping at all, it's probably the overwrite mod
+ continue;
+ } else if (priority >= static_cast<int>(m_ModIndexByPriority.size())) {
+ qCritical("invalid priority %d for mod", priority);
+ continue;
+ } else {
+ ++m_NumRegularMods;
+ m_ModIndexByPriority.at(priority) = i;
}
+ }
}
-std::vector<std::tuple<QString, QString, int>> Profile::getActiveMods() {
- std::vector<std::tuple<QString, QString, int>> result;
- for (std::vector<unsigned int>::const_iterator iter = m_ModIndexByPriority.begin();
- iter != m_ModIndexByPriority.end(); ++iter) {
- if ((*iter != UINT_MAX) && m_ModStatus[*iter].m_Enabled) {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(*iter);
- result.push_back(
- std::make_tuple(modInfo->internalName(), modInfo->absolutePath(), m_ModStatus[*iter].m_Priority));
- }
+
+std::vector<std::tuple<QString, QString, int> > Profile::getActiveMods()
+{
+ std::vector<std::tuple<QString, QString, int> > result;
+ for (std::vector<unsigned int>::const_iterator iter = m_ModIndexByPriority.begin();
+ iter != m_ModIndexByPriority.end(); ++iter) {
+ if ((*iter != UINT_MAX) && m_ModStatus[*iter].m_Enabled) {
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(*iter);
+ result.push_back(std::make_tuple(modInfo->internalName(), modInfo->absolutePath(), m_ModStatus[*iter].m_Priority));
}
+ }
- unsigned int overwriteIndex = ModInfo::findMod([](ModInfo::Ptr mod) -> bool {
- std::vector<ModInfo::EFlag> flags = mod->getFlags();
- return std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end();
- });
+ unsigned int overwriteIndex = ModInfo::findMod([](ModInfo::Ptr mod) -> bool {
+ std::vector<ModInfo::EFlag> flags = mod->getFlags();
+ return std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end(); });
- if (overwriteIndex != UINT_MAX) {
- ModInfo::Ptr overwriteInfo = ModInfo::getByIndex(overwriteIndex);
- result.push_back(std::make_tuple(overwriteInfo->name(), overwriteInfo->absolutePath(), UINT_MAX));
- } else {
- reportError(tr("Overwrite directory couldn't be parsed"));
- }
- return result;
+ if (overwriteIndex != UINT_MAX) {
+ ModInfo::Ptr overwriteInfo = ModInfo::getByIndex(overwriteIndex);
+ result.push_back(std::make_tuple(overwriteInfo->name(), overwriteInfo->absolutePath(), UINT_MAX));
+ } else {
+ reportError(tr("Overwrite directory couldn't be parsed"));
+ }
+ return result;
}
-unsigned int Profile::modIndexByPriority(unsigned int priority) const {
- if (priority >= m_ModStatus.size()) {
- throw MyException(tr("invalid priority %1").arg(priority));
- }
- return m_ModIndexByPriority[priority];
+unsigned int Profile::modIndexByPriority(unsigned int priority) const
+{
+ if (priority >= m_ModStatus.size()) {
+ throw MyException(tr("invalid priority %1").arg(priority));
+ }
+
+ return m_ModIndexByPriority[priority];
}
-void Profile::setModEnabled(unsigned int index, bool enabled) {
- if (index >= m_ModStatus.size()) {
- throw MyException(tr("invalid index %1").arg(index));
- }
- ModInfo::Ptr modInfo = ModInfo::getByIndex(index);
- // we could quit in the following case, this shouldn't be a change anyway,
- // but at least this allows the situation to be fixed in case of an error
- if (modInfo->alwaysEnabled()) {
- enabled = true;
- }
+void Profile::setModEnabled(unsigned int index, bool enabled)
+{
+ if (index >= m_ModStatus.size()) {
+ throw MyException(tr("invalid index %1").arg(index));
+ }
- if (enabled != m_ModStatus[index].m_Enabled) {
- m_ModStatus[index].m_Enabled = enabled;
- emit modStatusChanged(index);
- }
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(index);
+ // we could quit in the following case, this shouldn't be a change anyway,
+ // but at least this allows the situation to be fixed in case of an error
+ if (modInfo->alwaysEnabled()) {
+ enabled = true;
+ }
+
+ if (enabled != m_ModStatus[index].m_Enabled) {
+ m_ModStatus[index].m_Enabled = enabled;
+ emit modStatusChanged(index);
+ }
}
-bool Profile::modEnabled(unsigned int index) const {
- if (index >= m_ModStatus.size()) {
- throw MyException(tr("invalid index %1").arg(index));
- }
+bool Profile::modEnabled(unsigned int index) const
+{
+ if (index >= m_ModStatus.size()) {
+ throw MyException(tr("invalid index %1").arg(index));
+ }
- return m_ModStatus[index].m_Enabled;
+ return m_ModStatus[index].m_Enabled;
}
-int Profile::getModPriority(unsigned int index) const {
- if (index >= m_ModStatus.size()) {
- throw MyException(tr("invalid index %1").arg(index));
- }
- return m_ModStatus[index].m_Priority;
+int Profile::getModPriority(unsigned int index) const
+{
+ if (index >= m_ModStatus.size()) {
+ throw MyException(tr("invalid index %1").arg(index));
+ }
+
+ return m_ModStatus[index].m_Priority;
}
-void Profile::setModPriority(unsigned int index, int& newPriority) {
- if (m_ModStatus.at(index).m_Overwrite) {
- // can't change priority of the overwrite
- return;
- }
- int newPriorityTemp = (std::max)(0, (std::min<int>)(static_cast<int>(m_ModStatus.size()) - 1, newPriority));
+void Profile::setModPriority(unsigned int index, int &newPriority)
+{
+ if (m_ModStatus.at(index).m_Overwrite) {
+ // can't change priority of the overwrite
+ return;
+ }
- // don't try to place below overwrite
- while ((m_ModIndexByPriority.at(newPriorityTemp) >= m_ModStatus.size()) ||
- m_ModStatus.at(m_ModIndexByPriority.at(newPriorityTemp)).m_Overwrite) {
- --newPriorityTemp;
- }
+ int newPriorityTemp =
+ (std::max)(0, (std::min<int>)(static_cast<int>(m_ModStatus.size()) - 1,
+ newPriority));
- int oldPriority = m_ModStatus.at(index).m_Priority;
- if (newPriorityTemp > oldPriority) {
- // priority is higher than the old, so the gap we left is in lower priorities
- for (int i = oldPriority + 1; i <= newPriorityTemp; ++i) {
- --m_ModStatus.at(m_ModIndexByPriority.at(i)).m_Priority;
- }
- } else {
- for (int i = newPriorityTemp; i < oldPriority; ++i) {
- ++m_ModStatus.at(m_ModIndexByPriority.at(i)).m_Priority;
- }
- ++newPriority;
+ // don't try to place below overwrite
+ while ((m_ModIndexByPriority.at(newPriorityTemp) >= m_ModStatus.size()) ||
+ m_ModStatus.at(m_ModIndexByPriority.at(newPriorityTemp)).m_Overwrite) {
+ --newPriorityTemp;
+ }
+
+ int oldPriority = m_ModStatus.at(index).m_Priority;
+ if (newPriorityTemp > oldPriority) {
+ // priority is higher than the old, so the gap we left is in lower priorities
+ for (int i = oldPriority + 1; i <= newPriorityTemp; ++i) {
+ --m_ModStatus.at(m_ModIndexByPriority.at(i)).m_Priority;
}
+ } else {
+ for (int i = newPriorityTemp; i < oldPriority; ++i) {
+ ++m_ModStatus.at(m_ModIndexByPriority.at(i)).m_Priority;
+ }
+ ++newPriority;
+ }
- m_ModStatus.at(index).m_Priority = newPriorityTemp;
+ m_ModStatus.at(index).m_Priority = newPriorityTemp;
- updateIndices();
- m_ModListWriter.write();
+ updateIndices();
+ m_ModListWriter.write();
}
-Profile* Profile::createPtrFrom(const QString& name, const Profile& reference, MOBase::IPluginGame const* gamePlugin) {
- QString profileDirectory = Settings::instance().getProfileDirectory() + "/" + name;
- reference.copyFilesTo(profileDirectory);
- return new Profile(QDir(profileDirectory), gamePlugin);
+Profile *Profile::createPtrFrom(const QString &name, const Profile &reference, MOBase::IPluginGame const *gamePlugin)
+{
+ QString profileDirectory = Settings::instance().getProfileDirectory() + "/" + name;
+ reference.copyFilesTo(profileDirectory);
+ return new Profile(QDir(profileDirectory), gamePlugin);
}
-void Profile::copyFilesTo(QString& target) const { copyDir(m_Directory.absolutePath(), target, false); }
+void Profile::copyFilesTo(QString &target) const
+{
+ copyDir(m_Directory.absolutePath(), target, false);
+}
-std::vector<std::wstring> Profile::splitDZString(const wchar_t* buffer) const {
- std::vector<std::wstring> result;
- const wchar_t* pos = buffer;
- size_t length = wcslen(pos);
- while (length != 0U) {
- result.push_back(pos);
- pos += length + 1;
- length = wcslen(pos);
- }
- return result;
+std::vector<std::wstring> Profile::splitDZString(const wchar_t *buffer) const
+{
+ std::vector<std::wstring> result;
+ const wchar_t *pos = buffer;
+ size_t length = wcslen(pos);
+ while (length != 0U) {
+ result.push_back(pos);
+ pos += length + 1;
+ length = wcslen(pos);
+ }
+ return result;
}
-void Profile::mergeTweak(const QString& tweakName, const QString& tweakedIni) const {
- static const int bufferSize = 32768;
+void Profile::mergeTweak(const QString &tweakName, const QString &tweakedIni) const
+{
+ static const int bufferSize = 32768;
- std::wstring tweakNameW = ToWString(tweakName);
- std::wstring tweakedIniW = ToWString(tweakedIni);
- QScopedArrayPointer<wchar_t> buffer(new wchar_t[bufferSize]);
+ std::wstring tweakNameW = ToWString(tweakName);
+ std::wstring tweakedIniW = ToWString(tweakedIni);
+ QScopedArrayPointer<wchar_t> buffer(new wchar_t[bufferSize]);
- // retrieve a list of sections
- DWORD size = ::GetPrivateProfileSectionNamesW(buffer.data(), bufferSize, tweakNameW.c_str());
+ // retrieve a list of sections
+ DWORD size = ::GetPrivateProfileSectionNamesW(
+ buffer.data(), bufferSize, tweakNameW.c_str());
- if (size == bufferSize - 2) {
- // unfortunately there is no good way to find the required size
- // of the buffer
- throw MyException(QString("Buffer too small. Please report this as a bug. "
- "For now you might want to split up %1")
- .arg(tweakName));
- }
+ if (size == bufferSize - 2) {
+ // unfortunately there is no good way to find the required size
+ // of the buffer
+ throw MyException(QString("Buffer too small. Please report this as a bug. "
+ "For now you might want to split up %1").arg(tweakName));
+ }
- std::vector<std::wstring> sections = splitDZString(buffer.data());
+ std::vector<std::wstring> sections = splitDZString(buffer.data());
- // now iterate over all sections and retrieve a list of keys in each
- for (std::vector<std::wstring>::iterator iter = sections.begin(); iter != sections.end(); ++iter) {
- // retrieve the names of all keys
- size =
- ::GetPrivateProfileStringW(iter->c_str(), nullptr, nullptr, buffer.data(), bufferSize, tweakNameW.c_str());
- if (size == bufferSize - 2) {
- throw MyException(QString("Buffer too small. Please report this as a bug. "
- "For now you might want to split up %1")
- .arg(tweakName));
- }
+ // now iterate over all sections and retrieve a list of keys in each
+ for (std::vector<std::wstring>::iterator iter = sections.begin();
+ iter != sections.end(); ++iter) {
+ // retrieve the names of all keys
+ size = ::GetPrivateProfileStringW(iter->c_str(), nullptr, nullptr, buffer.data(),
+ bufferSize, tweakNameW.c_str());
+ if (size == bufferSize - 2) {
+ throw MyException(QString("Buffer too small. Please report this as a bug. "
+ "For now you might want to split up %1").arg(tweakName));
+ }
- std::vector<std::wstring> keys = splitDZString(buffer.data());
+ std::vector<std::wstring> keys = splitDZString(buffer.data());
- for (std::vector<std::wstring>::iterator keyIter = keys.begin(); keyIter != keys.end(); ++keyIter) {
- // TODO this treats everything as strings but how could I differentiate the type?
- ::GetPrivateProfileStringW(iter->c_str(), keyIter->c_str(), nullptr, buffer.data(), bufferSize,
- ToWString(tweakName).c_str());
- ::WritePrivateProfileStringW(iter->c_str(), keyIter->c_str(), buffer.data(), tweakedIniW.c_str());
- }
+ for (std::vector<std::wstring>::iterator keyIter = keys.begin();
+ keyIter != keys.end(); ++keyIter) {
+ //TODO this treats everything as strings but how could I differentiate the type?
+ ::GetPrivateProfileStringW(iter->c_str(), keyIter->c_str(),
+ nullptr, buffer.data(), bufferSize, ToWString(tweakName).c_str());
+ ::WritePrivateProfileStringW(iter->c_str(), keyIter->c_str(),
+ buffer.data(), tweakedIniW.c_str());
}
+ }
}
-void Profile::mergeTweaks(ModInfo::Ptr modInfo, const QString& tweakedIni) const {
- std::vector<QString> iniTweaks = modInfo->getIniTweaks();
- for (std::vector<QString>::iterator iter = iniTweaks.begin(); iter != iniTweaks.end(); ++iter) {
- mergeTweak(*iter, tweakedIni);
- }
+void Profile::mergeTweaks(ModInfo::Ptr modInfo, const QString &tweakedIni) const
+{
+ std::vector<QString> iniTweaks = modInfo->getIniTweaks();
+ for (std::vector<QString>::iterator iter = iniTweaks.begin();
+ iter != iniTweaks.end(); ++iter) {
+ mergeTweak(*iter, tweakedIni);
+ }
}
-bool Profile::invalidationActive(bool* supported) const {
- BSAInvalidation* invalidation = m_GamePlugin->feature<BSAInvalidation>();
- DataArchives* dataArchives = m_GamePlugin->feature<DataArchives>();
- if ((invalidation != nullptr) && (dataArchives != nullptr)) {
- if (supported != nullptr) {
- *supported = true;
- }
+bool Profile::invalidationActive(bool *supported) const
+{
+ BSAInvalidation *invalidation = m_GamePlugin->feature<BSAInvalidation>();
+ DataArchives *dataArchives = m_GamePlugin->feature<DataArchives>();
- for (const QString& archive : dataArchives->archives(this)) {
- if (invalidation->isInvalidationBSA(archive)) {
- return true;
- }
- }
- return false;
- } else {
- if (supported != nullptr) {
- *supported = false;
- }
+ if ((invalidation != nullptr) && (dataArchives != nullptr)) {
+ if (supported != nullptr) {
+ *supported = true;
+ }
+
+ for (const QString &archive : dataArchives->archives(this)) {
+ if (invalidation->isInvalidationBSA(archive)) {
+ return true;
+ }
}
return false;
+ } else {
+ if (supported != nullptr) {
+ *supported = false;
+ }
+ }
+ return false;
}
-void Profile::deactivateInvalidation() {
- BSAInvalidation* invalidation = m_GamePlugin->feature<BSAInvalidation>();
- if (invalidation != nullptr) {
- invalidation->deactivate(this);
- }
+void Profile::deactivateInvalidation()
+{
+ BSAInvalidation *invalidation = m_GamePlugin->feature<BSAInvalidation>();
+
+ if (invalidation != nullptr) {
+ invalidation->deactivate(this);
+ }
}
-void Profile::activateInvalidation() {
- BSAInvalidation* invalidation = m_GamePlugin->feature<BSAInvalidation>();
- if (invalidation != nullptr) {
- invalidation->activate(this);
- }
+void Profile::activateInvalidation()
+{
+ BSAInvalidation *invalidation = m_GamePlugin->feature<BSAInvalidation>();
+
+ if (invalidation != nullptr) {
+ invalidation->activate(this);
+ }
}
-bool Profile::localSavesEnabled() const { return m_Directory.exists("saves"); }
-bool Profile::enableLocalSaves(bool enable) {
- if (enable) {
- if (m_Directory.exists("_saves")) {
- m_Directory.rename("_saves", "saves");
- } else {
- m_Directory.mkdir("saves");
- }
+bool Profile::localSavesEnabled() const
+{
+ return m_Directory.exists("saves");
+}
+
+
+bool Profile::enableLocalSaves(bool enable)
+{
+ if (enable) {
+ if (m_Directory.exists("_saves")) {
+ m_Directory.rename("_saves", "saves");
} else {
- QMessageBox::StandardButton res =
- QMessageBox::question(QApplication::activeModalWidget(), tr("Delete savegames?"),
- tr("Do you want to delete local savegames? (If you select \"No\", the "
- "save games will show up again if you re-enable local savegames)"),
- QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, QMessageBox::Cancel);
- if (res == QMessageBox::Yes) {
- shellDelete(QStringList(m_Directory.absoluteFilePath("saves")));
- } else if (res == QMessageBox::No) {
- m_Directory.rename("saves", "_saves");
- } else {
- return false;
- }
+ m_Directory.mkdir("saves");
+ }
+ } else {
+ QMessageBox::StandardButton res = QMessageBox::question(
+ QApplication::activeModalWidget(), tr("Delete savegames?"),
+ tr("Do you want to delete local savegames? (If you select \"No\", the "
+ "save games will show up again if you re-enable local savegames)"),
+ QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
+ QMessageBox::Cancel);
+ if (res == QMessageBox::Yes) {
+ shellDelete(QStringList(m_Directory.absoluteFilePath("saves")));
+ } else if (res == QMessageBox::No) {
+ m_Directory.rename("saves", "_saves");
+ } else {
+ return false;
}
+ }
- // default: assume success
- return true;
+ // default: assume success
+ return true;
}
-bool Profile::localSettingsEnabled() const { return m_Directory.exists(getIniFileName()); }
+bool Profile::localSettingsEnabled() const
+{
+ return m_Directory.exists(getIniFileName());
+}
-bool Profile::enableLocalSettings(bool enable) {
- // TODO: this currently assumes game settings are stored in an ini file.
- // This shall become very interesting when a game stores its settings in the
- // registry
- QString backupFile = getIniFileName() + "_";
- if (enable) {
- if (m_Directory.exists(backupFile)) {
- shellRename(backupFile, getIniFileName());
- } else {
- IPluginGame* game = qApp->property("managed_game").value<IPluginGame*>();
- game->initializeProfile(m_Directory, IPluginGame::CONFIGURATION);
- }
+bool Profile::enableLocalSettings(bool enable)
+{
+ // TODO: this currently assumes game settings are stored in an ini file.
+ // This shall become very interesting when a game stores its settings in the
+ // registry
+ QString backupFile = getIniFileName() + "_";
+ if (enable) {
+ if (m_Directory.exists(backupFile)) {
+ shellRename(backupFile, getIniFileName());
} else {
- shellRename(getIniFileName(), backupFile);
+ IPluginGame *game = qApp->property("managed_game").value<IPluginGame *>();
+ game->initializeProfile(m_Directory, IPluginGame::CONFIGURATION);
}
+ } else {
+ shellRename(getIniFileName(), backupFile);
+ }
+
+ return true;
+}
- return true;
+QString Profile::getModlistFileName() const
+{
+ return QDir::cleanPath(m_Directory.absoluteFilePath("modlist.txt"));
}
-QString Profile::getModlistFileName() const { return QDir::cleanPath(m_Directory.absoluteFilePath("modlist.txt")); }
+QString Profile::getPluginsFileName() const
+{
+ return QDir::cleanPath(m_Directory.absoluteFilePath("plugins.txt"));
+}
-QString Profile::getPluginsFileName() const { return QDir::cleanPath(m_Directory.absoluteFilePath("plugins.txt")); }
+QString Profile::getLoadOrderFileName() const
+{
+ return QDir::cleanPath(m_Directory.absoluteFilePath("loadorder.txt"));
+}
-QString Profile::getLoadOrderFileName() const { return QDir::cleanPath(m_Directory.absoluteFilePath("loadorder.txt")); }
+QString Profile::getLockedOrderFileName() const
+{
+ return QDir::cleanPath(m_Directory.absoluteFilePath("lockedorder.txt"));
+}
-QString Profile::getLockedOrderFileName() const {
- return QDir::cleanPath(m_Directory.absoluteFilePath("lockedorder.txt"));
+QString Profile::getArchivesFileName() const
+{
+ return QDir::cleanPath(m_Directory.absoluteFilePath("archives.txt"));
}
-QString Profile::getArchivesFileName() const { return QDir::cleanPath(m_Directory.absoluteFilePath("archives.txt")); }
+QString Profile::getDeleterFileName() const
+{
+ return QDir::cleanPath(m_Directory.absoluteFilePath("hide_plugins.txt"));
+}
-QString Profile::getDeleterFileName() const {
- return QDir::cleanPath(m_Directory.absoluteFilePath("hide_plugins.txt"));
+QString Profile::getIniFileName() const
+{
+ return m_Directory.absoluteFilePath(m_GamePlugin->iniFiles()[0]);
}
-QString Profile::getIniFileName() const { return m_Directory.absoluteFilePath(m_GamePlugin->iniFiles()[0]); }
+QString Profile::getProfileTweaks() const
+{
+ return QDir::cleanPath(m_Directory.absoluteFilePath(ToQString(AppConfig::profileTweakIni())));
+}
-QString Profile::getProfileTweaks() const {
- return QDir::cleanPath(m_Directory.absoluteFilePath(ToQString(AppConfig::profileTweakIni())));
+QString Profile::absolutePath() const
+{
+ return QDir::cleanPath(m_Directory.absolutePath());
}
-QString Profile::absolutePath() const { return QDir::cleanPath(m_Directory.absolutePath()); }
+QString Profile::savePath() const
+{
+ return QDir::cleanPath(m_Directory.absoluteFilePath("saves"));
-QString Profile::savePath() const { return QDir::cleanPath(m_Directory.absoluteFilePath("saves")); }
+}
-void Profile::rename(const QString& newName) {
- QDir profileDir(Settings::instance().getProfileDirectory());
- profileDir.rename(name(), newName);
- m_Directory = profileDir.absoluteFilePath(newName);
+void Profile::rename(const QString &newName)
+{
+ QDir profileDir(Settings::instance().getProfileDirectory());
+ profileDir.rename(name(), newName);
+ m_Directory = profileDir.absoluteFilePath(newName);
}
-QVariant Profile::setting(const QString& section, const QString& name, const QVariant& fallback) {
- return m_Settings->value(section + "/" + name, fallback);
+QVariant Profile::setting(const QString &section, const QString &name,
+ const QVariant &fallback)
+{
+ return m_Settings->value(section + "/" + name, fallback);
}
-void Profile::storeSetting(const QString& section, const QString& name, const QVariant& value) {
- m_Settings->setValue(section + "/" + name, value);
+void Profile::storeSetting(const QString &section, const QString &name,
+ const QVariant &value)
+{
+ m_Settings->setValue(section + "/" + name, value);
}
-void Profile::removeSetting(const QString& section, const QString& name) { m_Settings->remove(section + "/" + name); } \ No newline at end of file
+void Profile::removeSetting(const QString &section, const QString &name)
+{
+ m_Settings->remove(section + "/" + name);
+} \ No newline at end of file
diff --git a/src/profile.h b/src/profile.h
index c1cd3e9f..1fcad046 100644
--- a/src/profile.h
+++ b/src/profile.h
@@ -20,15 +20,16 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef PROFILE_H
#define PROFILE_H
+
#include "modinfo.h"
-#include <delayedfilewriter.h>
#include <iprofile.h>
+#include <delayedfilewriter.h>
#include <QByteArray>
#include <QDir>
#include <QObject>
-#include <QSettings>
#include <QString>
+#include <QSettings>
#include <boost/shared_ptr.hpp>
@@ -36,316 +37,322 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <tuple>
#include <vector>
-namespace MOBase {
-class IPluginGame;
-}
+
+namespace MOBase { class IPluginGame; }
/**
* @brief represents a profile
**/
-class Profile : public QObject, public MOBase::IProfile {
+class Profile : public QObject, public MOBase::IProfile
+{
- Q_OBJECT
+ Q_OBJECT
public:
- typedef boost::shared_ptr<Profile> Ptr;
+
+ typedef boost::shared_ptr<Profile> Ptr;
public:
- /**
- * @brief constructor
- *
- * This constructor is used to create a new profile so it is to be assumed a profile
- * by this name does not yet exist
- * @param name name of the new profile
- * @param filter save game filter. Defaults to &lt;no filter&gt;.
- **/
- Profile(const QString& name, MOBase::IPluginGame const* gamePlugin, bool useDefaultSettings);
- /**
- * @brief constructor
- *
- * This constructor is used to open an existing profile though it will also try to repair
- * the profile if important files are missing (including the directory itself) so technically,
- * invoking this should always produce a working profile
- * @param directory directory to read the profile from
- **/
- Profile(const QDir& directory, MOBase::IPluginGame const* gamePlugin);
+ /**
+ * @brief constructor
+ *
+ * This constructor is used to create a new profile so it is to be assumed a profile
+ * by this name does not yet exist
+ * @param name name of the new profile
+ * @param filter save game filter. Defaults to &lt;no filter&gt;.
+ **/
+ Profile(const QString &name, MOBase::IPluginGame const *gamePlugin, bool useDefaultSettings);
- Profile(const Profile& reference);
+ /**
+ * @brief constructor
+ *
+ * This constructor is used to open an existing profile though it will also try to repair
+ * the profile if important files are missing (including the directory itself) so technically,
+ * invoking this should always produce a working profile
+ * @param directory directory to read the profile from
+ **/
+ Profile(const QDir &directory, MOBase::IPluginGame const *gamePlugin);
- ~Profile();
+ Profile(const Profile &reference);
- /**
- * @return true if this profile (still) exists on disc
- */
- bool exists() const;
+ ~Profile();
- /**
- * @param name of the new profile
- * @param reference profile to copy from
- **/
- static Profile* createPtrFrom(const QString& name, const Profile& reference, MOBase::IPluginGame const* gamePlugin);
+ /**
+ * @return true if this profile (still) exists on disc
+ */
+ bool exists() const;
- static void renameModInAllProfiles(const QString& oldName, const QString& newName);
+ /**
+ * @param name of the new profile
+ * @param reference profile to copy from
+ **/
+ static Profile *createPtrFrom(const QString &name, const Profile &reference, MOBase::IPluginGame const *gamePlugin);
- void writeModlist();
- void writeModlistNow(bool onlyIfPending = false);
+ static void renameModInAllProfiles(const QString& oldName, const QString& newName);
- void cancelModlistWrite();
+ void writeModlist();
- /**
- * @brief test if this profile uses archive invalidation
- *
- * @param supported if this is not null, the parameter will be set to false if invalidation is not supported in this
- *profile
- * @return true if archive invalidation is active
- * @note currently, invalidation is not supported if the relevant entry in the ini file does not exist
- **/
- bool invalidationActive(bool* supported) const;
+ void writeModlistNow(bool onlyIfPending=false);
- /**
- * @brief deactivate archive invalidation if it was active
- **/
- void deactivateInvalidation();
+ void cancelModlistWrite();
- /**
- * @brief activate archive invalidation
- **/
- void activateInvalidation();
+ /**
+ * @brief test if this profile uses archive invalidation
+ *
+ * @param supported if this is not null, the parameter will be set to false if invalidation is not supported in this profile
+ * @return true if archive invalidation is active
+ * @note currently, invalidation is not supported if the relevant entry in the ini file does not exist
+ **/
+ bool invalidationActive(bool *supported) const;
- /**
- * @return true if this profile uses local save games
- */
- virtual bool localSavesEnabled() const override;
+ /**
+ * @brief deactivate archive invalidation if it was active
+ **/
+ void deactivateInvalidation();
- /**
- * @brief enables or disables the use of local save games for this profile
- * when disabling the user will be asked if he wants to remove the save games
- * in the profile
- * @param enable if true, local saves are enabled, otherewise they are disabled
- */
- bool enableLocalSaves(bool enable);
+ /**
+ * @brief activate archive invalidation
+ **/
+ void activateInvalidation();
- /**
- * @return true if this profile uses local ini files
- */
- virtual bool localSettingsEnabled() const override;
+ /**
+ * @return true if this profile uses local save games
+ */
+ virtual bool localSavesEnabled() const override;
- /**
- * @brief enables or disables the use of local ini files for this profile
- * disabling this does not delete existing ini files but the global ones will be used
- * @param enable
- */
- bool enableLocalSettings(bool enable);
+ /**
+ * @brief enables or disables the use of local save games for this profile
+ * when disabling the user will be asked if he wants to remove the save games
+ * in the profile
+ * @param enable if true, local saves are enabled, otherewise they are disabled
+ */
+ bool enableLocalSaves(bool enable);
- /**
- * @return name of the profile (this is identical to its directory name)
- **/
- virtual QString name() const override { return m_Directory.dirName(); }
+ /**
+ * @return true if this profile uses local ini files
+ */
+ virtual bool localSettingsEnabled() const override;
- /**
- * @return the path of the plugins file in this profile
- * @todo is this required? can the functionality using this function be moved to the Profile-class?
- **/
- QString getPluginsFileName() const;
+ /**
+ * @brief enables or disables the use of local ini files for this profile
+ * disabling this does not delete existing ini files but the global ones will be used
+ * @param enable
+ */
+ bool enableLocalSettings(bool enable);
- /**
- * @return the path of the loadorder file in this profile
- **/
- QString getLoadOrderFileName() const;
+ /**
+ * @return name of the profile (this is identical to its directory name)
+ **/
+ virtual QString name() const override { return m_Directory.dirName(); }
- /**
- * @return the path of the file containing locked mod indices
- */
- QString getLockedOrderFileName() const;
+ /**
+ * @return the path of the plugins file in this profile
+ * @todo is this required? can the functionality using this function be moved to the Profile-class?
+ **/
+ QString getPluginsFileName() const;
- /**
- * @return the path of the modlist file in this profile
- */
- QString getModlistFileName() const;
+ /**
+ * @return the path of the loadorder file in this profile
+ **/
+ QString getLoadOrderFileName() const;
- /**
- * @return path of the archives file in this profile
- */
- QString getArchivesFileName() const;
+ /**
+ * @return the path of the file containing locked mod indices
+ */
+ QString getLockedOrderFileName() const;
- /**
- * @return the path of the delete file in this profile
- * @note the deleter file lists plugins that should be hidden from the game and other tools
- **/
- QString getDeleterFileName() const;
+ /**
+ * @return the path of the modlist file in this profile
+ */
+ QString getModlistFileName() const;
- /**
- * @return the path of the ini file in this profile
- * @todo since the game can contain multiple ini files (i.e. skyrim.ini skyrimprefs.ini)
- * the concept of this function is somewhat broken
- **/
- QString getIniFileName() const;
+ /**
+ * @return path of the archives file in this profile
+ */
+ QString getArchivesFileName() const;
- /**
- * @return the path of the tweak ini in this profile
- */
- QString getProfileTweaks() const;
+ /**
+ * @return the path of the delete file in this profile
+ * @note the deleter file lists plugins that should be hidden from the game and other tools
+ **/
+ QString getDeleterFileName() const;
- /**
- * @return path to this profile
- **/
- virtual QString absolutePath() const override;
+ /**
+ * @return the path of the ini file in this profile
+ * @todo since the game can contain multiple ini files (i.e. skyrim.ini skyrimprefs.ini)
+ * the concept of this function is somewhat broken
+ **/
+ QString getIniFileName() const;
- /**
- * @return path to this profile's save games
- **/
- QString savePath() const;
+ /**
+ * @return the path of the tweak ini in this profile
+ */
+ QString getProfileTweaks() const;
- /**
- * @brief rename profile
- * @param newName new name of profile
- */
- void rename(const QString& newName);
+ /**
+ * @return path to this profile
+ **/
+ virtual QString absolutePath() const override;
- /**
- * @brief create the ini file to be used by the game
- *
- * the tweaked ini file constructed by this file is a merger
- * of the game-ini of this profile with ini tweaks applied */
- void createTweakedIniFile();
+ /**
+ * @return path to this profile's save games
+ **/
+ QString savePath() const;
- /**
- * @brief re-read the modlist.txt and update the mod status from it
- **/
- void refreshModStatus();
+ /**
+ * @brief rename profile
+ * @param newName new name of profile
+ */
+ void rename(const QString &newName);
- /**
- * @brief retrieve a list of mods that are enabled in this profile
- *
- * @return list of active mods sorted by priority (ascending). "first" is the mod name, "second" is its path
- **/
- std::vector<std::tuple<QString, QString, int>> getActiveMods();
+ /**
+ * @brief create the ini file to be used by the game
+ *
+ * the tweaked ini file constructed by this file is a merger
+ * of the game-ini of this profile with ini tweaks applied */
+ void createTweakedIniFile();
- /**
- * retrieve the number of mods for which this object has status information.
- * This is usually the same as ModInfo::getNumMods() except between
- * calls to ModInfo::updateFromDisc() and the Profile::refreshModStatus()
- *
- * @return number of mods for which the profile has status information
- **/
- size_t numMods() const { return m_ModStatus.size(); }
+ /**
+ * @brief re-read the modlist.txt and update the mod status from it
+ **/
+ void refreshModStatus();
- /**
- * @return the number of mods that can be enabled and where the priority can be modified
- */
- unsigned int numRegularMods() const { return m_NumRegularMods; }
+ /**
+ * @brief retrieve a list of mods that are enabled in this profile
+ *
+ * @return list of active mods sorted by priority (ascending). "first" is the mod name, "second" is its path
+ **/
+ std::vector<std::tuple<QString, QString, int> > getActiveMods();
- /**
- * @brief retrieve the mod index based on the priority
- *
- * @param priority priority to look up
- * @return the index of the mod
- * @throw std::exception an exception is thrown if there is no mod with the specified priority
- **/
- unsigned int modIndexByPriority(unsigned int priority) const;
+ /**
+ * retrieve the number of mods for which this object has status information.
+ * This is usually the same as ModInfo::getNumMods() except between
+ * calls to ModInfo::updateFromDisc() and the Profile::refreshModStatus()
+ *
+ * @return number of mods for which the profile has status information
+ **/
+ size_t numMods() const { return m_ModStatus.size(); }
- /**
- * @brief enable or disable a mod
- *
- * @param index index of the mod to enable/disable
- * @param enabled true if the mod is to be enabled, false if it is to be disabled
- **/
- void setModEnabled(unsigned int index, bool enabled);
+ /**
+ * @return the number of mods that can be enabled and where the priority can be modified
+ */
+ unsigned int numRegularMods() const { return m_NumRegularMods; }
- /**
- * change the priority of a mod. Of course this also changes the priority of other mods.
- * The priority of the mods in the range ]old, new priority] are shifted so that no gaps
- * are possible.
- *
- * @param index index of the mod to change
- * @param newPriority the new priority value
- *
- * @todo what happens if the new priority is outside the range?
- **/
- void setModPriority(unsigned int index, int& newPriority);
+ /**
+ * @brief retrieve the mod index based on the priority
+ *
+ * @param priority priority to look up
+ * @return the index of the mod
+ * @throw std::exception an exception is thrown if there is no mod with the specified priority
+ **/
+ unsigned int modIndexByPriority(unsigned int priority) const;
- /**
- * @brief determine if a mod is enabled
- *
- * @param index index of the mod to look up
- * @return true if the mod is enabled, false otherwise
- **/
- bool modEnabled(unsigned int index) const;
+ /**
+ * @brief enable or disable a mod
+ *
+ * @param index index of the mod to enable/disable
+ * @param enabled true if the mod is to be enabled, false if it is to be disabled
+ **/
+ void setModEnabled(unsigned int index, bool enabled);
- /**
- * @brief query the priority of a mod
- *
- * @param index index of the mod to look up
- * @return priority of the specified mod
- **/
- int getModPriority(unsigned int index) const;
+ /**
+ * change the priority of a mod. Of course this also changes the priority of other mods.
+ * The priority of the mods in the range ]old, new priority] are shifted so that no gaps
+ * are possible.
+ *
+ * @param index index of the mod to change
+ * @param newPriority the new priority value
+ *
+ * @todo what happens if the new priority is outside the range?
+ **/
+ void setModPriority(unsigned int index, int &newPriority);
- void dumpModStatus() const;
+ /**
+ * @brief determine if a mod is enabled
+ *
+ * @param index index of the mod to look up
+ * @return true if the mod is enabled, false otherwise
+ **/
+ bool modEnabled(unsigned int index) const;
- QVariant setting(const QString& section, const QString& name, const QVariant& fallback = QVariant());
+ /**
+ * @brief query the priority of a mod
+ *
+ * @param index index of the mod to look up
+ * @return priority of the specified mod
+ **/
+ int getModPriority(unsigned int index) const;
- void storeSetting(const QString& section, const QString& name, const QVariant& value);
- void removeSetting(const QString& section, const QString& name);
+ void dumpModStatus() const;
+
+ QVariant setting(const QString &section, const QString &name,
+ const QVariant &fallback = QVariant());
+
+ void storeSetting(const QString &section, const QString &name,
+ const QVariant &value);
+ void removeSetting(const QString &section, const QString &name);
signals:
- /**
- * @brief emitted whenever the status (enabled/disabled) of a mod changed
- *
- * @param index index of the mod that changed
- **/
- void modStatusChanged(unsigned int index);
+ /**
+ * @brief emitted whenever the status (enabled/disabled) of a mod changed
+ *
+ * @param index index of the mod that changed
+ **/
+ void modStatusChanged(unsigned int index);
public slots:
- // should only be called by DelayedFileWriter, use writeModlist() and writeModlistNow() instead
- void doWriteModlist();
+ // should only be called by DelayedFileWriter, use writeModlist() and writeModlistNow() instead
+ void doWriteModlist();
private:
- class ModStatus {
- friend class Profile;
-
- public:
- ModStatus() : m_Overwrite(false), m_Enabled(false), m_Priority(-1) {}
- private:
- bool m_Overwrite;
- bool m_Enabled;
- int m_Priority;
- };
+ class ModStatus {
+ friend class Profile;
+ public:
+ ModStatus() : m_Overwrite(false), m_Enabled(false), m_Priority(-1) {}
+ private:
+ bool m_Overwrite;
+ bool m_Enabled;
+ int m_Priority;
+ };
private:
- Profile& operator=(const Profile& reference); // not implemented
+ Profile& operator=(const Profile &reference); // not implemented
- void initTimer();
+ void initTimer();
- void updateIndices();
+ void updateIndices();
- void copyFilesTo(QString& target) const;
+ void copyFilesTo(QString &target) const;
- std::vector<std::wstring> splitDZString(const wchar_t* buffer) const;
- void mergeTweak(const QString& tweakName, const QString& tweakedIni) const;
- void mergeTweaks(ModInfo::Ptr modInfo, const QString& tweakedIni) const;
- void touchFile(QString fileName);
- void finishChangeStatus() const;
+ std::vector<std::wstring> splitDZString(const wchar_t *buffer) const;
+ void mergeTweak(const QString &tweakName, const QString &tweakedIni) const;
+ void mergeTweaks(ModInfo::Ptr modInfo, const QString &tweakedIni) const;
+ void touchFile(QString fileName);
+ void finishChangeStatus() const;
- static void renameModInList(QFile& modList, const QString& oldName, const QString& newName);
+ static void renameModInList(QFile &modList, const QString &oldName, const QString &newName);
private:
- QDir m_Directory;
- QSettings* m_Settings;
+ QDir m_Directory;
- const MOBase::IPluginGame* m_GamePlugin;
+ QSettings *m_Settings;
- mutable QByteArray m_LastModlistHash;
- std::vector<ModStatus> m_ModStatus;
- std::vector<unsigned int> m_ModIndexByPriority;
- unsigned int m_NumRegularMods;
+ const MOBase::IPluginGame *m_GamePlugin;
+
+ mutable QByteArray m_LastModlistHash;
+ std::vector<ModStatus> m_ModStatus;
+ std::vector<unsigned int> m_ModIndexByPriority;
+ unsigned int m_NumRegularMods;
+
+ MOBase::DelayedFileWriter m_ModListWriter;
- MOBase::DelayedFileWriter m_ModListWriter;
};
+
#endif // PROFILE_H
diff --git a/src/profileinputdialog.cpp b/src/profileinputdialog.cpp
index 242f6356..5a1fd03c 100644
--- a/src/profileinputdialog.cpp
+++ b/src/profileinputdialog.cpp
@@ -21,18 +21,28 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "ui_profileinputdialog.h"
#include <utility.h>
-ProfileInputDialog::ProfileInputDialog(QWidget* parent) : QDialog(parent), ui(new Ui::ProfileInputDialog) {
- ui->setupUi(this);
+ProfileInputDialog::ProfileInputDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::ProfileInputDialog)
+{
+ ui->setupUi(this);
}
-ProfileInputDialog::~ProfileInputDialog() { delete ui; }
+ProfileInputDialog::~ProfileInputDialog()
+{
+ delete ui;
+}
-QString ProfileInputDialog::getName() const {
- QString result = ui->nameEdit->text();
- MOBase::fixDirectoryName(result);
- return result;
+QString ProfileInputDialog::getName() const
+{
+ QString result = ui->nameEdit->text();
+ MOBase::fixDirectoryName(result);
+ return result;
}
-bool ProfileInputDialog::getPreferDefaultSettings() const {
- return ui->defaultSettingsBox->checkState() == Qt::Checked;
+
+bool ProfileInputDialog::getPreferDefaultSettings() const
+{
+ return ui->defaultSettingsBox->checkState() == Qt::Checked;
}
+
diff --git a/src/profileinputdialog.h b/src/profileinputdialog.h
index b82696ea..8a132666 100644
--- a/src/profileinputdialog.h
+++ b/src/profileinputdialog.h
@@ -26,18 +26,19 @@ namespace Ui {
class ProfileInputDialog;
}
-class ProfileInputDialog : public QDialog {
- Q_OBJECT
-
+class ProfileInputDialog : public QDialog
+{
+ Q_OBJECT
+
public:
- explicit ProfileInputDialog(QWidget* parent = 0);
- ~ProfileInputDialog();
-
- QString getName() const;
- bool getPreferDefaultSettings() const;
+ explicit ProfileInputDialog(QWidget *parent = 0);
+ ~ProfileInputDialog();
+ QString getName() const;
+ bool getPreferDefaultSettings() const;
+
private:
- Ui::ProfileInputDialog* ui;
+ Ui::ProfileInputDialog *ui;
};
#endif // PROFILEINPUTDIALOG_H
diff --git a/src/profilesdialog.cpp b/src/profilesdialog.cpp
index 9470f101..04c1876d 100644
--- a/src/profilesdialog.cpp
+++ b/src/profilesdialog.cpp
@@ -26,9 +26,9 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "profile.h"
#include "profileinputdialog.h"
#include "report.h"
-#include "settings.h"
#include "transfersavesdialog.h"
#include "utility.h"
+#include "settings.h"
#include <QDir>
#include <QDirIterator>
@@ -47,267 +47,291 @@ using namespace MOShared;
Q_DECLARE_METATYPE(Profile::Ptr)
-ProfilesDialog::ProfilesDialog(const QString& profileName, MOBase::IPluginGame const* game, QWidget* parent)
- : TutorableDialog("Profiles", parent), ui(new Ui::ProfilesDialog), m_FailState(false), m_Game(game) {
- ui->setupUi(this);
- QDir profilesDir(Settings::instance().getProfileDirectory());
- profilesDir.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot);
+ProfilesDialog::ProfilesDialog(const QString &profileName, MOBase::IPluginGame const *game, QWidget *parent)
+ : TutorableDialog("Profiles", parent)
+ , ui(new Ui::ProfilesDialog)
+ , m_FailState(false)
+ , m_Game(game)
+{
+ ui->setupUi(this);
+
+ QDir profilesDir(Settings::instance().getProfileDirectory());
+ profilesDir.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot);
- QDirIterator profileIter(profilesDir);
+ QDirIterator profileIter(profilesDir);
- while (profileIter.hasNext()) {
- profileIter.next();
- QListWidgetItem* item = addItem(profileIter.filePath());
- if (profileName == profileIter.fileName()) {
- ui->profilesList->setCurrentItem(item);
- }
+ while (profileIter.hasNext()) {
+ profileIter.next();
+ QListWidgetItem *item = addItem(profileIter.filePath());
+ if (profileName == profileIter.fileName()) {
+ ui->profilesList->setCurrentItem(item);
}
+ }
- BSAInvalidation* invalidation = game->feature<BSAInvalidation>();
+ BSAInvalidation *invalidation = game->feature<BSAInvalidation>();
- if (invalidation == nullptr) {
- ui->invalidationBox->setToolTip(tr("Archive invalidation isn't required for this game."));
- ui->invalidationBox->setEnabled(false);
- }
+ if (invalidation == nullptr) {
+ ui->invalidationBox->setToolTip(tr("Archive invalidation isn't required for this game."));
+ ui->invalidationBox->setEnabled(false);
+ }
+}
+
+ProfilesDialog::~ProfilesDialog()
+{
+ delete ui;
}
-ProfilesDialog::~ProfilesDialog() { delete ui; }
+void ProfilesDialog::showEvent(QShowEvent *event)
+{
+ TutorableDialog::showEvent(event);
-void ProfilesDialog::showEvent(QShowEvent* event) {
- TutorableDialog::showEvent(event);
+ if (ui->profilesList->count() == 0) {
+ QPoint pos = ui->profilesList->mapToGlobal(QPoint(0, 0));
+ pos.rx() += ui->profilesList->width() / 2;
+ pos.ry() += (ui->profilesList->height() / 2) - 20;
+ QWhatsThis::showText(pos,
+ QObject::tr("Before you can use ModOrganizer, you need to create at least one profile. "
+ "ATTENTION: Run the game at least once before creating a profile!"), ui->profilesList);
+ }
+}
- if (ui->profilesList->count() == 0) {
- QPoint pos = ui->profilesList->mapToGlobal(QPoint(0, 0));
- pos.rx() += ui->profilesList->width() / 2;
- pos.ry() += (ui->profilesList->height() / 2) - 20;
- QWhatsThis::showText(pos,
- QObject::tr("Before you can use ModOrganizer, you need to create at least one profile. "
- "ATTENTION: Run the game at least once before creating a profile!"),
- ui->profilesList);
- }
+void ProfilesDialog::on_closeButton_clicked()
+{
+ close();
}
-void ProfilesDialog::on_closeButton_clicked() { close(); }
-QListWidgetItem* ProfilesDialog::addItem(const QString& name) {
- QDir profileDir(name);
- QListWidgetItem* newItem = new QListWidgetItem(profileDir.dirName(), ui->profilesList);
- try {
- newItem->setData(Qt::UserRole, QVariant::fromValue(Profile::Ptr(new Profile(profileDir, m_Game))));
- m_FailState = false;
- } catch (const std::exception& e) {
- reportError(tr("failed to create profile: %1").arg(e.what()));
- }
- return newItem;
+QListWidgetItem *ProfilesDialog::addItem(const QString &name)
+{
+ QDir profileDir(name);
+ QListWidgetItem *newItem = new QListWidgetItem(profileDir.dirName(), ui->profilesList);
+ try {
+ newItem->setData(Qt::UserRole, QVariant::fromValue(Profile::Ptr(new Profile(profileDir, m_Game))));
+ m_FailState = false;
+ } catch (const std::exception& e) {
+ reportError(tr("failed to create profile: %1").arg(e.what()));
+ }
+ return newItem;
}
-void ProfilesDialog::createProfile(const QString& name, bool useDefaultSettings) {
- try {
- QListWidgetItem* newItem = new QListWidgetItem(name, ui->profilesList);
- newItem->setData(Qt::UserRole,
- QVariant::fromValue(Profile::Ptr(new Profile(name, m_Game, useDefaultSettings))));
- ui->profilesList->addItem(newItem);
- m_FailState = false;
- } catch (const std::exception&) {
- m_FailState = true;
- throw;
- }
+void ProfilesDialog::createProfile(const QString &name, bool useDefaultSettings)
+{
+ try {
+ QListWidgetItem *newItem = new QListWidgetItem(name, ui->profilesList);
+ newItem->setData(Qt::UserRole, QVariant::fromValue(Profile::Ptr(new Profile(name, m_Game, useDefaultSettings))));
+ ui->profilesList->addItem(newItem);
+ m_FailState = false;
+ } catch (const std::exception&) {
+ m_FailState = true;
+ throw;
+ }
}
-void ProfilesDialog::createProfile(const QString& name, const Profile& reference) {
- try {
- QListWidgetItem* newItem = new QListWidgetItem(name, ui->profilesList);
- newItem->setData(Qt::UserRole,
- QVariant::fromValue(Profile::Ptr(Profile::createPtrFrom(name, reference, m_Game))));
- ui->profilesList->addItem(newItem);
- m_FailState = false;
- } catch (const std::exception&) {
- m_FailState = true;
- throw;
- }
+void ProfilesDialog::createProfile(const QString &name, const Profile &reference)
+{
+ try {
+ QListWidgetItem *newItem = new QListWidgetItem(name, ui->profilesList);
+ newItem->setData(Qt::UserRole, QVariant::fromValue(Profile::Ptr(Profile::createPtrFrom(name, reference, m_Game))));
+ ui->profilesList->addItem(newItem);
+ m_FailState = false;
+ } catch (const std::exception&) {
+ m_FailState = true;
+ throw;
+ }
}
-void ProfilesDialog::on_addProfileButton_clicked() {
- ProfileInputDialog dialog(this);
- bool okClicked = dialog.exec();
- QString name = dialog.getName();
+void ProfilesDialog::on_addProfileButton_clicked()
+{
+ ProfileInputDialog dialog(this);
+ bool okClicked = dialog.exec();
+ QString name = dialog.getName();
- if (okClicked && (name.size() > 0)) {
- try {
- createProfile(name, dialog.getPreferDefaultSettings());
- } catch (const std::exception& e) {
- reportError(tr("failed to create profile: %1").arg(e.what()));
- }
+ if (okClicked && (name.size() > 0)) {
+ try {
+ createProfile(name, dialog.getPreferDefaultSettings());
+ } catch (const std::exception &e) {
+ reportError(tr("failed to create profile: %1").arg(e.what()));
}
+ }
}
-void ProfilesDialog::on_copyProfileButton_clicked() {
- bool okClicked;
- QString name = QInputDialog::getText(this, tr("Name"), tr("Please enter a name for the new profile"),
- QLineEdit::Normal, QString(), &okClicked);
- fixDirectoryName(name);
- if (okClicked) {
- if (name.size() > 0) {
- try {
- const Profile::Ptr currentProfile =
- ui->profilesList->currentItem()->data(Qt::UserRole).value<Profile::Ptr>();
- createProfile(name, *currentProfile);
- } catch (const std::exception& e) {
- reportError(tr("failed to copy profile: %1").arg(e.what()));
- }
- } else {
- QMessageBox::warning(this, tr("Invalid name"), tr("Invalid profile name"));
- }
+void ProfilesDialog::on_copyProfileButton_clicked()
+{
+ bool okClicked;
+ QString name = QInputDialog::getText(
+ this, tr("Name"), tr("Please enter a name for the new profile"),
+ QLineEdit::Normal, QString(), &okClicked);
+ fixDirectoryName(name);
+ if (okClicked) {
+ if (name.size() > 0) {
+ try {
+ const Profile::Ptr currentProfile = ui->profilesList->currentItem()
+ ->data(Qt::UserRole)
+ .value<Profile::Ptr>();
+ createProfile(name, *currentProfile);
+ } catch (const std::exception &e) {
+ reportError(tr("failed to copy profile: %1").arg(e.what()));
+ }
+ } else {
+ QMessageBox::warning(this, tr("Invalid name"),
+ tr("Invalid profile name"));
}
+ }
}
-void ProfilesDialog::on_removeProfileButton_clicked() {
- QMessageBox confirmBox(QMessageBox::Question, tr("Confirm"),
- tr("Are you sure you want to remove this profile (including local savegames if any)?"),
- QMessageBox::Yes | QMessageBox::No);
+void ProfilesDialog::on_removeProfileButton_clicked()
+{
+ QMessageBox confirmBox(QMessageBox::Question, tr("Confirm"), tr("Are you sure you want to remove this profile (including local savegames if any)?"),
+ QMessageBox::Yes | QMessageBox::No);
- if (confirmBox.exec() == QMessageBox::Yes) {
- Profile::Ptr currentProfile = ui->profilesList->currentItem()->data(Qt::UserRole).value<Profile::Ptr>();
- QString profilePath;
- if (currentProfile.get() == nullptr) {
- profilePath = Settings::instance().getProfileDirectory() + "/" + ui->profilesList->currentItem()->text();
- if (QMessageBox::question(
- this, tr("Profile broken"),
- tr("This profile you're about to delete seems to be broken or the path is invalid. "
- "I'm about to delete the following folder: \"%1\". Proceed?")
- .arg(profilePath),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
- return;
- }
- } else {
- // on destruction, the profile object would write the profile.ini file again, so
- // we have to get rid of the it before deleting the directory
- profilePath = currentProfile->absolutePath();
- }
- QListWidgetItem* item = ui->profilesList->takeItem(ui->profilesList->currentRow());
- if (item != nullptr) {
- delete item;
- }
- if (!shellDelete(QStringList(profilePath))) {
- qWarning("Failed to shell-delete \"%s\" (errorcode %lu), trying regular delete", qPrintable(profilePath),
- ::GetLastError());
- if (!removeDir(profilePath)) {
- qWarning("regular delete failed too");
- }
- }
+ if (confirmBox.exec() == QMessageBox::Yes) {
+ Profile::Ptr currentProfile = ui->profilesList->currentItem()->data(Qt::UserRole).value<Profile::Ptr>();
+ QString profilePath;
+ if (currentProfile.get() == nullptr) {
+ profilePath = Settings::instance().getProfileDirectory()
+ + "/" + ui->profilesList->currentItem()->text();
+ if (QMessageBox::question(this, tr("Profile broken"),
+ tr("This profile you're about to delete seems to be broken or the path is invalid. "
+ "I'm about to delete the following folder: \"%1\". Proceed?").arg(profilePath), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
+ return;
+ }
+ } else {
+ // on destruction, the profile object would write the profile.ini file again, so
+ // we have to get rid of the it before deleting the directory
+ profilePath = currentProfile->absolutePath();
}
+ QListWidgetItem* item = ui->profilesList->takeItem(ui->profilesList->currentRow());
+ if (item != nullptr) {
+ delete item;
+ }
+ if (!shellDelete(QStringList(profilePath))) {
+ qWarning("Failed to shell-delete \"%s\" (errorcode %lu), trying regular delete", qPrintable(profilePath), ::GetLastError());
+ if (!removeDir(profilePath)) {
+ qWarning("regular delete failed too");
+ }
+ }
+ }
}
-void ProfilesDialog::on_renameButton_clicked() {
- Profile::Ptr currentProfile = ui->profilesList->currentItem()->data(Qt::UserRole).value<Profile::Ptr>();
- bool valid = false;
- QString name;
+void ProfilesDialog::on_renameButton_clicked()
+{
+ Profile::Ptr currentProfile = ui->profilesList->currentItem()->data(Qt::UserRole).value<Profile::Ptr>();
- while (!valid) {
- bool ok = false;
- name = QInputDialog::getText(this, tr("Rename Profile"), tr("New Name"), QLineEdit::Normal,
- currentProfile->name(), &ok);
- valid = fixDirectoryName(name);
- if (!ok) {
- return;
- }
+ bool valid = false;
+ QString name;
+
+ while (!valid) {
+ bool ok = false;
+ name = QInputDialog::getText(this, tr("Rename Profile"), tr("New Name"),
+ QLineEdit::Normal, currentProfile->name(),
+ &ok);
+ valid = fixDirectoryName(name);
+ if (!ok) {
+ return;
}
+ }
- ui->profilesList->currentItem()->setText(name);
- currentProfile->rename(name);
+ ui->profilesList->currentItem()->setText(name);
+ currentProfile->rename(name);
}
-void ProfilesDialog::on_invalidationBox_stateChanged(int state) {
- QListWidgetItem* currentItem = ui->profilesList->currentItem();
- if (currentItem == nullptr) {
- return;
- }
- if (!ui->invalidationBox->isEnabled()) {
- return;
+
+void ProfilesDialog::on_invalidationBox_stateChanged(int state)
+{
+ QListWidgetItem *currentItem = ui->profilesList->currentItem();
+ if (currentItem == nullptr) {
+ return;
+ }
+ if (!ui->invalidationBox->isEnabled()) {
+ return;
+ }
+ try {
+ QVariant currentProfileVariant = currentItem->data(Qt::UserRole);
+ if (!currentProfileVariant.isValid() || currentProfileVariant.isNull()) {
+ return;
}
- try {
- QVariant currentProfileVariant = currentItem->data(Qt::UserRole);
- if (!currentProfileVariant.isValid() || currentProfileVariant.isNull()) {
- return;
- }
- const Profile::Ptr currentProfile = currentItem->data(Qt::UserRole).value<Profile::Ptr>();
- if (state == Qt::Unchecked) {
- currentProfile->deactivateInvalidation();
- } else {
- currentProfile->activateInvalidation();
- }
- } catch (const std::exception& e) {
- reportError(tr("failed to change archive invalidation state: %1").arg(e.what()));
+ const Profile::Ptr currentProfile = currentItem->data(Qt::UserRole).value<Profile::Ptr>();
+ if (state == Qt::Unchecked) {
+ currentProfile->deactivateInvalidation();
+ } else {
+ currentProfile->activateInvalidation();
}
+ } catch (const std::exception &e) {
+ reportError(tr("failed to change archive invalidation state: %1").arg(e.what()));
+ }
}
-void ProfilesDialog::on_profilesList_currentItemChanged(QListWidgetItem* current, QListWidgetItem*) {
- if (current != nullptr) {
- if (!current->data(Qt::UserRole).isValid())
- return;
- const Profile::Ptr currentProfile = current->data(Qt::UserRole).value<Profile::Ptr>();
- try {
- bool invalidationSupported = false;
- ui->invalidationBox->blockSignals(true);
- ui->invalidationBox->setChecked(currentProfile->invalidationActive(&invalidationSupported));
- ui->invalidationBox->setEnabled(invalidationSupported);
- ui->invalidationBox->blockSignals(false);
+void ProfilesDialog::on_profilesList_currentItemChanged(QListWidgetItem *current, QListWidgetItem*)
+{
+ if (current != nullptr) {
+ if (!current->data(Qt::UserRole).isValid()) return;
+ const Profile::Ptr currentProfile = current->data(Qt::UserRole).value<Profile::Ptr>();
- bool localSaves = currentProfile->localSavesEnabled();
- ui->transferButton->setEnabled(localSaves);
- // prevent the stateChanged-event for the saves-box from triggering, otherwise it may think local saves
- // were disabled and delete the files/rename the dir
- ui->localSavesBox->blockSignals(true);
- ui->localSavesBox->setChecked(localSaves);
- ui->localSavesBox->blockSignals(false);
+ try {
+ bool invalidationSupported = false;
+ ui->invalidationBox->blockSignals(true);
+ ui->invalidationBox->setChecked(currentProfile->invalidationActive(&invalidationSupported));
+ ui->invalidationBox->setEnabled(invalidationSupported);
+ ui->invalidationBox->blockSignals(false);
- ui->copyProfileButton->setEnabled(true);
- ui->removeProfileButton->setEnabled(true);
- ui->renameButton->setEnabled(true);
+ bool localSaves = currentProfile->localSavesEnabled();
+ ui->transferButton->setEnabled(localSaves);
+ // prevent the stateChanged-event for the saves-box from triggering, otherwise it may think local saves
+ // were disabled and delete the files/rename the dir
+ ui->localSavesBox->blockSignals(true);
+ ui->localSavesBox->setChecked(localSaves);
+ ui->localSavesBox->blockSignals(false);
- ui->localIniFilesBox->blockSignals(true);
- ui->localIniFilesBox->setChecked(currentProfile->localSettingsEnabled());
- ui->localIniFilesBox->blockSignals(false);
- } catch (const std::exception& E) {
- reportError(tr("failed to determine if invalidation is active: %1").arg(E.what()));
- ui->copyProfileButton->setEnabled(false);
- ui->removeProfileButton->setEnabled(false);
- ui->renameButton->setEnabled(false);
- ui->invalidationBox->setChecked(false);
- }
- } else {
- ui->invalidationBox->setChecked(false);
- ui->copyProfileButton->setEnabled(false);
- ui->removeProfileButton->setEnabled(false);
- ui->renameButton->setEnabled(false);
+ ui->copyProfileButton->setEnabled(true);
+ ui->removeProfileButton->setEnabled(true);
+ ui->renameButton->setEnabled(true);
+
+ ui->localIniFilesBox->blockSignals(true);
+ ui->localIniFilesBox->setChecked(currentProfile->localSettingsEnabled());
+ ui->localIniFilesBox->blockSignals(false);
+ } catch (const std::exception& E) {
+ reportError(tr("failed to determine if invalidation is active: %1").arg(E.what()));
+ ui->copyProfileButton->setEnabled(false);
+ ui->removeProfileButton->setEnabled(false);
+ ui->renameButton->setEnabled(false);
+ ui->invalidationBox->setChecked(false);
}
+ } else {
+ ui->invalidationBox->setChecked(false);
+ ui->copyProfileButton->setEnabled(false);
+ ui->removeProfileButton->setEnabled(false);
+ ui->renameButton->setEnabled(false);
+ }
}
-void ProfilesDialog::on_localSavesBox_stateChanged(int state) {
- Profile::Ptr currentProfile = ui->profilesList->currentItem()->data(Qt::UserRole).value<Profile::Ptr>();
+void ProfilesDialog::on_localSavesBox_stateChanged(int state)
+{
+ Profile::Ptr currentProfile = ui->profilesList->currentItem()->data(Qt::UserRole).value<Profile::Ptr>();
- if (currentProfile->enableLocalSaves(state == Qt::Checked)) {
- ui->transferButton->setEnabled(state == Qt::Checked);
- } else {
- // revert checkbox-state
- ui->localSavesBox->setChecked(state != Qt::Checked);
- }
+ if (currentProfile->enableLocalSaves(state == Qt::Checked)) {
+ ui->transferButton->setEnabled(state == Qt::Checked);
+ } else {
+ // revert checkbox-state
+ ui->localSavesBox->setChecked(state != Qt::Checked);
+ }
}
-void ProfilesDialog::on_transferButton_clicked() {
- const Profile::Ptr currentProfile = ui->profilesList->currentItem()->data(Qt::UserRole).value<Profile::Ptr>();
- TransferSavesDialog transferDialog(*currentProfile, m_Game, this);
- transferDialog.exec();
+void ProfilesDialog::on_transferButton_clicked()
+{
+ const Profile::Ptr currentProfile = ui->profilesList->currentItem()->data(Qt::UserRole).value<Profile::Ptr>();
+ TransferSavesDialog transferDialog(*currentProfile, m_Game, this);
+ transferDialog.exec();
}
-void ProfilesDialog::on_localIniFilesBox_stateChanged(int state) {
- Profile::Ptr currentProfile = ui->profilesList->currentItem()->data(Qt::UserRole).value<Profile::Ptr>();
+void ProfilesDialog::on_localIniFilesBox_stateChanged(int state)
+{
+ Profile::Ptr currentProfile = ui->profilesList->currentItem()->data(Qt::UserRole).value<Profile::Ptr>();
- if (!currentProfile->enableLocalSettings(state == Qt::Checked)) {
- // revert checkbox-state
- ui->localIniFilesBox->setChecked(state != Qt::Checked);
- }
+ if (!currentProfile->enableLocalSettings(state == Qt::Checked)) {
+ // revert checkbox-state
+ ui->localIniFilesBox->setChecked(state != Qt::Checked);
+ }
}
diff --git a/src/profilesdialog.h b/src/profilesdialog.h
index ac8e2b76..cab25f6a 100644
--- a/src/profilesdialog.h
+++ b/src/profilesdialog.h
@@ -28,72 +28,73 @@ class QListWidgetItem;
#include <QObject>
class QString;
-namespace Ui {
-class ProfilesDialog;
-}
+namespace Ui { class ProfilesDialog; }
+
+namespace MOBase { class IPluginGame; }
-namespace MOBase {
-class IPluginGame;
-}
/**
* @brief Dialog that can be used to create/delete/modify profiles
**/
-class ProfilesDialog : public MOBase::TutorableDialog {
- Q_OBJECT
+class ProfilesDialog : public MOBase::TutorableDialog
+{
+ Q_OBJECT
public:
- /**
- * @brief constructor
- *
- * @param profileName currently enabled profile
- * @param parent parent widget
- **/
- explicit ProfilesDialog(const QString& profileName, MOBase::IPluginGame const* game, QWidget* parent = 0);
- ~ProfilesDialog();
- /**
- * @return true if creation of a new profile failed
- * @todo the notion of a fail state makes little sense in the current dialog
- **/
- bool failed() const { return m_FailState; }
+ /**
+ * @brief constructor
+ *
+ * @param profileName currently enabled profile
+ * @param parent parent widget
+ **/
+ explicit ProfilesDialog(const QString &profileName, MOBase::IPluginGame const *game, QWidget *parent = 0);
+ ~ProfilesDialog();
+
+ /**
+ * @return true if creation of a new profile failed
+ * @todo the notion of a fail state makes little sense in the current dialog
+ **/
+ bool failed() const { return m_FailState; }
protected:
- virtual void showEvent(QShowEvent* event);
+
+ virtual void showEvent(QShowEvent *event);
private slots:
- void on_localIniFilesBox_stateChanged(int state);
+ void on_localIniFilesBox_stateChanged(int state);
private:
- QListWidgetItem* addItem(const QString& name);
- void createProfile(const QString& name, bool useDefaultSettings);
- void createProfile(const QString& name, const Profile& reference);
+
+ QListWidgetItem *addItem(const QString &name);
+ void createProfile(const QString &name, bool useDefaultSettings);
+ void createProfile(const QString &name, const Profile &reference);
private slots:
- void on_closeButton_clicked();
+ void on_closeButton_clicked();
- void on_addProfileButton_clicked();
+ void on_addProfileButton_clicked();
- void on_invalidationBox_stateChanged(int arg1);
+ void on_invalidationBox_stateChanged(int arg1);
- void on_copyProfileButton_clicked();
+ void on_copyProfileButton_clicked();
- void on_profilesList_currentItemChanged(QListWidgetItem* current, QListWidgetItem* previous);
+ void on_profilesList_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous);
- void on_removeProfileButton_clicked();
+ void on_removeProfileButton_clicked();
- void on_localSavesBox_stateChanged(int arg1);
+ void on_localSavesBox_stateChanged(int arg1);
- void on_transferButton_clicked();
+ void on_transferButton_clicked();
- void on_renameButton_clicked();
+ void on_renameButton_clicked();
private:
- Ui::ProfilesDialog* ui;
- QListWidget* m_ProfilesList;
- bool m_FailState;
- MOBase::IPluginGame const* m_Game;
+ Ui::ProfilesDialog *ui;
+ QListWidget *m_ProfilesList;
+ bool m_FailState;
+ MOBase::IPluginGame const *m_Game;
};
#endif // PROFILESDIALOG_H
diff --git a/src/qtgroupingproxy.cpp b/src/qtgroupingproxy.cpp
index 51a1517c..5fcb84d3 100644
--- a/src/qtgroupingproxy.cpp
+++ b/src/qtgroupingproxy.cpp
@@ -16,6 +16,7 @@
// Modifications 2013-03-27 to 2013-03-29 by Sebastian Herbord
+
#include "qtgroupingproxy.h"
#include <QDebug>
@@ -30,890 +31,1038 @@
\ingroup model-view
*/
-QtGroupingProxy::QtGroupingProxy(QAbstractItemModel* model, QModelIndex rootNode, int groupedColumn, int groupedRole,
- unsigned int flags, int aggregateRole)
- : QAbstractProxyModel(), m_rootNode(rootNode), m_groupedColumn(0), m_groupedRole(groupedRole),
- m_aggregateRole(aggregateRole), m_flags(flags) {
- setSourceModel(model);
+QtGroupingProxy::QtGroupingProxy(QAbstractItemModel *model, QModelIndex rootNode, int groupedColumn, int groupedRole, unsigned int flags , int aggregateRole)
+ : QAbstractProxyModel()
+ , m_rootNode( rootNode )
+ , m_groupedColumn( 0 )
+ , m_groupedRole( groupedRole )
+ , m_aggregateRole( aggregateRole )
+ , m_flags( flags )
+{
+ setSourceModel( model );
- // signal proxies
- connect(sourceModel(), SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this,
- SLOT(modelDataChanged(const QModelIndex&, const QModelIndex&)));
- connect(sourceModel(), SIGNAL(rowsInserted(const QModelIndex&, int, int)),
- SLOT(modelRowsInserted(const QModelIndex&, int, int)));
- connect(sourceModel(), SIGNAL(rowsAboutToBeInserted(const QModelIndex&, int, int)),
- SLOT(modelRowsAboutToBeInserted(const QModelIndex&, int, int)));
- connect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex&, int, int)),
- SLOT(modelRowsRemoved(const QModelIndex&, int, int)));
- connect(sourceModel(), SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)),
- SLOT(modelRowsAboutToBeRemoved(QModelIndex, int, int)));
- connect(sourceModel(), SIGNAL(layoutChanged()), SLOT(buildTree()));
- connect(sourceModel(), SIGNAL(dataChanged(QModelIndex, QModelIndex)),
- SLOT(modelDataChanged(QModelIndex, QModelIndex)));
- connect(sourceModel(), SIGNAL(modelReset()), this, SLOT(resetModel()));
+ // signal proxies
+ connect( sourceModel(),
+ SIGNAL( dataChanged( const QModelIndex&, const QModelIndex& ) ),
+ this, SLOT( modelDataChanged( const QModelIndex&, const QModelIndex& ) )
+ );
+ connect( sourceModel(), SIGNAL( rowsInserted( const QModelIndex&, int, int ) ),
+ SLOT( modelRowsInserted( const QModelIndex &, int, int ) ) );
+ connect( sourceModel(), SIGNAL(rowsAboutToBeInserted( const QModelIndex &, int ,int )),
+ SLOT(modelRowsAboutToBeInserted( const QModelIndex &, int ,int )));
+ connect( sourceModel(), SIGNAL( rowsRemoved( const QModelIndex&, int, int ) ),
+ SLOT( modelRowsRemoved( const QModelIndex&, int, int ) ) );
+ connect( sourceModel(), SIGNAL(rowsAboutToBeRemoved( const QModelIndex &, int ,int )),
+ SLOT(modelRowsAboutToBeRemoved(QModelIndex,int,int)) );
+ connect( sourceModel(), SIGNAL(layoutChanged()), SLOT(buildTree()) );
+ connect( sourceModel(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
+ SLOT(modelDataChanged(QModelIndex,QModelIndex)) );
+ connect( sourceModel(), SIGNAL(modelReset()), this, SLOT(resetModel()) );
- if (groupedColumn != -1)
- setGroupedColumn(groupedColumn);
+ if( groupedColumn != -1 )
+ setGroupedColumn( groupedColumn );
}
-QtGroupingProxy::~QtGroupingProxy() {}
+QtGroupingProxy::~QtGroupingProxy()
+{
+}
-void QtGroupingProxy::setGroupedColumn(int groupedColumn) {
- m_groupedColumn = groupedColumn;
- buildTree();
+void
+QtGroupingProxy::setGroupedColumn( int groupedColumn )
+{
+ m_groupedColumn = groupedColumn;
+ buildTree();
}
/** Maps to what groups the source row belongs by returning the data of those groups.
- *
- * @returns a list of data for the rows the argument belongs to. In common cases this list will
- * contain only one entry. An empty list means that the source item will be placed in the root of
- * this proxyModel. There is no support for hiding source items.
- *
- * Group data can be pre-loaded in the return value so it's added to the cache maintained by this
- * class. This is required if you want to have data that is not present in the source model.
- */
-QList<RowData> QtGroupingProxy::belongsTo(const QModelIndex& idx) {
- // qDebug() << __FILE__ << __FUNCTION__;
- QList<RowData> rowDataList;
+ *
+ * @returns a list of data for the rows the argument belongs to. In common cases this list will
+ * contain only one entry. An empty list means that the source item will be placed in the root of
+ * this proxyModel. There is no support for hiding source items.
+ *
+ * Group data can be pre-loaded in the return value so it's added to the cache maintained by this
+ * class. This is required if you want to have data that is not present in the source model.
+ */
+QList<RowData>
+QtGroupingProxy::belongsTo( const QModelIndex &idx )
+{
+ //qDebug() << __FILE__ << __FUNCTION__;
+ QList<RowData> rowDataList;
- // get all the data for this index from the model
- ItemData itemData = sourceModel()->itemData(idx);
- if (m_groupedRole != Qt::DisplayRole) {
- itemData[Qt::DisplayRole] = itemData[m_groupedRole];
- }
+ //get all the data for this index from the model
+ ItemData itemData = sourceModel()->itemData( idx );
+ if (m_groupedRole != Qt::DisplayRole) {
+ itemData[Qt::DisplayRole] = itemData[m_groupedRole];
+ }
- // invalid value in grouped role -> ungrouped
- if (!itemData[Qt::DisplayRole].isValid()) {
- return rowDataList;
- }
+ // invalid value in grouped role -> ungrouped
+ if (!itemData[Qt::DisplayRole].isValid()) {
+ return rowDataList;
+ }
- QMapIterator<int, QVariant> i(itemData);
- while (i.hasNext()) {
- i.next();
- int role = i.key();
- QVariant variant = i.value();
- // qDebug() << "role " << role << " : (" << variant.typeName() << ") : "<< variant;
- if (variant.type() == QVariant::List) {
- // a list of variants get's expanded to multiple rows
- QVariantList list = variant.toList();
- for (int i = 0; i < list.length(); i++) {
- // take an existing row data or create a new one
- RowData rowData = (rowDataList.count() > i) ? rowDataList.takeAt(i) : RowData();
+ QMapIterator<int, QVariant> i( itemData );
+ while( i.hasNext() )
+ {
+ i.next();
+ int role = i.key();
+ QVariant variant = i.value();
+ // qDebug() << "role " << role << " : (" << variant.typeName() << ") : "<< variant;
+ if ( variant.type() == QVariant::List )
+ {
+ //a list of variants get's expanded to multiple rows
+ QVariantList list = variant.toList();
+ for( int i = 0; i < list.length(); i++ )
+ {
+ //take an existing row data or create a new one
+ RowData rowData = (rowDataList.count() > i) ? rowDataList.takeAt( i )
+ : RowData();
- // we only gather data for the first column
- ItemData indexData = rowData.contains(0) ? rowData.take(0) : ItemData();
- indexData.insert(role, list.value(i));
- rowData.insert(0, indexData);
- // for the grouped column the data should not be gathered from the children
- // this will allow filtering on the content of this column with a
- // QSortFilterProxyModel
- rowData.insert(m_groupedColumn, indexData);
- rowDataList.insert(i, rowData);
- }
- break;
- } else if (!variant.isNull()) {
- // it's just a normal item. Copy all the data and break this loop.
- RowData rowData;
- rowData.insert(0, itemData);
- rowDataList << rowData;
- break;
- }
+ //we only gather data for the first column
+ ItemData indexData = rowData.contains( 0 ) ? rowData.take( 0 ) : ItemData();
+ indexData.insert( role, list.value( i ) );
+ rowData.insert( 0, indexData );
+ //for the grouped column the data should not be gathered from the children
+ //this will allow filtering on the content of this column with a
+ //QSortFilterProxyModel
+ rowData.insert( m_groupedColumn, indexData );
+ rowDataList.insert( i, rowData );
+ }
+ break;
+ }
+ else if( !variant.isNull() )
+ {
+ //it's just a normal item. Copy all the data and break this loop.
+ RowData rowData;
+ rowData.insert( 0, itemData );
+ rowDataList << rowData;
+ break;
}
+ }
- return rowDataList;
+ return rowDataList;
}
/* m_groupHash layout
- * key : index of the group in m_groupMaps
- * value : a QList of the original rows in sourceModel() for the children of this group
- *
- * key = -1 contains a QList of the non-grouped indexes
- *
- * TODO: sub-groups
- */
-void QtGroupingProxy::buildTree() {
- if (!sourceModel())
- return;
- beginResetModel();
-
- m_groupHash.clear();
- // don't clear the data maps since most of it will probably be needed again.
- m_parentCreateList.clear();
+* key : index of the group in m_groupMaps
+* value : a QList of the original rows in sourceModel() for the children of this group
+*
+* key = -1 contains a QList of the non-grouped indexes
+*
+* TODO: sub-groups
+*/
+void
+QtGroupingProxy::buildTree()
+{
+ if( !sourceModel() )
+ return;
+ beginResetModel();
- int max = sourceModel()->rowCount(m_rootNode);
- // qDebug() << QString("building tree with %1 leafs.").arg( max );
- // WARNING: these have to be added in order because the addToGroups function is optimized for
- // modelRowsInserted(). Failure to do so will result in wrong data shown in the view at best.
- for (int row = 0; row < max; row++) {
- QModelIndex idx = sourceModel()->index(row, m_groupedColumn, m_rootNode);
- addSourceRow(idx);
- }
- // dumpGroups();
+ m_groupHash.clear();
+ //don't clear the data maps since most of it will probably be needed again.
+ m_parentCreateList.clear();
- if (m_flags & FLAG_NOSINGLE) {
- // awkward: flatten single-item groups as a post-processing steps.
+ int max = sourceModel()->rowCount( m_rootNode );
+ //qDebug() << QString("building tree with %1 leafs.").arg( max );
+ //WARNING: these have to be added in order because the addToGroups function is optimized for
+ //modelRowsInserted(). Failure to do so will result in wrong data shown in the view at best.
+ for( int row = 0; row < max; row++ )
+ {
+ QModelIndex idx = sourceModel()->index( row, m_groupedColumn, m_rootNode );
+ addSourceRow( idx );
+ }
+ //dumpGroups();
- int currentKey = 0;
- quint32 quint32max = std::numeric_limits<quint32>::max();
- std::vector<int> rmgroups;
+ if (m_flags & FLAG_NOSINGLE) {
+ // awkward: flatten single-item groups as a post-processing steps.
- QHash<quint32, QList<int>> temp;
+ int currentKey = 0;
+ quint32 quint32max = std::numeric_limits<quint32>::max();
+ std::vector<int> rmgroups;
- for (auto iter = m_groupHash.begin(); iter != m_groupHash.end(); ++iter) {
- if ((iter.key() == quint32max) || (iter->count() < 2)) {
- temp[quint32max].append(iter.value());
- if (iter.key() != quint32max) {
- rmgroups.push_back(iter.key());
- }
- } else {
- temp[currentKey++] = *iter;
- }
- }
- m_groupHash = temp;
+ QHash<quint32, QList<int> > temp;
- // second loop is necessary because qt containers can't be iterated from end to front
- // and removing by index from begin to end is ugly
- std::sort(rmgroups.begin(), rmgroups.end(), [](int lhs, int rhs) { return rhs < lhs; });
- for (auto iter = rmgroups.begin(); iter != rmgroups.end(); ++iter) {
- m_groupMaps.removeAt(*iter);
+ for (auto iter = m_groupHash.begin(); iter != m_groupHash.end(); ++iter) {
+ if ((iter.key() == quint32max) ||
+ (iter->count() < 2)) {
+ temp[quint32max].append(iter.value());
+ if (iter.key() != quint32max) {
+ rmgroups.push_back(iter.key());
}
+ } else {
+ temp[currentKey++] = *iter;
+ }
}
+ m_groupHash = temp;
- endResetModel();
- // restore expand-state
- for (int row = 0; row < rowCount(); row++) {
- QModelIndex idx = index(row, 0, QModelIndex());
- if (m_expandedItems.contains(idx.data(Qt::UserRole).toString())) {
- emit expandItem(idx);
- }
+ // second loop is necessary because qt containers can't be iterated from end to front
+ // and removing by index from begin to end is ugly
+ std::sort(rmgroups.begin(), rmgroups.end(), [] (int lhs, int rhs) { return rhs < lhs; });
+ for (auto iter = rmgroups.begin(); iter != rmgroups.end(); ++iter) {
+ m_groupMaps.removeAt(*iter);
}
-}
+ }
-QList<int> QtGroupingProxy::addSourceRow(const QModelIndex& idx) {
- QList<int> updatedGroups;
- QList<RowData> groupData = belongsTo(idx);
-
- // an empty list here means it's supposed to go in root.
- if (groupData.isEmpty()) {
- updatedGroups << -1;
- if (!m_groupHash.keys().contains(std::numeric_limits<quint32>::max()))
- m_groupHash.insert(std::numeric_limits<quint32>::max(), QList<int>()); // add an empty placeholder
+ endResetModel();
+ // restore expand-state
+ for( int row = 0; row < rowCount(); row++ ) {
+ QModelIndex idx = index( row, 0, QModelIndex() );
+ if (m_expandedItems.contains(idx.data(Qt::UserRole).toString())) {
+ emit expandItem(idx);
}
+ }
+}
- // an item can be in multiple groups
- foreach (RowData data, groupData) {
- int updatedGroup = -1;
- if (!data.isEmpty()) {
- // qDebug() << QString("index %1 belongs to group %2").arg( row )
- // .arg( data[0][Qt::DisplayRole].toString() );
+QList<int>
+QtGroupingProxy::addSourceRow( const QModelIndex &idx )
+{
+ QList<int> updatedGroups;
+ QList<RowData> groupData = belongsTo( idx );
- foreach (const RowData& cachedData, m_groupMaps) {
- // when this matches the index belongs to an existing group
- if (data[0][Qt::DisplayRole] == cachedData[0][Qt::DisplayRole]) {
- data = cachedData;
- break;
- }
- }
+ //an empty list here means it's supposed to go in root.
+ if( groupData.isEmpty() )
+ {
+ updatedGroups << -1;
+ if( !m_groupHash.keys().contains( std::numeric_limits<quint32>::max() ) )
+ m_groupHash.insert( std::numeric_limits<quint32>::max(), QList<int>() ); //add an empty placeholder
+ }
- updatedGroup = m_groupMaps.indexOf(data);
- //-1 means not found
- if (updatedGroup == -1) {
- // new groups are added to the end of the existing list
- m_groupMaps << data;
- updatedGroup = m_groupMaps.count() - 1;
- }
+ //an item can be in multiple groups
+ foreach( RowData data, groupData )
+ {
+ int updatedGroup = -1;
+ if( !data.isEmpty() )
+ {
+ // qDebug() << QString("index %1 belongs to group %2").arg( row )
+ // .arg( data[0][Qt::DisplayRole].toString() );
- if (!m_groupHash.keys().contains(updatedGroup))
- m_groupHash.insert(updatedGroup, QList<int>()); // add an empty placeholder
+ foreach( const RowData &cachedData, m_groupMaps )
+ {
+ //when this matches the index belongs to an existing group
+ if( data[0][Qt::DisplayRole] == cachedData[0][Qt::DisplayRole] )
+ {
+ data = cachedData;
+ break;
}
+ }
- if (!updatedGroups.contains(updatedGroup))
- updatedGroups << updatedGroup;
+ updatedGroup = m_groupMaps.indexOf( data );
+ //-1 means not found
+ if( updatedGroup == -1 )
+ {
+ //new groups are added to the end of the existing list
+ m_groupMaps << data;
+ updatedGroup = m_groupMaps.count() - 1;
+ }
+
+ if( !m_groupHash.keys().contains( updatedGroup ) )
+ m_groupHash.insert( updatedGroup, QList<int>() ); //add an empty placeholder
}
- // update m_groupHash to the new source-model layout (one row added)
- QMutableHashIterator<quint32, QList<int>> i(m_groupHash);
- while (i.hasNext()) {
- i.next();
- QList<int>& groupList = i.value();
- int insertedProxyRow = groupList.count();
- for (; insertedProxyRow > 0; insertedProxyRow--) {
- int& rowValue = groupList[insertedProxyRow - 1];
- if (idx.row() <= rowValue) {
- // increment the rows that come after the new row since they moved one place up.
- rowValue++;
- } else {
- break;
- }
- }
+ if( !updatedGroups.contains( updatedGroup ) )
+ updatedGroups << updatedGroup;
+ }
- if (updatedGroups.contains(i.key())) {
- // the row needs to be added to this group
- groupList.insert(insertedProxyRow, idx.row());
- }
+ //update m_groupHash to the new source-model layout (one row added)
+ QMutableHashIterator<quint32, QList<int> > i( m_groupHash );
+ while( i.hasNext() )
+ {
+ i.next();
+ QList<int> &groupList = i.value();
+ int insertedProxyRow = groupList.count();
+ for( ; insertedProxyRow > 0 ; insertedProxyRow-- )
+ {
+ int &rowValue = groupList[insertedProxyRow-1];
+ if( idx.row() <= rowValue )
+ {
+ //increment the rows that come after the new row since they moved one place up.
+ rowValue++;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if( updatedGroups.contains( i.key() ) )
+ {
+ //the row needs to be added to this group
+ groupList.insert( insertedProxyRow, idx.row() );
}
+ }
- return updatedGroups;
+ return updatedGroups;
}
/** Each ModelIndex has in it's internalId a position in the parentCreateList.
- * struct ParentCreate are the instructions to recreate the parent index.
- * It contains the proxy row number of the parent and the postion in this list of the grandfather.
- * This function creates the ParentCreate structs and saves them in a list.
- */
-int QtGroupingProxy::indexOfParentCreate(const QModelIndex& parent) const {
- if (!parent.isValid())
- return -1;
+ * struct ParentCreate are the instructions to recreate the parent index.
+ * It contains the proxy row number of the parent and the postion in this list of the grandfather.
+ * This function creates the ParentCreate structs and saves them in a list.
+ */
+int
+QtGroupingProxy::indexOfParentCreate( const QModelIndex &parent ) const
+{
+ if( !parent.isValid() )
+ return -1;
- struct ParentCreate pc;
- for (int i = 0; i < m_parentCreateList.size(); i++) {
- pc = m_parentCreateList[i];
- if (pc.parentCreateIndex == parent.internalId() && pc.row == parent.row())
- return i;
- }
- // there is no parentCreate yet for this index, so let's create one.
- pc.parentCreateIndex = parent.internalId();
- pc.row = parent.row();
- m_parentCreateList << pc;
+ struct ParentCreate pc;
+ for( int i = 0 ; i < m_parentCreateList.size() ; i++ )
+ {
+ pc = m_parentCreateList[i];
+ if( pc.parentCreateIndex == parent.internalId() && pc.row == parent.row() )
+ return i;
+ }
+ //there is no parentCreate yet for this index, so let's create one.
+ pc.parentCreateIndex = parent.internalId();
+ pc.row = parent.row();
+ m_parentCreateList << pc;
- // dumpParentCreateList();
- // qDebug() << QString( "m_parentCreateList: (%1)" ).arg( m_parentCreateList.size() );
- // for( int i = 0 ; i < m_parentCreateList.size() ; i++ )
- // {
- // qDebug() << i << " : " << m_parentCreateList[i].parentCreateIndex <<
- // " | " << m_parentCreateList[i].row;
- // }
+ //dumpParentCreateList();
+ // qDebug() << QString( "m_parentCreateList: (%1)" ).arg( m_parentCreateList.size() );
+ // for( int i = 0 ; i < m_parentCreateList.size() ; i++ )
+ // {
+ // qDebug() << i << " : " << m_parentCreateList[i].parentCreateIndex <<
+ // " | " << m_parentCreateList[i].row;
+ // }
- return m_parentCreateList.size() - 1;
+ return m_parentCreateList.size() - 1;
}
-QModelIndex QtGroupingProxy::index(int row, int column, const QModelIndex& parent) const {
- // qDebug() << "index requested for: (" << row << "," << column << "), " << parent;
- if (!hasIndex(row, column, parent)) {
- return QModelIndex();
- }
+QModelIndex
+QtGroupingProxy::index( int row, int column, const QModelIndex &parent ) const
+{
+ // qDebug() << "index requested for: (" << row << "," << column << "), " << parent;
+ if( !hasIndex(row, column, parent) ) {
+ return QModelIndex();
+ }
- if (parent.column() > 0) {
- return QModelIndex();
- }
+ if( parent.column() > 0 ) {
+ return QModelIndex();
+ }
- /* We save the instructions to make the parent of the index in a struct.
+ /* We save the instructions to make the parent of the index in a struct.
* The place of the struct in the list is stored in the internalId
*/
- int parentCreateIndex = indexOfParentCreate(parent);
+ int parentCreateIndex = indexOfParentCreate( parent );
- return createIndex(row, column, parentCreateIndex);
+ return createIndex( row, column, parentCreateIndex );
}
-QModelIndex QtGroupingProxy::parent(const QModelIndex& index) const {
- // qDebug() << "parent: " << index;
- if (!index.isValid())
- return QModelIndex();
+QModelIndex
+QtGroupingProxy::parent( const QModelIndex &index ) const
+{
+ //qDebug() << "parent: " << index;
+ if( !index.isValid() )
+ return QModelIndex();
- int parentCreateIndex = index.internalId();
- // qDebug() << "parentCreateIndex: " << parentCreateIndex;
- if (parentCreateIndex == -1 || parentCreateIndex >= m_parentCreateList.count())
- return QModelIndex();
+ int parentCreateIndex = index.internalId();
+ //qDebug() << "parentCreateIndex: " << parentCreateIndex;
+ if( parentCreateIndex == -1 || parentCreateIndex >= m_parentCreateList.count() )
+ return QModelIndex();
- struct ParentCreate pc = m_parentCreateList[parentCreateIndex];
- // qDebug() << "parentCreate: (" << pc.parentCreateIndex << "," << pc.row << ")";
- // only items at column 0 have children
- return createIndex(pc.row, 0, pc.parentCreateIndex);
+ struct ParentCreate pc = m_parentCreateList[parentCreateIndex];
+ //qDebug() << "parentCreate: (" << pc.parentCreateIndex << "," << pc.row << ")";
+ //only items at column 0 have children
+ return createIndex( pc.row, 0, pc.parentCreateIndex );
}
-int QtGroupingProxy::rowCount(const QModelIndex& index) const {
- // qDebug() << "rowCount: " << index;
- if (!index.isValid()) {
- // the number of top level groups + the number of non-grouped items
- int rows = m_groupMaps.count() + m_groupHash.value(std::numeric_limits<quint32>::max()).count();
- // qDebug() << rows << " in root group";
- return rows;
- }
+int
+QtGroupingProxy::rowCount( const QModelIndex &index ) const
+{
+ //qDebug() << "rowCount: " << index;
+ if( !index.isValid() )
+ {
+ //the number of top level groups + the number of non-grouped items
+ int rows = m_groupMaps.count() + m_groupHash.value( std::numeric_limits<quint32>::max() ).count();
+ //qDebug() << rows << " in root group";
+ return rows;
+ }
- // TODO:group in group support.
- if (isGroup(index)) {
- qint64 groupIndex = index.row();
- int rows = m_groupHash.value(groupIndex).count();
- // qDebug() << rows << " in group " << m_groupMaps[groupIndex];
- return rows;
- } else {
- QModelIndex originalIndex = mapToSource(index);
- int rowCount = sourceModel()->rowCount(originalIndex);
- // qDebug() << "original item: rowCount == " << rowCount;
- return rowCount;
- }
+ //TODO:group in group support.
+ if( isGroup( index ) )
+ {
+ qint64 groupIndex = index.row();
+ int rows = m_groupHash.value( groupIndex ).count();
+ //qDebug() << rows << " in group " << m_groupMaps[groupIndex];
+ return rows;
+ } else {
+ QModelIndex originalIndex = mapToSource( index );
+ int rowCount = sourceModel()->rowCount( originalIndex );
+ //qDebug() << "original item: rowCount == " << rowCount;
+ return rowCount;
+ }
}
-int QtGroupingProxy::columnCount(const QModelIndex& index) const {
- if (!index.isValid())
- return sourceModel()->columnCount(m_rootNode);
+int
+QtGroupingProxy::columnCount( const QModelIndex &index ) const
+{
+ if( !index.isValid() )
+ return sourceModel()->columnCount( m_rootNode );
- if (index.column() != 0)
- return 0;
+ if( index.column() != 0 )
+ return 0;
- return sourceModel()->columnCount(mapToSource(index));
+ return sourceModel()->columnCount( mapToSource( index ) );
}
-static bool variantLess(const QVariant& LHS, const QVariant& RHS) {
- if ((LHS.type() == RHS.type()) && ((LHS.type() == QVariant::Int) || (LHS.type() == QVariant::UInt))) {
- return LHS.toInt() < RHS.toInt();
- }
- // this should always work (comparing empty strings in the worst case) but
- // the results may be wrong
- return LHS.toString() < RHS.toString();
+static bool variantLess(const QVariant &LHS, const QVariant &RHS)
+{
+ if ((LHS.type() == RHS.type()) &&
+ ((LHS.type() == QVariant::Int) || (LHS.type() == QVariant::UInt))) {
+ return LHS.toInt() < RHS.toInt();
+ }
+
+ // this should always work (comparing empty strings in the worst case) but
+ // the results may be wrong
+ return LHS.toString() < RHS.toString();
}
-static QVariant variantMax(const QVariantList& variants) {
- QVariant result = variants.first();
- foreach (const QVariant& iter, variants) {
- if (variantLess(result, iter)) {
- result = iter;
- }
+
+static QVariant variantMax(const QVariantList &variants)
+{
+ QVariant result = variants.first();
+ foreach (const QVariant &iter, variants) {
+ if (variantLess(result, iter)) {
+ result = iter;
}
- return result;
+ }
+ return result;
}
-static QVariant variantMin(const QVariantList& variants) {
- QVariant result = variants.first();
- foreach (const QVariant& iter, variants) {
- if (variantLess(iter, result)) {
- result = iter;
- }
+
+static QVariant variantMin(const QVariantList &variants)
+{
+ QVariant result = variants.first();
+ foreach (const QVariant &iter, variants) {
+ if (variantLess(iter, result)) {
+ result = iter;
}
- return result;
+ }
+ return result;
}
-QVariant QtGroupingProxy::data(const QModelIndex& index, int role) const {
- if (!index.isValid())
- return QVariant();
- // qDebug() << __FUNCTION__ << index << " role: " << role;
- int row = index.row();
- int column = index.column();
- if (isGroup(index)) {
- if ((role != Qt::DisplayRole) && (role != Qt::EditRole)) {
- switch (role) {
- case Qt::ForegroundRole: {
- return QBrush(Qt::gray);
- } break;
- case Qt::FontRole: {
- QFont font(m_groupMaps[row][column].value(Qt::FontRole).value<QFont>());
- font.setItalic(true);
- return font;
- } break;
- case Qt::TextAlignmentRole: {
- return Qt::AlignHCenter;
- } break;
- case Qt::UserRole: {
- return m_groupMaps[row][column].value(Qt::DisplayRole).toString();
- } break;
- case Qt::CheckStateRole: {
- if (column != 0)
- return QVariant();
- int childCount = m_groupHash.value(row).count();
- int checked = 0;
- QModelIndex parentIndex = this->index(row, 0, index.parent());
- for (int childRow = 0; childRow < childCount; ++childRow) {
- QModelIndex childIndex = this->index(childRow, 0, parentIndex);
- QVariant data = mapToSource(childIndex).data(Qt::CheckStateRole);
- if (data.toInt() == 2)
- ++checked;
- }
- if (checked == childCount)
- return Qt::Checked;
- else if (checked == 0)
- return Qt::Unchecked;
- else
- return Qt::PartiallyChecked;
- } break;
- default: {
- QModelIndex parentIndex = this->index(row, 0, index.parent());
- if (m_groupHash.value(row).count() > 0) {
- return this->index(0, column, parentIndex).data(role);
- } else {
- return QVariant();
- }
- // return m_groupMaps[row][column].value( role );
- } break;
- }
- }
- // qDebug() << __FUNCTION__ << "is a group";
- // use cached or precalculated data
- if (m_groupMaps[row][column].contains(Qt::DisplayRole)) {
- // qDebug() << "Using cached data for " << row << "x" << column << ": " <<
- // m_groupMaps[row][column].value(Qt::DisplayRole).toString();
- if ((m_flags & FLAG_NOGROUPNAME) != 0) {
- QModelIndex parentIndex = this->index(row, 0, index.parent());
- QModelIndex childIndex = this->index(0, column, parentIndex);
- return childIndex.data(role).toString();
+QVariant
+QtGroupingProxy::data( const QModelIndex &index, int role ) const
+{
+ if( !index.isValid() )
+ return QVariant();
+ // qDebug() << __FUNCTION__ << index << " role: " << role;
+ int row = index.row();
+ int column = index.column();
+ if( isGroup( index ) )
+ {
+ if ((role != Qt::DisplayRole) && (role != Qt::EditRole)) {
+ switch (role) {
+ case Qt::ForegroundRole: {
+ return QBrush(Qt::gray);
+ } break;
+ case Qt::FontRole: {
+ QFont font(m_groupMaps[row][column].value(Qt::FontRole).value<QFont>());
+ font.setItalic(true);
+ return font;
+ } break;
+ case Qt::TextAlignmentRole: {
+ return Qt::AlignHCenter;
+ } break;
+ case Qt::UserRole: {
+ return m_groupMaps[row][column].value( Qt::DisplayRole ).toString();
+ } break;
+ case Qt::CheckStateRole: {
+ if (column != 0) return QVariant();
+ int childCount = m_groupHash.value( row ).count();
+ int checked = 0;
+ QModelIndex parentIndex = this->index( row, 0, index.parent() );
+ for( int childRow = 0; childRow < childCount; ++childRow )
+ {
+ QModelIndex childIndex = this->index( childRow, 0, parentIndex );
+ QVariant data = mapToSource( childIndex ).data( Qt::CheckStateRole );
+ if (data.toInt() == 2) ++checked;
+ }
+ if (checked == childCount) return Qt::Checked;
+ else if (checked == 0) return Qt::Unchecked;
+ else return Qt::PartiallyChecked;
+ } break;
+ default: {
+ QModelIndex parentIndex = this->index( row, 0, index.parent() );
+ if (m_groupHash.value( row ).count() > 0) {
+ return this->index(0, column, parentIndex).data(role);
} else {
- return m_groupMaps[row][column].value(role).toString();
+ return QVariant();
}
- }
+ // return m_groupMaps[row][column].value( role );
+ } break;
+ }
+ }
- // for column 0 we gather data from the grouped column instead
- if (column == 0)
- column = m_groupedColumn;
+ //qDebug() << __FUNCTION__ << "is a group";
+ //use cached or precalculated data
+ if( m_groupMaps[row][column].contains( Qt::DisplayRole ) )
+ {
+ // qDebug() << "Using cached data for " << row << "x" << column << ": " << m_groupMaps[row][column].value(Qt::DisplayRole).toString();
+ if ((m_flags & FLAG_NOGROUPNAME) != 0) {
+ QModelIndex parentIndex = this->index( row, 0, index.parent() );
+ QModelIndex childIndex = this->index( 0, column, parentIndex );
+ return childIndex.data(role).toString();
+ } else {
+ return m_groupMaps[row][column].value( role ).toString();
+ }
+ }
- // map all data from children to columns of group to allow grouping one level up
- QVariantList variantsOfChildren;
- int childCount = m_groupHash.value(row).count();
- if (childCount == 0)
- return QVariant();
+ //for column 0 we gather data from the grouped column instead
+ if( column == 0 )
+ column = m_groupedColumn;
- int function = AGGR_NONE;
- if (m_aggregateRole >= Qt::UserRole) {
- QModelIndex parentIndex = this->index(row, 0, index.parent());
- QModelIndex childIndex = this->index(0, column, parentIndex);
- function = mapToSource(childIndex).data(m_aggregateRole).toInt();
- }
+ //map all data from children to columns of group to allow grouping one level up
+ QVariantList variantsOfChildren;
+ int childCount = m_groupHash.value( row ).count();
+ if( childCount == 0 )
+ return QVariant();
- // qDebug() << __FUNCTION__ << "childCount: " << childCount;
- // Need a parentIndex with column == 0 because only those have children.
- QModelIndex parentIndex = this->index(row, 0, index.parent());
- for (int childRow = 0; childRow < childCount; childRow++) {
- QModelIndex childIndex = this->index(childRow, column, parentIndex);
- QVariant data = mapToSource(childIndex).data(role);
- // qDebug() << __FUNCTION__ << data << QVariant::typeToName(data.type());
- if (data.isValid() && !variantsOfChildren.contains(data))
- variantsOfChildren << data;
- }
- // qDebug() << "gathered this data from children: " << variantsOfChildren;
- // saving in cache
- ItemData roleMap = m_groupMaps[row].value(column);
- foreach (const QVariant& variant, variantsOfChildren) {
- if (roleMap[role] != variant) {
- roleMap.insert(role, variantsOfChildren);
- }
- }
+ int function = AGGR_NONE;
+ if (m_aggregateRole >= Qt::UserRole) {
+ QModelIndex parentIndex = this->index( row, 0, index.parent() );
+ QModelIndex childIndex = this->index( 0, column, parentIndex );
+ function = mapToSource(childIndex).data(m_aggregateRole).toInt();
+ }
- // qDebug() << QString("roleMap[%1]:").arg(role) << roleMap[role];
+ //qDebug() << __FUNCTION__ << "childCount: " << childCount;
+ //Need a parentIndex with column == 0 because only those have children.
+ QModelIndex parentIndex = this->index( row, 0, index.parent() );
+ for( int childRow = 0; childRow < childCount; childRow++ )
+ {
+ QModelIndex childIndex = this->index( childRow, column, parentIndex );
+ QVariant data = mapToSource( childIndex ).data( role );
+ //qDebug() << __FUNCTION__ << data << QVariant::typeToName(data.type());
+ if( data.isValid() && !variantsOfChildren.contains( data ) )
+ variantsOfChildren << data;
+ }
+ //qDebug() << "gathered this data from children: " << variantsOfChildren;
+ //saving in cache
+ ItemData roleMap = m_groupMaps[row].value( column );
+ foreach( const QVariant &variant, variantsOfChildren )
+ {
+ if( roleMap[ role ] != variant ) {
+ roleMap.insert( role, variantsOfChildren );
+ }
+ }
- if (variantsOfChildren.count() == 0)
- return QVariant();
+ //qDebug() << QString("roleMap[%1]:").arg(role) << roleMap[role];
- // only one unique variant? No need to return a list
- switch (function) {
- case AGGR_EMPTY:
- return QVariant();
- case AGGR_FIRST:
+ if( variantsOfChildren.count() == 0 )
+ return QVariant();
+
+ //only one unique variant? No need to return a list
+ switch (function) {
+ case AGGR_EMPTY: return QVariant();
+ case AGGR_FIRST: return variantsOfChildren.first();
+ case AGGR_MAX: return variantMax(variantsOfChildren);
+ case AGGR_MIN: return variantMin(variantsOfChildren);
+ default: {
+ if( variantsOfChildren.count() == 1 )
return variantsOfChildren.first();
- case AGGR_MAX:
- return variantMax(variantsOfChildren);
- case AGGR_MIN:
- return variantMin(variantsOfChildren);
- default: {
- if (variantsOfChildren.count() == 1)
- return variantsOfChildren.first();
- return variantsOfChildren;
+ return variantsOfChildren;
} break;
- }
}
+ }
- return mapToSource(index).data(role);
+ return mapToSource( index ).data( role );
}
-bool QtGroupingProxy::setData(const QModelIndex& idx, const QVariant& value, int role) {
- if (!idx.isValid())
- return false;
-
- // no need to set data to exactly the same value
- if (idx.data(role) == value)
- return false;
+bool
+QtGroupingProxy::setData( const QModelIndex &idx, const QVariant &value, int role )
+{
+ if( !idx.isValid() )
+ return false;
- if (isGroup(idx)) {
- ItemData columnData = m_groupMaps[idx.row()][idx.column()];
+ //no need to set data to exactly the same value
+ if( idx.data( role ) == value )
+ return false;
- columnData.insert(role, value);
- // QItemDelegate will always use Qt::EditRole
- if (role == Qt::EditRole)
- columnData.insert(Qt::DisplayRole, value);
+ if( isGroup( idx ) )
+ {
+ ItemData columnData = m_groupMaps[idx.row()][idx.column()];
- // and make sure it's stored in the map
- m_groupMaps[idx.row()].insert(idx.column(), columnData);
+ columnData.insert( role, value );
+ //QItemDelegate will always use Qt::EditRole
+ if( role == Qt::EditRole )
+ columnData.insert( Qt::DisplayRole, value );
- int columnToChange = idx.column() ? idx.column() : m_groupedColumn;
- foreach (int originalRow, m_groupHash.value(idx.row())) {
- QModelIndex childIdx = sourceModel()->index(originalRow, columnToChange, m_rootNode);
- if (childIdx.isValid())
- sourceModel()->setData(childIdx, value, role);
- }
- // TODO: we might need to reload the data from the children at this point
+ //and make sure it's stored in the map
+ m_groupMaps[idx.row()].insert( idx.column(), columnData );
- emit dataChanged(idx, idx);
- return true;
+ int columnToChange = idx.column() ? idx.column() : m_groupedColumn;
+ foreach( int originalRow, m_groupHash.value( idx.row() ) )
+ {
+ QModelIndex childIdx = sourceModel()->index( originalRow, columnToChange,
+ m_rootNode );
+ if( childIdx.isValid() )
+ sourceModel()->setData( childIdx, value, role );
}
+ //TODO: we might need to reload the data from the children at this point
- return sourceModel()->setData(mapToSource(idx), value, role);
+ emit dataChanged( idx, idx );
+ return true;
+ }
+
+ return sourceModel()->setData( mapToSource( idx ), value, role );
}
-bool QtGroupingProxy::isGroup(const QModelIndex& index) const {
- int parentCreateIndex = index.internalId();
- if (parentCreateIndex == -1 && index.row() < m_groupMaps.count())
- return true;
- return false;
+bool
+QtGroupingProxy::isGroup( const QModelIndex &index ) const
+{
+ int parentCreateIndex = index.internalId();
+ if( parentCreateIndex == -1 && index.row() < m_groupMaps.count() )
+ return true;
+ return false;
}
-QModelIndex QtGroupingProxy::mapToSource(const QModelIndex& index) const {
- // qDebug() << "mapToSource: " << index;
- if (!index.isValid()) {
- return m_rootNode;
- }
+QModelIndex
+QtGroupingProxy::mapToSource( const QModelIndex &index ) const
+{
+ //qDebug() << "mapToSource: " << index;
+ if( !index.isValid() ) {
+ return m_rootNode;
+ }
- if (isGroup(index)) {
- // qDebug() << "is a group: " << index.data( Qt::DisplayRole ).toString();
- return m_rootNode;
- }
+ if( isGroup( index ) )
+ {
+ //qDebug() << "is a group: " << index.data( Qt::DisplayRole ).toString();
+ return m_rootNode;
+ }
- QModelIndex proxyParent = index.parent();
- // qDebug() << "parent: " << proxyParent;
- QModelIndex originalParent = mapToSource(proxyParent);
- // qDebug() << "originalParent: " << originalParent;
- int originalRow = index.row();
- if (originalParent == m_rootNode) {
- int indexInGroup = index.row();
- if (!proxyParent.isValid())
- indexInGroup -= m_groupMaps.count();
- // qDebug() << "indexInGroup" << indexInGroup;
- QList<int> childRows = m_groupHash.value(proxyParent.row());
- if (childRows.isEmpty() || indexInGroup >= childRows.count() || indexInGroup < 0)
- return QModelIndex();
+ QModelIndex proxyParent = index.parent();
+ //qDebug() << "parent: " << proxyParent;
+ QModelIndex originalParent = mapToSource( proxyParent );
+ //qDebug() << "originalParent: " << originalParent;
+ int originalRow = index.row();
+ if( originalParent == m_rootNode )
+ {
+ int indexInGroup = index.row();
+ if( !proxyParent.isValid() )
+ indexInGroup -= m_groupMaps.count();
+ //qDebug() << "indexInGroup" << indexInGroup;
+ QList<int> childRows = m_groupHash.value( proxyParent.row() );
+ if( childRows.isEmpty() || indexInGroup >= childRows.count() || indexInGroup < 0 )
+ return QModelIndex();
- originalRow = childRows.at(indexInGroup);
- // qDebug() << "originalRow: " << originalRow;
- }
- return sourceModel()->index(originalRow, index.column(), originalParent);
+ originalRow = childRows.at( indexInGroup );
+ //qDebug() << "originalRow: " << originalRow;
+ }
+ return sourceModel()->index( originalRow, index.column(), originalParent );
}
-QModelIndexList QtGroupingProxy::mapToSource(const QModelIndexList& list) const {
- QModelIndexList originalList;
- foreach (const QModelIndex& index, list) {
- QModelIndex originalIndex = mapToSource(index);
- if (originalIndex.isValid())
- originalList << originalIndex;
- }
- return originalList;
+QModelIndexList
+QtGroupingProxy::mapToSource( const QModelIndexList& list ) const
+{
+ QModelIndexList originalList;
+ foreach( const QModelIndex &index, list )
+ {
+ QModelIndex originalIndex = mapToSource( index );
+ if( originalIndex.isValid() )
+ originalList << originalIndex;
+ }
+ return originalList;
}
-QModelIndex QtGroupingProxy::mapFromSource(const QModelIndex& idx) const {
- if (!idx.isValid())
- return QModelIndex();
+QModelIndex
+QtGroupingProxy::mapFromSource( const QModelIndex &idx ) const
+{
+ if( !idx.isValid() )
+ return QModelIndex();
- QModelIndex proxyParent;
- QModelIndex sourceParent = idx.parent();
- // qDebug() << "sourceParent: " << sourceParent;
- int proxyRow = idx.row();
- int sourceRow = idx.row();
+ QModelIndex proxyParent;
+ QModelIndex sourceParent = idx.parent();
+ //qDebug() << "sourceParent: " << sourceParent;
+ int proxyRow = idx.row();
+ int sourceRow = idx.row();
- if (sourceParent.isValid() && (sourceParent != m_rootNode)) {
- // idx is a child of one of the items in the source model
- proxyParent = mapFromSource(sourceParent);
- } else {
- // idx is an item in the top level of the source model (child of the rootnode)
- int groupRow = -1;
- QHashIterator<quint32, QList<int>> iterator(m_groupHash);
- while (iterator.hasNext()) {
- iterator.next();
- if (iterator.value().contains(sourceRow)) {
- groupRow = iterator.key();
- break;
- }
- }
+ if( sourceParent.isValid() && ( sourceParent != m_rootNode ) )
+ {
+ //idx is a child of one of the items in the source model
+ proxyParent = mapFromSource( sourceParent );
+ }
+ else
+ {
+ //idx is an item in the top level of the source model (child of the rootnode)
+ int groupRow = -1;
+ QHashIterator<quint32, QList<int> > iterator( m_groupHash );
+ while( iterator.hasNext() )
+ {
+ iterator.next();
+ if( iterator.value().contains( sourceRow ) )
+ {
+ groupRow = iterator.key();
+ break;
+ }
+ }
- if (groupRow != -1) // it's in a group, let's find the correct row.
- {
- proxyParent = this->index(groupRow, 0, QModelIndex());
- proxyRow = m_groupHash.value(groupRow).indexOf(sourceRow);
- } else {
- proxyParent = QModelIndex();
- // if the proxy item is not in a group it will be below the groups.
- int groupLength = m_groupMaps.count();
- // qDebug() << "groupNames length: " << groupLength;
- int i = m_groupHash.value(std::numeric_limits<quint32>::max()).indexOf(sourceRow);
- // qDebug() << "index in hash: " << i;
- proxyRow = groupLength + i;
- }
+ if( groupRow != -1 ) //it's in a group, let's find the correct row.
+ {
+ proxyParent = this->index( groupRow, 0, QModelIndex() );
+ proxyRow = m_groupHash.value( groupRow ).indexOf( sourceRow );
+ }
+ else
+ {
+ proxyParent = QModelIndex();
+ // if the proxy item is not in a group it will be below the groups.
+ int groupLength = m_groupMaps.count();
+ //qDebug() << "groupNames length: " << groupLength;
+ int i = m_groupHash.value( std::numeric_limits<quint32>::max() ).indexOf( sourceRow );
+ //qDebug() << "index in hash: " << i;
+ proxyRow = groupLength + i;
}
+ }
- // qDebug() << "proxyParent: " << proxyParent;
- // qDebug() << "proxyRow: " << proxyRow;
- return this->index(proxyRow, idx.column(), proxyParent);
+ //qDebug() << "proxyParent: " << proxyParent;
+ //qDebug() << "proxyRow: " << proxyRow;
+ return this->index( proxyRow, idx.column(), proxyParent );
}
-Qt::ItemFlags QtGroupingProxy::flags(const QModelIndex& idx) const {
- if (!idx.isValid()) {
- Qt::ItemFlags rootFlags = sourceModel()->flags(m_rootNode);
- if (rootFlags.testFlag(Qt::ItemIsDropEnabled))
- return Qt::ItemFlags(Qt::ItemIsDropEnabled);
+Qt::ItemFlags
+QtGroupingProxy::flags( const QModelIndex &idx ) const
+{
+ if( !idx.isValid() )
+ {
+ Qt::ItemFlags rootFlags = sourceModel()->flags( m_rootNode );
+ if( rootFlags.testFlag( Qt::ItemIsDropEnabled ) )
+ return Qt::ItemFlags( Qt::ItemIsDropEnabled );
- return 0;
- }
- // only if the grouped column has the editable flag set allow the
- // actions leading to setData on the source (edit & drop)
- // qDebug() << idx;
- if (isGroup(idx)) {
- // dumpGroups();
- Qt::ItemFlags defaultFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
- // Qt::ItemFlags defaultFlags(Qt::ItemIsEnabled);
- bool groupIsEditable = true;
-
- if (idx.column() == 0) {
- bool checkable = true;
- foreach (int originalRow, m_groupHash.value(idx.row())) {
- QModelIndex originalIdx = sourceModel()->index(originalRow, 0, m_rootNode.parent());
- if ((originalIdx.flags() & Qt::ItemIsUserCheckable) == 0) {
- qDebug("row %d is not checkable", originalRow);
- checkable = false;
- }
- }
+ return 0;
+ }
+ //only if the grouped column has the editable flag set allow the
+ //actions leading to setData on the source (edit & drop)
+ // qDebug() << idx;
+ if( isGroup( idx ) )
+ {
+ // dumpGroups();
+ Qt::ItemFlags defaultFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
+ //Qt::ItemFlags defaultFlags(Qt::ItemIsEnabled);
+ bool groupIsEditable = true;
- if (checkable) {
- defaultFlags |= Qt::ItemIsUserCheckable;
- }
+ if (idx.column() == 0) {
+ bool checkable = true;
+ foreach ( int originalRow, m_groupHash.value( idx.row() ) )
+ {
+ QModelIndex originalIdx = sourceModel()->index( originalRow, 0,
+ m_rootNode.parent() );
+ if ( (originalIdx.flags() & Qt::ItemIsUserCheckable) == 0 )
+ {
+ qDebug("row %d is not checkable", originalRow);
+ checkable = false;
}
+ }
- // it's possible to have empty groups
- if (m_groupHash.value(idx.row()).count() == 0) {
- // check the flags of this column with the root node
- QModelIndex originalRootNode = sourceModel()->index(m_rootNode.row(), m_groupedColumn, m_rootNode.parent());
- groupIsEditable = originalRootNode.flags().testFlag(Qt::ItemIsEditable);
- } else {
- foreach (int originalRow, m_groupHash.value(idx.row())) {
- QModelIndex originalIdx = sourceModel()->index(originalRow, m_groupedColumn, m_rootNode);
+ if ( checkable ) {
+ defaultFlags |= Qt::ItemIsUserCheckable;
+ }
+ }
- groupIsEditable = groupIsEditable ? originalIdx.flags().testFlag(Qt::ItemIsEditable) : false;
- if (!groupIsEditable) // all children need to have an editable grouped column
- break;
- }
- }
- if (groupIsEditable)
- return (defaultFlags | Qt::ItemIsEditable | Qt::ItemIsDropEnabled);
- return defaultFlags;
+ //it's possible to have empty groups
+ if( m_groupHash.value( idx.row() ).count() == 0 )
+ {
+ //check the flags of this column with the root node
+ QModelIndex originalRootNode = sourceModel()->index( m_rootNode.row(), m_groupedColumn,
+ m_rootNode.parent() );
+ groupIsEditable = originalRootNode.flags().testFlag( Qt::ItemIsEditable );
+ }
+ else
+ {
+ foreach( int originalRow, m_groupHash.value( idx.row() ) )
+ {
+ QModelIndex originalIdx = sourceModel()->index( originalRow, m_groupedColumn,
+ m_rootNode );
+
+ groupIsEditable = groupIsEditable
+ ? originalIdx.flags().testFlag( Qt::ItemIsEditable )
+ : false;
+ if( !groupIsEditable ) //all children need to have an editable grouped column
+ break;
+ }
}
+ if( groupIsEditable )
+ return ( defaultFlags | Qt::ItemIsEditable | Qt::ItemIsDropEnabled );
+ return defaultFlags;
+ }
- QModelIndex originalIdx = mapToSource(idx);
- Qt::ItemFlags originalItemFlags = sourceModel()->flags(originalIdx);
+ QModelIndex originalIdx = mapToSource( idx );
+ Qt::ItemFlags originalItemFlags = sourceModel()->flags( originalIdx );
- // check the source model to see if the grouped column is editable;
- QModelIndex groupedColumnIndex = sourceModel()->index(originalIdx.row(), m_groupedColumn, originalIdx.parent());
- bool groupIsEditable = sourceModel()->flags(groupedColumnIndex).testFlag(Qt::ItemIsEditable);
+ //check the source model to see if the grouped column is editable;
+ QModelIndex groupedColumnIndex =
+ sourceModel()->index( originalIdx.row(), m_groupedColumn, originalIdx.parent() );
+ bool groupIsEditable = sourceModel()->flags( groupedColumnIndex ).testFlag( Qt::ItemIsEditable );
- if (groupIsEditable)
- return originalItemFlags | Qt::ItemIsDragEnabled;
- return originalItemFlags;
+ if( groupIsEditable )
+ return originalItemFlags | Qt::ItemIsDragEnabled;
+ return originalItemFlags;
}
-QVariant QtGroupingProxy::headerData(int section, Qt::Orientation orientation, int role) const {
- return sourceModel()->headerData(section, orientation, role);
+QVariant
+QtGroupingProxy::headerData( int section, Qt::Orientation orientation, int role ) const
+{
+ return sourceModel()->headerData( section, orientation, role );
}
-bool QtGroupingProxy::canFetchMore(const QModelIndex& parent) const {
- if (!parent.isValid())
- return false;
+bool
+QtGroupingProxy::canFetchMore( const QModelIndex &parent ) const
+{
+ if( !parent.isValid() )
+ return false;
- if (isGroup(parent))
- return false;
+ if( isGroup( parent ) )
+ return false;
- return sourceModel()->canFetchMore(mapToSource(parent));
+ return sourceModel()->canFetchMore( mapToSource( parent ) );
}
-void QtGroupingProxy::fetchMore(const QModelIndex& parent) {
- if (!parent.isValid())
- return;
+void
+QtGroupingProxy::fetchMore ( const QModelIndex & parent )
+{
+ if( !parent.isValid() )
+ return;
- if (isGroup(parent))
- return;
+ if( isGroup( parent ) )
+ return;
- return sourceModel()->fetchMore(mapToSource(parent));
+ return sourceModel()->fetchMore( mapToSource( parent ) );
}
-QModelIndex QtGroupingProxy::addEmptyGroup(const RowData& data) {
- int newRow = m_groupMaps.count();
- beginInsertRows(QModelIndex(), newRow, newRow);
- m_groupMaps << data;
- endInsertRows();
- return index(newRow, 0, QModelIndex());
+QModelIndex
+QtGroupingProxy::addEmptyGroup( const RowData &data )
+{
+ int newRow = m_groupMaps.count();
+ beginInsertRows( QModelIndex(), newRow, newRow );
+ m_groupMaps << data;
+ endInsertRows();
+ return index( newRow, 0, QModelIndex() );
}
-bool QtGroupingProxy::removeGroup(const QModelIndex& idx) {
- beginRemoveRows(idx.parent(), idx.row(), idx.row());
- m_groupHash.remove(idx.row());
- m_groupMaps.removeAt(idx.row());
- m_parentCreateList.removeAt(idx.internalId());
- endRemoveRows();
+bool
+QtGroupingProxy::removeGroup( const QModelIndex &idx )
+{
+ beginRemoveRows( idx.parent(), idx.row(), idx.row() );
+ m_groupHash.remove( idx.row() );
+ m_groupMaps.removeAt( idx.row() );
+ m_parentCreateList.removeAt( idx.internalId() );
+ endRemoveRows();
- // TODO: only true if all data could be unset.
- return true;
+ //TODO: only true if all data could be unset.
+ return true;
}
-bool QtGroupingProxy::hasChildren(const QModelIndex& parent) const {
- if (!parent.isValid()) {
- return true;
- }
+bool
+QtGroupingProxy::hasChildren( const QModelIndex &parent ) const
+{
+ if( !parent.isValid() ) {
+ return true;
+ }
- if (isGroup(parent)) {
- return !m_groupHash.value(parent.row()).isEmpty();
- }
+ if( isGroup( parent ) ) {
+ return !m_groupHash.value( parent.row() ).isEmpty();
+ }
- return sourceModel()->hasChildren(mapToSource(parent));
+ return sourceModel()->hasChildren( mapToSource( parent ) );
}
-bool QtGroupingProxy::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column,
- const QModelIndex& parent) {
- QModelIndex idx = index(row, column, parent);
- if (isGroup(idx)) {
- QList<int> childRows = m_groupHash.value(idx.row());
- int max = *std::max_element(childRows.begin(), childRows.end());
+bool
+QtGroupingProxy::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
+{
+ QModelIndex idx = index(row, column, parent);
+ if (isGroup(idx)) {
+ QList<int> childRows = m_groupHash.value(idx.row());
+ int max = *std::max_element(childRows.begin(), childRows.end());
- QModelIndex newIdx = mapToSource(index(max, column, idx));
- return sourceModel()->dropMimeData(data, action, max, column, newIdx);
+ QModelIndex newIdx = mapToSource(index(max, column, idx));
+ return sourceModel()->dropMimeData(data, action, max, column, newIdx);
+ } else {
+ if (row == -1) {
+ return sourceModel()->dropMimeData(data, action, -1, -1, mapToSource(parent));
} else {
- if (row == -1) {
- return sourceModel()->dropMimeData(data, action, -1, -1, mapToSource(parent));
- } else {
- QModelIndex idx = mapToSource(index(row, column, parent));
- return sourceModel()->dropMimeData(data, action, idx.row(), idx.column(), idx.parent());
- }
+ QModelIndex idx = mapToSource(index(row, column, parent));
+ return sourceModel()->dropMimeData(data, action, idx.row(), idx.column(), idx.parent());
}
+ }
}
-void QtGroupingProxy::modelRowsAboutToBeInserted(const QModelIndex& parent, int start, int end) {
- if (parent != m_rootNode) {
- // an item will be added to an original index, remap and pass it on
- // qDebug() << parent;
- QModelIndex proxyParent = mapFromSource(parent);
- // qDebug() << proxyParent;
- beginInsertRows(proxyParent, start, end);
- }
+void
+QtGroupingProxy::modelRowsAboutToBeInserted( const QModelIndex &parent, int start, int end )
+{
+ if( parent != m_rootNode )
+ {
+ //an item will be added to an original index, remap and pass it on
+ // qDebug() << parent;
+ QModelIndex proxyParent = mapFromSource( parent );
+ // qDebug() << proxyParent;
+ beginInsertRows( proxyParent, start, end );
+ }
}
-void QtGroupingProxy::modelRowsInserted(const QModelIndex& parent, int start, int end) {
- if (parent == m_rootNode) {
- // top level of the model changed, these new rows need to be put in groups
- for (int modelRow = start; modelRow <= end; modelRow++) {
- addSourceRow(sourceModel()->index(modelRow, m_groupedColumn, m_rootNode));
- }
- } else {
- // an item was added to an original index, remap and pass it on
- QModelIndex proxyParent = mapFromSource(parent);
- qDebug() << proxyParent;
- // beginInsertRows had to be called in modelRowsAboutToBeInserted()
- endInsertRows();
+void
+QtGroupingProxy::modelRowsInserted( const QModelIndex &parent, int start, int end )
+{
+ if( parent == m_rootNode )
+ {
+ //top level of the model changed, these new rows need to be put in groups
+ for( int modelRow = start; modelRow <= end ; modelRow++ )
+ {
+ addSourceRow( sourceModel()->index( modelRow, m_groupedColumn, m_rootNode ) );
}
+ }
+ else
+ {
+ //an item was added to an original index, remap and pass it on
+ QModelIndex proxyParent = mapFromSource( parent );
+ qDebug() << proxyParent;
+ //beginInsertRows had to be called in modelRowsAboutToBeInserted()
+ endInsertRows();
+ }
}
-void QtGroupingProxy::modelRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end) {
- if (parent == m_rootNode) {
- QHash<quint32, QList<int>>::const_iterator i;
- // HACK, we are going to call beginRemoveRows() multiple times without
- // endRemoveRows() if a source index is in multiple groups.
- // This can be a problem for some views/proxies, but Q*Views can handle it.
- // TODO: investigate a queue for applying proxy model changes in the correct order
- for (i = m_groupHash.constBegin(); i != m_groupHash.constEnd(); ++i) {
- int groupIndex = i.key();
- const QList<int>& groupList = i.value();
- QModelIndex proxyParent = index(groupIndex, 0);
- foreach (int originalRow, groupList) {
- if (originalRow >= start && originalRow <= end) {
- int proxyRow = groupList.indexOf(originalRow);
- if (groupIndex == -1) // adjust for non-grouped (root level) original items
- proxyRow += m_groupMaps.count();
- // TODO: optimize for continues original rows in the same group
- beginRemoveRows(proxyParent, proxyRow, proxyRow);
- }
- }
+void
+QtGroupingProxy::modelRowsAboutToBeRemoved( const QModelIndex &parent, int start, int end )
+{
+ if( parent == m_rootNode )
+ {
+ QHash<quint32, QList<int> >::const_iterator i;
+ //HACK, we are going to call beginRemoveRows() multiple times without
+ // endRemoveRows() if a source index is in multiple groups.
+ // This can be a problem for some views/proxies, but Q*Views can handle it.
+ // TODO: investigate a queue for applying proxy model changes in the correct order
+ for( i = m_groupHash.constBegin(); i != m_groupHash.constEnd(); ++i )
+ {
+ int groupIndex = i.key();
+ const QList<int> &groupList = i.value();
+ QModelIndex proxyParent = index( groupIndex, 0 );
+ foreach( int originalRow, groupList )
+ {
+ if( originalRow >= start && originalRow <= end )
+ {
+ int proxyRow = groupList.indexOf( originalRow );
+ if( groupIndex == -1 ) //adjust for non-grouped (root level) original items
+ proxyRow += m_groupMaps.count();
+ //TODO: optimize for continues original rows in the same group
+ beginRemoveRows( proxyParent, proxyRow, proxyRow );
}
- } else {
- // child item(s) of an original item will be removed, remap and pass it on
- // qDebug() << parent;
- QModelIndex proxyParent = mapFromSource(parent);
- // qDebug() << proxyParent;
- beginRemoveRows(proxyParent, start, end);
+ }
}
+ }
+ else
+ {
+ //child item(s) of an original item will be removed, remap and pass it on
+ // qDebug() << parent;
+ QModelIndex proxyParent = mapFromSource( parent );
+ // qDebug() << proxyParent;
+ beginRemoveRows( proxyParent, start, end );
+ }
}
-void QtGroupingProxy::modelRowsRemoved(const QModelIndex& parent, int start, int end) {
- if (parent == m_rootNode) {
- // TODO: can be optimised by iterating over m_groupHash and checking start <= r < end
+void
+QtGroupingProxy::modelRowsRemoved( const QModelIndex &parent, int start, int end )
+{
+ if( parent == m_rootNode )
+ {
+ //TODO: can be optimised by iterating over m_groupHash and checking start <= r < end
- // rather than increasing i we change the stored sourceRows in-place and reuse argument start
- // X-times (where X = end - start).
- for (int i = start; i <= end; i++) {
- // HACK: we are going to iterate the hash in reverse so calls to endRemoveRows()
- // are matched up with the beginRemoveRows() in modelRowsAboutToBeRemoved()
- // NOTE: easier to do reverse with java style iterator
- QMutableHashIterator<quint32, QList<int>> iter(m_groupHash);
- iter.toBack();
- while (iter.hasPrevious()) {
- iter.previous();
- int groupIndex = iter.key();
- // has to be a modifiable reference for remove and replace operations
- QList<int>& groupList = iter.value();
- int rowIndex = groupList.indexOf(start);
- if (rowIndex != -1) {
- QModelIndex proxyParent = index(groupIndex, 0);
- groupList.removeAt(rowIndex);
- }
- // Now decrement all source rows that are after the removed row
- for (int j = 0; j < groupList.count(); j++) {
- int sourceRow = groupList.at(j);
- if (sourceRow > start)
- groupList.replace(j, sourceRow - 1);
- }
- if (rowIndex != -1)
- endRemoveRows(); // end remove operation only after group was updated.
- }
+ //rather than increasing i we change the stored sourceRows in-place and reuse argument start
+ //X-times (where X = end - start).
+ for( int i = start; i <= end; i++ )
+ {
+ //HACK: we are going to iterate the hash in reverse so calls to endRemoveRows()
+ // are matched up with the beginRemoveRows() in modelRowsAboutToBeRemoved()
+ //NOTE: easier to do reverse with java style iterator
+ QMutableHashIterator<quint32, QList<int> > iter( m_groupHash );
+ iter.toBack();
+ while( iter.hasPrevious() )
+ {
+ iter.previous();
+ int groupIndex = iter.key();
+ //has to be a modifiable reference for remove and replace operations
+ QList<int> &groupList = iter.value();
+ int rowIndex = groupList.indexOf( start );
+ if( rowIndex != -1 )
+ {
+ QModelIndex proxyParent = index( groupIndex, 0 );
+ groupList.removeAt( rowIndex );
}
-
- return;
+ //Now decrement all source rows that are after the removed row
+ for( int j = 0; j < groupList.count(); j++ )
+ {
+ int sourceRow = groupList.at( j );
+ if( sourceRow > start )
+ groupList.replace( j, sourceRow-1 );
+ }
+ if( rowIndex != -1)
+ endRemoveRows(); //end remove operation only after group was updated.
+ }
}
- // beginRemoveRows had to be called in modelRowsAboutToBeRemoved();
- endRemoveRows();
+ return;
+ }
+
+ //beginRemoveRows had to be called in modelRowsAboutToBeRemoved();
+ endRemoveRows();
}
-void QtGroupingProxy::resetModel() { buildTree(); }
+void
+QtGroupingProxy::resetModel()
+{
+ buildTree();
+}
-void QtGroupingProxy::modelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) {
- // TODO: need to look in the groupedColumn and see if it changed and changed grouping accordingly
- QModelIndex proxyTopLeft = mapFromSource(topLeft);
- if (!proxyTopLeft.isValid())
- return;
+void
+QtGroupingProxy::modelDataChanged( const QModelIndex &topLeft, const QModelIndex &bottomRight )
+{
+ //TODO: need to look in the groupedColumn and see if it changed and changed grouping accordingly
+ QModelIndex proxyTopLeft = mapFromSource( topLeft );
+ if( !proxyTopLeft.isValid() )
+ return;
- if (topLeft == bottomRight) {
- emit dataChanged(proxyTopLeft, proxyTopLeft);
- } else {
- QModelIndex proxyBottomRight = mapFromSource(bottomRight);
- emit dataChanged(proxyTopLeft, proxyBottomRight);
- }
+ if( topLeft == bottomRight )
+ {
+ emit dataChanged( proxyTopLeft, proxyTopLeft );
+ }
+ else
+ {
+ QModelIndex proxyBottomRight = mapFromSource( bottomRight );
+ emit dataChanged( proxyTopLeft, proxyBottomRight );
+ }
}
-bool QtGroupingProxy::isAGroupSelected(const QModelIndexList& list) const {
- foreach (const QModelIndex& index, list) {
- if (isGroup(index))
- return true;
- }
- return false;
+bool
+QtGroupingProxy::isAGroupSelected( const QModelIndexList& list ) const
+{
+ foreach( const QModelIndex &index, list )
+ {
+ if( isGroup( index ) )
+ return true;
+ }
+ return false;
}
-void QtGroupingProxy::dumpGroups() const {
- qDebug() << "m_groupHash: ";
- for (int groupIndex = -1; groupIndex < m_groupHash.keys().count() - 1; groupIndex++) {
- qDebug() << groupIndex << " : " << m_groupHash.value(groupIndex);
- }
+void
+QtGroupingProxy::dumpGroups() const
+{
+ qDebug() << "m_groupHash: ";
+ for( int groupIndex = -1; groupIndex < m_groupHash.keys().count() - 1; groupIndex++ )
+ {
+ qDebug() << groupIndex << " : " << m_groupHash.value( groupIndex );
+ }
- qDebug() << "m_groupMaps: ";
- for (int groupIndex = 0; groupIndex < m_groupMaps.count(); groupIndex++)
- qDebug() << m_groupMaps[groupIndex] << ": " << m_groupHash.value(groupIndex);
- qDebug() << m_groupHash.value(std::numeric_limits<quint32>::max());
+ qDebug() << "m_groupMaps: ";
+ for( int groupIndex = 0; groupIndex < m_groupMaps.count(); groupIndex++ )
+ qDebug() << m_groupMaps[groupIndex] << ": " << m_groupHash.value( groupIndex );
+ qDebug() << m_groupHash.value( std::numeric_limits<quint32>::max() );
}
-void QtGroupingProxy::expanded(const QModelIndex& index) {
- m_expandedItems.insert(index.data(Qt::UserRole).toString());
+
+void QtGroupingProxy::expanded(const QModelIndex &index)
+{
+ m_expandedItems.insert(index.data(Qt::UserRole).toString());
}
-void QtGroupingProxy::collapsed(const QModelIndex& index) {
- m_expandedItems.remove(index.data(Qt::UserRole).toString());
+void QtGroupingProxy::collapsed(const QModelIndex &index)
+{
+ m_expandedItems.remove(index.data(Qt::UserRole).toString());
}
diff --git a/src/qtgroupingproxy.h b/src/qtgroupingproxy.h
index 1f166265..6567cb0e 100644
--- a/src/qtgroupingproxy.h
+++ b/src/qtgroupingproxy.h
@@ -20,143 +20,150 @@
#define GROUPINGPROXY_H
#include <QAbstractProxyModel>
-#include <QIcon>
#include <QModelIndex>
#include <QMultiHash>
-#include <QSet>
#include <QStringList>
+#include <QIcon>
+#include <QSet>
typedef QMap<int, QVariant> ItemData;
typedef QMap<int, ItemData> RowData;
-class QtGroupingProxy : public QAbstractProxyModel {
- Q_OBJECT
+class QtGroupingProxy : public QAbstractProxyModel
+{
+ Q_OBJECT
public:
- static const unsigned int FLAG_NOSINGLE = 1;
- static const unsigned int FLAG_NOGROUPNAME = 2;
- enum EAggregateFunction {
- AGGR_NONE, // no aggregation, return child elements as list
- AGGR_EMPTY, // display nothing
- AGGR_FIRST, // return value of the topmost item
- AGGR_MAX, // return maximum value
- AGGR_MIN // return minimum value
- };
+ static const unsigned int FLAG_NOSINGLE = 1;
+ static const unsigned int FLAG_NOGROUPNAME = 2;
+
+ enum EAggregateFunction {
+ AGGR_NONE, // no aggregation, return child elements as list
+ AGGR_EMPTY, // display nothing
+ AGGR_FIRST, // return value of the topmost item
+ AGGR_MAX, // return maximum value
+ AGGR_MIN // return minimum value
+ };
public:
- explicit QtGroupingProxy(QAbstractItemModel* model, QModelIndex rootNode = QModelIndex(), int groupedColumn = -1,
- int groupedRole = Qt::DisplayRole, unsigned int flags = 0,
- int aggregateRole = Qt::DisplayRole);
- ~QtGroupingProxy();
+ explicit QtGroupingProxy( QAbstractItemModel *model, QModelIndex rootNode = QModelIndex(),
+ int groupedColumn = -1, int groupedRole = Qt::DisplayRole,
+ unsigned int flags = 0,
+ int aggregateRole = Qt::DisplayRole);
+ ~QtGroupingProxy();
- void setGroupedColumn(int groupedColumn);
+ void setGroupedColumn( int groupedColumn );
- /* QAbstractProxyModel methods */
- virtual QModelIndex index(int, int c = 0, const QModelIndex& parent = QModelIndex()) const;
- virtual Qt::ItemFlags flags(const QModelIndex& idx) const;
- virtual QModelIndex parent(const QModelIndex& idx) const;
- virtual int rowCount(const QModelIndex& idx = QModelIndex()) const;
- virtual int columnCount(const QModelIndex& idx) const;
- virtual QModelIndex mapToSource(const QModelIndex& idx) const;
- virtual QModelIndexList mapToSource(const QModelIndexList& list) const;
- virtual QModelIndex mapFromSource(const QModelIndex& idx) const;
- virtual QVariant data(const QModelIndex& idx, int role) const;
- virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
- virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
- virtual bool canFetchMore(const QModelIndex& parent) const;
- virtual void fetchMore(const QModelIndex& parent);
- virtual bool hasChildren(const QModelIndex& parent = QModelIndex()) const;
- virtual bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column,
- const QModelIndex& parent);
+ /* QAbstractProxyModel methods */
+ virtual QModelIndex index( int, int c = 0,
+ const QModelIndex& parent = QModelIndex() ) const;
+ virtual Qt::ItemFlags flags( const QModelIndex &idx ) const;
+ virtual QModelIndex parent( const QModelIndex &idx ) const;
+ virtual int rowCount( const QModelIndex &idx = QModelIndex() ) const;
+ virtual int columnCount( const QModelIndex &idx ) const;
+ virtual QModelIndex mapToSource( const QModelIndex &idx ) const;
+ virtual QModelIndexList mapToSource( const QModelIndexList &list ) const;
+ virtual QModelIndex mapFromSource( const QModelIndex &idx ) const;
+ virtual QVariant data( const QModelIndex &idx, int role ) const;
+ virtual bool setData( const QModelIndex &index, const QVariant &value,
+ int role = Qt::EditRole );
+ virtual QVariant headerData ( int section, Qt::Orientation orientation,
+ int role ) const;
+ virtual bool canFetchMore( const QModelIndex &parent ) const;
+ virtual void fetchMore( const QModelIndex &parent );
+ virtual bool hasChildren( const QModelIndex &parent = QModelIndex() ) const;
+ virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
- /* QtGroupingProxy methods */
- virtual QModelIndex addEmptyGroup(const RowData& data);
- virtual bool removeGroup(const QModelIndex& idx);
+ /* QtGroupingProxy methods */
+ virtual QModelIndex addEmptyGroup( const RowData &data );
+ virtual bool removeGroup( const QModelIndex &idx );
- QStringList expandedState();
+ QStringList expandedState();
signals:
- void expandItem(const QModelIndex& index);
+ void expandItem(const QModelIndex &index);
public slots:
- /**
- * @brief update expanded state
- * @param index index of the expanded/collapsed item (from the base model!)
- */
- void expanded(const QModelIndex& index);
- /**
- * @brief update expanded state
- * @param index index of the expanded/collapsed item (from the base model!)
- */
- void collapsed(const QModelIndex& index);
+ /**
+ * @brief update expanded state
+ * @param index index of the expanded/collapsed item (from the base model!)
+ */
+ void expanded(const QModelIndex &index);
+ /**
+ * @brief update expanded state
+ * @param index index of the expanded/collapsed item (from the base model!)
+ */
+ void collapsed(const QModelIndex &index);
protected slots:
- virtual void buildTree();
+ virtual void buildTree();
private slots:
- void modelDataChanged(const QModelIndex&, const QModelIndex&);
- void modelRowsAboutToBeInserted(const QModelIndex&, int, int);
- void modelRowsInserted(const QModelIndex&, int, int);
- void modelRowsAboutToBeRemoved(const QModelIndex&, int, int);
- void modelRowsRemoved(const QModelIndex&, int, int);
- void resetModel();
+ void modelDataChanged( const QModelIndex &, const QModelIndex & );
+ void modelRowsAboutToBeInserted( const QModelIndex &, int ,int );
+ void modelRowsInserted( const QModelIndex &, int, int );
+ void modelRowsAboutToBeRemoved( const QModelIndex &, int ,int );
+ void modelRowsRemoved( const QModelIndex &, int, int );
+ void resetModel();
protected:
- /** Maps an item to a group.
- * The return value is a list because an item can put in multiple groups.
- * Inside the list is a 2 dimensional map.
- * Mapped to column-number is another map of role-number to QVariant.
- * This data prepolulates the group-data cache. The rest is gathered on demand
- * from the children of the group.
- */
- virtual QList<RowData> belongsTo(const QModelIndex& idx);
+ /** Maps an item to a group.
+ * The return value is a list because an item can put in multiple groups.
+ * Inside the list is a 2 dimensional map.
+ * Mapped to column-number is another map of role-number to QVariant.
+ * This data prepolulates the group-data cache. The rest is gathered on demand
+ * from the children of the group.
+ */
+ virtual QList<RowData> belongsTo( const QModelIndex &idx );
- /**
- * calls belongsTo(), checks cached data and adds the index to existing or new groups.
- * @returns the groups this index was added to where -1 means it was added to the root.
- */
- QList<int> addSourceRow(const QModelIndex& idx);
+ /**
+ * calls belongsTo(), checks cached data and adds the index to existing or new groups.
+ * @returns the groups this index was added to where -1 means it was added to the root.
+ */
+ QList<int> addSourceRow( const QModelIndex &idx );
- bool isGroup(const QModelIndex& index) const;
- bool isAGroupSelected(const QModelIndexList& list) const;
+ bool isGroup( const QModelIndex &index ) const;
+ bool isAGroupSelected( const QModelIndexList &list ) const;
- /** Maintains the group -> sourcemodel row mapping
- * The reason a QList<int> is use instead of a QMultiHash is that the values have to be
- * reordered when rows are inserted or removed.
- * TODO:use some auto-incrementing container class (steveire's?) for the list
- */
- QHash<quint32, QList<int>> m_groupHash;
- /** The data cache of the groups.
- * This can be pre-loaded with data in belongsTo()
- */
- QList<RowData> m_groupMaps;
+ /** Maintains the group -> sourcemodel row mapping
+ * The reason a QList<int> is use instead of a QMultiHash is that the values have to be
+ * reordered when rows are inserted or removed.
+ * TODO:use some auto-incrementing container class (steveire's?) for the list
+ */
+ QHash<quint32, QList<int> > m_groupHash;
+ /** The data cache of the groups.
+ * This can be pre-loaded with data in belongsTo()
+ */
+ QList<RowData> m_groupMaps;
- /** "instuctions" how to create an item in the tree.
- * This is used by parent( QModelIndex )
- */
- struct ParentCreate {
- int parentCreateIndex;
- int row;
- };
- mutable QList<struct ParentCreate> m_parentCreateList;
- /** @returns index of the "instructions" to recreate the parent. Will create new if it doesn't exist yet.
- */
- int indexOfParentCreate(const QModelIndex& parent) const;
+ /** "instuctions" how to create an item in the tree.
+ * This is used by parent( QModelIndex )
+ */
+ struct ParentCreate
+ {
+ int parentCreateIndex;
+ int row;
+ };
+ mutable QList<struct ParentCreate> m_parentCreateList;
+ /** @returns index of the "instructions" to recreate the parent. Will create new if it doesn't exist yet.
+ */
+ int indexOfParentCreate( const QModelIndex &parent ) const;
- QModelIndexList m_selectedGroups;
+ QModelIndexList m_selectedGroups;
- QModelIndex m_rootNode;
- int m_groupedColumn;
+ QModelIndex m_rootNode;
+ int m_groupedColumn;
- /* debug function */
- void dumpGroups() const;
+ /* debug function */
+ void dumpGroups() const;
private:
- QSet<QString> m_expandedItems;
- unsigned int m_flags;
- int m_groupedRole;
+ QSet<QString> m_expandedItems;
+ unsigned int m_flags;
+ int m_groupedRole;
+
+ int m_aggregateRole;
- int m_aggregateRole;
};
-#endif // GROUPINGPROXY_H
+#endif //GROUPINGPROXY_H
diff --git a/src/queryoverwritedialog.cpp b/src/queryoverwritedialog.cpp
index 1cc92a01..932b2637 100644
--- a/src/queryoverwritedialog.cpp
+++ b/src/queryoverwritedialog.cpp
@@ -20,31 +20,46 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "queryoverwritedialog.h"
#include "ui_queryoverwritedialog.h"
-QueryOverwriteDialog::QueryOverwriteDialog(QWidget* parent, Backup b)
- : QDialog(parent), ui(new Ui::QueryOverwriteDialog), m_Action(ACT_NONE) {
- ui->setupUi(this);
- ui->backupBox->setChecked(b == BACKUP_YES);
- QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxQuestion);
- ui->iconLabel->setPixmap(icon.pixmap(128));
+QueryOverwriteDialog::QueryOverwriteDialog(QWidget *parent, Backup b)
+ : QDialog(parent), ui(new Ui::QueryOverwriteDialog),
+ m_Action(ACT_NONE)
+{
+ ui->setupUi(this);
+ ui->backupBox->setChecked(b == BACKUP_YES);
+ QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxQuestion);
+ ui->iconLabel->setPixmap(icon.pixmap(128));
+
}
-QueryOverwriteDialog::~QueryOverwriteDialog() { delete ui; }
+QueryOverwriteDialog::~QueryOverwriteDialog()
+{
+ delete ui;
+}
-bool QueryOverwriteDialog::backup() const { return ui->backupBox->isChecked(); }
+bool QueryOverwriteDialog::backup() const
+{
+ return ui->backupBox->isChecked();
+}
-void QueryOverwriteDialog::on_mergeBtn_clicked() {
- this->m_Action = ACT_MERGE;
- this->accept();
+void QueryOverwriteDialog::on_mergeBtn_clicked()
+{
+ this->m_Action = ACT_MERGE;
+ this->accept();
}
-void QueryOverwriteDialog::on_replaceBtn_clicked() {
- this->m_Action = ACT_REPLACE;
- this->accept();
+void QueryOverwriteDialog::on_replaceBtn_clicked()
+{
+ this->m_Action = ACT_REPLACE;
+ this->accept();
}
-void QueryOverwriteDialog::on_renameBtn_clicked() {
- this->m_Action = ACT_RENAME;
- this->accept();
+void QueryOverwriteDialog::on_renameBtn_clicked()
+{
+ this->m_Action = ACT_RENAME;
+ this->accept();
}
-void QueryOverwriteDialog::on_cancelBtn_clicked() { this->reject(); }
+void QueryOverwriteDialog::on_cancelBtn_clicked()
+{
+ this->reject();
+}
diff --git a/src/queryoverwritedialog.h b/src/queryoverwritedialog.h
index 519e108f..3f7b3194 100644
--- a/src/queryoverwritedialog.h
+++ b/src/queryoverwritedialog.h
@@ -26,27 +26,36 @@ namespace Ui {
class QueryOverwriteDialog;
}
-class QueryOverwriteDialog : public QDialog {
- Q_OBJECT
+class QueryOverwriteDialog : public QDialog
+{
+ Q_OBJECT
public:
- enum Action { ACT_NONE, ACT_MERGE, ACT_REPLACE, ACT_RENAME };
+ enum Action {
+ ACT_NONE,
+ ACT_MERGE,
+ ACT_REPLACE,
+ ACT_RENAME
+ };
- enum Backup { BACKUP_NO, BACKUP_YES };
+ enum Backup {
+ BACKUP_NO,
+ BACKUP_YES
+ };
public:
- QueryOverwriteDialog(QWidget* parent, Backup b);
- ~QueryOverwriteDialog();
- bool backup() const;
- Action action() const { return m_Action; }
+ QueryOverwriteDialog(QWidget *parent, Backup b);
+ ~QueryOverwriteDialog();
+ bool backup() const;
+ Action action() const { return m_Action; }
private slots:
- void on_mergeBtn_clicked();
- void on_replaceBtn_clicked();
- void on_renameBtn_clicked();
- void on_cancelBtn_clicked();
+ void on_mergeBtn_clicked();
+ void on_replaceBtn_clicked();
+ void on_renameBtn_clicked();
+ void on_cancelBtn_clicked();
private:
- Ui::QueryOverwriteDialog* ui;
- Action m_Action;
+ Ui::QueryOverwriteDialog *ui;
+ Action m_Action;
};
#endif // QUERYOVERWRITEDIALOG_H
diff --git a/src/savetextasdialog.cpp b/src/savetextasdialog.cpp
index eb455143..8f0095d8 100644
--- a/src/savetextasdialog.cpp
+++ b/src/savetextasdialog.cpp
@@ -1,36 +1,50 @@
#include "savetextasdialog.h"
#include "ui_savetextasdialog.h"
+#include <report.h>
#include <QClipboard>
#include <QFileDialog>
-#include <report.h>
+
using MOBase::reportError;
-SaveTextAsDialog::SaveTextAsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::SaveTextAsDialog) {
- ui->setupUi(this);
-}
-SaveTextAsDialog::~SaveTextAsDialog() { delete ui; }
+SaveTextAsDialog::SaveTextAsDialog(QWidget *parent)
+ : QDialog(parent), ui(new Ui::SaveTextAsDialog)
+{
+ ui->setupUi(this);
+}
-void SaveTextAsDialog::setText(const QString& text) { ui->textEdit->setPlainText(text); }
+SaveTextAsDialog::~SaveTextAsDialog()
+{
+ delete ui;
+}
-void SaveTextAsDialog::on_closeBtn_clicked() { this->close(); }
+void SaveTextAsDialog::setText(const QString &text)
+{
+ ui->textEdit->setPlainText(text);
+}
-void SaveTextAsDialog::on_clipboardBtn_clicked() {
- QClipboard* clipboard = QApplication::clipboard();
- clipboard->setText(ui->textEdit->toPlainText());
+void SaveTextAsDialog::on_closeBtn_clicked()
+{
+ this->close();
}
-void SaveTextAsDialog::on_saveAsBtn_clicked() {
- QString fileName =
- QFileDialog::getSaveFileName(this, tr("Save CSV"), QString(), tr("Text Files") + " (*.txt *.csv)");
- if (!fileName.isEmpty()) {
- QFile file(fileName);
- if (!file.open(QIODevice::WriteOnly)) {
- reportError(tr("failed to open \"%1\" for writing").arg(fileName));
- return;
- }
+void SaveTextAsDialog::on_clipboardBtn_clicked()
+{
+ QClipboard *clipboard = QApplication::clipboard();
+ clipboard->setText(ui->textEdit->toPlainText());
+}
- file.write(ui->textEdit->toPlainText().toUtf8());
+void SaveTextAsDialog::on_saveAsBtn_clicked()
+{
+ QString fileName = QFileDialog::getSaveFileName(this, tr("Save CSV"), QString(), tr("Text Files") + " (*.txt *.csv)");
+ if (!fileName.isEmpty()) {
+ QFile file(fileName);
+ if (!file.open(QIODevice::WriteOnly)) {
+ reportError(tr("failed to open \"%1\" for writing").arg(fileName));
+ return;
}
+
+ file.write(ui->textEdit->toPlainText().toUtf8());
+ }
}
diff --git a/src/savetextasdialog.h b/src/savetextasdialog.h
index ee5cc89b..1a17a2db 100644
--- a/src/savetextasdialog.h
+++ b/src/savetextasdialog.h
@@ -7,24 +7,25 @@ namespace Ui {
class SaveTextAsDialog;
}
-class SaveTextAsDialog : public QDialog {
- Q_OBJECT
-
+class SaveTextAsDialog : public QDialog
+{
+ Q_OBJECT
+
public:
- explicit SaveTextAsDialog(QWidget* parent = 0);
- ~SaveTextAsDialog();
+ explicit SaveTextAsDialog(QWidget *parent = 0);
+ ~SaveTextAsDialog();
- void setText(const QString& text);
+ void setText(const QString &text);
private slots:
- void on_closeBtn_clicked();
+ void on_closeBtn_clicked();
- void on_clipboardBtn_clicked();
+ void on_clipboardBtn_clicked();
- void on_saveAsBtn_clicked();
+ void on_saveAsBtn_clicked();
private:
- Ui::SaveTextAsDialog* ui;
+ Ui::SaveTextAsDialog *ui;
};
#endif // SAVETEXTASDIALOG_H
diff --git a/src/selectiondialog.cpp b/src/selectiondialog.cpp
index 4f582fd7..55728751 100644
--- a/src/selectiondialog.cpp
+++ b/src/selectiondialog.cpp
@@ -22,63 +22,80 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QCommandLinkButton>
-SelectionDialog::SelectionDialog(const QString& description, QWidget* parent, const QSize& iconSize)
- : QDialog(parent), ui(new Ui::SelectionDialog), m_Choice(nullptr), m_ValidateByData(false), m_IconSize(iconSize) {
- ui->setupUi(this);
+SelectionDialog::SelectionDialog(const QString &description, QWidget *parent, const QSize &iconSize)
+ : QDialog(parent), ui(new Ui::SelectionDialog), m_Choice(nullptr), m_ValidateByData(false), m_IconSize(iconSize)
+{
+ ui->setupUi(this);
- ui->descriptionLabel->setText(description);
+ ui->descriptionLabel->setText(description);
}
-SelectionDialog::~SelectionDialog() { delete ui; }
+SelectionDialog::~SelectionDialog()
+{
+ delete ui;
+}
-void SelectionDialog::addChoice(const QString& buttonText, const QString& description, const QVariant& data) {
- QAbstractButton* button = new QCommandLinkButton(buttonText, description, ui->buttonBox);
- if (m_IconSize.isValid()) {
- button->setIconSize(m_IconSize);
- }
- button->setProperty("data", data);
- ui->buttonBox->addButton(button, QDialogButtonBox::AcceptRole);
- if (data.isValid())
- m_ValidateByData = true;
+void SelectionDialog::addChoice(const QString &buttonText, const QString &description, const QVariant &data)
+{
+ QAbstractButton *button = new QCommandLinkButton(buttonText, description, ui->buttonBox);
+ if (m_IconSize.isValid()) {
+ button->setIconSize(m_IconSize);
+ }
+ button->setProperty("data", data);
+ ui->buttonBox->addButton(button, QDialogButtonBox::AcceptRole);
+ if (data.isValid()) m_ValidateByData = true;
}
-void SelectionDialog::addChoice(const QIcon& icon, const QString& buttonText, const QString& description,
- const QVariant& data) {
- QAbstractButton* button = new QCommandLinkButton(buttonText, description, ui->buttonBox);
- if (m_IconSize.isValid()) {
- button->setIconSize(m_IconSize);
- }
- button->setIcon(icon);
- button->setProperty("data", data);
- ui->buttonBox->addButton(button, QDialogButtonBox::AcceptRole);
- if (data.isValid())
- m_ValidateByData = true;
+void SelectionDialog::addChoice(const QIcon &icon, const QString &buttonText, const QString &description, const QVariant &data)
+{
+ QAbstractButton *button = new QCommandLinkButton(buttonText, description, ui->buttonBox);
+ if (m_IconSize.isValid()) {
+ button->setIconSize(m_IconSize);
+ }
+ button->setIcon(icon);
+ button->setProperty("data", data);
+ ui->buttonBox->addButton(button, QDialogButtonBox::AcceptRole);
+ if (data.isValid()) m_ValidateByData = true;
}
-int SelectionDialog::numChoices() const { return ui->buttonBox->findChildren<QCommandLinkButton*>(QString()).count(); }
+int SelectionDialog::numChoices() const
+{
+ return ui->buttonBox->findChildren<QCommandLinkButton*>(QString()).count();
+}
-QVariant SelectionDialog::getChoiceData() { return m_Choice->property("data"); }
+QVariant SelectionDialog::getChoiceData()
+{
+ return m_Choice->property("data");
+}
-QString SelectionDialog::getChoiceString() {
- if ((m_Choice == nullptr) || (m_ValidateByData && !m_Choice->property("data").isValid())) {
- return QString();
- } else {
- return m_Choice->text();
- }
+
+QString SelectionDialog::getChoiceString()
+{
+ if ((m_Choice == nullptr) ||
+ (m_ValidateByData && !m_Choice->property("data").isValid())) {
+ return QString();
+ } else {
+ return m_Choice->text();
+ }
}
-void SelectionDialog::disableCancel() {
- ui->cancelButton->setEnabled(false);
- ui->cancelButton->setHidden(true);
+void SelectionDialog::disableCancel()
+{
+ ui->cancelButton->setEnabled(false);
+ ui->cancelButton->setHidden(true);
}
-void SelectionDialog::on_buttonBox_clicked(QAbstractButton* button) {
- m_Choice = button;
- if (!m_ValidateByData || m_Choice->property("data").isValid()) {
- this->accept();
- } else {
- this->reject();
- }
+void SelectionDialog::on_buttonBox_clicked(QAbstractButton *button)
+{
+ m_Choice = button;
+ if (!m_ValidateByData || m_Choice->property("data").isValid()) {
+ this->accept();
+ } else {
+ this->reject();
+ }
}
-void SelectionDialog::on_cancelButton_clicked() { this->reject(); }
+void SelectionDialog::on_cancelButton_clicked()
+{
+ this->reject();
+}
diff --git a/src/selectiondialog.h b/src/selectiondialog.h
index 3f066707..3c4b25df 100644
--- a/src/selectiondialog.h
+++ b/src/selectiondialog.h
@@ -20,50 +20,54 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef SELECTIONDIALOG_H
#define SELECTIONDIALOG_H
-#include <QAbstractButton>
#include <QDialog>
+#include <QAbstractButton>
namespace Ui {
class SelectionDialog;
}
-class SelectionDialog : public QDialog {
- Q_OBJECT
-
+class SelectionDialog : public QDialog
+{
+ Q_OBJECT
+
public:
- explicit SelectionDialog(const QString& description, QWidget* parent = 0, const QSize& iconSize = QSize());
- ~SelectionDialog();
+ explicit SelectionDialog(const QString &description, QWidget *parent = 0, const QSize &iconSize = QSize());
- /**
- * @brief add a choice to the dialog
- * @param buttonText the text to be displayed on the button
- * @param description the description that shows up under in small letters inside the button
- * @param data data to be stored with the button. Please note that as soon as one choice has data associated with it
- * (non-invalid QVariant) all buttons that contain no data will be treated as "cancel" buttons
- */
- void addChoice(const QString& buttonText, const QString& description, const QVariant& data);
+ ~SelectionDialog();
- void addChoice(const QIcon& icon, const QString& buttonText, const QString& description, const QVariant& data);
+ /**
+ * @brief add a choice to the dialog
+ * @param buttonText the text to be displayed on the button
+ * @param description the description that shows up under in small letters inside the button
+ * @param data data to be stored with the button. Please note that as soon as one choice has data associated with it (non-invalid QVariant)
+ * all buttons that contain no data will be treated as "cancel" buttons
+ */
+ void addChoice(const QString &buttonText, const QString &description, const QVariant &data);
- int numChoices() const;
+ void addChoice(const QIcon &icon, const QString &buttonText, const QString &description, const QVariant &data);
- QVariant getChoiceData();
- QString getChoiceString();
+ int numChoices() const;
- void disableCancel();
+ QVariant getChoiceData();
+ QString getChoiceString();
+
+ void disableCancel();
private slots:
- void on_buttonBox_clicked(QAbstractButton* button);
+ void on_buttonBox_clicked(QAbstractButton *button);
- void on_cancelButton_clicked();
+ void on_cancelButton_clicked();
private:
- Ui::SelectionDialog* ui;
- QAbstractButton* m_Choice;
- bool m_ValidateByData;
- QSize m_IconSize;
+
+ Ui::SelectionDialog *ui;
+ QAbstractButton *m_Choice;
+ bool m_ValidateByData;
+ QSize m_IconSize;
+
};
#endif // SELECTIONDIALOG_H
diff --git a/src/selfupdater.cpp b/src/selfupdater.cpp
index 3cf0d5cb..273e9b45 100644
--- a/src/selfupdater.cpp
+++ b/src/selfupdater.cpp
@@ -20,21 +20,20 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "selfupdater.h"
#include "archive.h"
-#include "bbcode.h"
#include "callback.h"
-#include "downloadmanager.h"
+#include "utility.h"
#include "installationmanager.h"
#include "iplugingame.h"
#include "messagedialog.h"
+#include "downloadmanager.h"
#include "nexusinterface.h"
#include "nxmaccessmanager.h"
#include "settings.h"
-#include "utility.h"
+#include "bbcode.h"
+#include <versioninfo.h>
#include <report.h>
#include <util.h>
-#include <versioninfo.h>
-#include <QAbstractButton>
#include <QApplication>
#include <QCoreApplication>
#include <QDir>
@@ -42,8 +41,8 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QLibrary>
#include <QMessageBox>
#include <QNetworkAccessManager>
-#include <QNetworkReply>
#include <QNetworkRequest>
+#include <QNetworkReply>
#include <QProcess>
#include <QProgressDialog>
#include <QRegExp>
@@ -52,10 +51,11 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QUrl>
#include <QVariantList>
#include <QVariantMap>
+#include <QAbstractButton>
#include <Qt>
-#include <QtAlgorithms>
#include <QtDebug>
+#include <QtAlgorithms>
#include <boost/bind.hpp>
@@ -69,231 +69,279 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
using namespace MOBase;
using namespace MOShared;
+
typedef Archive* (*CreateArchiveType)();
-template <typename T>
-static T resolveFunction(QLibrary& lib, const char* name) {
- T temp = reinterpret_cast<T>(lib.resolve(name));
- if (temp == nullptr) {
- throw std::runtime_error(QObject::tr("invalid 7-zip32.dll: %1").arg(lib.errorString()).toLatin1().constData());
- }
- return temp;
+
+template <typename T> static T resolveFunction(QLibrary &lib, const char *name)
+{
+ T temp = reinterpret_cast<T>(lib.resolve(name));
+ if (temp == nullptr) {
+ throw std::runtime_error(QObject::tr("invalid 7-zip32.dll: %1").arg(lib.errorString()).toLatin1().constData());
+ }
+ return temp;
}
-SelfUpdater::SelfUpdater(NexusInterface* nexusInterface)
- : m_Parent(nullptr), m_Interface(nexusInterface), m_Reply(nullptr), m_Attempts(3) {
- QLibrary archiveLib(QCoreApplication::applicationDirPath() + "\\dlls\\archive.dll");
- if (!archiveLib.load()) {
- throw MyException(tr("archive.dll not loaded: \"%1\"").arg(archiveLib.errorString()));
- }
- CreateArchiveType CreateArchiveFunc = resolveFunction<CreateArchiveType>(archiveLib, "CreateArchive");
+SelfUpdater::SelfUpdater(NexusInterface *nexusInterface)
+ : m_Parent(nullptr)
+ , m_Interface(nexusInterface)
+ , m_Reply(nullptr)
+ , m_Attempts(3)
+{
+ QLibrary archiveLib(QCoreApplication::applicationDirPath() + "\\dlls\\archive.dll");
+ if (!archiveLib.load()) {
+ throw MyException(tr("archive.dll not loaded: \"%1\"").arg(archiveLib.errorString()));
+ }
- m_ArchiveHandler = CreateArchiveFunc();
- if (!m_ArchiveHandler->isValid()) {
- throw MyException(InstallationManager::getErrorString(m_ArchiveHandler->getLastError()));
- }
+ CreateArchiveType CreateArchiveFunc = resolveFunction<CreateArchiveType>(archiveLib, "CreateArchive");
- VS_FIXEDFILEINFO version = GetFileVersion(ToWString(QApplication::applicationFilePath()));
+ m_ArchiveHandler = CreateArchiveFunc();
+ if (!m_ArchiveHandler->isValid()) {
+ throw MyException(InstallationManager::getErrorString(m_ArchiveHandler->getLastError()));
+ }
- m_MOVersion = VersionInfo(version.dwFileVersionMS >> 16, version.dwFileVersionMS & 0xFFFF,
- version.dwFileVersionLS >> 16, version.dwFileVersionLS & 0xFFFF);
+ VS_FIXEDFILEINFO version = GetFileVersion(ToWString(QApplication::applicationFilePath()));
+
+ m_MOVersion = VersionInfo(version.dwFileVersionMS >> 16,
+ version.dwFileVersionMS & 0xFFFF,
+ version.dwFileVersionLS >> 16,
+ version.dwFileVersionLS & 0xFFFF);
}
-SelfUpdater::~SelfUpdater() { delete m_ArchiveHandler; }
-void SelfUpdater::setUserInterface(QWidget* widget) { m_Parent = widget; }
+SelfUpdater::~SelfUpdater()
+{
+ delete m_ArchiveHandler;
+}
-void SelfUpdater::testForUpdate() {
- // TODO: if prereleases are disabled we could just request the latest release
- // directly
- try {
- m_GitHub.releases(GitHub::Repository("LePresidente", "modorganizer"), [this](const QJsonArray& releases) {
- QJsonObject newest;
- for (const QJsonValue& releaseVal : releases) {
- QJsonObject release = releaseVal.toObject();
- if (!release["draft"].toBool() &&
- (Settings::instance().usePrereleases() || !release["prerelease"].toBool())) {
- if (newest.empty() ||
- (VersionInfo(release["tag_name"].toString()) > VersionInfo(newest["tag_name"].toString()))) {
- newest = release;
- }
- }
- }
+void SelfUpdater::setUserInterface(QWidget *widget)
+{
+ m_Parent = widget;
+}
- if (!newest.empty()) {
- VersionInfo newestVer(newest["tag_name"].toString());
- if (newestVer > this->m_MOVersion) {
- m_UpdateCandidate = newest;
- qDebug("update available: %s -> %s", qPrintable(this->m_MOVersion.displayString()),
- qPrintable(newestVer.displayString()));
- emit updateAvailable();
- } else if (newestVer < this->m_MOVersion) {
- // this could happen if the user switches from using prereleases to
- // stable builds. Should we downgrade?
- qDebug("this version is newer than the newest installed one: %s -> %s",
- qPrintable(this->m_MOVersion.displayString()), qPrintable(newestVer.displayString()));
- }
- }
- });
+void SelfUpdater::testForUpdate()
+{
+ // TODO: if prereleases are disabled we could just request the latest release
+ // directly
+ try {
+ m_GitHub.releases(GitHub::Repository("LePresidente", "modorganizer"),
+ [this](const QJsonArray &releases) {
+ QJsonObject newest;
+ for (const QJsonValue &releaseVal : releases) {
+ QJsonObject release = releaseVal.toObject();
+ if (!release["draft"].toBool() && (Settings::instance().usePrereleases()
+ || !release["prerelease"].toBool())) {
+ if (newest.empty() || (VersionInfo(release["tag_name"].toString())
+ > VersionInfo(newest["tag_name"].toString()))) {
+ newest = release;
+ }
+ }
}
- // Catch all is bad by design, should be improved
- catch (...) {
- qDebug("Unable to connect to github.com to check version");
+
+ if (!newest.empty()) {
+ VersionInfo newestVer(newest["tag_name"].toString());
+ if (newestVer > this->m_MOVersion) {
+ m_UpdateCandidate = newest;
+ qDebug("update available: %s -> %s",
+ qPrintable(this->m_MOVersion.displayString()),
+ qPrintable(newestVer.displayString()));
+ emit updateAvailable();
+ } else if (newestVer < this->m_MOVersion) {
+ // this could happen if the user switches from using prereleases to
+ // stable builds. Should we downgrade?
+ qDebug("this version is newer than the newest installed one: %s -> %s",
+ qPrintable(this->m_MOVersion.displayString()),
+ qPrintable(newestVer.displayString()));
+ }
}
+ });
+ }
+ //Catch all is bad by design, should be improved
+ catch (...) {
+ qDebug("Unable to connect to github.com to check version");
+ }
}
-void SelfUpdater::startUpdate() {
- // the button can't be pressed if there isn't an update candidate
- Q_ASSERT(!m_UpdateCandidate.empty());
+void SelfUpdater::startUpdate()
+{
+ // the button can't be pressed if there isn't an update candidate
+ Q_ASSERT(!m_UpdateCandidate.empty());
- QMessageBox query(
- QMessageBox::Question, tr("New update available (%1)").arg(m_UpdateCandidate["tag_name"].toString()),
- BBCode::convertToHTML(m_UpdateCandidate["body"].toString()), QMessageBox::Yes | QMessageBox::Cancel, m_Parent);
+ QMessageBox query(QMessageBox::Question,
+ tr("New update available (%1)")
+ .arg(m_UpdateCandidate["tag_name"].toString()),
+ BBCode::convertToHTML(m_UpdateCandidate["body"].toString()),
+ QMessageBox::Yes | QMessageBox::Cancel, m_Parent);
- query.button(QMessageBox::Yes)->setText(tr("Install"));
+ query.button(QMessageBox::Yes)->setText(tr("Install"));
- int res = query.exec();
+ int res = query.exec();
- if (query.result() == QMessageBox::Yes) {
- bool found = false;
- for (const QJsonValue& assetVal : m_UpdateCandidate["assets"].toArray()) {
- QJsonObject asset = assetVal.toObject();
- if (asset["content_type"].toString() == "application/x-msdownload") {
- openOutputFile(asset["name"].toString());
- download(asset["browser_download_url"].toString());
- found = true;
- break;
- }
- }
- if (!found) {
- QMessageBox::warning(m_Parent, tr("Download failed"),
- tr("Failed to find correct download, please try again later."));
- }
+ if (query.result() == QMessageBox::Yes) {
+ bool found = false;
+ for (const QJsonValue &assetVal : m_UpdateCandidate["assets"].toArray()) {
+ QJsonObject asset = assetVal.toObject();
+ if (asset["content_type"].toString() == "application/x-msdownload") {
+ openOutputFile(asset["name"].toString());
+ download(asset["browser_download_url"].toString());
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ QMessageBox::warning(
+ m_Parent, tr("Download failed"),
+ tr("Failed to find correct download, please try again later."));
}
+ }
}
-void SelfUpdater::showProgress() {
- if (m_Progress == nullptr) {
- m_Progress = new QProgressDialog(m_Parent, Qt::Dialog);
- connect(m_Progress, SIGNAL(canceled()), this, SLOT(downloadCancel()));
- }
- m_Progress->setModal(true);
- m_Progress->show();
- m_Progress->setValue(0);
- m_Progress->setWindowTitle(tr("Update"));
- m_Progress->setLabelText(tr("Download in progress"));
+
+void SelfUpdater::showProgress()
+{
+ if (m_Progress == nullptr) {
+ m_Progress = new QProgressDialog(m_Parent, Qt::Dialog);
+ connect(m_Progress, SIGNAL(canceled()), this, SLOT(downloadCancel()));
+ }
+ m_Progress->setModal(true);
+ m_Progress->show();
+ m_Progress->setValue(0);
+ m_Progress->setWindowTitle(tr("Update"));
+ m_Progress->setLabelText(tr("Download in progress"));
}
-void SelfUpdater::closeProgress() {
- if (m_Progress != nullptr) {
- m_Progress->hide();
- m_Progress->deleteLater();
- m_Progress = nullptr;
- }
+void SelfUpdater::closeProgress()
+{
+ if (m_Progress != nullptr) {
+ m_Progress->hide();
+ m_Progress->deleteLater();
+ m_Progress = nullptr;
+ }
}
-void SelfUpdater::openOutputFile(const QString& fileName) {
- QString outputPath = QDir::fromNativeSeparators(qApp->property("dataPath").toString()) + "/" + fileName;
- qDebug("downloading to %s", qPrintable(outputPath));
- m_UpdateFile.setFileName(outputPath);
- m_UpdateFile.open(QIODevice::WriteOnly);
+void SelfUpdater::openOutputFile(const QString &fileName)
+{
+ QString outputPath = QDir::fromNativeSeparators(qApp->property("dataPath").toString()) + "/" + fileName;
+ qDebug("downloading to %s", qPrintable(outputPath));
+ m_UpdateFile.setFileName(outputPath);
+ m_UpdateFile.open(QIODevice::WriteOnly);
}
-void SelfUpdater::download(const QString& downloadLink) {
- QNetworkAccessManager* accessManager = m_Interface->getAccessManager();
- QUrl dlUrl(downloadLink);
- QNetworkRequest request(dlUrl);
- m_Canceled = false;
- m_Reply = accessManager->get(request);
- showProgress();
+void SelfUpdater::download(const QString &downloadLink)
+{
+ QNetworkAccessManager *accessManager = m_Interface->getAccessManager();
+ QUrl dlUrl(downloadLink);
+ QNetworkRequest request(dlUrl);
+ m_Canceled = false;
+ m_Reply = accessManager->get(request);
+ showProgress();
- connect(m_Reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadProgress(qint64, qint64)));
- connect(m_Reply, SIGNAL(finished()), this, SLOT(downloadFinished()));
- connect(m_Reply, SIGNAL(readyRead()), this, SLOT(downloadReadyRead()));
+ connect(m_Reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadProgress(qint64, qint64)));
+ connect(m_Reply, SIGNAL(finished()), this, SLOT(downloadFinished()));
+ connect(m_Reply, SIGNAL(readyRead()), this, SLOT(downloadReadyRead()));
}
-void SelfUpdater::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) {
- if (m_Reply != nullptr) {
- if (m_Canceled) {
- m_Reply->abort();
- } else {
- if (bytesTotal != 0) {
- if (m_Progress != nullptr) {
- m_Progress->setValue((bytesReceived * 100) / bytesTotal);
- }
- }
+
+void SelfUpdater::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
+{
+ if (m_Reply != nullptr) {
+ if (m_Canceled) {
+ m_Reply->abort();
+ } else {
+ if (bytesTotal != 0) {
+ if (m_Progress != nullptr) {
+ m_Progress->setValue((bytesReceived * 100) / bytesTotal);
}
+ }
}
+ }
}
-void SelfUpdater::downloadReadyRead() {
- if (m_Reply != nullptr) {
- m_UpdateFile.write(m_Reply->readAll());
- }
-}
-void SelfUpdater::downloadFinished() {
- int error = QNetworkReply::NoError;
+void SelfUpdater::downloadReadyRead()
+{
+ if (m_Reply != nullptr) {
+ m_UpdateFile.write(m_Reply->readAll());
+ }
+}
- if (m_Reply != nullptr) {
- if (m_Reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 302) {
- QUrl url = m_Reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
- m_UpdateFile.reset();
- download(url.toString());
- return;
- }
- m_UpdateFile.write(m_Reply->readAll());
- error = m_Reply->error();
+void SelfUpdater::downloadFinished()
+{
+ int error = QNetworkReply::NoError;
- if (m_Reply->header(QNetworkRequest::ContentTypeHeader).toString().startsWith("text", Qt::CaseInsensitive)) {
- m_Canceled = true;
- }
+ if (m_Reply != nullptr) {
+ if (m_Reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 302) {
+ QUrl url = m_Reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
+ m_UpdateFile.reset();
+ download(url.toString());
+ return;
+ }
+ m_UpdateFile.write(m_Reply->readAll());
- closeProgress();
+ error = m_Reply->error();
- m_Reply->close();
- m_Reply->deleteLater();
- m_Reply = nullptr;
+ if (m_Reply->header(QNetworkRequest::ContentTypeHeader).toString().startsWith("text", Qt::CaseInsensitive)) {
+ m_Canceled = true;
}
- m_UpdateFile.close();
+ closeProgress();
- if ((m_UpdateFile.size() == 0) || (error != QNetworkReply::NoError) || m_Canceled) {
- if (!m_Canceled) {
- reportError(tr("Download failed: %1").arg(error));
- }
- m_UpdateFile.remove();
- return;
- }
+ m_Reply->close();
+ m_Reply->deleteLater();
+ m_Reply = nullptr;
+ }
- qDebug("download: %s", m_UpdateFile.fileName().toUtf8().constData());
+ m_UpdateFile.close();
- try {
- installUpdate();
- } catch (const std::exception& e) {
- reportError(tr("Failed to install update: %1").arg(e.what()));
+ if ((m_UpdateFile.size() == 0) ||
+ (error != QNetworkReply::NoError) ||
+ m_Canceled) {
+ if (!m_Canceled) {
+ reportError(tr("Download failed: %1").arg(error));
}
+ m_UpdateFile.remove();
+ return;
+ }
+
+ qDebug("download: %s", m_UpdateFile.fileName().toUtf8().constData());
+
+ try {
+ installUpdate();
+ } catch (const std::exception &e) {
+ reportError(tr("Failed to install update: %1").arg(e.what()));
+ }
}
-void SelfUpdater::downloadCancel() { m_Canceled = true; }
-void SelfUpdater::installUpdate() {
- const QString mopath = QDir::fromNativeSeparators(qApp->property("dataPath").toString());
+void SelfUpdater::downloadCancel()
+{
+ m_Canceled = true;
+}
- HINSTANCE res =
- ::ShellExecuteW(nullptr, L"open", m_UpdateFile.fileName().toStdWString().c_str(), nullptr, nullptr, SW_SHOW);
- if (res > (HINSTANCE)32) {
- QCoreApplication::quit();
- } else {
- reportError(tr("Failed to start %1: %2").arg(m_UpdateFile.fileName()).arg((int)res));
- }
+void SelfUpdater::installUpdate()
+{
+ const QString mopath
+ = QDir::fromNativeSeparators(qApp->property("dataPath").toString());
- m_UpdateFile.remove();
+ HINSTANCE res = ::ShellExecuteW(
+ nullptr, L"open", m_UpdateFile.fileName().toStdWString().c_str(), nullptr,
+ nullptr, SW_SHOW);
+
+ if (res > (HINSTANCE)32) {
+ QCoreApplication::quit();
+ } else {
+ reportError(tr("Failed to start %1: %2")
+ .arg(m_UpdateFile.fileName())
+ .arg((int)res));
+ }
+
+ m_UpdateFile.remove();
}
-void SelfUpdater::report7ZipError(QString const& errorMessage) {
- QMessageBox::critical(m_Parent, tr("Error"), errorMessage);
+void SelfUpdater::report7ZipError(QString const &errorMessage)
+{
+ QMessageBox::critical(m_Parent, tr("Error"), errorMessage);
}
diff --git a/src/selfupdater.h b/src/selfupdater.h
index 12b473bd..4743f6a4 100644
--- a/src/selfupdater.h
+++ b/src/selfupdater.h
@@ -20,14 +20,13 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef SELFUPDATER_H
#define SELFUPDATER_H
-#include <github.h>
+
#include <versioninfo.h>
+#include <github.h>
class Archive;
class NexusInterface;
-namespace MOBase {
-class IPluginGame;
-}
+namespace MOBase { class IPluginGame; }
#include <QFile>
#include <QObject>
@@ -38,6 +37,7 @@ class IPluginGame;
class QNetworkReply;
class QProgressDialog;
+
/**
* @brief manages updates for Mod Organizer itself
* This class is used to update the Mod Organizer
@@ -57,88 +57,94 @@ class QProgressDialog;
*
* @todo use NexusBridge
**/
-class SelfUpdater : public QObject {
+class SelfUpdater : public QObject
+{
- Q_OBJECT
+ Q_OBJECT
public:
- /**
- * @brief constructor
- *
- * @param nexusInterface interface to query information from nexus
- * @param parent parent widget
- * @todo passing the nexus interface is unneccessary
- **/
- explicit SelfUpdater(NexusInterface* nexusInterface);
- virtual ~SelfUpdater();
+ /**
+ * @brief constructor
+ *
+ * @param nexusInterface interface to query information from nexus
+ * @param parent parent widget
+ * @todo passing the nexus interface is unneccessary
+ **/
+ explicit SelfUpdater(NexusInterface *nexusInterface);
+
+ virtual ~SelfUpdater();
- void setUserInterface(QWidget* widget);
+ void setUserInterface(QWidget *widget);
- /**
- * @brief start the update process
- * @note this should not be called if there is no update available
- **/
- void startUpdate();
+ /**
+ * @brief start the update process
+ * @note this should not be called if there is no update available
+ **/
+ void startUpdate();
- /**
- * @return current version of Mod Organizer
- **/
- MOBase::VersionInfo getVersion() const { return m_MOVersion; }
+ /**
+ * @return current version of Mod Organizer
+ **/
+ MOBase::VersionInfo getVersion() const { return m_MOVersion; }
public slots:
- /**
- * @brief request information about the current version
- **/
- void testForUpdate();
+ /**
+ * @brief request information about the current version
+ **/
+ void testForUpdate();
signals:
- /**
- * @brief emitted if a restart of the client is necessary to complete the update
- **/
- void restart();
+ /**
+ * @brief emitted if a restart of the client is necessary to complete the update
+ **/
+ void restart();
- /**
- * @brief emitted if an update is available
- **/
- void updateAvailable();
+ /**
+ * @brief emitted if an update is available
+ **/
+ void updateAvailable();
- /**
- * @brief emitted if a message of the day was received
- **/
- void motdAvailable(const QString& motd);
+ /**
+ * @brief emitted if a message of the day was received
+ **/
+ void motdAvailable(const QString &motd);
private:
- void openOutputFile(const QString& fileName);
- void download(const QString& downloadLink);
- void installUpdate();
- void report7ZipError(const QString& errorMessage);
- void showProgress();
- void closeProgress();
+
+ void openOutputFile(const QString &fileName);
+ void download(const QString &downloadLink);
+ void installUpdate();
+ void report7ZipError(const QString &errorMessage);
+ void showProgress();
+ void closeProgress();
private slots:
- void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
- void downloadReadyRead();
- void downloadFinished();
- void downloadCancel();
+ void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
+ void downloadReadyRead();
+ void downloadFinished();
+ void downloadCancel();
private:
- QWidget* m_Parent;
- MOBase::VersionInfo m_MOVersion;
- NexusInterface* m_Interface;
- QFile m_UpdateFile;
- QNetworkReply* m_Reply;
- QProgressDialog* m_Progress{nullptr};
- bool m_Canceled;
- int m_Attempts;
- Archive* m_ArchiveHandler;
+ QWidget *m_Parent;
+ MOBase::VersionInfo m_MOVersion;
+ NexusInterface *m_Interface;
+ QFile m_UpdateFile;
+ QNetworkReply *m_Reply;
+ QProgressDialog *m_Progress { nullptr };
+ bool m_Canceled;
+ int m_Attempts;
+
+ Archive *m_ArchiveHandler;
+
+ GitHub m_GitHub;
+ QJsonObject m_UpdateCandidate;
- GitHub m_GitHub;
- QJsonObject m_UpdateCandidate;
};
+
#endif // SELFUPDATER_H
diff --git a/src/serverinfo.h b/src/serverinfo.h
index 36b0e3f3..8e5e935a 100644
--- a/src/serverinfo.h
+++ b/src/serverinfo.h
@@ -1,15 +1,16 @@
#ifndef SERVERINFO_H
#define SERVERINFO_H
+#include <QString>
#include <QDate>
#include <QMetaType>
-#include <QString>
-struct ServerInfo {
- QString name;
- bool premium;
- QDate lastSeen;
- bool preferred;
+struct ServerInfo
+{
+ QString name;
+ bool premium;
+ QDate lastSeen;
+ bool preferred;
};
Q_DECLARE_METATYPE(ServerInfo)
diff --git a/src/settings.cpp b/src/settings.cpp
index 2694c59a..d1130e05 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -19,38 +19,39 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "settings.h"
-#include "appconfig.h"
-#include "organizercore.h"
#include "pluginsetting.h"
#include "serverinfo.h"
#include "settingsdialog.h"
#include "versioninfo.h"
+#include "appconfig.h"
+#include "organizercore.h"
+#include <utility.h>
#include <iplugin.h>
#include <iplugingame.h>
#include <questionboxmemory.h>
#include <usvfsparameters.h>
-#include <utility.h>
-#include <QApplication>
#include <QCheckBox>
-#include <QComboBox>
#include <QCoreApplication>
+#include <QComboBox>
#include <QDate>
#include <QDialog>
#include <QDir>
#include <QDirIterator>
#include <QFileInfo>
-#include <QLabel>
#include <QLineEdit>
+#include <QSpinBox>
#include <QListWidgetItem>
#include <QLocale>
#include <QMessageBox>
+#include <QApplication>
#include <QRegExp>
-#include <QSpinBox>
+#include <QDir>
#include <QStringList>
#include <QVariantMap>
+#include <QLabel>
-#include <Qt> // for Qt::UserRole, etc
+#include <Qt> // for Qt::UserRole, etc
#include <QtDebug> // for qDebug, qWarning
#include <Windows.h> // For ShellExecuteW, HINSTANCE, etc
@@ -66,808 +67,934 @@ using namespace MOBase;
template <typename T>
class QListWidgetItemEx : public QListWidgetItem {
public:
- QListWidgetItemEx(const QString& text, int sortRole = Qt::DisplayRole, QListWidget* parent = 0, int type = Type)
- : QListWidgetItem(text, parent, type), m_SortRole(sortRole) {}
-
- virtual bool operator<(const QListWidgetItem& other) const {
- return this->data(m_SortRole).value<T>() < other.data(m_SortRole).value<T>();
- }
+ QListWidgetItemEx(const QString &text, int sortRole = Qt::DisplayRole, QListWidget *parent = 0, int type = Type)
+ : QListWidgetItem(text, parent, type), m_SortRole(sortRole) {}
+ virtual bool operator< ( const QListWidgetItem & other ) const {
+ return this->data(m_SortRole).value<T>() < other.data(m_SortRole).value<T>();
+ }
private:
- int m_SortRole;
+ int m_SortRole;
};
-static const unsigned char Key2[20] = {0x99, 0xb8, 0x76, 0x42, 0x3e, 0xc1, 0x60, 0xa4, 0x5b, 0x01,
- 0xdb, 0xf8, 0x43, 0x3a, 0xb7, 0xb6, 0x98, 0xd4, 0x7d, 0xa2};
-Settings* Settings::s_Instance = nullptr;
+static const unsigned char Key2[20] = { 0x99, 0xb8, 0x76, 0x42, 0x3e, 0xc1, 0x60, 0xa4, 0x5b, 0x01,
+ 0xdb, 0xf8, 0x43, 0x3a, 0xb7, 0xb6, 0x98, 0xd4, 0x7d, 0xa2 };
-Settings::Settings(const QSettings& settingsSource) : m_Settings(settingsSource.fileName(), settingsSource.format()) {
- if (s_Instance != nullptr) {
- throw std::runtime_error("second instance of \"Settings\" created");
- } else {
- s_Instance = this;
- }
+Settings *Settings::s_Instance = nullptr;
+
+
+Settings::Settings(const QSettings &settingsSource)
+ : m_Settings(settingsSource.fileName(), settingsSource.format())
+{
+ if (s_Instance != nullptr) {
+ throw std::runtime_error("second instance of \"Settings\" created");
+ } else {
+ s_Instance = this;
+ }
}
-Settings::~Settings() { s_Instance = nullptr; }
-Settings& Settings::instance() {
- if (s_Instance == nullptr) {
- throw std::runtime_error("no instance of \"Settings\"");
- }
- return *s_Instance;
+Settings::~Settings()
+{
+ s_Instance = nullptr;
}
-void Settings::clearPlugins() {
- m_Plugins.clear();
- m_PluginSettings.clear();
- m_PluginBlacklist.clear();
- int count = m_Settings.beginReadArray("pluginBlacklist");
- for (int i = 0; i < count; ++i) {
- m_Settings.setArrayIndex(i);
- m_PluginBlacklist.insert(m_Settings.value("name").toString());
- }
- m_Settings.endArray();
+Settings &Settings::instance()
+{
+ if (s_Instance == nullptr) {
+ throw std::runtime_error("no instance of \"Settings\"");
+ }
+ return *s_Instance;
}
-bool Settings::pluginBlacklisted(const QString& fileName) const { return m_PluginBlacklist.contains(fileName); }
+void Settings::clearPlugins()
+{
+ m_Plugins.clear();
+ m_PluginSettings.clear();
-void Settings::registerAsNXMHandler(bool force) {
- std::wstring nxmPath = ToWString(QCoreApplication::applicationDirPath() + "/nxmhandler.exe");
- std::wstring executable = ToWString(QCoreApplication::applicationFilePath());
- std::wstring mode = force ? L"forcereg" : L"reg";
- std::wstring parameters = mode + L" " + m_GamePlugin->gameShortName().toStdWString() + L" \"" + executable + L"\"";
- HINSTANCE res = ::ShellExecuteW(nullptr, L"open", nxmPath.c_str(), parameters.c_str(), nullptr, SW_SHOWNORMAL);
- if ((int)res <= 32) {
- QMessageBox::critical(nullptr, tr("Failed"), tr("Sorry, failed to start the helper application"));
- }
+ m_PluginBlacklist.clear();
+ int count = m_Settings.beginReadArray("pluginBlacklist");
+ for (int i = 0; i < count; ++i) {
+ m_Settings.setArrayIndex(i);
+ m_PluginBlacklist.insert(m_Settings.value("name").toString());
+ }
+ m_Settings.endArray();
}
-void Settings::managedGameChanged(IPluginGame const* gamePlugin) { m_GamePlugin = gamePlugin; }
+bool Settings::pluginBlacklisted(const QString &fileName) const
+{
+ return m_PluginBlacklist.contains(fileName);
+}
-void Settings::registerPlugin(IPlugin* plugin) {
- m_Plugins.push_back(plugin);
- m_PluginSettings.insert(plugin->name(), QMap<QString, QVariant>());
- m_PluginDescriptions.insert(plugin->name(), QMap<QString, QVariant>());
- for (const PluginSetting& setting : plugin->settings()) {
- QVariant temp = m_Settings.value("Plugins/" + plugin->name() + "/" + setting.key, setting.defaultValue);
- if (!temp.convert(setting.defaultValue.type())) {
- qWarning("failed to interpret \"%s\" as correct type for \"%s\" in plugin \"%s\", using default",
- qPrintable(temp.toString()), qPrintable(setting.key), qPrintable(plugin->name()));
- temp = setting.defaultValue;
- }
- m_PluginSettings[plugin->name()][setting.key] = temp;
- m_PluginDescriptions[plugin->name()][setting.key] =
- QString("%1 (default: %2)").arg(setting.description).arg(setting.defaultValue.toString());
- }
+void Settings::registerAsNXMHandler(bool force)
+{
+ std::wstring nxmPath = ToWString(QCoreApplication::applicationDirPath() + "/nxmhandler.exe");
+ std::wstring executable = ToWString(QCoreApplication::applicationFilePath());
+ std::wstring mode = force ? L"forcereg" : L"reg";
+ std::wstring parameters = mode + L" " + m_GamePlugin->gameShortName().toStdWString() + L" \"" + executable + L"\"";
+ HINSTANCE res = ::ShellExecuteW(nullptr, L"open", nxmPath.c_str(), parameters.c_str(), nullptr, SW_SHOWNORMAL);
+ if ((int)res <= 32) {
+ QMessageBox::critical(nullptr, tr("Failed"),
+ tr("Sorry, failed to start the helper application"));
+ }
}
-QString Settings::obfuscate(const QString& password) {
- QByteArray temp = password.toUtf8();
+void Settings::managedGameChanged(IPluginGame const *gamePlugin)
+{
+ m_GamePlugin = gamePlugin;
+}
- QByteArray buffer;
- for (int i = 0; i < temp.length(); ++i) {
- buffer.append(temp.at(i) ^ Key2[i % 20]);
+void Settings::registerPlugin(IPlugin *plugin)
+{
+ m_Plugins.push_back(plugin);
+ m_PluginSettings.insert(plugin->name(), QMap<QString, QVariant>());
+ m_PluginDescriptions.insert(plugin->name(), QMap<QString, QVariant>());
+ for (const PluginSetting &setting : plugin->settings()) {
+ QVariant temp = m_Settings.value("Plugins/" + plugin->name() + "/" + setting.key, setting.defaultValue);
+ if (!temp.convert(setting.defaultValue.type())) {
+ qWarning("failed to interpret \"%s\" as correct type for \"%s\" in plugin \"%s\", using default",
+ qPrintable(temp.toString()), qPrintable(setting.key), qPrintable(plugin->name()));
+ temp = setting.defaultValue;
}
- return buffer.toBase64();
+ m_PluginSettings[plugin->name()][setting.key] = temp;
+ m_PluginDescriptions[plugin->name()][setting.key] = QString("%1 (default: %2)").arg(setting.description).arg(setting.defaultValue.toString());
+ }
}
-QString Settings::deObfuscate(const QString& password) {
- QByteArray temp(QByteArray::fromBase64(password.toUtf8()));
+QString Settings::obfuscate(const QString &password)
+{
+ QByteArray temp = password.toUtf8();
- QByteArray buffer;
- for (int i = 0; i < temp.length(); ++i) {
- buffer.append(temp.at(i) ^ Key2[i % 20]);
- }
- return QString::fromUtf8(buffer.constData());
+ QByteArray buffer;
+ for (int i = 0; i < temp.length(); ++i) {
+ buffer.append(temp.at(i) ^ Key2[i % 20]);
+ }
+ return buffer.toBase64();
+}
+
+QString Settings::deObfuscate(const QString &password)
+{
+ QByteArray temp(QByteArray::fromBase64(password.toUtf8()));
+
+ QByteArray buffer;
+ for (int i = 0; i < temp.length(); ++i) {
+ buffer.append(temp.at(i) ^ Key2[i % 20]);
+ }
+ return QString::fromUtf8(buffer.constData());
}
-bool Settings::hideUncheckedPlugins() const {
- return m_Settings.value("Settings/hide_unchecked_plugins", false).toBool();
+bool Settings::hideUncheckedPlugins() const
+{
+ return m_Settings.value("Settings/hide_unchecked_plugins", false).toBool();
}
-bool Settings::forceEnableCoreFiles() const {
- return m_Settings.value("Settings/force_enable_core_files", true).toBool();
+bool Settings::forceEnableCoreFiles() const
+{
+ return m_Settings.value("Settings/force_enable_core_files", true).toBool();
}
-bool Settings::automaticLoginEnabled() const { return m_Settings.value("Settings/nexus_login", false).toBool(); }
+bool Settings::automaticLoginEnabled() const
+{
+ return m_Settings.value("Settings/nexus_login", false).toBool();
+}
-QString Settings::getSteamAppID() const {
- return m_Settings.value("Settings/app_id", m_GamePlugin->steamAPPId()).toString();
+QString Settings::getSteamAppID() const
+{
+ return m_Settings.value("Settings/app_id", m_GamePlugin->steamAPPId()).toString();
}
-bool Settings::usePrereleases() const { return m_Settings.value("Settings/use_prereleases", false).toBool(); }
+bool Settings::usePrereleases() const
+{
+ return m_Settings.value("Settings/use_prereleases", false).toBool();
+}
-void Settings::setDownloadSpeed(const QString& serverName, int bytesPerSecond) {
- m_Settings.beginGroup("Servers");
+void Settings::setDownloadSpeed(const QString &serverName, int bytesPerSecond)
+{
+ m_Settings.beginGroup("Servers");
- for (const QString& serverKey : m_Settings.childKeys()) {
- QVariantMap data = m_Settings.value(serverKey).toMap();
- if (serverKey == serverName) {
- data["downloadCount"] = data["downloadCount"].toInt() + 1;
- data["downloadSpeed"] = data["downloadSpeed"].toDouble() + static_cast<double>(bytesPerSecond);
- m_Settings.setValue(serverKey, data);
- }
+ for (const QString &serverKey : m_Settings.childKeys()) {
+ QVariantMap data = m_Settings.value(serverKey).toMap();
+ if (serverKey == serverName) {
+ data["downloadCount"] = data["downloadCount"].toInt() + 1;
+ data["downloadSpeed"] = data["downloadSpeed"].toDouble() + static_cast<double>(bytesPerSecond);
+ m_Settings.setValue(serverKey, data);
}
+ }
- m_Settings.endGroup();
- m_Settings.sync();
+ m_Settings.endGroup();
+ m_Settings.sync();
}
-std::map<QString, int> Settings::getPreferredServers() {
- std::map<QString, int> result;
- m_Settings.beginGroup("Servers");
+std::map<QString, int> Settings::getPreferredServers()
+{
+ std::map<QString, int> result;
+ m_Settings.beginGroup("Servers");
- for (const QString& serverKey : m_Settings.childKeys()) {
- QVariantMap data = m_Settings.value(serverKey).toMap();
- int preference = data["preferred"].toInt();
- if (preference > 0) {
- result[serverKey] = preference;
- }
+ for (const QString &serverKey : m_Settings.childKeys()) {
+ QVariantMap data = m_Settings.value(serverKey).toMap();
+ int preference = data["preferred"].toInt();
+ if (preference > 0) {
+ result[serverKey] = preference;
}
- m_Settings.endGroup();
+ }
+ m_Settings.endGroup();
- return result;
+ return result;
}
-QString Settings::getConfigurablePath(const QString& key, const QString& def, bool resolve) const {
- QString result = QDir::fromNativeSeparators(
- m_Settings.value(QString("settings/") + key, QString("%BASE_DIR%/") + def).toString());
- if (resolve) {
- result.replace("%BASE_DIR%", getBaseDirectory());
- }
- return result;
+QString Settings::getConfigurablePath(const QString &key,
+ const QString &def,
+ bool resolve) const
+{
+ QString result = QDir::fromNativeSeparators(
+ m_Settings.value(QString("settings/") + key, QString("%BASE_DIR%/") + def)
+ .toString());
+ if (resolve) {
+ result.replace("%BASE_DIR%", getBaseDirectory());
+ }
+ return result;
}
-QString Settings::getBaseDirectory() const {
- return QDir::fromNativeSeparators(
- m_Settings.value("settings/base_directory", qApp->property("dataPath").toString()).toString());
+QString Settings::getBaseDirectory() const
+{
+ return QDir::fromNativeSeparators(m_Settings.value(
+ "settings/base_directory", qApp->property("dataPath").toString()).toString());
}
-QString Settings::getDownloadDirectory(bool resolve) const {
- return getConfigurablePath("download_directory", ToQString(AppConfig::downloadPath()), resolve);
+QString Settings::getDownloadDirectory(bool resolve) const
+{
+ return getConfigurablePath("download_directory", ToQString(AppConfig::downloadPath()), resolve);
}
-QString Settings::getCacheDirectory(bool resolve) const {
- return getConfigurablePath("cache_directory", ToQString(AppConfig::cachePath()), resolve);
+QString Settings::getCacheDirectory(bool resolve) const
+{
+ return getConfigurablePath("cache_directory", ToQString(AppConfig::cachePath()), resolve);
}
-QString Settings::getModDirectory(bool resolve) const {
- return getConfigurablePath("mod_directory", ToQString(AppConfig::modsPath()), resolve);
+QString Settings::getModDirectory(bool resolve) const
+{
+ return getConfigurablePath("mod_directory", ToQString(AppConfig::modsPath()), resolve);
}
-QString Settings::getProfileDirectory(bool resolve) const {
- return getConfigurablePath("profiles_directory", ToQString(AppConfig::profilesPath()), resolve);
+QString Settings::getProfileDirectory(bool resolve) const
+{
+ return getConfigurablePath("profiles_directory", ToQString(AppConfig::profilesPath()), resolve);
}
-QString Settings::getOverwriteDirectory(bool resolve) const {
- return getConfigurablePath("overwrite_directory", ToQString(AppConfig::overwritePath()), resolve);
+QString Settings::getOverwriteDirectory(bool resolve) const
+{
+ return getConfigurablePath("overwrite_directory",
+ ToQString(AppConfig::overwritePath()), resolve);
}
-QString Settings::getNMMVersion() const {
- static const QString MIN_NMM_VERSION = "0.61.13";
- QString result = m_Settings.value("Settings/nmm_version", MIN_NMM_VERSION).toString();
- if (VersionInfo(result) < VersionInfo(MIN_NMM_VERSION)) {
- result = MIN_NMM_VERSION;
- }
- return result;
+QString Settings::getNMMVersion() const
+{
+ static const QString MIN_NMM_VERSION = "0.61.13";
+ QString result = m_Settings.value("Settings/nmm_version", MIN_NMM_VERSION).toString();
+ if (VersionInfo(result) < VersionInfo(MIN_NMM_VERSION)) {
+ result = MIN_NMM_VERSION;
+ }
+ return result;
}
-bool Settings::getNexusLogin(QString& username, QString& password) const {
- if (m_Settings.value("Settings/nexus_login", false).toBool()) {
- username = m_Settings.value("Settings/nexus_username", "").toString();
- password = deObfuscate(m_Settings.value("Settings/nexus_password", "").toString());
- return true;
- } else {
- return false;
- }
+bool Settings::getNexusLogin(QString &username, QString &password) const
+{
+ if (m_Settings.value("Settings/nexus_login", false).toBool()) {
+ username = m_Settings.value("Settings/nexus_username", "").toString();
+ password = deObfuscate(m_Settings.value("Settings/nexus_password", "").toString());
+ return true;
+ } else {
+ return false;
+ }
}
-bool Settings::getSteamLogin(QString& username, QString& password) const {
- if (m_Settings.contains("Settings/steam_username") && m_Settings.contains("Settings/steam_password")) {
- username = m_Settings.value("Settings/steam_username").toString();
- password = deObfuscate(m_Settings.value("Settings/steam_password").toString());
- return true;
- } else {
- return false;
- }
+bool Settings::getSteamLogin(QString &username, QString &password) const
+{
+ if (m_Settings.contains("Settings/steam_username")
+ && m_Settings.contains("Settings/steam_password")) {
+ username = m_Settings.value("Settings/steam_username").toString();
+ password = deObfuscate(m_Settings.value("Settings/steam_password").toString());
+ return true;
+ } else {
+ return false;
+ }
+}
+bool Settings::compactDownloads() const
+{
+ return m_Settings.value("Settings/compact_downloads", false).toBool();
}
-bool Settings::compactDownloads() const { return m_Settings.value("Settings/compact_downloads", false).toBool(); }
-bool Settings::metaDownloads() const { return m_Settings.value("Settings/meta_downloads", false).toBool(); }
+bool Settings::metaDownloads() const
+{
+ return m_Settings.value("Settings/meta_downloads", false).toBool();
+}
-bool Settings::offlineMode() const { return m_Settings.value("Settings/offline_mode", false).toBool(); }
+bool Settings::offlineMode() const
+{
+ return m_Settings.value("Settings/offline_mode", false).toBool();
+}
-int Settings::logLevel() const {
- return m_Settings.value("Settings/log_level", static_cast<int>(LogLevel::Info)).toInt();
+int Settings::logLevel() const
+{
+ return m_Settings.value("Settings/log_level", static_cast<int>(LogLevel::Info)).toInt();
}
-int Settings::crashDumpsType() const {
- return m_Settings.value("Settings/crash_dumps_type", static_cast<int>(CrashDumpsType::Mini)).toInt();
+int Settings::crashDumpsType() const
+{
+ return m_Settings.value("Settings/crash_dumps_type", static_cast<int>(CrashDumpsType::Mini)).toInt();
}
-int Settings::crashDumpsMax() const { return m_Settings.value("Settings/crash_dumps_max", 5).toInt(); }
+int Settings::crashDumpsMax() const
+{
+ return m_Settings.value("Settings/crash_dumps_max", 5).toInt();
+}
-void Settings::setNexusLogin(QString username, QString password) {
- m_Settings.setValue("Settings/nexus_login", true);
- m_Settings.setValue("Settings/nexus_username", username);
- m_Settings.setValue("Settings/nexus_password", obfuscate(password));
+void Settings::setNexusLogin(QString username, QString password)
+{
+ m_Settings.setValue("Settings/nexus_login", true);
+ m_Settings.setValue("Settings/nexus_username", username);
+ m_Settings.setValue("Settings/nexus_password", obfuscate(password));
}
-void Settings::setSteamLogin(QString username, QString password) {
- if (username == "") {
- m_Settings.remove("Settings/steam_username");
- password = "";
- } else {
- m_Settings.setValue("Settings/steam_username", username);
- }
- if (password == "") {
- m_Settings.remove("Settings/steam_password");
- } else {
- m_Settings.setValue("Settings/steam_password", obfuscate(password));
- }
+void Settings::setSteamLogin(QString username, QString password)
+{
+ if (username == "") {
+ m_Settings.remove("Settings/steam_username");
+ password = "";
+ } else {
+ m_Settings.setValue("Settings/steam_username", username);
+ }
+ if (password == "") {
+ m_Settings.remove("Settings/steam_password");
+ } else {
+ m_Settings.setValue("Settings/steam_password", obfuscate(password));
+ }
}
-LoadMechanism::EMechanism Settings::getLoadMechanism() const {
- switch (m_Settings.value("Settings/load_mechanism").toInt()) {
- case LoadMechanism::LOAD_MODORGANIZER:
- return LoadMechanism::LOAD_MODORGANIZER;
- case LoadMechanism::LOAD_SCRIPTEXTENDER:
- return LoadMechanism::LOAD_SCRIPTEXTENDER;
- case LoadMechanism::LOAD_PROXYDLL:
- return LoadMechanism::LOAD_PROXYDLL;
- }
- throw std::runtime_error("invalid load mechanism");
+LoadMechanism::EMechanism Settings::getLoadMechanism() const
+{
+ switch (m_Settings.value("Settings/load_mechanism").toInt()) {
+ case LoadMechanism::LOAD_MODORGANIZER: return LoadMechanism::LOAD_MODORGANIZER;
+ case LoadMechanism::LOAD_SCRIPTEXTENDER: return LoadMechanism::LOAD_SCRIPTEXTENDER;
+ case LoadMechanism::LOAD_PROXYDLL: return LoadMechanism::LOAD_PROXYDLL;
+ }
+ throw std::runtime_error("invalid load mechanism");
}
-void Settings::setupLoadMechanism() { m_LoadMechanism.activate(getLoadMechanism()); }
-bool Settings::useProxy() const { return m_Settings.value("Settings/use_proxy", false).toBool(); }
+void Settings::setupLoadMechanism()
+{
+ m_LoadMechanism.activate(getLoadMechanism());
+}
-bool Settings::displayForeign() const { return m_Settings.value("Settings/display_foreign", true).toBool(); }
-void Settings::setMotDHash(uint hash) { m_Settings.setValue("motd_hash", hash); }
+bool Settings::useProxy() const
+{
+ return m_Settings.value("Settings/use_proxy", false).toBool();
+}
-uint Settings::getMotDHash() const { return m_Settings.value("motd_hash", 0).toUInt(); }
+bool Settings::displayForeign() const
+{
+ return m_Settings.value("Settings/display_foreign", true).toBool();
+}
-QVariant Settings::pluginSetting(const QString& pluginName, const QString& key) const {
- auto iterPlugin = m_PluginSettings.find(pluginName);
- if (iterPlugin == m_PluginSettings.end()) {
- return QVariant();
- }
- auto iterSetting = iterPlugin->find(key);
- if (iterSetting == iterPlugin->end()) {
- return QVariant();
- }
+void Settings::setMotDHash(uint hash)
+{
+ m_Settings.setValue("motd_hash", hash);
+}
- return *iterSetting;
+uint Settings::getMotDHash() const
+{
+ return m_Settings.value("motd_hash", 0).toUInt();
}
-void Settings::setPluginSetting(const QString& pluginName, const QString& key, const QVariant& value) {
- auto iterPlugin = m_PluginSettings.find(pluginName);
- if (iterPlugin == m_PluginSettings.end()) {
- throw MyException(tr("attempt to store setting for unknown plugin \"%1\"").arg(pluginName));
- }
+QVariant Settings::pluginSetting(const QString &pluginName, const QString &key) const
+{
+ auto iterPlugin = m_PluginSettings.find(pluginName);
+ if (iterPlugin == m_PluginSettings.end()) {
+ return QVariant();
+ }
+ auto iterSetting = iterPlugin->find(key);
+ if (iterSetting == iterPlugin->end()) {
+ return QVariant();
+ }
- // store the new setting both in memory and in the ini
- m_PluginSettings[pluginName][key] = value;
- m_Settings.setValue("Plugins/" + pluginName + "/" + key, value);
+ return *iterSetting;
}
-QVariant Settings::pluginPersistent(const QString& pluginName, const QString& key, const QVariant& def) const {
- if (!m_PluginSettings.contains(pluginName)) {
- return def;
- }
- return m_Settings.value("PluginPersistance/" + pluginName + "/" + key, def);
+void Settings::setPluginSetting(const QString &pluginName, const QString &key, const QVariant &value)
+{
+ auto iterPlugin = m_PluginSettings.find(pluginName);
+ if (iterPlugin == m_PluginSettings.end()) {
+ throw MyException(tr("attempt to store setting for unknown plugin \"%1\"").arg(pluginName));
+ }
+
+ // store the new setting both in memory and in the ini
+ m_PluginSettings[pluginName][key] = value;
+ m_Settings.setValue("Plugins/" + pluginName + "/" + key, value);
}
-void Settings::setPluginPersistent(const QString& pluginName, const QString& key, const QVariant& value, bool sync) {
- if (!m_PluginSettings.contains(pluginName)) {
- throw MyException(tr("attempt to store setting for unknown plugin \"%1\"").arg(pluginName));
- }
- m_Settings.setValue("PluginPersistance/" + pluginName + "/" + key, value);
- if (sync) {
- m_Settings.sync();
- }
+QVariant Settings::pluginPersistent(const QString &pluginName, const QString &key, const QVariant &def) const
+{
+ if (!m_PluginSettings.contains(pluginName)) {
+ return def;
+ }
+ return m_Settings.value("PluginPersistance/" + pluginName + "/" + key, def);
}
-QString Settings::language() {
- QString result = m_Settings.value("Settings/language", "").toString();
- if (result.isEmpty()) {
- QStringList languagePreferences = QLocale::system().uiLanguages();
- if (languagePreferences.length() > 0) {
- // the users most favoritest language
- result = languagePreferences.at(0);
- } else {
- // fallback system locale
- result = QLocale::system().name();
- }
+void Settings::setPluginPersistent(const QString &pluginName, const QString &key, const QVariant &value, bool sync)
+{
+ if (!m_PluginSettings.contains(pluginName)) {
+ throw MyException(tr("attempt to store setting for unknown plugin \"%1\"").arg(pluginName));
+ }
+ m_Settings.setValue("PluginPersistance/" + pluginName + "/" + key, value);
+ if (sync) {
+ m_Settings.sync();
+ }
+}
+
+QString Settings::language()
+{
+ QString result = m_Settings.value("Settings/language", "").toString();
+ if (result.isEmpty()) {
+ QStringList languagePreferences = QLocale::system().uiLanguages();
+ if (languagePreferences.length() > 0) {
+ // the users most favoritest language
+ result = languagePreferences.at(0);
+ } else {
+ // fallback system locale
+ result = QLocale::system().name();
}
- return result;
+ }
+ return result;
}
-void Settings::updateServers(const QList<ServerInfo>& servers) {
- m_Settings.beginGroup("Servers");
- QStringList oldServerKeys = m_Settings.childKeys();
+void Settings::updateServers(const QList<ServerInfo> &servers)
+{
+ m_Settings.beginGroup("Servers");
+ QStringList oldServerKeys = m_Settings.childKeys();
- for (const ServerInfo& server : servers) {
- if (!oldServerKeys.contains(server.name)) {
- // not yet known server
- QVariantMap newVal;
- newVal["premium"] = server.premium;
- newVal["preferred"] = server.preferred ? 1 : 0;
- newVal["lastSeen"] = server.lastSeen;
- newVal["downloadCount"] = 0;
- newVal["downloadSpeed"] = 0.0;
+ for (const ServerInfo &server : servers) {
+ if (!oldServerKeys.contains(server.name)) {
+ // not yet known server
+ QVariantMap newVal;
+ newVal["premium"] = server.premium;
+ newVal["preferred"] = server.preferred ? 1 : 0;
+ newVal["lastSeen"] = server.lastSeen;
+ newVal["downloadCount"] = 0;
+ newVal["downloadSpeed"] = 0.0;
- m_Settings.setValue(server.name, newVal);
- } else {
- QVariantMap data = m_Settings.value(server.name).toMap();
- data["lastSeen"] = server.lastSeen;
- data["premium"] = server.premium;
+ m_Settings.setValue(server.name, newVal);
+ } else {
+ QVariantMap data = m_Settings.value(server.name).toMap();
+ data["lastSeen"] = server.lastSeen;
+ data["premium"] = server.premium;
- m_Settings.setValue(server.name, data);
- }
+ m_Settings.setValue(server.name, data);
}
+ }
- // clean up unavailable servers
- QDate now = QDate::currentDate();
- for (const QString& key : m_Settings.childKeys()) {
- QVariantMap val = m_Settings.value(key).toMap();
- QDate lastSeen = val["lastSeen"].toDate();
- if (lastSeen.daysTo(now) > 30) {
- qDebug("removing server %s since it hasn't been available for downloads in over a month", qPrintable(key));
- m_Settings.remove(key);
- }
+ // clean up unavailable servers
+ QDate now = QDate::currentDate();
+ for (const QString &key : m_Settings.childKeys()) {
+ QVariantMap val = m_Settings.value(key).toMap();
+ QDate lastSeen = val["lastSeen"].toDate();
+ if (lastSeen.daysTo(now) > 30) {
+ qDebug("removing server %s since it hasn't been available for downloads in over a month", qPrintable(key));
+ m_Settings.remove(key);
}
+ }
- m_Settings.endGroup();
+ m_Settings.endGroup();
- m_Settings.sync();
+ m_Settings.sync();
}
-void Settings::addBlacklistPlugin(const QString& fileName) {
- m_PluginBlacklist.insert(fileName);
- writePluginBlacklist();
+void Settings::addBlacklistPlugin(const QString &fileName)
+{
+ m_PluginBlacklist.insert(fileName);
+ writePluginBlacklist();
}
-void Settings::writePluginBlacklist() {
- m_Settings.beginWriteArray("pluginBlacklist");
- int idx = 0;
- for (const QString& plugin : m_PluginBlacklist) {
- m_Settings.setArrayIndex(idx++);
- m_Settings.setValue("name", plugin);
- }
+void Settings::writePluginBlacklist()
+{
+ m_Settings.beginWriteArray("pluginBlacklist");
+ int idx = 0;
+ for (const QString &plugin : m_PluginBlacklist) {
+ m_Settings.setArrayIndex(idx++);
+ m_Settings.setValue("name", plugin);
+ }
- m_Settings.endArray();
+ m_Settings.endArray();
}
-void Settings::addLanguages(QComboBox* languageBox) {
- std::vector<std::pair<QString, QString>> languages;
+void Settings::addLanguages(QComboBox *languageBox)
+{
+ std::vector<std::pair<QString, QString>> languages;
- QDirIterator langIter(QCoreApplication::applicationDirPath() + "/translations", QDir::Files);
- QString pattern = ToQString(AppConfig::translationPrefix()) + "_([a-z]{2,3}(_[A-Z]{2,2})?).qm";
- QRegExp exp(pattern);
- while (langIter.hasNext()) {
- langIter.next();
- QString file = langIter.fileName();
- if (exp.exactMatch(file)) {
- QString languageCode = exp.cap(1);
- QLocale locale(languageCode);
- QString languageString =
- QString("%1 (%2)")
- .arg(locale.nativeLanguageName())
- .arg(locale.nativeCountryName()); // QLocale::languageToString(locale.language());
- if (locale.language() == QLocale::Chinese) {
- if (languageCode == "zh_TW") {
- languageString = "Chinese (traditional)";
- } else {
- languageString = "Chinese (simplified)";
- }
- }
- languages.push_back(std::make_pair(QString("%1").arg(languageString), exp.cap(1)));
- // languageBox->addItem(QString("%1").arg(languageString), exp.cap(1));
+ QDirIterator langIter(QCoreApplication::applicationDirPath() + "/translations", QDir::Files);
+ QString pattern = ToQString(AppConfig::translationPrefix()) + "_([a-z]{2,3}(_[A-Z]{2,2})?).qm";
+ QRegExp exp(pattern);
+ while (langIter.hasNext()) {
+ langIter.next();
+ QString file = langIter.fileName();
+ if (exp.exactMatch(file)) {
+ QString languageCode = exp.cap(1);
+ QLocale locale(languageCode);
+ QString languageString = QString("%1 (%2)").arg(locale.nativeLanguageName()).arg(locale.nativeCountryName()); //QLocale::languageToString(locale.language());
+ if (locale.language() == QLocale::Chinese) {
+ if (languageCode == "zh_TW") {
+ languageString = "Chinese (traditional)";
+ } else {
+ languageString = "Chinese (simplified)";
}
+ }
+ languages.push_back(std::make_pair(QString("%1").arg(languageString), exp.cap(1)));
+ //languageBox->addItem(QString("%1").arg(languageString), exp.cap(1));
}
- if (!languageBox->findText("English")) {
- languages.push_back(std::make_pair(QString("English"), QString("en_US")));
- // languageBox->addItem("English", "en_US");
- }
- std::sort(languages.begin(), languages.end());
- for (const auto& lang : languages) {
- languageBox->addItem(lang.first, lang.second);
- }
+ }
+ if (!languageBox->findText("English")) {
+ languages.push_back(std::make_pair(QString("English"), QString("en_US")));
+ //languageBox->addItem("English", "en_US");
+ }
+ std::sort(languages.begin(), languages.end());
+ for (const auto &lang : languages) {
+ languageBox->addItem(lang.first, lang.second);
+ }
}
-void Settings::addStyles(QComboBox* styleBox) {
- styleBox->addItem("None", "");
- styleBox->addItem("Fusion", "Fusion");
+void Settings::addStyles(QComboBox *styleBox)
+{
+ styleBox->addItem("None", "");
+ styleBox->addItem("Fusion", "Fusion");
- QDirIterator langIter(QCoreApplication::applicationDirPath() + "/" + ToQString(AppConfig::stylesheetsPath()),
- QStringList("*.qss"), QDir::Files);
- while (langIter.hasNext()) {
- langIter.next();
- QString style = langIter.fileName();
- styleBox->addItem(style, style);
- }
+ QDirIterator langIter(QCoreApplication::applicationDirPath() + "/" + ToQString(AppConfig::stylesheetsPath()), QStringList("*.qss"), QDir::Files);
+ while (langIter.hasNext()) {
+ langIter.next();
+ QString style = langIter.fileName();
+ styleBox->addItem(style, style);
+ }
}
-void Settings::resetDialogs() { QuestionBoxMemory::resetDialogs(); }
+void Settings::resetDialogs()
+{
+ QuestionBoxMemory::resetDialogs();
+}
-void Settings::query(QWidget* parent) {
- SettingsDialog dialog(parent);
- connect(&dialog, SIGNAL(resetDialogs()), this, SLOT(resetDialogs()));
+void Settings::query(QWidget *parent)
+{
+ SettingsDialog dialog(parent);
- std::vector<std::unique_ptr<SettingsTab>> tabs;
+ connect(&dialog, SIGNAL(resetDialogs()), this, SLOT(resetDialogs()));
- tabs.push_back(std::unique_ptr<SettingsTab>(new GeneralTab(this, dialog)));
- tabs.push_back(std::unique_ptr<SettingsTab>(new PathsTab(this, dialog)));
- tabs.push_back(std::unique_ptr<SettingsTab>(new DiagnosticsTab(this, dialog)));
- tabs.push_back(std::unique_ptr<SettingsTab>(new NexusTab(this, dialog)));
- tabs.push_back(std::unique_ptr<SettingsTab>(new SteamTab(this, dialog)));
- tabs.push_back(std::unique_ptr<SettingsTab>(new PluginsTab(this, dialog)));
- tabs.push_back(std::unique_ptr<SettingsTab>(new WorkaroundsTab(this, dialog)));
+ std::vector<std::unique_ptr<SettingsTab>> tabs;
- if (dialog.exec() == QDialog::Accepted) {
- // remember settings before change
- QMap<QString, QString> before;
- m_Settings.beginGroup("Settings");
- for (auto k : m_Settings.allKeys())
- before[k] = m_Settings.value(k).toString();
- m_Settings.endGroup();
+ tabs.push_back(std::unique_ptr<SettingsTab>(new GeneralTab(this, dialog)));
+ tabs.push_back(std::unique_ptr<SettingsTab>(new PathsTab(this, dialog)));
+ tabs.push_back(std::unique_ptr<SettingsTab>(new DiagnosticsTab(this, dialog)));
+ tabs.push_back(std::unique_ptr<SettingsTab>(new NexusTab(this, dialog)));
+ tabs.push_back(std::unique_ptr<SettingsTab>(new SteamTab(this, dialog)));
+ tabs.push_back(std::unique_ptr<SettingsTab>(new PluginsTab(this, dialog)));
+ tabs.push_back(std::unique_ptr<SettingsTab>(new WorkaroundsTab(this, dialog)));
- // transfer modified settings to configuration file
- for (std::unique_ptr<SettingsTab> const& tab : tabs) {
- tab->update();
- }
+ if (dialog.exec() == QDialog::Accepted) {
+ // remember settings before change
+ QMap<QString, QString> before;
+ m_Settings.beginGroup("Settings");
+ for (auto k : m_Settings.allKeys())
+ before[k] = m_Settings.value(k).toString();
+ m_Settings.endGroup();
- // print "changed" settings
- m_Settings.beginGroup("Settings");
- bool first_update = true;
- for (auto k : m_Settings.allKeys())
- if (m_Settings.value(k).toString() != before[k] && !k.contains("username") && !k.contains("password")) {
- if (first_update) {
- qDebug("Changed settings:");
- first_update = false;
- }
- qDebug(" %s=%s", k.toUtf8().data(), m_Settings.value(k).toString().toUtf8().data());
- }
- m_Settings.endGroup();
+ // transfer modified settings to configuration file
+ for (std::unique_ptr<SettingsTab> const &tab: tabs) {
+ tab->update();
}
+
+ // print "changed" settings
+ m_Settings.beginGroup("Settings");
+ bool first_update = true;
+ for (auto k : m_Settings.allKeys())
+ if (m_Settings.value(k).toString() != before[k] && !k.contains("username") && !k.contains("password"))
+ {
+ if (first_update) {
+ qDebug("Changed settings:");
+ first_update = false;
+ }
+ qDebug(" %s=%s", k.toUtf8().data(), m_Settings.value(k).toString().toUtf8().data());
+ }
+ m_Settings.endGroup();
+ }
}
-Settings::SettingsTab::SettingsTab(Settings* m_parent, SettingsDialog& m_dialog)
- : m_parent(m_parent), m_Settings(m_parent->m_Settings), m_dialog(m_dialog) {}
+Settings::SettingsTab::SettingsTab(Settings *m_parent, SettingsDialog &m_dialog)
+ : m_parent(m_parent)
+ , m_Settings(m_parent->m_Settings)
+ , m_dialog(m_dialog)
+{
+}
-Settings::SettingsTab::~SettingsTab() {}
+Settings::SettingsTab::~SettingsTab()
+{}
-Settings::GeneralTab::GeneralTab(Settings* m_parent, SettingsDialog& m_dialog)
- : Settings::SettingsTab(m_parent, m_dialog), m_languageBox(m_dialog.findChild<QComboBox*>("languageBox")),
- m_styleBox(m_dialog.findChild<QComboBox*>("styleBox")),
- m_compactBox(m_dialog.findChild<QCheckBox*>("compactBox")),
- m_showMetaBox(m_dialog.findChild<QCheckBox*>("showMetaBox")),
- m_usePrereleaseBox(m_dialog.findChild<QCheckBox*>("usePrereleaseBox")) {
- // FIXME I think 'addLanguages' lives in here not in parent
- m_parent->addLanguages(m_languageBox);
- {
- QString languageCode = m_parent->language();
- int currentID = m_languageBox->findData(languageCode);
- // I made a mess. :( Most languages are stored with only the iso country
- // code (2 characters like "de") but chinese
- // with the exact language variant (zh_TW) so I have to search for both
- // variants
- if (currentID == -1) {
- currentID = m_languageBox->findData(languageCode.mid(0, 2));
- }
- if (currentID != -1) {
- m_languageBox->setCurrentIndex(currentID);
- }
+Settings::GeneralTab::GeneralTab(Settings *m_parent, SettingsDialog &m_dialog)
+ : Settings::SettingsTab(m_parent, m_dialog)
+ , m_languageBox(m_dialog.findChild<QComboBox *>("languageBox"))
+ , m_styleBox(m_dialog.findChild<QComboBox *>("styleBox"))
+ , m_compactBox(m_dialog.findChild<QCheckBox *>("compactBox"))
+ , m_showMetaBox(m_dialog.findChild<QCheckBox *>("showMetaBox"))
+ , m_usePrereleaseBox(m_dialog.findChild<QCheckBox *>("usePrereleaseBox"))
+{
+ // FIXME I think 'addLanguages' lives in here not in parent
+ m_parent->addLanguages(m_languageBox);
+ {
+ QString languageCode = m_parent->language();
+ int currentID = m_languageBox->findData(languageCode);
+ // I made a mess. :( Most languages are stored with only the iso country
+ // code (2 characters like "de") but chinese
+ // with the exact language variant (zh_TW) so I have to search for both
+ // variants
+ if (currentID == -1) {
+ currentID = m_languageBox->findData(languageCode.mid(0, 2));
}
+ if (currentID != -1) {
+ m_languageBox->setCurrentIndex(currentID);
+ }
+ }
- // FIXME I think addStyles lives in here not in parent
- m_parent->addStyles(m_styleBox);
- {
- int currentID = m_styleBox->findData(m_Settings.value("Settings/style", "").toString());
- if (currentID != -1) {
- m_styleBox->setCurrentIndex(currentID);
- }
+ // FIXME I think addStyles lives in here not in parent
+ m_parent->addStyles(m_styleBox);
+ {
+ int currentID = m_styleBox->findData(
+ m_Settings.value("Settings/style", "").toString());
+ if (currentID != -1) {
+ m_styleBox->setCurrentIndex(currentID);
}
+ }
- m_compactBox->setChecked(m_parent->compactDownloads());
- m_showMetaBox->setChecked(m_parent->metaDownloads());
- m_usePrereleaseBox->setChecked(m_parent->usePrereleases());
+ m_compactBox->setChecked(m_parent->compactDownloads());
+ m_showMetaBox->setChecked(m_parent->metaDownloads());
+ m_usePrereleaseBox->setChecked(m_parent->usePrereleases());
}
-void Settings::GeneralTab::update() {
- QString oldLanguage = m_parent->language();
- QString newLanguage = m_languageBox->itemData(m_languageBox->currentIndex()).toString();
- if (newLanguage != oldLanguage) {
- m_Settings.setValue("Settings/language", newLanguage);
- emit m_parent->languageChanged(newLanguage);
- }
+void Settings::GeneralTab::update()
+{
+ QString oldLanguage = m_parent->language();
+ QString newLanguage = m_languageBox->itemData(m_languageBox->currentIndex()).toString();
+ if (newLanguage != oldLanguage) {
+ m_Settings.setValue("Settings/language", newLanguage);
+ emit m_parent->languageChanged(newLanguage);
+ }
- QString oldStyle = m_Settings.value("Settings/style", "").toString();
- QString newStyle = m_styleBox->itemData(m_styleBox->currentIndex()).toString();
- if (oldStyle != newStyle) {
- m_Settings.setValue("Settings/style", newStyle);
- emit m_parent->styleChanged(newStyle);
- }
+ QString oldStyle = m_Settings.value("Settings/style", "").toString();
+ QString newStyle = m_styleBox->itemData(m_styleBox->currentIndex()).toString();
+ if (oldStyle != newStyle) {
+ m_Settings.setValue("Settings/style", newStyle);
+ emit m_parent->styleChanged(newStyle);
+ }
- m_Settings.setValue("Settings/compact_downloads", m_compactBox->isChecked());
- m_Settings.setValue("Settings/meta_downloads", m_showMetaBox->isChecked());
- m_Settings.setValue("Settings/use_prereleases", m_usePrereleaseBox->isChecked());
+ m_Settings.setValue("Settings/compact_downloads", m_compactBox->isChecked());
+ m_Settings.setValue("Settings/meta_downloads", m_showMetaBox->isChecked());
+ m_Settings.setValue("Settings/use_prereleases", m_usePrereleaseBox->isChecked());
}
-Settings::PathsTab::PathsTab(Settings* parent, SettingsDialog& dialog)
- : SettingsTab(parent, dialog), m_baseDirEdit(m_dialog.findChild<QLineEdit*>("baseDirEdit")),
- m_downloadDirEdit(m_dialog.findChild<QLineEdit*>("downloadDirEdit")),
- m_modDirEdit(m_dialog.findChild<QLineEdit*>("modDirEdit")),
- m_cacheDirEdit(m_dialog.findChild<QLineEdit*>("cacheDirEdit")),
- m_profilesDirEdit(m_dialog.findChild<QLineEdit*>("profilesDirEdit")),
- m_overwriteDirEdit(m_dialog.findChild<QLineEdit*>("overwriteDirEdit")) {
- m_baseDirEdit->setText(m_parent->getBaseDirectory());
+Settings::PathsTab::PathsTab(Settings *parent, SettingsDialog &dialog)
+ : SettingsTab(parent, dialog)
+ , m_baseDirEdit(m_dialog.findChild<QLineEdit *>("baseDirEdit"))
+ , m_downloadDirEdit(m_dialog.findChild<QLineEdit *>("downloadDirEdit"))
+ , m_modDirEdit(m_dialog.findChild<QLineEdit *>("modDirEdit"))
+ , m_cacheDirEdit(m_dialog.findChild<QLineEdit *>("cacheDirEdit"))
+ , m_profilesDirEdit(m_dialog.findChild<QLineEdit *>("profilesDirEdit"))
+ , m_overwriteDirEdit(m_dialog.findChild<QLineEdit *>("overwriteDirEdit"))
+{
+ m_baseDirEdit->setText(m_parent->getBaseDirectory());
- QString basePath = parent->getBaseDirectory();
- QDir baseDir(basePath);
- for (const auto& dir : {std::make_pair(m_downloadDirEdit, m_parent->getDownloadDirectory(false)),
- std::make_pair(m_modDirEdit, m_parent->getModDirectory(false)),
- std::make_pair(m_cacheDirEdit, m_parent->getCacheDirectory(false)),
- std::make_pair(m_profilesDirEdit, m_parent->getProfileDirectory(false)),
- std::make_pair(m_overwriteDirEdit, m_parent->getOverwriteDirectory(false))}) {
- QString storePath = baseDir.relativeFilePath(dir.second);
- storePath = dir.second;
- dir.first->setText(storePath);
- }
+ QString basePath = parent->getBaseDirectory();
+ QDir baseDir(basePath);
+ for (const auto &dir : {
+ std::make_pair(m_downloadDirEdit, m_parent->getDownloadDirectory(false)),
+ std::make_pair(m_modDirEdit, m_parent->getModDirectory(false)),
+ std::make_pair(m_cacheDirEdit, m_parent->getCacheDirectory(false)),
+ std::make_pair(m_profilesDirEdit, m_parent->getProfileDirectory(false)),
+ std::make_pair(m_overwriteDirEdit, m_parent->getOverwriteDirectory(false))
+ }) {
+ QString storePath = baseDir.relativeFilePath(dir.second);
+ storePath = dir.second;
+ dir.first->setText(storePath);
+ }
}
-void Settings::PathsTab::update() {
- typedef std::tuple<QString, QString, std::wstring> Directory;
-
- QString basePath = m_parent->getBaseDirectory();
+void Settings::PathsTab::update()
+{
+ typedef std::tuple<QString, QString, std::wstring> Directory;
- for (const Directory& dir :
- {Directory{m_downloadDirEdit->text(), "download_directory", AppConfig::downloadPath()},
- Directory{m_cacheDirEdit->text(), "cache_directory", AppConfig::cachePath()},
- Directory{m_modDirEdit->text(), "mod_directory", AppConfig::modsPath()},
- Directory{m_overwriteDirEdit->text(), "overwrite_directory", AppConfig::overwritePath()},
- Directory{m_profilesDirEdit->text(), "profiles_directory", AppConfig::profilesPath()}}) {
- QString path, settingsKey;
- std::wstring defaultName;
- std::tie(path, settingsKey, defaultName) = dir;
+ QString basePath = m_parent->getBaseDirectory();
- settingsKey = QString("Settings/%1").arg(settingsKey);
+ for (const Directory &dir :{
+ Directory{m_downloadDirEdit->text(), "download_directory", AppConfig::downloadPath()},
+ Directory{m_cacheDirEdit->text(), "cache_directory", AppConfig::cachePath()},
+ Directory{m_modDirEdit->text(), "mod_directory", AppConfig::modsPath()},
+ Directory{m_overwriteDirEdit->text(), "overwrite_directory", AppConfig::overwritePath()},
+ Directory{m_profilesDirEdit->text(), "profiles_directory", AppConfig::profilesPath()}
+ }) {
+ QString path, settingsKey;
+ std::wstring defaultName;
+ std::tie(path, settingsKey, defaultName) = dir;
- QString realPath = path;
- realPath.replace("%BASE_DIR%", m_baseDirEdit->text());
+ settingsKey = QString("Settings/%1").arg(settingsKey);
- if (!QDir(realPath).exists()) {
- if (!QDir().mkpath(realPath)) {
- QMessageBox::warning(qApp->activeWindow(), tr("Error"),
- tr("Failed to create \"%1\", you may not have the "
- "necessary permission. path remains unchanged.")
- .arg(realPath));
- }
- }
+ QString realPath = path;
+ realPath.replace("%BASE_DIR%", m_baseDirEdit->text());
- if (QFileInfo(realPath) != QFileInfo(basePath + "/" + QString::fromStdWString(defaultName))) {
- m_Settings.setValue(settingsKey, path);
- } else {
- m_Settings.remove(settingsKey);
- }
+ if (!QDir(realPath).exists()) {
+ if (!QDir().mkpath(realPath)) {
+ QMessageBox::warning(qApp->activeWindow(), tr("Error"),
+ tr("Failed to create \"%1\", you may not have the "
+ "necessary permission. path remains unchanged.")
+ .arg(realPath));
+ }
}
- if (QFileInfo(m_baseDirEdit->text()) != QFileInfo(qApp->property("dataPath").toString())) {
- m_Settings.setValue("Settings/base_directory", m_baseDirEdit->text());
+ if (QFileInfo(realPath)
+ != QFileInfo(basePath + "/" + QString::fromStdWString(defaultName))) {
+ m_Settings.setValue(settingsKey, path);
} else {
- m_Settings.remove("Settings/base_directory");
+ m_Settings.remove(settingsKey);
}
+ }
+
+ if (QFileInfo(m_baseDirEdit->text()) !=
+ QFileInfo(qApp->property("dataPath").toString())) {
+ m_Settings.setValue("Settings/base_directory", m_baseDirEdit->text());
+ } else {
+ m_Settings.remove("Settings/base_directory");
+ }
}
-Settings::DiagnosticsTab::DiagnosticsTab(Settings* m_parent, SettingsDialog& m_dialog)
- : Settings::SettingsTab(m_parent, m_dialog), m_logLevelBox(m_dialog.findChild<QComboBox*>("logLevelBox")),
- m_dumpsTypeBox(m_dialog.findChild<QComboBox*>("dumpsTypeBox")),
- m_dumpsMaxEdit(m_dialog.findChild<QSpinBox*>("dumpsMaxEdit")),
- m_diagnosticsExplainedLabel(m_dialog.findChild<QLabel*>("diagnosticsExplainedLabel")) {
- m_logLevelBox->setCurrentIndex(m_parent->logLevel());
- m_dumpsTypeBox->setCurrentIndex(m_parent->crashDumpsType());
- m_dumpsMaxEdit->setValue(m_parent->crashDumpsMax());
- QString logsPath = qApp->property("dataPath").toString() + "/" + QString::fromStdWString(AppConfig::logPath());
- m_diagnosticsExplainedLabel->setText(
- m_diagnosticsExplainedLabel->text()
- .replace("LOGS_FULL_PATH", logsPath)
- .replace("LOGS_DIR", QString::fromStdWString(AppConfig::logPath()))
- .replace("DUMPS_FULL_PATH", QString::fromStdWString(OrganizerCore::crashDumpsPath()))
- .replace("DUMPS_DIR", QString::fromStdWString(AppConfig::dumpsDir())));
+Settings::DiagnosticsTab::DiagnosticsTab(Settings *m_parent, SettingsDialog &m_dialog)
+ : Settings::SettingsTab(m_parent, m_dialog)
+ , m_logLevelBox(m_dialog.findChild<QComboBox *>("logLevelBox"))
+ , m_dumpsTypeBox(m_dialog.findChild<QComboBox *>("dumpsTypeBox"))
+ , m_dumpsMaxEdit(m_dialog.findChild<QSpinBox *>("dumpsMaxEdit"))
+ , m_diagnosticsExplainedLabel(m_dialog.findChild<QLabel *>("diagnosticsExplainedLabel"))
+{
+ m_logLevelBox->setCurrentIndex(m_parent->logLevel());
+ m_dumpsTypeBox->setCurrentIndex(m_parent->crashDumpsType());
+ m_dumpsMaxEdit->setValue(m_parent->crashDumpsMax());
+ QString logsPath = qApp->property("dataPath").toString()
+ + "/" + QString::fromStdWString(AppConfig::logPath());
+ m_diagnosticsExplainedLabel->setText(
+ m_diagnosticsExplainedLabel->text()
+ .replace("LOGS_FULL_PATH", logsPath)
+ .replace("LOGS_DIR", QString::fromStdWString(AppConfig::logPath()))
+ .replace("DUMPS_FULL_PATH", QString::fromStdWString(OrganizerCore::crashDumpsPath()))
+ .replace("DUMPS_DIR", QString::fromStdWString(AppConfig::dumpsDir()))
+ );
}
-void Settings::DiagnosticsTab::update() {
- m_Settings.setValue("Settings/log_level", m_logLevelBox->currentIndex());
- m_Settings.setValue("Settings/crash_dumps_type", m_dumpsTypeBox->currentIndex());
- m_Settings.setValue("Settings/crash_dumps_max", m_dumpsMaxEdit->value());
+void Settings::DiagnosticsTab::update()
+{
+ m_Settings.setValue("Settings/log_level", m_logLevelBox->currentIndex());
+ m_Settings.setValue("Settings/crash_dumps_type", m_dumpsTypeBox->currentIndex());
+ m_Settings.setValue("Settings/crash_dumps_max", m_dumpsMaxEdit->value());
}
-Settings::NexusTab::NexusTab(Settings* parent, SettingsDialog& dialog)
- : Settings::SettingsTab(parent, dialog), m_loginCheckBox(dialog.findChild<QCheckBox*>("loginCheckBox")),
- m_usernameEdit(dialog.findChild<QLineEdit*>("usernameEdit")),
- m_passwordEdit(dialog.findChild<QLineEdit*>("passwordEdit")),
- m_offlineBox(dialog.findChild<QCheckBox*>("offlineBox")), m_proxyBox(dialog.findChild<QCheckBox*>("proxyBox")),
- m_knownServersList(dialog.findChild<QListWidget*>("knownServersList")),
- m_preferredServersList(dialog.findChild<QListWidget*>("preferredServersList")) {
- if (parent->automaticLoginEnabled()) {
- m_loginCheckBox->setChecked(true);
- m_usernameEdit->setText(m_Settings.value("Settings/nexus_username", "").toString());
- m_passwordEdit->setText(deObfuscate(m_Settings.value("Settings/nexus_password", "").toString()));
- }
+Settings::NexusTab::NexusTab(Settings *parent, SettingsDialog &dialog)
+ : Settings::SettingsTab(parent, dialog)
+ , m_loginCheckBox(dialog.findChild<QCheckBox *>("loginCheckBox"))
+ , m_usernameEdit(dialog.findChild<QLineEdit *>("usernameEdit"))
+ , m_passwordEdit(dialog.findChild<QLineEdit *>("passwordEdit"))
+ , m_offlineBox(dialog.findChild<QCheckBox *>("offlineBox"))
+ , m_proxyBox(dialog.findChild<QCheckBox *>("proxyBox"))
+ , m_knownServersList(dialog.findChild<QListWidget *>("knownServersList"))
+ , m_preferredServersList(
+ dialog.findChild<QListWidget *>("preferredServersList"))
+{
+ if (parent->automaticLoginEnabled()) {
+ m_loginCheckBox->setChecked(true);
+ m_usernameEdit->setText(m_Settings.value("Settings/nexus_username", "").toString());
+ m_passwordEdit->setText(deObfuscate(m_Settings.value("Settings/nexus_password", "").toString()));
+ }
- m_offlineBox->setChecked(parent->offlineMode());
- m_proxyBox->setChecked(parent->useProxy());
+ m_offlineBox->setChecked(parent->offlineMode());
+ m_proxyBox->setChecked(parent->useProxy());
- // display server preferences
- m_Settings.beginGroup("Servers");
- for (const QString& key : m_Settings.childKeys()) {
- QVariantMap val = m_Settings.value(key).toMap();
- QString type = val["premium"].toBool() ? "(premium)" : "(free)";
+ // display server preferences
+ m_Settings.beginGroup("Servers");
+ for (const QString &key : m_Settings.childKeys()) {
+ QVariantMap val = m_Settings.value(key).toMap();
+ QString type = val["premium"].toBool() ? "(premium)" : "(free)";
- QString descriptor = key + " " + type;
- if (val.contains("downloadSpeed") && val.contains("downloadCount") && (val["downloadCount"].toInt() > 0)) {
- int bps = static_cast<int>(val["downloadSpeed"].toDouble() / val["downloadCount"].toInt());
- descriptor += QString(" (%1 kbps)").arg(bps / 1024);
- }
+ QString descriptor = key + " " + type;
+ if (val.contains("downloadSpeed") && val.contains("downloadCount") && (val["downloadCount"].toInt() > 0)) {
+ int bps = static_cast<int>(val["downloadSpeed"].toDouble() / val["downloadCount"].toInt());
+ descriptor += QString(" (%1 kbps)").arg(bps / 1024);
+ }
- QListWidgetItem* newItem = new QListWidgetItemEx<int>(descriptor, Qt::UserRole + 1);
+ QListWidgetItem *newItem = new QListWidgetItemEx<int>(descriptor, Qt::UserRole + 1);
- newItem->setData(Qt::UserRole, key);
- newItem->setData(Qt::UserRole + 1, val["preferred"].toInt());
- if (val["preferred"].toInt() > 0) {
- m_preferredServersList->addItem(newItem);
- } else {
- m_knownServersList->addItem(newItem);
- }
- m_preferredServersList->sortItems(Qt::DescendingOrder);
+ newItem->setData(Qt::UserRole, key);
+ newItem->setData(Qt::UserRole + 1, val["preferred"].toInt());
+ if (val["preferred"].toInt() > 0) {
+ m_preferredServersList->addItem(newItem);
+ } else {
+ m_knownServersList->addItem(newItem);
}
- m_Settings.endGroup();
+ m_preferredServersList->sortItems(Qt::DescendingOrder);
+ }
+ m_Settings.endGroup();
}
-void Settings::NexusTab::update() {
- if (m_loginCheckBox->isChecked()) {
- m_Settings.setValue("Settings/nexus_login", true);
- m_Settings.setValue("Settings/nexus_username", m_usernameEdit->text());
- m_Settings.setValue("Settings/nexus_password", obfuscate(m_passwordEdit->text()));
- } else {
- m_Settings.setValue("Settings/nexus_login", false);
- m_Settings.remove("Settings/nexus_username");
- m_Settings.remove("Settings/nexus_password");
- }
- m_Settings.setValue("Settings/offline_mode", m_offlineBox->isChecked());
- m_Settings.setValue("Settings/use_proxy", m_proxyBox->isChecked());
+void Settings::NexusTab::update()
+{
+ if (m_loginCheckBox->isChecked()) {
+ m_Settings.setValue("Settings/nexus_login", true);
+ m_Settings.setValue("Settings/nexus_username", m_usernameEdit->text());
+ m_Settings.setValue("Settings/nexus_password", obfuscate(m_passwordEdit->text()));
+ } else {
+ m_Settings.setValue("Settings/nexus_login", false);
+ m_Settings.remove("Settings/nexus_username");
+ m_Settings.remove("Settings/nexus_password");
+ }
+ m_Settings.setValue("Settings/offline_mode", m_offlineBox->isChecked());
+ m_Settings.setValue("Settings/use_proxy", m_proxyBox->isChecked());
- // store server preference
- m_Settings.beginGroup("Servers");
- for (int i = 0; i < m_knownServersList->count(); ++i) {
- QString key = m_knownServersList->item(i)->data(Qt::UserRole).toString();
- QVariantMap val = m_Settings.value(key).toMap();
- val["preferred"] = 0;
- m_Settings.setValue(key, val);
- }
- int count = m_preferredServersList->count();
- for (int i = 0; i < count; ++i) {
- QString key = m_preferredServersList->item(i)->data(Qt::UserRole).toString();
- QVariantMap val = m_Settings.value(key).toMap();
- val["preferred"] = count - i;
- m_Settings.setValue(key, val);
- }
- m_Settings.endGroup();
+ // store server preference
+ m_Settings.beginGroup("Servers");
+ for (int i = 0; i < m_knownServersList->count(); ++i) {
+ QString key = m_knownServersList->item(i)->data(Qt::UserRole).toString();
+ QVariantMap val = m_Settings.value(key).toMap();
+ val["preferred"] = 0;
+ m_Settings.setValue(key, val);
+ }
+ int count = m_preferredServersList->count();
+ for (int i = 0; i < count; ++i) {
+ QString key = m_preferredServersList->item(i)->data(Qt::UserRole).toString();
+ QVariantMap val = m_Settings.value(key).toMap();
+ val["preferred"] = count - i;
+ m_Settings.setValue(key, val);
+ }
+ m_Settings.endGroup();
}
-Settings::SteamTab::SteamTab(Settings* m_parent, SettingsDialog& m_dialog)
- : Settings::SettingsTab(m_parent, m_dialog), m_steamUserEdit(m_dialog.findChild<QLineEdit*>("steamUserEdit")),
- m_steamPassEdit(m_dialog.findChild<QLineEdit*>("steamPassEdit")) {
- if (m_Settings.contains("Settings/steam_username")) {
- m_steamUserEdit->setText(m_Settings.value("Settings/steam_username", "").toString());
- if (m_Settings.contains("Settings/steam_password")) {
- m_steamPassEdit->setText(deObfuscate(m_Settings.value("Settings/steam_password", "").toString()));
- }
+Settings::SteamTab::SteamTab(Settings *m_parent, SettingsDialog &m_dialog)
+ : Settings::SettingsTab(m_parent, m_dialog)
+ , m_steamUserEdit(m_dialog.findChild<QLineEdit *>("steamUserEdit"))
+ , m_steamPassEdit(m_dialog.findChild<QLineEdit *>("steamPassEdit"))
+{
+ if (m_Settings.contains("Settings/steam_username")) {
+ m_steamUserEdit->setText(m_Settings.value("Settings/steam_username", "").toString());
+ if (m_Settings.contains("Settings/steam_password")) {
+ m_steamPassEdit->setText(deObfuscate(m_Settings.value("Settings/steam_password", "").toString()));
}
+ }
}
-void Settings::SteamTab::update() {
- // FIXME this should be inlined here?
- m_parent->setSteamLogin(m_steamUserEdit->text(), m_steamPassEdit->text());
+void Settings::SteamTab::update()
+{
+ //FIXME this should be inlined here?
+ m_parent->setSteamLogin(m_steamUserEdit->text(), m_steamPassEdit->text());
}
-Settings::PluginsTab::PluginsTab(Settings* m_parent, SettingsDialog& m_dialog)
- : Settings::SettingsTab(m_parent, m_dialog), m_pluginsList(m_dialog.findChild<QListWidget*>("pluginsList")),
- m_pluginBlacklistList(m_dialog.findChild<QListWidget*>("pluginBlacklist")) {
- // display plugin settings
- for (IPlugin* plugin : m_parent->m_Plugins) {
- QListWidgetItem* listItem = new QListWidgetItem(plugin->name(), m_pluginsList);
- listItem->setData(Qt::UserRole, QVariant::fromValue((void*)plugin));
- listItem->setData(Qt::UserRole + 1, m_parent->m_PluginSettings[plugin->name()]);
- listItem->setData(Qt::UserRole + 2, m_parent->m_PluginDescriptions[plugin->name()]);
- m_pluginsList->addItem(listItem);
- }
+Settings::PluginsTab::PluginsTab(Settings *m_parent, SettingsDialog &m_dialog)
+ : Settings::SettingsTab(m_parent, m_dialog)
+ , m_pluginsList(m_dialog.findChild<QListWidget *>("pluginsList"))
+ , m_pluginBlacklistList(m_dialog.findChild<QListWidget *>("pluginBlacklist"))
+{
+ // display plugin settings
+ for (IPlugin *plugin : m_parent->m_Plugins) {
+ QListWidgetItem *listItem = new QListWidgetItem(plugin->name(), m_pluginsList);
+ listItem->setData(Qt::UserRole, QVariant::fromValue((void*)plugin));
+ listItem->setData(Qt::UserRole + 1, m_parent->m_PluginSettings[plugin->name()]);
+ listItem->setData(Qt::UserRole + 2, m_parent->m_PluginDescriptions[plugin->name()]);
+ m_pluginsList->addItem(listItem);
+ }
- // display plugin blacklist
- for (const QString& pluginName : m_parent->m_PluginBlacklist) {
- m_pluginBlacklistList->addItem(pluginName);
- }
+ // display plugin blacklist
+ for (const QString &pluginName : m_parent->m_PluginBlacklist) {
+ m_pluginBlacklistList->addItem(pluginName);
+ }
}
-void Settings::PluginsTab::update() {
- // transfer plugin settings to in-memory structure
- for (int i = 0; i < m_pluginsList->count(); ++i) {
- QListWidgetItem* item = m_pluginsList->item(i);
- m_parent->m_PluginSettings[item->text()] = item->data(Qt::UserRole + 1).toMap();
- }
- // store plugin settings on disc
- for (auto iterPlugins = m_parent->m_PluginSettings.begin(); iterPlugins != m_parent->m_PluginSettings.end();
- ++iterPlugins) {
- for (auto iterSettings = iterPlugins->begin(); iterSettings != iterPlugins->end(); ++iterSettings) {
- m_Settings.setValue("Plugins/" + iterPlugins.key() + "/" + iterSettings.key(), iterSettings.value());
- }
+void Settings::PluginsTab::update()
+{
+ // transfer plugin settings to in-memory structure
+ for (int i = 0; i < m_pluginsList->count(); ++i) {
+ QListWidgetItem *item = m_pluginsList->item(i);
+ m_parent->m_PluginSettings[item->text()] = item->data(Qt::UserRole + 1).toMap();
+ }
+ // store plugin settings on disc
+ for (auto iterPlugins = m_parent->m_PluginSettings.begin(); iterPlugins != m_parent->m_PluginSettings.end(); ++iterPlugins) {
+ for (auto iterSettings = iterPlugins->begin(); iterSettings != iterPlugins->end(); ++iterSettings) {
+ m_Settings.setValue("Plugins/" + iterPlugins.key() + "/" + iterSettings.key(), iterSettings.value());
}
+ }
- // store plugin blacklist
- m_parent->m_PluginBlacklist.clear();
- for (QListWidgetItem* item : m_pluginBlacklistList->findItems("*", Qt::MatchWildcard)) {
- m_parent->m_PluginBlacklist.insert(item->text());
- }
- m_parent->writePluginBlacklist();
+ // store plugin blacklist
+ m_parent->m_PluginBlacklist.clear();
+ for (QListWidgetItem *item : m_pluginBlacklistList->findItems("*", Qt::MatchWildcard)) {
+ m_parent->m_PluginBlacklist.insert(item->text());
+ }
+ m_parent->writePluginBlacklist();
}
-Settings::WorkaroundsTab::WorkaroundsTab(Settings* m_parent, SettingsDialog& m_dialog)
- : Settings::SettingsTab(m_parent, m_dialog), m_appIDEdit(m_dialog.findChild<QLineEdit*>("appIDEdit")),
- m_mechanismBox(m_dialog.findChild<QComboBox*>("mechanismBox")),
- m_nmmVersionEdit(m_dialog.findChild<QLineEdit*>("nmmVersionEdit")),
- m_hideUncheckedBox(m_dialog.findChild<QCheckBox*>("hideUncheckedBox")),
- m_forceEnableBox(m_dialog.findChild<QCheckBox*>("forceEnableBox")),
- m_displayForeignBox(m_dialog.findChild<QCheckBox*>("displayForeignBox")) {
- m_appIDEdit->setText(m_parent->getSteamAppID());
+Settings::WorkaroundsTab::WorkaroundsTab(Settings *m_parent,
+ SettingsDialog &m_dialog)
+ : Settings::SettingsTab(m_parent, m_dialog)
+ , m_appIDEdit(m_dialog.findChild<QLineEdit *>("appIDEdit"))
+ , m_mechanismBox(m_dialog.findChild<QComboBox *>("mechanismBox"))
+ , m_nmmVersionEdit(m_dialog.findChild<QLineEdit *>("nmmVersionEdit"))
+ , m_hideUncheckedBox(m_dialog.findChild<QCheckBox *>("hideUncheckedBox"))
+ , m_forceEnableBox(m_dialog.findChild<QCheckBox *>("forceEnableBox"))
+ , m_displayForeignBox(m_dialog.findChild<QCheckBox *>("displayForeignBox"))
+{
+ m_appIDEdit->setText(m_parent->getSteamAppID());
- LoadMechanism::EMechanism mechanismID = m_parent->getLoadMechanism();
- int index = 0;
+ LoadMechanism::EMechanism mechanismID = m_parent->getLoadMechanism();
+ int index = 0;
- if (m_parent->m_LoadMechanism.isDirectLoadingSupported()) {
- m_mechanismBox->addItem(QObject::tr("Mod Organizer"), LoadMechanism::LOAD_MODORGANIZER);
- if (mechanismID == LoadMechanism::LOAD_MODORGANIZER) {
- index = m_mechanismBox->count() - 1;
- }
+ if (m_parent->m_LoadMechanism.isDirectLoadingSupported()) {
+ m_mechanismBox->addItem(QObject::tr("Mod Organizer"), LoadMechanism::LOAD_MODORGANIZER);
+ if (mechanismID == LoadMechanism::LOAD_MODORGANIZER) {
+ index = m_mechanismBox->count() - 1;
}
+ }
- if (m_parent->m_LoadMechanism.isScriptExtenderSupported()) {
- m_mechanismBox->addItem(QObject::tr("Script Extender"), LoadMechanism::LOAD_SCRIPTEXTENDER);
- if (mechanismID == LoadMechanism::LOAD_SCRIPTEXTENDER) {
- index = m_mechanismBox->count() - 1;
- }
+ if (m_parent->m_LoadMechanism.isScriptExtenderSupported()) {
+ m_mechanismBox->addItem(QObject::tr("Script Extender"), LoadMechanism::LOAD_SCRIPTEXTENDER);
+ if (mechanismID == LoadMechanism::LOAD_SCRIPTEXTENDER) {
+ index = m_mechanismBox->count() - 1;
}
+ }
- if (m_parent->m_LoadMechanism.isProxyDLLSupported()) {
- m_mechanismBox->addItem(QObject::tr("Proxy DLL"), LoadMechanism::LOAD_PROXYDLL);
- if (mechanismID == LoadMechanism::LOAD_PROXYDLL) {
- index = m_mechanismBox->count() - 1;
- }
+ if (m_parent->m_LoadMechanism.isProxyDLLSupported()) {
+ m_mechanismBox->addItem(QObject::tr("Proxy DLL"), LoadMechanism::LOAD_PROXYDLL);
+ if (mechanismID == LoadMechanism::LOAD_PROXYDLL) {
+ index = m_mechanismBox->count() - 1;
}
+ }
- m_mechanismBox->setCurrentIndex(index);
+ m_mechanismBox->setCurrentIndex(index);
+
+ m_nmmVersionEdit->setText(m_parent->getNMMVersion());
+ m_hideUncheckedBox->setChecked(m_parent->hideUncheckedPlugins());
+ m_forceEnableBox->setChecked(m_parent->forceEnableCoreFiles());
+ m_displayForeignBox->setChecked(m_parent->displayForeign());
- m_nmmVersionEdit->setText(m_parent->getNMMVersion());
- m_hideUncheckedBox->setChecked(m_parent->hideUncheckedPlugins());
- m_forceEnableBox->setChecked(m_parent->forceEnableCoreFiles());
- m_displayForeignBox->setChecked(m_parent->displayForeign());
}
-void Settings::WorkaroundsTab::update() {
- if (m_appIDEdit->text() != m_parent->m_GamePlugin->steamAPPId()) {
- m_Settings.setValue("Settings/app_id", m_appIDEdit->text());
- } else {
- m_Settings.remove("Settings/app_id");
- }
- m_Settings.setValue("Settings/load_mechanism", m_mechanismBox->itemData(m_mechanismBox->currentIndex()).toInt());
- m_Settings.setValue("Settings/nmm_version", m_nmmVersionEdit->text());
- m_Settings.setValue("Settings/hide_unchecked_plugins", m_hideUncheckedBox->isChecked());
- m_Settings.setValue("Settings/force_enable_core_files", m_forceEnableBox->isChecked());
- m_Settings.setValue("Settings/display_foreign", m_displayForeignBox->isChecked());
+void Settings::WorkaroundsTab::update()
+{
+ if (m_appIDEdit->text() != m_parent->m_GamePlugin->steamAPPId()) {
+ m_Settings.setValue("Settings/app_id", m_appIDEdit->text());
+ } else {
+ m_Settings.remove("Settings/app_id");
+ }
+ m_Settings.setValue("Settings/load_mechanism", m_mechanismBox->itemData(m_mechanismBox->currentIndex()).toInt());
+ m_Settings.setValue("Settings/nmm_version", m_nmmVersionEdit->text());
+ m_Settings.setValue("Settings/hide_unchecked_plugins", m_hideUncheckedBox->isChecked());
+ m_Settings.setValue("Settings/force_enable_core_files", m_forceEnableBox->isChecked());
+ m_Settings.setValue("Settings/display_foreign", m_displayForeignBox->isChecked());
}
diff --git a/src/settings.h b/src/settings.h
index 015a2c13..ae38223f 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -46,9 +46,9 @@ class QLabel;
struct ServerInfo;
namespace MOBase {
-class IPlugin;
-class IPluginGame;
-} // namespace MOBase
+ class IPlugin;
+ class IPluginGame;
+}
class SettingsDialog;
@@ -56,441 +56,455 @@ class SettingsDialog;
* manages the settings for Mod Organizer. The settings are not cached
* inside the class but read/written directly from/to disc
**/
-class Settings : public QObject {
+class Settings : public QObject
+{
- Q_OBJECT
+ Q_OBJECT
public:
- /**
- * @brief constructor
- **/
- Settings(const QSettings& settingsSource);
- virtual ~Settings();
+ /**
+ * @brief constructor
+ **/
+ Settings(const QSettings &settingsSource);
- static Settings& instance();
+ virtual ~Settings();
- /**
- * unregister all plugins from settings
- */
- void clearPlugins();
+ static Settings &instance();
- /**
- * @brief register plugin to be configurable
- * @param plugin the plugin to register
- * @return true if the plugin may be registered, false if it is blacklisted
- */
- void registerPlugin(MOBase::IPlugin* plugin);
+ /**
+ * unregister all plugins from settings
+ */
+ void clearPlugins();
- /**
- * displays a SettingsDialog that allows the user to change settings. If the
- * user accepts the changes, the settings are immediately written
- **/
- void query(QWidget* parent);
+ /**
+ * @brief register plugin to be configurable
+ * @param plugin the plugin to register
+ * @return true if the plugin may be registered, false if it is blacklisted
+ */
+ void registerPlugin(MOBase::IPlugin *plugin);
- /**
- * set up the settings for the specified plugins
- **/
- void addPluginSettings(const std::vector<MOBase::IPlugin*>& plugins);
+ /**
+ * displays a SettingsDialog that allows the user to change settings. If the
+ * user accepts the changes, the settings are immediately written
+ **/
+ void query(QWidget *parent);
- /**
- * @return true if the user wants unchecked plugins (esp, esm) should be hidden from
- * the virtual dat adirectory
- **/
- bool hideUncheckedPlugins() const;
+ /**
+ * set up the settings for the specified plugins
+ **/
+ void addPluginSettings(const std::vector<MOBase::IPlugin*> &plugins);
- /**
- * @return true if files of the core game are forced-enabled so the user can't accidentally disable them
- */
- bool forceEnableCoreFiles() const;
+ /**
+ * @return true if the user wants unchecked plugins (esp, esm) should be hidden from
+ * the virtual dat adirectory
+ **/
+ bool hideUncheckedPlugins() const;
- /**
- * @brief register download speed
- * @param url complete download url
- * @param bytesPerSecond download size in bytes per second
- */
- void setDownloadSpeed(const QString& serverName, int bytesPerSecond);
+ /**
+ * @return true if files of the core game are forced-enabled so the user can't accidentally disable them
+ */
+ bool forceEnableCoreFiles() const;
- /**
- * the steam appid is assigned by the steam platform to each product sold there.
- * The appid may differ between different versions of a game so it may be impossible
- * for Mod Organizer to automatically recognize it, though usually it does
- * @return the steam appid for the game
- **/
- QString getSteamAppID() const;
+ /**
+ * @brief register download speed
+ * @param url complete download url
+ * @param bytesPerSecond download size in bytes per second
+ */
+ void setDownloadSpeed(const QString &serverName, int bytesPerSecond);
- /**
- * retrieves the base directory under which the other directories usually
- * reside
- */
- QString getBaseDirectory() const;
+ /**
+ * the steam appid is assigned by the steam platform to each product sold there.
+ * The appid may differ between different versions of a game so it may be impossible
+ * for Mod Organizer to automatically recognize it, though usually it does
+ * @return the steam appid for the game
+ **/
+ QString getSteamAppID() const;
- /**
- * retrieve the directory where downloads are stored (with native separators)
- **/
- QString getDownloadDirectory(bool resolve = true) const;
+ /**
+ * retrieves the base directory under which the other directories usually
+ * reside
+ */
+ QString getBaseDirectory() const;
- /**
- * retrieve a sorted list of preferred servers
- */
- std::map<QString, int> getPreferredServers();
+ /**
+ * retrieve the directory where downloads are stored (with native separators)
+ **/
+ QString getDownloadDirectory(bool resolve = true) const;
- /**
- * retrieve the directory where mods are stored (with native separators)
- **/
- QString getModDirectory(bool resolve = true) const;
+ /**
+ * retrieve a sorted list of preferred servers
+ */
+ std::map<QString, int> getPreferredServers();
- /**
- * returns the version of nmm to impersonate when connecting to nexus
- **/
- QString getNMMVersion() const;
+ /**
+ * retrieve the directory where mods are stored (with native separators)
+ **/
+ QString getModDirectory(bool resolve = true) const;
- /**
- * retrieve the directory where the web cache is stored (with native separators)
- **/
- QString getCacheDirectory(bool resolve = true) const;
+ /**
+ * returns the version of nmm to impersonate when connecting to nexus
+ **/
+ QString getNMMVersion() const;
- /**
- * retrieve the directory where profiles stored (with native separators)
- **/
- QString getProfileDirectory(bool resolve = true) const;
+ /**
+ * retrieve the directory where the web cache is stored (with native separators)
+ **/
+ QString getCacheDirectory(bool resolve = true) const;
- /**
- * retrieve the directory were new files are stored that can't be assigned
- * to a mod (with native separators)
- */
- QString getOverwriteDirectory(bool resolve = true) const;
+ /**
+ * retrieve the directory where profiles stored (with native separators)
+ **/
+ QString getProfileDirectory(bool resolve = true) const;
- /**
- * @return true if the user has set up automatic login to nexus
- **/
- bool automaticLoginEnabled() const;
+ /**
+ * retrieve the directory were new files are stored that can't be assigned
+ * to a mod (with native separators)
+ */
+ QString getOverwriteDirectory(bool resolve = true) const;
- /**
- * @brief retrieve the login information for nexus
- *
- * @param username (out) receives the user name for nexus
- * @param password (out) received the password for nexus
- * @return true if automatic login is active, false otherwise
- **/
- bool getNexusLogin(QString& username, QString& password) const;
+ /**
+ * @return true if the user has set up automatic login to nexus
+ **/
+ bool automaticLoginEnabled() const;
- /**
- * @brief retrieve the login information for steam
- *
- * @param username (out) receives the user name for nexus
- * @param password (out) received the password for nexus
- * @return true if a username has been specified, false otherwise
- **/
- bool getSteamLogin(QString& username, QString& password) const;
+ /**
+ * @brief retrieve the login information for nexus
+ *
+ * @param username (out) receives the user name for nexus
+ * @param password (out) received the password for nexus
+ * @return true if automatic login is active, false otherwise
+ **/
+ bool getNexusLogin(QString &username, QString &password) const;
- /**
- * @return true if the user disabled internet features
- */
- bool offlineMode() const;
+ /**
+ * @brief retrieve the login information for steam
+ *
+ * @param username (out) receives the user name for nexus
+ * @param password (out) received the password for nexus
+ * @return true if a username has been specified, false otherwise
+ **/
+ bool getSteamLogin(QString &username, QString &password) const;
- /**
- * @return true if the user chose compact downloads
- */
- bool compactDownloads() const;
+ /**
+ * @return true if the user disabled internet features
+ */
+ bool offlineMode() const;
- /**
- * @return true if the user chose meta downloads
- */
- bool metaDownloads() const;
+ /**
+ * @return true if the user chose compact downloads
+ */
+ bool compactDownloads() const;
- /**
- * @return the configured log level
- */
- int logLevel() const;
+ /**
+ * @return true if the user chose meta downloads
+ */
+ bool metaDownloads() const;
- /**
- * @return the configured crash dumps type
- */
- int crashDumpsType() const;
+ /**
+ * @return the configured log level
+ */
+ int logLevel() const;
- /**
- * @return the configured crash dumps max
- */
- int crashDumpsMax() const;
+ /**
+ * @return the configured crash dumps type
+ */
+ int crashDumpsType() const;
- /**
- * @brief set the nexus login information
- *
- * @param username username
- * @param password password
- */
- void setNexusLogin(QString username, QString password);
+ /**
+ * @return the configured crash dumps max
+ */
+ int crashDumpsMax() const;
- /**
- * @brief set the steam login information
- *
- * @param username username
- * @param password password
- */
- void setSteamLogin(QString username, QString password);
+ /**
+ * @brief set the nexus login information
+ *
+ * @param username username
+ * @param password password
+ */
+ void setNexusLogin(QString username, QString password);
- /**
- * @return the load mechanism to be used
- **/
- LoadMechanism::EMechanism getLoadMechanism() const;
+ /**
+ * @brief set the steam login information
+ *
+ * @param username username
+ * @param password password
+ */
+ void setSteamLogin(QString username, QString password);
- /**
- * @brief activate the load mechanism selected by the user
- **/
- void setupLoadMechanism();
+ /**
+ * @return the load mechanism to be used
+ **/
+ LoadMechanism::EMechanism getLoadMechanism() const;
- /**
- * @return true if the user configured the use of a network proxy
- */
- bool useProxy() const;
+ /**
+ * @brief activate the load mechanism selected by the user
+ **/
+ void setupLoadMechanism();
- /**
- * @return true if the user wants to see non-official plugins installed outside MO in his mod list
- */
- bool displayForeign() const;
+ /**
+ * @return true if the user configured the use of a network proxy
+ */
+ bool useProxy() const;
- /**
- * @brief sets the new motd hash
- **/
- void setMotDHash(uint hash);
+ /**
+ * @return true if the user wants to see non-official plugins installed outside MO in his mod list
+ */
+ bool displayForeign() const;
- /**
- * @return hash of the last displayed message of the day
- **/
- uint getMotDHash() const;
+ /**
+ * @brief sets the new motd hash
+ **/
+ void setMotDHash(uint hash);
- /**
- * @brief allows direct access to the wrapped QSettings object
- * @return the wrapped QSettings object
- */
- QSettings& directInterface() { return m_Settings; }
+ /**
+ * @return hash of the last displayed message of the day
+ **/
+ uint getMotDHash() const;
- /**
- * @brief retrieve a setting for one of the installed plugins
- * @param pluginName name of the plugin
- * @param key name of the setting to retrieve
- * @return the requested value as a QVariant
- * @note an invalid QVariant is returned if the the plugin/setting is not declared
- */
- QVariant pluginSetting(const QString& pluginName, const QString& key) const;
+ /**
+ * @brief allows direct access to the wrapped QSettings object
+ * @return the wrapped QSettings object
+ */
+ QSettings &directInterface() { return m_Settings; }
- /**
- * @brief set a setting for one of the installed mods
- * @param pluginName name of the plugin
- * @param key name of the setting to change
- * @param value the new value to set
- * @throw an exception is thrown if pluginName is invalid
- */
- void setPluginSetting(const QString& pluginName, const QString& key, const QVariant& value);
+ /**
+ * @brief retrieve a setting for one of the installed plugins
+ * @param pluginName name of the plugin
+ * @param key name of the setting to retrieve
+ * @return the requested value as a QVariant
+ * @note an invalid QVariant is returned if the the plugin/setting is not declared
+ */
+ QVariant pluginSetting(const QString &pluginName, const QString &key) const;
- /**
- * @brief retrieve a persistent value for a plugin
- * @param pluginName name of the plugin to store data for
- * @param key id of the value to retrieve
- * @param def default value to return if the value is not set
- * @return the requested value
- */
- QVariant pluginPersistent(const QString& pluginName, const QString& key, const QVariant& def) const;
+ /**
+ * @brief set a setting for one of the installed mods
+ * @param pluginName name of the plugin
+ * @param key name of the setting to change
+ * @param value the new value to set
+ * @throw an exception is thrown if pluginName is invalid
+ */
+ void setPluginSetting(const QString &pluginName, const QString &key, const QVariant &value);
- /**
- * @brief set a persistent value for a plugin
- * @param pluginName name of the plugin to store data for
- * @param key id of the value to retrieve
- * @param value value to set
- * @throw an exception is thrown if pluginName is invalid
- */
- void setPluginPersistent(const QString& pluginName, const QString& key, const QVariant& value, bool sync);
+ /**
+ * @brief retrieve a persistent value for a plugin
+ * @param pluginName name of the plugin to store data for
+ * @param key id of the value to retrieve
+ * @param def default value to return if the value is not set
+ * @return the requested value
+ */
+ QVariant pluginPersistent(const QString &pluginName, const QString &key, const QVariant &def) const;
- /**
- * @return short code of the configured language (corresponding to the translation files)
- */
- QString language();
+ /**
+ * @brief set a persistent value for a plugin
+ * @param pluginName name of the plugin to store data for
+ * @param key id of the value to retrieve
+ * @param value value to set
+ * @throw an exception is thrown if pluginName is invalid
+ */
+ void setPluginPersistent(const QString &pluginName, const QString &key, const QVariant &value, bool sync);
- /**
- * @brief updates the list of known servers
- * @param list of servers from a recent query
- */
- void updateServers(const QList<ServerInfo>& servers);
+ /**
+ * @return short code of the configured language (corresponding to the translation files)
+ */
+ QString language();
- /**
- * @brief add a plugin that is to be blacklisted
- * @param fileName name of the plugin to blacklist
- */
- void addBlacklistPlugin(const QString& fileName);
+ /**
+ * @brief updates the list of known servers
+ * @param list of servers from a recent query
+ */
+ void updateServers(const QList<ServerInfo> &servers);
- /**
- * @brief test if a plugin is blacklisted and shouldn't be loaded
- * @param fileName name of the plugin
- * @return true if the file is blacklisted
- */
- bool pluginBlacklisted(const QString& fileName) const;
+ /**
+ * @brief add a plugin that is to be blacklisted
+ * @param fileName name of the plugin to blacklist
+ */
+ void addBlacklistPlugin(const QString &fileName);
- /**
- * @return all loaded MO plugins
- */
- std::vector<MOBase::IPlugin*> plugins() const { return m_Plugins; }
+ /**
+ * @brief test if a plugin is blacklisted and shouldn't be loaded
+ * @param fileName name of the plugin
+ * @return true if the file is blacklisted
+ */
+ bool pluginBlacklisted(const QString &fileName) const;
- bool usePrereleases() const;
+ /**
+ * @return all loaded MO plugins
+ */
+ std::vector<MOBase::IPlugin*> plugins() const { return m_Plugins; }
- /**
- * @brief register MO as the handler for nxm links
- * @param force set to true to enforce the registration dialog to show up,
- * even if the user said earlier not to
- */
- void registerAsNXMHandler(bool force);
+ bool usePrereleases() const;
+
+ /**
+ * @brief register MO as the handler for nxm links
+ * @param force set to true to enforce the registration dialog to show up,
+ * even if the user said earlier not to
+ */
+ void registerAsNXMHandler(bool force);
public slots:
- void managedGameChanged(MOBase::IPluginGame const* gamePlugin);
+ void managedGameChanged(MOBase::IPluginGame const *gamePlugin);
private:
- static QString obfuscate(const QString& password);
- static QString deObfuscate(const QString& password);
- void addLanguages(QComboBox* languageBox);
- void addStyles(QComboBox* styleBox);
- void readPluginBlacklist();
- void writePluginBlacklist();
- QString getConfigurablePath(const QString& key, const QString& def, bool resolve) const;
+ static QString obfuscate(const QString &password);
+ static QString deObfuscate(const QString &password);
+
+ void addLanguages(QComboBox *languageBox);
+ void addStyles(QComboBox *styleBox);
+ void readPluginBlacklist();
+ void writePluginBlacklist();
+ QString getConfigurablePath(const QString &key, const QString &def, bool resolve) const;
+
+ class SettingsTab
+ {
+ public:
+ SettingsTab(Settings *m_parent, SettingsDialog &m_dialog);
+ virtual ~SettingsTab();
- class SettingsTab {
- public:
- SettingsTab(Settings* m_parent, SettingsDialog& m_dialog);
- virtual ~SettingsTab();
+ virtual void update() = 0;
- virtual void update() = 0;
+ protected:
+ Settings *m_parent;
+ QSettings &m_Settings;
+ SettingsDialog &m_dialog;
- protected:
- Settings* m_parent;
- QSettings& m_Settings;
- SettingsDialog& m_dialog;
- };
+ };
- /** Display/store the configuration in the 'general' tab of the settings dialogue */
- class GeneralTab : public SettingsTab {
- public:
- GeneralTab(Settings* m_parent, SettingsDialog& m_dialog);
+ /** Display/store the configuration in the 'general' tab of the settings dialogue */
+ class GeneralTab : public SettingsTab
+ {
+ public:
+ GeneralTab(Settings *m_parent, SettingsDialog &m_dialog);
- void update();
+ void update();
- private:
- QComboBox* m_languageBox;
- QComboBox* m_styleBox;
- QCheckBox* m_compactBox;
- QCheckBox* m_showMetaBox;
- QCheckBox* m_usePrereleaseBox;
- };
+ private:
+ QComboBox *m_languageBox;
+ QComboBox *m_styleBox;
+ QCheckBox *m_compactBox;
+ QCheckBox *m_showMetaBox;
+ QCheckBox *m_usePrereleaseBox;
+ };
- class PathsTab : public SettingsTab {
- public:
- PathsTab(Settings* parent, SettingsDialog& dialog);
+ class PathsTab : public SettingsTab
+ {
+ public:
+ PathsTab(Settings *parent, SettingsDialog &dialog);
- void update();
+ void update();
- private:
- QLineEdit* m_baseDirEdit;
- QLineEdit* m_downloadDirEdit;
- QLineEdit* m_modDirEdit;
- QLineEdit* m_cacheDirEdit;
- QLineEdit* m_profilesDirEdit;
- QLineEdit* m_overwriteDirEdit;
- };
+ private:
+ QLineEdit *m_baseDirEdit;
+ QLineEdit *m_downloadDirEdit;
+ QLineEdit *m_modDirEdit;
+ QLineEdit *m_cacheDirEdit;
+ QLineEdit *m_profilesDirEdit;
+ QLineEdit *m_overwriteDirEdit;
+ };
- class DiagnosticsTab : public SettingsTab {
- public:
- DiagnosticsTab(Settings* parent, SettingsDialog& dialog);
+ class DiagnosticsTab : public SettingsTab
+ {
+ public:
+ DiagnosticsTab(Settings *parent, SettingsDialog &dialog);
- void update();
+ void update();
- private:
- QComboBox* m_logLevelBox;
- QComboBox* m_dumpsTypeBox;
- QSpinBox* m_dumpsMaxEdit;
- QLabel* m_diagnosticsExplainedLabel;
- };
+ private:
+ QComboBox *m_logLevelBox;
+ QComboBox *m_dumpsTypeBox;
+ QSpinBox *m_dumpsMaxEdit;
+ QLabel *m_diagnosticsExplainedLabel;
+ };
- /** Display/store the configuration in the 'nexus' tab of the settings dialogue */
- class NexusTab : public SettingsTab {
- public:
- NexusTab(Settings* m_parent, SettingsDialog& m_dialog);
+ /** Display/store the configuration in the 'nexus' tab of the settings dialogue */
+ class NexusTab : public SettingsTab
+ {
+ public:
+ NexusTab(Settings *m_parent, SettingsDialog &m_dialog);
- void update();
+ void update();
- private:
- QCheckBox* m_loginCheckBox;
- QLineEdit* m_usernameEdit;
- QLineEdit* m_passwordEdit;
- QCheckBox* m_offlineBox;
- QCheckBox* m_proxyBox;
- QListWidget* m_knownServersList;
- QListWidget* m_preferredServersList;
- };
+ private:
+ QCheckBox *m_loginCheckBox;
+ QLineEdit *m_usernameEdit;
+ QLineEdit *m_passwordEdit;
+ QCheckBox *m_offlineBox;
+ QCheckBox *m_proxyBox;
+ QListWidget *m_knownServersList;
+ QListWidget *m_preferredServersList;
+ };
- /** Display/store the configuration in the 'steam' tab of the settings dialogue */
- class SteamTab : public SettingsTab {
- public:
- SteamTab(Settings* m_parent, SettingsDialog& m_dialog);
+ /** Display/store the configuration in the 'steam' tab of the settings dialogue */
+ class SteamTab : public SettingsTab
+ {
+ public:
+ SteamTab(Settings *m_parent, SettingsDialog &m_dialog);
- void update();
+ void update();
- private:
- QLineEdit* m_steamUserEdit;
- QLineEdit* m_steamPassEdit;
- };
+ private:
+ QLineEdit *m_steamUserEdit;
+ QLineEdit *m_steamPassEdit;
+ };
- /** Display/store the configuration in the 'plugins' tab of the settings dialogue */
- class PluginsTab : public SettingsTab {
- public:
- PluginsTab(Settings* m_parent, SettingsDialog& m_dialog);
+ /** Display/store the configuration in the 'plugins' tab of the settings dialogue */
+ class PluginsTab : public SettingsTab
+ {
+ public:
+ PluginsTab(Settings *m_parent, SettingsDialog &m_dialog);
- void update();
+ void update();
- private:
- QListWidget* m_pluginsList;
- QListWidget* m_pluginBlacklistList;
- };
+ private:
+ QListWidget *m_pluginsList;
+ QListWidget *m_pluginBlacklistList;
+ };
- /** Display/store the configuration in the 'workarounds' tab of the settings dialogue */
- class WorkaroundsTab : public SettingsTab {
- public:
- WorkaroundsTab(Settings* m_parent, SettingsDialog& m_dialog);
+ /** Display/store the configuration in the 'workarounds' tab of the settings dialogue */
+ class WorkaroundsTab : public SettingsTab
+ {
+ public:
+ WorkaroundsTab(Settings *m_parent, SettingsDialog &m_dialog);
- void update();
+ void update();
- private:
- QLineEdit* m_appIDEdit;
- QComboBox* m_mechanismBox;
- QLineEdit* m_nmmVersionEdit;
- QCheckBox* m_hideUncheckedBox;
- QCheckBox* m_forceEnableBox;
- QCheckBox* m_displayForeignBox;
- };
+ private:
+ QLineEdit *m_appIDEdit;
+ QComboBox *m_mechanismBox;
+ QLineEdit *m_nmmVersionEdit;
+ QCheckBox *m_hideUncheckedBox;
+ QCheckBox *m_forceEnableBox;
+ QCheckBox *m_displayForeignBox;
+ };
private slots:
- void resetDialogs();
+ void resetDialogs();
signals:
- void languageChanged(const QString& newLanguage);
- void styleChanged(const QString& newStyle);
+ void languageChanged(const QString &newLanguage);
+ void styleChanged(const QString &newStyle);
private:
- static Settings* s_Instance;
- MOBase::IPluginGame const* m_GamePlugin;
+ static Settings *s_Instance;
+
+ MOBase::IPluginGame const *m_GamePlugin;
+
+ QSettings m_Settings;
- QSettings m_Settings;
+ LoadMechanism m_LoadMechanism;
- LoadMechanism m_LoadMechanism;
+ std::vector<MOBase::IPlugin*> m_Plugins;
- std::vector<MOBase::IPlugin*> m_Plugins;
+ QMap<QString, QMap<QString, QVariant>> m_PluginSettings;
+ QMap<QString, QMap<QString, QVariant>> m_PluginDescriptions;
- QMap<QString, QMap<QString, QVariant>> m_PluginSettings;
- QMap<QString, QMap<QString, QVariant>> m_PluginDescriptions;
+ QSet<QString> m_PluginBlacklist;
- QSet<QString> m_PluginBlacklist;
};
#endif // WORKAROUNDS_H
diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp
index fd487c86..fb9433a6 100644
--- a/src/settingsdialog.cpp
+++ b/src/settingsdialog.cpp
@@ -19,14 +19,14 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "settingsdialog.h"
+#include "ui_settingsdialog.h"
#include "categoriesdialog.h"
#include "helper.h"
-#include "instancemanager.h"
-#include "iplugingame.h"
-#include "nexusinterface.h"
#include "noeditdelegate.h"
+#include "iplugingame.h"
#include "settings.h"
-#include "ui_settingsdialog.h"
+#include "instancemanager.h"
+#include "nexusinterface.h"
#include <QDirIterator>
#include <QFileDialog>
@@ -36,187 +36,222 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
+
using namespace MOBase;
-SettingsDialog::SettingsDialog(QWidget* parent)
- : TutorableDialog("SettingsDialog", parent), ui(new Ui::SettingsDialog) {
- ui->setupUi(this);
- QShortcut* delShortcut = new QShortcut(QKeySequence(Qt::Key_Delete), ui->pluginBlacklist);
- connect(delShortcut, SIGNAL(activated()), this, SLOT(deleteBlacklistItem()));
+SettingsDialog::SettingsDialog(QWidget *parent)
+ : TutorableDialog("SettingsDialog", parent)
+ , ui(new Ui::SettingsDialog)
+{
+ ui->setupUi(this);
+
+ QShortcut *delShortcut
+ = new QShortcut(QKeySequence(Qt::Key_Delete), ui->pluginBlacklist);
+ connect(delShortcut, SIGNAL(activated()), this, SLOT(deleteBlacklistItem()));
}
-SettingsDialog::~SettingsDialog() { delete ui; }
+SettingsDialog::~SettingsDialog()
+{
+ delete ui;
+}
-void SettingsDialog::addPlugins(const std::vector<IPlugin*>& plugins) {
- for (IPlugin* plugin : plugins) {
- ui->pluginsList->addItem(plugin->name());
- }
+void SettingsDialog::addPlugins(const std::vector<IPlugin*> &plugins)
+{
+ for (IPlugin *plugin : plugins) {
+ ui->pluginsList->addItem(plugin->name());
+ }
}
-void SettingsDialog::accept() {
- QString newModPath = ui->modDirEdit->text();
- newModPath.replace("%BASE_DIR%", ui->baseDirEdit->text());
+void SettingsDialog::accept()
+{
+ QString newModPath = ui->modDirEdit->text();
+ newModPath.replace("%BASE_DIR%", ui->baseDirEdit->text());
- if ((QDir::fromNativeSeparators(newModPath) !=
- QDir::fromNativeSeparators(Settings::instance().getModDirectory(true))) &&
- (QMessageBox::question(nullptr, tr("Confirm"),
- tr("Changing the mod directory affects all your profiles! "
- "Mods not present (or named differently) in the new location "
- "will be disabled in all profiles. "
- "There is no way to undo this unless you backed up your "
- "profiles manually. Proceed?"),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)) {
- return;
- }
+ if ((QDir::fromNativeSeparators(newModPath) !=
+ QDir::fromNativeSeparators(
+ Settings::instance().getModDirectory(true))) &&
+ (QMessageBox::question(
+ nullptr, tr("Confirm"),
+ tr("Changing the mod directory affects all your profiles! "
+ "Mods not present (or named differently) in the new location "
+ "will be disabled in all profiles. "
+ "There is no way to undo this unless you backed up your "
+ "profiles manually. Proceed?"),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)) {
+ return;
+ }
- storeSettings(ui->pluginsList->currentItem());
- TutorableDialog::accept();
+ storeSettings(ui->pluginsList->currentItem());
+ TutorableDialog::accept();
}
-void SettingsDialog::on_loginCheckBox_toggled(bool checked) {
- QLineEdit* usernameEdit = findChild<QLineEdit*>("usernameEdit");
- QLineEdit* passwordEdit = findChild<QLineEdit*>("passwordEdit");
- if (checked) {
- passwordEdit->setEnabled(true);
- usernameEdit->setEnabled(true);
- } else {
- passwordEdit->setEnabled(false);
- usernameEdit->setEnabled(false);
- }
+
+void SettingsDialog::on_loginCheckBox_toggled(bool checked)
+{
+ QLineEdit *usernameEdit = findChild<QLineEdit*>("usernameEdit");
+ QLineEdit *passwordEdit = findChild<QLineEdit*>("passwordEdit");
+ if (checked) {
+ passwordEdit->setEnabled(true);
+ usernameEdit->setEnabled(true);
+ } else {
+ passwordEdit->setEnabled(false);
+ usernameEdit->setEnabled(false);
+ }
}
-void SettingsDialog::on_categoriesBtn_clicked() {
- CategoriesDialog dialog(this);
- if (dialog.exec() == QDialog::Accepted) {
- dialog.commitChanges();
- }
+void SettingsDialog::on_categoriesBtn_clicked()
+{
+ CategoriesDialog dialog(this);
+ if (dialog.exec() == QDialog::Accepted) {
+ dialog.commitChanges();
+ }
}
-void SettingsDialog::on_bsaDateBtn_clicked() {
- IPluginGame const* game = qApp->property("managed_game").value<IPluginGame*>();
- QDir dir = game->dataDirectory();
+void SettingsDialog::on_bsaDateBtn_clicked()
+{
+ IPluginGame const *game
+ = qApp->property("managed_game").value<IPluginGame *>();
+ QDir dir = game->dataDirectory();
- Helper::backdateBSAs(qApp->applicationDirPath().toStdWString(), dir.absolutePath().toStdWString());
+ Helper::backdateBSAs(qApp->applicationDirPath().toStdWString(),
+ dir.absolutePath().toStdWString());
}
-void SettingsDialog::on_browseBaseDirBtn_clicked() {
- QString temp = QFileDialog::getExistingDirectory(this, tr("Select base directory"), ui->baseDirEdit->text());
- if (!temp.isEmpty()) {
- ui->baseDirEdit->setText(temp);
- }
+void SettingsDialog::on_browseBaseDirBtn_clicked()
+{
+ QString temp = QFileDialog::getExistingDirectory(
+ this, tr("Select base directory"), ui->baseDirEdit->text());
+ if (!temp.isEmpty()) {
+ ui->baseDirEdit->setText(temp);
+ }
}
-void SettingsDialog::on_browseDownloadDirBtn_clicked() {
- QString searchPath = ui->downloadDirEdit->text();
- searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text());
+void SettingsDialog::on_browseDownloadDirBtn_clicked()
+{
+ QString searchPath = ui->downloadDirEdit->text();
+ searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text());
- QString temp = QFileDialog::getExistingDirectory(this, tr("Select download directory"), searchPath);
- if (!temp.isEmpty()) {
- ui->downloadDirEdit->setText(temp);
- }
+ QString temp = QFileDialog::getExistingDirectory(this, tr("Select download directory"), searchPath);
+ if (!temp.isEmpty()) {
+ ui->downloadDirEdit->setText(temp);
+ }
}
-void SettingsDialog::on_browseModDirBtn_clicked() {
- QString searchPath = ui->modDirEdit->text();
- searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text());
+void SettingsDialog::on_browseModDirBtn_clicked()
+{
+ QString searchPath = ui->modDirEdit->text();
+ searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text());
- QString temp = QFileDialog::getExistingDirectory(this, tr("Select mod directory"), searchPath);
- if (!temp.isEmpty()) {
- ui->modDirEdit->setText(temp);
- }
+ QString temp = QFileDialog::getExistingDirectory(this, tr("Select mod directory"), searchPath);
+ if (!temp.isEmpty()) {
+ ui->modDirEdit->setText(temp);
+ }
}
-void SettingsDialog::on_browseCacheDirBtn_clicked() {
- QString searchPath = ui->cacheDirEdit->text();
- searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text());
+void SettingsDialog::on_browseCacheDirBtn_clicked()
+{
+ QString searchPath = ui->cacheDirEdit->text();
+ searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text());
- QString temp = QFileDialog::getExistingDirectory(this, tr("Select cache directory"), searchPath);
- if (!temp.isEmpty()) {
- ui->cacheDirEdit->setText(temp);
- }
+ QString temp = QFileDialog::getExistingDirectory(this, tr("Select cache directory"), searchPath);
+ if (!temp.isEmpty()) {
+ ui->cacheDirEdit->setText(temp);
+ }
}
-void SettingsDialog::on_browseProfilesDirBtn_clicked() {
- QString searchPath = ui->profilesDirEdit->text();
- searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text());
+void SettingsDialog::on_browseProfilesDirBtn_clicked()
+{
+ QString searchPath = ui->profilesDirEdit->text();
+ searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text());
- QString temp = QFileDialog::getExistingDirectory(this, tr("Select profiles directory"), searchPath);
- if (!temp.isEmpty()) {
- ui->profilesDirEdit->setText(temp);
- }
+ QString temp = QFileDialog::getExistingDirectory(this, tr("Select profiles directory"), searchPath);
+ if (!temp.isEmpty()) {
+ ui->profilesDirEdit->setText(temp);
+ }
}
-void SettingsDialog::on_browseOverwriteDirBtn_clicked() {
- QString searchPath = ui->overwriteDirEdit->text();
- searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text());
+void SettingsDialog::on_browseOverwriteDirBtn_clicked()
+{
+ QString searchPath = ui->overwriteDirEdit->text();
+ searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text());
- QString temp = QFileDialog::getExistingDirectory(this, tr("Select overwrite directory"), searchPath);
- if (!temp.isEmpty()) {
- ui->overwriteDirEdit->setText(temp);
- }
+ QString temp = QFileDialog::getExistingDirectory(this, tr("Select overwrite directory"), searchPath);
+ if (!temp.isEmpty()) {
+ ui->overwriteDirEdit->setText(temp);
+ }
}
-void SettingsDialog::on_resetDialogsButton_clicked() {
- if (QMessageBox::question(
- this, tr("Confirm?"),
- tr("This will make all dialogs show up again where you checked the \"Remember selection\"-box. Continue?"),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- emit resetDialogs();
- }
+void SettingsDialog::on_resetDialogsButton_clicked()
+{
+ if (QMessageBox::question(this, tr("Confirm?"),
+ tr("This will make all dialogs show up again where you checked the \"Remember selection\"-box. Continue?"),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ emit resetDialogs();
+ }
}
-void SettingsDialog::storeSettings(QListWidgetItem* pluginItem) {
- if (pluginItem != nullptr) {
- QMap<QString, QVariant> settings = pluginItem->data(Qt::UserRole + 1).toMap();
+void SettingsDialog::storeSettings(QListWidgetItem *pluginItem)
+{
+ if (pluginItem != nullptr) {
+ QMap<QString, QVariant> settings = pluginItem->data(Qt::UserRole + 1).toMap();
- for (int i = 0; i < ui->pluginSettingsList->topLevelItemCount(); ++i) {
- const QTreeWidgetItem* item = ui->pluginSettingsList->topLevelItem(i);
- settings[item->text(0)] = item->data(1, Qt::DisplayRole);
- }
-
- pluginItem->setData(Qt::UserRole + 1, settings);
+ for (int i = 0; i < ui->pluginSettingsList->topLevelItemCount(); ++i) {
+ const QTreeWidgetItem *item = ui->pluginSettingsList->topLevelItem(i);
+ settings[item->text(0)] = item->data(1, Qt::DisplayRole);
}
+
+ pluginItem->setData(Qt::UserRole + 1, settings);
+ }
}
-void SettingsDialog::on_pluginsList_currentItemChanged(QListWidgetItem* current, QListWidgetItem* previous) {
- storeSettings(previous);
+void SettingsDialog::on_pluginsList_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
+{
+ storeSettings(previous);
- ui->pluginSettingsList->clear();
- IPlugin* plugin = static_cast<IPlugin*>(current->data(Qt::UserRole).value<void*>());
- ui->authorLabel->setText(plugin->author());
- ui->versionLabel->setText(plugin->version().canonicalString());
- ui->descriptionLabel->setText(plugin->description());
+ ui->pluginSettingsList->clear();
+ IPlugin *plugin = static_cast<IPlugin*>(current->data(Qt::UserRole).value<void*>());
+ ui->authorLabel->setText(plugin->author());
+ ui->versionLabel->setText(plugin->version().canonicalString());
+ ui->descriptionLabel->setText(plugin->description());
- QMap<QString, QVariant> settings = current->data(Qt::UserRole + 1).toMap();
- QMap<QString, QVariant> descriptions = current->data(Qt::UserRole + 2).toMap();
- ui->pluginSettingsList->setEnabled(settings.count() != 0);
- for (auto iter = settings.begin(); iter != settings.end(); ++iter) {
- QTreeWidgetItem* newItem = new QTreeWidgetItem(QStringList(iter.key()));
- QVariant value = *iter;
- QString description;
- {
- auto descriptionIter = descriptions.find(iter.key());
- if (descriptionIter != descriptions.end()) {
- description = descriptionIter->toString();
- }
- }
+ QMap<QString, QVariant> settings = current->data(Qt::UserRole + 1).toMap();
+ QMap<QString, QVariant> descriptions = current->data(Qt::UserRole + 2).toMap();
+ ui->pluginSettingsList->setEnabled(settings.count() != 0);
+ for (auto iter = settings.begin(); iter != settings.end(); ++iter) {
+ QTreeWidgetItem *newItem = new QTreeWidgetItem(QStringList(iter.key()));
+ QVariant value = *iter;
+ QString description;
+ {
+ auto descriptionIter = descriptions.find(iter.key());
+ if (descriptionIter != descriptions.end()) {
+ description = descriptionIter->toString();
+ }
+ }
- ui->pluginSettingsList->setItemDelegateForColumn(0, new NoEditDelegate());
- newItem->setData(1, Qt::DisplayRole, value);
- newItem->setData(1, Qt::EditRole, value);
- newItem->setToolTip(1, description);
+ ui->pluginSettingsList->setItemDelegateForColumn(0, new NoEditDelegate());
+ newItem->setData(1, Qt::DisplayRole, value);
+ newItem->setData(1, Qt::EditRole, value);
+ newItem->setToolTip(1, description);
- newItem->setFlags(newItem->flags() | Qt::ItemIsEditable);
- ui->pluginSettingsList->addTopLevelItem(newItem);
- }
+ newItem->setFlags(newItem->flags() | Qt::ItemIsEditable);
+ ui->pluginSettingsList->addTopLevelItem(newItem);
+ }
}
-void SettingsDialog::deleteBlacklistItem() { ui->pluginBlacklist->takeItem(ui->pluginBlacklist->currentIndex().row()); }
+void SettingsDialog::deleteBlacklistItem()
+{
+ ui->pluginBlacklist->takeItem(ui->pluginBlacklist->currentIndex().row());
+}
-void SettingsDialog::on_associateButton_clicked() { Settings::instance().registerAsNXMHandler(false); }
+void SettingsDialog::on_associateButton_clicked()
+{
+ Settings::instance().registerAsNXMHandler(false);
+}
-void SettingsDialog::on_clearCacheButton_clicked() {
- QDir(Settings::instance().getCacheDirectory()).removeRecursively();
- NexusInterface::instance()->clearCache();
+void SettingsDialog::on_clearCacheButton_clicked()
+{
+ QDir(Settings::instance().getCacheDirectory()).removeRecursively();
+ NexusInterface::instance()->clearCache();
}
+
diff --git a/src/settingsdialog.h b/src/settingsdialog.h
index 6b95dde2..e9d995d3 100644
--- a/src/settingsdialog.h
+++ b/src/settingsdialog.h
@@ -21,12 +21,12 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#define WORKAROUNDDIALOG_H
#include "tutorabledialog.h"
+#include <iplugin.h>
#include <QDialog>
#include <QListWidgetItem>
-#include <iplugin.h>
namespace Ui {
-class SettingsDialog;
+ class SettingsDialog;
}
/**
@@ -34,57 +34,62 @@ class SettingsDialog;
* settings managed by the "Settings" class, this offers a button to open the
* CategoriesDialog
**/
-class SettingsDialog : public MOBase::TutorableDialog {
+class SettingsDialog : public MOBase::TutorableDialog
+{
Q_OBJECT
public:
- explicit SettingsDialog(QWidget* parent = 0);
- ~SettingsDialog();
+ explicit SettingsDialog(QWidget *parent = 0);
+ ~SettingsDialog();
- void addPlugins(const std::vector<MOBase::IPlugin*>& plugins);
+ void addPlugins(const std::vector<MOBase::IPlugin*> &plugins);
public slots:
- virtual void accept();
+ virtual void accept();
signals:
- void resetDialogs();
+ void resetDialogs();
private:
- void storeSettings(QListWidgetItem* pluginItem);
+
+ void storeSettings(QListWidgetItem *pluginItem);
private slots:
- void on_loginCheckBox_toggled(bool checked);
+ void on_loginCheckBox_toggled(bool checked);
- void on_categoriesBtn_clicked();
+ void on_categoriesBtn_clicked();
- void on_bsaDateBtn_clicked();
+ void on_bsaDateBtn_clicked();
- void on_browseDownloadDirBtn_clicked();
+ void on_browseDownloadDirBtn_clicked();
- void on_browseModDirBtn_clicked();
+ void on_browseModDirBtn_clicked();
- void on_browseCacheDirBtn_clicked();
+ void on_browseCacheDirBtn_clicked();
- void on_resetDialogsButton_clicked();
+ void on_resetDialogsButton_clicked();
- void on_pluginsList_currentItemChanged(QListWidgetItem* current, QListWidgetItem* previous);
+ void on_pluginsList_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous);
- void deleteBlacklistItem();
+ void deleteBlacklistItem();
- void on_associateButton_clicked();
+ void on_associateButton_clicked();
- void on_clearCacheButton_clicked();
+ void on_clearCacheButton_clicked();
- void on_browseBaseDirBtn_clicked();
+ void on_browseBaseDirBtn_clicked();
- void on_browseOverwriteDirBtn_clicked();
+ void on_browseOverwriteDirBtn_clicked();
- void on_browseProfilesDirBtn_clicked();
+ void on_browseProfilesDirBtn_clicked();
private:
- Ui::SettingsDialog* ui;
+ Ui::SettingsDialog *ui;
+
};
+
+
#endif // WORKAROUNDDIALOG_H
diff --git a/src/shared/appconfig.cpp b/src/shared/appconfig.cpp
index ebb72aba..49edcbcc 100644
--- a/src/shared/appconfig.cpp
+++ b/src/shared/appconfig.cpp
@@ -22,12 +22,12 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
namespace AppConfig {
#define PARWSTRING wstring
-#define APPPARAM(partype, parid, value) \
- partype parid() { return value; }
+#define APPPARAM(partype, parid, value) partype parid () { return value; }
#include "appconfig.inc"
namespace MOShared {
#undef PARWSTRING
#undef APPPARAM
+
}
} // namespace MOShared
diff --git a/src/shared/appconfig.h b/src/shared/appconfig.h
index b2dda14a..b32043e5 100644
--- a/src/shared/appconfig.h
+++ b/src/shared/appconfig.h
@@ -24,13 +24,15 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
namespace AppConfig {
+
#define PARWSTRING wstring
-#define APPPARAM(partype, parid, value) partype parid();
+#define APPPARAM(partype, parid, value) partype parid ();
#include "appconfig.inc"
namespace MOShared {
#undef PARWSTRING
#undef APPPARAM
+
}
} // namespace MOShared
diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp
index 2e25a1a3..cebf270e 100644
--- a/src/shared/directoryentry.cpp
+++ b/src/shared/directoryentry.cpp
@@ -18,19 +18,20 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "directoryentry.h"
-#include "error_report.h"
-#include "leaktrace.h"
#include "windows_error.h"
+#include "leaktrace.h"
+#include "error_report.h"
+#include <bsatk.h>
#include <boost/bind.hpp>
#include <boost/scoped_array.hpp>
-#include <bsatk.h>
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
-#include <algorithm>
-#include <atomic>
+#include <sstream>
#include <ctime>
+#include <algorithm>
#include <map>
-#include <sstream>
+#include <atomic>
+
namespace MOShared {
@@ -39,576 +40,671 @@ static const int MAXPATH_UNICODE = 32767;
class OriginConnection {
public:
- typedef int Index;
- static const int INVALID_INDEX = INT_MIN;
+
+ typedef int Index;
+ static const int INVALID_INDEX = INT_MIN;
public:
- OriginConnection() : m_NextID(0) { LEAK_TRACE; }
- ~OriginConnection() { LEAK_UNTRACE; }
+ OriginConnection()
+ : m_NextID(0)
+ {
+ LEAK_TRACE;
+ }
+
+ ~OriginConnection()
+ {
+ LEAK_UNTRACE;
+ }
- FilesOrigin& createOrigin(const std::wstring& originName, const std::wstring& directory, int priority,
- boost::shared_ptr<FileRegister> fileRegister,
- boost::shared_ptr<OriginConnection> originConnection) {
- int newID = createID();
- m_Origins[newID] = FilesOrigin(newID, originName, directory, priority, fileRegister, originConnection);
- m_OriginsNameMap[originName] = newID;
- m_OriginsPriorityMap[priority] = newID;
- return m_Origins[newID];
- }
+ FilesOrigin& createOrigin(const std::wstring &originName, const std::wstring &directory, int priority,
+ boost::shared_ptr<FileRegister> fileRegister, boost::shared_ptr<OriginConnection> originConnection) {
+ int newID = createID();
+ m_Origins[newID] = FilesOrigin(newID, originName, directory, priority, fileRegister, originConnection);
+ m_OriginsNameMap[originName] = newID;
+ m_OriginsPriorityMap[priority] = newID;
+ return m_Origins[newID];
+ }
- bool exists(const std::wstring& name) { return m_OriginsNameMap.find(name) != m_OriginsNameMap.end(); }
+ bool exists(const std::wstring &name) {
+ return m_OriginsNameMap.find(name) != m_OriginsNameMap.end();
+ }
- FilesOrigin& getByID(Index ID) { return m_Origins[ID]; }
+ FilesOrigin &getByID(Index ID) {
+ return m_Origins[ID];
+ }
- FilesOrigin& getByName(const std::wstring& name) {
- std::map<std::wstring, int>::iterator iter = m_OriginsNameMap.find(name);
- if (iter != m_OriginsNameMap.end()) {
- return m_Origins[iter->second];
- } else {
- std::ostringstream stream;
- stream << "invalid origin name: " << ToString(name, false);
- throw std::runtime_error(stream.str());
- }
+ FilesOrigin &getByName(const std::wstring &name) {
+ std::map<std::wstring, int>::iterator iter = m_OriginsNameMap.find(name);
+ if (iter != m_OriginsNameMap.end()) {
+ return m_Origins[iter->second];
+ } else {
+ std::ostringstream stream;
+ stream << "invalid origin name: " << ToString(name, false);
+ throw std::runtime_error(stream.str());
}
+ }
- void changePriorityLookup(int oldPriority, int newPriority) {
- auto iter = m_OriginsPriorityMap.find(oldPriority);
- if (iter != m_OriginsPriorityMap.end()) {
- Index idx = iter->second;
- m_OriginsPriorityMap.erase(iter);
- m_OriginsPriorityMap[newPriority] = idx;
- }
+ void changePriorityLookup(int oldPriority, int newPriority)
+ {
+ auto iter = m_OriginsPriorityMap.find(oldPriority);
+ if (iter != m_OriginsPriorityMap.end()) {
+ Index idx = iter->second;
+ m_OriginsPriorityMap.erase(iter);
+ m_OriginsPriorityMap[newPriority] = idx;
}
+ }
- void changeNameLookup(const std::wstring& oldName, const std::wstring& newName) {
- auto iter = m_OriginsNameMap.find(oldName);
- if (iter != m_OriginsNameMap.end()) {
- Index idx = iter->second;
- m_OriginsNameMap.erase(iter);
- m_OriginsNameMap[newName] = idx;
- } else {
- log("failed to change name lookup from %ls to %ls", oldName.c_str(), newName.c_str());
- }
+ void changeNameLookup(const std::wstring &oldName, const std::wstring &newName)
+ {
+ auto iter = m_OriginsNameMap.find(oldName);
+ if (iter != m_OriginsNameMap.end()) {
+ Index idx = iter->second;
+ m_OriginsNameMap.erase(iter);
+ m_OriginsNameMap[newName] = idx;
+ } else {
+ log("failed to change name lookup from %ls to %ls", oldName.c_str(), newName.c_str());
}
+ }
private:
- Index createID() { return m_NextID++; }
+
+ Index createID() {
+ return m_NextID++;
+ }
private:
- Index m_NextID;
- std::map<Index, FilesOrigin> m_Origins;
- std::map<std::wstring, Index> m_OriginsNameMap;
- std::map<int, Index> m_OriginsPriorityMap;
+ Index m_NextID;
+
+ std::map<Index, FilesOrigin> m_Origins;
+ std::map<std::wstring, Index> m_OriginsNameMap;
+ std::map<int, Index> m_OriginsPriorityMap;
+
};
+
//
// FilesOrigin
//
-void FilesOrigin::enable(bool enabled, time_t notAfter) {
- if (!enabled) {
- std::set<FileEntry::Index> copy = m_Files;
- m_FileRegister.lock()->removeOriginMulti(copy, m_ID, notAfter);
- m_Files.clear();
- }
- m_Disabled = !enabled;
+
+void FilesOrigin::enable(bool enabled, time_t notAfter)
+{
+ if (!enabled) {
+ std::set<FileEntry::Index> copy = m_Files;
+ m_FileRegister.lock()->removeOriginMulti(copy, m_ID, notAfter);
+ m_Files.clear();
+ }
+ m_Disabled = !enabled;
}
-void FilesOrigin::removeFile(FileEntry::Index index) {
- auto iter = m_Files.find(index);
- if (iter != m_Files.end()) {
- m_Files.erase(iter);
- }
+
+void FilesOrigin::removeFile(FileEntry::Index index)
+{
+ auto iter = m_Files.find(index);
+ if (iter != m_Files.end()) {
+ m_Files.erase(iter);
+ }
}
-static std::wstring tail(const std::wstring& source, const size_t count) {
- if (count >= source.length()) {
- return source;
- }
- return source.substr(source.length() - count);
+
+static std::wstring tail(const std::wstring &source, const size_t count)
+{
+ if (count >= source.length()) {
+ return source;
+ }
+
+ return source.substr(source.length() - count);
}
-FilesOrigin::FilesOrigin() : m_ID(0), m_Disabled(false), m_Name(), m_Path(), m_Priority(0) { LEAK_TRACE; }
-FilesOrigin::FilesOrigin(const FilesOrigin& reference)
- : m_ID(reference.m_ID), m_Disabled(reference.m_Disabled), m_Name(reference.m_Name), m_Path(reference.m_Path),
- m_Priority(reference.m_Priority), m_FileRegister(reference.m_FileRegister),
- m_OriginConnection(reference.m_OriginConnection) {
- LEAK_TRACE;
+FilesOrigin::FilesOrigin()
+ : m_ID(0), m_Disabled(false), m_Name(), m_Path(), m_Priority(0)
+{
+ LEAK_TRACE;
}
-FilesOrigin::FilesOrigin(int ID, const std::wstring& name, const std::wstring& path, int priority,
- boost::shared_ptr<MOShared::FileRegister> fileRegister,
- boost::shared_ptr<MOShared::OriginConnection> originConnection)
- : m_ID(ID), m_Disabled(false), m_Name(name), m_Path(path), m_Priority(priority), m_FileRegister(fileRegister),
- m_OriginConnection(originConnection) {
- LEAK_TRACE;
+FilesOrigin::FilesOrigin(const FilesOrigin &reference)
+ : m_ID(reference.m_ID)
+ , m_Disabled(reference.m_Disabled)
+ , m_Name(reference.m_Name)
+ , m_Path(reference.m_Path)
+ , m_Priority(reference.m_Priority)
+ , m_FileRegister(reference.m_FileRegister)
+ , m_OriginConnection(reference.m_OriginConnection)
+{
+ LEAK_TRACE;
}
-FilesOrigin::~FilesOrigin() { LEAK_UNTRACE; }
-void FilesOrigin::setPriority(int priority) {
- m_OriginConnection.lock()->changePriorityLookup(m_Priority, priority);
+FilesOrigin::FilesOrigin(int ID, const std::wstring &name, const std::wstring &path, int priority, boost::shared_ptr<MOShared::FileRegister> fileRegister, boost::shared_ptr<MOShared::OriginConnection> originConnection)
+ : m_ID(ID), m_Disabled(false), m_Name(name), m_Path(path), m_Priority(priority),
+ m_FileRegister(fileRegister), m_OriginConnection(originConnection)
+{
+ LEAK_TRACE;
+}
- m_Priority = priority;
+FilesOrigin::~FilesOrigin()
+{
+ LEAK_UNTRACE;
}
-void FilesOrigin::setName(const std::wstring& name) {
- m_OriginConnection.lock()->changeNameLookup(m_Name, name);
- // change path too
- if (tail(m_Path, m_Name.length()) == m_Name) {
- m_Path = m_Path.substr(0, m_Path.length() - m_Name.length()).append(name);
- }
- m_Name = name;
+
+void FilesOrigin::setPriority(int priority)
+{
+ m_OriginConnection.lock()->changePriorityLookup(m_Priority, priority);
+
+ m_Priority = priority;
+}
+
+
+void FilesOrigin::setName(const std::wstring &name)
+{
+ m_OriginConnection.lock()->changeNameLookup(m_Name, name);
+ // change path too
+ if (tail(m_Path, m_Name.length()) == m_Name) {
+ m_Path = m_Path.substr(0, m_Path.length() - m_Name.length()).append(name);
+ }
+ m_Name = name;
}
-std::vector<FileEntry::Ptr> FilesOrigin::getFiles() const {
- std::vector<FileEntry::Ptr> result;
- for (FileEntry::Index fileIdx : m_Files)
- if (FileEntry::Ptr p = m_FileRegister.lock()->getFile(fileIdx))
- result.push_back(p);
+std::vector<FileEntry::Ptr> FilesOrigin::getFiles() const
+{
+ std::vector<FileEntry::Ptr> result;
+ for (FileEntry::Index fileIdx : m_Files)
+ if (FileEntry::Ptr p = m_FileRegister.lock()->getFile(fileIdx))
+ result.push_back(p);
- return result;
+ return result;
}
+
//
// FileEntry
//
-void FileEntry::addOrigin(int origin, FILETIME fileTime, const std::wstring& archive) {
- m_LastAccessed = time(nullptr);
- if (m_Parent != nullptr) {
- m_Parent->propagateOrigin(origin);
+void FileEntry::addOrigin(int origin, FILETIME fileTime, const std::wstring &archive)
+{
+ m_LastAccessed = time(nullptr);
+ if (m_Parent != nullptr) {
+ m_Parent->propagateOrigin(origin);
+ }
+ if (m_Origin == -1) {
+ m_Origin = origin;
+ m_FileTime = fileTime;
+ m_Archive = archive;
+ } else if ((m_Parent != nullptr)
+ && (m_Parent->getOriginByID(origin).getPriority() > m_Parent->getOriginByID(m_Origin).getPriority())
+ && (archive.size() == 0 || m_Archive.size() > 0 )) {
+ if (std::find_if(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair<int, std::wstring> &i) -> bool { return i.first == m_Origin; }) == m_Alternatives.end()) {
+ m_Alternatives.push_back(std::pair<int, std::wstring>(m_Origin, m_Archive));
}
- if (m_Origin == -1) {
- m_Origin = origin;
- m_FileTime = fileTime;
- m_Archive = archive;
- } else if ((m_Parent != nullptr) &&
- (m_Parent->getOriginByID(origin).getPriority() > m_Parent->getOriginByID(m_Origin).getPriority()) &&
- (archive.size() == 0 || m_Archive.size() > 0)) {
- if (std::find_if(m_Alternatives.begin(), m_Alternatives.end(),
- [&](const std::pair<int, std::wstring>& i) -> bool { return i.first == m_Origin; }) ==
- m_Alternatives.end()) {
- m_Alternatives.push_back(std::pair<int, std::wstring>(m_Origin, m_Archive));
- }
- m_Origin = origin;
- m_FileTime = fileTime;
- m_Archive = archive;
- } else {
- bool found = false;
- if (m_Origin == origin) {
- // already an origin
- return;
- }
- for (std::vector<std::pair<int, std::wstring>>::iterator iter = m_Alternatives.begin();
- iter != m_Alternatives.end(); ++iter) {
- if (iter->first == origin) {
- // already an origin
- return;
- }
- if ((m_Parent != nullptr) &&
- (m_Parent->getOriginByID(iter->first).getPriority() < m_Parent->getOriginByID(origin).getPriority())) {
- m_Alternatives.insert(iter, std::pair<int, std::wstring>(origin, archive));
- found = true;
- break;
- }
- }
- if (!found) {
- m_Alternatives.push_back(std::pair<int, std::wstring>(origin, archive));
- }
+ m_Origin = origin;
+ m_FileTime = fileTime;
+ m_Archive = archive;
+ } else {
+ bool found = false;
+ if (m_Origin == origin) {
+ // already an origin
+ return;
+ }
+ for (std::vector<std::pair<int, std::wstring>>::iterator iter = m_Alternatives.begin(); iter != m_Alternatives.end(); ++iter) {
+ if (iter->first == origin) {
+ // already an origin
+ return;
+ }
+ if ((m_Parent != nullptr)
+ && (m_Parent->getOriginByID(iter->first).getPriority() < m_Parent->getOriginByID(origin).getPriority())) {
+ m_Alternatives.insert(iter, std::pair<int, std::wstring>(origin, archive));
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ m_Alternatives.push_back(std::pair<int, std::wstring>(origin, archive));
}
+ }
}
-bool FileEntry::removeOrigin(int origin) {
- if (m_Origin == origin) {
- if (!m_Alternatives.empty()) {
- // find alternative with the highest priority
- std::vector<std::pair<int, std::wstring>>::iterator currentIter = m_Alternatives.begin();
- for (std::vector<std::pair<int, std::wstring>>::iterator iter = m_Alternatives.begin();
- iter != m_Alternatives.end(); ++iter) {
- if ((m_Parent->getOriginByID(iter->first).getPriority() >
- m_Parent->getOriginByID(currentIter->first).getPriority()) &&
- (iter->first != origin)) {
- currentIter = iter;
- }
- }
- int currentID = currentIter->first;
- m_Alternatives.erase(currentIter);
+bool FileEntry::removeOrigin(int origin)
+{
+ if (m_Origin == origin) {
+ if (!m_Alternatives.empty()) {
+ // find alternative with the highest priority
+ std::vector<std::pair<int, std::wstring>>::iterator currentIter = m_Alternatives.begin();
+ for (std::vector<std::pair<int, std::wstring>>::iterator iter = m_Alternatives.begin(); iter != m_Alternatives.end(); ++iter) {
+ if ((m_Parent->getOriginByID(iter->first).getPriority() > m_Parent->getOriginByID(currentIter->first).getPriority()) &&
+ (iter->first != origin)) {
+ currentIter = iter;
+ }
+ }
+ int currentID = currentIter->first;
+ m_Alternatives.erase(currentIter);
- m_Origin = currentID;
+ m_Origin = currentID;
- // now we need to update the file time...
- std::wstring filePath = getFullPath();
- HANDLE file = ::CreateFile(filePath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL, nullptr);
- if (!::GetFileTime(file, nullptr, nullptr, &m_FileTime)) {
- // maybe this file is in a bsa, but there is no easy way to find out which. User should refresh
- // the view to find out
- m_Archive = L"bsa?";
- } else {
- m_Archive = L"";
- }
+ // now we need to update the file time...
+ std::wstring filePath = getFullPath();
+ HANDLE file = ::CreateFile(filePath.c_str(), GENERIC_READ | GENERIC_WRITE,
+ 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
+ if (!::GetFileTime(file, nullptr, nullptr, &m_FileTime)) {
+ // maybe this file is in a bsa, but there is no easy way to find out which. User should refresh
+ // the view to find out
+ m_Archive = L"bsa?";
+ } else {
+ m_Archive = L"";
+ }
- ::CloseHandle(file);
+ ::CloseHandle(file);
- } else {
- m_Origin = -1;
- return true;
- }
} else {
- std::vector<std::pair<int, std::wstring>>::iterator newEnd =
- std::find_if(m_Alternatives.begin(), m_Alternatives.end(),
- [&](const std::pair<int, std::wstring>& i) -> bool { return i.first == origin; });
- if (newEnd != m_Alternatives.end())
- m_Alternatives.erase(newEnd, m_Alternatives.end());
+ m_Origin = -1;
+ return true;
}
- return false;
+ } else {
+ std::vector<std::pair<int, std::wstring>>::iterator newEnd = std::find_if(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair<int, std::wstring> &i) -> bool { return i.first == origin; });
+ if (newEnd != m_Alternatives.end())
+ m_Alternatives.erase(newEnd, m_Alternatives.end());
+ }
+ return false;
}
-FileEntry::FileEntry() : m_Index(UINT_MAX), m_Name(), m_Origin(-1), m_Parent(nullptr), m_LastAccessed(time(nullptr)) {
- LEAK_TRACE;
+FileEntry::FileEntry()
+ : m_Index(UINT_MAX), m_Name(), m_Origin(-1), m_Parent(nullptr), m_LastAccessed(time(nullptr))
+{
+ LEAK_TRACE;
}
-FileEntry::FileEntry(Index index, const std::wstring& name, DirectoryEntry* parent)
- : m_Index(index), m_Name(name), m_Origin(-1), m_Archive(L""), m_Parent(parent), m_LastAccessed(time(nullptr)) {
- LEAK_TRACE;
+FileEntry::FileEntry(Index index, const std::wstring &name, DirectoryEntry *parent)
+ : m_Index(index), m_Name(name), m_Origin(-1), m_Archive(L""), m_Parent(parent), m_LastAccessed(time(nullptr))
+{
+ LEAK_TRACE;
}
-FileEntry::~FileEntry() { LEAK_UNTRACE; }
-
-void FileEntry::sortOrigins() {
- m_Alternatives.push_back(std::pair<int, std::wstring>(m_Origin, m_Archive));
- std::sort(m_Alternatives.begin(), m_Alternatives.end(),
- [&](const std::pair<int, std::wstring>& LHS, const std::pair<int, std::wstring>& RHS) -> bool {
- if ((!LHS.second.size() && !RHS.second.size()) || (LHS.second.size() && RHS.second.size())) {
- int l = m_Parent->getOriginByID(LHS.first).getPriority();
- if (l < 0)
- l = INT_MAX;
- int r = m_Parent->getOriginByID(RHS.first).getPriority();
- if (r < 0)
- r = INT_MAX;
+FileEntry::~FileEntry()
+{
+ LEAK_UNTRACE;
+}
- return l < r;
- }
+void FileEntry::sortOrigins()
+{
+ m_Alternatives.push_back(std::pair<int, std::wstring>(m_Origin, m_Archive));
+ std::sort(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair<int, std::wstring> &LHS, const std::pair<int, std::wstring> &RHS) -> bool {
+ if ((!LHS.second.size() && !RHS.second.size()) || (LHS.second.size() && RHS.second.size())) {
+ int l = m_Parent->getOriginByID(LHS.first).getPriority(); if (l < 0) l = INT_MAX;
+ int r = m_Parent->getOriginByID(RHS.first).getPriority(); if (r < 0) r = INT_MAX;
- if (RHS.second.size())
- return false;
- return true;
- });
- if (!m_Alternatives.empty()) {
- m_Origin = m_Alternatives.back().first;
- m_Archive = m_Alternatives.back().second;
- m_Alternatives.pop_back();
+ return l < r;
}
+
+ if (RHS.second.size()) return false;
+ return true;
+ });
+ if (!m_Alternatives.empty()) {
+ m_Origin = m_Alternatives.back().first;
+ m_Archive = m_Alternatives.back().second;
+ m_Alternatives.pop_back();
+ }
}
-bool FileEntry::recurseParents(std::wstring& path, const DirectoryEntry* parent) const {
- if (parent == nullptr) {
- return false;
- } else {
- // don't append the topmost parent because it is the virtual data-root
- if (recurseParents(path, parent->getParent())) {
- path.append(L"\\").append(parent->getName());
- }
- return true;
+
+bool FileEntry::recurseParents(std::wstring &path, const DirectoryEntry *parent) const
+{
+ if (parent == nullptr) {
+ return false;
+ } else {
+ // don't append the topmost parent because it is the virtual data-root
+ if (recurseParents(path, parent->getParent())) {
+ path.append(L"\\").append(parent->getName());
}
+ return true;
+ }
}
-std::wstring FileEntry::getFullPath() const {
- std::wstring result;
- bool ignore = false;
- result = m_Parent->getOriginByID(getOrigin(ignore)).getPath(); // base directory for origin
- recurseParents(result, m_Parent); // all intermediate directories
- return result + L"\\" + m_Name;
+std::wstring FileEntry::getFullPath() const
+{
+ std::wstring result;
+ bool ignore = false;
+ result = m_Parent->getOriginByID(getOrigin(ignore)).getPath(); //base directory for origin
+ recurseParents(result, m_Parent); // all intermediate directories
+ return result + L"\\" + m_Name;
}
-std::wstring FileEntry::getRelativePath() const {
- std::wstring result;
- recurseParents(result, m_Parent); // all intermediate directories
- return result + L"\\" + m_Name;
+std::wstring FileEntry::getRelativePath() const
+{
+ std::wstring result;
+ recurseParents(result, m_Parent); // all intermediate directories
+ return result + L"\\" + m_Name;
}
+
//
// DirectoryEntry
//
-DirectoryEntry::DirectoryEntry(const std::wstring& name, DirectoryEntry* parent, int originID)
- : m_OriginConnection(new OriginConnection), m_Name(name), m_Parent(parent), m_Populated(false), m_TopLevel(true) {
- m_FileRegister.reset(new FileRegister(m_OriginConnection));
- m_Origins.insert(originID);
- LEAK_TRACE;
+DirectoryEntry::DirectoryEntry(const std::wstring &name, DirectoryEntry *parent, int originID)
+ : m_OriginConnection(new OriginConnection),
+ m_Name(name), m_Parent(parent), m_Populated(false), m_TopLevel(true)
+{
+ m_FileRegister.reset(new FileRegister(m_OriginConnection));
+ m_Origins.insert(originID);
+ LEAK_TRACE;
}
-DirectoryEntry::DirectoryEntry(const std::wstring& name, DirectoryEntry* parent, int originID,
- boost::shared_ptr<FileRegister> fileRegister,
- boost::shared_ptr<OriginConnection> originConnection)
- : m_FileRegister(fileRegister), m_OriginConnection(originConnection), m_Name(name), m_Parent(parent),
- m_Populated(false), m_TopLevel(false) {
- LEAK_TRACE;
- m_Origins.insert(originID);
+DirectoryEntry::DirectoryEntry(const std::wstring &name, DirectoryEntry *parent, int originID,
+ boost::shared_ptr<FileRegister> fileRegister, boost::shared_ptr<OriginConnection> originConnection)
+ : m_FileRegister(fileRegister), m_OriginConnection(originConnection),
+ m_Name(name), m_Parent(parent), m_Populated(false), m_TopLevel(false)
+{
+ LEAK_TRACE;
+ m_Origins.insert(originID);
}
-DirectoryEntry::~DirectoryEntry() {
- LEAK_UNTRACE;
- clear();
+
+DirectoryEntry::~DirectoryEntry()
+{
+ LEAK_UNTRACE;
+ clear();
}
-const std::wstring& DirectoryEntry::getName() const { return m_Name; }
-void DirectoryEntry::clear() {
- m_Files.clear();
- for (DirectoryEntry* entry : m_SubDirectories) {
- delete entry;
- }
- m_SubDirectories.clear();
+const std::wstring &DirectoryEntry::getName() const
+{
+ return m_Name;
}
-FilesOrigin& DirectoryEntry::createOrigin(const std::wstring& originName, const std::wstring& directory, int priority) {
- if (m_OriginConnection->exists(originName)) {
- FilesOrigin& origin = m_OriginConnection->getByName(originName);
- origin.enable(true);
- return origin;
- } else {
- return m_OriginConnection->createOrigin(originName, directory, priority, m_FileRegister, m_OriginConnection);
- }
+
+void DirectoryEntry::clear()
+{
+ m_Files.clear();
+ for (DirectoryEntry *entry : m_SubDirectories) {
+ delete entry;
+ }
+ m_SubDirectories.clear();
}
-void DirectoryEntry::addFromOrigin(const std::wstring& originName, const std::wstring& directory, int priority) {
- FilesOrigin& origin = createOrigin(originName, directory, priority);
- if (directory.length() != 0) {
- boost::scoped_array<wchar_t> buffer(new wchar_t[MAXPATH_UNICODE + 1]);
- memset(buffer.get(), L'\0', MAXPATH_UNICODE + 1);
- int offset = _snwprintf(buffer.get(), MAXPATH_UNICODE, L"%ls", directory.c_str());
- buffer.get()[offset] = L'\0';
- addFiles(origin, buffer.get(), offset);
- }
- m_Populated = true;
+
+FilesOrigin &DirectoryEntry::createOrigin(const std::wstring &originName, const std::wstring &directory, int priority)
+{
+ if (m_OriginConnection->exists(originName)) {
+ FilesOrigin &origin = m_OriginConnection->getByName(originName);
+ origin.enable(true);
+ return origin;
+ } else {
+ return m_OriginConnection->createOrigin(originName, directory, priority, m_FileRegister, m_OriginConnection);
+ }
}
-void DirectoryEntry::addFromBSA(const std::wstring& originName, std::wstring& directory, const std::wstring& fileName,
- int priority) {
- FilesOrigin& origin = createOrigin(originName, directory, priority);
- WIN32_FILE_ATTRIBUTE_DATA fileData;
- if (::GetFileAttributesExW(fileName.c_str(), GetFileExInfoStandard, &fileData) == 0) {
- throw windows_error("failed to determine file time");
- }
+void DirectoryEntry::addFromOrigin(const std::wstring &originName, const std::wstring &directory, int priority)
+{
+ FilesOrigin &origin = createOrigin(originName, directory, priority);
+ if (directory.length() != 0) {
+ boost::scoped_array<wchar_t> buffer(new wchar_t[MAXPATH_UNICODE + 1]);
+ memset(buffer.get(), L'\0', MAXPATH_UNICODE + 1);
+ int offset = _snwprintf(buffer.get(), MAXPATH_UNICODE, L"%ls", directory.c_str());
+ buffer.get()[offset] = L'\0';
+ addFiles(origin, buffer.get(), offset);
+ }
+ m_Populated = true;
+}
- BSA::Archive archive;
- BSA::EErrorCode res = archive.read(ToString(fileName, false).c_str(), false);
- if ((res != BSA::ERROR_NONE) && (res != BSA::ERROR_INVALIDHASHES)) {
- std::ostringstream stream;
- stream << "invalid bsa file: " << ToString(fileName, false) << " errorcode " << res << " - "
- << ::GetLastError();
- throw std::runtime_error(stream.str());
- }
- size_t namePos = fileName.find_last_of(L"\\/");
- if (namePos == std::wstring::npos) {
- namePos = 0;
- } else {
- ++namePos;
- }
- addFiles(origin, archive.getRoot(), fileData.ftLastWriteTime, fileName.substr(namePos));
- m_Populated = true;
+void DirectoryEntry::addFromBSA(const std::wstring &originName, std::wstring &directory, const std::wstring &fileName, int priority)
+{
+ FilesOrigin &origin = createOrigin(originName, directory, priority);
+
+ WIN32_FILE_ATTRIBUTE_DATA fileData;
+ if (::GetFileAttributesExW(fileName.c_str(), GetFileExInfoStandard, &fileData) == 0) {
+ throw windows_error("failed to determine file time");
+ }
+
+ BSA::Archive archive;
+ BSA::EErrorCode res = archive.read(ToString(fileName, false).c_str(), false);
+ if ((res != BSA::ERROR_NONE) && (res != BSA::ERROR_INVALIDHASHES)) {
+ std::ostringstream stream;
+ stream << "invalid bsa file: " << ToString(fileName, false) << " errorcode " << res << " - " << ::GetLastError();
+ throw std::runtime_error(stream.str());
+ }
+ size_t namePos = fileName.find_last_of(L"\\/");
+ if (namePos == std::wstring::npos) {
+ namePos = 0;
+ } else {
+ ++namePos;
+ }
+
+ addFiles(origin, archive.getRoot(), fileData.ftLastWriteTime, fileName.substr(namePos));
+ m_Populated = true;
}
-void DirectoryEntry::propagateOrigin(int origin) {
- m_Origins.insert(origin);
- if (m_Parent != nullptr) {
- m_Parent->propagateOrigin(origin);
- }
+void DirectoryEntry::propagateOrigin(int origin)
+{
+ m_Origins.insert(origin);
+ if (m_Parent != nullptr) {
+ m_Parent->propagateOrigin(origin);
+ }
}
-static bool SupportOptimizedFind() {
- // large fetch and basic info for FindFirstFileEx is supported on win server 2008 r2, win 7 and newer
- OSVERSIONINFOEX versionInfo;
- versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
- versionInfo.dwMajorVersion = 6;
- versionInfo.dwMinorVersion = 1;
- ULONGLONG mask = ::VerSetConditionMask(::VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL),
- VER_MINORVERSION, VER_GREATER_EQUAL);
+static bool SupportOptimizedFind()
+{
+ // large fetch and basic info for FindFirstFileEx is supported on win server 2008 r2, win 7 and newer
+
+ OSVERSIONINFOEX versionInfo;
+ versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+ versionInfo.dwMajorVersion = 6;
+ versionInfo.dwMinorVersion = 1;
+ ULONGLONG mask = ::VerSetConditionMask(
+ ::VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL),
+ VER_MINORVERSION, VER_GREATER_EQUAL);
- bool res = ::VerifyVersionInfo(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION, mask) == TRUE;
- return res;
+ bool res = ::VerifyVersionInfo(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION, mask) == TRUE;
+ return res;
}
-static bool DirCompareByName(const DirectoryEntry* lhs, const DirectoryEntry* rhs) {
- return _wcsicmp(lhs->getName().c_str(), rhs->getName().c_str()) < 0;
+
+static bool DirCompareByName(const DirectoryEntry *lhs, const DirectoryEntry *rhs)
+{
+ return _wcsicmp(lhs->getName().c_str(), rhs->getName().c_str()) < 0;
}
-void DirectoryEntry::addFiles(FilesOrigin& origin, wchar_t* buffer, int bufferOffset) {
- WIN32_FIND_DATAW findData;
- _snwprintf_s(buffer + bufferOffset, MAXPATH_UNICODE - bufferOffset, _TRUNCATE, L"\\*");
+void DirectoryEntry::addFiles(FilesOrigin &origin, wchar_t *buffer, int bufferOffset)
+{
+ WIN32_FIND_DATAW findData;
- HANDLE searchHandle = nullptr;
+ _snwprintf_s(buffer + bufferOffset, MAXPATH_UNICODE - bufferOffset, _TRUNCATE, L"\\*");
- if (SupportOptimizedFind()) {
- searchHandle = ::FindFirstFileExW(buffer, FindExInfoBasic, &findData, FindExSearchNameMatch, nullptr,
- FIND_FIRST_EX_LARGE_FETCH);
- } else {
- searchHandle = ::FindFirstFileExW(buffer, FindExInfoStandard, &findData, FindExSearchNameMatch, nullptr, 0);
- }
+ HANDLE searchHandle = nullptr;
- if (searchHandle != INVALID_HANDLE_VALUE) {
- BOOL result = true;
- while (result) {
- if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- if ((wcscmp(findData.cFileName, L".") != 0) && (wcscmp(findData.cFileName, L"..") != 0)) {
- int offset = _snwprintf(buffer + bufferOffset, MAXPATH_UNICODE, L"\\%ls", findData.cFileName);
- // recurse into subdirectories
- getSubDirectory(findData.cFileName, true, origin.getID())
- ->addFiles(origin, buffer, bufferOffset + offset);
- }
- } else {
- insert(findData.cFileName, origin, findData.ftLastWriteTime, L"");
- }
- result = ::FindNextFileW(searchHandle, &findData);
+ if (SupportOptimizedFind()) {
+ searchHandle = ::FindFirstFileExW(buffer, FindExInfoBasic, &findData, FindExSearchNameMatch, nullptr,
+ FIND_FIRST_EX_LARGE_FETCH);
+ } else {
+ searchHandle = ::FindFirstFileExW(buffer, FindExInfoStandard, &findData, FindExSearchNameMatch, nullptr, 0);
+ }
+
+ if (searchHandle != INVALID_HANDLE_VALUE) {
+ BOOL result = true;
+ while (result) {
+ if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ if ((wcscmp(findData.cFileName, L".") != 0) &&
+ (wcscmp(findData.cFileName, L"..") != 0)) {
+ int offset = _snwprintf(buffer + bufferOffset, MAXPATH_UNICODE, L"\\%ls", findData.cFileName);
+ // recurse into subdirectories
+ getSubDirectory(findData.cFileName, true, origin.getID())->addFiles(origin, buffer, bufferOffset + offset);
}
+ } else {
+ insert(findData.cFileName, origin, findData.ftLastWriteTime, L"");
+ }
+ result = ::FindNextFileW(searchHandle, &findData);
}
- std::sort(m_SubDirectories.begin(), m_SubDirectories.end(), &DirCompareByName);
- ::FindClose(searchHandle);
+ }
+ std::sort(m_SubDirectories.begin(), m_SubDirectories.end(), &DirCompareByName);
+ ::FindClose(searchHandle);
}
-void DirectoryEntry::addFiles(FilesOrigin& origin, BSA::Folder::Ptr archiveFolder, FILETIME& fileTime,
- const std::wstring& archiveName) {
- // add files
- for (unsigned int fileIdx = 0; fileIdx < archiveFolder->getNumFiles(); ++fileIdx) {
- BSA::File::Ptr file = archiveFolder->getFile(fileIdx);
- insert(ToWString(file->getName(), true), origin, fileTime, archiveName);
- }
- // recurse into subdirectories
- for (unsigned int folderIdx = 0; folderIdx < archiveFolder->getNumSubFolders(); ++folderIdx) {
- BSA::Folder::Ptr folder = archiveFolder->getSubFolder(folderIdx);
- DirectoryEntry* folderEntry =
- getSubDirectoryRecursive(ToWString(folder->getName(), true), true, origin.getID());
+void DirectoryEntry::addFiles(FilesOrigin &origin, BSA::Folder::Ptr archiveFolder, FILETIME &fileTime, const std::wstring &archiveName)
+{
+ // add files
+ for (unsigned int fileIdx = 0; fileIdx < archiveFolder->getNumFiles(); ++fileIdx) {
+ BSA::File::Ptr file = archiveFolder->getFile(fileIdx);
+ insert(ToWString(file->getName(), true), origin, fileTime, archiveName);
+ }
- folderEntry->addFiles(origin, folder, fileTime, archiveName);
- }
+ // recurse into subdirectories
+ for (unsigned int folderIdx = 0; folderIdx < archiveFolder->getNumSubFolders(); ++folderIdx) {
+ BSA::Folder::Ptr folder = archiveFolder->getSubFolder(folderIdx);
+ DirectoryEntry *folderEntry = getSubDirectoryRecursive(ToWString(folder->getName(), true), true, origin.getID());
+
+ folderEntry->addFiles(origin, folder, fileTime, archiveName);
+ }
}
-bool DirectoryEntry::removeFile(const std::wstring& filePath, int* origin) {
- size_t pos = filePath.find_first_of(L"\\/");
- if (pos == std::string::npos) {
- return this->remove(filePath, origin);
+
+bool DirectoryEntry::removeFile(const std::wstring &filePath, int *origin)
+{
+ size_t pos = filePath.find_first_of(L"\\/");
+ if (pos == std::string::npos) {
+ return this->remove(filePath, origin);
+ } else {
+ std::wstring dirName = filePath.substr(0, pos);
+ std::wstring rest = filePath.substr(pos + 1);
+ DirectoryEntry *entry = getSubDirectoryRecursive(dirName, false);
+ if (entry != nullptr) {
+ return entry->removeFile(rest, origin);
} else {
- std::wstring dirName = filePath.substr(0, pos);
- std::wstring rest = filePath.substr(pos + 1);
- DirectoryEntry* entry = getSubDirectoryRecursive(dirName, false);
- if (entry != nullptr) {
- return entry->removeFile(rest, origin);
- } else {
- return false;
- }
+ return false;
}
+ }
}
-void DirectoryEntry::removeDirRecursive() {
- while (!m_Files.empty()) {
- m_FileRegister->removeFile(m_Files.begin()->second);
- }
+void DirectoryEntry::removeDirRecursive()
+{
+ while (!m_Files.empty()) {
+ m_FileRegister->removeFile(m_Files.begin()->second);
+ }
+
+ for (DirectoryEntry *entry : m_SubDirectories) {
+ entry->removeDirRecursive();
+ delete entry;
+ }
+ m_SubDirectories.clear();
+}
- for (DirectoryEntry* entry : m_SubDirectories) {
+void DirectoryEntry::removeDir(const std::wstring &path)
+{
+ size_t pos = path.find_first_of(L"\\/");
+ if (pos == std::string::npos) {
+ for (auto iter = m_SubDirectories.begin(); iter != m_SubDirectories.end(); ++iter) {
+ DirectoryEntry *entry = *iter;
+ if (CaseInsensitiveEqual(entry->getName(), path)) {
entry->removeDirRecursive();
+ m_SubDirectories.erase(iter);
delete entry;
+ break;
+ }
+ }
+ } else {
+ std::wstring dirName = path.substr(0, pos);
+ std::wstring rest = path.substr(pos + 1);
+ DirectoryEntry *entry = getSubDirectoryRecursive(dirName, false);
+ if (entry != nullptr) {
+ entry->removeDir(rest);
}
- m_SubDirectories.clear();
+ }
}
-void DirectoryEntry::removeDir(const std::wstring& path) {
- size_t pos = path.find_first_of(L"\\/");
- if (pos == std::string::npos) {
- for (auto iter = m_SubDirectories.begin(); iter != m_SubDirectories.end(); ++iter) {
- DirectoryEntry* entry = *iter;
- if (CaseInsensitiveEqual(entry->getName(), path)) {
- entry->removeDirRecursive();
- m_SubDirectories.erase(iter);
- delete entry;
- break;
- }
- }
- } else {
- std::wstring dirName = path.substr(0, pos);
- std::wstring rest = path.substr(pos + 1);
- DirectoryEntry* entry = getSubDirectoryRecursive(dirName, false);
- if (entry != nullptr) {
- entry->removeDir(rest);
- }
- }
+bool DirectoryEntry::hasContentsFromOrigin(int originID) const
+{
+ return m_Origins.find(originID) != m_Origins.end();
+}
+
+void DirectoryEntry::insertFile(const std::wstring &filePath, FilesOrigin &origin, FILETIME fileTime)
+{
+ size_t pos = filePath.find_first_of(L"\\/");
+ if (pos == std::string::npos) {
+ this->insert(filePath, origin, fileTime, std::wstring());
+ } else {
+ std::wstring dirName = filePath.substr(0, pos);
+ std::wstring rest = filePath.substr(pos + 1);
+ getSubDirectoryRecursive(dirName, true, origin.getID())->insertFile(rest, origin, fileTime);
+ }
}
-bool DirectoryEntry::hasContentsFromOrigin(int originID) const { return m_Origins.find(originID) != m_Origins.end(); }
-void DirectoryEntry::insertFile(const std::wstring& filePath, FilesOrigin& origin, FILETIME fileTime) {
- size_t pos = filePath.find_first_of(L"\\/");
- if (pos == std::string::npos) {
- this->insert(filePath, origin, fileTime, std::wstring());
+void DirectoryEntry::removeFile(FileEntry::Index index)
+{
+ if (!m_Files.empty()) {
+ auto iter = std::find_if(m_Files.begin(), m_Files.end(),
+ [&index](const std::pair<std::wstring, FileEntry::Index> &iter) -> bool {
+ return iter.second == index; } );
+ if (iter != m_Files.end()) {
+ m_Files.erase(iter);
} else {
- std::wstring dirName = filePath.substr(0, pos);
- std::wstring rest = filePath.substr(pos + 1);
- getSubDirectoryRecursive(dirName, true, origin.getID())->insertFile(rest, origin, fileTime);
+ log("file \"%ls\" not in directory \"%ls\"",
+ m_FileRegister->getFile(index)->getName().c_str(),
+ this->getName().c_str());
}
+ } else {
+ log("file \"%ls\" not in directory \"%ls\", directory empty",
+ m_FileRegister->getFile(index)->getName().c_str(),
+ this->getName().c_str());
+ }
}
-void DirectoryEntry::removeFile(FileEntry::Index index) {
- if (!m_Files.empty()) {
- auto iter = std::find_if(
- m_Files.begin(), m_Files.end(),
- [&index](const std::pair<std::wstring, FileEntry::Index>& iter) -> bool { return iter.second == index; });
- if (iter != m_Files.end()) {
- m_Files.erase(iter);
- } else {
- log("file \"%ls\" not in directory \"%ls\"", m_FileRegister->getFile(index)->getName().c_str(),
- this->getName().c_str());
- }
+
+void DirectoryEntry::removeFiles(const std::set<FileEntry::Index> &indices)
+{
+ for (auto iter = m_Files.begin(); iter != m_Files.end();) {
+ if (indices.find(iter->second) != indices.end()) {
+ m_Files.erase(iter++);
} else {
- log("file \"%ls\" not in directory \"%ls\", directory empty", m_FileRegister->getFile(index)->getName().c_str(),
- this->getName().c_str());
+ ++iter;
}
+ }
}
-void DirectoryEntry::removeFiles(const std::set<FileEntry::Index>& indices) {
- for (auto iter = m_Files.begin(); iter != m_Files.end();) {
- if (indices.find(iter->second) != indices.end()) {
- m_Files.erase(iter++);
- } else {
- ++iter;
- }
- }
-}
-int DirectoryEntry::anyOrigin() const {
- bool ignore;
- for (auto iter = m_Files.begin(); iter != m_Files.end(); ++iter) {
- FileEntry::Ptr entry = m_FileRegister->getFile(iter->second);
- if ((entry.get() != nullptr) && !entry->isFromArchive()) {
- return entry->getOrigin(ignore);
- }
+int DirectoryEntry::anyOrigin() const
+{
+ bool ignore;
+ for (auto iter = m_Files.begin(); iter != m_Files.end(); ++iter) {
+ FileEntry::Ptr entry = m_FileRegister->getFile(iter->second);
+ if ((entry.get() != nullptr) && !entry->isFromArchive()) {
+ return entry->getOrigin(ignore);
}
+ }
- // if we got here, no file directly within this directory is a valid indicator for a mod, thus
- // we continue looking in subdirectories
- for (DirectoryEntry* entry : m_SubDirectories) {
- int res = entry->anyOrigin();
- if (res != -1) {
- return res;
- }
+ // if we got here, no file directly within this directory is a valid indicator for a mod, thus
+ // we continue looking in subdirectories
+ for (DirectoryEntry *entry : m_SubDirectories) {
+ int res = entry->anyOrigin();
+ if (res != -1){
+ return res;
}
- return *(m_Origins.begin());
+ }
+ return *(m_Origins.begin());
+}
+
+
+bool DirectoryEntry::originExists(const std::wstring &name) const
+{
+ return m_OriginConnection->exists(name);
}
-bool DirectoryEntry::originExists(const std::wstring& name) const { return m_OriginConnection->exists(name); }
-FilesOrigin& DirectoryEntry::getOriginByID(int ID) const { return m_OriginConnection->getByID(ID); }
+FilesOrigin &DirectoryEntry::getOriginByID(int ID) const
+{
+ return m_OriginConnection->getByID(ID);
+}
-FilesOrigin& DirectoryEntry::getOriginByName(const std::wstring& name) const {
- return m_OriginConnection->getByName(name);
+
+FilesOrigin &DirectoryEntry::getOriginByName(const std::wstring &name) const
+{
+ return m_OriginConnection->getByName(name);
}
/*
@@ -627,219 +723,251 @@ int DirectoryEntry::getOrigin(const std::wstring &path, bool &archive)
}
}*/
-std::vector<FileEntry::Ptr> DirectoryEntry::getFiles() const {
- std::vector<FileEntry::Ptr> result;
- for (auto iter = m_Files.begin(); iter != m_Files.end(); ++iter) {
- result.push_back(m_FileRegister->getFile(iter->second));
- }
- return result;
+std::vector<FileEntry::Ptr> DirectoryEntry::getFiles() const
+{
+ std::vector<FileEntry::Ptr> result;
+ for (auto iter = m_Files.begin(); iter != m_Files.end(); ++iter) {
+ result.push_back(m_FileRegister->getFile(iter->second));
+ }
+ return result;
}
-const FileEntry::Ptr DirectoryEntry::searchFile(const std::wstring& path, const DirectoryEntry** directory) const {
+
+const FileEntry::Ptr DirectoryEntry::searchFile(const std::wstring &path, const DirectoryEntry **directory) const
+{
+ if (directory != nullptr) {
+ *directory = nullptr;
+ }
+
+ if ((path.length() == 0) || (path == L"*")) {
+ // no file name -> the path ended on a (back-)slash
if (directory != nullptr) {
- *directory = nullptr;
+ *directory = this;
}
+ return FileEntry::Ptr();
+ }
- if ((path.length() == 0) || (path == L"*")) {
- // no file name -> the path ended on a (back-)slash
- if (directory != nullptr) {
- *directory = this;
- }
+ size_t len = path.find_first_of(L"\\/");
+
+ if (len == std::string::npos) {
+ // no more path components
+ auto iter = m_Files.find(ToLower(path));
+ if (iter != m_Files.end()) {
+ return m_FileRegister->getFile(iter->second);
+ } else if (directory != nullptr) {
+ DirectoryEntry *temp = findSubDirectory(path);
+ if (temp != nullptr) {
+ *directory = temp;
+ }
+ }
+ } else {
+ // file is in in a subdirectory, recurse into the matching subdirectory
+ std::wstring pathComponent = path.substr(0, len);
+ DirectoryEntry *temp = findSubDirectory(pathComponent);
+ if (temp != nullptr) {
+ if (len >= path.size()) {
+ log("unexpected end of path");
return FileEntry::Ptr();
+ }
+ return temp->searchFile(path.substr(len + 1), directory);
}
+ }
+ return FileEntry::Ptr();
+}
- size_t len = path.find_first_of(L"\\/");
- if (len == std::string::npos) {
- // no more path components
- auto iter = m_Files.find(ToLower(path));
- if (iter != m_Files.end()) {
- return m_FileRegister->getFile(iter->second);
- } else if (directory != nullptr) {
- DirectoryEntry* temp = findSubDirectory(path);
- if (temp != nullptr) {
- *directory = temp;
- }
- }
- } else {
- // file is in in a subdirectory, recurse into the matching subdirectory
- std::wstring pathComponent = path.substr(0, len);
- DirectoryEntry* temp = findSubDirectory(pathComponent);
- if (temp != nullptr) {
- if (len >= path.size()) {
- log("unexpected end of path");
- return FileEntry::Ptr();
- }
- return temp->searchFile(path.substr(len + 1), directory);
- }
+DirectoryEntry *DirectoryEntry::findSubDirectory(const std::wstring &name) const
+{
+ for (DirectoryEntry *entry : m_SubDirectories) {
+ if (CaseInsensitiveEqual(entry->getName(), name)) {
+ return entry;
}
- return FileEntry::Ptr();
+ }
+ return nullptr;
}
-DirectoryEntry* DirectoryEntry::findSubDirectory(const std::wstring& name) const {
- for (DirectoryEntry* entry : m_SubDirectories) {
- if (CaseInsensitiveEqual(entry->getName(), name)) {
- return entry;
- }
- }
- return nullptr;
-}
-DirectoryEntry* DirectoryEntry::findSubDirectoryRecursive(const std::wstring& path) {
- return getSubDirectoryRecursive(path, false, -1);
+DirectoryEntry *DirectoryEntry::findSubDirectoryRecursive(const std::wstring &path)
+{
+ return getSubDirectoryRecursive(path, false, -1);
}
-const FileEntry::Ptr DirectoryEntry::findFile(const std::wstring& name) const {
- auto iter = m_Files.find(ToLower(name));
- if (iter != m_Files.end()) {
- return m_FileRegister->getFile(iter->second);
- } else {
- return FileEntry::Ptr();
- }
+
+const FileEntry::Ptr DirectoryEntry::findFile(const std::wstring &name) const
+{
+ auto iter = m_Files.find(ToLower(name));
+ if (iter != m_Files.end()) {
+ return m_FileRegister->getFile(iter->second);
+ } else {
+ return FileEntry::Ptr();
+ }
}
-DirectoryEntry* DirectoryEntry::getSubDirectory(const std::wstring& name, bool create, int originID) {
- for (DirectoryEntry* entry : m_SubDirectories) {
- if (CaseInsensitiveEqual(entry->getName(), name)) {
- return entry;
- }
- }
- if (create) {
- std::vector<DirectoryEntry*>::iterator iter = m_SubDirectories.insert(
- m_SubDirectories.end(), new DirectoryEntry(name, this, originID, m_FileRegister, m_OriginConnection));
- return *iter;
- } else {
- return nullptr;
+DirectoryEntry *DirectoryEntry::getSubDirectory(const std::wstring &name, bool create, int originID)
+{
+ for (DirectoryEntry *entry : m_SubDirectories) {
+ if (CaseInsensitiveEqual(entry->getName(), name)) {
+ return entry;
}
+ }
+ if (create) {
+ std::vector<DirectoryEntry*>::iterator iter = m_SubDirectories.insert(m_SubDirectories.end(),
+ new DirectoryEntry(name, this, originID, m_FileRegister, m_OriginConnection));
+ return *iter;
+ } else {
+ return nullptr;
+ }
}
-DirectoryEntry* DirectoryEntry::getSubDirectoryRecursive(const std::wstring& path, bool create, int originID) {
- if (path.length() == 0) {
- // path ended with a backslash?
- return this;
- }
- size_t pos = path.find_first_of(L"\\/");
- if (pos == std::wstring::npos) {
- return getSubDirectory(path, create);
+DirectoryEntry *DirectoryEntry::getSubDirectoryRecursive(const std::wstring &path, bool create, int originID)
+{
+ if (path.length() == 0) {
+ // path ended with a backslash?
+ return this;
+ }
+
+ size_t pos = path.find_first_of(L"\\/");
+ if (pos == std::wstring::npos) {
+ return getSubDirectory(path, create);
+ } else {
+ DirectoryEntry *nextChild = getSubDirectory(path.substr(0, pos), create, originID);
+ if (nextChild == nullptr) {
+ return nullptr;
} else {
- DirectoryEntry* nextChild = getSubDirectory(path.substr(0, pos), create, originID);
- if (nextChild == nullptr) {
- return nullptr;
- } else {
- return nextChild->getSubDirectoryRecursive(path.substr(pos + 1), create, originID);
- }
+ return nextChild->getSubDirectoryRecursive(path.substr(pos + 1), create, originID);
}
+ }
}
+
+
FileRegister::FileRegister(boost::shared_ptr<OriginConnection> originConnection)
- : m_OriginConnection(originConnection) {
- LEAK_TRACE;
+ : m_OriginConnection(originConnection)
+{
+ LEAK_TRACE;
}
-FileRegister::~FileRegister() {
- LEAK_UNTRACE;
- m_Files.clear();
+FileRegister::~FileRegister()
+{
+ LEAK_UNTRACE;
+ m_Files.clear();
}
-FileEntry::Index FileRegister::generateIndex() {
- static std::atomic<FileEntry::Index> sIndex(0);
- return sIndex++;
+
+FileEntry::Index FileRegister::generateIndex()
+{
+ static std::atomic<FileEntry::Index> sIndex(0);
+ return sIndex++;
}
-bool FileRegister::indexValid(FileEntry::Index index) const { return m_Files.find(index) != m_Files.end(); }
+bool FileRegister::indexValid(FileEntry::Index index) const
+{
+ return m_Files.find(index) != m_Files.end();
+}
-FileEntry::Ptr FileRegister::createFile(const std::wstring& name, DirectoryEntry* parent) {
- FileEntry::Index index = generateIndex();
- m_Files[index] = FileEntry::Ptr(new FileEntry(index, name, parent));
- return m_Files[index];
+FileEntry::Ptr FileRegister::createFile(const std::wstring &name, DirectoryEntry *parent)
+{
+ FileEntry::Index index = generateIndex();
+ m_Files[index] = FileEntry::Ptr(new FileEntry(index, name, parent));
+ return m_Files[index];
}
-FileEntry::Ptr FileRegister::getFile(FileEntry::Index index) const {
- auto iter = m_Files.find(index);
- if (iter != m_Files.end()) {
- return iter->second;
- } else {
- return FileEntry::Ptr();
- }
+
+FileEntry::Ptr FileRegister::getFile(FileEntry::Index index) const
+{
+ auto iter = m_Files.find(index);
+ if (iter != m_Files.end()) {
+ return iter->second;
+ } else {
+ return FileEntry::Ptr();
+ }
}
-void FileRegister::unregisterFile(FileEntry::Ptr file) {
- bool ignore;
- // unregister from origin
- int originID = file->getOrigin(ignore);
- m_OriginConnection->getByID(originID).removeFile(file->getIndex());
- const std::vector<std::pair<int, std::wstring>>& alternatives = file->getAlternatives();
- for (auto iter = alternatives.begin(); iter != alternatives.end(); ++iter) {
- m_OriginConnection->getByID(iter->first).removeFile(file->getIndex());
- }
+void FileRegister::unregisterFile(FileEntry::Ptr file)
+{
+ bool ignore;
+ // unregister from origin
+ int originID = file->getOrigin(ignore);
+ m_OriginConnection->getByID(originID).removeFile(file->getIndex());
+ const std::vector<std::pair<int, std::wstring>> &alternatives = file->getAlternatives();
+ for (auto iter = alternatives.begin(); iter != alternatives.end(); ++iter) {
+ m_OriginConnection->getByID(iter->first).removeFile(file->getIndex());
+ }
- // unregister from directory
- if (file->getParent() != nullptr) {
- file->getParent()->removeFile(file->getIndex());
- }
+ // unregister from directory
+ if (file->getParent() != nullptr) {
+ file->getParent()->removeFile(file->getIndex());
+ }
}
-bool FileRegister::removeFile(FileEntry::Index index) {
- auto iter = m_Files.find(index);
- if (iter != m_Files.end()) {
- unregisterFile(iter->second);
- m_Files.erase(index);
- return true;
- } else {
- log("invalid file index for remove: %lu", index);
- return false;
- }
+
+bool FileRegister::removeFile(FileEntry::Index index)
+{
+ auto iter = m_Files.find(index);
+ if (iter != m_Files.end()) {
+ unregisterFile(iter->second);
+ m_Files.erase(index);
+ return true;
+ } else {
+ log("invalid file index for remove: %lu", index);
+ return false;
+ }
}
-void FileRegister::removeOrigin(FileEntry::Index index, int originID) {
- auto iter = m_Files.find(index);
- if (iter != m_Files.end()) {
- if (iter->second->removeOrigin(originID)) {
- unregisterFile(iter->second);
- m_Files.erase(iter);
- }
- } else {
- log("invalid file index for remove (for origin): %lu", index);
+void FileRegister::removeOrigin(FileEntry::Index index, int originID)
+{
+ auto iter = m_Files.find(index);
+ if (iter != m_Files.end()) {
+ if (iter->second->removeOrigin(originID)) {
+ unregisterFile(iter->second);
+ m_Files.erase(iter);
}
+ } else {
+ log("invalid file index for remove (for origin): %lu", index);
+ }
}
-void FileRegister::removeOriginMulti(std::set<FileEntry::Index> indices, int originID, time_t notAfter) {
- std::vector<FileEntry::Ptr> removedFiles;
- for (auto iter = indices.begin(); iter != indices.end();) {
- auto pos = m_Files.find(*iter);
- if (pos != m_Files.end() && (pos->second->lastAccessed() < notAfter) && pos->second->removeOrigin(originID)) {
- removedFiles.push_back(pos->second);
- m_Files.erase(pos);
- ++iter;
- } else {
- indices.erase(iter++);
- }
+void FileRegister::removeOriginMulti(std::set<FileEntry::Index> indices, int originID, time_t notAfter)
+{
+ std::vector<FileEntry::Ptr> removedFiles;
+ for (auto iter = indices.begin(); iter != indices.end();) {
+ auto pos = m_Files.find(*iter);
+ if (pos != m_Files.end()
+ && (pos->second->lastAccessed() < notAfter)
+ && pos->second->removeOrigin(originID)) {
+ removedFiles.push_back(pos->second);
+ m_Files.erase(pos);
+ ++iter;
+ } else {
+ indices.erase(iter++);
}
+ }
- // optimization: this is only called when disabling an origin and in this case we don't have
- // to remove the file from the origin
+ // optimization: this is only called when disabling an origin and in this case we don't have
+ // to remove the file from the origin
- // need to remove files from their parent directories. multiple ways to go about this:
- // a) for each file, search its parents file-list (preferably by name) and remove what is found
- // b) gather the parent directories, go through the file list for each once and remove all files that have been
- // removed the latter should be faster when there are many files in few directories. since this is called only when
- // disabling an origin that is probably frequently the case
- std::set<DirectoryEntry*> parents;
- for (const FileEntry::Ptr& file : removedFiles) {
- if (file->getParent() != nullptr) {
- parents.insert(file->getParent());
- }
- }
- for (DirectoryEntry* parent : parents) {
- parent->removeFiles(indices);
+ // need to remove files from their parent directories. multiple ways to go about this:
+ // a) for each file, search its parents file-list (preferably by name) and remove what is found
+ // b) gather the parent directories, go through the file list for each once and remove all files that have been removed
+ // the latter should be faster when there are many files in few directories. since this is called
+ // only when disabling an origin that is probably frequently the case
+ std::set<DirectoryEntry*> parents;
+ for (const FileEntry::Ptr &file : removedFiles) {
+ if (file->getParent() != nullptr) {
+ parents.insert(file->getParent());
}
+ }
+ for (DirectoryEntry *parent : parents) {
+ parent->removeFiles(indices);
+ }
}
-void FileRegister::sortOrigins() {
- for (auto iter = m_Files.begin(); iter != m_Files.end(); ++iter) {
- iter->second->sortOrigins();
- }
+void FileRegister::sortOrigins()
+{
+ for (auto iter = m_Files.begin(); iter != m_Files.end(); ++iter) {
+ iter->second->sortOrigins();
+ }
}
} // namespace MOShared
diff --git a/src/shared/directoryentry.h b/src/shared/directoryentry.h
index c26fb433..8dbedaf4 100644
--- a/src/shared/directoryentry.h
+++ b/src/shared/directoryentry.h
@@ -20,11 +20,12 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef DIRECTORYENTRY_H
#define DIRECTORYENTRY_H
-#include <cassert>
-#include <map>
-#include <set>
+
#include <string>
+#include <set>
#include <vector>
+#include <map>
+#include <cassert>
#define WIN32_MEAN_AND_LEAN
#include <Windows.h>
#include <bsatk.h>
@@ -34,291 +35,311 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#endif
#include "util.h"
+
namespace MOShared {
+
class DirectoryEntry;
class OriginConnection;
class FileRegister;
+
class FileEntry {
public:
- typedef unsigned int Index;
- typedef boost::shared_ptr<FileEntry> Ptr;
+ typedef unsigned int Index;
+
+ typedef boost::shared_ptr<FileEntry> Ptr;
public:
- FileEntry();
- FileEntry(Index index, const std::wstring& name, DirectoryEntry* parent);
+ FileEntry();
- ~FileEntry();
+ FileEntry(Index index, const std::wstring &name, DirectoryEntry *parent);
- Index getIndex() const { return m_Index; }
+ ~FileEntry();
- time_t lastAccessed() const { return m_LastAccessed; }
+ Index getIndex() const { return m_Index; }
- void addOrigin(int origin, FILETIME fileTime, const std::wstring& archive);
- // remove the specified origin from the list of origins that contain this file. if no origin is left,
- // the file is effectively deleted and true is returned. otherwise, false is returned
- bool removeOrigin(int origin);
- void sortOrigins();
+ time_t lastAccessed() const { return m_LastAccessed; }
- // gets the list of alternative origins (origins with lower priority than the primary one).
- // if sortOrigins has been called, it is sorted by priority (ascending)
- const std::vector<std::pair<int, std::wstring>>& getAlternatives() const { return m_Alternatives; }
+ void addOrigin(int origin, FILETIME fileTime, const std::wstring &archive);
+ // remove the specified origin from the list of origins that contain this file. if no origin is left,
+ // the file is effectively deleted and true is returned. otherwise, false is returned
+ bool removeOrigin(int origin);
+ void sortOrigins();
- const std::wstring& getName() const { return m_Name; }
- int getOrigin() const { return m_Origin; }
- int getOrigin(bool& archive) const {
- archive = (m_Archive.length() != 0);
- return m_Origin;
- }
- const std::wstring& getArchive() const { return m_Archive; }
- bool isFromArchive() const { return m_Archive.length() != 0; }
- std::wstring getFullPath() const;
- std::wstring getRelativePath() const;
- DirectoryEntry* getParent() { return m_Parent; }
+ // gets the list of alternative origins (origins with lower priority than the primary one).
+ // if sortOrigins has been called, it is sorted by priority (ascending)
+ const std::vector<std::pair<int, std::wstring>> &getAlternatives() const { return m_Alternatives; }
+
+ const std::wstring &getName() const { return m_Name; }
+ int getOrigin() const { return m_Origin; }
+ int getOrigin(bool &archive) const { archive = (m_Archive.length() != 0); return m_Origin; }
+ const std::wstring &getArchive() const { return m_Archive; }
+ bool isFromArchive() const { return m_Archive.length() != 0; }
+ std::wstring getFullPath() const;
+ std::wstring getRelativePath() const;
+ DirectoryEntry *getParent() { return m_Parent; }
- void setFileTime(FILETIME fileTime) const { m_FileTime = fileTime; }
- FILETIME getFileTime() const { return m_FileTime; }
+ void setFileTime(FILETIME fileTime) const { m_FileTime = fileTime; }
+ FILETIME getFileTime() const { return m_FileTime; }
private:
- bool recurseParents(std::wstring& path, const DirectoryEntry* parent) const;
- void determineTime();
+ bool recurseParents(std::wstring &path, const DirectoryEntry *parent) const;
+
+ void determineTime();
private:
- Index m_Index;
- std::wstring m_Name;
- int m_Origin = -1;
- std::wstring m_Archive;
- std::vector<std::pair<int, std::wstring>> m_Alternatives;
- DirectoryEntry* m_Parent;
- mutable FILETIME m_FileTime;
- time_t m_LastAccessed;
+ Index m_Index;
+ std::wstring m_Name;
+ int m_Origin = -1;
+ std::wstring m_Archive;
+ std::vector<std::pair<int, std::wstring>> m_Alternatives;
+ DirectoryEntry *m_Parent;
+ mutable FILETIME m_FileTime;
- friend bool operator<(const FileEntry& lhs, const FileEntry& rhs) {
- return _wcsicmp(lhs.m_Name.c_str(), rhs.m_Name.c_str()) < 0;
- }
- friend bool operator==(const FileEntry& lhs, const FileEntry& rhs) {
- return _wcsicmp(lhs.m_Name.c_str(), rhs.m_Name.c_str()) == 0;
- }
+ time_t m_LastAccessed;
+
+ friend bool operator<(const FileEntry &lhs, const FileEntry &rhs) {
+ return _wcsicmp(lhs.m_Name.c_str(), rhs.m_Name.c_str()) < 0;
+ }
+ friend bool operator==(const FileEntry &lhs, const FileEntry &rhs) {
+ return _wcsicmp(lhs.m_Name.c_str(), rhs.m_Name.c_str()) == 0;
+ }
};
+
// represents a mod or the data directory, providing files to the tree
class FilesOrigin {
- friend class OriginConnection;
-
+ friend class OriginConnection;
public:
- FilesOrigin();
- FilesOrigin(const FilesOrigin& reference);
- ~FilesOrigin();
- // sets priority for this origin, but it will overwrite the exisiting mapping for this priority,
- // the previous origin will no longer be referenced
- void setPriority(int priority);
+ FilesOrigin();
+ FilesOrigin(const FilesOrigin &reference);
+ ~FilesOrigin();
- int getPriority() const { return m_Priority; }
+ // sets priority for this origin, but it will overwrite the exisiting mapping for this priority,
+ // the previous origin will no longer be referenced
+ void setPriority(int priority);
- void setName(const std::wstring& name);
- const std::wstring& getName() const { return m_Name; }
+ int getPriority() const { return m_Priority; }
- int getID() const { return m_ID; }
- const std::wstring& getPath() const { return m_Path; }
+ void setName(const std::wstring &name);
+ const std::wstring &getName() const { return m_Name; }
- std::vector<FileEntry::Ptr> getFiles() const;
+ int getID() const { return m_ID; }
+ const std::wstring &getPath() const { return m_Path; }
- void enable(bool enabled, time_t notAfter = LONG_MAX);
- bool isDisabled() const { return m_Disabled; }
+ std::vector<FileEntry::Ptr> getFiles() const;
- void addFile(FileEntry::Index index) { m_Files.insert(index); }
- void removeFile(FileEntry::Index index);
+ void enable(bool enabled, time_t notAfter = LONG_MAX);
+ bool isDisabled() const { return m_Disabled; }
+
+ void addFile(FileEntry::Index index) { m_Files.insert(index); }
+ void removeFile(FileEntry::Index index);
private:
- FilesOrigin(int ID, const std::wstring& name, const std::wstring& path, int priority,
- boost::shared_ptr<FileRegister> fileRegister, boost::shared_ptr<OriginConnection> originConnection);
+
+ FilesOrigin(int ID, const std::wstring &name, const std::wstring &path, int priority,
+ boost::shared_ptr<FileRegister> fileRegister, boost::shared_ptr<OriginConnection> originConnection);
+
private:
- int m_ID;
- bool m_Disabled;
+ int m_ID;
+
+ bool m_Disabled;
+
+ std::set<FileEntry::Index> m_Files;
+ std::wstring m_Name;
+ std::wstring m_Path;
+ int m_Priority;
+ boost::weak_ptr<FileRegister> m_FileRegister;
+ boost::weak_ptr<OriginConnection> m_OriginConnection;
- std::set<FileEntry::Index> m_Files;
- std::wstring m_Name;
- std::wstring m_Path;
- int m_Priority;
- boost::weak_ptr<FileRegister> m_FileRegister;
- boost::weak_ptr<OriginConnection> m_OriginConnection;
};
-class FileRegister {
+
+class FileRegister
+{
public:
- FileRegister(boost::shared_ptr<OriginConnection> originConnection);
- ~FileRegister();
- bool indexValid(FileEntry::Index index) const;
+ FileRegister(boost::shared_ptr<OriginConnection> originConnection);
+ ~FileRegister();
+
+ bool indexValid(FileEntry::Index index) const;
- FileEntry::Ptr createFile(const std::wstring& name, DirectoryEntry* parent);
- FileEntry::Ptr getFile(FileEntry::Index index) const;
+ FileEntry::Ptr createFile(const std::wstring &name, DirectoryEntry *parent);
+ FileEntry::Ptr getFile(FileEntry::Index index) const;
- size_t size() const { return m_Files.size(); }
+ size_t size() const { return m_Files.size(); }
- bool removeFile(FileEntry::Index index);
- void removeOrigin(FileEntry::Index index, int originID);
- void removeOriginMulti(std::set<FileEntry::Index> indices, int originID, time_t notAfter);
+ bool removeFile(FileEntry::Index index);
+ void removeOrigin(FileEntry::Index index, int originID);
+ void removeOriginMulti(std::set<FileEntry::Index> indices, int originID, time_t notAfter);
- void sortOrigins();
+ void sortOrigins();
private:
- FileEntry::Index generateIndex();
- void unregisterFile(FileEntry::Ptr file);
+ FileEntry::Index generateIndex();
+
+ void unregisterFile(FileEntry::Ptr file);
private:
- std::map<FileEntry::Index, FileEntry::Ptr> m_Files;
- boost::shared_ptr<OriginConnection> m_OriginConnection;
+ std::map<FileEntry::Index, FileEntry::Ptr> m_Files;
+
+ boost::shared_ptr<OriginConnection> m_OriginConnection;
+
};
-class DirectoryEntry {
+
+class DirectoryEntry
+{
public:
- DirectoryEntry(const std::wstring& name, DirectoryEntry* parent, int originID);
- DirectoryEntry(const std::wstring& name, DirectoryEntry* parent, int originID,
- boost::shared_ptr<FileRegister> fileRegister, boost::shared_ptr<OriginConnection> originConnection);
+ DirectoryEntry(const std::wstring &name, DirectoryEntry *parent, int originID);
- ~DirectoryEntry();
+ DirectoryEntry(const std::wstring &name, DirectoryEntry *parent, int originID,
+ boost::shared_ptr<FileRegister> fileRegister,
+ boost::shared_ptr<OriginConnection> originConnection);
- void clear();
- bool isPopulated() const { return m_Populated; }
+ ~DirectoryEntry();
- bool isEmpty() const { return m_Files.empty() && m_SubDirectories.empty(); }
+ void clear();
+ bool isPopulated() const { return m_Populated; }
- const DirectoryEntry* getParent() const { return m_Parent; }
+ bool isEmpty() const { return m_Files.empty() && m_SubDirectories.empty(); }
- // add files to this directory (and subdirectories) from the specified origin. That origin may exist or not
- void addFromOrigin(const std::wstring& originName, const std::wstring& directory, int priority);
- void addFromBSA(const std::wstring& originName, std::wstring& directory, const std::wstring& fileName,
- int priority);
+ const DirectoryEntry *getParent() const { return m_Parent; }
- void propagateOrigin(int origin);
+ // add files to this directory (and subdirectories) from the specified origin. That origin may exist or not
+ void addFromOrigin(const std::wstring &originName, const std::wstring &directory, int priority);
+ void addFromBSA(const std::wstring &originName, std::wstring &directory, const std::wstring &fileName, int priority);
- const std::wstring& getName() const;
+ void propagateOrigin(int origin);
- boost::shared_ptr<FileRegister> getFileRegister() { return m_FileRegister; }
+ const std::wstring &getName() const;
- bool originExists(const std::wstring& name) const;
- FilesOrigin& getOriginByID(int ID) const;
- FilesOrigin& getOriginByName(const std::wstring& name) const;
+ boost::shared_ptr<FileRegister> getFileRegister() { return m_FileRegister; }
- int anyOrigin() const;
+ bool originExists(const std::wstring &name) const;
+ FilesOrigin &getOriginByID(int ID) const;
+ FilesOrigin &getOriginByName(const std::wstring &name) const;
- // int getOrigin(const std::wstring &path, bool &archive);
+ int anyOrigin() const;
- std::vector<FileEntry::Ptr> getFiles() const;
+ //int getOrigin(const std::wstring &path, bool &archive);
- void getSubDirectories(std::vector<DirectoryEntry*>::const_iterator& begin,
- std::vector<DirectoryEntry*>::const_iterator& end) const {
- begin = m_SubDirectories.begin();
- end = m_SubDirectories.end();
- }
+ std::vector<FileEntry::Ptr> getFiles() const;
- DirectoryEntry* findSubDirectory(const std::wstring& name) const;
- DirectoryEntry* findSubDirectoryRecursive(const std::wstring& path);
+ void getSubDirectories(std::vector<DirectoryEntry*>::const_iterator &begin
+ , std::vector<DirectoryEntry*>::const_iterator &end) const {
+ begin = m_SubDirectories.begin(); end = m_SubDirectories.end();
+ }
- /** retrieve a file in this directory by name.
- * @param name name of the file
- * @return fileentry object for the file or nullptr if no file matches
- */
- const FileEntry::Ptr findFile(const std::wstring& name) const;
+ DirectoryEntry *findSubDirectory(const std::wstring &name) const;
+ DirectoryEntry *findSubDirectoryRecursive(const std::wstring &path);
- /** search through this directory and all subdirectories for a file by the specified name (relative path).
- if directory is not nullptr, the referenced variable will be set to the path containing the file */
- const FileEntry::Ptr searchFile(const std::wstring& path, const DirectoryEntry** directory) const;
+ /** retrieve a file in this directory by name.
+ * @param name name of the file
+ * @return fileentry object for the file or nullptr if no file matches
+ */
+ const FileEntry::Ptr findFile(const std::wstring &name) const;
- void insertFile(const std::wstring& filePath, FilesOrigin& origin, FILETIME fileTime);
+ /** search through this directory and all subdirectories for a file by the specified name (relative path).
+ if directory is not nullptr, the referenced variable will be set to the path containing the file */
+ const FileEntry::Ptr searchFile(const std::wstring &path, const DirectoryEntry **directory) const;
- void removeFile(FileEntry::Index index);
+ void insertFile(const std::wstring &filePath, FilesOrigin &origin, FILETIME fileTime);
- // remove the specified file from the tree. This can be a path leading to a file in a subdirectory
- bool removeFile(const std::wstring& filePath, int* origin = nullptr);
+ void removeFile(FileEntry::Index index);
- /**
- * @brief remove the specified directory
- * @param path directory to remove
- */
- void removeDir(const std::wstring& path);
+ // remove the specified file from the tree. This can be a path leading to a file in a subdirectory
+ bool removeFile(const std::wstring &filePath, int *origin = nullptr);
- bool remove(const std::wstring& fileName, int* origin) {
- auto iter = m_Files.find(ToLower(fileName));
- if (iter != m_Files.end()) {
- if (origin != nullptr) {
- FileEntry::Ptr entry = m_FileRegister->getFile(iter->second);
- if (entry.get() != nullptr) {
- bool ignore;
- *origin = entry->getOrigin(ignore);
- }
- }
- return m_FileRegister->removeFile(iter->second);
- } else {
- return false;
+ /**
+ * @brief remove the specified directory
+ * @param path directory to remove
+ */
+ void removeDir(const std::wstring &path);
+
+ bool remove(const std::wstring &fileName, int *origin) {
+ auto iter = m_Files.find(ToLower(fileName));
+ if (iter != m_Files.end()) {
+ if (origin != nullptr) {
+ FileEntry::Ptr entry = m_FileRegister->getFile(iter->second);
+ if (entry.get() != nullptr) {
+ bool ignore;
+ *origin = entry->getOrigin(ignore);
}
+ }
+ return m_FileRegister->removeFile(iter->second);
+ } else {
+ return false;
}
+ }
- bool hasContentsFromOrigin(int originID) const;
+ bool hasContentsFromOrigin(int originID) const;
- FilesOrigin& createOrigin(const std::wstring& originName, const std::wstring& directory, int priority);
+ FilesOrigin &createOrigin(const std::wstring &originName, const std::wstring &directory, int priority);
- void removeFiles(const std::set<FileEntry::Index>& indices);
+ void removeFiles(const std::set<FileEntry::Index> &indices);
private:
- DirectoryEntry(const DirectoryEntry& reference);
- DirectoryEntry& operator=(const DirectoryEntry& reference);
- void insert(const std::wstring& fileName, FilesOrigin& origin, FILETIME fileTime, const std::wstring& archive) {
- std::wstring fileNameLower = ToLower(fileName);
- auto iter = m_Files.find(fileNameLower);
- FileEntry::Ptr file;
- if (iter != m_Files.end()) {
- file = m_FileRegister->getFile(iter->second);
- } else {
- file = m_FileRegister->createFile(fileName, this);
- // TODO this has been observed to cause a crash, no clue why
- m_Files[fileNameLower] = file->getIndex();
- }
- file->addOrigin(origin.getID(), fileTime, archive);
- origin.addFile(file->getIndex());
+ DirectoryEntry(const DirectoryEntry &reference);
+ DirectoryEntry &operator=(const DirectoryEntry &reference);
+
+ void insert(const std::wstring &fileName, FilesOrigin &origin, FILETIME fileTime, const std::wstring &archive) {
+ std::wstring fileNameLower = ToLower(fileName);
+ auto iter = m_Files.find(fileNameLower);
+ FileEntry::Ptr file;
+ if (iter != m_Files.end()) {
+ file = m_FileRegister->getFile(iter->second);
+ } else {
+ file = m_FileRegister->createFile(fileName, this);
+ // TODO this has been observed to cause a crash, no clue why
+ m_Files[fileNameLower] = file->getIndex();
}
+ file->addOrigin(origin.getID(), fileTime, archive);
+ origin.addFile(file->getIndex());
+ }
- void addFiles(FilesOrigin& origin, wchar_t* buffer, int bufferOffset);
- void addFiles(FilesOrigin& origin, BSA::Folder::Ptr archiveFolder, FILETIME& fileTime,
- const std::wstring& archiveName);
+ void addFiles(FilesOrigin &origin, wchar_t *buffer, int bufferOffset);
+ void addFiles(FilesOrigin &origin, BSA::Folder::Ptr archiveFolder, FILETIME &fileTime, const std::wstring &archiveName);
- DirectoryEntry* getSubDirectory(const std::wstring& name, bool create, int originID = -1);
+ DirectoryEntry *getSubDirectory(const std::wstring &name, bool create, int originID = -1);
- DirectoryEntry* getSubDirectoryRecursive(const std::wstring& path, bool create, int originID = -1);
+ DirectoryEntry *getSubDirectoryRecursive(const std::wstring &path, bool create, int originID = -1);
- void removeDirRecursive();
+ void removeDirRecursive();
private:
- boost::shared_ptr<FileRegister> m_FileRegister;
- boost::shared_ptr<OriginConnection> m_OriginConnection;
- std::wstring m_Name;
- std::map<std::wstring, FileEntry::Index> m_Files;
- std::vector<DirectoryEntry*> m_SubDirectories;
+ boost::shared_ptr<FileRegister> m_FileRegister;
+ boost::shared_ptr<OriginConnection> m_OriginConnection;
+
+ std::wstring m_Name;
+ std::map<std::wstring, FileEntry::Index> m_Files;
+ std::vector<DirectoryEntry*> m_SubDirectories;
- DirectoryEntry* m_Parent;
- std::set<int> m_Origins;
+ DirectoryEntry *m_Parent;
+ std::set<int> m_Origins;
- bool m_Populated;
+ bool m_Populated;
+
+ bool m_TopLevel;
- bool m_TopLevel;
};
+
} // namespace MOShared
#endif // DIRECTORYENTRY_H
diff --git a/src/shared/error_report.cpp b/src/shared/error_report.cpp
index fffd77b9..6d091630 100644
--- a/src/shared/error_report.cpp
+++ b/src/shared/error_report.cpp
@@ -23,71 +23,77 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
namespace MOShared {
-void reportError(LPCSTR format, ...) {
- char buffer[1025];
- memset(buffer, 0, sizeof(char) * 1025);
- va_list argList;
- va_start(argList, format);
+void reportError(LPCSTR format, ...)
+{
+ char buffer[1025];
+ memset(buffer, 0, sizeof(char) * 1025);
- vsnprintf(buffer, 1024, format, argList);
- va_end(argList);
+ va_list argList;
+ va_start(argList, format);
- MessageBoxA(nullptr, buffer, "Error", MB_OK | MB_ICONERROR);
+ vsnprintf(buffer, 1024, format, argList);
+ va_end(argList);
+
+ MessageBoxA(nullptr, buffer, "Error", MB_OK | MB_ICONERROR);
}
-void reportError(LPCWSTR format, ...) {
- WCHAR buffer[1025];
- memset(buffer, 0, sizeof(WCHAR) * 1025);
+void reportError(LPCWSTR format, ...)
+{
+ WCHAR buffer[1025];
+ memset(buffer, 0, sizeof(WCHAR) * 1025);
- va_list argList;
- va_start(argList, format);
+ va_list argList;
+ va_start(argList, format);
- _vsnwprintf_s(buffer, 1024, format, argList);
- va_end(argList);
+ _vsnwprintf_s(buffer, 1024, format, argList);
+ va_end(argList);
- MessageBoxW(nullptr, buffer, L"Error", MB_OK | MB_ICONERROR);
+ MessageBoxW(nullptr, buffer, L"Error", MB_OK | MB_ICONERROR);
}
-std::string getCurrentErrorStringA() {
- LPSTR buffer = nullptr;
- DWORD errorCode = ::GetLastError();
+std::string getCurrentErrorStringA()
+{
+ LPSTR buffer = nullptr;
+
+ DWORD errorCode = ::GetLastError();
- if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, nullptr, errorCode,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buffer, 0, nullptr) == 0) {
- ::SetLastError(errorCode);
- return std::string();
- } else {
- LPSTR lastChar = buffer + strlen(buffer) - 2;
- *lastChar = '\0';
+ if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ nullptr, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buffer, 0, nullptr) == 0) {
+ ::SetLastError(errorCode);
+ return std::string();
+ } else {
+ LPSTR lastChar = buffer + strlen(buffer) - 2;
+ *lastChar = '\0';
- std::string result(buffer);
+ std::string result(buffer);
- LocalFree(buffer);
- ::SetLastError(errorCode);
- return result;
- }
+ LocalFree(buffer);
+ ::SetLastError(errorCode);
+ return result;
+ }
}
-std::wstring getCurrentErrorStringW() {
- LPWSTR buffer = nullptr;
+std::wstring getCurrentErrorStringW()
+{
+ LPWSTR buffer = nullptr;
- DWORD errorCode = ::GetLastError();
+ DWORD errorCode = ::GetLastError();
- if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, nullptr, errorCode,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&buffer, 0, nullptr) == 0) {
- ::SetLastError(errorCode);
- return std::wstring();
- } else {
- LPWSTR lastChar = buffer + wcslen(buffer) - 2;
- *lastChar = '\0';
+ if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ nullptr, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&buffer, 0, nullptr) == 0) {
+ ::SetLastError(errorCode);
+ return std::wstring();
+ } else {
+ LPWSTR lastChar = buffer + wcslen(buffer) - 2;
+ *lastChar = '\0';
- std::wstring result(buffer);
+ std::wstring result(buffer);
- LocalFree(buffer);
- ::SetLastError(errorCode);
- return result;
- }
+ LocalFree(buffer);
+ ::SetLastError(errorCode);
+ return result;
+ }
}
} // namespace MOShared
diff --git a/src/shared/leaktrace.cpp b/src/shared/leaktrace.cpp
index dd85c4b4..1ff1fa9d 100644
--- a/src/shared/leaktrace.cpp
+++ b/src/shared/leaktrace.cpp
@@ -1,47 +1,57 @@
#include "leaktrace.h"
#include "stackdata.h"
-#include <DbgHelp.h>
#include <Windows.h>
-#include <algorithm>
-#include <map>
+#include <DbgHelp.h>
#include <set>
-#include <sstream>
+#include <map>
#include <vector>
+#include <sstream>
+#include <algorithm>
+
using namespace MOShared;
+
static struct __TraceData {
- void regTrace(void* pointer, const char* functionName, int line) {
- m_Traces[reinterpret_cast<unsigned long>(pointer)] = StackData(functionName, line);
- }
- void deregTrace(void* pointer) {
- auto iter = m_Traces.find(reinterpret_cast<unsigned long>(pointer));
- if (iter != m_Traces.end()) {
- m_Traces.erase(iter);
- }
+ void regTrace(void *pointer, const char *functionName, int line) {
+ m_Traces[reinterpret_cast<unsigned long>(pointer)] = StackData(functionName, line);
+ }
+ void deregTrace(void *pointer) {
+ auto iter = m_Traces.find(reinterpret_cast<unsigned long>(pointer));
+ if (iter != m_Traces.end()) {
+ m_Traces.erase(iter);
}
+ }
- ~__TraceData() {
- std::map<StackData, std::vector<unsigned long>> result;
- for (auto iter = m_Traces.begin(); iter != m_Traces.end(); ++iter) {
- result[iter->second].push_back(iter->first);
- }
- for (auto iter = result.begin(); iter != result.end(); ++iter) {
- printf("-----------------------------------\n"
- "%d objects not freed, allocated at:\n%s",
- iter->second.size(), iter->first.toString().c_str());
- printf("Addresses: ");
- for (int i = 0; i < (std::min<int>)(5, static_cast<int>(iter->second.size())); ++i) {
- printf("%p, ", reinterpret_cast<void*>(iter->second[i]));
- }
- printf("\n");
- }
+ ~__TraceData() {
+ std::map<StackData, std::vector<unsigned long> > result;
+ for (auto iter = m_Traces.begin(); iter != m_Traces.end(); ++iter) {
+ result[iter->second].push_back(iter->first);
+ }
+ for (auto iter = result.begin(); iter != result.end(); ++iter) {
+ printf("-----------------------------------\n"
+ "%d objects not freed, allocated at:\n%s",
+ iter->second.size(), iter->first.toString().c_str());
+ printf("Addresses: ");
+ for (int i = 0;
+ i < (std::min<int>)(5, static_cast<int>(iter->second.size())); ++i) {
+ printf("%p, ", reinterpret_cast<void *>(iter->second[i]));
+ }
+ printf("\n");
}
+ }
- std::map<unsigned long, StackData> m_Traces;
+ std::map<unsigned long, StackData> m_Traces;
} __trace;
-void LeakTrace::TraceAlloc(void* ptr, const char* functionName, int line) { __trace.regTrace(ptr, functionName, line); }
-void LeakTrace::TraceDealloc(void* ptr) { __trace.deregTrace(ptr); }
+void LeakTrace::TraceAlloc(void *ptr, const char *functionName, int line)
+{
+ __trace.regTrace(ptr, functionName, line);
+}
+
+void LeakTrace::TraceDealloc(void *ptr)
+{
+ __trace.deregTrace(ptr);
+}
diff --git a/src/shared/leaktrace.h b/src/shared/leaktrace.h
index b0d04129..4985925e 100644
--- a/src/shared/leaktrace.h
+++ b/src/shared/leaktrace.h
@@ -1,12 +1,13 @@
#ifndef LEAKTRACE_H
#define LEAKTRACE_H
+
namespace LeakTrace {
-void TraceAlloc(void* ptr, const char* functionName, int line);
-void TraceDealloc(void* ptr);
+void TraceAlloc(void *ptr, const char *functionName, int line);
+void TraceDealloc(void *ptr);
-}; // namespace LeakTrace
+};
#ifdef TRACE_LEAKS
diff --git a/src/shared/stackdata.cpp b/src/shared/stackdata.cpp
index 5f77bbfa..b336593a 100644
--- a/src/shared/stackdata.cpp
+++ b/src/shared/stackdata.cpp
@@ -1,150 +1,169 @@
#include "stackdata.h"
-#include "error_report.h"
#include "util.h"
#include <DbgHelp.h>
+#include <sstream>
#include <TlHelp32.h>
-#include <boost/predef.h>
#include <set>
-#include <sstream>
+#include "error_report.h"
+#include <boost/predef.h>
+
using namespace MOShared;
#if defined _MSC_VER
-static void initDbgIfNecess() {
- HANDLE process = ::GetCurrentProcess();
- static std::set<DWORD> initialized;
- if (initialized.find(::GetCurrentProcessId()) == initialized.end()) {
- static bool firstCall = true;
- if (firstCall) {
- ::SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
- firstCall = false;
- }
- if (!::SymInitialize(process, NULL, TRUE)) {
- printf("failed to initialize symbols: %lu", ::GetLastError());
- }
- initialized.insert(::GetCurrentProcessId());
+static void initDbgIfNecess()
+{
+ HANDLE process = ::GetCurrentProcess();
+ static std::set<DWORD> initialized;
+ if (initialized.find(::GetCurrentProcessId()) == initialized.end()) {
+ static bool firstCall = true;
+ if (firstCall) {
+ ::SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
+ firstCall = false;
}
+ if (!::SymInitialize(process, NULL, TRUE)) {
+ printf("failed to initialize symbols: %lu", ::GetLastError());
+ }
+ initialized.insert(::GetCurrentProcessId());
+ }
+}
+
+
+
+StackData::StackData()
+ : m_Count(0)
+ , m_Function()
+ , m_Line(-1)
+{
+ initTrace();
}
-StackData::StackData() : m_Count(0), m_Function(), m_Line(-1) { initTrace(); }
+StackData::StackData(const char *function, int line)
+ : m_Count(0)
+ , m_Function(function)
+ , m_Line(line)
+{
-StackData::StackData(const char* function, int line) : m_Count(0), m_Function(function), m_Line(line) {}
+}
std::string StackData::toString() const {
- initDbgIfNecess();
+ initDbgIfNecess();
- char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
- PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
- symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
- symbol->MaxNameLen = MAX_SYM_NAME;
+ char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
+ PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
+ symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
+ symbol->MaxNameLen = MAX_SYM_NAME;
- std::ostringstream stackStream;
+ std::ostringstream stackStream;
- if (m_Function.length() > 0) {
- stackStream << "[" << m_Function << ":" << m_Line << "]\n";
- }
+ if (m_Function.length() > 0) {
+ stackStream << "[" << m_Function << ":" << m_Line << "]\n";
+ }
- for (unsigned int i = 0; i < m_Count; ++i) {
- DWORD64 displacement = 0;
- if (!::SymFromAddr(::GetCurrentProcess(), (DWORD64)m_Stack[i], &displacement, symbol)) {
- stackStream << m_Count - i - 1 << ": [" << m_Stack[i] << "]\n";
- } else {
- stackStream << m_Count - i - 1 << ": " << symbol->Name << "\n";
- }
+ for(unsigned int i = 0; i < m_Count; ++i) {
+ DWORD64 displacement = 0;
+ if (!::SymFromAddr(::GetCurrentProcess(), (DWORD64)m_Stack[i], &displacement, symbol)) {
+ stackStream << m_Count - i - 1 << ": [" << m_Stack[i] << "]\n";
+ } else {
+ stackStream << m_Count - i - 1 << ": " << symbol->Name << "\n";
}
- return stackStream.str();
+ }
+ return stackStream.str();
}
void StackData::load_modules(HANDLE process, DWORD processID) {
- HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, processID);
- if (snap == INVALID_HANDLE_VALUE)
- return;
+ HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, processID);
+ if (snap == INVALID_HANDLE_VALUE)
+ return;
- MODULEENTRY32 entry;
- entry.dwSize = sizeof(entry);
+ MODULEENTRY32 entry;
+ entry.dwSize = sizeof(entry);
- if (Module32First(snap, &entry)) {
- do {
- std::string fileName = ToString(entry.szExePath, false);
- std::string moduleName = ToString(entry.szModule, false);
- SymLoadModule64(process, NULL, fileName.c_str(), moduleName.c_str(), (DWORD64)entry.modBaseAddr,
- entry.modBaseSize);
- } while (Module32Next(snap, &entry));
- }
- CloseHandle(snap);
+ if (Module32First(snap, &entry)) {
+ do {
+ std::string fileName = ToString(entry.szExePath, false);
+ std::string moduleName = ToString(entry.szModule, false);
+ SymLoadModule64(process, NULL, fileName.c_str(), moduleName.c_str(), (DWORD64) entry.modBaseAddr, entry.modBaseSize);
+ } while (Module32Next(snap, &entry));
+ }
+ CloseHandle(snap);
}
-#pragma warning(disable : 4748)
+#pragma warning( disable : 4748 )
void StackData::initTrace() {
#ifdef _X86_
- load_modules(::GetCurrentProcess(), ::GetCurrentProcessId());
- CONTEXT context;
- std::memset(&context, 0, sizeof(CONTEXT));
- context.ContextFlags = CONTEXT_CONTROL;
- // Why only for 64 bit?
+ load_modules(::GetCurrentProcess(), ::GetCurrentProcessId());
+ CONTEXT context;
+ std::memset(&context, 0, sizeof(CONTEXT));
+ context.ContextFlags = CONTEXT_CONTROL;
+ //Why only for 64 bit?
#if BOOST_ARCH_X86_64 || defined(__clang__)
- ::RtlCaptureContext(&context);
+ ::RtlCaptureContext(&context);
#else
- __asm {
+ __asm
+ {
Label:
mov [context.Ebp], ebp;
mov [context.Esp], esp;
mov eax, [Label];
mov [context.Eip], eax;
- }
+ }
#endif
- STACKFRAME64 stackFrame;
- ::ZeroMemory(&stackFrame, sizeof(STACKFRAME64));
- stackFrame.AddrPC.Offset = context.Eip;
- stackFrame.AddrPC.Mode = AddrModeFlat;
- stackFrame.AddrFrame.Offset = context.Ebp;
- stackFrame.AddrFrame.Mode = AddrModeFlat;
- stackFrame.AddrStack.Offset = context.Esp;
- stackFrame.AddrStack.Mode = AddrModeFlat;
- m_Count = 0;
- while (m_Count < FRAMES_TO_CAPTURE) {
- if (!StackWalk64(IMAGE_FILE_MACHINE_I386, ::GetCurrentProcess(), ::GetCurrentThread(), &stackFrame, &context,
- NULL, &SymFunctionTableAccess64, &SymGetModuleBase64, NULL)) {
- break;
- }
-
- if (stackFrame.AddrPC.Offset == 0) {
- continue;
- break;
- }
+ STACKFRAME64 stackFrame;
+ ::ZeroMemory(&stackFrame, sizeof(STACKFRAME64));
+ stackFrame.AddrPC.Offset = context.Eip;
+ stackFrame.AddrPC.Mode = AddrModeFlat;
+ stackFrame.AddrFrame.Offset = context.Ebp;
+ stackFrame.AddrFrame.Mode = AddrModeFlat;
+ stackFrame.AddrStack.Offset = context.Esp;
+ stackFrame.AddrStack.Mode = AddrModeFlat;
+ m_Count = 0;
+ while (m_Count < FRAMES_TO_CAPTURE) {
+ if (!StackWalk64(IMAGE_FILE_MACHINE_I386, ::GetCurrentProcess(),
+ ::GetCurrentThread(), &stackFrame, &context, NULL,
+ &SymFunctionTableAccess64, &SymGetModuleBase64, NULL)) {
+ break;
+ }
- m_Stack[m_Count++] = reinterpret_cast<void*>(stackFrame.AddrPC.Offset);
+ if (stackFrame.AddrPC.Offset == 0) {
+ continue;
+ break;
}
+
+ m_Stack[m_Count++] = reinterpret_cast<void *>(stackFrame.AddrPC.Offset);
+ }
#endif
}
-bool MOShared::operator==(const StackData& LHS, const StackData& RHS) {
- if (LHS.m_Count != RHS.m_Count) {
+
+bool MOShared::operator==(const StackData &LHS, const StackData &RHS) {
+ if (LHS.m_Count != RHS.m_Count) {
+ return false;
+ } else {
+ for (int i = 0; i < LHS.m_Count; ++i) {
+ if (LHS.m_Stack[i] != RHS.m_Stack[i]) {
return false;
- } else {
- for (int i = 0; i < LHS.m_Count; ++i) {
- if (LHS.m_Stack[i] != RHS.m_Stack[i]) {
- return false;
- }
- }
+ }
}
- return true;
+ }
+ return true;
}
-bool MOShared::operator<(const StackData& LHS, const StackData& RHS) {
- if (LHS.m_Count != RHS.m_Count) {
- return LHS.m_Count < RHS.m_Count;
- } else {
- for (int i = 0; i < LHS.m_Count; ++i) {
- if (LHS.m_Stack[i] != RHS.m_Stack[i]) {
- return LHS.m_Stack[i] < RHS.m_Stack[i];
- }
- }
+
+bool MOShared::operator<(const StackData &LHS, const StackData &RHS) {
+ if (LHS.m_Count != RHS.m_Count) {
+ return LHS.m_Count < RHS.m_Count;
+ } else {
+ for (int i = 0; i < LHS.m_Count; ++i) {
+ if (LHS.m_Stack[i] != RHS.m_Stack[i]) {
+ return LHS.m_Stack[i] < RHS.m_Stack[i];
+ }
}
- return false;
+ }
+ return false;
}
#endif
diff --git a/src/shared/stackdata.h b/src/shared/stackdata.h
index 252b5ba4..7151699c 100644
--- a/src/shared/stackdata.h
+++ b/src/shared/stackdata.h
@@ -1,41 +1,50 @@
#ifndef STACKDATA_H
#define STACKDATA_H
-#include <Windows.h>
+
#include <string>
+#include <Windows.h>
+
namespace MOShared {
-class StackData {
- friend bool operator==(const StackData& LHS, const StackData& RHS);
- friend bool operator<(const StackData& LHS, const StackData& RHS);
+class StackData {
+ friend bool operator==(const StackData &LHS, const StackData &RHS);
+ friend bool operator<(const StackData &LHS, const StackData &RHS);
public:
- StackData();
- StackData(const char* function, int line);
- std::string toString() const;
+ StackData();
+ StackData(const char *function, int line);
+
+ std::string toString() const;
private:
- void load_modules(HANDLE process, DWORD processID);
- void initTrace();
+ void load_modules(HANDLE process, DWORD processID);
+
+ void initTrace();
private:
- static const int FRAMES_TO_SKIP = 1;
- static const int FRAMES_TO_CAPTURE = 20;
+
+ static const int FRAMES_TO_SKIP = 1;
+ static const int FRAMES_TO_CAPTURE = 20;
private:
- LPVOID m_Stack[FRAMES_TO_CAPTURE];
- USHORT m_Count;
- std::string m_Function;
- int m_Line;
+
+ LPVOID m_Stack[FRAMES_TO_CAPTURE];
+ USHORT m_Count;
+ std::string m_Function;
+ int m_Line;
+
};
-bool operator==(const StackData& LHS, const StackData& RHS);
-bool operator<(const StackData& LHS, const StackData& RHS);
+bool operator==(const StackData &LHS, const StackData &RHS);
+
+bool operator<(const StackData &LHS, const StackData &RHS);
} // namespace MOShared
+
#endif // STACKDATA_H
diff --git a/src/shared/util.cpp b/src/shared/util.cpp
index 0243bb88..5491a9e6 100644
--- a/src/shared/util.cpp
+++ b/src/shared/util.cpp
@@ -18,136 +18,161 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "util.h"
-#include "error_report.h"
#include "windows_error.h"
+#include "error_report.h"
-#include <DbgHelp.h>
-#include <algorithm>
-#include <boost/scoped_array.hpp>
+#include <sstream>
#include <locale>
+#include <algorithm>
+#include <DbgHelp.h>
#include <set>
-#include <sstream>
+#include <boost/scoped_array.hpp>
namespace MOShared {
-bool FileExists(const std::string& filename) {
- DWORD dwAttrib = ::GetFileAttributesA(filename.c_str());
- return (dwAttrib != INVALID_FILE_ATTRIBUTES);
+bool FileExists(const std::string &filename)
+{
+ DWORD dwAttrib = ::GetFileAttributesA(filename.c_str());
+
+ return (dwAttrib != INVALID_FILE_ATTRIBUTES);
}
-bool FileExists(const std::wstring& filename) {
- DWORD dwAttrib = ::GetFileAttributesW(filename.c_str());
+bool FileExists(const std::wstring &filename)
+{
+ DWORD dwAttrib = ::GetFileAttributesW(filename.c_str());
- return (dwAttrib != INVALID_FILE_ATTRIBUTES);
+ return (dwAttrib != INVALID_FILE_ATTRIBUTES);
}
-bool FileExists(const std::wstring& searchPath, const std::wstring& filename) {
- std::wstringstream stream;
- stream << searchPath << "\\" << filename;
- return FileExists(stream.str());
+bool FileExists(const std::wstring &searchPath, const std::wstring &filename)
+{
+ std::wstringstream stream;
+ stream << searchPath << "\\" << filename;
+ return FileExists(stream.str());
}
-std::string ToString(const std::wstring& source, bool utf8) {
- std::string result;
- if (source.length() > 0) {
- UINT codepage = CP_UTF8;
- if (!utf8) {
- codepage = AreFileApisANSI() ? GetACP() : GetOEMCP();
- }
- int sizeRequired = ::WideCharToMultiByte(codepage, 0, &source[0], -1, nullptr, 0, nullptr, nullptr);
- if (sizeRequired == 0) {
- throw windows_error("failed to convert string to multibyte");
- }
- // the size returned by WideCharToMultiByte contains zero termination IF -1 is specified for the length.
- // we don't want that \0 in the string because then the length field would be wrong. Because madness
- result.resize(sizeRequired - 1, '\0');
- ::WideCharToMultiByte(codepage, 0, &source[0], (int)source.size(), &result[0], sizeRequired, nullptr, nullptr);
+std::string ToString(const std::wstring &source, bool utf8)
+{
+ std::string result;
+ if (source.length() > 0) {
+ UINT codepage = CP_UTF8;
+ if (!utf8) {
+ codepage = AreFileApisANSI() ? GetACP() : GetOEMCP();
+ }
+ int sizeRequired = ::WideCharToMultiByte(codepage, 0, &source[0], -1, nullptr, 0, nullptr, nullptr);
+ if (sizeRequired == 0) {
+ throw windows_error("failed to convert string to multibyte");
}
+ // the size returned by WideCharToMultiByte contains zero termination IF -1 is specified for the length.
+ // we don't want that \0 in the string because then the length field would be wrong. Because madness
+ result.resize(sizeRequired - 1, '\0');
+ ::WideCharToMultiByte(codepage, 0, &source[0], (int)source.size(), &result[0], sizeRequired, nullptr, nullptr);
+ }
- return result;
+ return result;
}
-std::wstring ToWString(const std::string& source, bool utf8) {
- std::wstring result;
- if (source.length() > 0) {
- UINT codepage = CP_UTF8;
- if (!utf8) {
- codepage = AreFileApisANSI() ? GetACP() : GetOEMCP();
- }
- int sizeRequired =
- ::MultiByteToWideChar(codepage, 0, source.c_str(), static_cast<int>(source.length()), nullptr, 0);
- if (sizeRequired == 0) {
- throw windows_error("failed to convert string to wide character");
- }
- result.resize(sizeRequired, L'\0');
- ::MultiByteToWideChar(codepage, 0, source.c_str(), static_cast<int>(source.length()), &result[0], sizeRequired);
+std::wstring ToWString(const std::string &source, bool utf8)
+{
+ std::wstring result;
+ if (source.length() > 0) {
+ UINT codepage = CP_UTF8;
+ if (!utf8) {
+ codepage = AreFileApisANSI() ? GetACP() : GetOEMCP();
+ }
+ int sizeRequired
+ = ::MultiByteToWideChar(codepage, 0, source.c_str(),
+ static_cast<int>(source.length()), nullptr, 0);
+ if (sizeRequired == 0) {
+ throw windows_error("failed to convert string to wide character");
}
+ result.resize(sizeRequired, L'\0');
+ ::MultiByteToWideChar(codepage, 0, source.c_str(),
+ static_cast<int>(source.length()), &result[0],
+ sizeRequired);
+ }
- return result;
+ return result;
}
static std::locale loc("");
-static auto locToLowerW = [](wchar_t in) -> wchar_t { return std::tolower(in, loc); };
+static auto locToLowerW = [] (wchar_t in) -> wchar_t {
+ return std::tolower(in, loc);
+};
-static auto locToLower = [](char in) -> char { return std::tolower(in, loc); };
+static auto locToLower = [] (char in) -> char {
+ return std::tolower(in, loc);
+};
-std::string& ToLower(std::string& text) {
- std::transform(text.begin(), text.end(), text.begin(), locToLower);
- return text;
+std::string &ToLower(std::string &text)
+{
+ std::transform(text.begin(), text.end(), text.begin(), locToLower);
+ return text;
}
-std::string ToLower(const std::string& text) {
- std::string result(text);
- std::transform(result.begin(), result.end(), result.begin(), locToLower);
- return result;
+std::string ToLower(const std::string &text)
+{
+ std::string result(text);
+ std::transform(result.begin(), result.end(), result.begin(), locToLower);
+ return result;
}
-std::wstring& ToLower(std::wstring& text) {
- std::transform(text.begin(), text.end(), text.begin(), locToLowerW);
- return text;
+std::wstring &ToLower(std::wstring &text)
+{
+ std::transform(text.begin(), text.end(), text.begin(), locToLowerW);
+ return text;
}
-std::wstring ToLower(const std::wstring& text) {
- std::wstring result(text);
- std::transform(result.begin(), result.end(), result.begin(), locToLowerW);
- return result;
+std::wstring ToLower(const std::wstring &text)
+{
+ std::wstring result(text);
+ std::transform(result.begin(), result.end(), result.begin(), locToLowerW);
+ return result;
}
-bool CaseInsenstiveComparePred(wchar_t lhs, wchar_t rhs) { return std::tolower(lhs, loc) == std::tolower(rhs, loc); }
-
-bool CaseInsensitiveEqual(const std::wstring& lhs, const std::wstring& rhs) {
- return (lhs.length() == rhs.length()) &&
- std::equal(lhs.begin(), lhs.end(), rhs.begin(), [](wchar_t lhs, wchar_t rhs) -> bool {
- return std::tolower(lhs, loc) == std::tolower(rhs, loc);
- });
+bool CaseInsenstiveComparePred(wchar_t lhs, wchar_t rhs)
+{
+ return std::tolower(lhs, loc) == std::tolower(rhs, loc);
}
-VS_FIXEDFILEINFO GetFileVersion(const std::wstring& fileName) {
- DWORD handle = 0UL;
- DWORD size = ::GetFileVersionInfoSizeW(fileName.c_str(), &handle);
- if (size == 0) {
- throw windows_error("failed to determine file version info size");
- }
+bool CaseInsensitiveEqual(const std::wstring &lhs, const std::wstring &rhs)
+{
+ return (lhs.length() == rhs.length())
+ && std::equal(lhs.begin(), lhs.end(),
+ rhs.begin(),
+ [] (wchar_t lhs, wchar_t rhs) -> bool {
+ return std::tolower(lhs, loc) == std::tolower(rhs, loc);
+ });
+}
- boost::scoped_array<char> buffer(new char[size]);
- try {
- handle = 0UL;
- if (!::GetFileVersionInfoW(fileName.c_str(), handle, size, buffer.get())) {
- throw windows_error("failed to determine file version info");
- }
+VS_FIXEDFILEINFO GetFileVersion(const std::wstring &fileName)
+{
+ DWORD handle = 0UL;
+ DWORD size = ::GetFileVersionInfoSizeW(fileName.c_str(), &handle);
+ if (size == 0) {
+ throw windows_error("failed to determine file version info size");
+ }
- void* versionInfoPtr = nullptr;
- UINT versionInfoLength = 0;
- if (!::VerQueryValue(buffer.get(), L"\\", &versionInfoPtr, &versionInfoLength)) {
- throw windows_error("failed to determine file version");
- }
+ boost::scoped_array<char> buffer(new char[size]);
+ try {
+ handle = 0UL;
+ if (!::GetFileVersionInfoW(fileName.c_str(), handle, size, buffer.get())) {
+ throw windows_error("failed to determine file version info");
+ }
- VS_FIXEDFILEINFO result = *(VS_FIXEDFILEINFO*)versionInfoPtr;
- return result;
- } catch (...) {
- throw;
+ void *versionInfoPtr = nullptr;
+ UINT versionInfoLength = 0;
+ if (!::VerQueryValue(buffer.get(), L"\\", &versionInfoPtr, &versionInfoLength)) {
+ throw windows_error("failed to determine file version");
}
+
+ VS_FIXEDFILEINFO result = *(VS_FIXEDFILEINFO*)versionInfoPtr;
+ return result;
+ } catch (...) {
+ throw;
+ }
}
+
} // namespace MOShared
diff --git a/src/shared/util.h b/src/shared/util.h
index 4b390cf3..1e498059 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -20,6 +20,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef UTIL_H
#define UTIL_H
+
#include <string>
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
@@ -27,23 +28,23 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
namespace MOShared {
/// Test if a file (or directory) by the specified name exists
-bool FileExists(const std::string& filename);
-bool FileExists(const std::wstring& filename);
+bool FileExists(const std::string &filename);
+bool FileExists(const std::wstring &filename);
-bool FileExists(const std::wstring& searchPath, const std::wstring& filename);
+bool FileExists(const std::wstring &searchPath, const std::wstring &filename);
-std::string ToString(const std::wstring& source, bool utf8);
-std::wstring ToWString(const std::string& source, bool utf8);
+std::string ToString(const std::wstring &source, bool utf8);
+std::wstring ToWString(const std::string &source, bool utf8);
-std::string& ToLower(std::string& text);
-std::string ToLower(const std::string& text);
+std::string &ToLower(std::string &text);
+std::string ToLower(const std::string &text);
-std::wstring& ToLower(std::wstring& text);
-std::wstring ToLower(const std::wstring& text);
+std::wstring &ToLower(std::wstring &text);
+std::wstring ToLower(const std::wstring &text);
-bool CaseInsensitiveEqual(const std::wstring& lhs, const std::wstring& rhs);
+bool CaseInsensitiveEqual(const std::wstring &lhs, const std::wstring &rhs);
-VS_FIXEDFILEINFO GetFileVersion(const std::wstring& fileName);
+VS_FIXEDFILEINFO GetFileVersion(const std::wstring &fileName);
} // namespace MOShared
diff --git a/src/shared/windows_error.cpp b/src/shared/windows_error.cpp
index ab5c7b8e..97a58a20 100644
--- a/src/shared/windows_error.cpp
+++ b/src/shared/windows_error.cpp
@@ -22,27 +22,28 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
namespace MOShared {
-std::string windows_error::constructMessage(const std::string& input, int inErrorCode) {
- std::ostringstream finalMessage;
- finalMessage << input;
+std::string windows_error::constructMessage(const std::string& input, int inErrorCode)
+{
+ std::ostringstream finalMessage;
+ finalMessage << input;
- LPSTR buffer = nullptr;
+ LPSTR buffer = nullptr;
- DWORD errorCode = inErrorCode != -1 ? inErrorCode : ::GetLastError();
+ DWORD errorCode = inErrorCode != -1 ? inErrorCode : ::GetLastError();
- // TODO: the message is not english?
- if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, nullptr, errorCode,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buffer, 0, nullptr) == 0) {
- finalMessage << " (errorcode " << errorCode << ")";
- } else {
- LPSTR lastChar = buffer + strlen(buffer) - 2;
- *lastChar = '\0';
- finalMessage << " (" << buffer << " [" << errorCode << "])";
- LocalFree(buffer); // allocated by FormatMessage
- }
+ // TODO: the message is not english?
+ if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ nullptr, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buffer, 0, nullptr) == 0) {
+ finalMessage << " (errorcode " << errorCode << ")";
+ } else {
+ LPSTR lastChar = buffer + strlen(buffer) - 2;
+ *lastChar = '\0';
+ finalMessage << " (" << buffer << " [" << errorCode << "])";
+ LocalFree(buffer); // allocated by FormatMessage
+ }
- ::SetLastError(errorCode); // restore error code because FormatMessage might have modified it
- return finalMessage.str();
+ ::SetLastError(errorCode); // restore error code because FormatMessage might have modified it
+ return finalMessage.str();
}
} // namespace MOShared
diff --git a/src/shared/windows_error.h b/src/shared/windows_error.h
index 66c512f6..03ce0abd 100644
--- a/src/shared/windows_error.h
+++ b/src/shared/windows_error.h
@@ -20,6 +20,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef WINDOWS_ERROR_H
#define WINDOWS_ERROR_H
+
#include <stdexcept>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
@@ -28,15 +29,14 @@ namespace MOShared {
class windows_error : public std::runtime_error {
public:
- windows_error(const std::string& message, int errorcode = ::GetLastError())
- : runtime_error(constructMessage(message, errorcode)), m_ErrorCode(errorcode) {}
- int getErrorCode() const { return m_ErrorCode; }
-
+ windows_error(const std::string& message, int errorcode = ::GetLastError())
+ : runtime_error(constructMessage(message, errorcode)), m_ErrorCode(errorcode)
+ {}
+ int getErrorCode() const { return m_ErrorCode; }
private:
- std::string constructMessage(const std::string& input, int errorcode);
-
+ std::string constructMessage(const std::string& input, int errorcode);
private:
- int m_ErrorCode;
+ int m_ErrorCode;
};
} // namespace MOShared
diff --git a/src/singleinstance.cpp b/src/singleinstance.cpp
index b681317c..89332f9b 100644
--- a/src/singleinstance.cpp
+++ b/src/singleinstance.cpp
@@ -19,85 +19,92 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "singleinstance.h"
#include "utility.h"
-#include <QLocalSocket>
#include <report.h>
+#include <QLocalSocket>
static const char s_Key[] = "mo-43d1a3ad-eeb0-4818-97c9-eda5216c29b5";
static const int s_Timeout = 5000;
using MOBase::reportError;
-SingleInstance::SingleInstance(bool forcePrimary, QObject* parent) : QObject(parent), m_PrimaryInstance(false) {
- m_SharedMem.setKey(s_Key);
- if (!m_SharedMem.create(1)) {
- if (forcePrimary) {
- while (m_SharedMem.error() == QSharedMemory::AlreadyExists) {
- Sleep(500);
- if (m_SharedMem.create(1)) {
- m_PrimaryInstance = true;
- break;
- }
- }
+SingleInstance::SingleInstance(bool forcePrimary, QObject *parent) :
+ QObject(parent), m_PrimaryInstance(false)
+{
+ m_SharedMem.setKey(s_Key);
+ if (!m_SharedMem.create(1)) {
+ if (forcePrimary) {
+ while (m_SharedMem.error() == QSharedMemory::AlreadyExists) {
+ Sleep(500);
+ if (m_SharedMem.create(1)) {
+ m_PrimaryInstance = true;
+ break;
}
+ }
+ }
- if (m_SharedMem.error() == QSharedMemory::AlreadyExists) {
- m_SharedMem.attach();
- m_PrimaryInstance = false;
- }
- if ((m_SharedMem.error() != QSharedMemory::NoError) && (m_SharedMem.error() != QSharedMemory::AlreadyExists)) {
- throw MOBase::MyException(tr("SHM error: %1").arg(m_SharedMem.errorString()));
- }
- } else {
- m_PrimaryInstance = true;
+ if (m_SharedMem.error() == QSharedMemory::AlreadyExists) {
+ m_SharedMem.attach();
+ m_PrimaryInstance = false;
}
- if (m_PrimaryInstance) {
- connect(&m_Server, SIGNAL(newConnection()), this, SLOT(receiveMessage()));
- // has to be called before listen
- m_Server.setSocketOptions(QLocalServer::WorldAccessOption);
- m_Server.listen(s_Key);
+ if ((m_SharedMem.error() != QSharedMemory::NoError) &&
+ (m_SharedMem.error() != QSharedMemory::AlreadyExists)) {
+ throw MOBase::MyException(tr("SHM error: %1").arg(m_SharedMem.errorString()));
}
+ } else {
+ m_PrimaryInstance = true;
+ }
+ if (m_PrimaryInstance) {
+ connect(&m_Server, SIGNAL(newConnection()), this, SLOT(receiveMessage()));
+ // has to be called before listen
+ m_Server.setSocketOptions(QLocalServer::WorldAccessOption);
+ m_Server.listen(s_Key);
+ }
}
-void SingleInstance::sendMessage(const QString& message) {
- if (m_PrimaryInstance) {
- // nobody there to receive the message
- return;
- }
- QLocalSocket socket(this);
- bool connected = false;
- for (int i = 0; i < 2 && !connected; ++i) {
- if (i > 0) {
- Sleep(250);
- }
+void SingleInstance::sendMessage(const QString &message)
+{
+ if (m_PrimaryInstance) {
+ // nobody there to receive the message
+ return;
+ }
+ QLocalSocket socket(this);
- // other instance may be just starting up
- socket.connectToServer(s_Key, QIODevice::WriteOnly);
- connected = socket.waitForConnected(s_Timeout);
+ bool connected = false;
+ for(int i = 0; i < 2 && !connected; ++i) {
+ if (i > 0) {
+ Sleep(250);
}
- if (!connected) {
- reportError(tr("failed to connect to running instance: %1").arg(socket.errorString()));
- return;
- }
+ // other instance may be just starting up
+ socket.connectToServer(s_Key, QIODevice::WriteOnly);
+ connected = socket.waitForConnected(s_Timeout);
+ }
- socket.write(message.toUtf8());
- if (!socket.waitForBytesWritten(s_Timeout)) {
- reportError(tr("failed to communicate with running instance: %1").arg(socket.errorString()));
- return;
- }
+ if (!connected) {
+ reportError(tr("failed to connect to running instance: %1").arg(socket.errorString()));
+ return;
+ }
- socket.disconnectFromServer();
+ socket.write(message.toUtf8());
+ if (!socket.waitForBytesWritten(s_Timeout)) {
+ reportError(tr("failed to communicate with running instance: %1").arg(socket.errorString()));
+ return;
+ }
+
+ socket.disconnectFromServer();
}
-void SingleInstance::receiveMessage() {
- QLocalSocket* socket = m_Server.nextPendingConnection();
- if (!socket->waitForReadyRead(s_Timeout)) {
- reportError(tr("failed to receive data from secondary instance: %1").arg(socket->errorString()));
- return;
- }
- QString message = QString::fromUtf8(socket->readAll().constData());
- emit messageSent(message);
- socket->disconnectFromServer();
+void SingleInstance::receiveMessage()
+{
+ QLocalSocket *socket = m_Server.nextPendingConnection();
+ if (!socket->waitForReadyRead(s_Timeout)) {
+ reportError(tr("failed to receive data from secondary instance: %1").arg(socket->errorString()));
+ return;
+ }
+
+ QString message = QString::fromUtf8(socket->readAll().constData());
+ emit messageSent(message);
+ socket->disconnectFromServer();
}
diff --git a/src/singleinstance.h b/src/singleinstance.h
index 9011d93a..14d49d6d 100644
--- a/src/singleinstance.h
+++ b/src/singleinstance.h
@@ -20,64 +20,69 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef SINGLEINSTANCE_H
#define SINGLEINSTANCE_H
-#include <QLocalServer>
#include <QObject>
#include <QSharedMemory>
+#include <QLocalServer>
+
/**
* used to ensure only a single instance of Mod Organizer is started and to
* allow secondary instances to send messages to the primary (visible) one. This way,
* secondary instances can start a download in the primary one
**/
-class SingleInstance : public QObject {
+class SingleInstance : public QObject
+{
- Q_OBJECT
+ Q_OBJECT
public:
- /**
- * @brief constructor
- *
- * @param forcePrimary if true, this will be treated as the primary instance even
- * if another instance is running. This is used after an update since
- * the other instance is assumed to be in the process of quitting
- * @param parent parent object
- * @todo the forcePrimary parameter makes no sense. The second instance after an update
- * needs to delete the files from before the update so the first instance needs to quit
- * first anyway
- **/
- explicit SingleInstance(bool forcePrimary, QObject* parent = 0);
- /**
- * @return true if this is the primary instance (the one that gets to display a UI)
- **/
- bool primaryInstance() const { return m_PrimaryInstance; }
+ /**
+ * @brief constructor
+ *
+ * @param forcePrimary if true, this will be treated as the primary instance even
+ * if another instance is running. This is used after an update since
+ * the other instance is assumed to be in the process of quitting
+ * @param parent parent object
+ * @todo the forcePrimary parameter makes no sense. The second instance after an update
+ * needs to delete the files from before the update so the first instance needs to quit
+ * first anyway
+ **/
+ explicit SingleInstance(bool forcePrimary, QObject *parent = 0);
- /**
- * send a message to the primary instance. This can be used to transmit download urls
- *
- * @param message message to send
- **/
- void sendMessage(const QString& message);
+ /**
+ * @return true if this is the primary instance (the one that gets to display a UI)
+ **/
+ bool primaryInstance() const { return m_PrimaryInstance; }
+
+ /**
+ * send a message to the primary instance. This can be used to transmit download urls
+ *
+ * @param message message to send
+ **/
+ void sendMessage(const QString &message);
signals:
- /**
- * @brief emitted when a secondary instance has sent a message (to us)
- *
- * @param message the message we received
- **/
- void messageSent(const QString& message);
+ /**
+ * @brief emitted when a secondary instance has sent a message (to us)
+ *
+ * @param message the message we received
+ **/
+ void messageSent(const QString &message);
public slots:
private slots:
- void receiveMessage();
+ void receiveMessage();
private:
- bool m_PrimaryInstance;
- QSharedMemory m_SharedMem;
- QLocalServer m_Server;
+
+ bool m_PrimaryInstance;
+ QSharedMemory m_SharedMem;
+ QLocalServer m_Server;
+
};
#endif // SINGLEINSTANCE_H
diff --git a/src/spawn.cpp b/src/spawn.cpp
index f5b0bdb2..ac8ccf30 100644
--- a/src/spawn.cpp
+++ b/src/spawn.cpp
@@ -21,10 +21,10 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "report.h"
#include "utility.h"
-#include <Shellapi.h>
-#include <appconfig.h>
#include <report.h>
#include <usvfs.h>
+#include <Shellapi.h>
+#include <appconfig.h>
#include <windows_error.h>
#include <QApplication>
@@ -37,127 +37,137 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
using namespace MOBase;
using namespace MOShared;
+
static const int BUFSIZE = 4096;
-static bool spawn(LPCWSTR binary, LPCWSTR arguments, LPCWSTR currentDirectory, bool suspended, bool hooked,
- HANDLE stdOut, HANDLE stdErr, HANDLE& processHandle, HANDLE& threadHandle) {
- BOOL inheritHandles = FALSE;
- STARTUPINFO si;
- ::ZeroMemory(&si, sizeof(si));
- if (stdOut != INVALID_HANDLE_VALUE) {
- si.hStdOutput = stdOut;
- inheritHandles = TRUE;
- si.dwFlags |= STARTF_USESTDHANDLES;
- }
- if (stdErr != INVALID_HANDLE_VALUE) {
- si.hStdError = stdErr;
- inheritHandles = TRUE;
- si.dwFlags |= STARTF_USESTDHANDLES;
- }
- si.cb = sizeof(si);
- size_t length = wcslen(binary) + wcslen(arguments) + 4;
- wchar_t* commandLine = nullptr;
- if (arguments[0] != L'\0') {
- commandLine = new wchar_t[length];
- _snwprintf(commandLine, length, L"\"%ls\" %ls", binary, arguments);
- } else {
- commandLine = new wchar_t[length];
- _snwprintf_s(commandLine, length, _TRUNCATE, L"\"%ls\"", binary);
- }
+static bool spawn(LPCWSTR binary, LPCWSTR arguments, LPCWSTR currentDirectory,
+ bool suspended, bool hooked,
+ HANDLE stdOut, HANDLE stdErr,
+ HANDLE& processHandle, HANDLE& threadHandle)
+{
+ BOOL inheritHandles = FALSE;
+ STARTUPINFO si;
+ ::ZeroMemory(&si, sizeof(si));
+ if (stdOut != INVALID_HANDLE_VALUE) {
+ si.hStdOutput = stdOut;
+ inheritHandles = TRUE;
+ si.dwFlags |= STARTF_USESTDHANDLES;
+ }
+ if (stdErr != INVALID_HANDLE_VALUE) {
+ si.hStdError = stdErr;
+ inheritHandles = TRUE;
+ si.dwFlags |= STARTF_USESTDHANDLES;
+ }
+ si.cb = sizeof(si);
+ size_t length = wcslen(binary) + wcslen(arguments) + 4;
+ wchar_t *commandLine = nullptr;
+ if (arguments[0] != L'\0') {
+ commandLine = new wchar_t[length];
+ _snwprintf(commandLine, length, L"\"%ls\" %ls", binary, arguments);
+ } else {
+ commandLine = new wchar_t[length];
+ _snwprintf_s(commandLine, length, _TRUNCATE, L"\"%ls\"", binary);
+ }
- QString moPath = QCoreApplication::applicationDirPath();
+ QString moPath = QCoreApplication::applicationDirPath();
- boost::scoped_array<TCHAR> oldPath(new TCHAR[BUFSIZE]);
- DWORD offset = ::GetEnvironmentVariable(TEXT("PATH"), oldPath.get(), BUFSIZE);
- if (offset > BUFSIZE) {
- oldPath.reset(new TCHAR[offset]);
- ::GetEnvironmentVariable(TEXT("PATH"), oldPath.get(), offset);
- }
+ boost::scoped_array<TCHAR> oldPath(new TCHAR[BUFSIZE]);
+ DWORD offset = ::GetEnvironmentVariable(TEXT("PATH"), oldPath.get(), BUFSIZE);
+ if (offset > BUFSIZE) {
+ oldPath.reset(new TCHAR[offset]);
+ ::GetEnvironmentVariable(TEXT("PATH"), oldPath.get(), offset);
+ }
- {
- boost::scoped_array<TCHAR> newPath(new TCHAR[offset + moPath.length() + 2]);
- _tcsncpy(newPath.get(), oldPath.get(), offset);
- newPath.get()[offset] = '\0';
- _tcsncat(newPath.get(), TEXT(";"), 1);
- _tcsncat(newPath.get(), ToWString(QDir::toNativeSeparators(moPath)).c_str(), moPath.length());
+ {
+ boost::scoped_array<TCHAR> newPath(new TCHAR[offset + moPath.length() + 2]);
+ _tcsncpy(newPath.get(), oldPath.get(), offset);
+ newPath.get()[offset] = '\0';
+ _tcsncat(newPath.get(), TEXT(";"), 1);
+ _tcsncat(newPath.get(), ToWString(QDir::toNativeSeparators(moPath)).c_str(), moPath.length());
- ::SetEnvironmentVariable(TEXT("PATH"), newPath.get());
- }
+ ::SetEnvironmentVariable(TEXT("PATH"), newPath.get());
+ }
- PROCESS_INFORMATION pi;
- BOOL success = FALSE;
- if (hooked) {
- success =
- ::CreateProcessHooked(nullptr, commandLine, nullptr, nullptr, // no special process or thread attributes
- inheritHandles, // inherit handles if we plan to use stdout or stderr reroute
- CREATE_BREAKAWAY_FROM_JOB,
- nullptr, // same environment as parent
- currentDirectory, // current directory
- &si, &pi // startup and process information
- );
- } else {
- success = ::CreateProcess(nullptr, commandLine, nullptr, nullptr, // no special process or thread attributes
- inheritHandles, // inherit handles if we plan to use stdout or stderr reroute
- CREATE_BREAKAWAY_FROM_JOB,
- nullptr, // same environment as parent
- currentDirectory, // current directory
- &si, &pi // startup and process information
- );
- }
+ PROCESS_INFORMATION pi;
+ BOOL success = FALSE;
+ if (hooked) {
+ success = ::CreateProcessHooked(nullptr,
+ commandLine,
+ nullptr, nullptr, // no special process or thread attributes
+ inheritHandles, // inherit handles if we plan to use stdout or stderr reroute
+ CREATE_BREAKAWAY_FROM_JOB,
+ nullptr, // same environment as parent
+ currentDirectory, // current directory
+ &si, &pi // startup and process information
+ );
+ } else {
+ success = ::CreateProcess(nullptr,
+ commandLine,
+ nullptr, nullptr, // no special process or thread attributes
+ inheritHandles, // inherit handles if we plan to use stdout or stderr reroute
+ CREATE_BREAKAWAY_FROM_JOB,
+ nullptr, // same environment as parent
+ currentDirectory, // current directory
+ &si, &pi // startup and process information
+ );
+ }
- ::SetEnvironmentVariable(TEXT("PATH"), oldPath.get());
+ ::SetEnvironmentVariable(TEXT("PATH"), oldPath.get());
- delete[] commandLine;
+ delete [] commandLine;
- if (!success) {
- throw windows_error("failed to start process");
- }
+ if (!success) {
+ throw windows_error("failed to start process");
+ }
- processHandle = pi.hProcess;
- threadHandle = pi.hThread;
- return true;
+ processHandle = pi.hProcess;
+ threadHandle = pi.hThread;
+ return true;
}
-HANDLE startBinary(const QFileInfo& binary, const QString& arguments, const QDir& currentDirectory, bool hooked,
- HANDLE stdOut, HANDLE stdErr) {
- HANDLE processHandle, threadHandle;
- std::wstring binaryName = ToWString(QDir::toNativeSeparators(binary.absoluteFilePath()));
- std::wstring currentDirectoryName = ToWString(QDir::toNativeSeparators(currentDirectory.absolutePath()));
- try {
- if (!spawn(binaryName.c_str(), ToWString(arguments).c_str(), currentDirectoryName.c_str(), true, hooked, stdOut,
- stdErr, processHandle, threadHandle)) {
- reportError(QObject::tr("failed to spawn \"%1\"").arg(binary.fileName()));
- return INVALID_HANDLE_VALUE;
- }
- } catch (const windows_error& e) {
- if (e.getErrorCode() == ERROR_ELEVATION_REQUIRED) {
- // TODO: check if this is really correct. Are all settings updated that the secondary instance may use?
+HANDLE startBinary(const QFileInfo &binary,
+ const QString &arguments,
+ const QDir &currentDirectory,
+ bool hooked,
+ HANDLE stdOut,
+ HANDLE stdErr)
+{
+ HANDLE processHandle, threadHandle;
+ std::wstring binaryName = ToWString(QDir::toNativeSeparators(binary.absoluteFilePath()));
+ std::wstring currentDirectoryName = ToWString(QDir::toNativeSeparators(currentDirectory.absolutePath()));
+
+ try {
+ if (!spawn(binaryName.c_str(), ToWString(arguments).c_str(), currentDirectoryName.c_str(),
+ true, hooked, stdOut, stdErr, processHandle, threadHandle)) {
+ reportError(QObject::tr("failed to spawn \"%1\"").arg(binary.fileName()));
+ return INVALID_HANDLE_VALUE;
+ }
+ } catch (const windows_error &e) {
+ if (e.getErrorCode() == ERROR_ELEVATION_REQUIRED) {
+ // TODO: check if this is really correct. Are all settings updated that the secondary instance may use?
- if (QMessageBox::question(
- nullptr, QObject::tr("Elevation required"),
- QObject::tr(
- "This process requires elevation to run.\n"
- "This is a potential security risk so I highly advice you to investigate if\n"
- "\"%1\"\n"
- "can be installed to work without elevation.\n\n"
- "Start elevated anyway? "
- "(you will be asked if you want to allow ModOrganizer.exe to make changes to the system)")
- .arg(QDir::toNativeSeparators(binary.absoluteFilePath())),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- ::ShellExecuteW(nullptr, L"runas", ToWString(QCoreApplication::applicationFilePath()).c_str(),
- (std::wstring(L"\"") + binaryName + L"\" " + ToWString(arguments)).c_str(),
- currentDirectoryName.c_str(), SW_SHOWNORMAL);
- return INVALID_HANDLE_VALUE;
- } else {
- return INVALID_HANDLE_VALUE;
- }
- } else {
- reportError(QObject::tr("failed to spawn \"%1\": %2").arg(binary.fileName()).arg(e.what()));
- return INVALID_HANDLE_VALUE;
- }
+ if (QMessageBox::question(nullptr, QObject::tr("Elevation required"),
+ QObject::tr("This process requires elevation to run.\n"
+ "This is a potential security risk so I highly advice you to investigate if\n"
+ "\"%1\"\n"
+ "can be installed to work without elevation.\n\n"
+ "Start elevated anyway? "
+ "(you will be asked if you want to allow ModOrganizer.exe to make changes to the system)").arg(
+ QDir::toNativeSeparators(binary.absoluteFilePath())),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ ::ShellExecuteW(nullptr, L"runas", ToWString(QCoreApplication::applicationFilePath()).c_str(),
+ (std::wstring(L"\"") + binaryName + L"\" " + ToWString(arguments)).c_str(), currentDirectoryName.c_str(), SW_SHOWNORMAL);
+ return INVALID_HANDLE_VALUE;
+ } else {
+ return INVALID_HANDLE_VALUE;
+ }
+ } else {
+ reportError(QObject::tr("failed to spawn \"%1\": %2").arg(binary.fileName()).arg(e.what()));
+ return INVALID_HANDLE_VALUE;
}
+ }
- ::CloseHandle(threadHandle);
- return processHandle;
+ ::CloseHandle(threadHandle);
+ return processHandle;
}
diff --git a/src/spawn.h b/src/spawn.h
index d2e3d99c..c2d99bdb 100644
--- a/src/spawn.h
+++ b/src/spawn.h
@@ -21,10 +21,11 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#define SPAWN_H
#define WIN32_LEAN_AND_MEAN
-#include <QDir>
-#include <QFileInfo>
-#include <tchar.h>
#include <windows.h>
+#include <tchar.h>
+#include <QFileInfo>
+#include <QDir>
+
/**
* @brief a dirty little trick so we can issue a clean restart from startBinary
@@ -43,6 +44,7 @@ private:
static ExitProxy *s_Instance;
};*/
+
/**
* @brief spawn a binary with Mod Organizer injected
*
@@ -58,7 +60,9 @@ private:
* @todo is the profile name even used any more?
* @todo is the hooked parameter used?
**/
-HANDLE startBinary(const QFileInfo& binary, const QString& arguments, const QDir& currentDirectory, bool hooked,
+HANDLE startBinary(const QFileInfo &binary, const QString &arguments,
+ const QDir &currentDirectory, bool hooked,
HANDLE stdOut = INVALID_HANDLE_VALUE, HANDLE stdErr = INVALID_HANDLE_VALUE);
#endif // SPAWN_H
+
diff --git a/src/syncoverwritedialog.cpp b/src/syncoverwritedialog.cpp
index 3220f356..f03e29c5 100644
--- a/src/syncoverwritedialog.cpp
+++ b/src/syncoverwritedialog.cpp
@@ -20,133 +20,148 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "syncoverwritedialog.h"
#include "ui_syncoverwritedialog.h"
-#include <report.h>
#include <utility.h>
+#include <report.h>
-#include <QComboBox>
#include <QDir>
#include <QDirIterator>
+#include <QComboBox>
#include <QStringList>
+
using namespace MOBase;
using namespace MOShared;
-SyncOverwriteDialog::SyncOverwriteDialog(const QString& path, DirectoryEntry* directoryStructure, QWidget* parent)
- : TutorableDialog("SyncOverwrite", parent), ui(new Ui::SyncOverwriteDialog), m_SourcePath(path),
- m_DirectoryStructure(directoryStructure) {
- ui->setupUi(this);
- refresh(path);
- QHeaderView* headerView = ui->syncTree->header();
-#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
- headerView->setSectionResizeMode(0, QHeaderView::Stretch);
- headerView->setSectionResizeMode(1, QHeaderView::Interactive);
+SyncOverwriteDialog::SyncOverwriteDialog(const QString &path, DirectoryEntry *directoryStructure, QWidget *parent)
+ : TutorableDialog("SyncOverwrite", parent),
+ ui(new Ui::SyncOverwriteDialog), m_SourcePath(path), m_DirectoryStructure(directoryStructure)
+{
+ ui->setupUi(this);
+ refresh(path);
+
+ QHeaderView *headerView = ui->syncTree->header();
+#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
+ headerView->setSectionResizeMode(0, QHeaderView::Stretch);
+ headerView->setSectionResizeMode(1, QHeaderView::Interactive);
#else
- headerView->setResizeMode(0, QHeaderView::Stretch);
- headerView->setResizeMode(1, QHeaderView::Interactive);
+ headerView->setResizeMode(0, QHeaderView::Stretch);
+ headerView->setResizeMode(1, QHeaderView::Interactive);
#endif
}
-SyncOverwriteDialog::~SyncOverwriteDialog() { delete ui; }
-static void addToComboBox(QComboBox* box, const QString& name, const QVariant& userData) {
- if (QString::compare(name, "overwrite", Qt::CaseInsensitive) != 0) {
- box->addItem(name, userData);
- }
+SyncOverwriteDialog::~SyncOverwriteDialog()
+{
+ delete ui;
}
-void SyncOverwriteDialog::readTree(const QString& path, DirectoryEntry* directoryStructure, QTreeWidgetItem* subTree) {
- QDir overwrite(path);
- overwrite.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
- QDirIterator dirIter(overwrite);
- while (dirIter.hasNext()) {
- dirIter.next();
- QFileInfo fileInfo = dirIter.fileInfo();
- QString file = fileInfo.fileName();
- if (file == "meta.ini") {
- continue;
- }
+static void addToComboBox(QComboBox *box, const QString &name, const QVariant &userData)
+{
+ if (QString::compare(name, "overwrite", Qt::CaseInsensitive) != 0) {
+ box->addItem(name, userData);
+ }
+}
- QTreeWidgetItem* newItem = new QTreeWidgetItem(subTree, QStringList(file));
- if (fileInfo.isDir()) {
- DirectoryEntry* subDir = directoryStructure->findSubDirectory(ToWString(file));
- if (subDir != nullptr) {
- readTree(fileInfo.absoluteFilePath(), subDir, newItem);
- } else {
- qCritical("no directory structure for %s?", file.toUtf8().constData());
- delete newItem;
- newItem = nullptr;
- }
- } else {
- const FileEntry::Ptr entry = directoryStructure->findFile(ToWString(file));
- QComboBox* combo = new QComboBox(ui->syncTree);
- combo->addItem(tr("<don't sync>"), -1);
- if (entry.get() != nullptr) {
- bool ignore;
- int origin = entry->getOrigin(ignore);
- addToComboBox(combo, ToQString(m_DirectoryStructure->getOriginByID(origin).getName()), origin);
- const std::vector<std::pair<int, std::wstring>>& alternatives = entry->getAlternatives();
- for (std::vector<std::pair<int, std::wstring>>::const_iterator iter = alternatives.begin();
- iter != alternatives.end(); ++iter) {
- addToComboBox(combo, ToQString(m_DirectoryStructure->getOriginByID(iter->first).getName()),
- iter->first);
- }
- combo->setCurrentIndex(combo->count() - 1);
- } else {
- combo->setCurrentIndex(0);
- }
- ui->syncTree->setItemWidget(newItem, 1, combo);
- }
- if (newItem != nullptr) {
- subTree->addChild(newItem);
+void SyncOverwriteDialog::readTree(const QString &path, DirectoryEntry *directoryStructure, QTreeWidgetItem *subTree)
+{
+ QDir overwrite(path);
+ overwrite.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
+ QDirIterator dirIter(overwrite);
+ while (dirIter.hasNext()) {
+ dirIter.next();
+ QFileInfo fileInfo = dirIter.fileInfo();
+
+ QString file = fileInfo.fileName();
+ if (file == "meta.ini") {
+ continue;
+ }
+
+ QTreeWidgetItem *newItem = new QTreeWidgetItem(subTree, QStringList(file));
+
+ if (fileInfo.isDir()) {
+ DirectoryEntry *subDir = directoryStructure->findSubDirectory(ToWString(file));
+ if (subDir != nullptr) {
+ readTree(fileInfo.absoluteFilePath(), subDir, newItem);
+ } else {
+ qCritical("no directory structure for %s?", file.toUtf8().constData());
+ delete newItem;
+ newItem = nullptr;
+ }
+ } else {
+ const FileEntry::Ptr entry = directoryStructure->findFile(ToWString(file));
+ QComboBox* combo = new QComboBox(ui->syncTree);
+ combo->addItem(tr("<don't sync>"), -1);
+ if (entry.get() != nullptr) {
+ bool ignore;
+ int origin = entry->getOrigin(ignore);
+ addToComboBox(combo, ToQString(m_DirectoryStructure->getOriginByID(origin).getName()), origin);
+ const std::vector<std::pair<int, std::wstring>> &alternatives = entry->getAlternatives();
+ for (std::vector<std::pair<int, std::wstring>>::const_iterator iter = alternatives.begin(); iter != alternatives.end(); ++iter) {
+ addToComboBox(combo, ToQString(m_DirectoryStructure->getOriginByID(iter->first).getName()), iter->first);
}
+ combo->setCurrentIndex(combo->count() - 1);
+ } else {
+ combo->setCurrentIndex(0);
+ }
+ ui->syncTree->setItemWidget(newItem, 1, combo);
}
+ if (newItem != nullptr) {
+ subTree->addChild(newItem);
+ }
+ }
}
-void SyncOverwriteDialog::refresh(const QString& path) {
- QTreeWidgetItem* rootItem = new QTreeWidgetItem(ui->syncTree, QStringList("<data>"));
- readTree(path, m_DirectoryStructure, rootItem);
- ui->syncTree->addTopLevelItem(rootItem);
- ui->syncTree->expandAll();
+
+void SyncOverwriteDialog::refresh(const QString &path)
+{
+ QTreeWidgetItem *rootItem = new QTreeWidgetItem(ui->syncTree, QStringList("<data>"));
+ readTree(path, m_DirectoryStructure, rootItem);
+ ui->syncTree->addTopLevelItem(rootItem);
+ ui->syncTree->expandAll();
}
-void SyncOverwriteDialog::applyTo(QTreeWidgetItem* item, const QString& path, const QString& modDirectory) {
- for (int i = 0; i < item->childCount(); ++i) {
- QTreeWidgetItem* child = item->child(i);
- QString filePath;
- if (path.length() != 0) {
- filePath = path + "/" + child->text(0);
- } else {
- filePath = child->text(0);
- }
- if (child->childCount() != 0) {
- applyTo(child, filePath, modDirectory);
- } else {
- QComboBox* comboBox = qobject_cast<QComboBox*>(ui->syncTree->itemWidget(child, 1));
- if (comboBox != nullptr) {
- int originID = comboBox->itemData(comboBox->currentIndex(), Qt::UserRole).toInt();
- if (originID != -1) {
- FilesOrigin& origin = m_DirectoryStructure->getOriginByID(originID);
- QString source = m_SourcePath + "/" + filePath;
- QString destination = modDirectory + "/" + ToQString(origin.getName()) + "/" + filePath;
- if (!QFile::remove(destination)) {
- reportError(tr("failed to remove %1").arg(destination));
- } else if (!QFile::rename(source, destination)) {
- reportError(tr("failed to move %1 to %2").arg(source).arg(destination));
- }
- }
- }
+
+void SyncOverwriteDialog::applyTo(QTreeWidgetItem *item, const QString &path, const QString &modDirectory)
+{
+ for (int i = 0; i < item->childCount(); ++i) {
+ QTreeWidgetItem *child = item->child(i);
+ QString filePath;
+ if (path.length() != 0) {
+ filePath = path + "/" + child->text(0);
+ } else {
+ filePath = child->text(0);
+ }
+ if (child->childCount() != 0) {
+ applyTo(child, filePath, modDirectory);
+ } else {
+ QComboBox *comboBox = qobject_cast<QComboBox*>(ui->syncTree->itemWidget(child, 1));
+ if (comboBox != nullptr) {
+ int originID = comboBox->itemData(comboBox->currentIndex(), Qt::UserRole).toInt();
+ if (originID != -1) {
+ FilesOrigin &origin = m_DirectoryStructure->getOriginByID(originID);
+ QString source = m_SourcePath + "/" + filePath;
+ QString destination = modDirectory + "/" + ToQString(origin.getName()) + "/" + filePath;
+ if (!QFile::remove(destination)) {
+ reportError(tr("failed to remove %1").arg(destination));
+ } else if (!QFile::rename(source, destination)) {
+ reportError(tr("failed to move %1 to %2").arg(source).arg(destination));
+ }
}
+ }
}
+ }
- QDir dir(m_SourcePath + "/" + path);
- if ((path.length() > 0) && (dir.count() == 2)) {
- dir.rmpath(".");
- }
+ QDir dir(m_SourcePath + "/" + path);
+ if ((path.length() > 0) && (dir.count() == 2)) {
+ dir.rmpath(".");
+ }
}
-void SyncOverwriteDialog::apply(const QString& modDirectory) {
- applyTo(ui->syncTree->topLevelItem(0), "", modDirectory);
+
+void SyncOverwriteDialog::apply(const QString &modDirectory)
+{
+ applyTo(ui->syncTree->topLevelItem(0), "", modDirectory);
}
diff --git a/src/syncoverwritedialog.h b/src/syncoverwritedialog.h
index d5952bda..79b30a8d 100644
--- a/src/syncoverwritedialog.h
+++ b/src/syncoverwritedialog.h
@@ -20,33 +20,36 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef SYNCOVERWRITEDIALOG_H
#define SYNCOVERWRITEDIALOG_H
+
#include "tutorabledialog.h"
#include <QTreeWidgetItem>
#include <directoryentry.h>
+
namespace Ui {
class SyncOverwriteDialog;
}
-class SyncOverwriteDialog : public MOBase::TutorableDialog {
- Q_OBJECT
-
+class SyncOverwriteDialog : public MOBase::TutorableDialog
+{
+ Q_OBJECT
+
public:
- explicit SyncOverwriteDialog(const QString& path, MOShared::DirectoryEntry* directoryStructure,
- QWidget* parent = 0);
- ~SyncOverwriteDialog();
-
- void apply(const QString& modDirectory);
+ explicit SyncOverwriteDialog(const QString &path, MOShared::DirectoryEntry *directoryStructure, QWidget *parent = 0);
+ ~SyncOverwriteDialog();
+ void apply(const QString &modDirectory);
private:
- void refresh(const QString& path);
- void readTree(const QString& path, MOShared::DirectoryEntry* directoryStructure, QTreeWidgetItem* subTree);
- void applyTo(QTreeWidgetItem* item, const QString& path, const QString& modDirectory);
+ void refresh(const QString &path);
+ void readTree(const QString &path, MOShared::DirectoryEntry *directoryStructure, QTreeWidgetItem *subTree);
+ void applyTo(QTreeWidgetItem *item, const QString &path, const QString &modDirectory);
private:
- Ui::SyncOverwriteDialog* ui;
- QString m_SourcePath;
- MOShared::DirectoryEntry* m_DirectoryStructure;
+
+ Ui::SyncOverwriteDialog *ui;
+ QString m_SourcePath;
+ MOShared::DirectoryEntry *m_DirectoryStructure;
+
};
#endif // SYNCOVERWRITEDIALOG_H
diff --git a/src/transfersavesdialog.cpp b/src/transfersavesdialog.cpp
index dc139b39..b8dda056 100644
--- a/src/transfersavesdialog.cpp
+++ b/src/transfersavesdialog.cpp
@@ -19,12 +19,13 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "transfersavesdialog.h"
+#include "ui_transfersavesdialog.h"
#include "iplugingame.h"
#include "isavegame.h"
#include "savegameinfo.h"
-#include "ui_transfersavesdialog.h"
#include <utility.h>
+#include <QtDebug>
#include <QDateTime>
#include <QDir>
#include <QFile>
@@ -36,259 +37,324 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QMessageBox>
#include <QPushButton>
#include <QStringList>
-#include <QtDebug>
using namespace MOBase;
using namespace MOShared;
-// These two classes give the save-transfer box a smidgin of useful info even
-// if save game isn't supported yet.
+//These two classes give the save-transfer box a smidgin of useful info even
+//if save game isn't supported yet.
namespace {
-class DummySave : public ISaveGame {
+class DummySave : public ISaveGame
+{
public:
- DummySave(QString const& filename) : m_File(filename) {}
+ DummySave(QString const &filename) :
+ m_File(filename)
+ {}
- ~DummySave() {}
+ ~DummySave() {}
- virtual QString getFilename() const override { return m_File; }
+ virtual QString getFilename() const override
+ {
+ return m_File;
+ }
- virtual QDateTime getCreationTime() const override { return QFileInfo(m_File).created(); }
+ virtual QDateTime getCreationTime() const override
+ {
+ return QFileInfo(m_File).created();
+ }
- virtual QString getSaveGroupIdentifier() const override { return m_File; }
+ virtual QString getSaveGroupIdentifier() const override
+ {
+ return m_File;
+ }
- virtual QStringList allFiles() const override { return {m_File}; }
+ virtual QStringList allFiles() const override
+ {
+ return { m_File };
+ }
private:
- QString m_File;
+ QString m_File;
};
-class DummyInfo : public SaveGameInfo {
+class DummyInfo : public SaveGameInfo
+{
public:
- virtual MOBase::ISaveGame const* getSaveGameInfo(QString const& file) const override { return new DummySave(file); }
+ virtual MOBase::ISaveGame const *getSaveGameInfo(QString const &file) const override
+ {
+ return new DummySave(file);
+ }
- virtual MissingAssets getMissingAssets(QString const&) const override { return {}; }
+ virtual MissingAssets getMissingAssets(QString const &) const override
+ {
+ return {};
+ }
- MOBase::ISaveGameInfoWidget* getSaveGameWidget(QWidget*) const override { return nullptr; }
+ MOBase::ISaveGameInfoWidget *getSaveGameWidget(QWidget *) const override
+ {
+ return nullptr;
+ }
};
-} // end anonymous namespace
+} //end anonymous namespace
-TransferSavesDialog::TransferSavesDialog(const Profile& profile, IPluginGame const* gamePlugin, QWidget* parent)
- : TutorableDialog("TransferSaves", parent), ui(new Ui::TransferSavesDialog), m_Profile(profile),
- m_GamePlugin(gamePlugin) {
- ui->setupUi(this);
- ui->label_2->setText(tr("Characters for profile %1").arg(m_Profile.name()));
- refreshGlobalSaves();
- refreshLocalSaves();
- refreshGlobalCharacters();
- refreshLocalCharacters();
+TransferSavesDialog::TransferSavesDialog(const Profile &profile, IPluginGame const *gamePlugin, QWidget *parent)
+ : TutorableDialog("TransferSaves", parent)
+ , ui(new Ui::TransferSavesDialog)
+ , m_Profile(profile)
+ , m_GamePlugin(gamePlugin)
+{
+ ui->setupUi(this);
+ ui->label_2->setText(tr("Characters for profile %1").arg(m_Profile.name()));
+ refreshGlobalSaves();
+ refreshLocalSaves();
+ refreshGlobalCharacters();
+ refreshLocalCharacters();
}
-TransferSavesDialog::~TransferSavesDialog() { delete ui; }
+TransferSavesDialog::~TransferSavesDialog()
+{
+ delete ui;
+}
-void TransferSavesDialog::refreshGlobalSaves() {
- refreshSaves(m_GlobalSaves, m_GamePlugin->savesDirectory().absolutePath());
+void TransferSavesDialog::refreshGlobalSaves()
+{
+ refreshSaves(m_GlobalSaves, m_GamePlugin->savesDirectory().absolutePath());
}
-void TransferSavesDialog::refreshLocalSaves() { refreshSaves(m_LocalSaves, m_Profile.savePath()); }
-void TransferSavesDialog::refreshGlobalCharacters() {
- refreshCharacters(m_GlobalSaves, ui->globalCharacterList, ui->copyToLocalBtn, ui->moveToLocalBtn);
+void TransferSavesDialog::refreshLocalSaves()
+{
+ refreshSaves(m_LocalSaves, m_Profile.savePath());
}
-void TransferSavesDialog::refreshLocalCharacters() {
- refreshCharacters(m_LocalSaves, ui->localCharacterList, ui->copyToGlobalBtn, ui->moveToGlobalBtn);
+
+void TransferSavesDialog::refreshGlobalCharacters()
+{
+ refreshCharacters(m_GlobalSaves, ui->globalCharacterList, ui->copyToLocalBtn, ui->moveToLocalBtn);
}
-bool TransferSavesDialog::testOverwrite(OverwriteMode& overwriteMode, const QString& destinationFile) {
- QMessageBox::StandardButton res = overwriteMode == OVERWRITE_YES ? QMessageBox::Yes : QMessageBox::No;
- if (overwriteMode == OVERWRITE_ASK) {
- res = QMessageBox::question(this, tr("Overwrite"), tr("Overwrite the file \"%1\"").arg(destinationFile),
- QMessageBox::Yes | QMessageBox::No | QMessageBox::YesToAll | QMessageBox::NoToAll);
- if (res == QMessageBox::YesToAll) {
- overwriteMode = OVERWRITE_YES;
- res = QMessageBox::Yes;
- } else if (res == QMessageBox::NoToAll) {
- overwriteMode = OVERWRITE_NO;
- res = QMessageBox::No;
- }
+
+void TransferSavesDialog::refreshLocalCharacters()
+{
+ refreshCharacters(m_LocalSaves, ui->localCharacterList, ui->copyToGlobalBtn, ui->moveToGlobalBtn);
+}
+
+
+bool TransferSavesDialog::testOverwrite(OverwriteMode &overwriteMode, const QString &destinationFile)
+{
+ QMessageBox::StandardButton res = overwriteMode == OVERWRITE_YES ? QMessageBox::Yes : QMessageBox::No;
+ if (overwriteMode == OVERWRITE_ASK) {
+ res = QMessageBox::question(this, tr("Overwrite"),
+ tr("Overwrite the file \"%1\"").arg(destinationFile),
+ QMessageBox::Yes | QMessageBox::No | QMessageBox::YesToAll | QMessageBox::NoToAll);
+ if (res == QMessageBox::YesToAll) {
+ overwriteMode = OVERWRITE_YES;
+ res = QMessageBox::Yes;
+ } else if (res == QMessageBox::NoToAll) {
+ overwriteMode = OVERWRITE_NO;
+ res = QMessageBox::No;
}
- return res == QMessageBox::Yes;
+ }
+ return res == QMessageBox::Yes;
}
-#define MOVE_SAVES "Move all save games of character \"%1\""
-#define COPY_SAVES "Copy all save games of character \"%1\""
+
+#define MOVE_SAVES "Move all save games of character \"%1\""
+#define COPY_SAVES "Copy all save games of character \"%1\""
#define TO_PROFILE "to the profile?"
-#define TO_GLOBAL "to the global location? Please be aware that this will mess up the running number of save games."
+#define TO_GLOBAL "to the global location? Please be aware that this will mess up the running number of save games."
-void TransferSavesDialog::on_moveToLocalBtn_clicked() {
- QString character = ui->globalCharacterList->currentItem()->text();
- if (transferCharacters(character, MOVE_SAVES TO_PROFILE, m_GlobalSaves[character], m_Profile.savePath(),
- [this](const QString& source, const QString& destination) -> bool {
- return shellMove(source, destination, this);
- },
- "Failed to move %s to %s")) {
- refreshGlobalSaves();
- refreshGlobalCharacters();
- refreshLocalSaves();
- refreshLocalCharacters();
- }
+void TransferSavesDialog::on_moveToLocalBtn_clicked()
+{
+ QString character = ui->globalCharacterList->currentItem()->text();
+ if (transferCharacters(
+ character, MOVE_SAVES TO_PROFILE, m_GlobalSaves[character],
+ m_Profile.savePath(),
+ [this](const QString &source, const QString &destination) -> bool {
+ return shellMove(source, destination, this);
+ },
+ "Failed to move %s to %s")) {
+ refreshGlobalSaves();
+ refreshGlobalCharacters();
+ refreshLocalSaves();
+ refreshLocalCharacters();
+ }
}
-void TransferSavesDialog::on_copyToLocalBtn_clicked() {
- QString character = ui->globalCharacterList->currentItem()->text();
- if (transferCharacters(character, COPY_SAVES TO_PROFILE, m_GlobalSaves[character], m_Profile.savePath(),
- [this](const QString& source, const QString& destination) -> bool {
- return shellCopy(source, destination, this);
- },
- "Failed to copy %s to %s")) {
- refreshLocalSaves();
- refreshLocalCharacters();
- }
+void TransferSavesDialog::on_copyToLocalBtn_clicked()
+{
+ QString character = ui->globalCharacterList->currentItem()->text();
+ if (transferCharacters(
+ character, COPY_SAVES TO_PROFILE, m_GlobalSaves[character],
+ m_Profile.savePath(),
+ [this](const QString &source, const QString &destination) -> bool {
+ return shellCopy(source, destination, this);
+ },
+ "Failed to copy %s to %s")) {
+ refreshLocalSaves();
+ refreshLocalCharacters();
+ }
}
-void TransferSavesDialog::on_moveToGlobalBtn_clicked() {
- QString character = ui->localCharacterList->currentItem()->text();
- if (transferCharacters(character, MOVE_SAVES TO_GLOBAL, m_LocalSaves[character],
- m_GamePlugin->savesDirectory().absolutePath(),
- [this](const QString& source, const QString& destination) -> bool {
- return shellMove(source, destination, this);
- },
- "Failed to move %s to %s")) {
- refreshGlobalSaves();
- refreshGlobalCharacters();
- refreshLocalSaves();
- refreshLocalCharacters();
- }
+void TransferSavesDialog::on_moveToGlobalBtn_clicked()
+{
+ QString character = ui->localCharacterList->currentItem()->text();
+ if (transferCharacters(
+ character, MOVE_SAVES TO_GLOBAL, m_LocalSaves[character],
+ m_GamePlugin->savesDirectory().absolutePath(),
+ [this](const QString &source, const QString &destination) -> bool {
+ return shellMove(source, destination, this);
+ },
+ "Failed to move %s to %s")) {
+ refreshGlobalSaves();
+ refreshGlobalCharacters();
+ refreshLocalSaves();
+ refreshLocalCharacters();
+ }
}
-void TransferSavesDialog::on_copyToGlobalBtn_clicked() {
- QString character = ui->localCharacterList->currentItem()->text();
- if (transferCharacters(character, COPY_SAVES TO_GLOBAL, m_LocalSaves[character],
- m_GamePlugin->savesDirectory().absolutePath(),
- [this](const QString& source, const QString& destination) -> bool {
- return shellCopy(source, destination, this);
- },
- "Failed to copy %s to %s")) {
- refreshGlobalSaves();
- refreshGlobalCharacters();
- }
+void TransferSavesDialog::on_copyToGlobalBtn_clicked()
+{
+ QString character = ui->localCharacterList->currentItem()->text();
+ if (transferCharacters(
+ character, COPY_SAVES TO_GLOBAL, m_LocalSaves[character],
+ m_GamePlugin->savesDirectory().absolutePath(),
+ [this](const QString &source, const QString &destination) -> bool {
+ return shellCopy(source, destination, this);
+ },
+ "Failed to copy %s to %s")) {
+ refreshGlobalSaves();
+ refreshGlobalCharacters();
+ }
}
-void TransferSavesDialog::on_doneButton_clicked() { close(); }
+void TransferSavesDialog::on_doneButton_clicked()
+{
+ close();
+}
-void TransferSavesDialog::on_globalCharacterList_currentTextChanged(const QString& currentText) {
- ui->globalSavesList->clear();
- // sadly this can get called while we're resetting the list, with an invalid
- // name, so we have to check.
- SaveCollection::const_iterator saveList = m_GlobalSaves.find(currentText);
- if (saveList != m_GlobalSaves.end()) {
- for (SaveListItem const& save : saveList->second) {
- ui->globalSavesList->addItem(QFileInfo(save->getFilename()).fileName());
- }
+void TransferSavesDialog::on_globalCharacterList_currentTextChanged(const QString &currentText)
+{
+ ui->globalSavesList->clear();
+ //sadly this can get called while we're resetting the list, with an invalid
+ //name, so we have to check.
+ SaveCollection::const_iterator saveList = m_GlobalSaves.find(currentText);
+ if (saveList != m_GlobalSaves.end()) {
+ for (SaveListItem const &save : saveList->second) {
+ ui->globalSavesList->addItem(QFileInfo(save->getFilename()).fileName());
}
+ }
}
-void TransferSavesDialog::on_localCharacterList_currentTextChanged(const QString& currentText) {
- ui->localSavesList->clear();
- // sadly this can get called while we're resetting the list, with an invalid
- // name, so we have to check.
- SaveCollection::const_iterator saveList = m_LocalSaves.find(currentText);
- if (saveList != m_LocalSaves.end()) {
- for (SaveListItem const& save : saveList->second) {
- ui->localSavesList->addItem(QFileInfo(save->getFilename()).fileName());
- }
+void TransferSavesDialog::on_localCharacterList_currentTextChanged(const QString &currentText)
+{
+ ui->localSavesList->clear();
+ //sadly this can get called while we're resetting the list, with an invalid
+ //name, so we have to check.
+ SaveCollection::const_iterator saveList = m_LocalSaves.find(currentText);
+ if (saveList != m_LocalSaves.end()) {
+ for (SaveListItem const &save : saveList->second) {
+ ui->localSavesList->addItem(QFileInfo(save->getFilename()).fileName());
}
+ }
}
-void TransferSavesDialog::refreshSaves(SaveCollection& saveCollection, QString const& savedir) {
- saveCollection.clear();
- QDir savesDir(savedir);
- savesDir.setNameFilters(QStringList() << QString("*.%1").arg(m_GamePlugin->savegameExtension()));
+void TransferSavesDialog::refreshSaves(SaveCollection &saveCollection, QString const &savedir)
+{
+ saveCollection.clear();
+ QDir savesDir(savedir);
+ savesDir.setNameFilters(QStringList() << QString("*.%1").arg(m_GamePlugin->savegameExtension()));
- SaveGameInfo const* info = m_GamePlugin->feature<SaveGameInfo>();
- if (info == nullptr) {
- static DummyInfo dummyInfo;
- info = &dummyInfo;
- }
+ SaveGameInfo const *info = m_GamePlugin->feature<SaveGameInfo>();
+ if (info == nullptr) {
+ static DummyInfo dummyInfo;
+ info = &dummyInfo;
+ }
- QStringList files = savesDir.entryList(QDir::Files, QDir::Time);
- for (const QString& filename : files) {
- QString file = savesDir.absoluteFilePath(filename);
- MOBase::ISaveGame const* save = info->getSaveGameInfo(file);
- saveCollection[save->getSaveGroupIdentifier()].push_back(std::unique_ptr<MOBase::ISaveGame const>(save));
- }
+ QStringList files = savesDir.entryList(QDir::Files, QDir::Time);
+ for (const QString &filename : files) {
+ QString file = savesDir.absoluteFilePath(filename);
+ MOBase::ISaveGame const *save = info->getSaveGameInfo(file);
+ saveCollection[save->getSaveGroupIdentifier()].push_back(
+ std::unique_ptr<MOBase::ISaveGame const>(save));
+ }
}
-void TransferSavesDialog::refreshCharacters(const SaveCollection& saveCollection, QListWidget* charList,
- QPushButton* copy, QPushButton* move) {
- charList->clear();
- for (SaveCollection::value_type const& val : saveCollection) {
- charList->addItem(val.first);
- }
- if (charList->count() > 0) {
- charList->setCurrentRow(0);
- copy->setEnabled(true);
- move->setEnabled(true);
- } else {
- copy->setEnabled(false);
- move->setEnabled(false);
- }
+void TransferSavesDialog::refreshCharacters(const SaveCollection &saveCollection,
+ QListWidget *charList, QPushButton *copy, QPushButton *move)
+{
+ charList->clear();
+ for (SaveCollection::value_type const &val : saveCollection) {
+ charList->addItem(val.first);
+ }
+ if (charList->count() > 0) {
+ charList->setCurrentRow(0);
+ copy->setEnabled(true);
+ move->setEnabled(true);
+ } else {
+ copy->setEnabled(false);
+ move->setEnabled(false);
+ }
}
-bool TransferSavesDialog::transferCharacters(QString const& character, char const* message, SaveList& saves,
- QString const& dest,
- const std::function<bool(const QString&, const QString&)>& method,
- char const* errmsg) {
- if (QMessageBox::question(this, tr("Confirm"), tr(message).arg(character), QMessageBox::Yes | QMessageBox::No) !=
- QMessageBox::Yes) {
- return false;
- }
+bool TransferSavesDialog::transferCharacters(
+ QString const &character, char const *message, SaveList &saves,
+ QString const &dest,
+ const std::function<bool(const QString &, const QString &)> &method,
+ char const *errmsg)
+{
+ if (QMessageBox::question(this, tr("Confirm"),
+ tr(message).arg(character),
+ QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
+ return false;
+ }
- OverwriteMode overwriteMode = OVERWRITE_ASK;
+ OverwriteMode overwriteMode = OVERWRITE_ASK;
- QDir destination(dest);
- for (SaveListItem const& save : saves) {
- for (QString source : save->allFiles()) {
- QFileInfo sourceFile(source);
- QString destinationFile(destination.absoluteFilePath(sourceFile.fileName()));
+ QDir destination(dest);
+ for (SaveListItem const &save : saves) {
+ for (QString source : save->allFiles()) {
+ QFileInfo sourceFile(source);
+ QString destinationFile(destination.absoluteFilePath(sourceFile.fileName()));
- // If the file is already there, let them skip (or not).
- if (QFile::exists(destinationFile)) {
- if (!testOverwrite(overwriteMode, destinationFile)) {
- continue;
- }
- // OK, they want to remove it.
- QFile::remove(destinationFile);
- }
+ //If the file is already there, let them skip (or not).
+ if (QFile::exists(destinationFile)) {
+ if (! testOverwrite(overwriteMode, destinationFile)) {
+ continue;
+ }
+ //OK, they want to remove it.
+ QFile::remove(destinationFile);
+ }
- if (!method(sourceFile.absoluteFilePath(), destinationFile)) {
- qCritical(errmsg, sourceFile.absoluteFilePath().toUtf8().constData(),
- destinationFile.toUtf8().constData());
- }
+ if (!method(sourceFile.absoluteFilePath(), destinationFile)) {
+ qCritical(errmsg,
+ sourceFile.absoluteFilePath().toUtf8().constData(),
+ destinationFile.toUtf8().constData());
+ }
- QFileInfo sourceFileSE(sourceFile.absolutePath() + "/" + sourceFile.completeBaseName() + "." +
- m_GamePlugin->savegameSEExtension());
- if (sourceFileSE.exists()) {
- QString destinationFileSE(destination.absoluteFilePath(sourceFileSE.fileName()));
+ QFileInfo sourceFileSE(sourceFile.absolutePath() + "/" + sourceFile.completeBaseName() + "." + m_GamePlugin->savegameSEExtension());
+ if (sourceFileSE.exists()) {
+ QString destinationFileSE(destination.absoluteFilePath(sourceFileSE.fileName()));
- // If the file is already there, let them skip (or not).
- if (QFile::exists(destinationFileSE)) {
- if (!testOverwrite(overwriteMode, destinationFileSE)) {
- continue;
- }
- // OK, they want to remove it.
- QFile::remove(destinationFileSE);
- }
+ //If the file is already there, let them skip (or not).
+ if (QFile::exists(destinationFileSE)) {
+ if (!testOverwrite(overwriteMode, destinationFileSE)) {
+ continue;
+ }
+ //OK, they want to remove it.
+ QFile::remove(destinationFileSE);
+ }
- if (!method(sourceFileSE.absoluteFilePath(), destinationFileSE)) {
- qCritical(errmsg, sourceFileSE.absoluteFilePath().toUtf8().constData(),
- destinationFileSE.toUtf8().constData());
- }
- }
+ if (!method(sourceFileSE.absoluteFilePath(), destinationFileSE)) {
+ qCritical(errmsg,
+ sourceFileSE.absoluteFilePath().toUtf8().constData(),
+ destinationFileSE.toUtf8().constData());
}
+ }
}
- return true;
+ }
+ return true;
}
diff --git a/src/transfersavesdialog.h b/src/transfersavesdialog.h
index 81c44f57..dee41c72 100644
--- a/src/transfersavesdialog.h
+++ b/src/transfersavesdialog.h
@@ -20,8 +20,8 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#ifndef TRANSFERSAVESDIALOG_H
#define TRANSFERSAVESDIALOG_H
-#include "profile.h"
#include "tutorabledialog.h"
+#include "profile.h"
class QListWidget;
#include <QObject>
@@ -29,72 +29,73 @@ class QPushButton;
#include <QString>
class QWidget;
-#include <map>
#include <memory>
+#include <map>
#include <vector>
-namespace Ui {
-class TransferSavesDialog;
-}
-namespace MOBase {
-class IPluginGame;
-}
-namespace MOBase {
-class ISaveGame;
-}
+namespace Ui { class TransferSavesDialog; }
+namespace MOBase { class IPluginGame; }
+namespace MOBase { class ISaveGame; }
class TransferSavesDialog : public MOBase::TutorableDialog {
- Q_OBJECT
+ Q_OBJECT
public:
- explicit TransferSavesDialog(const Profile& profile, MOBase::IPluginGame const* gamePlugin, QWidget* parent = 0);
- ~TransferSavesDialog();
+ explicit TransferSavesDialog(const Profile &profile,
+ MOBase::IPluginGame const *gamePlugin,
+ QWidget *parent = 0);
+ ~TransferSavesDialog();
private slots:
- void on_moveToLocalBtn_clicked();
+ void on_moveToLocalBtn_clicked();
- void on_doneButton_clicked();
+ void on_doneButton_clicked();
- void on_globalCharacterList_currentTextChanged(const QString& currentText);
+ void on_globalCharacterList_currentTextChanged(const QString &currentText);
- void on_localCharacterList_currentTextChanged(const QString& currentText);
+ void on_localCharacterList_currentTextChanged(const QString &currentText);
- void on_copyToLocalBtn_clicked();
+ void on_copyToLocalBtn_clicked();
- void on_moveToGlobalBtn_clicked();
+ void on_moveToGlobalBtn_clicked();
- void on_copyToGlobalBtn_clicked();
+ void on_copyToGlobalBtn_clicked();
private:
- enum OverwriteMode { OVERWRITE_ASK, OVERWRITE_YES, OVERWRITE_NO };
+ enum OverwriteMode { OVERWRITE_ASK, OVERWRITE_YES, OVERWRITE_NO };
private:
- void refreshGlobalCharacters();
- void refreshLocalCharacters();
- void refreshGlobalSaves();
- void refreshLocalSaves();
- bool testOverwrite(OverwriteMode& overwriteMode, const QString& destinationFile);
+ void refreshGlobalCharacters();
+ void refreshLocalCharacters();
+ void refreshGlobalSaves();
+ void refreshLocalSaves();
+ bool testOverwrite(OverwriteMode &overwriteMode,
+ const QString &destinationFile);
private:
- Ui::TransferSavesDialog* ui;
+ Ui::TransferSavesDialog *ui;
- Profile m_Profile;
+ Profile m_Profile;
- MOBase::IPluginGame const* m_GamePlugin;
+ MOBase::IPluginGame const *m_GamePlugin;
- typedef std::unique_ptr<MOBase::ISaveGame const> SaveListItem;
- typedef std::vector<SaveListItem> SaveList;
- typedef std::map<QString, SaveList> SaveCollection;
- SaveCollection m_GlobalSaves;
- SaveCollection m_LocalSaves;
+ typedef std::unique_ptr<MOBase::ISaveGame const> SaveListItem;
+ typedef std::vector<SaveListItem> SaveList;
+ typedef std::map<QString, SaveList> SaveCollection;
+ SaveCollection m_GlobalSaves;
+ SaveCollection m_LocalSaves;
- void refreshSaves(SaveCollection& saveCollection, const QString& savedir);
- void refreshCharacters(SaveCollection const& saveCollection, QListWidget* charList, QPushButton* copy,
- QPushButton* move);
+ void refreshSaves(SaveCollection &saveCollection, const QString &savedir);
+ void refreshCharacters(SaveCollection const &saveCollection,
+ QListWidget *charList, QPushButton *copy,
+ QPushButton *move);
- bool transferCharacters(QString const& character, char const* message, SaveList& saves, QString const& dest,
- const std::function<bool(const QString&, const QString&)>& method, char const* errmsg);
+ bool transferCharacters(
+ QString const &character, char const *message, SaveList &saves,
+ QString const &dest,
+ const std::function<bool(const QString &, const QString &)> &method,
+ char const *errmsg);
};
#endif // TRANSFERSAVESDIALOG_H
diff --git a/src/usvfsconnector.cpp b/src/usvfsconnector.cpp
index 5504684e..ffbdf3aa 100644
--- a/src/usvfsconnector.cpp
+++ b/src/usvfsconnector.cpp
@@ -18,160 +18,183 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "usvfsconnector.h"
-#include "organizercore.h"
#include "settings.h"
+#include "organizercore.h"
#include "shared/util.h"
-#include <QCoreApplication>
-#include <QDateTime>
-#include <QProgressDialog>
-#include <QTemporaryFile>
-#include <iomanip>
#include <memory>
-#include <qstandardpaths.h>
#include <sstream>
+#include <iomanip>
#include <usvfs.h>
+#include <QTemporaryFile>
+#include <QProgressDialog>
+#include <QDateTime>
+#include <QCoreApplication>
+#include <qstandardpaths.h>
static const char SHMID[] = "mod_organizer_instance";
-std::string to_hex(void* bufferIn, size_t bufferSize) {
- unsigned char* buffer = static_cast<unsigned char*>(bufferIn);
- std::ostringstream temp;
- temp << std::hex;
- for (size_t i = 0; i < bufferSize; ++i) {
- temp << std::setfill('0') << std::setw(2) << (unsigned int)buffer[i];
- if ((i % 16) == 15) {
- temp << "\n";
- } else {
- temp << " ";
- }
+
+std::string to_hex(void *bufferIn, size_t bufferSize)
+{
+ unsigned char *buffer = static_cast<unsigned char *>(bufferIn);
+ std::ostringstream temp;
+ temp << std::hex;
+ for (size_t i = 0; i < bufferSize; ++i) {
+ temp << std::setfill('0') << std::setw(2) << (unsigned int)buffer[i];
+ if ((i % 16) == 15) {
+ temp << "\n";
+ } else {
+ temp << " ";
}
- return temp.str();
+ }
+ return temp.str();
}
+
LogWorker::LogWorker()
- : m_Buffer(1024, '\0'), m_QuitRequested(false),
- m_LogFile(qApp->property("dataPath").toString() +
- QString("/logs/usvfs-%1.log").arg(QDateTime::currentDateTimeUtc().toString("yyyy-MM-dd_hh-mm-ss"))) {
- m_LogFile.open(QIODevice::WriteOnly);
- qDebug("usvfs log messages are written to %s", qPrintable(m_LogFile.fileName()));
+ : m_Buffer(1024, '\0')
+ , m_QuitRequested(false)
+ , m_LogFile(qApp->property("dataPath").toString()
+ + QString("/logs/usvfs-%1.log")
+ .arg(QDateTime::currentDateTimeUtc().toString(
+ "yyyy-MM-dd_hh-mm-ss")))
+{
+ m_LogFile.open(QIODevice::WriteOnly);
+ qDebug("usvfs log messages are written to %s",
+ qPrintable(m_LogFile.fileName()));
}
-LogWorker::~LogWorker() {}
+LogWorker::~LogWorker()
+{
+}
-void LogWorker::process() {
- int noLogCycles = 0;
- while (!m_QuitRequested) {
- if (GetLogMessages(&m_Buffer[0], m_Buffer.size(), false)) {
- m_LogFile.write(m_Buffer.c_str());
- m_LogFile.write("\n");
- m_LogFile.flush();
- noLogCycles = 0;
- } else {
- QThread::msleep(std::min(40, noLogCycles) * 5);
- ++noLogCycles;
- }
+void LogWorker::process()
+{
+ int noLogCycles = 0;
+ while (!m_QuitRequested) {
+ if (GetLogMessages(&m_Buffer[0], m_Buffer.size(), false)) {
+ m_LogFile.write(m_Buffer.c_str());
+ m_LogFile.write("\n");
+ m_LogFile.flush();
+ noLogCycles = 0;
+ } else {
+ QThread::msleep(std::min(40, noLogCycles) * 5);
+ ++noLogCycles;
}
- emit finished();
+ }
+ emit finished();
}
-void LogWorker::exit() { m_QuitRequested = true; }
+void LogWorker::exit()
+{
+ m_QuitRequested = true;
+}
-LogLevel logLevel(int level) {
- switch (level) {
+LogLevel logLevel(int level)
+{
+ switch (level) {
case LogLevel::Info:
- return LogLevel::Info;
+ return LogLevel::Info;
case LogLevel::Warning:
- return LogLevel::Warning;
+ return LogLevel::Warning;
case LogLevel::Error:
- return LogLevel::Error;
+ return LogLevel::Error;
default:
- return LogLevel::Debug;
- }
+ return LogLevel::Debug;
+ }
}
-CrashDumpsType crashDumpsType(int type) {
- switch (type) {
- case CrashDumpsType::Mini:
- return CrashDumpsType::Mini;
- case CrashDumpsType::Data:
- return CrashDumpsType::Data;
- case CrashDumpsType::Full:
- return CrashDumpsType::Full;
- default:
- return CrashDumpsType::None;
- }
+CrashDumpsType crashDumpsType(int type)
+{
+ switch (type) {
+ case CrashDumpsType::Mini:
+ return CrashDumpsType::Mini;
+ case CrashDumpsType::Data:
+ return CrashDumpsType::Data;
+ case CrashDumpsType::Full:
+ return CrashDumpsType::Full;
+ default:
+ return CrashDumpsType::None;
+ }
}
-UsvfsConnector::UsvfsConnector() {
- USVFSParameters params;
- LogLevel level = logLevel(Settings::instance().logLevel());
- CrashDumpsType dumpType = crashDumpsType(Settings::instance().crashDumpsType());
+UsvfsConnector::UsvfsConnector()
+{
+ USVFSParameters params;
+ LogLevel level = logLevel(Settings::instance().logLevel());
+ CrashDumpsType dumpType = crashDumpsType(Settings::instance().crashDumpsType());
- std::string dumpPath = MOShared::ToString(OrganizerCore::crashDumpsPath(), true);
- USVFSInitParameters(&params, SHMID, false, level, dumpType, dumpPath.c_str());
- InitLogging(false);
+ std::string dumpPath = MOShared::ToString(OrganizerCore::crashDumpsPath(), true);
+ USVFSInitParameters(&params, SHMID, false, level, dumpType, dumpPath.c_str());
+ InitLogging(false);
- qDebug("Initializing VFS <%s, %d, %d, %s>", params.instanceName, params.logLevel, params.crashDumpsType,
- params.crashDumpsPath);
+ qDebug("Initializing VFS <%s, %d, %d, %s>", params.instanceName, params.logLevel, params.crashDumpsType, params.crashDumpsPath);
- CreateVFS(&params);
+ CreateVFS(&params);
- BlacklistExecutable(L"TSVNCache.exe");
+ BlacklistExecutable(L"TSVNCache.exe");
- m_LogWorker.moveToThread(&m_WorkerThread);
+ m_LogWorker.moveToThread(&m_WorkerThread);
- connect(&m_WorkerThread, SIGNAL(started()), &m_LogWorker, SLOT(process()));
- connect(&m_LogWorker, SIGNAL(finished()), &m_WorkerThread, SLOT(quit()));
+ connect(&m_WorkerThread, SIGNAL(started()), &m_LogWorker, SLOT(process()));
+ connect(&m_LogWorker, SIGNAL(finished()), &m_WorkerThread, SLOT(quit()));
- m_WorkerThread.start(QThread::LowestPriority);
+ m_WorkerThread.start(QThread::LowestPriority);
}
-UsvfsConnector::~UsvfsConnector() {
- DisconnectVFS();
- m_LogWorker.exit();
- m_WorkerThread.quit();
- m_WorkerThread.wait();
+UsvfsConnector::~UsvfsConnector()
+{
+ DisconnectVFS();
+ m_LogWorker.exit();
+ m_WorkerThread.quit();
+ m_WorkerThread.wait();
}
-void UsvfsConnector::updateMapping(const MappingType& mapping) {
- QProgressDialog progress;
- progress.setLabelText(tr("Preparing vfs"));
- progress.setMaximum(static_cast<int>(mapping.size()));
- progress.show();
- int value = 0;
- int files = 0;
- int dirs = 0;
- qDebug("Updating VFS mappings...");
+void UsvfsConnector::updateMapping(const MappingType &mapping)
+{
+ QProgressDialog progress;
+ progress.setLabelText(tr("Preparing vfs"));
+ progress.setMaximum(static_cast<int>(mapping.size()));
+ progress.show();
+ int value = 0;
+ int files = 0;
+ int dirs = 0;
- ClearVirtualMappings();
+ qDebug("Updating VFS mappings...");
- for (auto map : mapping) {
- progress.setValue(value++);
- if (value % 10 == 0) {
- QCoreApplication::processEvents();
- }
+ ClearVirtualMappings();
+
+ for (auto map : mapping) {
+ progress.setValue(value++);
+ if (value % 10 == 0) {
+ QCoreApplication::processEvents();
+ }
- if (map.isDirectory) {
- VirtualLinkDirectoryStatic(map.source.toStdWString().c_str(), map.destination.toStdWString().c_str(),
- (map.createTarget ? LINKFLAG_CREATETARGET : 0) | LINKFLAG_RECURSIVE);
- ++dirs;
- } else {
- VirtualLinkFile(map.source.toStdWString().c_str(), map.destination.toStdWString().c_str(), 0);
- ++files;
- }
+ if (map.isDirectory) {
+ VirtualLinkDirectoryStatic(map.source.toStdWString().c_str(),
+ map.destination.toStdWString().c_str(),
+ (map.createTarget ? LINKFLAG_CREATETARGET : 0)
+ | LINKFLAG_RECURSIVE
+ );
+ ++dirs;
+ } else {
+ VirtualLinkFile(map.source.toStdWString().c_str(),
+ map.destination.toStdWString().c_str(), 0);
+ ++files;
}
+ }
- qDebug("VFS mappings updated <linked %d dirs, %d files>", dirs, files);
- /*
- size_t dumpSize = 0;
- CreateVFSDump(nullptr, &dumpSize);
- std::unique_ptr<char[]> buffer(new char[dumpSize]);
- CreateVFSDump(buffer.get(), &dumpSize);
- qDebug(buffer.get());
- */
+ qDebug("VFS mappings updated <linked %d dirs, %d files>", dirs, files);
+ /*
+ size_t dumpSize = 0;
+ CreateVFSDump(nullptr, &dumpSize);
+ std::unique_ptr<char[]> buffer(new char[dumpSize]);
+ CreateVFSDump(buffer.get(), &dumpSize);
+ qDebug(buffer.get());
+ */
}
void UsvfsConnector::updateParams(int logLevel, int crashDumpsType) {
- USVFSUpdateParams(::logLevel(logLevel), ::crashDumpsType(crashDumpsType));
+ USVFSUpdateParams(::logLevel(logLevel), ::crashDumpsType(crashDumpsType));
}
diff --git a/src/usvfsconnector.h b/src/usvfsconnector.h
index 937912bf..0935bac1 100644
--- a/src/usvfsconnector.h
+++ b/src/usvfsconnector.h
@@ -17,54 +17,64 @@ You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
+
#ifndef USVFSCONNECTOR_H
#define USVFSCONNECTOR_H
-#include <QDebug>
-#include <QFile>
+
+#include <filemapping.h>
#include <QString>
#include <QThread>
-#include <filemapping.h>
+#include <QFile>
+#include <QDebug>
#include <usvfsparameters.h>
+
class LogWorker : public QThread {
- Q_OBJECT
+ Q_OBJECT
public:
- LogWorker();
- ~LogWorker();
+
+ LogWorker();
+ ~LogWorker();
public slots:
- void process();
- void exit();
+ void process();
+ void exit();
signals:
- void outputLog(const QString& message);
- void finished();
+ void outputLog(const QString &message);
+ void finished();
private:
- std::string m_Buffer;
- bool m_QuitRequested;
- QFile m_LogFile;
+
+ std::string m_Buffer;
+ bool m_QuitRequested;
+ QFile m_LogFile;
+
};
+
class UsvfsConnector : public QObject {
- Q_OBJECT
+ Q_OBJECT
public:
- UsvfsConnector();
- ~UsvfsConnector();
- void updateMapping(const MappingType& mapping);
- void updateParams(int logLevel, int crashDumpsType);
+ UsvfsConnector();
+ ~UsvfsConnector();
+
+ void updateMapping(const MappingType &mapping);
+ void updateParams(int logLevel, int crashDumpsType);
private:
- LogWorker m_LogWorker;
- QThread m_WorkerThread;
+
+ LogWorker m_LogWorker;
+ QThread m_WorkerThread;
+
};
CrashDumpsType crashDumpsType(int type);
diff --git a/src/viewmarkingscrollbar.cpp b/src/viewmarkingscrollbar.cpp
index 596af533..2452d0e3 100644
--- a/src/viewmarkingscrollbar.cpp
+++ b/src/viewmarkingscrollbar.cpp
@@ -1,38 +1,42 @@
#include "viewmarkingscrollbar.h"
-#include <QPainter>
#include <QStyle>
#include <QStyleOptionSlider>
+#include <QPainter>
-ViewMarkingScrollBar::ViewMarkingScrollBar(QAbstractItemModel* model, QWidget* parent, int role)
- : QScrollBar(parent), m_Model(model), m_Role(role) {
- // not implemented for horizontal sliders
- Q_ASSERT(this->orientation() == Qt::Vertical);
+ViewMarkingScrollBar::ViewMarkingScrollBar(QAbstractItemModel *model, QWidget *parent, int role)
+ : QScrollBar(parent)
+ , m_Model(model)
+ , m_Role(role)
+{
+ // not implemented for horizontal sliders
+ Q_ASSERT(this->orientation() == Qt::Vertical);
}
-void ViewMarkingScrollBar::paintEvent(QPaintEvent* event) {
- if (m_Model == nullptr) {
- return;
- }
- QScrollBar::paintEvent(event);
+void ViewMarkingScrollBar::paintEvent(QPaintEvent *event)
+{
+ if (m_Model == nullptr) {
+ return;
+ }
+ QScrollBar::paintEvent(event);
- QStyleOptionSlider styleOption;
- initStyleOption(&styleOption);
+ QStyleOptionSlider styleOption;
+ initStyleOption(&styleOption);
- QPainter painter(this);
+ QPainter painter(this);
- QRect handleRect = style()->subControlRect(QStyle::CC_ScrollBar, &styleOption, QStyle::SC_ScrollBarSlider, this);
- QRect innerRect = style()->subControlRect(QStyle::CC_ScrollBar, &styleOption, QStyle::SC_ScrollBarGroove, this);
+ QRect handleRect = style()->subControlRect(QStyle::CC_ScrollBar, &styleOption, QStyle::SC_ScrollBarSlider, this);
+ QRect innerRect = style()->subControlRect(QStyle::CC_ScrollBar, &styleOption, QStyle::SC_ScrollBarGroove, this);
- painter.translate(innerRect.topLeft() + QPoint(0, 3));
- qreal scale = static_cast<qreal>(innerRect.height() - 3) / static_cast<qreal>(m_Model->rowCount());
+ painter.translate(innerRect.topLeft() + QPoint(0, 3));
+ qreal scale = static_cast<qreal>(innerRect.height() - 3) / static_cast<qreal>(m_Model->rowCount());
- for (int i = 0; i < m_Model->rowCount(); ++i) {
- QVariant data = m_Model->data(m_Model->index(i, 0), m_Role);
- if (data.isValid()) {
- QColor col = data.value<QColor>();
- painter.setPen(col);
- painter.setBrush(col);
- painter.drawRect(QRect(2, i * scale - 2, handleRect.width() - 5, 3));
- }
+ for (int i = 0; i < m_Model->rowCount(); ++i) {
+ QVariant data = m_Model->data(m_Model->index(i, 0), m_Role);
+ if (data.isValid()) {
+ QColor col = data.value<QColor>();
+ painter.setPen(col);
+ painter.setBrush(col);
+ painter.drawRect(QRect(2, i * scale - 2, handleRect.width() - 5, 3));
}
+ }
}
diff --git a/src/viewmarkingscrollbar.h b/src/viewmarkingscrollbar.h
index bcf8f21e..12a297d1 100644
--- a/src/viewmarkingscrollbar.h
+++ b/src/viewmarkingscrollbar.h
@@ -1,22 +1,22 @@
#ifndef VIEWMARKINGSCROLLBAR_H
#define VIEWMARKINGSCROLLBAR_H
-#include <QAbstractItemModel>
#include <QScrollBar>
+#include <QAbstractItemModel>
-class ViewMarkingScrollBar : public QScrollBar {
-public:
- static const int DEFAULT_ROLE = Qt::UserRole + 42;
+class ViewMarkingScrollBar : public QScrollBar
+{
public:
- ViewMarkingScrollBar(QAbstractItemModel* model, QWidget* parent = 0, int role = DEFAULT_ROLE);
-
+ static const int DEFAULT_ROLE = Qt::UserRole + 42;
+public:
+ ViewMarkingScrollBar(QAbstractItemModel *model, QWidget *parent = 0, int role = DEFAULT_ROLE);
protected:
- virtual void paintEvent(QPaintEvent* event);
-
+ virtual void paintEvent(QPaintEvent *event);
private:
- QAbstractItemModel* m_Model;
- int m_Role;
+ QAbstractItemModel *m_Model;
+ int m_Role;
};
+
#endif // VIEWMARKINGSCROLLBAR_H
diff --git a/src/waitingonclosedialog.cpp b/src/waitingonclosedialog.cpp
index 6ab328b8..565d0a36 100644
--- a/src/waitingonclosedialog.cpp
+++ b/src/waitingonclosedialog.cpp
@@ -23,36 +23,49 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QPoint>
#include <QResizeEvent>
#include <QWidget>
-#include <Qt> // for Qt::FramelessWindowHint, etc
+#include <Qt> // for Qt::FramelessWindowHint, etc
-WaitingOnCloseDialog::WaitingOnCloseDialog(QWidget* parent)
- : LockedDialogBase(parent, true), ui(new Ui::WaitingOnCloseDialog) {
- ui->setupUi(this);
+WaitingOnCloseDialog::WaitingOnCloseDialog(QWidget *parent)
+ : LockedDialogBase(parent,true)
+ , ui(new Ui::WaitingOnCloseDialog)
+{
+ ui->setupUi(this);
- // Supposedly the Qt::CustomizeWindowHint should use a customized window
- // allowing us to select if there is a close button. In practice this doesn't
- // seem to work. We will ignore pressing the close button if unlockByButton == true
- Qt::WindowFlags flags =
- this->windowFlags() | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowMinimizeButtonHint;
- if (m_allowClose)
- flags |= Qt::WindowCloseButtonHint;
- this->setWindowFlags(flags);
+ // Supposedly the Qt::CustomizeWindowHint should use a customized window
+ // allowing us to select if there is a close button. In practice this doesn't
+ // seem to work. We will ignore pressing the close button if unlockByButton == true
+ Qt::WindowFlags flags =
+ this->windowFlags() | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowMinimizeButtonHint;
+ if (m_allowClose)
+ flags |= Qt::WindowCloseButtonHint;
+ this->setWindowFlags(flags);
+}
+
+WaitingOnCloseDialog::~WaitingOnCloseDialog()
+{
+ delete ui;
}
-WaitingOnCloseDialog::~WaitingOnCloseDialog() { delete ui; }
-void WaitingOnCloseDialog::setProcessName(const QString& name) { ui->processLabel->setText(name); }
+void WaitingOnCloseDialog::setProcessName(const QString &name)
+{
+ ui->processLabel->setText(name);
+}
-void WaitingOnCloseDialog::on_closeButton_clicked() { unlock(); }
+void WaitingOnCloseDialog::on_closeButton_clicked()
+{
+ unlock();
+}
-void WaitingOnCloseDialog::on_cancelButton_clicked() {
- cancel();
- unlock();
+void WaitingOnCloseDialog::on_cancelButton_clicked()
+{
+ cancel();
+ unlock();
}
void WaitingOnCloseDialog::unlock() {
- LockedDialogBase::unlock();
- ui->label->setText("unlocking may take a few seconds");
- ui->closeButton->setEnabled(false);
- ui->cancelButton->setEnabled(false);
+ LockedDialogBase::unlock();
+ ui->label->setText("unlocking may take a few seconds");
+ ui->closeButton->setEnabled(false);
+ ui->cancelButton->setEnabled(false);
}
diff --git a/src/waitingonclosedialog.h b/src/waitingonclosedialog.h
index ca0f4d2b..6650c390 100644
--- a/src/waitingonclosedialog.h
+++ b/src/waitingonclosedialog.h
@@ -22,32 +22,35 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "lockeddialogbase.h"
namespace Ui {
-class WaitingOnCloseDialog;
+ class WaitingOnCloseDialog;
}
/**
* Similar to the LockedDialog but used for waiting on running process during
* a process close request which requries a slightly different dialog.
**/
-class WaitingOnCloseDialog : public LockedDialogBase {
+class WaitingOnCloseDialog : public LockedDialogBase
+{
Q_OBJECT
public:
- explicit WaitingOnCloseDialog(QWidget* parent = 0);
- ~WaitingOnCloseDialog();
+ explicit WaitingOnCloseDialog(QWidget *parent = 0);
+ ~WaitingOnCloseDialog();
- bool canceled() const { return m_Canceled; }
+ bool canceled() const { return m_Canceled; }
- void setProcessName(const QString& name) override;
+ void setProcessName(const QString &name) override;
protected:
- void unlock() override;
+
+ void unlock() override;
private slots:
- void on_closeButton_clicked();
- void on_cancelButton_clicked();
+ void on_closeButton_clicked();
+ void on_cancelButton_clicked();
private:
- Ui::WaitingOnCloseDialog* ui;
+
+ Ui::WaitingOnCloseDialog *ui;
};