summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/installationmanager.cpp2
-rw-r--r--src/main.cpp2
-rw-r--r--src/mainwindow.cpp50
-rw-r--r--src/mainwindow.h5
-rw-r--r--src/moapplication.cpp29
-rw-r--r--src/moapplication.h2
-rw-r--r--src/modinfodialog.ui33
-rw-r--r--src/modlist.cpp7
-rw-r--r--src/modlist.h4
-rw-r--r--src/organizer.qbs44
-rw-r--r--src/pluginlist.cpp21
-rw-r--r--src/pluginlist.h7
-rw-r--r--src/settings.cpp3
-rw-r--r--src/shared/shared.qbs14
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>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
-&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:7.8pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-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;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;-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;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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'
]
}