summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTannin <devnull@localhost>2013-02-22 19:28:54 +0100
committerTannin <devnull@localhost>2013-02-22 19:28:54 +0100
commit8b4e11060b37ad70754aa665ad59744eadd2dd1e (patch)
tree3e0dd354a519a6c6af18fe6d233d03fdb1f6ca62
parentcb297d20b616e49803470396c21dd5747370cfaf (diff)
- bugfix: update on overwrite directory leads files incorrectly being assigned to it
- bugfix: getfullpathname reroute now correctly handles relative paths - bugfix: cwd change to overwrite is now handled too - bugfix: using the external fomod installer to merge a mod caused error messages because directories couldn't be renamed - bugfix: The memory for file dialogs wasn't saved to the ini file - file category (main, update, optional, old) is now stored with the download for future use - when overwriting a mod, the version of the mod is only increased, never reduced. This is less correct for the unusual case that the user is downgrading but more correct for the more commen case he is installing an optional file with incorrect version number - the install mod dialog now uses the file dialog memory
-rw-r--r--src/downloadmanager.cpp2
-rw-r--r--src/filedialogmemory.cpp150
-rw-r--r--src/installationmanager.cpp36
-rw-r--r--src/mainwindow.cpp7
-rw-r--r--src/modlist.cpp1
-rw-r--r--src/nexusinterface.cpp3
-rw-r--r--src/profile.cpp2
-rw-r--r--src/shared/directoryentry.cpp2
-rw-r--r--src/shared/directoryentry.h1
-rw-r--r--src/shared/util.cpp36
-rw-r--r--src/shared/util.h3
-rw-r--r--src/version.rc4
12 files changed, 148 insertions, 99 deletions
diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp
index 2700e598..24e20bc6 100644
--- a/src/downloadmanager.cpp
+++ b/src/downloadmanager.cpp
@@ -144,7 +144,6 @@ void DownloadManager::refreshList()
DownloadInfo *info = new DownloadInfo;
info->m_State = STATE_READY;
if (file.endsWith(UNFINISHED)) {
-#pragma message("files not correctly named _unfinished")
info->m_FileName = file.mid(0, file.length() - strlen(UNFINISHED));
info->m_State = STATE_PAUSED;
} else {
@@ -624,6 +623,7 @@ void DownloadManager::createMetaFile(DownloadInfo *info)
metaFile.setValue("name", info->m_NexusInfo.m_Name);
metaFile.setValue("modName", info->m_NexusInfo.m_ModName);
metaFile.setValue("version", info->m_NexusInfo.m_Version);
+ metaFile.setValue("fileCategory", info->m_NexusInfo.m_FileCategory);
metaFile.setValue("newestVersion", info->m_NexusInfo.m_NewestVersion);
metaFile.setValue("category", info->m_NexusInfo.m_Category);
metaFile.setValue("installed", info->m_State == DownloadManager::STATE_INSTALLED);
diff --git a/src/filedialogmemory.cpp b/src/filedialogmemory.cpp
index 86bf22c3..f614e76d 100644
--- a/src/filedialogmemory.cpp
+++ b/src/filedialogmemory.cpp
@@ -17,78 +17,78 @@ You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "filedialogmemory.h"
-#include <QFileDialog>
-
-
-FileDialogMemory::FileDialogMemory()
-{
-}
-
-
-void FileDialogMemory::save(QSettings &settings)
-{
- settings.remove("recentDirectories");
- settings.beginWriteArray("recentDirectories");
- int index = 0;
- for (std::map<QString, QString>::const_iterator iter = instance().m_Cache.begin();
- iter != instance().m_Cache.end(); ++iter) {
- settings.setArrayIndex(index++);
- settings.setValue("name", iter->first);
- settings.setValue("directory", iter->second);
- }
- settings.endArray();
-}
-
-
-void FileDialogMemory::restore(QSettings &settings)
-{
- int size = settings.beginReadArray("recentDirectories");
- for (int i = 0; i < size; ++i) {
- settings.setArrayIndex(i);
- QVariant name = settings.value("name");
- QVariant dir = settings.value("directory");
- if (name.isValid() && dir.isValid()) {
- instance().m_Cache.insert(std::make_pair(name.toString(), dir.toString()));
- }
- }
- settings.endArray();
-}
-
-
-QString FileDialogMemory::getOpenFileName(const QString &dirID, QWidget *parent,
- const QString &caption, const QString &dir,
- const QString &filter, QString *selectedFilter,
- QFileDialog::Options options)
-{
- std::pair<std::map<QString, QString>::iterator, bool> currentDir =
- instance().m_Cache.insert(std::make_pair(dirID, dir));
-
- QString result = QFileDialog::getOpenFileName(parent, caption, currentDir.first->second,
- filter, selectedFilter, options);
- if (!result.isNull()) {
- instance().m_Cache[dirID] = QFileInfo(result).path();
- }
- return result;
-}
-
-
-QString FileDialogMemory::getExistingDirectory(const QString &dirID, QWidget *parent,
- const QString &caption, const QString &dir, QFileDialog::Options options)
-{
- std::pair<std::map<QString, QString>::iterator, bool> currentDir =
- instance().m_Cache.insert(std::make_pair(dirID, dir));
-
- QString result = QFileDialog::getExistingDirectory(parent, caption, currentDir.first->second, options);
- if (!result.isNull()) {
- instance().m_Cache[dirID] = QFileInfo(result).path();
- }
- return result;
-}
-
-
-FileDialogMemory &FileDialogMemory::instance()
-{
- static FileDialogMemory instance;
- return instance;
-}
+#include "filedialogmemory.h"
+#include <QFileDialog>
+
+
+FileDialogMemory::FileDialogMemory()
+{
+}
+
+
+void FileDialogMemory::save(QSettings &settings)
+{
+ settings.remove("recentDirectories");
+ settings.beginWriteArray("recentDirectories");
+ int index = 0;
+ for (std::map<QString, QString>::const_iterator iter = instance().m_Cache.begin();
+ iter != instance().m_Cache.end(); ++iter) {
+ settings.setArrayIndex(index++);
+ settings.setValue("name", iter->first);
+ settings.setValue("directory", iter->second);
+ }
+ settings.endArray();
+}
+
+
+void FileDialogMemory::restore(QSettings &settings)
+{
+ int size = settings.beginReadArray("recentDirectories");
+ for (int i = 0; i < size; ++i) {
+ settings.setArrayIndex(i);
+ QVariant name = settings.value("name");
+ QVariant dir = settings.value("directory");
+ if (name.isValid() && dir.isValid()) {
+ instance().m_Cache.insert(std::make_pair(name.toString(), dir.toString()));
+ }
+ }
+ settings.endArray();
+}
+
+
+QString FileDialogMemory::getOpenFileName(const QString &dirID, QWidget *parent,
+ const QString &caption, const QString &dir,
+ const QString &filter, QString *selectedFilter,
+ QFileDialog::Options options)
+{
+ std::pair<std::map<QString, QString>::iterator, bool> currentDir =
+ instance().m_Cache.insert(std::make_pair(dirID, dir));
+
+ QString result = QFileDialog::getOpenFileName(parent, caption, currentDir.first->second,
+ filter, selectedFilter, options);
+ if (!result.isNull()) {
+ instance().m_Cache[dirID] = QFileInfo(result).path();
+ }
+ return result;
+}
+
+
+QString FileDialogMemory::getExistingDirectory(const QString &dirID, QWidget *parent,
+ const QString &caption, const QString &dir, QFileDialog::Options options)
+{
+ std::pair<std::map<QString, QString>::iterator, bool> currentDir =
+ instance().m_Cache.insert(std::make_pair(dirID, dir));
+
+ QString result = QFileDialog::getExistingDirectory(parent, caption, currentDir.first->second, options);
+ if (!result.isNull()) {
+ instance().m_Cache[dirID] = QFileInfo(result).path();
+ }
+ return result;
+}
+
+
+FileDialogMemory &FileDialogMemory::instance()
+{
+ static FileDialogMemory instance;
+ return instance;
+}
diff --git a/src/installationmanager.cpp b/src/installationmanager.cpp
index b1b7ff6c..27dfea6e 100644
--- a/src/installationmanager.cpp
+++ b/src/installationmanager.cpp
@@ -26,7 +26,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "fomodinstallerdialog.h"
#include "report.h"
#include "categories.h"
-#include <scopeguard.h>
#include "questionboxmemory.h"
#include "settings.h"
#include "queryoverwritedialog.h"
@@ -35,8 +34,10 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "iplugininstallercustom.h"
#include "nexusinterface.h"
#include "selectiondialog.h"
+#include <scopeguard.h>
#include <installationtester.h>
#include <gameinfo.h>
+#include <utility.h>
#include <QFileInfo>
#include <QLibrary>
#include <QInputDialog>
@@ -625,7 +626,9 @@ bool InstallationManager::doInstall(const QString &modsDirectory, QString &modNa
if ((modID != 0) || !settingsFile.contains("modid")) {
settingsFile.setValue("modid", modID);
}
- if (!version.isEmpty() || !settingsFile.contains("version")) {
+ if (!settingsFile.contains("version") ||
+ (!version.isEmpty() &&
+ (VersionInfo(version) >= VersionInfo(settingsFile.value("version").toString())))) {
settingsFile.setValue("version", version);
}
if (!newestVersion.isEmpty() || !settingsFile.contains("newestVersion")) {
@@ -800,7 +803,7 @@ bool InstallationManager::installFomodExternal(const QString &fileName, const QS
QFile::copy(QDir::fromNativeSeparators(ToQString(gameInfo.getGameDirectory().append(L"\\").append(gameInfo.getBinaryName()))),
binaryDestination);
- ON_BLOCK_EXIT([&binaryDestination] { QFile::remove(binaryDestination); } );
+ ON_BLOCK_EXIT([&binaryDestination] { if (!QFile::remove(binaryDestination)) qCritical("failed to remove %s", qPrintable(binaryDestination)); } );
SHELLEXECUTEINFOW execInfo = {0};
execInfo.cbSize = sizeof(SHELLEXECUTEINFOW);
@@ -851,28 +854,31 @@ bool InstallationManager::installFomodExternal(const QString &fileName, const QS
::CloseHandle(execInfo.hProcess);
-
if ((exitCode == 0) || (exitCode == 10)) { // 0 = success, 10 = incomplete installation
bool errorOccured = false;
{ // move all installed files from the data directory one directory up
- QDirIterator dirIter(QDir(modDirectory).absoluteFilePath("Data"), QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
+ QDir targetDir(modDirectory);
+
+ QDirIterator dirIter(targetDir.absoluteFilePath("Data"), QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
bool hasFiles = false;
+
while (dirIter.hasNext()) {
dirIter.next();
QFileInfo fileInfo = dirIter.fileInfo();
-
- QDir dir(fileInfo.absolutePath());
- dir.cdUp();
- QString newName = dir.absoluteFilePath(fileInfo.fileName());
- if (QFile::exists(newName)) {
+ QString newName = targetDir.absoluteFilePath(fileInfo.fileName());
+ if (fileInfo.isFile() && QFile::exists(newName)) {
if (!QFile::remove(newName)) {
qCritical("failed to overwrite %s", qPrintable(newName));
errorOccured = true;
}
- }
+ } // if it's a directory and the target exists that isn't really a problem
+
if (!QFile::rename(fileInfo.absoluteFilePath(), newName)) {
- qCritical("failed to move %s to %s", qPrintable(fileInfo.absoluteFilePath()), qPrintable(newName));
- errorOccured = true;
+ // moving doesn't work when merging
+ if (!copyDir(fileInfo.absoluteFilePath(), newName, true)) {
+ qCritical("failed to move %s to %s", qPrintable(fileInfo.absoluteFilePath()), qPrintable(newName));
+ errorOccured = true;
+ }
}
hasFiles = true;
}
@@ -1110,7 +1116,9 @@ bool InstallationManager::install(const QString &fileName, const QString &plugin
if ((modID != 0) || !settingsFile.contains("modid")) {
settingsFile.setValue("modid", modID);
}
- if (!version.isEmpty() || !settingsFile.contains("version")) {
+ if (!settingsFile.contains("version") ||
+ (!version.isEmpty() &&
+ (VersionInfo(version) >= VersionInfo(settingsFile.value("version").toString())))) {
settingsFile.setValue("version", version);
}
if (!newestVersion.isEmpty() || !settingsFile.contains("newestVersion")) {
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 71cb1c9d..ac368719 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -1616,6 +1616,8 @@ void MainWindow::storeSettings()
QComboBox *executableBox = findChild<QComboBox*>("executablesListBox");
settings.setValue("selected_executable", executableBox->currentIndex());
+
+ FileDialogMemory::save(m_Settings.directInterface());
}
@@ -1693,9 +1695,8 @@ void MainWindow::installMod()
*iter = "*." + *iter;
}
- QString fileName = QFileDialog::getOpenFileName(this,
- tr("Choose Mod"), QString(),
- tr("Mod Archive").append(QString(" (%1)").arg(extensions.join(" "))));
+ QString fileName = FileDialogMemory::getOpenFileName("installMod", this, tr("Choose Mod"), QString(),
+ tr("Mod Archive").append(QString(" (%1)").arg(extensions.join(" "))));
if (fileName.length() == 0) {
return;
diff --git a/src/modlist.cpp b/src/modlist.cpp
index 680e0af5..e70e3c31 100644
--- a/src/modlist.cpp
+++ b/src/modlist.cpp
@@ -294,6 +294,7 @@ bool ModList::renameMod(int index, const QString &newName)
emit modRenamed(oldName, newName);
// invalidate the currently displayed state of this list
+#pragma message("why is this necessary? It unselects the current selection")
notifyChange(-1);
return true;
}
diff --git a/src/nexusinterface.cpp b/src/nexusinterface.cpp
index 016cdeef..2a53235d 100644
--- a/src/nexusinterface.cpp
+++ b/src/nexusinterface.cpp
@@ -365,7 +365,8 @@ void NexusInterface::nextRequest()
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml");
- request.setRawHeader("User-Agent", QString("Mod Organizer v0.12.0 (compatible to Nexus Client v%1)").arg(m_NMMVersion).toUtf8());
+#pragma message("automatically insert the correct version number")
+ request.setRawHeader("User-Agent", QString("Mod Organizer v0.12.8 (compatible to Nexus Client v%1)").arg(m_NMMVersion).toUtf8());
info.m_Reply = m_AccessManager->get(request);
diff --git a/src/profile.cpp b/src/profile.cpp
index 4892fd78..002c93c0 100644
--- a/src/profile.cpp
+++ b/src/profile.cpp
@@ -133,7 +133,7 @@ void Profile::cancelWriteModlist() const
void Profile::writeModlistNow() const
{
m_SaveTimer->stop();
-#pragma message("right now, we're doing unnecessary saves. We need a flag that says that mod priority, enabled-state or name of a mod has changed")
+#pragma message("right now, this is doing unnecessary saves. Need a flag that says that mod priority, enabled-state or name of a mod has changed")
QString fileName = getModlistFileName();
QFile file(fileName);
diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp
index eaba91a6..abf9affb 100644
--- a/src/shared/directoryentry.cpp
+++ b/src/shared/directoryentry.cpp
@@ -155,7 +155,7 @@ void FilesOrigin::setPriority(int priority)
{
m_OriginConnection->changePriorityLookup(m_Priority, priority);
- m_Priority = priority;
+ m_Priority = priority;
}
diff --git a/src/shared/directoryentry.h b/src/shared/directoryentry.h
index e292861d..c6d155de 100644
--- a/src/shared/directoryentry.h
+++ b/src/shared/directoryentry.h
@@ -31,6 +31,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <boost/shared_ptr.hpp>
#include "util.h"
+
namespace MOShared {
diff --git a/src/shared/util.cpp b/src/shared/util.cpp
index c256e959..a6378a74 100644
--- a/src/shared/util.cpp
+++ b/src/shared/util.cpp
@@ -19,8 +19,11 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "util.h"
#include "windows_error.h"
+#include "error_report.h"
+
#include <sstream>
#include <algorithm>
+#include <DbgHelp.h>
namespace MOShared {
@@ -119,4 +122,35 @@ VS_FIXEDFILEINFO GetFileVersion(const std::wstring &fileName)
}
}
-} // namespace MOShared
+
+
+
+std::string GetStack()
+{
+#ifdef DEBUG
+ HANDLE process = ::GetCurrentProcess();
+ static bool firstCall = true;
+ if (firstCall) {
+ ::SymInitialize(process, NULL, TRUE);
+ firstCall = false;
+ }
+
+ LPVOID stack[32];
+ WORD frames = ::CaptureStackBackTrace(0, 100, stack, NULL);
+ SYMBOL_INFO_PACKAGE symbol;
+ symbol.si.SizeOfStruct = sizeof(SYMBOL_INFO);
+ symbol.si.MaxNameLen = MAX_SYM_NAME;
+
+ std::ostringstream stackStream;
+ for(unsigned int i = 0; i < frames; ++i) {
+ ::SymFromAddr(process, (DWORD64)(stack[i]), 0, &symbol.si);
+ stackStream << frames - i - 1 << ": " << symbol.si.Name << "\n";
+ }
+ return stackStream.str();
+#else
+ return "";
+#endif
+}
+
+
+} // namespace MOShared
diff --git a/src/shared/util.h b/src/shared/util.h
index 4faf0a30..9c59f6db 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -45,6 +45,9 @@ std::wstring ToLower(const std::wstring &text);
VS_FIXEDFILEINFO GetFileVersion(const std::wstring &fileName);
+/// Get a stack trace as a line-break separated list of function names. This only works in debug builds
+std::string GetStack();
+
} // namespace MOShared
#endif // UTIL_H
diff --git a/src/version.rc b/src/version.rc
index bc952c2a..23f7b6e3 100644
--- a/src/version.rc
+++ b/src/version.rc
@@ -1,7 +1,7 @@
#include "Winver.h"
-#define VER_FILEVERSION 0,12,7,0
-#define VER_FILEVERSION_STR 0,12,7,0
+#define VER_FILEVERSION 0,12,8,0
+#define VER_FILEVERSION_STR 0,12,8,0
VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILEVERSION