diff options
| -rw-r--r-- | src/installationmanager.cpp | 2 | ||||
| -rw-r--r-- | src/main.cpp | 2 | ||||
| -rw-r--r-- | src/mainwindow.cpp | 50 | ||||
| -rw-r--r-- | src/mainwindow.h | 5 | ||||
| -rw-r--r-- | src/moapplication.cpp | 29 | ||||
| -rw-r--r-- | src/moapplication.h | 2 | ||||
| -rw-r--r-- | src/modinfodialog.ui | 33 | ||||
| -rw-r--r-- | src/modlist.cpp | 7 | ||||
| -rw-r--r-- | src/modlist.h | 4 | ||||
| -rw-r--r-- | src/organizer.qbs | 44 | ||||
| -rw-r--r-- | src/pluginlist.cpp | 21 | ||||
| -rw-r--r-- | src/pluginlist.h | 7 | ||||
| -rw-r--r-- | src/settings.cpp | 3 | ||||
| -rw-r--r-- | src/shared/shared.qbs | 14 |
14 files changed, 167 insertions, 56 deletions
diff --git a/src/installationmanager.cpp b/src/installationmanager.cpp index 6b430eea..a8571ec9 100644 --- a/src/installationmanager.cpp +++ b/src/installationmanager.cpp @@ -506,7 +506,6 @@ bool InstallationManager::ensureValidModName(GuessedValue<QString> &name) const return true; } - bool InstallationManager::doInstall(GuessedValue<QString> &modName, int modID, const QString &version, const QString &newestVersion, int categoryID) { @@ -528,7 +527,6 @@ 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(), new MethodCallback<InstallationManager, void, float>(this, &InstallationManager::updateProgress), new MethodCallback<InstallationManager, void, LPCWSTR>(this, &InstallationManager::updateProgressFile), diff --git a/src/main.cpp b/src/main.cpp index 5053d21d..8b74ba83 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -60,7 +60,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "selectiondialog.h" #include "moapplication.h" #include "tutorialmanager.h" -#include <QLibrary> #include <iostream> #include <QMessageBox> #include <QSharedMemory> @@ -156,6 +155,7 @@ bool bootstrap() // verify the hook-dll exists QString dllName = qApp->applicationDirPath() + "/" + ToQString(AppConfig::hookDLLName()); + HMODULE dllMod = ::LoadLibraryW(ToWString(dllName).c_str()); if (dllMod == NULL) { throw windows_error("hook.dll is missing or invalid"); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index f726757c..a8026b68 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -188,8 +188,13 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget ui->modList->header()->installEventFilter(&m_ModList); if (initSettings.contains("mod_list_state")) { ui->modList->header()->restoreState(initSettings.value("mod_list_state").toByteArray()); + } else { + // hide these columns by default + ui->modList->header()->setSectionHidden(ModList::COL_MODID, true); + ui->modList->header()->setSectionHidden(ModList::COL_INSTALLTIME, true); } - ui->modList->header()->setSectionHidden(0, false); // prevent the name-column from being hidden + + ui->modList->header()->setSectionHidden(ModList::COL_NAME, false); // prevent the name-column from being hidden ui->modList->installEventFilter(&m_ModList); // set up plugin list @@ -1364,10 +1369,12 @@ void MainWindow::startExeAction() } -void MainWindow::refreshModList() +void MainWindow::refreshModList(bool saveChanges) { // don't lose changes! - m_CurrentProfile->writeModlistNow(true); + if (saveChanges) { + m_CurrentProfile->writeModlistNow(true); + } ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure); m_CurrentProfile->refreshModStatus(); @@ -2096,6 +2103,32 @@ QStringList MainWindow::findFiles(const QString &path, const std::function<bool( return result; } +QList<IOrganizer::FileInfo> MainWindow::findFileInfos(const QString &path, const std::function<bool (const IOrganizer::FileInfo &)> &filter) const +{ + QList<IOrganizer::FileInfo> result; + DirectoryEntry *dir = m_DirectoryStructure->findSubDirectoryRecursive(ToWString(path)); + if (dir != NULL) { + std::vector<FileEntry::Ptr> files = dir->getFiles(); + foreach (FileEntry::Ptr file, files) { + FileInfo info; + info.filePath = ToQString(file->getFullPath()); + bool fromArchive = false; + info.origins.append(ToQString(m_DirectoryStructure->getOriginByID(file->getOrigin(fromArchive)).getName())); + info.archive = fromArchive ? ToQString(file->getArchive()) : ""; + foreach (int idx, file->getAlternatives()) { + info.origins.append(ToQString(m_DirectoryStructure->getOriginByID(idx).getName())); + } + + if (filter(info)) { + result.append(info); + } + } + } else { + qWarning("directory %s not found", qPrintable(path)); + } + return result; +} + IDownloadManager *MainWindow::downloadManager() { return &m_DownloadManager; @@ -2161,6 +2194,9 @@ std::vector<unsigned int> MainWindow::activeProblems() const if (m_UnloadedPlugins.size() != 0) { problems.push_back(PROBLEM_PLUGINSNOTLOADED); } + if (m_PluginList.enabledCount() > 256) { + problems.push_back(PROBLEM_TOOMANYPLUGINS); + } return problems; } @@ -2170,6 +2206,9 @@ QString MainWindow::shortDescription(unsigned int key) const case PROBLEM_PLUGINSNOTLOADED: { return tr("Some plugins could not be loaded"); } break; + case PROBLEM_TOOMANYPLUGINS: { + return tr("Too many esps and esms enabled"); + } break; default: { return tr("Description missing"); } break; @@ -2187,6 +2226,10 @@ QString MainWindow::fullDescription(unsigned int key) const result += "<ul>"; return result; } break; + case PROBLEM_TOOMANYPLUGINS: { + return tr("The game doesn't allow more than 256 active plugins (including the official ones) to be loaded. You have to disable some unused plugins or " + "merge some plugins into one. You can find a guide here: <a href=\"http://wiki.step-project.com/Guide:Merging_Plugins\">http://wiki.step-project.com/Guide:Merging_Plugins</a>"); + } break; default: { return tr("Description missing"); } break; @@ -3195,6 +3238,7 @@ void MainWindow::syncOverwrite() modInfo->testValid(); refreshDirectoryStructure(); } + } void MainWindow::createModFromOverwrite() diff --git a/src/mainwindow.h b/src/mainwindow.h index cf97d4f9..dfd2e571 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -98,7 +98,6 @@ public: void refreshBSAList(); void refreshDataTree(); void refreshSaveList(); - void refreshModList(); void setExecutablesList(const ExecutablesList &executablesList); @@ -135,11 +134,14 @@ public: virtual QString resolvePath(const QString &fileName) const; virtual QStringList listDirectories(const QString &directoryName) const; virtual QStringList findFiles(const QString &path, const std::function<bool(const QString &)> &filter) const; + virtual QList<FileInfo> findFileInfos(const QString &path, const std::function<bool(const FileInfo&)> &filter) const; + virtual MOBase::IDownloadManager *downloadManager(); virtual MOBase::IPluginList *pluginList(); virtual MOBase::IModList *modList(); virtual HANDLE startApplication(const QString &executable, const QStringList &args = QStringList(), const QString &cwd = "", const QString &profile = ""); virtual bool onAboutToRun(const std::function<bool(const QString&)> &func); + virtual void refreshModList(bool saveChanges = true); virtual std::vector<unsigned int> activeProblems() const; virtual QString shortDescription(unsigned int key) const; @@ -274,6 +276,7 @@ private: private: static const unsigned int PROBLEM_PLUGINSNOTLOADED = 1; + static const unsigned int PROBLEM_TOOMANYPLUGINS = 2; private: diff --git a/src/moapplication.cpp b/src/moapplication.cpp index ba23808b..7e3104db 100644 --- a/src/moapplication.cpp +++ b/src/moapplication.cpp @@ -23,12 +23,15 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include <appconfig.h> #include <QFile> #include <QStringList> +#include <QPlastiqueStyle> +#include <QCleanlooksStyle> MOApplication::MOApplication(int argc, char **argv) : QApplication(argc, argv) { connect(&m_StyleWatcher, SIGNAL(fileChanged(QString)), SLOT(updateStyle(QString))); + m_DefaultStyle = style()->objectName(); } @@ -42,11 +45,12 @@ bool MOApplication::setStyleFile(const QString &styleName) // set new stylesheet or clear it if (styleName.length() != 0) { QString styleSheetName = applicationDirPath() + "/" + MOBase::ToQString(AppConfig::stylesheetsPath()) + "/" + styleName; - if (!QFile::exists(styleSheetName)) { - return false; + if (QFile::exists(styleSheetName)) { + m_StyleWatcher.addPath(styleSheetName); + updateStyle(styleSheetName); + } else { + updateStyle(styleName); } - m_StyleWatcher.addPath(styleSheetName); - updateStyle(styleSheetName); } else { setStyleSheet(""); } @@ -74,11 +78,18 @@ bool MOApplication::notify(QObject *receiver, QEvent *event) void MOApplication::updateStyle(const QString &fileName) { - QFile file(fileName); - if (file.open(QFile::ReadOnly)) { - setStyleSheet(file.readAll()); + if (fileName == "Plastique") { + setStyle(new QPlastiqueStyle); + setStyleSheet(""); + } else if (fileName == "Cleanlooks") { + setStyle(new QCleanlooksStyle); + setStyleSheet(""); } else { - qDebug("no stylesheet"); + setStyle(m_DefaultStyle); + if (QFile::exists(fileName)) { + setStyleSheet(QString("file:///%1").arg(fileName)); + } else { + qWarning("invalid stylesheet: %s", qPrintable(fileName)); + } } - file.close(); } diff --git a/src/moapplication.h b/src/moapplication.h index dd7f5eab..645b9144 100644 --- a/src/moapplication.h +++ b/src/moapplication.h @@ -43,6 +43,8 @@ private slots: private: QFileSystemWatcher m_StyleWatcher; + QString m_DefaultStyle; + }; diff --git a/src/modinfodialog.ui b/src/modinfodialog.ui index 2fdbe5f3..d0039a95 100644 --- a/src/modinfodialog.ui +++ b/src/modinfodialog.ui @@ -209,7 +209,7 @@ <rect>
<x>0</x>
<y>0</y>
- <width>668</width>
+ <width>676</width>
<height>126</height>
</rect>
</property>
@@ -223,16 +223,7 @@ <property name="spacing">
<number>0</number>
</property>
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
+ <property name="margin">
<number>0</number>
</property>
<item>
@@ -293,7 +284,7 @@ Most mods do not have optional esps, so chances are good you are looking at an e <string/>
</property>
<property name="icon">
- <iconset resource="resources.qrc">
+ <iconset>
<normaloff>:/MO/gui/resources/go-up.png</normaloff>:/MO/gui/resources/go-up.png</iconset>
</property>
<property name="iconSize">
@@ -322,7 +313,7 @@ Most mods do not have optional esps, so chances are good you are looking at an e <string/>
</property>
<property name="icon">
- <iconset resource="resources.qrc">
+ <iconset>
<normaloff>:/MO/gui/resources/go-down.png</normaloff>:/MO/gui/resources/go-down.png</iconset>
</property>
<property name="iconSize">
@@ -525,9 +516,9 @@ Most mods do not have optional esps, so chances are good you are looking at an e </widget>
</item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout_8">
+ <layout class="QHBoxLayout" name="horizontalLayout_12">
<item>
- <widget class="QLabel" name="label_9">
+ <widget class="QLabel" name="label_12">
<property name="text">
<string>Primary Category</string>
</property>
@@ -542,7 +533,7 @@ Most mods do not have optional esps, so chances are good you are looking at an e </widget>
<widget class="QWidget" name="tabNexus_2">
<attribute name="icon">
- <iconset resource="resources.qrc">
+ <iconset>
<normaloff>:/MO/gui/resources/internet-web-browser.png</normaloff>:/MO/gui/resources/internet-web-browser.png</iconset>
</attribute>
<attribute name="title">
@@ -634,7 +625,7 @@ p, li { white-space: pre-wrap; } <string/>
</property>
<property name="icon">
- <iconset resource="resources.qrc">
+ <iconset>
<normaloff>:/MO/gui/refresh</normaloff>:/MO/gui/refresh</iconset>
</property>
</widget>
@@ -660,7 +651,7 @@ p, li { white-space: pre-wrap; } <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:7.8pt; font-weight:400; font-style:normal;">
+</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p></body></html></string>
</property>
@@ -696,7 +687,7 @@ p, li { white-space: pre-wrap; } <string>Endorse</string>
</property>
<property name="icon">
- <iconset resource="resources.qrc">
+ <iconset>
<normaloff>:/MO/gui/icon_favorite</normaloff>:/MO/gui/icon_favorite</iconset>
</property>
</widget>
@@ -791,8 +782,6 @@ p, li { white-space: pre-wrap; } </item>
</layout>
</widget>
- <resources>
- <include location="resources.qrc"/>
- </resources>
+ <resources/>
<connections/>
</ui>
diff --git a/src/modlist.cpp b/src/modlist.cpp index eac02372..b35d6ad2 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -186,7 +186,12 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const return QVariant(); } } else if (column == COL_INSTALLTIME) { - return modInfo->creationTime(); + // display installation time for mods that can be updated + if (modInfo->canBeUpdated()) { + return modInfo->creationTime(); + } else { + return QVariant(); + } } else { return tr("invalid"); } diff --git a/src/modlist.h b/src/modlist.h index 8cab7f3e..cc5955d0 100644 --- a/src/modlist.h +++ b/src/modlist.h @@ -275,6 +275,10 @@ private: SignalModStateChanged m_ModStateChanged; + + // QAbstractItemModel interface + + // IModList interface }; #endif // MODLIST_H diff --git a/src/organizer.qbs b/src/organizer.qbs index fdfb914c..2b7f45fc 100644 --- a/src/organizer.qbs +++ b/src/organizer.qbs @@ -3,21 +3,41 @@ import qbs.base 1.0 Application {
name: 'Organizer'
- Depends { name: 'Qt.core' }
- Depends { name: 'Qt.gui' }
- Depends { name: 'Qt.network' }
- Depends { name: 'Qt.declarative' }
- Depends { name: 'UIBase' }
+ Depends { name: "Qt"; submodules: ["core", "gui", "network", "declarative"] }
Depends { name: 'Shared' }
+ Depends { name: 'UIBase' }
Depends { name: 'cpp' }
- cpp.defines: []
- cpp.includePaths: [ '../shared', '../archive', '../uibase', qbs.getenv("BOOSTPATH") ]
+ cpp.defines: [ 'UNICODE', '_UNICODE' ]
+ cpp.libraryPaths: [ qbs.getenv('BOOSTPATH') + '/stage/lib' ]
+ cpp.includePaths: [ '../shared', '../archive', '../bsatk', '../esptk', '../uibase', qbs.getenv("BOOSTPATH") ]
// '../bsatk', '../esptk',
- files: [
- '*.cpp',
- '*.h',
- '*.ui'
- ]
+ cpp.staticLibraries: [ 'shell32', 'user32', 'Version', 'shlwapi' ]
+ //LIBS += -lmo_shared -luibase -lshell32 -lole32 -luser32 -ladvapi32 -lgdi32 -lPsapi -lVersion -lbsatk -lshlwapi
+
+ Group {
+ name: 'Headers'
+ files: [ '*.h' ]
+ }
+
+ Group {
+ name: 'Sources'
+ files: [ '*.cpp' ]
+ }
+
+ Group {
+ name: 'UI Files'
+ files: [ '*.ui' ]
+ }
+
+ Group {
+ name: 'ESP Toolkit'
+ files: [ '../esptk/*.h', '../esptk/*.cpp' ]
+ }
}
+
+// /nologo /c
+
+
+// /Zi -GR -W3
diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index b0228849..8eeed76e 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -499,6 +499,17 @@ bool PluginList::saveLoadOrder(DirectoryEntry &directoryStructure) return true; } +int PluginList::enabledCount() const +{ + int enabled = 0; + foreach (auto info, m_ESPs) { + if (info.m_Enabled) { + ++enabled; + } + } + return enabled; +} + bool PluginList::isESPLocked(int index) const { return m_LockedOrder.find(m_ESPs.at(index).m_Name.toLower()) != m_LockedOrder.end(); @@ -713,6 +724,8 @@ QVariant PluginList::data(const QModelIndex &modelIndex, int role) const return QIcon(":/MO/gui/warning"); } else if (m_LockedOrder.find(m_ESPs[index].m_Name.toLower()) != m_LockedOrder.end()) { return QIcon(":/MO/gui/locked"); + } else if (m_ESPs[index].m_IsDummy && m_ESPs[index].m_Enabled) { + return QIcon(":/MO/gui/edit_clear"); } else { return QVariant(); } @@ -723,6 +736,8 @@ QVariant PluginList::data(const QModelIndex &modelIndex, int role) const if (m_ESPs[index].m_IsMaster) { result.setItalic(true); result.setWeight(QFont::Bold); + } else if (m_ESPs[index].m_IsDummy) { + result.setItalic(true); } return result; } else if (role == Qt::TextAlignmentRole) { @@ -744,6 +759,10 @@ QVariant PluginList::data(const QModelIndex &modelIndex, int role) const m_ESPs[index].m_MasterUnset.begin(), m_ESPs[index].m_MasterUnset.end(), std::inserter(enabledMasters, enabledMasters.end())); text += "<br>" + tr("Enabled Masters") + ": " + SetJoin(enabledMasters, ", "); + if (m_ESPs[index].m_IsDummy) { + text += "<br>This file is a dummy! It exists only so the bsa with the same name gets loaded. With MO you don't need this: " + "If you enable the archive with the same name in the \"Archive\" tab you can disable this plugin."; + } return text; } } else { @@ -1009,6 +1028,7 @@ PluginList::ESPInfo::ESPInfo(const QString &name, bool enabled, FILETIME time, c try { ESP::File file(ToWString(fullPath)); m_IsMaster = file.isMaster(); + m_IsDummy = file.isDummy(); std::set<std::string> masters = file.masters(); for (auto iter = masters.begin(); iter != masters.end(); ++iter) { m_Masters.insert(QString(iter->c_str())); @@ -1016,5 +1036,6 @@ PluginList::ESPInfo::ESPInfo(const QString &name, bool enabled, FILETIME time, c } catch (const std::exception &e) { qCritical("failed to parse esp file %s: %s", qPrintable(fullPath), e.what()); m_IsMaster = false; + m_IsDummy = false; } } diff --git a/src/pluginlist.h b/src/pluginlist.h index 2af5a0df..2f1a3f5f 100644 --- a/src/pluginlist.h +++ b/src/pluginlist.h @@ -126,6 +126,12 @@ public: **/ bool saveLoadOrder(MOShared::DirectoryEntry &directoryStructure); + /** + * @return number of enabled plugins in the list + */ + int enabledCount() const; + + QString getName(int index) const { return m_ESPs.at(index).m_Name; } int getPriority(int index) const { return m_ESPs.at(index).m_Priority; } bool isESPLocked(int index) const; @@ -198,6 +204,7 @@ private: FILETIME m_Time; QString m_OriginName; bool m_IsMaster; + bool m_IsDummy; std::set<QString> m_Masters; mutable std::set<QString> m_MasterUnset; }; diff --git a/src/settings.cpp b/src/settings.cpp index 36a4f1f8..144049aa 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -422,6 +422,9 @@ void Settings::addLanguages(QComboBox *languageBox) void Settings::addStyles(QComboBox *styleBox) { styleBox->addItem("None", ""); + styleBox->addItem("Plastique", "Plastique"); + styleBox->addItem("Cleanlooks", "Cleanlooks"); + QDirIterator langIter(QCoreApplication::applicationDirPath() + "/" + ToQString(AppConfig::stylesheetsPath()), QStringList("*.qss"), QDir::Files); while (langIter.hasNext()) { langIter.next(); diff --git a/src/shared/shared.qbs b/src/shared/shared.qbs index 44b7539f..1fa471a0 100644 --- a/src/shared/shared.qbs +++ b/src/shared/shared.qbs @@ -1,16 +1,20 @@ import qbs.base 1.0
-Application {
- name: 'Shared'
+StaticLibrary {
+ name: {
+ print(qbs.getenv("BOOSTPATH") + "/stage/lib")
+ return 'Shared'
+ }
Depends { name: 'cpp' }
Depends { name: 'BSAToolkit' }
cpp.defines: []
- cpp.libraryPaths: [ qbs.getenv("BOOSTPATH") ]
- cpp.includePaths: [ 'bsatk', qbs.getenv("BOOSTPATH") ]
+ cpp.libraryPaths: [ qbs.getenv("BOOSTPATH") + "/stage/lib" ]
+ cpp.includePaths: [ '../bsatk', qbs.getenv("BOOSTPATH") ]
files: [
'*.h',
- '*.cpp'
+ '*.cpp',
+ '*.inc'
]
}
|
