summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikaël Capelle <capelle.mikael@gmail.com>2020-12-30 22:56:34 +0100
committerMikaël Capelle <capelle.mikael@gmail.com>2021-01-02 15:38:17 +0100
commit8a88421fd9748f64163f18d8b89ea9d651402014 (patch)
treec4720283a1d246cc5054fdbbcff7780bb17a1b28
parent07c2badd174059f7cc4ca404c22c6741b679cc7f (diff)
Start moving modlist context menu actions to separate structures.
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/mainwindow.cpp337
-rw-r--r--src/mainwindow.h7
-rw-r--r--src/modlistcontextmenu.cpp273
-rw-r--r--src/modlistcontextmenu.h39
-rw-r--r--src/modlistview.cpp9
-rw-r--r--src/modlistview.h9
-rw-r--r--src/modlistviewactions.cpp339
-rw-r--r--src/modlistviewactions.h55
-rw-r--r--src/organizercore.cpp12
-rw-r--r--src/organizercore.h5
11 files changed, 742 insertions, 345 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 93b9e768..4c7bcd46 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -138,6 +138,8 @@ add_filter(NAME src/modlist GROUPS
modlistsortproxy
modlistbypriorityproxy
modlistview
+ modlistviewactions
+ modlistcontextmenu
)
add_filter(NAME src/plugins GROUPS
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index bafe05f5..58061c96 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -58,8 +58,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "filedialogmemory.h"
#include "tutorialmanager.h"
#include "selectiondialog.h"
-#include "csvbuilder.h"
-#include "savetextasdialog.h"
#include "problemsdialog.h"
#include "previewdialog.h"
#include "browserdialog.h"
@@ -86,6 +84,8 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "envshortcut.h"
#include "browserdialog.h"
#include "modlistbypriorityproxy.h"
+#include "modlistviewactions.h"
+#include "modlistcontextmenu.h"
#include "directoryrefresher.h"
#include "shared/directoryentry.h"
@@ -392,9 +392,7 @@ MainWindow::MainWindow(Settings &settings
m_LinkStartMenu = linkMenu->addAction(QIcon(":/MO/gui/link"), tr("Start Menu"), this, SLOT(linkMenu()));
ui->linkButton->setMenu(linkMenu);
- QMenu *listOptionsMenu = new QMenu(ui->listOptionsBtn);
- initModListContextMenu(listOptionsMenu);
- ui->listOptionsBtn->setMenu(listOptionsMenu);
+ ui->listOptionsBtn->setMenu(new ModListGlobalContextMenu(m_OrganizerCore, ui->modList, ui->listOptionsBtn));
ui->openFolderMenu->setMenu(openFolderMenu());
@@ -537,7 +535,7 @@ MainWindow::MainWindow(Settings &settings
void MainWindow::setupModList()
{
- ui->modList->setup(m_OrganizerCore, ui);
+ ui->modList->setup(m_OrganizerCore, new ModListViewActions(m_OrganizerCore, *m_Filters, m_CategoryFactory, this, ui->modList), ui);
connect(ui->modList, &ModListView::removeSelectedMods, [=]() { removeMod_clicked(-1); });
@@ -2076,30 +2074,6 @@ void MainWindow::on_tabWidget_currentChanged(int index)
}
}
-
-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(" "))));
- }
-
- if (fileName.isEmpty()) {
- return;
- } else {
- m_OrganizerCore.installMod(fileName, false, nullptr, QString());
- }
- } catch (const std::exception &e) {
- reportError(e.what());
- }
-}
-
void MainWindow::on_startButton_clicked()
{
const Executable* selectedExecutable = getSelectedExecutable();
@@ -2192,7 +2166,7 @@ void MainWindow::tutorialTriggered()
void MainWindow::on_actionInstallMod_triggered()
{
- installMod();
+ ui->modList->actions().installMod();
}
void MainWindow::on_action_Refresh_triggered()
@@ -2328,7 +2302,7 @@ void MainWindow::showError(const QString &message)
void MainWindow::installMod_clicked()
{
- installMod();
+ ui->modList->actions().installMod();
}
void MainWindow::modRenamed(const QString &oldName, const QString &newName)
@@ -3173,87 +3147,6 @@ void MainWindow::information_clicked(int modIndex)
}
}
-void MainWindow::createEmptyMod_clicked(int modIndex)
-{
- 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;
- }
- }
-
- if (m_OrganizerCore.modList()->getMod(name) != nullptr) {
- reportError(tr("A mod with this name already exists"));
- return;
- }
-
- int newPriority = -1;
- if (modIndex >= 0 && ui->modList->sortColumn() == ModList::COL_PRIORITY) {
- newPriority = m_OrganizerCore.currentProfile()->getModPriority(modIndex);
- }
-
- IModInterface *newMod = m_OrganizerCore.createMod(name);
- if (newMod == nullptr) {
- return;
- }
-
- m_OrganizerCore.refresh();
-
- if (newPriority >= 0) {
- m_OrganizerCore.modList()->changeModPriority(ModInfo::getIndex(name), newPriority);
- }
-}
-
-void MainWindow::createSeparator_clicked(int modIndex)
-{
- GuessedValue<QString> name;
- name.setFilter(&fixDirectoryName);
- while (name->isEmpty())
- {
- bool ok;
- name.update(QInputDialog::getText(this, tr("Create Separator..."),
- tr("This will create a new separator.\n"
- "Please enter a name:"), QLineEdit::Normal, "", &ok),
- GUESS_USER);
- if (!ok) { return; }
- }
- if (m_OrganizerCore.modList()->getMod(name) != nullptr)
- {
- reportError(tr("A separator with this name already exists"));
- return;
- }
- name->append("_separator");
- if (m_OrganizerCore.modList()->getMod(name) != nullptr)
- {
- return;
- }
-
- int newPriority = -1;
- if (modIndex >= 0 && ui->modList->sortColumn() == ModList::COL_PRIORITY)
- {
- newPriority = m_OrganizerCore.currentProfile()->getModPriority(modIndex);
- }
-
- if (m_OrganizerCore.createMod(name) == nullptr) { return; }
- m_OrganizerCore.refresh();
-
- if (newPriority >= 0)
- {
- m_OrganizerCore.modList()->changeModPriority(ModInfo::getIndex(name), newPriority);
- }
-
- if (auto c=m_OrganizerCore.settings().colors().previousSeparatorColor()) {
- ModInfo::getByIndex(ModInfo::getIndex(name))->setColor(*c);
- }
-}
-
void MainWindow::setColor_clicked(int modIndex)
{
auto& settings = m_OrganizerCore.settings();
@@ -3917,22 +3810,6 @@ void MainWindow::setPrimaryCategoryCandidates(QMenu *primaryCategoryMenu,
}
}
-void MainWindow::enableVisibleMods()
-{
- if (QMessageBox::question(nullptr, tr("Confirm"), tr("Really enable all visible mods?"),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- ui->modList->enableAllVisible();
- }
-}
-
-void MainWindow::disableVisibleMods()
-{
- if (QMessageBox::question(nullptr, tr("Confirm"), tr("Really disable all visible mods?"),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- ui->modList->disableAllVisible();
- }
-}
-
void MainWindow::openInstanceFolder()
{
QString dataPath = qApp->property("dataPath").toString();
@@ -3998,175 +3875,6 @@ void MainWindow::openMyGamesFolder()
shell::Explore(m_OrganizerCore.managedGame()->documentsDirectory());
}
-
-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);
-
- QDialog selection(this);
- QGridLayout *grid = new QGridLayout;
- selection.setWindowTitle(tr("Export to csv"));
-
- QLabel *csvDescription = new QLabel();
- csvDescription->setText(tr("CSV (Comma Separated Values) is a format that can be imported in programs like Excel to create a spreadsheet.\nYou can also use online editors and converters instead."));
- grid->addWidget(csvDescription);
-
- 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"));
-
- QVBoxLayout *vbox = new QVBoxLayout;
- vbox->addWidget(all);
- vbox->addWidget(active);
- vbox->addWidget(visible);
- vbox->addStretch(1);
- groupBoxRows->setLayout(vbox);
-
-
-
- grid->addWidget(groupBoxRows);
-
- 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_Note = new QCheckBox(tr("Notes_column"));
- QCheckBox *mod_Status = new QCheckBox(tr("Mod_Status"));
- mod_Status->setChecked(true);
- 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"));
-
- QVBoxLayout *vbox1 = new QVBoxLayout;
- vbox1->addWidget(mod_Priority);
- vbox1->addWidget(mod_Name);
- vbox1->addWidget(mod_Status);
- vbox1->addWidget(mod_Note);
- 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);
-
- 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()));
-
- grid->addWidget(buttons);
-
- selection.setLayout(grid);
-
-
- if (selection.exec() == QDialog::Accepted) {
-
- 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_Status->isChecked())
- fields.push_back(std::make_pair(QString("#Mod_Status"), CSVBuilder::TYPE_STRING));
- if (mod_Name->isChecked())
- fields.push_back(std::make_pair(QString("#Mod_Name"), CSVBuilder::TYPE_STRING));
- if (mod_Note->isChecked())
- fields.push_back(std::make_pair(QString("#Note"), 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);
-
- builder.writeHeader();
-
- auto indexesByPriority = m_OrganizerCore.currentProfile()->getAllIndexesByPriority();
- for (auto& iter : indexesByPriority) {
- ModInfo::Ptr info = ModInfo::getByIndex(iter.second);
- bool enabled = m_OrganizerCore.currentProfile()->modEnabled(iter.second);
- if ((selectedRowID == 1) && !enabled) {
- continue;
- }
- else if ((selectedRowID == 2) && !ui->modList->isModVisible(iter.second)) {
- 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(iter.first, 4, 10, QChar('0')));
- if (mod_Status->isChecked())
- builder.setRowField("#Mod_Status", (enabled) ? "+" : "-");
- if (mod_Name->isChecked())
- builder.setRowField("#Mod_Name", info->name());
- if (mod_Note->isChecked())
- builder.setRowField("#Note", QString("%1").arg(info->comments().remove(',')));
- if (primary_Category->isChecked())
- builder.setRowField("#Primary_Category", (m_CategoryFactory.categoryExists(info->primaryCategory())) ? m_CategoryFactory.getCategoryNameByID(info->primaryCategory()) : "");
- if (nexus_ID->isChecked())
- builder.setRowField("#Nexus_ID", info->nexusId());
- if (mod_Nexus_URL->isChecked())
- builder.setRowField("#Mod_Nexus_URL",(info->nexusId()>0)? NexusInterface::instance().getModURL(info->nexusId(), info->gameName()) : "");
- if (mod_Version->isChecked())
- builder.setRowField("#Mod_Version", info->version().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->installationFile());
-
- builder.writeRow();
- }
- }
-
- SaveTextAsDialog saveDialog(this);
- saveDialog.setText(buffer.data());
- saveDialog.exec();
- }
- catch (const std::exception &e) {
- reportError(tr("export failed: %1").arg(e.what()));
- }
- }
-}
-
static void addMenuAsPushButton(QMenu *menu, QMenu *subMenu)
{
QPushButton *pushBtn = new QPushButton(subMenu->title());
@@ -4205,27 +3913,6 @@ QMenu *MainWindow::openFolderMenu()
return FolderMenu;
}
-void MainWindow::initModListContextMenu(QMenu *menu)
-{
- menu->addAction(tr("Install Mod..."), [&]() { installMod_clicked(); });
- menu->addAction(tr("Create empty mod"), [&]() { createEmptyMod_clicked(-1); });
- menu->addAction(tr("Create Separator"), [&]() { createSeparator_clicked(-1); });
-
- if (ui->modList->hasCollapsibleSeparators()) {
- menu->addSeparator();
- menu->addAction(tr("Collapse all"), ui->modList, &QTreeView::collapseAll);
- menu->addAction(tr("Expand all"), ui->modList, &QTreeView::expandAll);
- }
-
- menu->addSeparator();
-
- menu->addAction(tr("Enable all visible"), [&]() { enableVisibleMods(); });
- menu->addAction(tr("Disable all visible"), [&]() { disableVisibleMods(); });
- menu->addAction(tr("Check for updates"), [&]() { checkModsForUpdates(); });
- menu->addAction(tr("Refresh"), &m_OrganizerCore, &OrganizerCore::profileRefresh);
- menu->addAction(tr("Export to csv..."), [&]() { exportModListCSV(); });
-}
-
void MainWindow::addModSendToContextMenu(QMenu *menu)
{
if (ui->modList->sortColumn() != ModList::COL_PRIORITY)
@@ -4269,15 +3956,12 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos)
if (modIndex == -1) {
// no selection
- QMenu menu(this);
- initModListContextMenu(&menu);
- menu.exec(modList->viewport()->mapToGlobal(pos));
+ ModListGlobalContextMenu(m_OrganizerCore, ui->modList).exec(modList->viewport()->mapToGlobal(pos));
}
else {
QMenu menu(this);
- QMenu *allMods = new QMenu(&menu);
- initModListContextMenu(allMods);
+ QMenu *allMods = new ModListGlobalContextMenu(m_OrganizerCore, ui->modList, this);
allMods->setTitle(tr("All Mods"));
menu.addMenu(allMods);
@@ -4711,10 +4395,7 @@ void MainWindow::languageChange(const QString &newLanguage)
m_DownloadsTab->update();
}
- QMenu *listOptionsMenu = new QMenu(ui->listOptionsBtn);
- initModListContextMenu(listOptionsMenu);
- ui->listOptionsBtn->setMenu(listOptionsMenu);
-
+ ui->listOptionsBtn->setMenu(new ModListGlobalContextMenu(m_OrganizerCore, ui->modList, this));
ui->openFolderMenu->setMenu(openFolderMenu());
}
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 9e9e9591..a49c12fe 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -207,7 +207,6 @@ private:
bool refreshProfiles(bool selectProfile = true);
void refreshExecutablesList();
- void installMod(QString fileName = "");
bool modifyExecutablesDialog(int selection);
void displayModInformation(int row, ModInfoTabIDs tab=ModInfoTabIDs::None);
@@ -251,7 +250,6 @@ private:
bool createBackup(const QString &filePath, const QDateTime &time);
QString queryRestore(const QString &filePath);
- void initModListContextMenu(QMenu *menu);
void addModSendToContextMenu(QMenu *menu);
void addPluginSendToContextMenu(QMenu *menu);
@@ -358,8 +356,6 @@ private slots:
// modlist context menu
void installMod_clicked();
- void createEmptyMod_clicked(int modIndex);
- void createSeparator_clicked(int modIndex);
void restoreBackup_clicked(int modIndex);
void renameMod_clicked();
void removeMod_clicked(int modIndex);
@@ -473,9 +469,6 @@ private slots:
void trackMod(ModInfo::Ptr mod, bool doTrack);
void cancelModListEditor();
- void enableVisibleMods();
- void disableVisibleMods();
- void exportModListCSV();
void openInstanceFolder();
void openLogsFolder();
void openInstallFolder();
diff --git a/src/modlistcontextmenu.cpp b/src/modlistcontextmenu.cpp
new file mode 100644
index 00000000..5b45a217
--- /dev/null
+++ b/src/modlistcontextmenu.cpp
@@ -0,0 +1,273 @@
+#include "modlistcontextmenu.h"
+
+#include <report.h>
+
+#include "modlist.h"
+#include "modlistview.h"
+#include "modlistviewactions.h"
+#include "organizercore.h"
+
+using namespace MOBase;
+
+ModListGlobalContextMenu::ModListGlobalContextMenu(OrganizerCore& core, ModListView* view, QWidget* parent)
+ : QMenu(parent)
+{
+ addAction(tr("Install Mod..."), [=]() { view->actions().installMod(); });
+ addAction(tr("Create empty mod"), [=]() { view->actions().createEmptyMod(-1); });
+ addAction(tr("Create Separator"), [=]() { view->actions().createSeparator(-1); });
+
+ if (view->hasCollapsibleSeparators()) {
+ addSeparator();
+ addAction(tr("Collapse all"), view, &QTreeView::collapseAll);
+ addAction(tr("Expand all"), view, &QTreeView::expandAll);
+ }
+
+ addSeparator();
+
+ addAction(tr("Enable all visible"), [=]() {
+ if (QMessageBox::question(view, tr("Confirm"), tr("Really enable all visible mods?"),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ view->enableAllVisible();
+ }
+ });
+ addAction(tr("Disable all visible"), [=]() {
+ if (QMessageBox::question(view, tr("Confirm"), tr("Really disable all visible mods?"),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ view->disableAllVisible();
+ }
+ });
+ addAction(tr("Check for updates"), [=]() { view->actions().checkModsForUpdates(); });
+ addAction(tr("Refresh"), &core, &OrganizerCore::profileRefresh);
+ addAction(tr("Export to csv..."), [=]() { view->actions().exportModListCSV(); });
+}
+
+ModListContextMenu::ModListContextMenu(OrganizerCore& core, const QModelIndexList& index, ModListView* modListView) :
+ QMenu(modListView)
+ , m_core(core)
+ , m_index(index)
+{
+ // TODO: Change this.
+ QModelIndex contextIdx = index.at(0);
+ int contextColumn = contextIdx.column();
+ int modIndex = contextIdx.data(ModList::IndexRole).toInt();
+
+ try {
+ /*
+ if (modIndex == -1) {
+ // no selection
+ QMenu menu(this);
+ initModListContextMenu(&menu);
+ menu.exec(modList->viewport()->mapToGlobal(pos));
+ }
+ else {
+ QMenu menu(this);
+
+ QMenu* allMods = new QMenu(&menu);
+ initModListContextMenu(allMods);
+ allMods->setTitle(tr("All Mods"));
+ menu.addMenu(allMods);
+
+ if (ui->modList->hasCollapsibleSeparators()) {
+ menu.addAction(tr("Collapse all"), ui->modList, &QTreeView::collapseAll);
+ menu.addAction(tr("Expand all"), ui->modList, &QTreeView::expandAll);
+ }
+
+ menu.addSeparator();
+
+ ModInfo::Ptr info = ModInfo::getByIndex(modIndex);
+ std::vector<ModInfo::EFlag> flags = info->getFlags();
+
+ // context menu for overwrites
+ 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.syncOverwrite(); });
+ menu.addAction(tr("Create Mod..."), [=]() { createModFromOverwrite(); });
+ menu.addAction(tr("Move content to Mod..."), [=]() { moveOverwriteContentToExistingMod(); });
+ menu.addAction(tr("Clear Overwrite..."), [=]() { clearOverwrite(); });
+ }
+ menu.addAction(tr("Open in Explorer"), [=]() { openExplorer_clicked(modIndex); });
+ }
+
+ // context menu for mod backups
+ else if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP) != flags.end()) {
+ menu.addAction(tr("Restore Backup"), [=]() { restoreBackup_clicked(modIndex); });
+ menu.addAction(tr("Remove Backup..."), [=]() { removeMod_clicked(modIndex); });
+ menu.addSeparator();
+ if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_INVALID) != flags.end()) {
+ menu.addAction(tr("Ignore missing data"), [=]() { ignoreMissingData_clicked(modIndex); });
+ }
+ if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_ALTERNATE_GAME) != flags.end()) {
+ menu.addAction(tr("Mark as converted/working"), [=]() { markConverted_clicked(modIndex); });
+ }
+ menu.addSeparator();
+ if (info->nexusId() > 0) {
+ menu.addAction(tr("Visit on Nexus"), [=]() { visitOnNexus_clicked(modIndex); });
+ }
+
+ const auto url = info->parseCustomURL();
+ if (url.isValid()) {
+ menu.addAction(tr("Visit on %1").arg(url.host()), [=]() { visitWebPage_clicked(modIndex); });
+ }
+
+ menu.addAction(tr("Open in Explorer"), [=]() { openExplorer_clicked(modIndex); });
+ }
+
+ // separator
+ else if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_SEPARATOR) != flags.end()) {
+ menu.addSeparator();
+ QMenu* addRemoveCategoriesMenu = new QMenu(tr("Change Categories"), &menu);
+ populateMenuCategories(modIndex, addRemoveCategoriesMenu, 0);
+ connect(addRemoveCategoriesMenu, &QMenu::aboutToHide, [=]() { addRemoveCategories_MenuHandler(addRemoveCategoriesMenu, modIndex, contextIdx); });
+ addMenuAsPushButton(&menu, addRemoveCategoriesMenu);
+ QMenu* primaryCategoryMenu = new QMenu(tr("Primary Category"), &menu);
+ connect(primaryCategoryMenu, &QMenu::aboutToShow, [=]() { setPrimaryCategoryCandidates(primaryCategoryMenu, info); });
+ addMenuAsPushButton(&menu, primaryCategoryMenu);
+ menu.addSeparator();
+ menu.addAction(tr("Rename Separator..."), [=]() { renameMod_clicked(); });
+ menu.addAction(tr("Remove Separator..."), [=]() { removeMod_clicked(modIndex); });
+ menu.addSeparator();
+ addModSendToContextMenu(&menu);
+ menu.addAction(tr("Select Color..."), [=]() { setColor_clicked(modIndex); });
+
+ if (info->color().isValid()) {
+ menu.addAction(tr("Reset Color"), [=]() { resetColor_clicked(modIndex); });
+ }
+
+ menu.addSeparator();
+ }
+
+ // foregin
+ else if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_FOREIGN) != flags.end()) {
+ addModSendToContextMenu(&menu);
+ }
+
+ // regular
+ else {
+ QMenu* addRemoveCategoriesMenu = new QMenu(tr("Change Categories"), &menu);
+ populateMenuCategories(modIndex, addRemoveCategoriesMenu, 0);
+ connect(addRemoveCategoriesMenu, &QMenu::aboutToHide, [=]() { addRemoveCategories_MenuHandler(addRemoveCategoriesMenu, modIndex, contextIdx); });
+ addMenuAsPushButton(&menu, addRemoveCategoriesMenu);
+
+ QMenu* primaryCategoryMenu = new QMenu(tr("Primary Category"), &menu);
+ connect(primaryCategoryMenu, &QMenu::aboutToShow, [=]() { setPrimaryCategoryCandidates(primaryCategoryMenu, info); });
+ addMenuAsPushButton(&menu, primaryCategoryMenu);
+
+ menu.addSeparator();
+
+ if (info->downgradeAvailable()) {
+ menu.addAction(tr("Change versioning scheme"), [=]() { changeVersioningScheme(modIndex); });
+ }
+
+ if (info->nexusId() > 0)
+ menu.addAction(tr("Force-check updates"), [=]() { checkModUpdates_clicked(modIndex); });
+ if (info->updateIgnored()) {
+ menu.addAction(tr("Un-ignore update"), [=]() { unignoreUpdate(modIndex); });
+ }
+ else {
+ if (info->updateAvailable() || info->downgradeAvailable()) {
+ menu.addAction(tr("Ignore update"), [=]() { ignoreUpdate(modIndex); });
+ }
+ }
+ menu.addSeparator();
+
+ menu.addAction(tr("Enable selected"), [=]() { enableSelectedMods_clicked(); });
+ menu.addAction(tr("Disable selected"), [=]() { disableSelectedMods_clicked(); });
+
+ menu.addSeparator();
+
+ addModSendToContextMenu(&menu);
+
+ menu.addAction(tr("Rename Mod..."), [=]() { renameMod_clicked(); });
+ menu.addAction(tr("Reinstall Mod"), [=]() { reinstallMod_clicked(modIndex); });
+ menu.addAction(tr("Remove Mod..."), [=]() { removeMod_clicked(modIndex); });
+ menu.addAction(tr("Create Backup"), [=]() { backupMod_clicked(modIndex); });
+
+ if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_HIDDEN_FILES) != flags.end()) {
+ menu.addAction(tr("Restore hidden files"), [=]() { restoreHiddenFiles_clicked(modIndex); });
+ }
+
+ menu.addSeparator();
+
+ if (contextColumn == ModList::COL_NOTES) {
+ menu.addAction(tr("Select Color..."), [=]() { setColor_clicked(modIndex); });
+ if (info->color().isValid()) {
+ menu.addAction(tr("Reset Color"), [=]() { resetColor_clicked(modIndex); });
+ }
+ menu.addSeparator();
+ }
+
+ if (info->nexusId() > 0 && Settings::instance().nexus().endorsementIntegration()) {
+ switch (info->endorsedState()) {
+ case EndorsedState::ENDORSED_TRUE: {
+ menu.addAction(tr("Un-Endorse"), [=]() { unendorse_clicked(); });
+ } break;
+ case EndorsedState::ENDORSED_FALSE: {
+ menu.addAction(tr("Endorse"), [=]() { endorse_clicked(); });
+ menu.addAction(tr("Won't endorse"), [=]() { dontendorse_clicked(modIndex); });
+ } break;
+ case EndorsedState::ENDORSED_NEVER: {
+ menu.addAction(tr("Endorse"), [=]() { endorse_clicked(); });
+ } break;
+ default: {
+ QAction* action = new QAction(tr("Endorsement state unknown"), &menu);
+ action->setEnabled(false);
+ menu.addAction(action);
+ } break;
+ }
+ }
+
+ if (info->nexusId() > 0 && Settings::instance().nexus().trackedIntegration()) {
+ switch (info->trackedState()) {
+ case TrackedState::TRACKED_FALSE: {
+ menu.addAction(tr("Start tracking"), [=]() { track_clicked(); });
+ } break;
+ case TrackedState::TRACKED_TRUE: {
+ menu.addAction(tr("Stop tracking"), [=]() { untrack_clicked(); });
+ } break;
+ default: {
+ QAction* action = new QAction(tr("Tracked state unknown"), &menu);
+ action->setEnabled(false);
+ menu.addAction(action);
+ } break;
+ }
+ }
+
+ 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"), [=]() { ignoreMissingData_clicked(modIndex); });
+ }
+
+ if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_ALTERNATE_GAME) != flags.end()) {
+ menu.addAction(tr("Mark as converted/working"), [=]() { markConverted_clicked(modIndex); });
+ }
+
+ menu.addSeparator();
+
+ if (info->nexusId() > 0) {
+ menu.addAction(tr("Visit on Nexus"), [=]() { visitOnNexus_clicked(modIndex); });
+ }
+
+ const auto url = info->parseCustomURL();
+ if (url.isValid()) {
+ menu.addAction(tr("Visit on %1").arg(url.host()), [=]() { visitWebPage_clicked(modIndex); });
+ }
+
+ menu.addAction(tr("Open in Explorer"), [&, modIndex]() { openExplorer_clicked(modIndex); });
+ }
+
+ if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_FOREIGN) == flags.end()) {
+ QAction* infoAction = menu.addAction(tr("Information..."), [=]() { information_clicked(modIndex); });
+ menu.setDefaultAction(infoAction);
+ }
+ }
+ */
+ }
+ catch (const std::exception& e) {
+ reportError(tr("Exception: ").arg(e.what()));
+ }
+ catch (...) {
+ reportError(tr("Unknown exception"));
+ }
+}
diff --git a/src/modlistcontextmenu.h b/src/modlistcontextmenu.h
new file mode 100644
index 00000000..bc72fbdf
--- /dev/null
+++ b/src/modlistcontextmenu.h
@@ -0,0 +1,39 @@
+#ifndef MODLISTCONTEXTMENU_H
+#define MODLISTCONTEXTMENU_H
+
+#include <vector>
+
+#include <QMenu>
+#include <QModelIndex>
+#include <QTreeView>
+
+class ModListView;
+class OrganizerCore;
+
+class ModListGlobalContextMenu : public QMenu
+{
+ Q_OBJECT
+public:
+
+ ModListGlobalContextMenu(OrganizerCore& core, ModListView* modListView, QWidget* parent = nullptr);
+
+};
+
+class ModListContextMenu : public QMenu
+{
+ Q_OBJECT
+
+private:
+
+ friend class ModListView;
+
+ // creates a new context menu that will act on the given mod list
+ // index (those should be index from the modlist)
+ ModListContextMenu(OrganizerCore& core, const QModelIndexList& index, ModListView* modListView);
+
+ OrganizerCore& m_core;
+ QModelIndexList m_index;
+
+};
+
+#endif
diff --git a/src/modlistview.cpp b/src/modlistview.cpp
index b36a77d9..f8192758 100644
--- a/src/modlistview.cpp
+++ b/src/modlistview.cpp
@@ -17,6 +17,7 @@
#include "log.h"
#include "modflagicondelegate.h"
#include "modconflicticondelegate.h"
+#include "modlistviewactions.h"
#include "modlistdropinfo.h"
#include "genericicondelegate.h"
#include "shared/directoryentry.h"
@@ -118,6 +119,11 @@ int ModListView::sortColumn() const
return m_sortProxy ? m_sortProxy->sortColumn() : -1;
}
+ModListViewActions& ModListView::actions() const
+{
+ return *m_actions;
+}
+
int ModListView::nextMod(int modIndex) const
{
const QModelIndex start = indexModelToView(m_core->modList()->index(modIndex, 0));
@@ -634,10 +640,11 @@ void ModListView::updateGroupByProxy(int groupIndex)
}
}
-void ModListView::setup(OrganizerCore& core, Ui::MainWindow* mwui)
+void ModListView::setup(OrganizerCore& core, ModListViewActions* actions, Ui::MainWindow* mwui)
{
// attributes
m_core = &core;
+ m_actions = actions;
ui = { mwui->groupCombo, mwui->activeModsCounter, mwui->modFilterEdit, mwui->clearFiltersButton };
connect(m_core, &OrganizerCore::modInstalled, this, &ModListView::onModInstalled);
diff --git a/src/modlistview.h b/src/modlistview.h
index 8e37161b..d5eea54f 100644
--- a/src/modlistview.h
+++ b/src/modlistview.h
@@ -13,9 +13,11 @@
namespace Ui { class MainWindow; }
+class FilterList;
class OrganizerCore;
class Profile;
class ModListByPriorityProxy;
+class ModListViewActions;
class ModListView : public QTreeView
{
@@ -35,7 +37,7 @@ public:
explicit ModListView(QWidget* parent = 0);
void setModel(QAbstractItemModel* model) override;
- void setup(OrganizerCore& core, Ui::MainWindow* mwui);
+ void setup(OrganizerCore& core, ModListViewActions* actions, Ui::MainWindow* mwui);
// set the current profile
//
@@ -49,6 +51,10 @@ public:
//
int sortColumn() const;
+ // retrieve the actions from the view
+ //
+ ModListViewActions& actions() const;
+
// retrieve the next/previous mod in the current view, the given index
// should be a mod index (not a model row), and the return value will be
// a mod index or -1 if no mod was found
@@ -180,6 +186,7 @@ private:
OrganizerCore* m_core;
ModListViewUi ui;
+ ModListViewActions* m_actions;
ModListSortProxy* m_sortProxy;
ModListByPriorityProxy* m_byPriorityProxy;
diff --git a/src/modlistviewactions.cpp b/src/modlistviewactions.cpp
new file mode 100644
index 00000000..8b234b81
--- /dev/null
+++ b/src/modlistviewactions.cpp
@@ -0,0 +1,339 @@
+#include "modlistviewactions.h"
+
+#include <QGridLayout>
+#include <QGroupBox>
+#include <QInputDialog>
+#include <QLabel>
+
+#include <report.h>
+
+#include "categories.h"
+#include "filedialogmemory.h"
+#include "filterlist.h"
+#include "modlist.h"
+#include "modlistview.h"
+#include "nexusinterface.h"
+#include "nxmaccessmanager.h"
+#include "savetextasdialog.h"
+#include "organizercore.h"
+#include "csvbuilder.h"
+
+using namespace MOBase;
+
+ModListViewActions::ModListViewActions(
+ OrganizerCore& core, FilterList& filters, CategoryFactory& categoryFactory, QObject* nxmReceiver, ModListView* view) :
+ QObject(view)
+ , m_core(core)
+ , m_filters(filters)
+ , m_categories(categoryFactory)
+ , m_receiver(nxmReceiver)
+ , m_view(view)
+{
+
+}
+
+void ModListViewActions::installMod(const QString& archivePath) const
+{
+ try {
+ QString path = archivePath;
+ if (path.isEmpty()) {
+ QStringList extensions = m_core.installationManager()->getSupportedExtensions();
+ for (auto iter = extensions.begin(); iter != extensions.end(); ++iter) {
+ *iter = "*." + *iter;
+ }
+
+ path = FileDialogMemory::getOpenFileName("installMod", m_view, tr("Choose Mod"), QString(),
+ tr("Mod Archive").append(QString(" (%1)").arg(extensions.join(" "))));
+ }
+
+ if (path.isEmpty()) {
+ return;
+ }
+ else {
+ m_core.installMod(path, false, nullptr, QString());
+ }
+ }
+ catch (const std::exception& e) {
+ reportError(e.what());
+ }
+}
+
+void ModListViewActions::createEmptyMod(int modIndex) const
+{
+ GuessedValue<QString> name;
+ name.setFilter(&fixDirectoryName);
+
+ while (name->isEmpty()) {
+ bool ok;
+ name.update(QInputDialog::getText(m_view, 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_core.modList()->getMod(name) != nullptr) {
+ reportError(tr("A mod with this name already exists"));
+ return;
+ }
+
+ int newPriority = -1;
+ if (modIndex >= 0 && m_view->sortColumn() == ModList::COL_PRIORITY) {
+ newPriority = m_core.currentProfile()->getModPriority(modIndex);
+ }
+
+ IModInterface* newMod = m_core.createMod(name);
+ if (newMod == nullptr) {
+ return;
+ }
+
+ m_core.refresh();
+
+ if (newPriority >= 0) {
+ m_core.modList()->changeModPriority(ModInfo::getIndex(name), newPriority);
+ }
+}
+
+void ModListViewActions::createSeparator(int modIndex) const
+{
+ GuessedValue<QString> name;
+ name.setFilter(&fixDirectoryName);
+ while (name->isEmpty())
+ {
+ bool ok;
+ name.update(QInputDialog::getText(m_view, tr("Create Separator..."),
+ tr("This will create a new separator.\n"
+ "Please enter a name:"), QLineEdit::Normal, "", &ok),
+ GUESS_USER);
+ if (!ok) { return; }
+ }
+ if (m_core.modList()->getMod(name) != nullptr)
+ {
+ reportError(tr("A separator with this name already exists"));
+ return;
+ }
+ name->append("_separator");
+ if (m_core.modList()->getMod(name) != nullptr)
+ {
+ return;
+ }
+
+ int newPriority = -1;
+ if (modIndex >= 0 && m_view->sortColumn() == ModList::COL_PRIORITY)
+ {
+ newPriority = m_core.currentProfile()->getModPriority(modIndex);
+ }
+
+ if (m_core.createMod(name) == nullptr) { return; }
+ m_core.refresh();
+
+ if (newPriority >= 0)
+ {
+ m_core.modList()->changeModPriority(ModInfo::getIndex(name), newPriority);
+ }
+
+ if (auto c = m_core.settings().colors().previousSeparatorColor()) {
+ ModInfo::getByIndex(ModInfo::getIndex(name))->setColor(*c);
+ }
+}
+
+void ModListViewActions::checkModsForUpdates() const
+{
+ bool checkingModsForUpdate = false;
+ if (NexusInterface::instance().getAccessManager()->validated()) {
+ checkingModsForUpdate = ModInfo::checkAllForUpdate(&m_core.pluginContainer(), m_receiver);
+ NexusInterface::instance().requestEndorsementInfo(m_receiver, QVariant(), QString());
+ NexusInterface::instance().requestTrackingInfo(m_receiver, QVariant(), QString());
+ } else {
+ QString apiKey;
+ if (GlobalSettings::nexusApiKey(apiKey)) {
+ m_core.doAfterLogin([=] () { checkModsForUpdates(); });
+ NexusInterface::instance().getAccessManager()->apiCheck(apiKey);
+ } else {
+ log::warn("{}", tr("You are not currently authenticated with Nexus. Please do so under Settings -> Nexus."));
+ }
+ }
+
+ bool updatesAvailable = false;
+ for (auto mod : m_core.modList()->allMods()) {
+ ModInfo::Ptr modInfo = ModInfo::getByName(mod);
+ if (modInfo->updateAvailable()) {
+ updatesAvailable = true;
+ break;
+ }
+ }
+
+ if (updatesAvailable || checkingModsForUpdate) {
+ m_view->setFilterCriteria({{
+ ModListSortProxy::TypeSpecial,
+ CategoryFactory::UpdateAvailable,
+ false}
+ });
+
+ m_filters.setSelection({{
+ ModListSortProxy::TypeSpecial,
+ CategoryFactory::UpdateAvailable,
+ false
+ }});
+ }
+}
+
+void ModListViewActions::exportModListCSV() const
+{
+ QDialog selection(m_view);
+ QGridLayout* grid = new QGridLayout;
+ selection.setWindowTitle(tr("Export to csv"));
+
+ QLabel* csvDescription = new QLabel();
+ csvDescription->setText(tr("CSV (Comma Separated Values) is a format that can be imported in programs like Excel to create a spreadsheet.\nYou can also use online editors and converters instead."));
+ grid->addWidget(csvDescription);
+
+ 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"));
+
+ QVBoxLayout* vbox = new QVBoxLayout;
+ vbox->addWidget(all);
+ vbox->addWidget(active);
+ vbox->addWidget(visible);
+ vbox->addStretch(1);
+ groupBoxRows->setLayout(vbox);
+
+ grid->addWidget(groupBoxRows);
+
+ 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_Note = new QCheckBox(tr("Notes_column"));
+ QCheckBox* mod_Status = new QCheckBox(tr("Mod_Status"));
+ mod_Status->setChecked(true);
+ 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"));
+
+ QVBoxLayout* vbox1 = new QVBoxLayout;
+ vbox1->addWidget(mod_Priority);
+ vbox1->addWidget(mod_Name);
+ vbox1->addWidget(mod_Status);
+ vbox1->addWidget(mod_Note);
+ 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);
+
+ 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()));
+
+ grid->addWidget(buttons);
+
+ selection.setLayout(grid);
+
+
+ if (selection.exec() == QDialog::Accepted) {
+
+ 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_Status->isChecked())
+ fields.push_back(std::make_pair(QString("#Mod_Status"), CSVBuilder::TYPE_STRING));
+ if (mod_Name->isChecked())
+ fields.push_back(std::make_pair(QString("#Mod_Name"), CSVBuilder::TYPE_STRING));
+ if (mod_Note->isChecked())
+ fields.push_back(std::make_pair(QString("#Note"), 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);
+
+ builder.writeHeader();
+
+ auto indexesByPriority = m_core.currentProfile()->getAllIndexesByPriority();
+ for (auto& iter : indexesByPriority) {
+ ModInfo::Ptr info = ModInfo::getByIndex(iter.second);
+ bool enabled = m_core.currentProfile()->modEnabled(iter.second);
+ if ((selectedRowID == 1) && !enabled) {
+ continue;
+ }
+ else if ((selectedRowID == 2) && !m_view->isModVisible(iter.second)) {
+ 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(iter.first, 4, 10, QChar('0')));
+ if (mod_Status->isChecked())
+ builder.setRowField("#Mod_Status", (enabled) ? "+" : "-");
+ if (mod_Name->isChecked())
+ builder.setRowField("#Mod_Name", info->name());
+ if (mod_Note->isChecked())
+ builder.setRowField("#Note", QString("%1").arg(info->comments().remove(',')));
+ if (primary_Category->isChecked())
+ builder.setRowField("#Primary_Category", (m_categories.categoryExists(info->primaryCategory())) ? m_categories.getCategoryNameByID(info->primaryCategory()) : "");
+ if (nexus_ID->isChecked())
+ builder.setRowField("#Nexus_ID", info->nexusId());
+ if (mod_Nexus_URL->isChecked())
+ builder.setRowField("#Mod_Nexus_URL", (info->nexusId() > 0) ? NexusInterface::instance().getModURL(info->nexusId(), info->gameName()) : "");
+ if (mod_Version->isChecked())
+ builder.setRowField("#Mod_Version", info->version().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->installationFile());
+
+ builder.writeRow();
+ }
+ }
+
+ SaveTextAsDialog saveDialog(m_view);
+ saveDialog.setText(buffer.data());
+ saveDialog.exec();
+ }
+ catch (const std::exception& e) {
+ reportError(tr("export failed: %1").arg(e.what()));
+ }
+ }
+}
diff --git a/src/modlistviewactions.h b/src/modlistviewactions.h
new file mode 100644
index 00000000..49cffaef
--- /dev/null
+++ b/src/modlistviewactions.h
@@ -0,0 +1,55 @@
+#ifndef MODLISTVIEWACTIONS_H
+#define MODLISTVIEWACTIONS_H
+
+#include <QObject>
+#include <QString>
+
+class CategoryFactory;
+class FilterList;
+class ModListView;
+class OrganizerCore;
+
+class ModListViewActions : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ // the nxmReceiver is a (hopefully temporary) "hack" because it would require a lots of change
+ // to do otherwise since NXM is mostly based on the old Qt signal-slot system
+ //
+ ModListViewActions(
+ OrganizerCore& core,
+ FilterList& filters,
+ CategoryFactory& categoryFactory,
+ QObject* nxmReceiver,
+ ModListView* view);
+
+ // install the mod from the given archive
+ //
+ void installMod(const QString& archivePath = "") const;
+
+ // create an empty mod/a separator before the given mod or at
+ // the end of the list if the index is -1
+ //
+ void createEmptyMod(int modIndex) const;
+ void createSeparator(int modIndex) const;
+
+ // check all mods for update
+ //
+ void checkModsForUpdates() const;
+
+ // start the "Export Mod List" dialog
+ //
+ void exportModListCSV() const;
+
+private:
+
+ OrganizerCore& m_core;
+ FilterList& m_filters;
+ CategoryFactory& m_categories;
+ QObject* m_receiver; // receiver for NXM signals (temporary)
+ ModListView* m_view;
+};
+
+#endif
diff --git a/src/organizercore.cpp b/src/organizercore.cpp
index 1a6083b4..986b6fbb 100644
--- a/src/organizercore.cpp
+++ b/src/organizercore.cpp
@@ -1510,13 +1510,6 @@ void OrganizerCore::requestDownload(const QUrl &url, QNetworkReply *reply)
}
}
-ModListSortProxy *OrganizerCore::createModListProxyModel()
-{
- ModListSortProxy *result = new ModListSortProxy(m_CurrentProfile.get(), this);
- result->setSourceModel(&m_ModList);
- return result;
-}
-
PluginListSortProxy *OrganizerCore::createPluginListProxyModel()
{
PluginListSortProxy *result = new PluginListSortProxy(this);
@@ -1524,6 +1517,11 @@ PluginListSortProxy *OrganizerCore::createPluginListProxyModel()
return result;
}
+PluginContainer& OrganizerCore::pluginContainer() const
+{
+ return *m_PluginContainer;
+}
+
IPluginGame const *OrganizerCore::managedGame() const
{
return m_GamePlugin;
diff --git a/src/organizercore.h b/src/organizercore.h
index 3fb4f20e..e060fbcb 100644
--- a/src/organizercore.h
+++ b/src/organizercore.h
@@ -227,9 +227,12 @@ public:
MOBase::VersionInfo getVersion() const { return m_Updater.getVersion(); }
- ModListSortProxy *createModListProxyModel();
PluginListSortProxy *createPluginListProxyModel();
+ // return the plugin container
+ //
+ PluginContainer& pluginContainer() const;
+
MOBase::IPluginGame const *managedGame() const;
/**