From bf0db9c218edde72750426e2fb273359497db5bb Mon Sep 17 00:00:00 2001 From: Tannin Date: Sun, 25 Aug 2013 13:15:23 +0200 Subject: - position of splitter in main window is now saved and restored - confirmation dialog before enabling/disabling all plugins - bugfix: GetPrivateProfileString-hook potentially accessed buffer that is allowed to be NULL - bugfix: attempt to extract an archive crashed MO in 0.99.2 - bugfix: archive list wasn't saved correctly in 0.99.2 - bugfix: plugins.txt was incorrectly interpreted as utf-8 --- src/downloadlistwidgetcompact.cpp | 2 +- src/downloadlistwidgetcompact.ui | 36 +++++--------- src/mainwindow.cpp | 99 +++++++++++++++++++++++---------------- src/mainwindow.h | 2 +- src/pluginlist.cpp | 48 +++++++++---------- src/pluginlist.h | 3 ++ src/version.rc | 4 +- 7 files changed, 101 insertions(+), 93 deletions(-) (limited to 'src') diff --git a/src/downloadlistwidgetcompact.cpp b/src/downloadlistwidgetcompact.cpp index f3e395da..0cbdd0b1 100644 --- a/src/downloadlistwidgetcompact.cpp +++ b/src/downloadlistwidgetcompact.cpp @@ -110,7 +110,7 @@ void DownloadListWidgetCompactDelegate::paint(QPainter *painter, const QStyleOpt DownloadManager::DownloadState state = m_Manager->getState(downloadIndex); - if (state >= DownloadManager::STATE_READY) { + if ((m_SizeLabel != NULL) && (state >= DownloadManager::STATE_READY)) { m_SizeLabel->setText(QString::number(m_Manager->getFileSize(downloadIndex) / 1048576)); } diff --git a/src/downloadlistwidgetcompact.ui b/src/downloadlistwidgetcompact.ui index bc960c8e..b43f1fb3 100644 --- a/src/downloadlistwidgetcompact.ui +++ b/src/downloadlistwidgetcompact.ui @@ -7,7 +7,7 @@ 0 0 315 - 22 + 24 @@ -23,14 +23,23 @@ 2 - + + 2 + + + 2 + + + 2 + + 2 - 1 + 0 0 @@ -48,27 +57,6 @@ - - - - ( - - - - - - - 0 - - - - - - - MB) - - - diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 9d0a7f07..ebfdfc42 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -100,6 +100,11 @@ along with Mod Organizer. If not, see . #include +#ifdef TEST_MODELS +#include "modeltest.h" +#endif // TEST_MODELS + + using namespace MOBase; using namespace MOShared; @@ -128,11 +133,6 @@ static bool isOnline() } -#ifdef TEST_MODELS -#include "modeltest.h" -#endif // TEST_MODELS - - MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), m_Tutorial(this, "MainWindow"), m_ExeName(exeName), m_OldProfileIndex(-1), @@ -162,7 +162,6 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget updateProblemsButton(); updateToolBar(); -// ui->toolBar->blockSignals(true); ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure); @@ -181,21 +180,26 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget ui->modList->setItemDelegateForColumn(ModList::COL_FLAGS, new IconDelegate(ui->modList)); //ui->modList->setAcceptDrops(true); ui->modList->header()->installEventFilter(&m_ModList); - ui->modList->header()->restoreState(initSettings.value("mod_list_state").toByteArray()); + if (initSettings.contains("mod_list_state")) { + ui->modList->header()->restoreState(initSettings.value("mod_list_state").toByteArray()); + } ui->modList->header()->setSectionHidden(0, false); // prevent the name-column from being hidden ui->modList->installEventFilter(&m_ModList); - resizeLists(); - // set up plugin list m_PluginListSortProxy = new PluginListSortProxy(this); m_PluginListSortProxy->setSourceModel(&m_PluginList); ui->espList->setModel(m_PluginListSortProxy); ui->espList->sortByColumn(PluginList::COL_PRIORITY, Qt::AscendingOrder); - ui->espList->header()->restoreState(initSettings.value("plugin_list_state").toByteArray()); + if (initSettings.contains("plugin_list_state")) { + ui->espList->header()->restoreState(initSettings.value("plugin_list_state").toByteArray()); + } ui->espList->installEventFilter(&m_PluginList); + resizeLists(initSettings.contains("mod_list_state"), initSettings.contains("plugin_list_state")); + + QMenu *linkMenu = new QMenu(this); linkMenu->addAction(QIcon(":/MO/gui/link"), tr("Toolbar"), this, SLOT(linkToolbar())); linkMenu->addAction(QIcon(":/MO/gui/link"), tr("Desktop"), this, SLOT(linkDesktop())); @@ -294,34 +298,37 @@ MainWindow::~MainWindow() } -void MainWindow::resizeLists() +void MainWindow::resizeLists(bool modListCustom, bool pluginListCustom) { - // resize mod list to fit content + if (!modListCustom) { + // resize mod list to fit content #if QT_VERSION >= QT_VERSION_CHECK(5,0,0) - for (int i = 0; i < ui->modList->header()->count(); ++i) { - ui->modList->header()->setSectionResizeMode(i, QHeaderView::ResizeToContents); - } - ui->modList->header()->setSectionResizeMode(ModList::COL_NAME, QHeaderView::Stretch); + for (int i = 0; i < ui->modList->header()->count(); ++i) { + ui->modList->header()->setSectionResizeMode(i, QHeaderView::ResizeToContents); + } + ui->modList->header()->setSectionResizeMode(ModList::COL_NAME, QHeaderView::Stretch); #else - for (int i = 0; i < ui->modList->header()->count(); ++i) { - ui->modList->header()->setResizeMode(i, QHeaderView::ResizeToContents); - } - ui->modList->header()->setResizeMode(ModList::COL_NAME, QHeaderView::Stretch); + for (int i = 0; i < ui->modList->header()->count(); ++i) { + ui->modList->header()->setResizeMode(i, QHeaderView::ResizeToContents); + } + ui->modList->header()->setResizeMode(ModList::COL_NAME, QHeaderView::Stretch); #endif + } - - // resize plugin list to fit content + if (!pluginListCustom) { + // resize plugin list to fit content #if QT_VERSION >= QT_VERSION_CHECK(5,0,0) - for (int i = 0; i < ui->espList->header()->count(); ++i) { - ui->espList->header()->setSectionResizeMode(i, QHeaderView::ResizeToContents); - } - ui->espList->header()->setSectionResizeMode(0, QHeaderView::Stretch); + for (int i = 0; i < ui->espList->header()->count(); ++i) { + ui->espList->header()->setSectionResizeMode(i, QHeaderView::ResizeToContents); + } + ui->espList->header()->setSectionResizeMode(0, QHeaderView::Stretch); #else - for (int i = 0; i < ui->espList->header()->count(); ++i) { - ui->espList->header()->setResizeMode(i, QHeaderView::ResizeToContents); - } - ui->espList->header()->setResizeMode(0, QHeaderView::Stretch); + for (int i = 0; i < ui->espList->header()->count(); ++i) { + ui->espList->header()->setResizeMode(i, QHeaderView::ResizeToContents); + } + ui->espList->header()->setResizeMode(0, QHeaderView::Stretch); #endif + } } @@ -580,9 +587,12 @@ void MainWindow::saveArchiveList() 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")); + QTreeWidgetItem *tlItem = ui->bsaList->topLevelItem(i); + for (int j = 0; j < tlItem->childCount(); ++j) { + QTreeWidgetItem *item = tlItem->child(j); + if (item->checkState(0) == Qt::Checked) { + archiveFile.write(item->text(0).toUtf8().append("\r\n")); + } } } } else { @@ -1038,7 +1048,7 @@ void MainWindow::loadPlugins() pluginName.toUtf8().constData(), pluginLoader.errorString().toUtf8().constData()); } else { if (registerPlugin(pluginLoader.instance())) { - qDebug("loaded plugin \"%s\"", pluginName.toUtf8().constData()); + qDebug("loaded plugin \"%s\"", QDir::toNativeSeparators(pluginName).toUtf8().constData()); } else { m_UnloadedPlugins.push_back(pluginName); qWarning("plugin \"%s\" failed to load", pluginName.toUtf8().constData()); @@ -1615,7 +1625,8 @@ void MainWindow::refreshESPList() m_CurrentProfile->writeModlist(); // clear list - m_PluginList.refresh(m_CurrentProfile->getName(), *m_DirectoryStructure, + m_PluginList.refresh(m_CurrentProfile->getName(), + *m_DirectoryStructure, m_CurrentProfile->getPluginsFileName(), m_CurrentProfile->getLoadOrderFileName(), m_CurrentProfile->getLockedOrderFileName()); @@ -1839,6 +1850,10 @@ void MainWindow::readSettings() restoreGeometry(settings.value("window_geometry").toByteArray()); } + if (settings.contains("window_split")) { + ui->splitter->restoreState(settings.value("window_split").toByteArray()); + } + bool filtersVisible = settings.value("filters_visible", false).toBool(); setCategoryListVisible(filtersVisible); ui->displayCategoriesBtn->setChecked(filtersVisible); @@ -1877,7 +1892,8 @@ void MainWindow::storeSettings() settings.setValue("compact_downloads", ui->compactBox->isChecked()); settings.setValue("ask_for_nexuspw", m_AskForNexusPW); - settings.setValue("window_geometry", this->saveGeometry()); + settings.setValue("window_geometry", saveGeometry()); + settings.setValue("window_split", ui->splitter->saveState()); settings.setValue("filters_visible", ui->displayCategoriesBtn->isChecked()); @@ -4305,10 +4321,9 @@ bool MainWindow::extractProgress(QProgressDialog &progress, int percentage, std: void MainWindow::extractBSATriggered() { - QTreeWidgetItem *item = ui->bsaList->topLevelItem(m_ContextRow); + QTreeWidgetItem *item = m_ContextItem; QString targetFolder = FileDialogMemory::getExistingDirectory("extractBSA", this, tr("Extract BSA")); - if (!targetFolder.isEmpty()) { BSA::Archive archive; QString originPath = QDir::fromNativeSeparators(ToQString(m_DirectoryStructure->getOriginByName(ToWString(item->text(1))).getPath())); @@ -4324,10 +4339,8 @@ void MainWindow::extractBSATriggered() progress.setMaximum(100); progress.setValue(0); progress.show(); - archive.extractAll(QDir::toNativeSeparators(targetFolder).toUtf8().constData(), boost::bind(&MainWindow::extractProgress, this, boost::ref(progress), _1, _2)); - if (result == BSA::ERROR_INVALIDHASHES) { reportError(tr("This archive contains invalid hashes. Some files may be broken.")); } @@ -4369,7 +4382,9 @@ void MainWindow::displayColumnSelection(const QPoint &pos) void MainWindow::on_bsaList_customContextMenuRequested(const QPoint &pos) { - m_ContextRow = ui->bsaList->indexOfTopLevelItem(ui->bsaList->itemAt(pos)); + m_ContextItem = ui->bsaList->itemAt(pos); + +// m_ContextRow = ui->bsaList->indexOfTopLevelItem(ui->bsaList->itemAt(pos)); QMenu menu; menu.addAction(tr("Extract..."), this, SLOT(extractBSATriggered())); @@ -4475,6 +4490,8 @@ void MainWindow::on_espList_customContextMenuRequested(const QPoint &pos) } } + menu.addSeparator(); + if (hasLocked) { menu.addAction(tr("Unlock load order"), this, SLOT(unlockESPIndex())); } diff --git a/src/mainwindow.h b/src/mainwindow.h index ae2343c6..e9115e06 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -445,7 +445,7 @@ private slots: /** * @brief resize columns in mod list and plugin list to content */ - void resizeLists(); + void resizeLists(bool modListCustom, bool pluginListCustom); /** * @brief allow columns in mod list and plugin list to be resized diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index dc2410ee..95780c18 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -78,6 +78,15 @@ PluginList::PluginList(QObject *parent) { m_SaveTimer.setSingleShot(true); connect(&m_SaveTimer, SIGNAL(timeout()), this, SIGNAL(saveTimer())); + + m_Utf8Codec = QTextCodec::codecForName("utf-8"); + m_LocalCodec = QTextCodec::codecForName("Windows-1252"); + + if (m_LocalCodec == NULL) { + qCritical("required 8-bit string-encoding not supported."); + m_LocalCodec = m_Utf8Codec; + } + } @@ -203,21 +212,27 @@ void PluginList::enableESP(const QString &name) void PluginList::enableAll() { - for (std::vector::iterator iter = m_ESPs.begin(); iter != m_ESPs.end(); ++iter) { - iter->m_Enabled = true; + if (QMessageBox::question(NULL, tr("Confirm"), tr("Really enable all plugins?"), + QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { + for (std::vector::iterator iter = m_ESPs.begin(); iter != m_ESPs.end(); ++iter) { + iter->m_Enabled = true; + } + startSaveTime(); } - startSaveTime(); } void PluginList::disableAll() { - for (std::vector::iterator iter = m_ESPs.begin(); iter != m_ESPs.end(); ++iter) { - if (!iter->m_ForceEnabled) { - iter->m_Enabled = false; + if (QMessageBox::question(NULL, tr("Confirm"), tr("Really disable all plugins?"), + QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { + for (std::vector::iterator iter = m_ESPs.begin(); iter != m_ESPs.end(); ++iter) { + if (!iter->m_ForceEnabled) { + iter->m_Enabled = false; + } } + startSaveTime(); } - startSaveTime(); } @@ -300,7 +315,7 @@ void PluginList::readEnabledFrom(const QString &fileName) QByteArray line = file.readLine(); QString modName; if ((line.size() > 0) && (line.at(0) != '#')) { - modName = QString::fromUtf8(line.trimmed().constData()); + modName = m_LocalCodec->toUnicode(line.trimmed().constData()); } if (modName.size() > 0) { std::map::iterator iter = m_ESPsByName.find(modName.toLower()); @@ -351,22 +366,7 @@ void PluginList::writePlugins(const QString &fileName, bool writeUnchecked) cons throw MyException(tr("failed to open output file: %1").arg(fileName)); } - QTextCodec *textCodec = writeUnchecked ? QTextCodec::codecForName("utf-8") - : QTextCodec::codecForName("Windows-1252"); - - if (textCodec == NULL) { - QList encodingList = QTextCodec::availableCodecs(); - QString encodings; - QTextStream temp(&encodings); - foreach (QByteArray encoding, encodingList) { - temp << encoding << ", "; - } - qCritical("required string-encoding not supported. Available codecs: %s", - encodings.toUtf8().constData()); - - throw std::runtime_error(QObject::tr("encoding error, please report this as a bug and include the file " - "mo_interface.log!").toUtf8().constData()); - } + QTextCodec *textCodec = writeUnchecked ? m_Utf8Codec : m_LocalCodec; file.resize(0); diff --git a/src/pluginlist.h b/src/pluginlist.h index bba775dc..003abd53 100644 --- a/src/pluginlist.h +++ b/src/pluginlist.h @@ -223,6 +223,9 @@ private: QString m_CurrentProfile; QFontMetrics m_FontMetrics; + QTextCodec *m_Utf8Codec; + QTextCodec *m_LocalCodec; + mutable QTimer m_SaveTimer; }; diff --git a/src/version.rc b/src/version.rc index e23603f1..42e947f5 100644 --- a/src/version.rc +++ b/src/version.rc @@ -1,7 +1,7 @@ #include "Winver.h" -#define VER_FILEVERSION 0,99,2,0 -#define VER_FILEVERSION_STR "0,99,2,0\0" +#define VER_FILEVERSION 0,99,3,0 +#define VER_FILEVERSION_STR "0,99,3,0\0" VS_VERSION_INFO VERSIONINFO FILEVERSION VER_FILEVERSION -- cgit v1.3.1