mirror of
https://github.com/ModOrganizer2/modorganizer.git
synced 2026-07-27 13:58:24 -07:00
Compare commits
23
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff78c6a014 | ||
|
|
340edcfbca | ||
|
|
c4f0bc39c7 | ||
|
|
e71c37df37 | ||
|
|
b32457a7d2 | ||
|
|
6e1e8c37eb | ||
|
|
469cc2d945 | ||
|
|
0e90b9d233 | ||
|
|
0e19c84722 | ||
|
|
daf4ae44fa | ||
|
|
ac29aa81f2 | ||
|
|
a0335d0a63 | ||
|
|
f1515193ca | ||
|
|
db0347212a | ||
|
|
5895a1a92d | ||
|
|
c6101e34e1 | ||
|
|
75475a7984 | ||
|
|
315ed6e41a | ||
|
|
b2d613e9d1 | ||
|
|
f010c22a3b | ||
|
|
d1594798e6 | ||
|
|
09bd3dbead | ||
|
|
8c0b309bde |
+14
-11
@@ -6,29 +6,31 @@ Requirements:
|
||||
|
||||
Visual C++ compiler 2010 (VC 10.0) or up
|
||||
- Included in visual c++ express 2010 or windows sdk 7.0
|
||||
Note: If you're having trouble installing the windows sdk, you may be affected by this bug: http://support.microsoft.com/kb/2717426
|
||||
|
||||
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
|
||||
- Compile according to their instructions (using vc++): http://www.boost.org/doc/libs/1_54_0/more/getting_started/windows.html
|
||||
- A few of the boost libraries need to be built (the rest is header-only). The only compiled lib MO needs (at the time of writing) is
|
||||
boost_thread. You can disable the others to safe yourself compile time (even on a modern system compiling boost can easily take an hour)
|
||||
|
||||
zlib (http://www.zlib.net/)
|
||||
- Compile static library according to their instructions
|
||||
- You should have a "zlibstatic.lib" under "build" afterwards
|
||||
- Depending on the version of zlib and how you built you should have a file called zlibstatic.lib or zlibstat.lib in "build" or "x86\ZLibStatRelease".
|
||||
- Please copy that lib file to "build\zlibstatic.lib" (if it doesn't exist) so MO finds it.
|
||||
|
||||
7z.dll (http://www.7-zip.org/download.html)
|
||||
- Part of the 7-zip program
|
||||
- Has to be the 32-bit dll! (approx. 893kb)
|
||||
- If you don't want to install 7-zip (32-bit) you can open the 7z installer (i.e. 7z920.exe) in an archiving tool and unpack only the 7z.dll
|
||||
|
||||
Recommended:
|
||||
------------
|
||||
|
||||
Qt Creator
|
||||
- Included in QtSDK but there might be a newer version as a separate download
|
||||
|
||||
Set up (using Qt Creator):
|
||||
--------------------------
|
||||
@@ -40,14 +42,15 @@ Set up (using Qt Creator):
|
||||
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"
|
||||
8. Determine the folder of the qt binaries in the package you downloaded. This could be "QtSDK\Desktop\Qt\4.8.5\msvc2010\bin" or "Qt4.8.5\bin"
|
||||
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
|
||||
9r. Add a "Run configuration" that points to <your working copy>\output\ModOrganizer.exe
|
||||
10r. Copy "7z.dll" to <your working copy>\output\dlls
|
||||
11r. From the qt binaries directory, 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
|
||||
9d. Add a "Run configuration" that points to <your working copy>\outputd\ModOrganizer.exe
|
||||
10d. Copy "7z.dll" to <your working copy>\outputd\dlls
|
||||
11d. From the qt binaries 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
|
||||
|
||||
+11
-11
@@ -1,23 +1,23 @@
|
||||
TEMPLATE = subdirs
|
||||
CONFIG += ordered
|
||||
|
||||
|
||||
SUBDIRS = bsatk \
|
||||
shared \
|
||||
uibase \
|
||||
organizer \
|
||||
hookdll \
|
||||
archive \
|
||||
helper \
|
||||
shared \
|
||||
uibase \
|
||||
organizer \
|
||||
hookdll \
|
||||
archive \
|
||||
helper \
|
||||
plugins \
|
||||
proxydll \
|
||||
nxmhandler \
|
||||
BossDummy \
|
||||
pythonRunner \
|
||||
esptk
|
||||
BossDummy \
|
||||
pythonRunner \
|
||||
esptk
|
||||
|
||||
plugins.depends = pythonRunner
|
||||
hookdll.depends = shared
|
||||
organizer.depends = shared, uibase, plugins
|
||||
organizer.depends = shared uibase plugins
|
||||
|
||||
CONFIG(debug, debug|release) {
|
||||
DESTDIR = outputd
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>315</width>
|
||||
<height>75</height>
|
||||
<height>81</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
@@ -78,14 +78,14 @@
|
||||
<item>
|
||||
<widget class="QLabel" name="sizeLabel">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
<string notr="true">0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>KB</string>
|
||||
<string notr="true">KB</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
+22
-4
@@ -153,7 +153,8 @@ QString DownloadManager::DownloadInfo::currentURL()
|
||||
|
||||
|
||||
DownloadManager::DownloadManager(NexusInterface *nexusInterface, QObject *parent)
|
||||
: IDownloadManager(parent), m_NexusInterface(nexusInterface), m_DirWatcher(), m_ShowHidden(false)
|
||||
: IDownloadManager(parent), m_NexusInterface(nexusInterface), m_DirWatcher(), m_ShowHidden(false),
|
||||
m_DateExpression("/Date\\((\\d+)\\)/")
|
||||
{
|
||||
connect(&m_DirWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(directoryChanged(QString)));
|
||||
}
|
||||
@@ -851,7 +852,6 @@ void DownloadManager::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
|
||||
setState(info, STATE_PAUSED);
|
||||
} else {
|
||||
if (bytesTotal > info->m_TotalSize) {
|
||||
qDebug("file size %s: %lld", qPrintable(info->m_FileName), bytesTotal);
|
||||
info->m_TotalSize = bytesTotal;
|
||||
}
|
||||
int oldProgress = info->m_Progress;
|
||||
@@ -883,6 +883,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("fileTime", info->m_NexusInfo.m_FileTime);
|
||||
metaFile.setValue("fileCategory", info->m_NexusInfo.m_FileCategory);
|
||||
metaFile.setValue("newestVersion", info->m_NexusInfo.m_NewestVersion);
|
||||
metaFile.setValue("category", info->m_NexusInfo.m_Category);
|
||||
@@ -914,11 +915,9 @@ void DownloadManager::nxmDescriptionAvailable(int, QVariant userData, QVariant r
|
||||
|
||||
DownloadInfo *info = downloadInfoByID(userData.toInt());
|
||||
if (info == NULL) return;
|
||||
|
||||
info->m_NexusInfo.m_Category = result["category_id"].toInt();
|
||||
info->m_NexusInfo.m_ModName = result["name"].toString().trimmed();
|
||||
info->m_NexusInfo.m_NewestVersion = result["version"].toString();
|
||||
|
||||
if (info->m_FileID != 0) {
|
||||
setState(info, STATE_READY);
|
||||
} else {
|
||||
@@ -927,6 +926,17 @@ void DownloadManager::nxmDescriptionAvailable(int, QVariant userData, QVariant r
|
||||
}
|
||||
|
||||
|
||||
QDateTime DownloadManager::matchDate(const QString &timeString)
|
||||
{
|
||||
if (m_DateExpression.exactMatch(timeString)) {
|
||||
return QDateTime::fromMSecsSinceEpoch(m_DateExpression.cap(1).toLongLong());
|
||||
} else {
|
||||
qWarning("date not matched: %s", qPrintable(timeString));
|
||||
return QDateTime::currentDateTime();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DownloadManager::nxmFilesAvailable(int, QVariant userData, QVariant resultData, int requestID)
|
||||
{
|
||||
std::set<int>::iterator idIter = m_RequestIDs.find(requestID);
|
||||
@@ -960,7 +970,11 @@ void DownloadManager::nxmFilesAvailable(int, QVariant userData, QVariant resultD
|
||||
(fileNameVariant == info->m_FileName) || (fileNameVariant == alternativeLocalName)) {
|
||||
info->m_NexusInfo.m_Name = fileInfo["name"].toString();
|
||||
info->m_NexusInfo.m_Version = fileInfo["version"].toString();
|
||||
if (info->m_NexusInfo.m_Version.isEmpty()) {
|
||||
info->m_NexusInfo.m_Version = info->m_NexusInfo.m_NewestVersion;
|
||||
}
|
||||
info->m_NexusInfo.m_FileCategory = fileInfo["category_id"].toInt();
|
||||
info->m_NexusInfo.m_FileTime = matchDate(fileInfo["date"].toString());
|
||||
info->m_FileID = fileInfo["id"].toInt();
|
||||
found = true;
|
||||
break;
|
||||
@@ -1014,7 +1028,11 @@ void DownloadManager::nxmFileInfoAvailable(int modID, int fileID, QVariant userD
|
||||
|
||||
info.m_Name = result["name"].toString();
|
||||
info.m_Version = result["version"].toString();
|
||||
if (info.m_Version.isEmpty()) {
|
||||
info.m_Version = info.m_NewestVersion;
|
||||
}
|
||||
info.m_FileName = result["uri"].toString();
|
||||
info.m_FileTime = matchDate(result["date"].toString());
|
||||
|
||||
if (userData.isValid()) {
|
||||
m_RequestIDs.insert(m_NexusInterface->requestDownloadURL(modID, fileID, this, qVariantFromValue(info), userData.toString()));
|
||||
|
||||
@@ -46,6 +46,7 @@ struct NexusInfo {
|
||||
QString m_NewestVersion;
|
||||
QString m_FileName;
|
||||
QVariantList m_DownloadMap;
|
||||
QDateTime m_FileTime;
|
||||
bool m_Set;
|
||||
};
|
||||
Q_DECLARE_METATYPE(NexusInfo)
|
||||
@@ -437,6 +438,8 @@ private:
|
||||
|
||||
DownloadInfo *downloadInfoByID(unsigned int id);
|
||||
|
||||
QDateTime matchDate(const QString &timeString);
|
||||
|
||||
private:
|
||||
|
||||
static const int AUTOMATIC_RETRIES = 3;
|
||||
@@ -458,6 +461,8 @@ private:
|
||||
|
||||
bool m_ShowHidden;
|
||||
|
||||
QRegExp m_DateExpression;
|
||||
|
||||
};
|
||||
|
||||
#endif // DOWNLOADMANAGER_H
|
||||
|
||||
@@ -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),
|
||||
@@ -649,7 +647,7 @@ bool InstallationManager::install(const QString &fileName, GuessedValue<QString>
|
||||
}
|
||||
|
||||
m_CurrentFile = fileInfo.absoluteFilePath();
|
||||
if (fileInfo.dir() == QDir(ToQString(GameInfo::instance().getDownloadDir()))) {
|
||||
if (fileInfo.dir() == QDir(m_DownloadsDirectory)) {
|
||||
m_CurrentFile = fileInfo.fileName();
|
||||
}
|
||||
qDebug("using mod name \"%s\" (id %d) -> %s", modName->toUtf8().constData(), modID, qPrintable(m_CurrentFile));
|
||||
|
||||
@@ -64,6 +64,12 @@ public:
|
||||
*/
|
||||
void setModsDirectory(const QString &modsDirectory) { m_ModsDirectory = modsDirectory; }
|
||||
|
||||
/**
|
||||
* @brief update the directory where downloads are stored
|
||||
* @param downloadDirectory the download directory
|
||||
*/
|
||||
void setDownloadDirectory(const QString &downloadDirectory) { m_DownloadsDirectory = downloadDirectory; }
|
||||
|
||||
/**
|
||||
* @brief install a mod from an archive
|
||||
*
|
||||
@@ -191,6 +197,7 @@ private:
|
||||
QWidget *m_ParentWidget;
|
||||
|
||||
QString m_ModsDirectory;
|
||||
QString m_DownloadsDirectory;
|
||||
|
||||
std::vector<MOBase::IPluginInstaller*> m_Installers;
|
||||
std::set<QString, CaseInsensitive> m_SupportedExtensions;
|
||||
|
||||
+23
-2
@@ -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>
|
||||
@@ -140,7 +139,7 @@ bool bootstrap()
|
||||
QObject::tr("The current user account doesn't have the required access rights to run "
|
||||
"Mod Organizer. The neccessary changes can be made automatically (the MO directory "
|
||||
"will be made writable for the current user account). You will be asked to run "
|
||||
"\"helper.exe\" with administrative rights)."),
|
||||
"\"helper.exe\" with administrative rights."),
|
||||
QMessageBox::Yes | QMessageBox::Cancel) == QMessageBox::Yes) {
|
||||
if (!Helper::init(GameInfo::instance().getOrganizerDirectory())) {
|
||||
return false;
|
||||
@@ -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");
|
||||
@@ -400,6 +400,27 @@ int main(int argc, char *argv[])
|
||||
settings.setValue("gamePath", gamePath.toUtf8().constData());
|
||||
}
|
||||
|
||||
int edition = 0;
|
||||
if (settings.contains("game_edition")) {
|
||||
edition = settings.value("game_edition").toInt();
|
||||
} else {
|
||||
std::vector<std::wstring> editions = GameInfo::instance().getSteamVariants();
|
||||
if (editions.size() < 2) {
|
||||
edition = 0;
|
||||
} else {
|
||||
SelectionDialog selection(QObject::tr("Please select the game edition you have (MO can't start the game correctly if this is set incorrectly!)"), NULL);
|
||||
int index = 0;
|
||||
for (auto iter = editions.begin(); iter != editions.end(); ++iter) {
|
||||
selection.addChoice(ToQString(*iter), "", index++);
|
||||
}
|
||||
if (selection.exec() == QDialog::Rejected) {
|
||||
return -1;
|
||||
} else {
|
||||
settings.setValue("game_edition", selection.getChoiceData().toInt());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qDebug("managing game at %s", qPrintable(QDir::toNativeSeparators(gamePath)));
|
||||
|
||||
ExecutablesList executablesList;
|
||||
|
||||
+218
-63
File diff suppressed because it is too large
Load Diff
+31
-9
@@ -98,7 +98,6 @@ public:
|
||||
void refreshBSAList();
|
||||
void refreshDataTree();
|
||||
void refreshSaveList();
|
||||
void refreshModList();
|
||||
|
||||
void setExecutablesList(const ExecutablesList &executablesList);
|
||||
|
||||
@@ -135,10 +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;
|
||||
@@ -194,7 +197,7 @@ private:
|
||||
void actionToToolButton(QAction *&sourceAction);
|
||||
bool verifyPlugin(MOBase::IPlugin *plugin);
|
||||
void registerPluginTool(MOBase::IPluginTool *tool);
|
||||
bool registerPlugin(QObject *pluginObj);
|
||||
bool registerPlugin(QObject *pluginObj, const QString &fileName);
|
||||
|
||||
void updateToolBar();
|
||||
void activateSelectedProfile();
|
||||
@@ -227,9 +230,23 @@ private:
|
||||
|
||||
void refreshFilters();
|
||||
|
||||
void saveCategoriesFromMenu(QMenu *menu, int modRow);
|
||||
/**
|
||||
* Sets category selections from menu; for multiple mods, this will only apply
|
||||
* the changes made in the menu (which is the delta between the current menu selection and the reference mod)
|
||||
* @param menu the menu after editing by the user
|
||||
* @param modRow index of the mod to edit
|
||||
*/
|
||||
void addRemoveCategoriesFromMenu(QMenu *menu, int modRow);
|
||||
|
||||
bool addCategories(QMenu *menu, int targetID);
|
||||
/**
|
||||
* Sets category selections from menu; for multiple mods, this will completely
|
||||
* replace the current set of categories on each selected with those selected in the menu
|
||||
* @param menu the menu after editing by the user
|
||||
* @param modRow index of the mod to edit
|
||||
*/
|
||||
void replaceCategoriesFromMenu(QMenu *menu, int modRow);
|
||||
|
||||
bool populateMenuCategories(QMenu *menu, int targetID);
|
||||
|
||||
void updateDownloadListDelegate();
|
||||
|
||||
@@ -269,10 +286,12 @@ private:
|
||||
|
||||
static void setupNetworkProxy(bool activate);
|
||||
void activateProxy(bool activate);
|
||||
void installTranslator(const QString &name);
|
||||
|
||||
private:
|
||||
|
||||
static const unsigned int PROBLEM_PLUGINSNOTLOADED = 1;
|
||||
static const unsigned int PROBLEM_TOOMANYPLUGINS = 2;
|
||||
|
||||
private:
|
||||
|
||||
@@ -314,9 +333,6 @@ private:
|
||||
DownloadManager m_DownloadManager;
|
||||
InstallationManager m_InstallationManager;
|
||||
|
||||
QTranslator *m_Translator;
|
||||
QTranslator *m_TranslatorQt;
|
||||
|
||||
SelfUpdater m_Updater;
|
||||
|
||||
CategoryFactory &m_CategoryFactory;
|
||||
@@ -348,6 +364,9 @@ private:
|
||||
|
||||
SignalAboutToRunApplication m_AboutToRun;
|
||||
|
||||
QString m_CurrentLanguage;
|
||||
std::vector<QTranslator*> m_Translators;
|
||||
|
||||
private slots:
|
||||
|
||||
void showMessage(const QString &message);
|
||||
@@ -427,7 +446,9 @@ private slots:
|
||||
|
||||
void originModified(int originID);
|
||||
|
||||
void saveCategories();
|
||||
void addRemoveCategories_MenuHandler();
|
||||
void replaceCategories_MenuHandler();
|
||||
|
||||
void savePrimaryCategory();
|
||||
void addPrimaryCategoryCandidates();
|
||||
|
||||
@@ -510,7 +531,7 @@ private slots: // ui slots
|
||||
void on_actionEndorseMO_triggered();
|
||||
|
||||
void on_bsaList_customContextMenuRequested(const QPoint &pos);
|
||||
void on_bsaList_itemChanged(QTreeWidgetItem *item, int column);
|
||||
void bsaList_itemMoved();
|
||||
void on_btnRefreshData_clicked();
|
||||
void on_categoriesList_customContextMenuRequested(const QPoint &pos);
|
||||
void on_compactBox_toggled(bool checked);
|
||||
@@ -531,6 +552,7 @@ private slots: // ui slots
|
||||
void on_categoriesList_itemSelectionChanged();
|
||||
void on_linkButton_pressed();
|
||||
void on_showHiddenBox_toggled(bool checked);
|
||||
void on_bsaList_itemChanged(QTreeWidgetItem *item, int column);
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
||||
+15
-9
@@ -725,7 +725,7 @@ p, li { white-space: pre-wrap; }
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="bsaList">
|
||||
<widget class="MOBase::SortableTreeWidget" name="bsaList">
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
@@ -742,7 +742,7 @@ BSAs checked here are loaded in such a way that your installation order is obeye
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragEnabled">
|
||||
<bool>false</bool>
|
||||
@@ -751,10 +751,10 @@ BSAs checked here are loaded in such a way that your installation order is obeye
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::NoDragDrop</enum>
|
||||
<enum>QAbstractItemView::DragDrop</enum>
|
||||
</property>
|
||||
<property name="defaultDropAction">
|
||||
<enum>Qt::IgnoreAction</enum>
|
||||
<enum>Qt::MoveAction</enum>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
@@ -768,6 +768,12 @@ BSAs checked here are loaded in such a way that your installation order is obeye
|
||||
<property name="itemsExpandable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="columnCount">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<attribute name="headerVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="headerDefaultSectionSize">
|
||||
<number>200</number>
|
||||
</attribute>
|
||||
@@ -776,11 +782,6 @@ BSAs checked here are loaded in such a way that your installation order is obeye
|
||||
<string>File</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Mod</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
@@ -1224,6 +1225,11 @@ Right now this has very limited functionality</string>
|
||||
<extends>QTreeView</extends>
|
||||
<header>modlistview.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>MOBase::SortableTreeWidget</class>
|
||||
<extends>QTreeWidget</extends>
|
||||
<header>sortabletreewidget.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="resources.qrc"/>
|
||||
|
||||
+21
-10
@@ -19,16 +19,19 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "moapplication.h"
|
||||
#include "report.h"
|
||||
#include "utility.h"
|
||||
#include <utility.h>
|
||||
#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();
|
||||
}
|
||||
|
||||
@@ -43,6 +43,8 @@ private slots:
|
||||
private:
|
||||
|
||||
QFileSystemWatcher m_StyleWatcher;
|
||||
QString m_DefaultStyle;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
+16
-1
@@ -541,6 +541,13 @@ bool ModInfoRegular::setName(const QString &name)
|
||||
void ModInfoRegular::setNotes(const QString ¬es)
|
||||
{
|
||||
m_Notes = notes;
|
||||
m_MetaInfoChanged = true;
|
||||
}
|
||||
|
||||
void ModInfoRegular::setNexusID(int modID)
|
||||
{
|
||||
m_NexusID = modID;
|
||||
m_MetaInfoChanged = true;
|
||||
}
|
||||
|
||||
void ModInfoRegular::setVersion(const VersionInfo &version)
|
||||
@@ -560,7 +567,6 @@ void ModInfoRegular::addNexusCategory(int categoryID)
|
||||
m_Categories.insert(CategoryFactory::instance().resolveNexusID(categoryID));
|
||||
}
|
||||
|
||||
|
||||
void ModInfoRegular::setIsEndorsed(bool endorsed)
|
||||
{
|
||||
if (m_EndorsedState != ENDORSED_NEVER) {
|
||||
@@ -828,6 +834,15 @@ ModInfoOverwrite::ModInfoOverwrite()
|
||||
}
|
||||
|
||||
|
||||
bool ModInfoOverwrite::isEmpty() const
|
||||
{
|
||||
QDirIterator iter(absolutePath(), QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs);
|
||||
if (!iter.hasNext()) return true;
|
||||
iter.next();
|
||||
if ((iter.fileName() == "meta.ini") && !iter.hasNext()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
QString ModInfoOverwrite::absolutePath() const
|
||||
{
|
||||
return QDir::fromNativeSeparators(ToQString(GameInfo::instance().getOverwriteDir()));
|
||||
|
||||
+2
-1
@@ -570,7 +570,7 @@ public:
|
||||
*
|
||||
* @param modID the nexus mod id
|
||||
**/
|
||||
void setNexusID(int modID) { m_NexusID = modID; }
|
||||
void setNexusID(int modID);
|
||||
|
||||
/**
|
||||
* @brief set the version of this mod
|
||||
@@ -866,6 +866,7 @@ public:
|
||||
virtual void setNeverEndorse() {}
|
||||
virtual bool remove() { return false; }
|
||||
virtual void endorse(bool) {}
|
||||
virtual bool isEmpty() const;
|
||||
virtual QString name() const { return "Overwrite"; }
|
||||
virtual QString notes() const { return ""; }
|
||||
virtual QDateTime creationTime() const { return m_StartupTime; }
|
||||
|
||||
+22
-14
@@ -254,17 +254,19 @@ void ModInfoDialog::refreshLists()
|
||||
} else if ((fileName.endsWith(".png", Qt::CaseInsensitive)) ||
|
||||
(fileName.endsWith(".jpg", Qt::CaseInsensitive))) {
|
||||
QImage image = QImage(fileName);
|
||||
if (static_cast<float>(image.width()) / static_cast<float>(image.height()) > 1.34) {
|
||||
image = image.scaledToWidth(128);
|
||||
} else {
|
||||
image = image.scaledToHeight(96);
|
||||
}
|
||||
if (!image.isNull()) {
|
||||
if (static_cast<float>(image.width()) / static_cast<float>(image.height()) > 1.34) {
|
||||
image = image.scaledToWidth(128);
|
||||
} else {
|
||||
image = image.scaledToHeight(96);
|
||||
}
|
||||
|
||||
QPushButton *thumbnailButton = new QPushButton(QPixmap::fromImage(image), "");
|
||||
thumbnailButton->setIconSize(QSize(image.width(), image.height()));
|
||||
connect(thumbnailButton, SIGNAL(clicked()), &m_ThumbnailMapper, SLOT(map()));
|
||||
m_ThumbnailMapper.setMapping(thumbnailButton, fileName);
|
||||
ui->thumbnailArea->addWidget(thumbnailButton);
|
||||
QPushButton *thumbnailButton = new QPushButton(QPixmap::fromImage(image), "");
|
||||
thumbnailButton->setIconSize(QSize(image.width(), image.height()));
|
||||
connect(thumbnailButton, SIGNAL(clicked()), &m_ThumbnailMapper, SLOT(map()));
|
||||
m_ThumbnailMapper.setMapping(thumbnailButton, fileName);
|
||||
ui->thumbnailArea->addWidget(thumbnailButton);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -400,7 +402,13 @@ void ModInfoDialog::openTextFile(const QString &fileName)
|
||||
textFile.open(QIODevice::ReadOnly);
|
||||
QByteArray buffer = textFile.readAll();
|
||||
QTextCodec *codec = QTextCodec::codecForUtfText(buffer, m_UTF8Codec);
|
||||
ui->textFileView->setText(codec->toUnicode(buffer));
|
||||
QString text = codec->toUnicode(buffer);
|
||||
if (codec->fromUnicode(text) != buffer) {
|
||||
qDebug("conversion failed assuming local encoding");
|
||||
codec = QTextCodec::codecForLocale();
|
||||
text = codec->toUnicode(buffer);
|
||||
}
|
||||
ui->textFileView->setText(text);
|
||||
ui->textFileView->setProperty("currentFile", fileName);
|
||||
ui->textFileView->setProperty("encoding", codec->name());
|
||||
ui->saveTXTButton->setEnabled(false);
|
||||
@@ -1169,10 +1177,10 @@ void ModInfoDialog::on_prevButton_clicked()
|
||||
void ModInfoDialog::createTweak()
|
||||
{
|
||||
QString name = QInputDialog::getText(this, tr("Name"), tr("Please enter a name"));
|
||||
if (!fixDirectoryName(name)) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Invalid name. Must be a valid file name"));
|
||||
if (name.isNull()) {
|
||||
return;
|
||||
} else if (name.isEmpty()) {
|
||||
} else if (!fixDirectoryName(name)) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Invalid name. Must be a valid file name"));
|
||||
return;
|
||||
} else if (ui->iniTweaksList->findItems(name, Qt::MatchFixedString).count() != 0) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("A tweak by that name exists"));
|
||||
|
||||
+30
-24
@@ -209,7 +209,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>676</width>
|
||||
<width>668</width>
|
||||
<height>126</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -217,17 +217,22 @@
|
||||
<string>Images located in the mod.</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<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:8.25pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">This lists all the images (.jpg and .png) in the mod directory, like screenshots and such. Click one to get a larger view.</span></p></body></html></string>
|
||||
<string>This lists all the images (.jpg and .png) in the mod directory, like screenshots and such. Click one to get a larger view.</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
@@ -254,14 +259,10 @@ p, li { white-space: pre-wrap; }
|
||||
<string>List of esps and esms that can not be loaded by the game.</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<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:8.25pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">List of esps and esms contained in this plugin that currently can not be loaded by the game. They will not even appear in the esp-list in the main MO-window.</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">They usually contain optional functionality, see the readme.</span></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;"></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Most mods do not have optional esps, so chances are good you are looking at an empty list.</span></p></body></html></string>
|
||||
<string>List of esps and esms contained in this plugin that currently can not be loaded by the game. They will not even appear in the esp-list in the main MO-window.
|
||||
They usually contain optional functionality, see the readme.
|
||||
|
||||
Most mods do not have optional esps, so chances are good you are looking at an empty list.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -403,6 +404,9 @@ p, li { white-space: pre-wrap; }
|
||||
<property name="textElideMode">
|
||||
<enum>Qt::ElideLeft</enum>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="animated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
@@ -413,13 +417,13 @@ p, li { white-space: pre-wrap; }
|
||||
<number>2</number>
|
||||
</property>
|
||||
<attribute name="headerDefaultSectionSize">
|
||||
<number>500</number>
|
||||
<number>365</number>
|
||||
</attribute>
|
||||
<attribute name="headerHighlightSections">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="headerMinimumSectionSize">
|
||||
<number>300</number>
|
||||
<number>200</number>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
@@ -459,14 +463,17 @@ p, li { white-space: pre-wrap; }
|
||||
<property name="textElideMode">
|
||||
<enum>Qt::ElideLeft</enum>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="animated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="headerDefaultSectionSize">
|
||||
<number>500</number>
|
||||
<number>365</number>
|
||||
</attribute>
|
||||
<attribute name="headerMinimumSectionSize">
|
||||
<number>300</number>
|
||||
<number>200</number>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
@@ -524,9 +531,9 @@ p, li { white-space: pre-wrap; }
|
||||
</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>
|
||||
@@ -659,9 +666,8 @@ 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: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>
|
||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:7.8pt; 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;"><br /></p></body></html></string>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::TextBrowserInteraction</set>
|
||||
|
||||
+96
-5
@@ -169,10 +169,16 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const
|
||||
int category = modInfo->getPrimaryCategory();
|
||||
if (category != -1) {
|
||||
CategoryFactory &categoryFactory = CategoryFactory::instance();
|
||||
try {
|
||||
return categoryFactory.getCategoryName(categoryFactory.getCategoryIndex(category));
|
||||
} catch (const std::exception &e) {
|
||||
qCritical("failed to retrieve category name: %s", e.what());
|
||||
if (categoryFactory.categoryExists(category)) {
|
||||
try {
|
||||
return categoryFactory.getCategoryName(categoryFactory.getCategoryIndex(category));
|
||||
} catch (const std::exception &e) {
|
||||
qCritical("failed to retrieve category name: %s", e.what());
|
||||
return QString();
|
||||
}
|
||||
} else {
|
||||
qWarning("category %d doesn't exist (may have been removed)", category);
|
||||
modInfo->setCategory(category, false);
|
||||
return QString();
|
||||
}
|
||||
} else {
|
||||
@@ -180,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");
|
||||
}
|
||||
@@ -545,6 +556,86 @@ void ModList::changeModPriority(int sourceIndex, int newPriority)
|
||||
emit modorder_changed();
|
||||
}
|
||||
|
||||
void ModList::modInfoAboutToChange(ModInfo::Ptr info)
|
||||
{
|
||||
m_ChangeInfo.name = info->name();
|
||||
m_ChangeInfo.state = state(info->name());
|
||||
}
|
||||
|
||||
void ModList::modInfoChanged(ModInfo::Ptr info)
|
||||
{
|
||||
if (info->name() == m_ChangeInfo.name) {
|
||||
IModList::ModStates newState = state(info->name());
|
||||
if (m_ChangeInfo.state != newState) {
|
||||
m_ModStateChanged(info->name(), newState);
|
||||
}
|
||||
int row = ModInfo::getIndex(info->name());
|
||||
info->testValid();
|
||||
emit dataChanged(index(row, 0), index(row, columnCount()));
|
||||
} else {
|
||||
qCritical("modInfoChanged not called after modInfoAboutToChange");
|
||||
}
|
||||
}
|
||||
|
||||
IModList::ModStates ModList::state(const QString &name) const
|
||||
{
|
||||
ModStates result;
|
||||
unsigned int modIndex = ModInfo::getIndex(name);
|
||||
if (modIndex != UINT_MAX) {
|
||||
result |= IModList::STATE_EXISTS;
|
||||
ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex);
|
||||
if (modInfo->isEmpty()) {
|
||||
result |= IModList::STATE_EMPTY;
|
||||
}
|
||||
if (modInfo->endorsedState() == ModInfo::ENDORSED_TRUE) {
|
||||
result |= IModList::STATE_ENDORSED;
|
||||
}
|
||||
if (modInfo->isValid()) {
|
||||
result |= IModList::STATE_VALID;
|
||||
}
|
||||
if (modInfo->canBeEnabled()) {
|
||||
if (m_Profile->modEnabled(modIndex)) {
|
||||
result |= IModList::STATE_ACTIVE;
|
||||
}
|
||||
} else {
|
||||
result |= IModList::STATE_ESSENTIAL;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int ModList::priority(const QString &name) const
|
||||
{
|
||||
unsigned int modIndex = ModInfo::getIndex(name);
|
||||
if (modIndex == UINT_MAX) {
|
||||
return -1;
|
||||
} else {
|
||||
return m_Profile->getModPriority(modIndex);
|
||||
}
|
||||
}
|
||||
|
||||
bool ModList::setPriority(const QString &name, int newPriority)
|
||||
{
|
||||
if ((newPriority < 0) || (newPriority >= static_cast<int>(m_Profile->numRegularMods()))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int modIndex = ModInfo::getIndex(name);
|
||||
if (modIndex == UINT_MAX) {
|
||||
return false;
|
||||
} else {
|
||||
m_Profile->setModPriority(modIndex, newPriority);
|
||||
notifyChange(modIndex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ModList::onModStateChanged(const std::function<void (const QString &, IModList::ModStates)> &func)
|
||||
{
|
||||
auto conn = m_ModStateChanged.connect(func);
|
||||
return conn.connected();
|
||||
}
|
||||
|
||||
bool ModList::dropURLs(const QMimeData *mimeData, int row, const QModelIndex &parent)
|
||||
{
|
||||
|
||||
+36
-2
@@ -26,11 +26,13 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "modinfo.h"
|
||||
#include "profile.h"
|
||||
|
||||
#include <imodlist.h>
|
||||
|
||||
#include <QFile>
|
||||
#include <QListWidget>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkAccessManager>
|
||||
|
||||
#include <boost/signals2.hpp>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <QVector>
|
||||
@@ -41,7 +43,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
* This is used in a view in the main window of MO. It combines general information about
|
||||
* the mods from ModInfo with status information from the Profile
|
||||
**/
|
||||
class ModList : public QAbstractItemModel
|
||||
class ModList : public QAbstractItemModel, public MOBase::IModList
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -59,6 +61,8 @@ public:
|
||||
COL_LASTCOLUMN = COL_PRIORITY
|
||||
};
|
||||
|
||||
typedef boost::signals2::signal<void (const QString &, ModStates)> SignalModStateChanged;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
@@ -92,6 +96,23 @@ public:
|
||||
|
||||
void changeModPriority(int sourceIndex, int newPriority);
|
||||
|
||||
void modInfoAboutToChange(ModInfo::Ptr info);
|
||||
void modInfoChanged(ModInfo::Ptr info);
|
||||
|
||||
public:
|
||||
|
||||
/// \copydoc MOBase::IModList::state
|
||||
virtual ModStates state(const QString &name) const;
|
||||
|
||||
/// \copydoc MOBase::IModList::priority
|
||||
virtual int priority(const QString &name) const;
|
||||
|
||||
/// \copydoc MOBase::IModList::setPriority
|
||||
virtual bool setPriority(const QString &name, int newPriority);
|
||||
|
||||
/// \copydoc MOBase::IModList::onModStateChanged
|
||||
virtual bool onModStateChanged(const std::function<void (const QString &, ModStates)> &func);
|
||||
|
||||
public: // implementation of virtual functions of QAbstractItemModel
|
||||
|
||||
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
@@ -232,6 +253,11 @@ private:
|
||||
unsigned int categoryOrder;
|
||||
};
|
||||
|
||||
struct TModInfoChange {
|
||||
QString name;
|
||||
QFlags<IModList::ModStates> state;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
Profile *m_Profile;
|
||||
@@ -245,6 +271,14 @@ private:
|
||||
|
||||
bool m_DropOnItems;
|
||||
|
||||
TModInfoChange m_ChangeInfo;
|
||||
|
||||
SignalModStateChanged m_ModStateChanged;
|
||||
|
||||
|
||||
// QAbstractItemModel interface
|
||||
|
||||
// IModList interface
|
||||
};
|
||||
|
||||
#endif // MODLIST_H
|
||||
|
||||
@@ -220,7 +220,7 @@ bool ModListSortProxy::hasConflictFlag(const std::vector<ModInfo::EFlag> &flags)
|
||||
}
|
||||
|
||||
|
||||
bool ModListSortProxy::filterMatches(ModInfo::Ptr info, bool enabled) const
|
||||
bool ModListSortProxy::filterMatchesMod(ModInfo::Ptr info, bool enabled) const
|
||||
{
|
||||
if (!m_CurrentFilter.isEmpty() &&
|
||||
!info->name().contains(m_CurrentFilter, Qt::CaseInsensitive)) {
|
||||
@@ -258,7 +258,7 @@ bool ModListSortProxy::filterMatches(ModInfo::Ptr info, bool enabled) const
|
||||
}
|
||||
|
||||
|
||||
bool ModListSortProxy::filterAcceptsRow(int row, const QModelIndex&) const
|
||||
bool ModListSortProxy::filterAcceptsRow(int row, const QModelIndex &parent) const
|
||||
{
|
||||
if (m_Profile == NULL) {
|
||||
return false;
|
||||
@@ -268,9 +268,25 @@ bool ModListSortProxy::filterAcceptsRow(int row, const QModelIndex&) const
|
||||
qWarning("invalid row idx %d", row);
|
||||
return false;
|
||||
}
|
||||
bool modEnabled = m_Profile->modEnabled(row);
|
||||
|
||||
return filterMatches(ModInfo::getByIndex(row), modEnabled);
|
||||
QModelIndex idx = sourceModel()->index(row, 0, parent);
|
||||
if (!idx.isValid()) {
|
||||
qDebug("invalid index");
|
||||
return false;
|
||||
}
|
||||
if (idx.isValid() && sourceModel()->hasChildren(idx)) {
|
||||
for (int i = 0; i < sourceModel()->rowCount(idx); ++i) {
|
||||
if (filterAcceptsRow(i, idx)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} else {
|
||||
bool modEnabled = idx.sibling(row, 0).data(Qt::CheckStateRole).toInt() == Qt::Checked;
|
||||
unsigned int index = idx.data(Qt::UserRole + 1).toInt();
|
||||
return filterMatchesMod(ModInfo::getByIndex(index), modEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user