Compare commits

..
Author SHA1 Message Date
Tannin 5e7c875b29 - test-plugins accidentally distributed in the 1.2.5 release are now automatically deleted
- some fixes to the tutorial (mostly wording but also some actual problems)
- bugfix: could disable mods that aren't supposed to be disable-able
- bugfix: mod list wasn't saved on some changes
- bugfix: when trying to start directly to application, MO didn't start up correctly
- bugfix: hook.dll didn't load mod bsas into its directory structure and thus didn't allow bsas to overwrite loose files
- bugfix: in some constellations the tutorial files couldn't be found despite being in the right location
2014-06-25 23:51:29 +02:00
Tannin b2a7c7c223 Merge 2014-06-23 21:43:40 +02:00
Tannin 7b4582c1b1 - adjusted mod load order in hook.dll to match the one from the UI
- bugfix: fnis checker took files in archives into consideration for hashing
2014-06-23 20:23:59 +02:00
Tannin 5d7b23acef - bugfix: networkaccessmanager of browser dialog wasn't destroyed correctly. As a result the cookie jar doesn't get saved 2014-06-21 12:16:57 +02:00
Tannin 3628ec930b - changed the url used to login on nexus (the previous page was disabled)
- bugfix: download manager might have tried to read from a closed connection
2014-06-21 10:39:28 +02:00
Tannin e22aeca3ff - download read buffer is now limited to 1MB. Might prevent out-of-memory errors during download
- bugfix: plugins are now disabled when deactivating a mod  before the files are removed from the vfs
2014-06-17 18:36:28 +02:00
Tannin cbd6b288eb Merge 2014-06-16 21:50:53 +02:00
Tannin 484749e612 - added pseudo-categories to filter for mo-managed vs. unmanaged mods
- deleted mods are now moved to the recycle bin instead of being deleted permanently
- reduced modinfo dialog for foreign mods
- foreign mods are now displayed with a pseudo-category
- added a signal when a plugin is moved
- bugfix: refreshing of directory structure for mods with bsas didn't work correctly when enabling a mod and on changing display of foreign mods
- bugfix: one mod in the list was assigned the same priority on the directory structure as the data directory
- bugfix: conflicts tab in the mod info dialog offered the hide option for files in bsas
2014-06-16 21:49:57 +02:00
Tannin 5b3cdaa83b bugfix: the warning dialog upon changing the mod directory didn't have an effect, the process couldn't be canceled 2014-06-14 09:17:57 +02:00
Tannin 6d3f88b330 Added tag release v1.2.3 for changeset c503e48f97aa 2014-06-08 15:10:21 +02:00
40 changed files with 15780 additions and 21843 deletions
+13
View File
@@ -18,5 +18,18 @@ staging_prepare/*
staging_trans/*
tools/python_zip/*
Makefile
html
*.vcxproj
*.pdb
*.dll
*.exp
*.tlog
*.user
*.obj
*.suo
*.sln
*.log
*.filters
*.lib
syntax: regexp
Makefile\.(Debug|Release)
+1 -1
View File
@@ -43,7 +43,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
BrowserDialog::BrowserDialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::BrowserDialog)
, m_AccessManager(new QNetworkAccessManager)
, m_AccessManager(new QNetworkAccessManager(this))
{
ui->setupUi(this);
+2
View File
@@ -47,6 +47,8 @@ public:
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:
+26 -27
View File
@@ -63,7 +63,6 @@ void DirectoryRefresher::setMods(const std::vector<std::tuple<QString, QString,
m_EnabledArchives = managedArchives;
}
void DirectoryRefresher::cleanStructure(DirectoryEntry *structure)
{
static wchar_t *files[] = { L"meta.ini", L"readme.txt" };
@@ -77,21 +76,27 @@ void DirectoryRefresher::cleanStructure(DirectoryEntry *structure)
}
}
void DirectoryRefresher::addModToStructure(DirectoryEntry *directoryStructure
, const QString &modName
, int priority
, const QString &directory
, const QStringList &stealFiles
, const QStringList &archives)
void DirectoryRefresher::addModBSAToStructure(DirectoryEntry *directoryStructure, const QString &modName, int priority, const QString &directory, const QStringList &archives)
{
std::wstring directoryW = ToWString(QDir::toNativeSeparators(directory));
std::wstring modNameW = ToWString(modName);
foreach (const QString &archive, archives) {
QFileInfo fileInfo(archive);
if (m_EnabledArchives.find(fileInfo.fileName()) != m_EnabledArchives.end()) {
directoryStructure->addFromBSA(ToWString(modName), directoryW,
ToWString(QDir::toNativeSeparators(fileInfo.absoluteFilePath())), priority);
}
}
}
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
directoryStructure->createOrigin(modNameW, directoryW, priority);
FilesOrigin origin = directoryStructure->createOrigin(ToWString(modName), directoryW, priority);
foreach (const QString &filename, stealFiles) {
QFileInfo fileInfo(filename);
FileEntry::Ptr file = directoryStructure->findFile(ToWString(fileInfo.fileName()));
@@ -99,30 +104,24 @@ void DirectoryRefresher::addModToStructure(DirectoryEntry *directoryStructure
if (file->getOrigin() == 0) {
// replace data as the origin on this bsa
file->removeOrigin(0);
file->addOrigin(directoryStructure->getOriginByName(modNameW).getID(),
file->getFileTime(), L"");
file->addOrigin(origin.getID(), file->getFileTime(), L"");
}
}
}
} else {
directoryStructure->addFromOrigin(modNameW, directoryW, priority);
directoryStructure->addFromOrigin(ToWString(modName), directoryW, priority);
}
/* QDir dir(directory);
QFileInfoList bsaFiles = dir.entryInfoList(QStringList("*.bsa"), QDir::Files);
foreach (QFileInfo file, bsaFiles) {
if (m_EnabledArchives.find(file.fileName()) != m_EnabledArchives.end()) {
directoryStructure->addFromBSA(ToWString(modName), directoryW,
ToWString(QDir::toNativeSeparators(file.absoluteFilePath())), priority);
}
}*/
}
foreach (const QString &archive, archives) {
QFileInfo fileInfo(archive);
if (m_EnabledArchives.find(fileInfo.fileName()) != m_EnabledArchives.end()) {
directoryStructure->addFromBSA(modNameW, directoryW,
ToWString(QDir::toNativeSeparators(fileInfo.absoluteFilePath())), 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::refresh()
+24 -2
View File
@@ -79,13 +79,35 @@ public:
/**
* @brief add files for a mod to the directory structure, including bsas
* @param directoryStructure
* @param modName
* @param priorityBSA
* @param priority
* @param directory
* @param priorityDir
* @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 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:
/**
+4 -4
View File
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="dlls" version="1.0.0.0" processorArchitecture="x86"/>
<file name="icuin49.dll"/>
<file name="icuuc49.dll"/>
<file name="icudt49.dll"/>
<file name="icuin52.dll"/>
<file name="icuuc52.dll"/>
<file name="icudt52.dll"/>
<file name="Qt5Core.dll"/>
<file name="Qt5Declarative.dll"/>
<file name="Qt5Gui.dll"/>
@@ -14,4 +14,4 @@
<file name="Qt5Widgets.dll"/>
<file name="Qt5Xml.dll"/>
<file name="Qt5XmlPatterns.dll"/>
</assembly>
</assembly>
+6 -5
View File
@@ -350,9 +350,6 @@ bool DownloadManager::addDownload(QNetworkReply *reply, const ModRepositoryFileI
bool DownloadManager::addDownload(QNetworkReply *reply, const QStringList &URLs, const QString &fileName,
int modID, int fileID, const ModRepositoryFileInfo *fileInfo)
{
if (!reply->isRunning()) {
qDebug("this is not a running download! %d", reply->isFinished());
}
// download invoked from an already open network reply (i.e. download link in the browser)
DownloadInfo *newDownload = DownloadInfo::createNew(fileInfo, URLs);
@@ -401,6 +398,7 @@ void DownloadManager::removePending(int modID, int fileID)
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) {
@@ -1339,8 +1337,11 @@ void DownloadManager::downloadFinished()
DownloadInfo *info = findDownload(this->sender(), &index);
if (info != NULL) {
QNetworkReply *reply = info->m_Reply;
QByteArray data = info->m_Reply->readAll();
info->m_Output.write(data);
QByteArray data;
if (reply->isOpen()) {
data = reply->readAll();
info->m_Output.write(data);
}
info->m_Output.close();
TaskProgressManager::instance().forgetMe(info->m_TaskProgressId);
+3 -1
View File
@@ -174,7 +174,9 @@ void cleanupDir()
"QtXml4.dll",
"QtWebKit4.dll",
"qjpeg4.dll",
"NCC/GamebryoBase.dll"
"NCC/GamebryoBase.dll",
"plugins/helloWorld.dll",
"plugins/testnexus.py"
};
static const int NUM_FILES = sizeof(fileNames) / sizeof(QString);
+84 -69
View File
@@ -163,7 +163,7 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget
m_DownloadManager(NexusInterface::instance(), this), m_InstallationManager(this),
m_Updater(NexusInterface::instance(), this), m_CategoryFactory(CategoryFactory::instance()),
m_CurrentProfile(NULL), m_AskForNexusPW(false),
m_ArchivesInit(false), m_ContextItem(NULL), m_ContextAction(NULL), m_CurrentSaveView(NULL),
m_ArchivesInit(false), m_DirectoryUpdate(false), m_ContextItem(NULL), m_ContextAction(NULL), m_CurrentSaveView(NULL),
m_GameInfo(new GameInfoImpl()), m_AboutToRun(), m_ModInstalled(), m_DidUpdateMasterList(false)
{
ui->setupUi(this);
@@ -320,6 +320,9 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget
m_CheckBSATimer.setSingleShot(true);
connect(&m_CheckBSATimer, SIGNAL(timeout()), this, SLOT(checkBSAList()));
m_UpdateProblemsTimer.setSingleShot(true);
connect(&m_UpdateProblemsTimer, SIGNAL(timeout()), this, SLOT(updateProblemsButton()));
m_SaveMetaTimer.setSingleShot(false);
connect(&m_SaveMetaTimer, SIGNAL(timeout()), this, SLOT(saveModMetas()));
m_SaveMetaTimer.start(5000);
@@ -530,6 +533,14 @@ void MainWindow::updateToolBar()
}
void MainWindow::scheduleUpdateButton()
{
if (!m_UpdateProblemsTimer.isActive()) {
m_UpdateProblemsTimer.start(1000);
}
}
void MainWindow::updateProblemsButton()
{
int numProblems = checkForProblems();
@@ -661,7 +672,7 @@ void MainWindow::createHelpWidget()
}
void MainWindow::saveArchiveList()
bool MainWindow::saveArchiveList()
{
if (m_ArchivesInit) {
SafeWriteFile archiveFile(m_CurrentProfile->getArchivesFileName());
@@ -680,10 +691,12 @@ void MainWindow::saveArchiveList()
}
if (archiveFile.commitIfDifferent(m_ArchiveListHash)) {
qDebug("%s saved", qPrintable(QDir::toNativeSeparators(m_CurrentProfile->getArchivesFileName())));
return true;
}
} else {
qWarning("archive list not initialised");
}
return false;
}
void MainWindow::savePluginList()
@@ -1148,7 +1161,7 @@ bool MainWindow::registerPlugin(QObject *plugin, const QString &fileName)
IPluginDiagnose *diagnose = qobject_cast<IPluginDiagnose*>(plugin);
if (diagnose != NULL) {
m_DiagnosisPlugins.push_back(diagnose);
diagnose->onInvalidated([&] () { this->updateProblemsButton(); });
diagnose->onInvalidated([&] () { this->scheduleUpdateButton(); });
}
}
{ // mod page plugin
@@ -1418,10 +1431,8 @@ void MainWindow::setExecutableIndex(int index)
} else {
executableBox->setCurrentIndex(1);
}
}
void MainWindow::activateSelectedProfile()
{
QString profileName = ui->profileBox->currentText();
@@ -1440,7 +1451,6 @@ void MainWindow::activateSelectedProfile()
refreshModList();
}
void MainWindow::on_profileBox_currentIndexChanged(int index)
{
if (ui->profileBox->isEnabled()) {
@@ -1646,8 +1656,6 @@ bool MainWindow::refreshProfiles(bool selectProfile)
std::set<QString> MainWindow::enabledArchives()
{
std::set<QString> result;
QFile archiveFile(m_CurrentProfile->getArchivesFileName());
if (archiveFile.open(QIODevice::ReadOnly)) {
while (!archiveFile.atEnd()) {
@@ -1658,7 +1666,6 @@ std::set<QString> MainWindow::enabledArchives()
return result;
}
void MainWindow::refreshDirectoryStructure()
{
m_DirectoryUpdate = true;
@@ -1672,7 +1679,6 @@ void MainWindow::refreshDirectoryStructure()
QTimer::singleShot(0, &m_DirectoryRefresher, SLOT(refresh()));
}
#if QT_VERSION >= 0x050000
extern QPixmap qt_pixmapFromWinHICON(HICON icon);
#else
@@ -1692,7 +1698,6 @@ QIcon MainWindow::iconForExecutable(const QString &filePath)
}
}
void MainWindow::refreshExecutablesList()
{
QComboBox* executablesList = findChild<QComboBox*>("executablesListBox");
@@ -1806,6 +1811,7 @@ void MainWindow::refreshModList(bool saveChanges)
m_CurrentProfile->writeModlistNow(true);
}
ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, m_Settings.displayForeign());
m_CurrentProfile->refreshModStatus();
m_ModList.notifyChange(-1);
@@ -1969,15 +1975,6 @@ void MainWindow::checkBSAList()
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;
/* } else {
QString espName = filename.mid(0, filename.length() - 3).append("esp").toLower();
QString esmName = filename.mid(0, filename.length() - 3).append("esm").toLower();
if (m_PluginList.isEnabled(espName) || m_PluginList.isEnabled(esmName)) {
item->setIcon(0, QIcon(":/MO/gui/warning"));
item->setToolTip(0, tr("This archive will still be loaded since there is a plugin of the same name but "
"its files will not follow installation order!"));
modWarning = true;
}*/
}
}
}
@@ -2632,7 +2629,6 @@ void MainWindow::directory_refreshed()
if (m_CurrentProfile != NULL) {
refreshLists();
}
// m_RefreshProgress->setVisible(false);
// some problem-reports may rely on the virtual directory tree so they need to be updated
// now
@@ -2645,7 +2641,6 @@ void MainWindow::directory_refreshed()
statusBar()->hide();
}
void MainWindow::externalMessage(const QString &message)
{
if (message.left(6).toLower() == "nxm://") {
@@ -2654,31 +2649,56 @@ void MainWindow::externalMessage(const QString &message)
}
}
void MainWindow::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();
saveArchiveList();
m_DirectoryRefresher.setMods(m_CurrentProfile->getActiveMods(), enabledArchives());
// 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 MainWindow::modStatusChanged(unsigned int index)
{
try {
ModInfo::Ptr modInfo = ModInfo::getByIndex(index);
if (m_CurrentProfile->modEnabled(index)) {
m_DirectoryRefresher.addModToStructure(m_DirectoryStructure
, modInfo->name()
, m_CurrentProfile->getModPriority(index)
, modInfo->absolutePath()
, modInfo->stealFiles()
, modInfo->archives());
DirectoryRefresher::cleanStructure(m_DirectoryStructure);
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);
}
}
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()))) {
m_DirectoryStructure->getOriginByName(ToWString(modInfo->name())).setPriority(priority);
// 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();
@@ -2704,10 +2724,12 @@ void MainWindow::modorder_changed()
int priority = m_CurrentProfile->getModPriority(i);
if (m_CurrentProfile->modEnabled(i)) {
ModInfo::Ptr modInfo = ModInfo::getByIndex(i);
m_DirectoryStructure->getOriginByName(ToWString(modInfo->name())).setPriority(priority);
// priorities in the directory structure are one higher because data is 0
m_DirectoryStructure->getOriginByName(ToWString(modInfo->name())).setPriority(priority + 1);
}
}
refreshBSAList();
m_CurrentProfile->writeModlist();
saveArchiveList();
m_DirectoryStructure->getFileRegister()->sortOrigins();
}
@@ -2723,33 +2745,30 @@ void MainWindow::procFinished(int, QProcess::ExitStatus)
this->sender()->deleteLater();
}
void MainWindow::profileRefresh()
{
m_CurrentProfile->writeModlist();
// 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());
m_CurrentProfile->refreshModStatus();
refreshModList();
}
void MainWindow::showMessage(const QString &message)
{
MessageDialog::showMessage(message, this);
}
void MainWindow::showError(const QString &message)
{
reportError(message);
}
void MainWindow::installMod_clicked()
{
installMod();
}
void MainWindow::renameModInList(QFile &modList, const QString &oldName, const QString &newName)
{
//TODO this code needs to be merged with ModList::readFrom
@@ -2911,6 +2930,8 @@ void MainWindow::refreshFilters()
addFilterItem(NULL, tr("<Checked>"), CategoryFactory::CATEGORY_SPECIAL_CHECKED);
addFilterItem(NULL, tr("<Unchecked>"), CategoryFactory::CATEGORY_SPECIAL_UNCHECKED);
addFilterItem(NULL, tr("<Update>"), CategoryFactory::CATEGORY_SPECIAL_UPDATEAVAILABLE);
addFilterItem(NULL, tr("<Managed by MO>"), CategoryFactory::CATEGORY_SPECIAL_MANAGED);
addFilterItem(NULL, tr("<Managed outside MO>"), CategoryFactory::CATEGORY_SPECIAL_UNMANAGED);
addFilterItem(NULL, tr("<No category>"), CategoryFactory::CATEGORY_SPECIAL_NOCATEGORY);
addFilterItem(NULL, tr("<Conflicted>"), CategoryFactory::CATEGORY_SPECIAL_CONFLICT);
addFilterItem(NULL, tr("<Not Endorsed>"), CategoryFactory::CATEGORY_SPECIAL_NOTENDORSED);
@@ -2975,37 +2996,35 @@ void MainWindow::restoreBackup_clicked()
}
}
void MainWindow::modlistChanged(const QModelIndex &index, int role)
void MainWindow::updateModActiveState(int index, bool active)
{
if (role == Qt::CheckStateRole) {
if (index.data(Qt::CheckStateRole).toBool()) {
ModInfo::Ptr modInfo = ModInfo::getByIndex(index.row());
ModInfo::Ptr modInfo = ModInfo::getByIndex(index);
QDir dir(modInfo->absolutePath());
foreach (const QString &esm, dir.entryList(QStringList("*.esm"), QDir::Files)) {
m_PluginList.enableESP(esm);
}
int enabled = 0;
QStringList esps = dir.entryList(QStringList("*.esp"), QDir::Files);
foreach (const QString &esp, esps) {
if (!m_PluginList.isEnabled(esp)) {
m_PluginList.enableESP(esp);
++enabled;
}
}
if (enabled > 1) {
MessageDialog::showMessage(tr("Multiple esps activated, please check that they don't conflict."), this);
}
m_PluginList.refreshLoadOrder();
// immediately save affected lists
savePluginList();
saveArchiveList();
QDir dir(modInfo->absolutePath());
foreach (const QString &esm, dir.entryList(QStringList("*.esm"), QDir::Files)) {
m_PluginList.enableESP(esm, active);
}
int enabled = 0;
QStringList esps = dir.entryList(QStringList("*.esp"), QDir::Files);
foreach (const QString &esp, esps) {
if (active != m_PluginList.isEnabled(esp)) {
m_PluginList.enableESP(esp, active);
++enabled;
}
}
if (active && (enabled > 1)) {
MessageDialog::showMessage(tr("Multiple esps activated, please check that they don't conflict."), this);
}
m_PluginList.refreshLoadOrder();
// immediately save affected lists
savePluginList();
// refreshBSAList();
}
void MainWindow::modlistChanged(const QModelIndex&, int)
{
m_CurrentProfile->writeModlist();
}
void MainWindow::removeMod_clicked()
{
@@ -3162,12 +3181,9 @@ void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index,
dialog->raise();
dialog->activateWindow();
connect(dialog, SIGNAL(finished(int)), this, SLOT(overwriteClosed(int)));
} else if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_FOREIGN) != flags.end()) {
// nop - no menu for this file type
return;
} else {
modInfo->saveMeta();
ModInfoDialog dialog(modInfo, m_DirectoryStructure, this);
ModInfoDialog dialog(modInfo, m_DirectoryStructure, modInfo->hasFlag(ModInfo::FLAG_FOREIGN), this);
connect(&dialog, SIGNAL(nexusLinkActivated(QString)), this, SLOT(nexusLinkActivated(QString)));
connect(&dialog, SIGNAL(downloadRequest(QString)), this, SLOT(downloadRequestedNXM(QString)));
connect(&dialog, SIGNAL(modOpen(QString, int)), this, SLOT(displayModInformation(QString, int)), Qt::QueuedConnection);
@@ -3995,6 +4011,7 @@ void MainWindow::linkToolbar()
const Executable &selectedExecutable = ui->executablesListBox->itemData(ui->executablesListBox->currentIndex()).value<Executable>();
Executable &exe = m_ExecutablesList.find(selectedExecutable.m_Title);
exe.m_Toolbar = !exe.m_Toolbar;
ui->linkButton->menu()->actions().at(2)->setIcon(exe.m_Toolbar ? QIcon(":/MO/gui/remove") : QIcon(":/MO/gui/link"));
updateToolBar();
}
@@ -4091,8 +4108,7 @@ void MainWindow::on_actionSettings_triggered()
if ((m_Settings.getModDirectory() != oldModDirectory)
|| (m_Settings.displayForeign() != oldDisplayForeign)) {
refreshModList();
refreshLists();
profileRefresh();
}
if (m_Settings.getCacheDirectory() != oldCacheDirectory) {
@@ -4244,7 +4260,6 @@ void MainWindow::installDownload(int index)
MessageDialog::showMessage(tr("Installation successful"), this);
refreshModList();
QModelIndexList posList = m_ModList.match(m_ModList.index(0, 0), Qt::DisplayRole, static_cast<const QString&>(modName));
if (posList.count() == 1) {
ui->modList->scrollTo(posList.at(0));
+15 -7
View File
@@ -99,7 +99,6 @@ public:
void readSettings();
bool addProfile();
void refreshLists();
void refreshBSAList();
void refreshDataTree();
void refreshSaveList();
@@ -127,7 +126,7 @@ public:
void addPrimaryCategoryCandidates(QMenu *primaryCategoryMenu, ModInfo::Ptr info);
void saveArchiveList();
bool saveArchiveList();
void createStdoutPipe(HANDLE *stdOutRead, HANDLE *stdOutWrite);
std::string readFromPipe(HANDLE stdOutRead);
@@ -135,8 +134,12 @@ public:
HANDLE startApplication(const QString &executable, const QStringList &args = QStringList(), const QString &cwd = "", const QString &profile = "");
void updateModInDirectoryStructure(unsigned int index, ModInfo::Ptr modInfo);
public slots:
void refreshLists();
void displayColumnSelection(const QPoint &pos);
void externalMessage(const QString &message);
@@ -260,8 +263,6 @@ private:
void setCategoryListVisible(bool visible);
void updateProblemsButton();
SaveGameGamebryo *getSaveGame(const QString &name);
SaveGameGamebryo *getSaveGame(QListWidgetItem *item);
@@ -287,6 +288,10 @@ private:
std::set<QString> enabledArchives();
void scheduleUpdateButton();
void updateModActiveState(int index, bool active);
private:
static const unsigned int PROBLEM_PLUGINSNOTLOADED = 1;
@@ -356,6 +361,7 @@ private:
bool m_ArchivesInit;
QTimer m_CheckBSATimer;
QTimer m_SaveMetaTimer;
QTimer m_UpdateProblemsTimer;
QTime m_StartTime;
SaveGameInfoWidget *m_CurrentSaveView;
@@ -381,7 +387,7 @@ private:
std::vector<QTreeWidgetItem*> m_RemoveWidget;
uint m_ArchiveListHash;
QByteArray m_ArchiveListHash;
bool m_DidUpdateMasterList;
@@ -478,7 +484,6 @@ private slots:
void modlistChanged(int row);
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);
@@ -510,6 +515,9 @@ private slots:
void startExeAction();
void checkBSAList();
void updateProblemsButton();
void saveModMetas();
void updateStyle(const QString &style);
@@ -551,9 +559,9 @@ private slots:
void delayedRemove();
void requestDownload(const QUrl &url, QNetworkReply *reply);
void profileRefresh();
private slots: // ui slots
void profileRefresh();
// actions
void on_actionAdd_Profile_triggered();
void on_actionInstallMod_triggered();
+1 -1
View File
@@ -212,7 +212,7 @@ p, li { white-space: pre-wrap; }
</size>
</property>
<property name="toolTip">
<string>Refresh list</string>
<string>Open list options...</string>
</property>
<property name="whatsThis">
<string>Refresh list. This is usually not necessary unless you modified data outside the program.</string>
+1
View File
@@ -81,6 +81,7 @@ void MessageDialog::resizeEvent(QResizeEvent *event)
void MessageDialog::showMessage(const QString &text, QWidget *reference, bool bringToFront)
{
qDebug("%s", qPrintable(text));
if (reference != NULL) {
if (bringToFront || (qApp->activeWindow() != NULL)) {
MessageDialog *dialog = new MessageDialog(text, reference);
+1 -1
View File
@@ -756,7 +756,7 @@ void ModInfoRegular::setNeverEndorse()
bool ModInfoRegular::remove()
{
m_MetaInfoChanged = false;
return shellDelete(QStringList(absolutePath()));
return shellDelete(QStringList(absolutePath()), true);
}
void ModInfoRegular::endorse(bool doEndorse)
+122 -109
View File
@@ -60,7 +60,7 @@ bool operator<(const ModFileListWidget &LHS, const ModFileListWidget &RHS)
}
ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directory, QWidget *parent)
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(NULL), m_RenameAction(NULL), m_OpenAction(NULL),
@@ -69,54 +69,19 @@ ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directo
ui->setupUi(this);
this->setWindowTitle(modInfo->name());
this->setWindowModality(Qt::WindowModal);
m_UTF8Codec = QTextCodec::codecForName("utf-8");
QListWidget *textFileList = findChild<QListWidget*>("textFileList");
QListWidget *iniTweaksList = findChild<QListWidget*>("iniTweaksList");
QListWidget *activeESPList = findChild<QListWidget*>("activeESPList");
QListWidget *inactiveESPList = findChild<QListWidget*>("inactiveESPList");
QTreeWidget *categoriesTree = findChild<QTreeWidget*>("categoriesTree");
QHBoxLayout *thumbnailArea = findChild<QHBoxLayout*>("thumbnailArea");
m_FileTree = findChild<QTreeView*>("fileTree");
m_RootPath = modInfo->absolutePath();
QString metaFileName = m_RootPath.mid(0).append("/meta.ini");
m_Settings = new QSettings(metaFileName, QSettings::IniFormat);
QLineEdit *modIDEdit = findChild<QLineEdit*>("modIDEdit");
modIDEdit->setValidator(new QIntValidator(modIDEdit));
modIDEdit->setText(QString("%1").arg(modInfo->getNexusID()));
ui->modIDEdit->setValidator(new QIntValidator(modIDEdit));
ui->modIDEdit->setText(QString("%1").arg(modInfo->getNexusID()));
ui->notesEdit->setText(modInfo->notes());
m_FileSystemModel = new QFileSystemModel(this);
m_FileSystemModel->setReadOnly(false);
m_FileSystemModel->setRootPath(m_RootPath);
m_FileTree->setModel(m_FileSystemModel);
m_FileTree->setRootIndex(m_FileSystemModel->index(m_RootPath));
m_FileTree->setColumnWidth(0, 300);
connect(&m_ThumbnailMapper, SIGNAL(mapped(const QString&)), this, SIGNAL(thumbnailClickedSignal(const QString&)));
connect(this, SIGNAL(thumbnailClickedSignal(const QString&)), this, SLOT(thumbnailClicked(const QString&)));
m_DeleteAction = new QAction(tr("&Delete"), m_FileTree);
m_RenameAction = new QAction(tr("&Rename"), m_FileTree);
m_HideAction = new QAction(tr("&Hide"), m_FileTree);
m_UnhideAction = new QAction(tr("&Unhide"), m_FileTree);
m_OpenAction = new QAction(tr("&Open"), m_FileTree);
m_NewFolderAction = new QAction(tr("&New Folder"), m_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()));
connect(m_ModInfo.data(), SIGNAL(modDetailsUpdated(bool)), this, SLOT(modDetailsUpdated(bool)));
// ui->descriptionView->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
// QObject::connect(ui->descriptionView, SIGNAL(linkClicked(QUrl)), this, SLOT(linkClicked(QUrl)));
connect(ui->descriptionView, SIGNAL(anchorClicked(QUrl)), this, SLOT(linkClicked(QUrl)));
if (directory->originExists(ToWString(modInfo->name()))) {
@@ -126,32 +91,39 @@ ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directo
}
}
addCategories(CategoryFactory::instance(), modInfo->getCategories(), categoriesTree->invisibleRootItem(), 0);
refreshPrimaryCategoriesBox();
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);
} else {
initFiletree(modInfo);
initINITweaks();
addCategories(CategoryFactory::instance(), modInfo->getCategories(), ui->categoriesTree->invisibleRootItem(), 0);
refreshPrimaryCategoriesBox();
}
refreshLists();
int numTweaks = m_Settings->beginReadArray("INI Tweaks");
for (int i = 0; i < numTweaks; ++i) {
m_Settings->setArrayIndex(i);
QList<QListWidgetItem*> items = iniTweaksList->findItems(m_Settings->value("name").toString(), Qt::MatchFixedString);
if (items.size() != 0) {
items.at(0)->setCheckState(Qt::Checked);
}
}
m_Settings->endArray();
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));
ui->tabWidget->setTabEnabled(TAB_CONFLICTS, m_Origin != NULL);
QTabWidget *tabWidget = findChild<QTabWidget*>("tabWidget");
tabWidget->setTabEnabled(TAB_TEXTFILES, textFileList->count() != 0);
tabWidget->setTabEnabled(TAB_IMAGES, thumbnailArea->count() != 0);
tabWidget->setTabEnabled(TAB_ESPS, (inactiveESPList->count() != 0) || (activeESPList->count() != 0));
tabWidget->setTabEnabled(TAB_CONFLICTS, m_Origin != NULL);
if (tabWidget->currentIndex() == TAB_NEXUS) {
if (ui->tabWidget->currentIndex() == TAB_NEXUS) {
activateNexusTab();
}
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;
}
}
}
@@ -165,6 +137,46 @@ ModInfoDialog::~ModInfoDialog()
}
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();
}
void ModInfoDialog::initFiletree(ModInfo::Ptr modInfo)
{
m_RootPath = modInfo->absolutePath();
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_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) {
@@ -271,51 +283,52 @@ void ModInfoDialog::refreshLists()
}
}
if (m_RootPath.length() > 0) {
QDirIterator dirIterator(m_RootPath, QDir::Files, QDirIterator::Subdirectories);
while (dirIterator.hasNext()) {
QString fileName = dirIterator.next();
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)) {
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);
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 {
image = image.scaledToHeight(96);
ui->iniFileList->addItem(namePart);
}
} else if (fileName.endsWith(".esp", Qt::CaseInsensitive) ||
fileName.endsWith(".esm", 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);
}
}
}
}
@@ -460,7 +473,8 @@ void ModInfoDialog::openIniFile(const QString &fileName)
QFile iniFile(fileName);
iniFile.open(QIODevice::ReadOnly);
QByteArray buffer = iniFile.readAll();
QTextCodec *codec = QTextCodec::codecForUtfText(buffer, m_UTF8Codec);
QTextCodec *codec = QTextCodec::codecForUtfText(buffer, QTextCodec::codecForName("utf-8"));
QTextEdit *iniFileView = findChild<QTextEdit*>("iniFileView");
iniFileView->setText(codec->toUnicode(buffer));
iniFileView->setProperty("currentFile", fileName);
@@ -929,7 +943,7 @@ void ModInfoDialog::renameTriggered()
return;
}
m_FileTree->edit(index);
ui->fileTree->edit(index);
}
@@ -999,18 +1013,18 @@ void ModInfoDialog::createDirectoryTriggered()
return;
}
m_FileTree->setCurrentIndex(newIndex);
m_FileTree->edit(newIndex);
ui->fileTree->setCurrentIndex(newIndex);
ui->fileTree->edit(newIndex);
}
void ModInfoDialog::on_fileTree_customContextMenuRequested(const QPoint &pos)
{
QItemSelectionModel *selectionModel = m_FileTree->selectionModel();
QItemSelectionModel *selectionModel = ui->fileTree->selectionModel();
m_FileSelection = selectionModel->selectedRows(0);
// m_FileSelection = m_FileTree->indexAt(pos);
QMenu menu(m_FileTree);
// m_FileSelection = ui->fileTree->indexAt(pos);
QMenu menu(ui->fileTree);
menu.addAction(m_NewFolderAction);
@@ -1038,7 +1052,7 @@ void ModInfoDialog::on_fileTree_customContextMenuRequested(const QPoint &pos)
m_FileSelection.clear();
m_FileSelection.append(m_FileSystemModel->index(m_FileSystemModel->rootPath(), 0));
}
menu.exec(m_FileTree->mapToGlobal(pos));
menu.exec(ui->fileTree->mapToGlobal(pos));
}
@@ -1164,18 +1178,17 @@ void ModInfoDialog::on_overwriteTree_customContextMenuRequested(const QPoint &po
{
m_ConflictsContextItem = ui->overwriteTree->itemAt(pos.x(), pos.y());
QMenu menu;
if (m_ConflictsContextItem != NULL) {
// offer to hide/unhide file, but not for files from archives
// if (!m_ConflictsContextItem->data(0, Qt::UserRole + 1).toBool()) {
if (!m_ConflictsContextItem->data(0, Qt::UserRole + 2).toBool()) {
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));
}
menu.exec(ui->overwriteTree->mapToGlobal(pos));
}
}
+5 -2
View File
@@ -65,6 +65,7 @@ public:
TAB_CONFLICTS,
TAB_CATEGORIES,
TAB_NEXUS,
TAB_NOTES,
TAB_FILETREE
};
@@ -76,7 +77,7 @@ public:
* @param modInfo info structure about the mod to display
* @param parent parend widget
**/
explicit ModInfoDialog(ModInfo::Ptr modInfo, const MOShared::DirectoryEntry *directory, QWidget *parent = 0);
explicit ModInfoDialog(ModInfo::Ptr modInfo, const MOShared::DirectoryEntry *directory, bool unmanaged, QWidget *parent = 0);
~ModInfoDialog();
/**
@@ -121,6 +122,9 @@ public slots:
private:
void initFiletree(ModInfo::Ptr modInfo);
void initINITweaks();
void refreshLists();
void addCategories(const CategoryFactory &factory, const std::set<int> &enabledCategories, QTreeWidgetItem *root, int rootLevel);
@@ -225,7 +229,6 @@ private:
const MOShared::DirectoryEntry *m_Directory;
MOShared::FilesOrigin *m_Origin;
QTextCodec *m_UTF8Codec;
std::map<int, int> m_RealTabPos;
+21 -16
View File
@@ -166,25 +166,29 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const
return QVariant();
}
} else if (column == COL_CATEGORY) {
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());
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 {
qWarning("category %d doesn't exist (may have been removed)", category);
modInfo->setCategory(category, false);
return QString();
//return tr("None");
return QVariant();
}
} else {
//return tr("None");
return QVariant();
}
} else if (column == COL_INSTALLTIME) {
// display installation time for mods that can be updated
@@ -253,6 +257,8 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const
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);
@@ -650,7 +656,6 @@ bool ModList::setPriority(const QString &name, int newPriority)
}
}
bool ModList::onModStateChanged(const std::function<void (const QString &, IModList::ModStates)> &func)
{
auto conn = m_ModStateChanged.connect(func);
+12
View File
@@ -248,6 +248,12 @@ bool ModListSortProxy::filterMatchesModAnd(ModInfo::Ptr info, bool enabled) cons
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;
@@ -279,6 +285,12 @@ bool ModListSortProxy::filterMatchesModOr(ModInfo::Ptr info, bool enabled) const
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;
+1 -1
View File
@@ -122,7 +122,7 @@ void NXMAccessManager::login(const QString &username, const QString &password)
void NXMAccessManager::pageLogin()
{
QString requestString = QString("http://gatekeeper.nexusmods.com/Sessions/?Login&uri=%1")
QString requestString = (ToQString(GameInfo::instance().getNexusPage()) + "/sessions/?Login&uri=%1")
.arg(QString(QUrl::toPercentEncoding(ToQString(GameInfo::instance().getNexusPage()))));
QNetworkRequest request(requestString);
+4 -3
View File
@@ -221,9 +221,9 @@ CONFIG(debug, debug|release) {
LIBS += -L$$OUT_PWD/../bsatk/release
LIBS += -L$$OUT_PWD/../uibase/release
LIBS += -L$$OUT_PWD/../boss_modified/release
QMAKE_CXXFLAGS += /Zi# /GL
QMAKE_CXXFLAGS += /Zi /GL
# QMAKE_CXXFLAGS -= -O2
QMAKE_LFLAGS += /DEBUG# /LTCG /OPT:REF /OPT:ICF
QMAKE_LFLAGS += /DEBUG /LTCG /OPT:REF /OPT:ICF
}
#QMAKE_CXXFLAGS_WARN_ON -= -W3
@@ -321,7 +321,8 @@ OTHER_FILES += \
dark.qss \
stylesheets/dark.qss \
tutorials/tutorial_window_installer.js \
tutorials/tutorials_installdialog.qml
tutorials/tutorials_installdialog.qml \
tutorials/tutorial_firststeps_settings.js
# leak detection with vld
+1760 -2994
View File
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More