Compare commits

..
Author SHA1 Message Date
Tannin 8b31996525 - bugfix: invalid ini file name when creating profile for oblivion from default settings
- bugfix: archives.txt file was potentially not generated if there were no bsas
- bugfix: static __declspec(thread) declaration causes crashes in windows versions before vista
- logger class in hook.dll now tries alternative names for the log file if it can't access the regular file
- path-environment variable for mo-spawned processes now contains the path to MO, in case the hook.dll needs to find the msvc-dlls
- stack-search in ini-limit hack now starts searching on local stack. This should find the right stack position for the hack more reliable
2013-03-18 20:03:46 +01:00
Tannin b3d0fcb208 - some more safety checks in the ini-limit removal code
- some code cleanup and minor bug fixes based on results from static code analysis
- added naemfilter for the esp list
- bsa changes are now stored automatically but delayed by up to 0.5 seconds (for performance reasons)
- bugfix: buffer overrun when certain functions are called with empty file names
- bugfix: reroute for the ini-limit fix was placed in the data segment
- bugfix: mod list got mixed up when the mod directory was changed externally
- bugfix: plugins.txt reroute on skyrim didn't work on winXP
- bugfix: MO could become unresponsive if the tutorial script couldn't be interpreted
2013-03-13 19:35:20 +01:00
Tannin 93e073c324 Added tag release v0.12.8 for changeset 0f4efc99546f 2013-03-06 19:33:55 +01:00
Tannin b2f3d8e47c - rewrote the mechanism removing the Archive List limit
- openfile is now rerouted
- .jar files can now be added as executables directly
- bugfix: no message was displayed when checking for updates with no valid credentials configured
- added a readme with compilation instructions
2013-03-01 13:03:30 +01:00
Tannin 8b4e11060b - 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
2013-02-22 19:28:54 +01:00
Tannin cb297d20b6 - proper detection of user-preferred language
- resume and removal of failed download fixed
2013-02-19 21:33:58 +01:00
Tannin efe4243077 added hgignore 2013-02-19 20:34:38 +01:00
Tannin 2c1fad4d98 - fixed broken help menu
- work towards resume of failed downloads
2013-02-19 20:32:44 +01:00
Tannin fba05e7fab Added tag release v0.12.7 for changeset 92578a6d6331 2013-02-17 22:06:28 +01:00
53 changed files with 22228 additions and 13180 deletions
+4
View File
@@ -0,0 +1,4 @@
syntax: glob
ModOrganizer-build-desktop*
outputd/*
output/*
+68
View File
@@ -0,0 +1,68 @@
HOW TO BUILD
============
Requirements:
-------------
Visual C++ compiler 2010 (VC 10.0) or up
- Included in visual c++ express 2010 or windows sdk 7.0
QtSDK 4.8.x (http://qt-project.org/downloads)
- Qt5 is not yet supported but WIP
- Install according to instruction
boost libraries (http://www.boost.org/)
- Compile according to their instructions (using vc++)
- As of time of writing boost_thread is the only compiled boost library used, you can
disable the others to safe yourself the compile time
zlib (http://www.zlib.net/)
- Compile static library according to their instructions
- You should have a "zlibstatic.lib" under "build" afterwards
7z.dll (http://www.7-zip.org/download.html)
- Part of the 7-zip program
- Has to be the 32-bit dll! (approx. 893kb)
Recommended:
------------
Qt Creator
- Included in QtSDK but there might be a newer version as a separate download
Set up (using Qt Creator):
--------------------------
1. Using Qt Creator open source/ModOrganizer.pro from your working copy
2. Open the "Projects" tab, open the "Details" for "Build Environment"
3. Click "Add" to add a variable called "BOOSTPATH" with the path of your boost installation as the value (i.e. C:\code\boost_1_52_0)
4. Click "Add" to add a variable called "ZLIBPATH" with the path of your zlib installation as the value (i.e. C:\code\zlib-1.2.7)
5. Switch the build configuration at the very top of the same page from "debug" to "release" (or vice versa) and repeat steps 3 and 4
6. Compile the configuration(s) you want to use (debug and/or release) (Build All). This should compile correctly.
7. return to the "projects" tab and switch to "Run Settings"
For Release build:
8r. Add a "Run configuration" that points to <your working copy>\output\ModOrganizer.exe
9r. Copy "7z.dll" to <your working copy>\output\dlls
10r. From QtSDK\Desktop\Qt\4.8.0\msvc2010\bin copy the following files to <your working copy>\output\dlls: QtCore4.dll, QtDeclarative4.dll, QtGui4.dll, QtNetwork4.dll, QtScript4.dll, QtSql4.dll, QtWebkit4.dll, QtXml4.dll, QtXmlPatterns4.dll
For Debug build:
8d. Add a "Run configuration" that points to <your working copy>\outputd\ModOrganizer.exe
9d. Copy "7z.dll" to <your working copy>\outputd\dlls
10d. From QtSDK\Desktop\Qt\4.8.0\msvc2010\bin copy the following files to <your working copy>\outputd\dlls: QtCored4.dll, QtDeclaratived4.dll, QtGuid4.dll, QtNetworkd4.dll, QtScriptd4.dll, QtSqld4.dll, QtWebkitd4.dll, QtXmld4.dll, QtXmlPatternsd4.dll
Now you should be able to compile and run Mod Organizer.
Please note that when you change anything apart from the "organizer" subproject, qt creator may not pick up on the changes
and not recompile the modified subproject. the "organizer" project on the other hand is always re-linked. If anyone knowledgeable enough with qmake
can fix that that would be awesome.
Set up (without Qt Creator):
----------------------------
1. open a command line shell and navigate to <your working copy>\source
2. run "qmake -tp vc" to create a visual c++ solution
3. Open that solution
4. - 98. A miracle happens
99. You can now compile MO using VC
I'm not using this workflow so I can't give more detailed instructions.
Please note that the primary project format of MO remains qmake, if you work with visual studio and make changes to the project (like adding
source files) you have to manually transfer those changes to the .pro file.
+2 -1
View File
@@ -86,7 +86,8 @@ public:
{
QLineEdit *edit = qobject_cast<QLineEdit*>(editor);
int pos = 0;
if (m_Validator->validate(edit->text(), pos) == QValidator::Acceptable) {
QString editText = edit->text();
if (m_Validator->validate(editText, pos) == QValidator::Acceptable) {
QItemDelegate::setModelData(editor, model, index);
}
}
+236 -223
View File
@@ -17,226 +17,239 @@ 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 "downloadlistwidget.h"
#include "ui_downloadlistwidget.h"
#include "downloadmanager.h"
#include <QPainter>
#include <QMouseEvent>
#include <QMenu>
#include <QMessageBox>
#include <QSortFilterProxyModel>
DownloadListWidget::DownloadListWidget(QWidget *parent)
: QWidget(parent), ui(new Ui::DownloadListWidget)
{
ui->setupUi(this);
}
DownloadListWidget::~DownloadListWidget()
{
delete ui;
}
DownloadListWidgetDelegate::DownloadListWidgetDelegate(DownloadManager *manager, QTreeView *view, QObject *parent)
: QItemDelegate(parent), m_Manager(manager), m_ItemWidget(new DownloadListWidget), m_ContextRow(0), m_View(view)
{
m_NameLabel = m_ItemWidget->findChild<QLabel*>("nameLabel");
m_Progress = m_ItemWidget->findChild<QProgressBar*>("downloadProgress");
m_InstallLabel = m_ItemWidget->findChild<QLabel*>("installLabel");
m_InstallLabel->setVisible(false);
}
DownloadListWidgetDelegate::~DownloadListWidgetDelegate()
{
delete m_ItemWidget;
}
void DownloadListWidgetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
try {
m_ItemWidget->resize(QSize(m_View->columnWidth(0) + m_View->columnWidth(1) + m_View->columnWidth(2), option.rect.height()));
int downloadIndex = index.data().toInt();
QString name = m_Manager->getFileName(downloadIndex);
if (name.length() > 53) {
name.truncate(50);
name.append("...");
}
m_NameLabel->setText(name);
DownloadManager::DownloadState state = m_Manager->getState(downloadIndex);
if (state >= DownloadManager::STATE_READY) {
QPalette labelPalette;
m_InstallLabel->setVisible(true);
m_Progress->setVisible(false);
if (state == DownloadManager::STATE_INSTALLED) {
// the tr-macro doesn't work here, maybe because the translation is actually associated with DownloadListWidget instead
// of DownloadListWidgetDelegate?
#if QT_VERSION >= 0x050000
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Installed - Double Click to re-install", 0));
#else
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Installed - Double Click to re-install", 0, QApplication::UnicodeUTF8));
#endif
labelPalette.setColor(QPalette::WindowText, Qt::darkGray);
} else {
// the tr-macro doesn't work here, maybe because the translation is actually associated with DownloadListWidget instead
// of DownloadListWidgetDelegate?
#if QT_VERSION >= 0x050000
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Done - Double Click to install", 0));
#else
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Done - Double Click to install", 0, QApplication::UnicodeUTF8));
#endif
labelPalette.setColor(QPalette::WindowText, Qt::darkGreen);
}
m_InstallLabel->setPalette(labelPalette);
if (m_Manager->isInfoIncomplete(downloadIndex)) {
m_NameLabel->setText("<img src=\":/MO/gui/resources/dialog-warning_16.png\" /> " + m_NameLabel->text());
}
} else {
m_InstallLabel->setVisible(false);
m_Progress->setVisible(true);
m_Progress->setValue(m_Manager->getProgress(downloadIndex));
}
painter->save();
painter->translate(QPoint(0, option.rect.topLeft().y()));
m_ItemWidget->render(painter);
painter->restore();
} catch (const std::exception &e) {
qCritical("failed to paint download list: %s", e.what());
}
}
QSize DownloadListWidgetDelegate::sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const
{
const int width = m_ItemWidget->minimumWidth();
const int height = m_ItemWidget->height();
return QSize(width, height);
}
void DownloadListWidgetDelegate::issueInstall()
{
emit installDownload(m_ContextRow);
}
void DownloadListWidgetDelegate::issueQueryInfo()
{
emit queryInfo(m_ContextRow);
}
void DownloadListWidgetDelegate::issueDelete()
{
emit removeDownload(m_ContextRow, true);
}
void DownloadListWidgetDelegate::issueRemoveFromView()
{
emit removeDownload(m_ContextRow, false);
}
void DownloadListWidgetDelegate::issueCancel()
{
emit cancelDownload(m_ContextRow);
}
void DownloadListWidgetDelegate::issuePause()
{
emit pauseDownload(m_ContextRow);
}
void DownloadListWidgetDelegate::issueResume()
{
emit resumeDownload(m_ContextRow);
}
void DownloadListWidgetDelegate::issueDeleteAll()
{
if (QMessageBox::question(NULL, tr("Are you sure?"),
tr("This will remove all finished downloads from this list and from disk."),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
emit removeDownload(-1, true);
}
}
void DownloadListWidgetDelegate::issueDeleteCompleted()
{
if (QMessageBox::question(NULL, tr("Are you sure?"),
tr("This will remove all installed downloads from this list and from disk."),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
emit removeDownload(-2, true);
}
}
void DownloadListWidgetDelegate::issueRemoveFromViewAll()
{
if (QMessageBox::question(NULL, tr("Are you sure?"),
tr("This will remove all finished downloads from this list (but NOT from disk)."),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
emit removeDownload(-1, false);
}
}
void DownloadListWidgetDelegate::issueRemoveFromViewCompleted()
{
if (QMessageBox::question(NULL, tr("Are you sure?"),
tr("This will remove all installed downloads from this list (but NOT from disk)."),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
emit removeDownload(-2, false);
}
}
bool DownloadListWidgetDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
const QStyleOptionViewItem &option, const QModelIndex &index)
{
try {
if (event->type() == QEvent::MouseButtonDblClick) {
QModelIndex sourceIndex = qobject_cast<QSortFilterProxyModel*>(model)->mapToSource(index);
if (m_Manager->getState(sourceIndex.row()) >= DownloadManager::STATE_READY) {
emit installDownload(sourceIndex.row());
}
return true;
} else if (event->type() == QEvent::MouseButtonRelease) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
if (mouseEvent->button() == Qt::RightButton) {
QMenu menu(m_View);
m_ContextRow = qobject_cast<QSortFilterProxyModel*>(model)->mapToSource(index).row();
DownloadManager::DownloadState state = m_Manager->getState(m_ContextRow);
if (state >= DownloadManager::STATE_READY) {
menu.addAction(tr("Install"), this, SLOT(issueInstall()));
if (m_Manager->isInfoIncomplete(m_ContextRow)) {
menu.addAction(tr("Query Info"), this, SLOT(issueQueryInfo()));
}
menu.addAction(tr("Delete"), this, SLOT(issueDelete()));
menu.addAction(tr("Remove from View"), this, SLOT(issueRemoveFromView()));
} else if (state == DownloadManager::STATE_DOWNLOADING){
menu.addAction(tr("Cancel"), this, SLOT(issueCancel()));
menu.addAction(tr("Pause"), this, SLOT(issuePause()));
} else if (state == DownloadManager::STATE_PAUSED) {
menu.addAction(tr("Remove"), this, SLOT(issueRemove()));
menu.addAction(tr("Resume"), this, SLOT(issueResume()));
}
menu.addSeparator();
menu.addAction(tr("Delete Installed..."), this, SLOT(issueDeleteCompleted()));
menu.addAction(tr("Delete All..."), this, SLOT(issueDeleteAll()));
menu.addSeparator();
menu.addAction(tr("Remove Installed..."), this, SLOT(issueRemoveFromViewCompleted()));
menu.addAction(tr("Remove All..."), this, SLOT(issueRemoveFromViewAll()));
menu.exec(mouseEvent->globalPos());
event->accept();
return true;
}
}
} catch (const std::exception &e) {
qCritical("failed to handle editor event: %s", e.what());
}
return QItemDelegate::editorEvent(event, model, option, index);
}
#include "downloadlistwidget.h"
#include "ui_downloadlistwidget.h"
#include "downloadmanager.h"
#include <QPainter>
#include <QMouseEvent>
#include <QMenu>
#include <QMessageBox>
#include <QSortFilterProxyModel>
DownloadListWidget::DownloadListWidget(QWidget *parent)
: QWidget(parent), ui(new Ui::DownloadListWidget)
{
ui->setupUi(this);
}
DownloadListWidget::~DownloadListWidget()
{
delete ui;
}
DownloadListWidgetDelegate::DownloadListWidgetDelegate(DownloadManager *manager, QTreeView *view, QObject *parent)
: QItemDelegate(parent), m_Manager(manager), m_ItemWidget(new DownloadListWidget), m_ContextRow(0), m_View(view)
{
m_NameLabel = m_ItemWidget->findChild<QLabel*>("nameLabel");
m_Progress = m_ItemWidget->findChild<QProgressBar*>("downloadProgress");
m_InstallLabel = m_ItemWidget->findChild<QLabel*>("installLabel");
m_InstallLabel->setVisible(false);
}
DownloadListWidgetDelegate::~DownloadListWidgetDelegate()
{
delete m_ItemWidget;
}
void DownloadListWidgetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
try {
m_ItemWidget->resize(QSize(m_View->columnWidth(0) + m_View->columnWidth(1) + m_View->columnWidth(2), option.rect.height()));
int downloadIndex = index.data().toInt();
QString name = m_Manager->getFileName(downloadIndex);
if (name.length() > 53) {
name.truncate(50);
name.append("...");
}
m_NameLabel->setText(name);
DownloadManager::DownloadState state = m_Manager->getState(downloadIndex);
if (state == DownloadManager::STATE_PAUSED) {
QPalette labelPalette;
m_InstallLabel->setVisible(true);
m_Progress->setVisible(false);
#if QT_VERSION >= 0x050000
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Paused - Double Click to resume", 0));
#else
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Paused - Double Click to resume", 0, QApplication::UnicodeUTF8));
#endif
labelPalette.setColor(QPalette::WindowText, Qt::darkRed);
m_InstallLabel->setPalette(labelPalette);
} else if (state >= DownloadManager::STATE_READY) {
QPalette labelPalette;
m_InstallLabel->setVisible(true);
m_Progress->setVisible(false);
if (state == DownloadManager::STATE_INSTALLED) {
// the tr-macro doesn't work here, maybe because the translation is actually associated with DownloadListWidget instead
// of DownloadListWidgetDelegate?
#if QT_VERSION >= 0x050000
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Installed - Double Click to re-install", 0));
#else
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Installed - Double Click to re-install", 0, QApplication::UnicodeUTF8));
#endif
labelPalette.setColor(QPalette::WindowText, Qt::darkGray);
} else {
// the tr-macro doesn't work here, maybe because the translation is actually associated with DownloadListWidget instead
// of DownloadListWidgetDelegate?
#if QT_VERSION >= 0x050000
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Done - Double Click to install", 0));
#else
m_InstallLabel->setText(QApplication::translate("DownloadListWidget", "Done - Double Click to install", 0, QApplication::UnicodeUTF8));
#endif
labelPalette.setColor(QPalette::WindowText, Qt::darkGreen);
}
m_InstallLabel->setPalette(labelPalette);
if (m_Manager->isInfoIncomplete(downloadIndex)) {
m_NameLabel->setText("<img src=\":/MO/gui/resources/dialog-warning_16.png\" /> " + m_NameLabel->text());
}
} else {
m_InstallLabel->setVisible(false);
m_Progress->setVisible(true);
m_Progress->setValue(m_Manager->getProgress(downloadIndex));
}
painter->save();
painter->translate(QPoint(0, option.rect.topLeft().y()));
m_ItemWidget->render(painter);
painter->restore();
} catch (const std::exception &e) {
qCritical("failed to paint download list: %s", e.what());
}
}
QSize DownloadListWidgetDelegate::sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const
{
const int width = m_ItemWidget->minimumWidth();
const int height = m_ItemWidget->height();
return QSize(width, height);
}
void DownloadListWidgetDelegate::issueInstall()
{
emit installDownload(m_ContextRow);
}
void DownloadListWidgetDelegate::issueQueryInfo()
{
emit queryInfo(m_ContextRow);
}
void DownloadListWidgetDelegate::issueDelete()
{
emit removeDownload(m_ContextRow, true);
}
void DownloadListWidgetDelegate::issueRemoveFromView()
{
emit removeDownload(m_ContextRow, false);
}
void DownloadListWidgetDelegate::issueCancel()
{
emit cancelDownload(m_ContextRow);
}
void DownloadListWidgetDelegate::issuePause()
{
emit pauseDownload(m_ContextRow);
}
void DownloadListWidgetDelegate::issueResume()
{
emit resumeDownload(m_ContextRow);
}
void DownloadListWidgetDelegate::issueDeleteAll()
{
if (QMessageBox::question(NULL, tr("Are you sure?"),
tr("This will remove all finished downloads from this list and from disk."),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
emit removeDownload(-1, true);
}
}
void DownloadListWidgetDelegate::issueDeleteCompleted()
{
if (QMessageBox::question(NULL, tr("Are you sure?"),
tr("This will remove all installed downloads from this list and from disk."),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
emit removeDownload(-2, true);
}
}
void DownloadListWidgetDelegate::issueRemoveFromViewAll()
{
if (QMessageBox::question(NULL, tr("Are you sure?"),
tr("This will remove all finished downloads from this list (but NOT from disk)."),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
emit removeDownload(-1, false);
}
}
void DownloadListWidgetDelegate::issueRemoveFromViewCompleted()
{
if (QMessageBox::question(NULL, tr("Are you sure?"),
tr("This will remove all installed downloads from this list (but NOT from disk)."),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
emit removeDownload(-2, false);
}
}
bool DownloadListWidgetDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
const QStyleOptionViewItem &option, const QModelIndex &index)
{
try {
if (event->type() == QEvent::MouseButtonDblClick) {
QModelIndex sourceIndex = qobject_cast<QSortFilterProxyModel*>(model)->mapToSource(index);
if (m_Manager->getState(sourceIndex.row()) >= DownloadManager::STATE_READY) {
emit installDownload(sourceIndex.row());
} else if (m_Manager->getState(sourceIndex.row()) >= DownloadManager::STATE_PAUSED) {
emit resumeDownload(sourceIndex.row());
}
return true;
} else if (event->type() == QEvent::MouseButtonRelease) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
if (mouseEvent->button() == Qt::RightButton) {
QMenu menu(m_View);
m_ContextRow = qobject_cast<QSortFilterProxyModel*>(model)->mapToSource(index).row();
DownloadManager::DownloadState state = m_Manager->getState(m_ContextRow);
if (state >= DownloadManager::STATE_READY) {
menu.addAction(tr("Install"), this, SLOT(issueInstall()));
if (m_Manager->isInfoIncomplete(m_ContextRow)) {
menu.addAction(tr("Query Info"), this, SLOT(issueQueryInfo()));
}
menu.addAction(tr("Delete"), this, SLOT(issueDelete()));
menu.addAction(tr("Remove from View"), this, SLOT(issueRemoveFromView()));
} else if (state == DownloadManager::STATE_DOWNLOADING){
menu.addAction(tr("Cancel"), this, SLOT(issueCancel()));
menu.addAction(tr("Pause"), this, SLOT(issuePause()));
} else if (state == DownloadManager::STATE_PAUSED) {
menu.addAction(tr("Remove"), this, SLOT(issueDelete()));
menu.addAction(tr("Resume"), this, SLOT(issueResume()));
}
menu.addSeparator();
menu.addAction(tr("Delete Installed..."), this, SLOT(issueDeleteCompleted()));
menu.addAction(tr("Delete All..."), this, SLOT(issueDeleteAll()));
menu.addSeparator();
menu.addAction(tr("Remove Installed..."), this, SLOT(issueRemoveFromViewCompleted()));
menu.addAction(tr("Remove All..."), this, SLOT(issueRemoveFromViewAll()));
menu.exec(mouseEvent->globalPos());
event->accept();
return true;
}
}
} catch (const std::exception &e) {
qCritical("failed to handle editor event: %s", e.what());
}
return QItemDelegate::editorEvent(event, model, option, index);
}
+225 -218
View File
@@ -17,221 +17,228 @@ 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 "downloadlistwidgetcompact.h"
#include "ui_downloadlistwidgetcompact.h"
#include <QPainter>
#include <QMouseEvent>
#include <QMenu>
#include <QMessageBox>
#include <QSortFilterProxyModel>
#include "downloadmanager.h"
DownloadListWidgetCompact::DownloadListWidgetCompact(QWidget *parent) :
QWidget(parent),
ui(new Ui::DownloadListWidgetCompact)
{
ui->setupUi(this);
}
DownloadListWidgetCompact::~DownloadListWidgetCompact()
{
delete ui;
}
DownloadListWidgetCompactDelegate::DownloadListWidgetCompactDelegate(DownloadManager *manager, QTreeView *view, QObject *parent)
: QItemDelegate(parent), m_Manager(manager), m_ItemWidget(new DownloadListWidgetCompact), m_View(view)
{
m_NameLabel = m_ItemWidget->findChild<QLabel*>("nameLabel");
m_Progress = m_ItemWidget->findChild<QProgressBar*>("downloadProgress");
m_DoneLabel = m_ItemWidget->findChild<QLabel*>("doneLabel");
m_DoneLabel->setVisible(false);
}
DownloadListWidgetCompactDelegate::~DownloadListWidgetCompactDelegate()
{
delete m_ItemWidget;
}
void DownloadListWidgetCompactDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
try {
// m_ItemWidget->resize(option.rect.size());
m_ItemWidget->resize(QSize(m_View->columnWidth(0) + m_View->columnWidth(1) + m_View->columnWidth(2), option.rect.height()));
if (index.row() % 2 == 1) {
m_ItemWidget->setBackgroundRole(QPalette::AlternateBase);
} else {
m_ItemWidget->setBackgroundRole(QPalette::Base);
}
int downloadIndex = index.data().toInt();
QString name = m_Manager->getFileName(downloadIndex);
if (name.length() > 53) {
name.truncate(50);
name.append("...");
}
m_NameLabel->setText(name);
DownloadManager::DownloadState state = m_Manager->getState(downloadIndex);
if (state >= DownloadManager::STATE_READY) {
m_DoneLabel->setVisible(true);
m_Progress->setVisible(false);
if (state == DownloadManager::STATE_INSTALLED) {
m_DoneLabel->setText(tr("Installed"));
m_DoneLabel->setForegroundRole(QPalette::Mid);
} else {
m_DoneLabel->setText(tr("Done"));
m_DoneLabel->setForegroundRole(QPalette::WindowText);
}
if (m_Manager->isInfoIncomplete(downloadIndex)) {
m_NameLabel->setText("<img src=\":/MO/gui/resources/dialog-warning_16.png\"/> " + m_NameLabel->text());
}
} else {
m_DoneLabel->setVisible(false);
m_Progress->setVisible(true);
m_Progress->setValue(m_Manager->getProgress(downloadIndex));
}
painter->save();
painter->translate(QPoint(0, option.rect.topLeft().y()));
m_ItemWidget->render(painter);
painter->restore();
} catch (const std::exception &e) {
qCritical("failed to paint download list item %d: %s", index.row(), e.what());
}
}
QSize DownloadListWidgetCompactDelegate::sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const
{
const int width = m_ItemWidget->minimumWidth();
const int height = m_ItemWidget->height();
return QSize(width, height);
}
void DownloadListWidgetCompactDelegate::issueInstall()
{
emit installDownload(m_ContextIndex.row());
}
void DownloadListWidgetCompactDelegate::issueQueryInfo()
{
emit queryInfo(m_ContextIndex.row());
}
void DownloadListWidgetCompactDelegate::issueDelete()
{
emit removeDownload(m_ContextIndex.row(), true);
}
void DownloadListWidgetCompactDelegate::issueRemoveFromView()
{
emit removeDownload(m_ContextIndex.row(), false);
}
void DownloadListWidgetCompactDelegate::issueCancel()
{
emit cancelDownload(m_ContextIndex.row());
}
void DownloadListWidgetCompactDelegate::issuePause()
{
emit pauseDownload(m_ContextIndex.row());
}
void DownloadListWidgetCompactDelegate::issueResume()
{
emit resumeDownload(m_ContextIndex.row());
}
void DownloadListWidgetCompactDelegate::issueDeleteAll()
{
if (QMessageBox::question(NULL, tr("Are you sure?"),
tr("This will remove all finished downloads from this list and from disk."),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
emit removeDownload(-1, true);
}
}
void DownloadListWidgetCompactDelegate::issueDeleteCompleted()
{
if (QMessageBox::question(NULL, tr("Are you sure?"),
tr("This will remove all installed downloads from this list and from disk."),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
emit removeDownload(-2, true);
}
}
void DownloadListWidgetCompactDelegate::issueRemoveFromViewAll()
{
if (QMessageBox::question(NULL, tr("Are you sure?"),
tr("This will permanently remove all finished downloads from this list (but NOT from disk)."),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
emit removeDownload(-1, false);
}
}
void DownloadListWidgetCompactDelegate::issueRemoveFromViewCompleted()
{
if (QMessageBox::question(NULL, tr("Are you sure?"),
tr("This will permanently remove all installed downloads from this list (but NOT from disk)."),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
emit removeDownload(-2, false);
}
}
bool DownloadListWidgetCompactDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
const QStyleOptionViewItem &option, const QModelIndex &index)
{
try {
if (event->type() == QEvent::MouseButtonDblClick) {
QModelIndex sourceIndex = qobject_cast<QSortFilterProxyModel*>(model)->mapToSource(index);
if (m_Manager->getState(sourceIndex.row()) >= DownloadManager::STATE_READY) {
emit installDownload(sourceIndex.row());
}
return true;
} else if (event->type() == QEvent::MouseButtonRelease) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
if (mouseEvent->button() == Qt::RightButton) {
QMenu menu;
m_ContextIndex = qobject_cast<QSortFilterProxyModel*>(model)->mapToSource(index);
DownloadManager::DownloadState state = m_Manager->getState(m_ContextIndex.row());
if (state >= DownloadManager::STATE_READY) {
menu.addAction(tr("Install"), this, SLOT(issueInstall()));
if (m_Manager->isInfoIncomplete(m_ContextIndex.row())) {
menu.addAction(tr("Query Info"), this, SLOT(issueQueryInfo()));
}
menu.addAction(tr("Delete"), this, SLOT(issueDelete()));
menu.addAction(tr("Remove from View"), this, SLOT(issueRemoveFromView()));
} else if (state == DownloadManager::STATE_DOWNLOADING){
menu.addAction(tr("Cancel"), this, SLOT(issueCancel()));
menu.addAction(tr("Pause"), this, SLOT(issuePause()));
} else if (state == DownloadManager::STATE_PAUSED) {
menu.addAction(tr("Remove"), this, SLOT(issueDelete()));
menu.addAction(tr("Resume"), this, SLOT(issueResume()));
}
menu.addSeparator();
menu.addAction(tr("Delete Installed..."), this, SLOT(issueDeleteCompleted()));
menu.addAction(tr("Delete All..."), this, SLOT(issueDeleteAll()));
menu.addSeparator();
menu.addAction(tr("Remove Installed..."), this, SLOT(issueRemoveFromViewCompleted()));
menu.addAction(tr("Remove All..."), this, SLOT(issueRemoveFromViewAll()));
menu.exec(mouseEvent->globalPos());
event->accept();
return false;
}
}
} catch (const std::exception &e) {
qCritical("failed to handle editor event: %s", e.what());
}
return QItemDelegate::editorEvent(event, model, option, index);
}
#include "downloadlistwidgetcompact.h"
#include "ui_downloadlistwidgetcompact.h"
#include <QPainter>
#include <QMouseEvent>
#include <QMenu>
#include <QMessageBox>
#include <QSortFilterProxyModel>
#include "downloadmanager.h"
DownloadListWidgetCompact::DownloadListWidgetCompact(QWidget *parent) :
QWidget(parent),
ui(new Ui::DownloadListWidgetCompact)
{
ui->setupUi(this);
}
DownloadListWidgetCompact::~DownloadListWidgetCompact()
{
delete ui;
}
DownloadListWidgetCompactDelegate::DownloadListWidgetCompactDelegate(DownloadManager *manager, QTreeView *view, QObject *parent)
: QItemDelegate(parent), m_Manager(manager), m_ItemWidget(new DownloadListWidgetCompact), m_View(view)
{
m_NameLabel = m_ItemWidget->findChild<QLabel*>("nameLabel");
m_Progress = m_ItemWidget->findChild<QProgressBar*>("downloadProgress");
m_DoneLabel = m_ItemWidget->findChild<QLabel*>("doneLabel");
m_DoneLabel->setVisible(false);
}
DownloadListWidgetCompactDelegate::~DownloadListWidgetCompactDelegate()
{
delete m_ItemWidget;
}
void DownloadListWidgetCompactDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
try {
// m_ItemWidget->resize(option.rect.size());
m_ItemWidget->resize(QSize(m_View->columnWidth(0) + m_View->columnWidth(1) + m_View->columnWidth(2), option.rect.height()));
if (index.row() % 2 == 1) {
m_ItemWidget->setBackgroundRole(QPalette::AlternateBase);
} else {
m_ItemWidget->setBackgroundRole(QPalette::Base);
}
int downloadIndex = index.data().toInt();
QString name = m_Manager->getFileName(downloadIndex);
if (name.length() > 53) {
name.truncate(50);
name.append("...");
}
m_NameLabel->setText(name);
DownloadManager::DownloadState state = m_Manager->getState(downloadIndex);
if (state == DownloadManager::STATE_PAUSED) {
m_DoneLabel->setVisible(true);
m_Progress->setVisible(false);
m_DoneLabel->setText(tr("Paused"));
m_DoneLabel->setForegroundRole(QPalette::Link);
} else if (state >= DownloadManager::STATE_READY) {
m_DoneLabel->setVisible(true);
m_Progress->setVisible(false);
if (state == DownloadManager::STATE_INSTALLED) {
m_DoneLabel->setText(tr("Installed"));
m_DoneLabel->setForegroundRole(QPalette::Mid);
} else {
m_DoneLabel->setText(tr("Done"));
m_DoneLabel->setForegroundRole(QPalette::WindowText);
}
if (m_Manager->isInfoIncomplete(downloadIndex)) {
m_NameLabel->setText("<img src=\":/MO/gui/resources/dialog-warning_16.png\"/> " + m_NameLabel->text());
}
} else {
m_DoneLabel->setVisible(false);
m_Progress->setVisible(true);
m_Progress->setValue(m_Manager->getProgress(downloadIndex));
}
painter->save();
painter->translate(QPoint(0, option.rect.topLeft().y()));
m_ItemWidget->render(painter);
painter->restore();
} catch (const std::exception &e) {
qCritical("failed to paint download list item %d: %s", index.row(), e.what());
}
}
QSize DownloadListWidgetCompactDelegate::sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const
{
const int width = m_ItemWidget->minimumWidth();
const int height = m_ItemWidget->height();
return QSize(width, height);
}
void DownloadListWidgetCompactDelegate::issueInstall()
{
emit installDownload(m_ContextIndex.row());
}
void DownloadListWidgetCompactDelegate::issueQueryInfo()
{
emit queryInfo(m_ContextIndex.row());
}
void DownloadListWidgetCompactDelegate::issueDelete()
{
emit removeDownload(m_ContextIndex.row(), true);
}
void DownloadListWidgetCompactDelegate::issueRemoveFromView()
{
emit removeDownload(m_ContextIndex.row(), false);
}
void DownloadListWidgetCompactDelegate::issueCancel()
{
emit cancelDownload(m_ContextIndex.row());
}
void DownloadListWidgetCompactDelegate::issuePause()
{
emit pauseDownload(m_ContextIndex.row());
}
void DownloadListWidgetCompactDelegate::issueResume()
{
emit resumeDownload(m_ContextIndex.row());
}
void DownloadListWidgetCompactDelegate::issueDeleteAll()
{
if (QMessageBox::question(NULL, tr("Are you sure?"),
tr("This will remove all finished downloads from this list and from disk."),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
emit removeDownload(-1, true);
}
}
void DownloadListWidgetCompactDelegate::issueDeleteCompleted()
{
if (QMessageBox::question(NULL, tr("Are you sure?"),
tr("This will remove all installed downloads from this list and from disk."),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
emit removeDownload(-2, true);
}
}
void DownloadListWidgetCompactDelegate::issueRemoveFromViewAll()
{
if (QMessageBox::question(NULL, tr("Are you sure?"),
tr("This will permanently remove all finished downloads from this list (but NOT from disk)."),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
emit removeDownload(-1, false);
}
}
void DownloadListWidgetCompactDelegate::issueRemoveFromViewCompleted()
{
if (QMessageBox::question(NULL, tr("Are you sure?"),
tr("This will permanently remove all installed downloads from this list (but NOT from disk)."),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
emit removeDownload(-2, false);
}
}
bool DownloadListWidgetCompactDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
const QStyleOptionViewItem &option, const QModelIndex &index)
{
try {
if (event->type() == QEvent::MouseButtonDblClick) {
QModelIndex sourceIndex = qobject_cast<QSortFilterProxyModel*>(model)->mapToSource(index);
if (m_Manager->getState(sourceIndex.row()) >= DownloadManager::STATE_READY) {
emit installDownload(sourceIndex.row());
} else if (m_Manager->getState(sourceIndex.row()) >= DownloadManager::STATE_PAUSED) {
emit resumeDownload(sourceIndex.row());
}
return true;
} else if (event->type() == QEvent::MouseButtonRelease) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
if (mouseEvent->button() == Qt::RightButton) {
QMenu menu;
m_ContextIndex = qobject_cast<QSortFilterProxyModel*>(model)->mapToSource(index);
DownloadManager::DownloadState state = m_Manager->getState(m_ContextIndex.row());
if (state >= DownloadManager::STATE_READY) {
menu.addAction(tr("Install"), this, SLOT(issueInstall()));
if (m_Manager->isInfoIncomplete(m_ContextIndex.row())) {
menu.addAction(tr("Query Info"), this, SLOT(issueQueryInfo()));
}
menu.addAction(tr("Delete"), this, SLOT(issueDelete()));
menu.addAction(tr("Remove from View"), this, SLOT(issueRemoveFromView()));
} else if (state == DownloadManager::STATE_DOWNLOADING){
menu.addAction(tr("Cancel"), this, SLOT(issueCancel()));
menu.addAction(tr("Pause"), this, SLOT(issuePause()));
} else if (state == DownloadManager::STATE_PAUSED) {
menu.addAction(tr("Remove"), this, SLOT(issueDelete()));
menu.addAction(tr("Resume"), this, SLOT(issueResume()));
}
menu.addSeparator();
menu.addAction(tr("Delete Installed..."), this, SLOT(issueDeleteCompleted()));
menu.addAction(tr("Delete All..."), this, SLOT(issueDeleteAll()));
menu.addSeparator();
menu.addAction(tr("Remove Installed..."), this, SLOT(issueRemoveFromViewCompleted()));
menu.addAction(tr("Remove All..."), this, SLOT(issueRemoveFromViewAll()));
menu.exec(mouseEvent->globalPos());
event->accept();
return false;
}
}
} catch (const std::exception &e) {
qCritical("failed to handle editor event: %s", e.what());
}
return QItemDelegate::editorEvent(event, model, option, index);
}
+5 -3
View File
@@ -199,6 +199,7 @@ bool DownloadManager::addDownload(QNetworkReply *reply, const QString &fileName,
newDownload->m_ModID = modID;
newDownload->m_FileID = fileID;
newDownload->m_NexusInfo = nexusInfo;
newDownload->m_State = STATE_STARTED;
QString baseName = fileName;
@@ -285,7 +286,7 @@ void DownloadManager::removeFile(int index, bool deleteFile)
}
if (download->m_State == STATE_PAUSED) {
filePath.append(UNFINISHED);
filePath = download->m_Output.fileName();
}
if (deleteFile) {
@@ -317,6 +318,7 @@ private:
DownloadManager *m_Manager;
};
bool DownloadManager::ByName(int LHS, int RHS)
{
return m_ActiveDownloads[LHS]->m_FileName < m_ActiveDownloads[RHS]->m_FileName;
@@ -587,7 +589,6 @@ void DownloadManager::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
return;
}
int index = 0;
DownloadInfo *info = findDownload(this->sender(), &index);
if (info != NULL) {
if (info->m_State == STATE_CANCELING) {
@@ -622,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);
@@ -855,7 +857,7 @@ void DownloadManager::downloadFinished()
(reply->error() != QNetworkReply::NoError) ||
reply->header(QNetworkRequest::ContentTypeHeader).toString().startsWith("text", Qt::CaseInsensitive)) {
emit showMessage(tr("Download failed: %1 (%2)").arg(reply->errorString()).arg(reply->error()));
info->m_State = STATE_CANCELING;
info->m_State = STATE_PAUSING;
}
}
+320 -320
View File
File diff suppressed because it is too large Load Diff
+37 -3
View File
@@ -21,6 +21,8 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "ui_editexecutablesdialog.h"
#include "filedialogmemory.h"
#include <QMessageBox>
#include <Shellapi.h>
#include <utility.h>
using namespace MOBase;
@@ -87,6 +89,7 @@ void EditExecutablesDialog::resetInput()
{
ui->binaryEdit->setText("");
ui->titleEdit->setText("");
ui->workingDirEdit->clear();
ui->argumentsEdit->setText("");
ui->closeCheckBox->setChecked(false);
}
@@ -113,11 +116,42 @@ void EditExecutablesDialog::on_addButton_clicked()
void EditExecutablesDialog::on_browseButton_clicked()
{
QString binaryName = FileDialogMemory::getOpenFileName("editExecutableBinary", this,
tr("Select a binary"), QString(), tr("Executable (%1)").arg("*.exe *.bat"));
tr("Select a binary"), QString(), tr("Executable (%1)").arg("*.exe *.bat *.jar"));
QLineEdit *binaryEdit = findChild<QLineEdit*>("binaryEdit");
if (binaryName.endsWith(".jar", Qt::CaseInsensitive)) {
QString binaryPath;
{ // try to find java automatically
std::wstring binaryNameW = ToWString(binaryName);
WCHAR buffer[MAX_PATH];
if (::FindExecutableW(binaryNameW.c_str(), NULL, buffer) > (HINSTANCE)32) {
DWORD binaryType = 0UL;
if (!::GetBinaryTypeW(binaryNameW.c_str(), &binaryType)) {
qDebug("failed to determine binary type: %lu", ::GetLastError());
} else if (binaryType == SCS_32BIT_BINARY) {
binaryPath = ToQString(buffer);
}
}
}
if (binaryPath.isEmpty()) {
QSettings javaReg("HKEY_LOCAL_MACHINE\\Software\\JavaSoft\\Java Runtime Environment", QSettings::NativeFormat);
if (javaReg.contains("CurrentVersion")) {
QString currentVersion = javaReg.value("CurrentVersion").toString();
binaryPath = javaReg.value(QString("%1/JavaHome").arg(currentVersion)).toString().append("\\bin\\javaw.exe");
}
}
if (binaryPath.isEmpty()) {
QMessageBox::information(this, tr("Java (32-bit) required"),
tr("MO requires 32-bit java to run this application. If you already have it installed, select javaw.exe "
"from that installation as the binary."));
} else {
ui->binaryEdit->setText(binaryPath);
}
binaryEdit->setText(QDir::toNativeSeparators(binaryName));
ui->workingDirEdit->setText(QDir::toNativeSeparators(QFileInfo(binaryName).absolutePath()));
ui->argumentsEdit->setText("-jar \"" + QDir::toNativeSeparators(binaryName) + "\"");
} else {
ui->binaryEdit->setText(QDir::toNativeSeparators(binaryName));
}
}
void EditExecutablesDialog::on_browseDirButton_clicked()
+75 -75
View File
@@ -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;
}
+22 -14
View File
@@ -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")) {
+2 -1
View File
@@ -169,7 +169,8 @@ void LoadMechanism::deactivateProxyDLL()
}
}
removeHintFile(QDir(gameDirectory));
QDir dir(gameDirectory);
removeHintFile(dir);
} catch (const std::exception &e) {
QMessageBox::critical(NULL, QObject::tr("Failed to deactivate proxy-dll loading"), e.what());
}
+53 -37
View File
@@ -125,8 +125,7 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget
updateProblemsButton();
updateToolBar();
ui->toolBar->blockSignals(true);
createHelpWidget();
// ui->toolBar->blockSignals(true);
ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure);
@@ -203,6 +202,7 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget
connect(&m_ModList, SIGNAL(showMessage(QString)), this, SLOT(showMessage(QString)));
connect(&m_ModList, SIGNAL(modRenamed(QString,QString)), this, SLOT(modRenamed(QString,QString)));
connect(ui->modFilterEdit, SIGNAL(textChanged(QString)), m_ModListSortProxy, SLOT(updateFilter(QString)));
connect(ui->espFilterEdit, SIGNAL(textChanged(QString)), m_PluginListSortProxy, SLOT(updateFilter(QString)));
connect(&m_ModList, SIGNAL(modlist_changed(int)), m_ModListSortProxy, SLOT(invalidate()));
connect(&m_ModList, SIGNAL(removeSelectedMods()), this, SLOT(removeMod_clicked()));
@@ -222,6 +222,9 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget
connect(&TutorialManager::instance(), SIGNAL(windowTutorialFinished(QString)), this, SLOT(windowTutorialFinished(QString)));
m_CheckBSATimer.setSingleShot(true);
connect(&m_CheckBSATimer, SIGNAL(timeout()), this, SLOT(checkBSAList()));
m_DirectoryRefresher.moveToThread(&m_RefresherThread);
m_RefresherThread.start();
@@ -300,6 +303,7 @@ void MainWindow::updateToolBar()
}
actionToToolButton(ui->actionHelp);
createHelpWidget();
foreach (QAction *action, ui->toolBar->actions()) {
if (action->isSeparator()) {
@@ -441,10 +445,12 @@ void MainWindow::createHelpWidget()
typedef std::vector<std::pair<int, QAction*> > ActionList;
ActionList tutorials;
QDirIterator dirIter("tutorials", QStringList("*.js"), QDir::Files);
QDirIterator dirIter(QApplication::applicationDirPath() + "/tutorials", QStringList("*.js"), QDir::Files);
while (dirIter.hasNext()) {
dirIter.next();
QString fileName = dirIter.fileName();
QFile file(dirIter.filePath());
if (!file.open(QIODevice::ReadOnly)) {
qCritical() << "Failed to open " << fileName;
@@ -476,6 +482,27 @@ void MainWindow::createHelpWidget()
}
void MainWindow::saveArchiveList()
{
if (m_ArchivesInit) {
QFile archiveFile(m_CurrentProfile->getArchivesFileName());
if (archiveFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
for (int i = 0; i < ui->bsaList->topLevelItemCount(); ++i) {
QTreeWidgetItem *item = ui->bsaList->topLevelItem(i);
if ((item != NULL) && (item->checkState(0) == Qt::Checked)) {
archiveFile.write(item->text(0).toUtf8().append("\r\n"));
}
}
} else {
reportError(tr("failed to save archives order, do you have write access "
"to \"%1\"?").arg(m_CurrentProfile->getArchivesFileName()));
}
archiveFile.close();
} else {
qWarning("archive list not initialised");
}
}
bool MainWindow::saveCurrentLists()
{
if (m_DirectoryUpdate) {
@@ -501,23 +528,11 @@ bool MainWindow::saveCurrentLists()
reportError(tr("failed to save load order: %1").arg(e.what()));
}
if (m_ArchivesInit) {
QFile archiveFile(m_CurrentProfile->getArchivesFileName());
if (archiveFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
for (int i = 0; i < ui->bsaList->topLevelItemCount(); ++i) {
QTreeWidgetItem *item = ui->bsaList->topLevelItem(i);
if ((item != NULL) && (item->checkState(0) == Qt::Checked)) {
archiveFile.write(item->text(0).toUtf8().append("\r\n"));
}
}
} else {
reportError(tr("failed to save archives order, do you have write access "
"to \"%1\"?").arg(m_CurrentProfile->getArchivesFileName()));
}
archiveFile.close();
} else {
qWarning("archive list not initialised");
// ensure the archive list exists
if (!QFile::exists(m_CurrentProfile->getArchivesFileName())) {
saveArchiveList();
}
return true;
}
@@ -547,7 +562,7 @@ bool MainWindow::addProfile()
void MainWindow::hookUpWindowTutorials()
{
QDirIterator dirIter("tutorials", QStringList("*.js"), QDir::Files);
QDirIterator dirIter(QApplication::applicationDirPath() + "/tutorials", QStringList("*.js"), QDir::Files);
while (dirIter.hasNext()) {
dirIter.next();
QString fileName = dirIter.fileName();
@@ -1057,6 +1072,9 @@ void MainWindow::startExeAction()
void MainWindow::refreshModList()
{
// don't lose changes!
m_CurrentProfile->writeModlistNow(true);
ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure);
m_CurrentProfile->refreshModStatus();
@@ -1100,7 +1118,7 @@ void MainWindow::setExecutableIndex(int index)
void MainWindow::activateSelectedProfile()
{
QString profileName = ui->profileBox->currentText();
qDebug() << "activate profile " << profileName;
qDebug("activate profile \"%s\"", qPrintable(profileName));
QString profileDir = QDir::fromNativeSeparators(ToQString(GameInfo::instance().getProfilesDir()))
.append("/").append(profileName);
delete m_CurrentProfile;
@@ -1560,9 +1578,7 @@ void MainWindow::readSettings()
setCategoryListVisible(filtersVisible);
ui->displayCategoriesBtn->setChecked(filtersVisible);
QString language = settings.value("Settings/language", QLocale::system().name()).toString();
languageChange(language);
languageChange(m_Settings.language());
int selectedExecutable = settings.value("selected_executable").toInt();
setExecutableIndex(selectedExecutable);
}
@@ -1618,6 +1634,8 @@ void MainWindow::storeSettings()
QComboBox *executableBox = findChild<QComboBox*>("executablesListBox");
settings.setValue("selected_executable", executableBox->currentIndex());
FileDialogMemory::save(m_Settings.directInterface());
}
@@ -1648,12 +1666,6 @@ void MainWindow::on_tabWidget_currentChanged(int index)
}
static QString guessModName(const QString &fileName)
{
return QFileInfo(fileName).baseName();
}
void MainWindow::installMod(const QString &fileName)
{
bool hasIniTweaks = false;
@@ -1695,9 +1707,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;
@@ -2667,9 +2678,9 @@ void MainWindow::savePrimaryCategory()
void MainWindow::checkModsForUpdates()
{
statusBar()->show();
if (NexusInterface::instance()->getAccessManager()->loggedIn()) {
m_ModsToUpdate = ModInfo::checkAllForUpdate(this);
statusBar()->show();
m_RefreshProgress->setRange(0, m_ModsToUpdate);
} else {
QString username, password;
@@ -3299,7 +3310,7 @@ int MainWindow::getBinaryExecuteInfo(const QFileInfo &targetInfo,
{ // try to find java automatically
WCHAR buffer[MAX_PATH];
if (FindExecutableW(targetPathW.c_str(), NULL, buffer) > (HINSTANCE)32) {
if (::FindExecutableW(targetPathW.c_str(), NULL, buffer) > (HINSTANCE)32) {
DWORD binaryType = 0UL;
if (!::GetBinaryTypeW(targetPathW.c_str(), &binaryType)) {
qDebug("failed to determine binary type: %lu", ::GetLastError());
@@ -3683,8 +3694,12 @@ void MainWindow::loginFailed(const QString &message)
foreach (QString url, m_PendingDownloads) {
downloadRequestedNXM(url);
}
m_PendingDownloads.clear();
} else {
MessageDialog::showMessage(tr("login failed: %1").arg(message), this);
m_PostLoginTasks.clear();
statusBar()->hide();
}
m_PendingDownloads.clear();
}
@@ -3826,7 +3841,8 @@ void MainWindow::on_bsaList_customContextMenuRequested(const QPoint &pos)
void MainWindow::on_bsaList_itemChanged(QTreeWidgetItem*, int)
{
checkBSAList();
saveArchiveList();
m_CheckBSATimer.start(500);
}
void MainWindow::on_actionProblems_triggered()
+6 -2
View File
@@ -103,6 +103,7 @@ public:
void addPrimaryCategoryCandidates(QMenu *primaryCategoryMenu, ModInfo::Ptr info);
void saveArchiveList();
public slots:
void displayColumnSelection(const QPoint &pos);
@@ -170,6 +171,7 @@ private:
void installMod(const QString &fileName);
void installMod();
bool modifyExecutablesDialog();
void modOpenNext();
void displayModInformation(ModInfo::Ptr modInfo, unsigned int index, int tab);
void displayModInformation(int row, int tab = 0);
void testExtractBSA(int modIndex);
@@ -197,8 +199,6 @@ private:
bool extractProgress(QProgressDialog &extractProgress, int percentage, std::string fileName);
void checkBSAList();
bool checkForProblems(QString &problemDescription);
int getBinaryExecuteInfo(const QFileInfo &targetInfo, QFileInfo &binaryInfo, QString &arguments);
@@ -277,6 +277,7 @@ private:
QStringList m_ActiveArchives;
bool m_DirectoryUpdate;
bool m_ArchivesInit;
QTimer m_CheckBSATimer;
QTime m_StartTime;
SaveGameInfoWidget *m_CurrentSaveView;
@@ -394,6 +395,8 @@ private slots:
void startExeAction();
void checkBSAList();
private slots: // ui slots
// actions
void on_actionAdd_Profile_triggered();
@@ -425,6 +428,7 @@ private slots: // ui slots
void on_espList_customContextMenuRequested(const QPoint &pos);
void on_displayCategoriesBtn_toggled(bool checked);
};
#endif // MAINWINDOW_H
+20 -1
View File
@@ -596,9 +596,18 @@ p, li { white-space: pre-wrap; }
<string notr="true">ESPs</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="margin">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
@@ -720,6 +729,16 @@ p, li { white-space: pre-wrap; }
</attribute>
</widget>
</item>
<item>
<widget class="MOBase::LineEditClear" name="espFilterEdit">
<property name="text">
<string/>
</property>
<property name="placeholderText">
<string>Namefilter</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="bsaTab">
+3
View File
@@ -731,6 +731,9 @@ ModInfoRegular::EConflictType ModInfoRegular::isConflicted() const
overwritten = true;
break;
}
} else if (alternatives.size() == 1) {
// only alternative is data -> no conflict
regular = true;
}
}
}
+2 -1
View File
@@ -145,7 +145,7 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const
} else {
if ((m_Profile->getModPriority(modIndex) == 0) && (role == Qt::DisplayRole)) {
return tr("min");
} else if ((m_Profile->getModPriority(modIndex) == m_Profile->numRegularMods() - 1) &&
} else if ((m_Profile->getModPriority(modIndex) == static_cast<int>(m_Profile->numRegularMods()) - 1) &&
(role == Qt::DisplayRole)) {
return tr("max");
} else {
@@ -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;
}
+3 -2
View File
@@ -142,8 +142,8 @@ void NexusDialog::login(const QString &username, const QString &password)
{
m_AccessManager->login(username, password);
connect(m_AccessManager, SIGNAL(loginSuccessful(bool)), this, SLOT(loginFinished(bool)));
connect(m_AccessManager, SIGNAL(loginFailed(QString)), this, SLOT(loginFailed(QString)));
connect(m_AccessManager, SIGNAL(loginSuccessful(bool)), this, SLOT(loginFinished(bool)), Qt::UniqueConnection);
connect(m_AccessManager, SIGNAL(loginFailed(QString)), this, SLOT(loginFailed(QString)), Qt::UniqueConnection);
}
@@ -160,6 +160,7 @@ void NexusDialog::loginFinished(bool necessary)
if (necessary && this->isVisible()) {
MessageDialog::showMessage(tr("login successful"), this);
}
loadNexus();
emit loginSuccessful(necessary);
}
+2 -1
View File
@@ -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);
+6 -1
View File
@@ -199,6 +199,11 @@ CONFIG(debug, debug|release) {
QMAKE_LFLAGS += /DEBUG
}
QMAKE_CXXFLAGS_WARN_ON -= -W3
QMAKE_CXXFLAGS_WARN_ON += -W4
QMAKE_CXXFLAGS += -wd4127 -wd4512 -wd4189
CONFIG += embed_manifest_exe
# QMAKE_CXXFLAGS += /analyze
@@ -231,7 +236,7 @@ TRANSLATIONS = organizer_de.ts \
PRE_TARGETDEPS += compiler_TSQM_make_all
} else:message(No translation files in project)
LIBS += -lmo_shared -luibase -lshell32 -lole32 -luser32 -ladvapi32 -lgdi32 -lPsapi -lVersion -lbsatk
LIBS += -lmo_shared -luibase -lshell32 -lole32 -luser32 -ladvapi32 -lgdi32 -lPsapi -lVersion -lbsatk -lshlwapi
DEFINES += UNICODE _UNICODE _CRT_SECURE_NO_WARNINGS NOMINMAX
Binary file not shown.

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