mirror of
https://github.com/ModOrganizer2/modorganizer.git
synced 2026-07-27 13:58:24 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bbab59f681 | ||
|
|
bfbb190998 | ||
|
|
c3b7737ae4 | ||
|
|
30878ae394 | ||
|
|
45a182a381 | ||
|
|
0b07cfa3f0 | ||
|
|
986330a3bd | ||
|
|
81c5ca5308 | ||
|
|
3a8da159da | ||
|
|
f6c3b516fd | ||
|
|
5665be7fd1 | ||
|
|
e522afa63b | ||
|
|
e3c3c2dcc4 | ||
|
|
519f215fd7 | ||
|
|
89221af929 | ||
|
|
59a36107a1 | ||
|
|
bc5d5d8bfa | ||
|
|
a294f8410f | ||
|
|
ba8464f01f | ||
|
|
0e9a86ebfc | ||
|
|
8da9ba5404 | ||
|
|
387326f2d6 | ||
|
|
d07b4f7ff0 | ||
|
|
197c49e996 | ||
|
|
0d50427b83 | ||
|
|
e90fbb1df2 | ||
|
|
a4dbe82be7 | ||
|
|
42417b6a01 | ||
|
|
f2b2ee1a11 | ||
|
|
ae6bb99c52 | ||
|
|
3869eaaf2b | ||
|
|
6edf12f2f7 | ||
|
|
f55a5f2b21 | ||
|
|
5f5184ebfe | ||
|
|
30b29635f6 | ||
|
|
0c536a4c12 | ||
|
|
967c2ae653 | ||
|
|
ba176e5e9b |
@@ -86,7 +86,6 @@ SET(organizer_SRCS
|
||||
usvfsconnector.cpp
|
||||
eventfilter.cpp
|
||||
|
||||
shared/inject.cpp
|
||||
shared/windows_error.cpp
|
||||
shared/error_report.cpp
|
||||
shared/directoryentry.cpp
|
||||
@@ -173,7 +172,6 @@ SET(organizer_HDRS
|
||||
usvfsconnector.h
|
||||
eventfilter.h
|
||||
|
||||
shared/inject.h
|
||||
shared/windows_error.h
|
||||
shared/error_report.h
|
||||
shared/directoryentry.h
|
||||
|
||||
@@ -35,13 +35,8 @@ ActivateModsDialog::ActivateModsDialog(SaveGameInfo::MissingAssets const &missin
|
||||
|
||||
QTableWidget *modsTable = findChild<QTableWidget*>("modsTable");
|
||||
QHeaderView *headerView = modsTable->horizontalHeader();
|
||||
#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);
|
||||
#endif
|
||||
|
||||
int row = 0;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
<file name="icuin53.dll"/>
|
||||
<file name="icuuc53.dll"/>
|
||||
<file name="icudt53.dll"/>
|
||||
<file name="libeay32.dll"/>
|
||||
<file name="ssleay32.dll"/>
|
||||
<file name="Qt5Core.dll"/>
|
||||
<file name="Qt5Declarative.dll"/>
|
||||
<file name="Qt5Gui.dll"/>
|
||||
|
||||
+5
-5
@@ -62,7 +62,7 @@ static bool helperExec(LPCWSTR moDirectory, LPCWSTR commandLine)
|
||||
}
|
||||
|
||||
|
||||
bool init(const std::wstring &moDirectory)
|
||||
bool init(const std::wstring &moPath, const std::wstring &dataPath)
|
||||
{
|
||||
DWORD userNameLen = UNLEN + 1;
|
||||
wchar_t userName[UNLEN + 1];
|
||||
@@ -74,22 +74,22 @@ bool init(const std::wstring &moDirectory)
|
||||
wchar_t *commandLine = new wchar_t[32768];
|
||||
|
||||
_snwprintf(commandLine, 32768, L"init \"%ls\" \"%ls\"",
|
||||
moDirectory.c_str(), userName);
|
||||
dataPath.c_str(), userName);
|
||||
|
||||
bool res = helperExec(moDirectory.c_str(), commandLine);
|
||||
bool res = helperExec(moPath.c_str(), commandLine);
|
||||
delete [] commandLine;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
bool backdateBSAs(const std::wstring &moDirectory, const std::wstring &dataPath)
|
||||
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(moDirectory.c_str(), commandLine);
|
||||
bool res = helperExec(moPath.c_str(), commandLine);
|
||||
delete [] commandLine;
|
||||
|
||||
return res;
|
||||
|
||||
+4
-4
@@ -38,17 +38,17 @@ namespace Helper {
|
||||
* This will create all required sub-directories and give the user running ModOrganizer
|
||||
* write-access
|
||||
*
|
||||
* @param moDirectory absolute path to the ModOrganizer base directory
|
||||
* @param moPath absolute path to the ModOrganizer base directory
|
||||
* @return true on success
|
||||
**/
|
||||
bool init(const std::wstring &moDirectory);
|
||||
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 moDirectory absolute path to the modOrganizer base directory
|
||||
* @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 &moDirectory, const std::wstring &dataPath);
|
||||
bool backdateBSAs(const std::wstring &moPath, const std::wstring &dataPath);
|
||||
|
||||
}
|
||||
|
||||
|
||||
+53
-53
@@ -27,6 +27,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include <QStandardPaths>
|
||||
#include <QInputDialog>
|
||||
#include <QMessageBox>
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
static const char COMPANY_NAME[] = "Tannin";
|
||||
@@ -40,6 +41,11 @@ InstanceManager::InstanceManager()
|
||||
{
|
||||
}
|
||||
|
||||
InstanceManager &InstanceManager::instance()
|
||||
{
|
||||
static InstanceManager s_Instance;
|
||||
return s_Instance;
|
||||
}
|
||||
|
||||
QString InstanceManager::currentInstance() const
|
||||
{
|
||||
@@ -49,6 +55,7 @@ QString InstanceManager::currentInstance() const
|
||||
void InstanceManager::clearCurrentInstance()
|
||||
{
|
||||
setCurrentInstance("");
|
||||
m_Reset = true;
|
||||
}
|
||||
|
||||
void InstanceManager::setCurrentInstance(const QString &name)
|
||||
@@ -81,26 +88,51 @@ QString InstanceManager::queryInstanceName() const
|
||||
|
||||
QString InstanceManager::chooseInstance(const QStringList &instanceList) const
|
||||
{
|
||||
SelectionDialog selection(QObject::tr("Choose Instance"), nullptr);
|
||||
enum class Special : uint8_t {
|
||||
NewInstance,
|
||||
Portable
|
||||
};
|
||||
|
||||
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, ...). Use multiple "
|
||||
"instances for different games. If your MO folder is "
|
||||
"writable, you can also store a single instance locally (called "
|
||||
"a portable install).")),
|
||||
nullptr);
|
||||
selection.disableCancel();
|
||||
for (const QString &instance : instanceList) {
|
||||
selection.addChoice(instance, "", instance);
|
||||
}
|
||||
|
||||
selection.addChoice(QObject::tr("New"),
|
||||
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));
|
||||
}
|
||||
|
||||
if (selection.exec() == QDialog::Rejected) {
|
||||
qDebug("rejected");
|
||||
throw MOBase::MyException(QObject::tr("Canceled"));
|
||||
}
|
||||
|
||||
QString choice = selection.getChoiceData().toString();
|
||||
QVariant choice = selection.getChoiceData();
|
||||
|
||||
if (choice.isEmpty()) {
|
||||
return queryInstanceName();
|
||||
if (choice.type() == QVariant::String) {
|
||||
return choice.toString();
|
||||
} else {
|
||||
return choice;
|
||||
switch (choice.value<uint8_t>()) {
|
||||
case Special::NewInstance: return queryInstanceName();
|
||||
case Special::Portable: return QString();
|
||||
default: throw std::runtime_error("invalid selection");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,27 +157,6 @@ bool InstanceManager::portableInstall() const
|
||||
}
|
||||
|
||||
|
||||
InstanceManager::InstallationMode InstanceManager::queryInstallMode() const
|
||||
{
|
||||
SelectionDialog selection(QObject::tr("Installation Mode"), nullptr);
|
||||
selection.disableCancel();
|
||||
selection.addChoice(QObject::tr("Portable"),
|
||||
QObject::tr("Everything in one directory, only one game per installation."),
|
||||
0);
|
||||
selection.addChoice(QObject::tr("Regular"),
|
||||
QObject::tr("Data in separate directory, multiple games supported."),
|
||||
1);
|
||||
if (selection.exec() == QDialog::Rejected) {
|
||||
throw MOBase::MyException(QObject::tr("Canceled"));
|
||||
}
|
||||
|
||||
switch (selection.getChoiceData().toInt()) {
|
||||
case 0: return InstallationMode::PORTABLE;
|
||||
default: return InstallationMode::REGULAR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void InstanceManager::createDataPath(const QString &dataPath) const
|
||||
{
|
||||
if (!QDir(dataPath).exists()) {
|
||||
@@ -166,41 +177,30 @@ void InstanceManager::createDataPath(const QString &dataPath) const
|
||||
QString InstanceManager::determineDataPath()
|
||||
{
|
||||
QString instanceId = currentInstance();
|
||||
if (instanceId.isEmpty() && portableInstall() && !m_Reset) {
|
||||
// startup, apparently using portable mode before
|
||||
return qApp->applicationDirPath();
|
||||
}
|
||||
|
||||
if (instanceId.isEmpty() && !portableInstall()) {
|
||||
// no portable install and no selected instance
|
||||
QString dataPath = QDir::fromNativeSeparators(
|
||||
QStandardPaths::writableLocation(QStandardPaths::DataLocation)
|
||||
+ "/" + instanceId);
|
||||
|
||||
QStringList instanceList = instances();
|
||||
|
||||
if (instanceList.size() == 0) {
|
||||
if (QFileInfo(qApp->applicationDirPath()).isWritable()) {
|
||||
switch (queryInstallMode()) {
|
||||
case InstallationMode::PORTABLE: {
|
||||
instanceId = QString();
|
||||
} break;
|
||||
case InstallationMode::REGULAR: {
|
||||
instanceId = queryInstanceName();
|
||||
} break;
|
||||
}
|
||||
} else {
|
||||
instanceId = queryInstanceName();
|
||||
}
|
||||
} else {
|
||||
// don't offer portable instance if we can't set one up.
|
||||
instanceId = chooseInstance(instanceList);
|
||||
if (instanceId.isEmpty() || !QFileInfo::exists(dataPath)) {
|
||||
instanceId = chooseInstance(instances());
|
||||
if (!instanceId.isEmpty()) {
|
||||
dataPath = QDir::fromNativeSeparators(
|
||||
QStandardPaths::writableLocation(QStandardPaths::DataLocation)
|
||||
+ "/" + instanceId);
|
||||
}
|
||||
}
|
||||
|
||||
if (instanceId.isEmpty()) {
|
||||
qDebug("portable mode");
|
||||
if (instanceId.isEmpty() || !QFileInfo::exists(dataPath)) {
|
||||
return qApp->applicationDirPath();
|
||||
} else {
|
||||
setCurrentInstance(instanceId);
|
||||
|
||||
QString dataPath = QDir::fromNativeSeparators(
|
||||
QStandardPaths::writableLocation(QStandardPaths::DataLocation)
|
||||
+ "/" + instanceId);
|
||||
|
||||
createDataPath(dataPath);
|
||||
|
||||
return dataPath;
|
||||
|
||||
@@ -27,25 +27,21 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
class InstanceManager {
|
||||
|
||||
enum class InstallationMode {
|
||||
PORTABLE,
|
||||
REGULAR
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
InstanceManager();
|
||||
static InstanceManager &instance();
|
||||
|
||||
QString determineDataPath();
|
||||
QStringList instances() const;
|
||||
void clearCurrentInstance();
|
||||
|
||||
private:
|
||||
|
||||
InstanceManager();
|
||||
|
||||
QString currentInstance() const;
|
||||
QString instancePath() const;
|
||||
|
||||
bool portableInstall() const;
|
||||
QStringList instances() const;
|
||||
|
||||
void setCurrentInstance(const QString &name);
|
||||
|
||||
@@ -53,10 +49,11 @@ private:
|
||||
QString chooseInstance(const QStringList &instanceList) const;
|
||||
|
||||
void createDataPath(const QString &dataPath) const;
|
||||
InstallationMode queryInstallMode() const;
|
||||
bool portableInstall() const;
|
||||
|
||||
private:
|
||||
|
||||
QSettings m_AppSettings;
|
||||
bool m_Reset {false};
|
||||
|
||||
};
|
||||
|
||||
+3
-5
@@ -27,7 +27,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include <windows.h>
|
||||
#include <DbgHelp.h>
|
||||
|
||||
#include <inject.h>
|
||||
#include <appconfig.h>
|
||||
#include <utility.h>
|
||||
#include <scopeguard.h>
|
||||
@@ -104,7 +103,8 @@ bool createAndMakeWritable(const std::wstring &subPath)
|
||||
"will be made writable for the current user account). You will be asked to run "
|
||||
"\"helper.exe\" with administrative rights."),
|
||||
QMessageBox::Yes | QMessageBox::Cancel) == QMessageBox::Yes) {
|
||||
if (!Helper::init(dataPath.toStdWString())) {
|
||||
if (!Helper::init(qApp->applicationDirPath().toStdWString(),
|
||||
dataPath.toStdWString())) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
@@ -630,13 +630,12 @@ int main(int argc, char *argv[])
|
||||
QString dataPath;
|
||||
|
||||
try {
|
||||
dataPath = InstanceManager().determineDataPath();
|
||||
dataPath = InstanceManager::instance().determineDataPath();
|
||||
} catch (const std::exception &e) {
|
||||
QMessageBox::critical(nullptr, QObject::tr("Failed to set up instance"),
|
||||
e.what());
|
||||
return 1;
|
||||
}
|
||||
|
||||
application.setProperty("dataPath", dataPath);
|
||||
|
||||
LogBuffer::init(100, QtDebugMsg, qApp->property("dataPath").toString() + "/logs/mo_interface.log");
|
||||
@@ -647,7 +646,6 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
int result = runApplication(application, instance, splash);
|
||||
|
||||
if (result != INT_MAX) {
|
||||
return result;
|
||||
}
|
||||
|
||||
+24
-34
@@ -37,6 +37,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "savegameinfo.h"
|
||||
#include "spawn.h"
|
||||
#include "versioninfo.h"
|
||||
#include "instancemanager.h"
|
||||
|
||||
#include "report.h"
|
||||
#include "modlist.h"
|
||||
@@ -2676,31 +2677,6 @@ void MainWindow::replaceCategories_MenuHandler() {
|
||||
refreshFilters();
|
||||
}
|
||||
|
||||
void MainWindow::savePrimaryCategory()
|
||||
{
|
||||
QMenu *menu = qobject_cast<QMenu*>(sender());
|
||||
if (menu == nullptr) {
|
||||
qCritical("not a menu?");
|
||||
return;
|
||||
}
|
||||
|
||||
for (QAction* action : menu->actions()) {
|
||||
QWidgetAction *widgetAction = qobject_cast<QWidgetAction*>(action);
|
||||
if (widgetAction != nullptr) {
|
||||
QRadioButton *btn = qobject_cast<QRadioButton*>(widgetAction->defaultWidget());
|
||||
if (btn->isChecked()) {
|
||||
QModelIndexList selected = ui->modList->selectionModel()->selectedRows();
|
||||
for (int i = 0; i < selected.size(); ++i) {
|
||||
ModInfo::Ptr modInfo = ModInfo::getByIndex(m_ModListSortProxy->mapToSource(selected.at(i)).row());
|
||||
modInfo->setPrimaryCategory(widgetAction->data().toInt());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::checkModsForUpdates()
|
||||
{
|
||||
statusBar()->show();
|
||||
@@ -2760,15 +2736,21 @@ void MainWindow::unignoreUpdate()
|
||||
info->ignoreUpdate(false);
|
||||
}
|
||||
|
||||
void MainWindow::addPrimaryCategoryCandidates(QMenu *primaryCategoryMenu, ModInfo::Ptr info)
|
||||
{
|
||||
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);
|
||||
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) {
|
||||
@@ -2932,7 +2914,6 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos)
|
||||
|
||||
QMenu *primaryCategoryMenu = new QMenu(tr("Primary Category"));
|
||||
connect(primaryCategoryMenu, SIGNAL(aboutToShow()), this, SLOT(addPrimaryCategoryCandidates()));
|
||||
connect(primaryCategoryMenu, SIGNAL(aboutToHide()), this, SLOT(savePrimaryCategory()));
|
||||
addMenuAsPushButton(menu, primaryCategoryMenu);
|
||||
|
||||
menu->addSeparator();
|
||||
@@ -3069,6 +3050,7 @@ void MainWindow::deleteSavegame_clicked()
|
||||
.arg(savesMsgLabel),
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||
shellDelete(deleteFiles, true); // recycle bin delete.
|
||||
refreshSaveList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3902,6 +3884,17 @@ void MainWindow::on_actionProblems_triggered()
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -4339,10 +4332,7 @@ void MainWindow::on_bossButton_clicked()
|
||||
QFile::remove(m_OrganizerCore.currentProfile()->getLoadOrderFileName());
|
||||
}
|
||||
m_OrganizerCore.refreshESPList();
|
||||
if (m_OrganizerCore.managedGame()->loadOrderMechanism() == IPluginGame::LoadOrderMechanism::FileTime) {
|
||||
// the load order should have been retrieved from file time, now save it to our own format
|
||||
m_OrganizerCore.savePluginList();
|
||||
}
|
||||
m_OrganizerCore.savePluginList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -183,6 +183,9 @@ protected:
|
||||
virtual void dragEnterEvent(QDragEnterEvent *event);
|
||||
virtual void dropEvent(QDropEvent *event);
|
||||
|
||||
private slots:
|
||||
void on_actionChange_Game_triggered();
|
||||
|
||||
private slots:
|
||||
void on_clickBlankButton_clicked();
|
||||
|
||||
@@ -430,7 +433,6 @@ private slots:
|
||||
void addRemoveCategories_MenuHandler();
|
||||
void replaceCategories_MenuHandler();
|
||||
|
||||
void savePrimaryCategory();
|
||||
void addPrimaryCategoryCandidates();
|
||||
|
||||
void modDetailsUpdated(bool success);
|
||||
|
||||
@@ -1197,6 +1197,7 @@ p, li { white-space: pre-wrap; }
|
||||
<attribute name="toolBarBreak">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<addaction name="actionChange_Game"/>
|
||||
<addaction name="actionInstallMod"/>
|
||||
<addaction name="actionNexus"/>
|
||||
<addaction name="actionAdd_Profile"/>
|
||||
@@ -1383,6 +1384,18 @@ Right now this has very limited functionality</string>
|
||||
<string>Ctrl+C</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionChange_Game">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/MO/gui/app_icon</normaloff>:/MO/gui/app_icon</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Change Game</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Open the game selection dialog</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<customwidgets>
|
||||
|
||||
@@ -27,6 +27,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include <util.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QNetworkCookieJar>
|
||||
|
||||
#include <regex>
|
||||
|
||||
@@ -339,10 +340,6 @@ int NexusInterface::requestFiles(int modID, QObject *receiver, QVariant userData
|
||||
connect(this, SIGNAL(nxmRequestFailed(int,int,QVariant,int,QString)),
|
||||
receiver, SLOT(nxmRequestFailed(int,int,QVariant,int,QString)), Qt::UniqueConnection);
|
||||
|
||||
// QTimer::singleShot(1000, this, SLOT(fakeFiles()));
|
||||
// static int fID = 42;
|
||||
// return fID++;
|
||||
|
||||
nextRequest();
|
||||
return requestInfo.m_ID;
|
||||
}
|
||||
@@ -413,6 +410,12 @@ void NexusInterface::cleanup()
|
||||
m_DiskCache = nullptr;
|
||||
}
|
||||
|
||||
void NexusInterface::clearCache()
|
||||
{
|
||||
m_DiskCache->clear();
|
||||
m_AccessManager->clearCookies();
|
||||
}
|
||||
|
||||
void NexusInterface::nextRequest()
|
||||
{
|
||||
if ((m_ActiveRequest.size() >= MAX_ACTIVE_DOWNLOADS)
|
||||
|
||||
@@ -142,6 +142,11 @@ public:
|
||||
*/
|
||||
void cleanup();
|
||||
|
||||
/**
|
||||
* @brief clear webcache and cookies associated with this access manager
|
||||
*/
|
||||
void clearCache();
|
||||
|
||||
/**
|
||||
* @brief request description for a mod
|
||||
*
|
||||
|
||||
@@ -110,6 +110,15 @@ void NXMAccessManager::showCookies() const
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
@@ -206,7 +215,6 @@ void NXMAccessManager::login(const QString &username, const QString &password)
|
||||
emit loginSuccessful(false);
|
||||
return;
|
||||
}
|
||||
|
||||
m_Username = username;
|
||||
m_Password = password;
|
||||
pageLogin();
|
||||
@@ -228,7 +236,6 @@ QString NXMAccessManager::userAgent(const QString &subModule) const
|
||||
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)));
|
||||
|
||||
@@ -238,8 +245,8 @@ void NXMAccessManager::pageLogin()
|
||||
QByteArray postDataQuery;
|
||||
QUrlQuery postData;
|
||||
postData.addQueryItem("username", m_Username);
|
||||
postData.addQueryItem("password", m_Password);
|
||||
postDataQuery = postData.query(QUrl::FullyEncoded).toUtf8();
|
||||
postData.addQueryItem("password", QUrl::toPercentEncoding(m_Password));
|
||||
postDataQuery = postData.query(QUrl::EncodeReserved).toUtf8();
|
||||
|
||||
request.setRawHeader("User-Agent", userAgent().toUtf8());
|
||||
|
||||
|
||||
@@ -52,6 +52,8 @@ public:
|
||||
|
||||
void showCookies() const;
|
||||
|
||||
void clearCookies();
|
||||
|
||||
QString userAgent(const QString &subModule = QString()) const;
|
||||
|
||||
void startLoginCheck();
|
||||
|
||||
@@ -801,7 +801,7 @@ p, li { white-space: pre-wrap; }
|
||||
</message>
|
||||
<message>
|
||||
<location filename="editexecutablesdialog.ui" line="23"/>
|
||||
<source>This is a list of your configured executables. Executables in grey are automatically recognised and can not be modified.</source>
|
||||
<source>This is a list of your configured executables. Executables in grey are automatically recognised. Existing entries can be modified and new ones added.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
|
||||
+13
-12
@@ -1066,7 +1066,6 @@ void OrganizerCore::spawnBinary(const QFileInfo &binary,
|
||||
if (m_UserInterface != nullptr) {
|
||||
m_UserInterface->setWindowEnabled(true);
|
||||
}
|
||||
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
|
||||
@@ -1076,13 +1075,10 @@ void OrganizerCore::spawnBinary(const QFileInfo &binary,
|
||||
qDebug("removing loadorder.txt");
|
||||
QFile::remove(m_CurrentProfile->getLoadOrderFileName());
|
||||
}
|
||||
refreshDirectoryStructure();
|
||||
|
||||
refreshESPList();
|
||||
if (managedGame()->loadOrderMechanism()
|
||||
== IPluginGame::LoadOrderMechanism::FileTime) {
|
||||
// the load order should have been retrieved from file time, now save it
|
||||
// to our own format
|
||||
savePluginList();
|
||||
}
|
||||
savePluginList();
|
||||
|
||||
m_FinishedRun(binary.absoluteFilePath(), processExitCode);
|
||||
}
|
||||
@@ -1361,7 +1357,9 @@ 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(); });
|
||||
m_PostRefreshTasks.append([this]() {
|
||||
this->refreshESPList();
|
||||
});
|
||||
return;
|
||||
}
|
||||
m_CurrentProfile->modlistWriter().write();
|
||||
@@ -1579,9 +1577,6 @@ void OrganizerCore::directory_refreshed()
|
||||
return;
|
||||
}
|
||||
m_DirectoryUpdate = false;
|
||||
if (m_CurrentProfile != nullptr) {
|
||||
refreshLists();
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_ModList.rowCount(); ++i) {
|
||||
ModInfo::Ptr modInfo = ModInfo::getByIndex(i);
|
||||
@@ -1590,6 +1585,10 @@ void OrganizerCore::directory_refreshed()
|
||||
for (auto task : m_PostRefreshTasks) {
|
||||
task();
|
||||
}
|
||||
|
||||
if (m_CurrentProfile != nullptr) {
|
||||
refreshLists();
|
||||
}
|
||||
}
|
||||
|
||||
void OrganizerCore::profileRefresh()
|
||||
@@ -1784,7 +1783,9 @@ void OrganizerCore::savePluginList()
|
||||
{
|
||||
if (m_DirectoryUpdate) {
|
||||
// delay save till after directory update
|
||||
m_PostRefreshTasks.append([&]() { this->savePluginList(); });
|
||||
m_PostRefreshTasks.append([this]() {
|
||||
this->savePluginList();
|
||||
});
|
||||
return;
|
||||
}
|
||||
m_PluginList.saveTo(m_CurrentProfile->getLockedOrderFileName(),
|
||||
|
||||
@@ -152,11 +152,6 @@ QList<MOBase::IOrganizer::FileInfo> OrganizerProxy::findFileInfos(const QString
|
||||
return m_Proxied->findFileInfos(path, filter);
|
||||
}
|
||||
|
||||
MOBase::IProfile *OrganizerProxy::profile()
|
||||
{
|
||||
return m_Proxied->currentProfile();
|
||||
}
|
||||
|
||||
MOBase::IDownloadManager *OrganizerProxy::downloadManager() const
|
||||
{
|
||||
return m_Proxied->downloadManager();
|
||||
|
||||
@@ -34,7 +34,6 @@ public:
|
||||
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::IProfile *profile();
|
||||
|
||||
virtual MOBase::IDownloadManager *downloadManager() const;
|
||||
virtual MOBase::IPluginList *pluginList() const;
|
||||
|
||||
@@ -15,6 +15,12 @@ PersistentCookieJar::~PersistentCookieJar() {
|
||||
save();
|
||||
}
|
||||
|
||||
void PersistentCookieJar::clear() {
|
||||
for (const QNetworkCookie &cookie : allCookies()) {
|
||||
deleteCookie(cookie);
|
||||
}
|
||||
}
|
||||
|
||||
void PersistentCookieJar::save() {
|
||||
QTemporaryFile file;
|
||||
if (!file.open()) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user