/*
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see .
*/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
#include
#include
#include
#include
#include "delayedfilewriter.h"
#include "iuserinterface.h"
#include "modinfo.h"
#include "modlistbypriorityproxy.h"
#include "modlistsortproxy.h"
#include "plugincontainer.h"
#include "shared/fileregisterfwd.h"
#include "systemtraymanager.h"
class Executable;
class CategoryFactory;
class OrganizerCore;
class FilterList;
class DataTab;
class DownloadsTab;
class SavesTab;
class BrowserDialog;
class PluginListSortProxy;
namespace BSA
{
class Archive;
}
namespace MOBase
{
class IPluginModPage;
}
namespace MOBase
{
class IPluginTool;
}
namespace MOShared
{
class DirectoryEntry;
}
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
class QAction;
class QAbstractItemModel;
class QDateTime;
class QEvent;
class QFile;
class QListWidgetItem;
class QMenu;
class QModelIndex;
class QPoint;
class QProgressDialog;
class QTranslator;
class QTreeWidgetItem;
class QUrl;
class QWidget;
#ifndef Q_MOC_RUN
#include
#endif
// Sigh - just for HANDLE
#define WIN32_LEAN_AND_MEAN
#include
#include
#include
#include
#include
namespace Ui
{
class MainWindow;
}
class Settings;
class MainWindow : public QMainWindow, public IUserInterface
{
Q_OBJECT
friend class OrganizerProxy;
public:
explicit MainWindow(Settings& settings, OrganizerCore& organizerCore,
PluginContainer& pluginContainer, QWidget* parent = 0);
~MainWindow();
void processUpdates();
QMainWindow* mainWindow() override;
bool addProfile();
void updateBSAList(const QStringList& defaultArchives,
const QStringList& activeArchives);
void saveArchiveList();
void installTranslator(const QString& name);
void displayModInformation(ModInfo::Ptr modInfo, unsigned int modIndex,
ModInfoTabIDs tabID) override;
bool canExit();
void onBeforeClose();
virtual bool closeWindow();
virtual void setWindowEnabled(bool enabled);
virtual MOBase::DelayedFileWriterBase& archivesWriter() override
{
return m_ArchiveListWriter;
}
void showNotification(const QString& title, const QString& message,
QSystemTrayIcon::MessageIcon icon =
QSystemTrayIcon::MessageIcon::Information) override;
public slots:
void refresherProgress(const DirectoryRefreshProgress* p);
signals:
// emitted after the information dialog has been closed, used by tutorials
//
void modInfoDisplayed();
/**
* @brief emitted when the selected style changes
*/
void styleChanged(const QString& styleFile);
void checkForProblemsDone();
protected:
void showEvent(QShowEvent* event) override;
void paintEvent(QPaintEvent* event) override;
void closeEvent(QCloseEvent* event) override;
bool eventFilter(QObject* obj, QEvent* event) override;
void resizeEvent(QResizeEvent* event) override;
void dragEnterEvent(QDragEnterEvent* event) override;
void dropEvent(QDropEvent* event) override;
void keyReleaseEvent(QKeyEvent* event) override;
private slots:
void on_actionChange_Game_triggered();
private:
// update data tab and schedule a problem check after a directory
// structure update
//
void onDirectoryStructureChanged();
void cleanup();
void setupToolbar();
void setupActionMenu(QAction* a);
void createHelpMenu();
void createEndorseMenu();
void updatePinnedExecutables();
void setToolbarSize(const QSize& s);
void setToolbarButtonStyle(Qt::ToolButtonStyle s);
void registerModPage(MOBase::IPluginModPage* modPage);
bool registerNexusPage(const QString& gameName);
void registerPluginTool(MOBase::IPluginTool* tool, QString name = QString(),
QMenu* menu = nullptr);
void updateToolbarMenu();
void updateToolMenu();
void updateModPageMenu();
void updateViewMenu();
QMenu* createPopupMenu() override;
void activateSelectedProfile();
bool refreshProfiles(bool selectProfile = true, QString newProfile = QString());
void refreshExecutablesList();
bool modifyExecutablesDialog(int selection);
// remove invalid category-references from mods
void fixCategories();
bool extractProgress(QProgressDialog& extractProgress, int percentage,
std::string fileName);
// Performs checks, sets the m_NumberOfProblems and signals checkForProblemsDone().
void checkForProblemsImpl();
void setCategoryListVisible(bool visible);
bool errorReported(QString& logFile);
static void setupNetworkProxy(bool activate);
void activateProxy(bool activate);
bool createBackup(const QString& filePath, const QDateTime& time);
QString queryRestore(const QString& filePath);
QMenu* openFolderMenu();
void dropLocalFile(const QUrl& url, const QString& outputDir, bool move);
void toggleMO2EndorseState();
void toggleUpdateAction();
void updateSortButton();
// update info
struct NxmUpdateInfoData
{
QString game;
std::set finalMods;
};
void finishUpdateInfo(const NxmUpdateInfoData& data);
private:
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;
bool m_FirstPaint;
// last separator on the toolbar, used to add spacer for right-alignment and
// as an insert point for executables
QAction* m_linksSeparator;
MOBase::TutorialControl m_Tutorial;
std::unique_ptr m_DataTab;
std::unique_ptr m_DownloadsTab;
std::unique_ptr m_SavesTab;
int m_OldProfileIndex;
std::vector
m_ModNameList; // the mod-list to go with the directory structure
QStringList m_DefaultArchives;
int m_OldExecutableIndex;
QAction* m_ContextAction;
CategoryFactory& m_CategoryFactory;
QTimer m_CheckBSATimer;
QTimer m_SaveMetaTimer;
QTimer m_UpdateProblemsTimer;
QFuture m_MetaSave;
QTime m_StartTime;
OrganizerCore& m_OrganizerCore;
PluginContainer& m_PluginContainer;
QString m_CurrentLanguage;
std::vector m_Translators;
std::unique_ptr m_IntegratedBrowser;
MOBase::DelayedFileWriter m_ArchiveListWriter;
QAction* m_LinkToolbar;
QAction* m_LinkDesktop;
QAction* m_LinkStartMenu;
SystemTrayManager* m_SystemTrayManager;
// icon set by the stylesheet, used to remember its original appearance
// when painting the count
QIcon m_originalNotificationIcon;
std::atomic m_NumberOfProblems;
std::atomic m_ProblemsCheckRequired;
std::mutex m_CheckForProblemsMutex;
QVersionNumber m_LastVersion;
Executable* getSelectedExecutable();
private slots:
void updateWindowTitle(const APIUserAccount& user);
void showMessage(const QString& message);
void showError(const QString& message);
// main window actions
void helpTriggered();
void issueTriggered();
void wikiTriggered();
void gameSupportTriggered();
void discordTriggered();
void tutorialTriggered();
void extractBSATriggered(QTreeWidgetItem* item);
void refreshProfile_activated();
void linkToolbar();
void linkDesktop();
void linkMenu();
void languageChange(const QString& newLanguage);
void windowTutorialFinished(const QString& windowName);
BSA::EErrorCode extractBSA(BSA::Archive& archive, BSA::Folder::Ptr folder,
const QString& destination,
QProgressDialog& extractProgress);
// nexus related
void updateAvailable();
void actionEndorseMO();
void actionWontEndorseMO();
void motdReceived(const QString& motd);
void originModified(int originID);
void modInstalled(const QString& modName);
void importCategories(bool);
void refreshNexusCategories(CategoriesDialog* dialog);
void categoriesSaved();
// update info
void nxmUpdateInfoAvailable(QString gameName, QVariant userData, QVariant resultData,
int requestID);
void nxmEndorsementsAvailable(QVariant userData, QVariant resultData, int);
void nxmUpdatesAvailable(QString gameName, int modID, QVariant userData,
QVariant resultData, int requestID);
void nxmModInfoAvailable(QString gameName, int modID, QVariant userData,
QVariant resultData, int requestID);
void nxmEndorsementToggled(QString, int, QVariant, QVariant resultData, int);
void nxmTrackedModsAvailable(QVariant userData, QVariant resultData, int);
void nxmDownloadURLs(QString, int modID, int fileID, QVariant userData,
QVariant resultData, int requestID);
void nxmGameInfoAvailable(QString gameName, QVariant, QVariant resultData, int);
void nxmRequestFailed(QString gameName, int modID, int fileID, QVariant userData,
int requestID, int errorCode, const QString& errorString);
void modRenamed(const QString& oldName, const QString& newName);
void modRemoved(const QString& fileName);
void hookUpWindowTutorials();
bool shouldStartTutorial() const;
void openInstanceFolder();
void openInstallFolder();
void openPluginsFolder();
void openStylesheetsFolder();
void openDownloadsFolder();
void openModsFolder();
void openProfileFolder();
void openIniFolder();
void openGameFolder();
void openMyGamesFolder();
void startExeAction();
void checkBSAList();
// Only visually update the problems icon.
void updateProblemsButton();
// Queue a problem check to allow collapsing of multiple requests in short amount of
// time.
void scheduleCheckForProblems();
// Perform the actual problem check in another thread.
QFuture checkForProblemsAsync();
void saveModMetas();
void updateStyle(const QString& style);
void resizeLists(bool pluginListCustom);
void fileMoved(const QString& filePath, const QString& oldOriginName,
const QString& newOriginName);
/**
* @brief allow columns in mod list and plugin list to be resized
*/
void allowListResize();
void toolBar_customContextMenuRequested(const QPoint& point);
void removeFromToolbar(QAction* action);
void about();
void resetActionIcons();
private slots: // ui slots
// actions
void on_actionAdd_Profile_triggered();
void on_actionInstallMod_triggered();
void on_action_Refresh_triggered();
void on_actionModify_Executables_triggered();
void on_actionNexus_triggered();
void on_actionNotifications_triggered();
void on_actionSettings_triggered();
void on_actionUpdate_triggered();
void on_actionExit_triggered();
void on_actionMainMenuToggle_triggered();
void on_actionToolBarMainToggle_triggered();
void on_actionStatusBarToggle_triggered();
void on_actionToolBarSmallIcons_triggered();
void on_actionToolBarMediumIcons_triggered();
void on_actionToolBarLargeIcons_triggered();
void on_actionToolBarIconsOnly_triggered();
void on_actionToolBarTextOnly_triggered();
void on_actionToolBarIconsAndText_triggered();
void on_actionViewLog_triggered();
void on_centralWidget_customContextMenuRequested(const QPoint& pos);
void on_bsaList_customContextMenuRequested(const QPoint& pos);
void on_executablesListBox_currentIndexChanged(int index);
void on_profileBox_currentIndexChanged(int index);
void on_startButton_clicked();
void on_tabWidget_currentChanged(int index);
void on_displayCategoriesBtn_toggled(bool checked);
void on_linkButton_pressed();
void on_showHiddenBox_toggled(bool checked);
void on_bsaList_itemChanged(QTreeWidgetItem* item, int column);
void on_saveButton_clicked();
void on_restoreButton_clicked();
void on_restoreModsButton_clicked();
void on_saveModsButton_clicked();
void on_managedArchiveLabel_linkHovered(const QString& link);
void onPluginRegistrationChanged();
void storeSettings();
void readSettings();
void setupModList();
};
#endif // MAINWINDOW_H