summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.txt14
-rw-r--r--src/SConscript34
-rw-r--r--src/downloadmanager.h14
-rw-r--r--src/installationmanager.cpp14
-rw-r--r--src/mainwindow.cpp103
-rw-r--r--src/mainwindow.h2
-rw-r--r--src/mainwindow.ui8
-rw-r--r--src/moapplication.cpp2
-rw-r--r--src/moapplication.h2
-rw-r--r--src/organizer.pro3
-rw-r--r--src/plugincontainer.cpp4
-rw-r--r--src/queryoverwritedialog.cpp3
-rw-r--r--src/queryoverwritedialog.h7
-rw-r--r--src/savegamegamebyro.h3
-rw-r--r--src/savegameinfowidgetgamebryo.cpp6
-rw-r--r--src/savetextasdialog.cpp4
-rw-r--r--src/shared/SConscript3
17 files changed, 192 insertions, 34 deletions
diff --git a/README.txt b/README.txt
index 2e14f4d8..637d0910 100644
--- a/README.txt
+++ b/README.txt
@@ -227,6 +227,13 @@ Troubleshooting (thanks to Ross):
Complains about 'qtwebkit4' missing. For some reason this seems to insist on
living with modorganiser.exe
+6) Debugging the python proxy: I (TT) don't think this is possible unless you have a debug
+ build of PyQt. However, a debug build of PyQt requires a debug build of python. There doesn't
+ appear to be a half way house which is build wiht normal python but debug versions of QT libraries.
+ You can confuse pyqt by copying the debug QT DLLs to appropriate named files in the DLLs
+ directory, and removing QT from your project run path, which results in the python proxy
+ initialising succesfully, but causes mod organiser to crash in strange places.
+
-------------------
Building with scons
-------------------
@@ -235,8 +242,7 @@ Building with scons
2) Download QT4 (and/or QT5) from https://bitbucket.org/dirkbaechle/scons_qt4 and
https://bitbucket.org/dirkbaechle/scons_qt5. Install as per instructions
3) Copy scons_configure_template.py to scons_configure.py. Edit to point to your
- boost/python/zlib/7zip paths as appropriate (you can create an empty one if
- you set up the params in qt creator)
+ boost/python/zlib/7zip/loot directories as appropriate.
4) Create build kits as follows:
Custom Process step:
Command: <python path>\Scripts\scons.bat
@@ -262,4 +268,6 @@ Building with scons
Please note: the generated (runnable) output files end up in the build directory,
in the '_ModOrganizer' subdirectory (not at the top level). Named like that
- so you can see it!
+ so you can see it! The scons build will also populate the directory with
+ all the necessary DLLs (but see note 6 above about your build tool path if
+ trying to debug).
diff --git a/src/SConscript b/src/SConscript
index 2eeb869e..6783fd8b 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -13,27 +13,24 @@ modules = [
'Sql',
'WebKit',
'Xml',
- 'XmlPatterns'
+ 'XmlPatterns',
+ 'Declarative'
]
if env['QT_MAJOR_VERSION'] > 4:
modules += [
'Widgets',
'Qml',
- 'Quick',
'WebKitWidgets'
]
-else:
- modules += [
- 'Declarative'
- ]
env.EnableQtModules(*modules)
-env.Uic4(env.Glob('*.ui'))
+env.Uic(env.Glob('*.ui'))
env.RequireLibraries('uibase', 'shared', 'bsatk', 'esptk')
+
env.AppendUnique(LIBS = [
'shell32',
'user32',
@@ -50,6 +47,7 @@ env.AppendUnique(LIBS = [
other_sources = env.AddExtraMoc(env.Glob('*.h'))
for file in env.Glob('*.rc'):
+ # version.rc is included in app_icon.rc. Not sure why it's a separate file.
if file.name == 'version.rc':
continue
other_sources.append(env.RES(file))
@@ -58,8 +56,10 @@ for file in env.Glob('*.rc'):
# Doing appendunique seems to throw the moc code into a tizzy
env['CPPPATH'] += [
'../archive',
- '../boss_modified/boss-api',
+# '../boss_modified/boss-api',
+ '../plugins/gamefeatures',
'.', # Why is this necessary?
+ '${LOOTPATH}',
'${BOOSTPATH}',
]
@@ -67,11 +67,9 @@ env.AppendUnique(CPPDEFINES = [
'_UNICODE',
'_CRT_SECURE_NO_WARNINGS',
'_SCL_SECURE_NO_WARNINGS',
- 'NOMINMAX',
'BOOST_DISABLE_ASSERTS',
-# Although the .pro file says it adds this, the compile line doesn't seem to
-# have it (unless it's in the annoying '@' file
-# 'NDEBUG'
+ 'NDEBUG',
+ 'QT_MESSAGELOGCONTEXT'
])
env.AppendUnique(CPPFLAGS = [ '-wd4100', '-wd4127', '-wd4512', '-wd4189' ])
@@ -88,11 +86,18 @@ cpp_files = [
]
about_env = env.Clone()
-hgid = subprocess.check_output(['hg', 'id', '-i']).rstrip()
+try:
+ hgid = subprocess.check_output(['hg', 'id', '-i']).rstrip()
+except:
+ hgid = 'Unknown version'
+
# FIXME: It'd be much easier to stringify this in the source code
about_env.AppendUnique(CPPDEFINES = [ 'HGID=\\"%s\\"' % hgid ])
other_sources.append(about_env.StaticObject('aboutdialog.cpp'))
+env.AppendUnique(LIBPATH = "${ZLIBPATH}/build")
+env.AppendUnique(LIBS = 'zlibstatic')
+
prog = env.Program('ModOrganizer',
cpp_files + env.Glob('*.qrc') + other_sources)
@@ -104,6 +109,9 @@ for subdir in ('tutorials', 'stylesheets'):
# FIXME Sort the translations. Except they don't exist on the 1.2 branch
+res = env['QT_USED_MODULES']
+Return('res')
+
"""
CONFIG(debug, debug|release) {
} else {
diff --git a/src/downloadmanager.h b/src/downloadmanager.h
index c077ae79..5d047766 100644
--- a/src/downloadmanager.h
+++ b/src/downloadmanager.h
@@ -426,8 +426,22 @@ private slots:
private:
void createMetaFile(DownloadInfo *info);
+
+public:
+
+ /** Get a unique filename for a download.
+ *
+ * This allows you multiple versions of download files, useful if the file
+ * comes from a web site with no version control
+ *
+ * @param basename: Name of the file
+ *
+ * @return Unique(ish) name
+ */
QString getDownloadFileName(const QString &baseName) const;
+private:
+
void startDownload(QNetworkReply *reply, DownloadInfo *newDownload, bool resume);
void resumeDownloadInt(int index);
diff --git a/src/installationmanager.cpp b/src/installationmanager.cpp
index 7d431f02..b55d8d3a 100644
--- a/src/installationmanager.cpp
+++ b/src/installationmanager.cpp
@@ -414,11 +414,7 @@ void InstallationManager::updateProgressFile(LPCWSTR fileName)
void InstallationManager::report7ZipError(LPCWSTR errorMessage)
{
-#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
- m_InstallationProgress.setLabelText(QString::fromWCharArray(errorMessage));
-#else
- reportError(QString::fromUtf16(errorMessage));
-#endif
+ reportError(QString::fromWCharArray(errorMessage));
m_CurrentArchive->cancel();
}
@@ -443,8 +439,12 @@ bool InstallationManager::testOverwrite(GuessedValue<QString> &modName, bool *me
{
QString targetDirectory = QDir::fromNativeSeparators(m_ModsDirectory + "\\" + modName);
while (QDir(targetDirectory).exists()) {
- QueryOverwriteDialog overwriteDialog(m_ParentWidget);
+ Settings &settings(Settings::instance());
+ bool backup = settings.directInterface().value("backup_install", false).toBool();
+ QueryOverwriteDialog overwriteDialog(m_ParentWidget,
+ backup ? QueryOverwriteDialog::BACKUP_YES : QueryOverwriteDialog::BACKUP_NO);
if (overwriteDialog.exec()) {
+ settings.directInterface().setValue("backup_install", overwriteDialog.backup());
if (overwriteDialog.backup()) {
QString backupDirectory = generateBackupName(targetDirectory);
if (!copyDir(targetDirectory, backupDirectory, false)) {
@@ -545,7 +545,7 @@ bool InstallationManager::doInstall(GuessedValue<QString> &modName, int modID,
m_InstallationProgress.setValue(0);
m_InstallationProgress.setWindowModality(Qt::WindowModal);
m_InstallationProgress.show();
- if (!m_CurrentArchive->extract(ToWString(QDir::toNativeSeparators(targetDirectory)).c_str(),
+ if (!m_CurrentArchive->extract(ToWString("\\\\?\\" + QDir::toNativeSeparators(targetDirectory)).c_str(),
new MethodCallback<InstallationManager, void, float>(this, &InstallationManager::updateProgress),
new MethodCallback<InstallationManager, void, LPCWSTR>(this, &InstallationManager::updateProgressFile),
new MethodCallback<InstallationManager, void, LPCWSTR>(this, &InstallationManager::report7ZipError))) {
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index d36ec158..7dba6c72 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -110,6 +110,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonValue>
+#include <QMimeData>
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QtConcurrent/QtConcurrentRun>
#else
@@ -4577,3 +4578,105 @@ void MainWindow::on_manageArchivesBox_toggled(bool)
{
m_OrganizerCore.refreshBSAList();
}
+
+void MainWindow::dragEnterEvent(QDragEnterEvent *event)
+{
+ //Accept copy or move drags to the download window. Link drags are not
+ //meaningful (Well, they are - we could drop a link in the download folder,
+ //but you need privileges to do that).
+ if (ui->downloadTab->isVisible() &&
+ (event->proposedAction() == Qt::CopyAction ||
+ event->proposedAction() == Qt::MoveAction) &&
+ event->answerRect().intersects(ui->downloadTab->rect())) {
+
+ //If I read the documentation right, this won't work under a motif windows
+ //manager and the check needs to be done at the drop. However, that means
+ //the user might be allowed to drop things which we can't sanely process
+ QMimeData const *data = event->mimeData();
+
+ if (data->hasUrls()) {
+ QStringList extensions =
+ m_OrganizerCore.installationManager()->getSupportedExtensions();
+
+ //This is probably OK - scan to see if these are moderately sane archive
+ //types
+ QList<QUrl> urls = data->urls();
+ bool ok = true;
+ for (auto url : urls) {
+ if (url.isLocalFile()) {
+ QString local = url.toLocalFile();
+ bool fok = false;
+ for (auto ext : extensions) {
+ if (local.endsWith(ext, Qt::CaseInsensitive)) {
+ fok = true;
+ break;
+ }
+ }
+ if (! fok) {
+ ok = false;
+ break;
+ }
+ }
+ //We should probably allow the user to drop urls here and remember the
+ //url for installing later.
+ }
+ if (ok) {
+ event->accept();
+ }
+ }
+ }
+}
+
+void MainWindow::dropEvent(QDropEvent *event)
+{
+ Qt::DropAction action = event->proposedAction();
+ QString output_dir = m_OrganizerCore.downloadManager()->getOutputDirectory();
+ if (action == Qt::MoveAction) {
+ //Tell windows I'm taking control and will delete the source of a move.
+ event->setDropAction(Qt::TargetMoveAction);
+ }
+ for (auto url : event->mimeData()->urls()) {
+ QFileInfo file(url.toLocalFile());
+ QString target = output_dir + "/" + file.fileName();
+ if (QFile::exists(target)) {
+ QMessageBox box(QMessageBox::Question,
+ file.fileName(),
+ tr("A file with the same name has already been downloaded. "
+ "What would you like to do?"));
+ box.addButton(tr("Overwrite"), QMessageBox::ActionRole);
+ box.addButton(tr("Rename new file"), QMessageBox::YesRole);
+ box.addButton(tr("Ignore file"), QMessageBox::RejectRole);
+
+ box.exec();
+ QMessageBox::ButtonRole role = box.buttonRole(box.clickedButton());
+ switch (role)
+ {
+ case QMessageBox::RejectRole:
+ continue;
+
+ case QMessageBox::ActionRole:
+ break;
+
+ default:
+ case QMessageBox::YesRole:
+ target = m_OrganizerCore.downloadManager()->getDownloadFileName(file.fileName());
+ break;
+
+ }
+ }
+
+ if (action == Qt::MoveAction) {
+ if (shellMove(file.absoluteFilePath(), target, true, this)) {
+ continue;
+ }
+ }
+ else {
+ if (shellCopy(file.absoluteFilePath(), target, true, this)) {
+ continue;
+ }
+ }
+ //Something has gone horribly wrong here
+ qDebug("error %d", GetLastError());
+ }
+ event->accept();
+}
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 51d67e1e..7e59a7b0 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -157,6 +157,8 @@ protected:
virtual void closeEvent(QCloseEvent *event);
virtual bool eventFilter(QObject *obj, QEvent *event);
virtual void resizeEvent(QResizeEvent *event);
+ virtual void dragEnterEvent(QDragEnterEvent *event);
+ virtual void dropEvent(QDropEvent *event);
private:
diff --git a/src/mainwindow.ui b/src/mainwindow.ui
index 4201babf..ca93ea54 100644
--- a/src/mainwindow.ui
+++ b/src/mainwindow.ui
@@ -10,6 +10,9 @@
<height>710</height>
</rect>
</property>
+ <property name="acceptDrops">
+ <bool>true</bool>
+ </property>
<property name="windowTitle">
<string notr="true">Mod Organizer</string>
</property>
@@ -1140,11 +1143,14 @@ p, li { white-space: pre-wrap; }
<property name="contextMenuPolicy">
<enum>Qt::PreventContextMenu</enum>
</property>
+ <property name="acceptDrops">
+ <bool>true</bool>
+ </property>
<property name="toolTip">
<string/>
</property>
<property name="whatsThis">
- <string>This is a list of mods you downloaded from Nexus. Double click one to install it.</string>
+ <string>This is a list of mods you downloaded from Nexus. Double click one to install it. You can also drag an archive into here.</string>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOn</enum>
diff --git a/src/moapplication.cpp b/src/moapplication.cpp
index e25591d8..07e6ac39 100644
--- a/src/moapplication.cpp
+++ b/src/moapplication.cpp
@@ -76,7 +76,7 @@ public:
};
-MOApplication::MOApplication(int argc, char **argv)
+MOApplication::MOApplication(int &argc, char **argv)
: QApplication(argc, argv)
{
connect(&m_StyleWatcher, SIGNAL(fileChanged(QString)), SLOT(updateStyle(QString)));
diff --git a/src/moapplication.h b/src/moapplication.h
index cf6bc625..9db130af 100644
--- a/src/moapplication.h
+++ b/src/moapplication.h
@@ -28,7 +28,7 @@ class MOApplication : public QApplication {
Q_OBJECT
public:
- MOApplication(int argc, char **argv);
+ MOApplication(int &argc, char **argv);
virtual bool notify (QObject *receiver, QEvent *event);
diff --git a/src/organizer.pro b/src/organizer.pro
index 340fbc72..8424ac3f 100644
--- a/src/organizer.pro
+++ b/src/organizer.pro
@@ -358,6 +358,9 @@ CONFIG(debug, debug|release) {
}
}
+OTHER_FILES += \
+ SConscript
+
DISTFILES += \
tutorials/tutorial_primer_main.js \
tutorials/Tooltip.qml \
diff --git a/src/plugincontainer.cpp b/src/plugincontainer.cpp
index 738a4cec..f741e0dc 100644
--- a/src/plugincontainer.cpp
+++ b/src/plugincontainer.cpp
@@ -266,7 +266,7 @@ void PluginContainer::loadPlugins()
loadCheck.flush();
QString pluginName = iter.filePath();
if (QLibrary::isLibrary(pluginName)) {
- QPluginLoader *pluginLoader = new QPluginLoader(pluginName, this);
+ std::unique_ptr<QPluginLoader> pluginLoader(new QPluginLoader(pluginName, this));
if (pluginLoader->instance() == nullptr) {
m_FailedPlugins.push_back(pluginName);
qCritical("failed to load plugin %s: %s",
@@ -274,7 +274,7 @@ void PluginContainer::loadPlugins()
} else {
if (registerPlugin(pluginLoader->instance(), pluginName)) {
qDebug("loaded plugin \"%s\"", qPrintable(QFileInfo(pluginName).fileName()));
- m_PluginLoaders.push_back(pluginLoader);
+ m_PluginLoaders.push_back(pluginLoader.release());
} else {
m_FailedPlugins.push_back(pluginName);
qWarning("plugin \"%s\" failed to load", qPrintable(pluginName));
diff --git a/src/queryoverwritedialog.cpp b/src/queryoverwritedialog.cpp
index 1d7aea0a..932b2637 100644
--- a/src/queryoverwritedialog.cpp
+++ b/src/queryoverwritedialog.cpp
@@ -20,11 +20,12 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "queryoverwritedialog.h"
#include "ui_queryoverwritedialog.h"
-QueryOverwriteDialog::QueryOverwriteDialog(QWidget *parent)
+QueryOverwriteDialog::QueryOverwriteDialog(QWidget *parent, Backup b)
: QDialog(parent), ui(new Ui::QueryOverwriteDialog),
m_Action(ACT_NONE)
{
ui->setupUi(this);
+ ui->backupBox->setChecked(b == BACKUP_YES);
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxQuestion);
ui->iconLabel->setPixmap(icon.pixmap(128));
diff --git a/src/queryoverwritedialog.h b/src/queryoverwritedialog.h
index 1a22a60e..3f7b3194 100644
--- a/src/queryoverwritedialog.h
+++ b/src/queryoverwritedialog.h
@@ -37,8 +37,13 @@ public:
ACT_RENAME
};
+ enum Backup {
+ BACKUP_NO,
+ BACKUP_YES
+ };
+
public:
- explicit QueryOverwriteDialog(QWidget *parent = 0);
+ QueryOverwriteDialog(QWidget *parent, Backup b);
~QueryOverwriteDialog();
bool backup() const;
Action action() const { return m_Action; }
diff --git a/src/savegamegamebyro.h b/src/savegamegamebyro.h
index eedda6c2..e08e1044 100644
--- a/src/savegamegamebyro.h
+++ b/src/savegamegamebyro.h
@@ -22,10 +22,9 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "savegame.h"
-#include <gameinfo.h>
+
#include <QString>
#include <QObject>
-#include <QImage>
#include <QMetaType>
#include <QFile>
diff --git a/src/savegameinfowidgetgamebryo.cpp b/src/savegameinfowidgetgamebryo.cpp
index b87d3165..c97e5810 100644
--- a/src/savegameinfowidgetgamebryo.cpp
+++ b/src/savegameinfowidgetgamebryo.cpp
@@ -71,4 +71,10 @@ void SaveGameInfoWidgetGamebryo::setSave(const SaveGame *saveGame)
dotDotLabel->setFont(contentFont);
layout->addWidget(dotDotLabel);
}
+ if (count == 0) {
+ QLabel *dotDotLabel = new QLabel(tr("None"));
+ dotDotLabel->setIndent(10);
+ dotDotLabel->setFont(contentFont);
+ layout->addWidget(dotDotLabel);
+ }
}
diff --git a/src/savetextasdialog.cpp b/src/savetextasdialog.cpp
index 1f23356f..1a940094 100644
--- a/src/savetextasdialog.cpp
+++ b/src/savetextasdialog.cpp
@@ -1,6 +1,6 @@
#include "savetextasdialog.h"
#include "ui_savetextasdialog.h"
-#include <report.h>
+#include "report.h"
#include <QClipboard>
#include <QFileDialog>
@@ -37,7 +37,7 @@ void SaveTextAsDialog::on_saveAsBtn_clicked()
if (!fileName.isEmpty()) {
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly)) {
- MOBase::reportError(tr("failed to open \"%1\" for writing").arg(fileName));
+ reportError(tr("failed to open \"%1\" for writing").arg(fileName));
return;
}
diff --git a/src/shared/SConscript b/src/shared/SConscript
index 35c65d73..69a95289 100644
--- a/src/shared/SConscript
+++ b/src/shared/SConscript
@@ -20,3 +20,6 @@ env.AppendUnique(CPPPATH = [
# Not sure if renaming this helps much as it's static
env.StaticLibrary('mo_shared', env.Glob('*.cpp'))
+
+res = env['QT_USED_MODULES']
+Return('res')