mirror of
https://github.com/ModOrganizer2/modorganizer.git
synced 2026-07-27 13:58:24 -07:00
Compare commits
42
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa21a192cb | ||
|
|
d4d7ce1fd3 | ||
|
|
e31baf3ee6 | ||
|
|
5dcfca7c9d | ||
|
|
e9ee7e7f85 | ||
|
|
67d017fc98 | ||
|
|
a700e6a3ef | ||
|
|
c95de1b3aa | ||
|
|
351fc9ca9c | ||
|
|
53f0a2bc79 | ||
|
|
793dfb1637 | ||
|
|
d25a81071c | ||
|
|
ef9a61886c | ||
|
|
13a40b43c8 | ||
|
|
d7790cd717 | ||
|
|
84d632af6a | ||
|
|
b14b35349d | ||
|
|
83a4db2362 | ||
|
|
c797af8b76 | ||
|
|
ebf6ff3f76 | ||
|
|
02b5e73c2d | ||
|
|
b0b2f1d3a9 | ||
|
|
d8e406daa0 | ||
|
|
50dcc4c1d4 | ||
|
|
e21db0eaea | ||
|
|
859332e18d | ||
|
|
1fd8f44960 | ||
|
|
e0c655330d | ||
|
|
a0999cd42b | ||
|
|
eb47d4d0bb | ||
|
|
59476e38ec | ||
|
|
c5d36af06d | ||
|
|
8d1931bc6b | ||
|
|
c05be9f5c3 | ||
|
|
75714907d9 | ||
|
|
02471a3da1 | ||
|
|
afab0cec7e | ||
|
|
02cc97a58d | ||
|
|
ffd94e72b4 | ||
|
|
6435e1ab8a | ||
|
|
dbfa9b89d1 | ||
|
|
fe5c4255c8 |
+20
-4
@@ -83,7 +83,7 @@
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string notr="true">Copyright 2011-2014 Sebastian Herbord</string>
|
||||
<string notr="true">Copyright 2011-2015 Sebastian Herbord</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -180,7 +180,18 @@
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Ren (Korean)</string>
|
||||
<string notr="true">Ren (Korean)</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>... more (Can't track)</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
@@ -221,12 +232,12 @@
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>GamerPoet</string>
|
||||
<string notr="true">GamerPoet</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Gopher</string>
|
||||
<string notr="true">Gopher</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
@@ -249,6 +260,11 @@
|
||||
<string notr="true">z929669</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">thosrtanner</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
+27
-5
@@ -166,22 +166,32 @@ void CategoryFactory::saveCategories()
|
||||
unsigned int CategoryFactory::countCategories(std::tr1::function<bool (const Category &category)> filter)
|
||||
{
|
||||
unsigned int result = 0;
|
||||
for (auto iter = m_Categories.begin(); iter != m_Categories.end(); ++iter) {
|
||||
if (filter(*iter)) {
|
||||
for (const Category &cat : m_Categories) {
|
||||
if (filter(cat)) {
|
||||
++result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int CategoryFactory::addCategory(const QString &name, const std::vector<int> &nexusIDs, int parentID)
|
||||
{
|
||||
int id = 1;
|
||||
while (m_IDMap.find(id) != m_IDMap.end()) {
|
||||
++id;
|
||||
}
|
||||
addCategory(id, name, nexusIDs, parentID);
|
||||
|
||||
saveCategories();
|
||||
return id;
|
||||
}
|
||||
|
||||
void CategoryFactory::addCategory(int id, const QString &name, const std::vector<int> &nexusIDs, int parentID)
|
||||
{
|
||||
int index = m_Categories.size();
|
||||
m_Categories.push_back(Category(index, id, name, nexusIDs, parentID));
|
||||
for (std::vector<int>::const_iterator iter = nexusIDs.begin();
|
||||
iter != nexusIDs.end(); ++iter) {
|
||||
m_NexusMap[*iter] = index;
|
||||
for (int nexusID : nexusIDs) {
|
||||
m_NexusMap[nexusID] = index;
|
||||
}
|
||||
m_IDMap[id] = index;
|
||||
}
|
||||
@@ -305,6 +315,18 @@ int CategoryFactory::getCategoryIndex(int ID) const
|
||||
}
|
||||
|
||||
|
||||
int CategoryFactory::getCategoryID(const QString &name) const
|
||||
{
|
||||
auto iter = std::find_if(m_Categories.begin(), m_Categories.end(), [name] (const Category &cat) -> bool {
|
||||
return cat.m_Name == name;
|
||||
});
|
||||
if (iter != m_Categories.end()) {
|
||||
return iter->m_ID;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned int CategoryFactory::resolveNexusID(int nexusID) const
|
||||
{
|
||||
|
||||
@@ -80,6 +80,8 @@ public:
|
||||
**/
|
||||
void saveCategories();
|
||||
|
||||
int addCategory(const QString &name, const std::vector<int> &nexusIDs, int parentID);
|
||||
|
||||
/**
|
||||
* @brief retrieve the number of available categories
|
||||
*
|
||||
@@ -142,6 +144,12 @@ public:
|
||||
**/
|
||||
int getCategoryID(unsigned int index) const;
|
||||
|
||||
/**
|
||||
* @brief look up the id of a category by its name
|
||||
* @note O(n)
|
||||
*/
|
||||
int getCategoryID(const QString &name) const;
|
||||
|
||||
/**
|
||||
* @brief look up the index of a category by its id
|
||||
*
|
||||
|
||||
@@ -100,16 +100,19 @@ void DirectoryRefresher::addModFilesToStructure(DirectoryEntry *directoryStructu
|
||||
if (stealFiles.length() > 0) {
|
||||
// instead of adding all the files of the target directory, we just change the root of the specified
|
||||
// files to this mod
|
||||
FilesOrigin origin = directoryStructure->createOrigin(ToWString(modName), directoryW, priority);
|
||||
foreach (const QString &filename, stealFiles) {
|
||||
FilesOrigin &origin = directoryStructure->createOrigin(ToWString(modName), directoryW, priority);
|
||||
for (const QString &filename : stealFiles) {
|
||||
QFileInfo fileInfo(filename);
|
||||
FileEntry::Ptr file = directoryStructure->findFile(ToWString(fileInfo.fileName()));
|
||||
if (file.get() != nullptr) {
|
||||
if (file->getOrigin() == 0) {
|
||||
// replace data as the origin on this bsa
|
||||
file->removeOrigin(0);
|
||||
file->addOrigin(origin.getID(), file->getFileTime(), L"");
|
||||
}
|
||||
origin.addFile(file->getIndex());
|
||||
file->addOrigin(origin.getID(), file->getFileTime(), L"");
|
||||
} else {
|
||||
qWarning("%s not found", qPrintable(fileInfo.fileName()));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -20,6 +20,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "downloadlistsortproxy.h"
|
||||
#include "downloadlist.h"
|
||||
#include "downloadmanager.h"
|
||||
#include "settings.h"
|
||||
|
||||
DownloadListSortProxy::DownloadListSortProxy(const DownloadManager *manager, QObject *parent)
|
||||
: QSortFilterProxyModel(parent), m_Manager(manager), m_CurrentFilter()
|
||||
@@ -55,12 +56,17 @@ bool DownloadListSortProxy::lessThan(const QModelIndex &left,
|
||||
}
|
||||
|
||||
|
||||
bool DownloadListSortProxy::filterAcceptsRow(int source_row, const QModelIndex&) const
|
||||
bool DownloadListSortProxy::filterAcceptsRow(int sourceRow, const QModelIndex&) const
|
||||
{
|
||||
if (m_CurrentFilter.length() == 0) {
|
||||
return true;
|
||||
} else if (source_row < m_Manager->numTotalDownloads()) {
|
||||
return sourceModel()->index(source_row, 0).data().toString().contains(m_CurrentFilter, Qt::CaseInsensitive);
|
||||
} else if (sourceRow < m_Manager->numTotalDownloads()) {
|
||||
int downloadIndex = sourceModel()->index(sourceRow, 0).data().toInt();
|
||||
|
||||
QString displayedName = Settings::instance().metaDownloads()
|
||||
? m_Manager->getDisplayName(downloadIndex)
|
||||
: m_Manager->getFileName(downloadIndex);
|
||||
return displayedName.contains(m_CurrentFilter, Qt::CaseInsensitive);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public slots:
|
||||
protected:
|
||||
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
|
||||
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &source_parent) const;
|
||||
|
||||
signals:
|
||||
|
||||
|
||||
@@ -53,7 +53,8 @@ DownloadListWidgetCompactDelegate::DownloadListWidgetCompactDelegate(DownloadMan
|
||||
|
||||
m_DoneLabel->setVisible(false);
|
||||
|
||||
connect(manager, SIGNAL(stateChanged(int,DownloadManager::DownloadState)), this, SLOT(stateChanged(int,DownloadManager::DownloadState)));
|
||||
connect(manager, SIGNAL(stateChanged(int,DownloadManager::DownloadState)),
|
||||
this, SLOT(stateChanged(int,DownloadManager::DownloadState)));
|
||||
connect(manager, SIGNAL(downloadRemoved(int)), this, SLOT(resetCache(int)));
|
||||
}
|
||||
|
||||
@@ -116,24 +117,20 @@ void DownloadListWidgetCompactDelegate::paintRegularDownload(int downloadIndex)
|
||||
if ((state == DownloadManager::STATE_PAUSED) || (state == DownloadManager::STATE_ERROR)) {
|
||||
m_DoneLabel->setVisible(true);
|
||||
m_Progress->setVisible(false);
|
||||
m_DoneLabel->setText(tr("Paused"));
|
||||
m_DoneLabel->setForegroundRole(QPalette::Link);
|
||||
m_DoneLabel->setText(QString("%1<img src=\":/MO/gui/inactive\">").arg(tr("Paused")));
|
||||
} else if (state == DownloadManager::STATE_FETCHINGMODINFO) {
|
||||
m_DoneLabel->setText(tr("Fetching Info 1"));
|
||||
m_DoneLabel->setText(QString("%1").arg(tr("Fetching Info 1")));
|
||||
} else if (state == DownloadManager::STATE_FETCHINGFILEINFO) {
|
||||
m_DoneLabel->setText(tr("Fetching Info 2"));
|
||||
m_DoneLabel->setText(QString("%1").arg(tr("Fetching Info 2")));
|
||||
} else if (state >= DownloadManager::STATE_READY) {
|
||||
m_DoneLabel->setVisible(true);
|
||||
m_Progress->setVisible(false);
|
||||
if (state == DownloadManager::STATE_INSTALLED) {
|
||||
m_DoneLabel->setText(tr("Installed"));
|
||||
m_DoneLabel->setForegroundRole(QPalette::Mid);
|
||||
m_DoneLabel->setText(QString("%1<img src=\":/MO/gui/check\">").arg(tr("Installed")));
|
||||
} else if (state == DownloadManager::STATE_UNINSTALLED) {
|
||||
m_DoneLabel->setText(tr("Uninstalled"));
|
||||
m_DoneLabel->setForegroundRole(QPalette::Dark);
|
||||
m_DoneLabel->setText(QString("%1<img src=\":/MO/gui/awaiting\">").arg(tr("Uninstalled")));
|
||||
} else {
|
||||
m_DoneLabel->setText(tr("Done"));
|
||||
m_DoneLabel->setForegroundRole(QPalette::WindowText);
|
||||
m_DoneLabel->setText(QString("%1<img src=\":/MO/gui/active\">").arg(tr("Done")));
|
||||
}
|
||||
if (m_Manager->isInfoIncomplete(downloadIndex)) {
|
||||
m_NameLabel->setText("<img src=\":/MO/gui/warning_16\"/> " + m_NameLabel->text());
|
||||
|
||||
@@ -1354,7 +1354,9 @@ void DownloadManager::downloadFinished()
|
||||
if (info->m_State == STATE_CANCELING) {
|
||||
setState(info, STATE_CANCELED);
|
||||
} else if (info->m_State == STATE_PAUSING) {
|
||||
info->m_Output.write(info->m_Reply->readAll());
|
||||
if (info->m_Output.isOpen()) {
|
||||
info->m_Output.write(info->m_Reply->readAll());
|
||||
}
|
||||
|
||||
if (error) {
|
||||
setState(info, STATE_ERROR);
|
||||
@@ -1426,7 +1428,10 @@ void DownloadManager::downloadFinished()
|
||||
void DownloadManager::downloadError(QNetworkReply::NetworkError error)
|
||||
{
|
||||
if (error != QNetworkReply::OperationCanceledError) {
|
||||
qWarning("Download error occured: %d", error);
|
||||
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
|
||||
qWarning("%s (%d)", reply != nullptr ? qPrintable(reply->errorString())
|
||||
: "Download error occured",
|
||||
error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ private:
|
||||
|
||||
quint32 m_TaskProgressId;
|
||||
|
||||
MOBase::ModRepositoryFileInfo *m_FileInfo;
|
||||
MOBase::ModRepositoryFileInfo *m_FileInfo { nullptr };
|
||||
|
||||
bool m_Hidden;
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<enum>QAbstractItemView::InternalMove</enum>
|
||||
</property>
|
||||
<property name="defaultDropAction">
|
||||
<enum>Qt::MoveAction</enum>
|
||||
<enum>Qt::TargetMoveAction</enum>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
|
||||
@@ -114,22 +114,28 @@ void InstallationManager::queryPassword(LPSTR password)
|
||||
void InstallationManager::mapToArchive(const DirectoryTree::Node *node, std::wstring path, FileData * const *data)
|
||||
{
|
||||
if (path.length() > 0) {
|
||||
path.append(L"\\");
|
||||
// when using a long windows path (starting with \\?\) we apparently can have redundant
|
||||
// . components in the path. This wasn't a problem with "regular" path names.
|
||||
if (path == L".") {
|
||||
path.clear();
|
||||
} else {
|
||||
path.append(L"\\");
|
||||
}
|
||||
}
|
||||
|
||||
for (DirectoryTree::const_leaf_iterator iter = node->leafsBegin(); iter != node->leafsEnd(); ++iter) {
|
||||
data[iter->getIndex()]->setSkip(false);
|
||||
std::wstring temp = path.substr().append(ToWString(iter->getName()));
|
||||
std::wstring temp = path + iter->getName().toStdWString();
|
||||
data[iter->getIndex()]->setOutputFileName(temp.c_str());
|
||||
}
|
||||
|
||||
for (DirectoryTree::const_node_iterator iter = node->nodesBegin(); iter != node->nodesEnd(); ++iter) {
|
||||
if ((*iter)->getData().index != -1) {
|
||||
data[(*iter)->getData().index]->setSkip(false);
|
||||
std::wstring temp = path.substr().append(ToWString((*iter)->getData().name));
|
||||
std::wstring temp = path + (*iter)->getData().name.toStdWString();
|
||||
data[(*iter)->getData().index]->setOutputFileName(temp.c_str());
|
||||
}
|
||||
mapToArchive(*iter, path.substr().append(ToWString((*iter)->getData().name)), data);
|
||||
mapToArchive(*iter, path + (*iter)->getData().name.toStdWString(), data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -535,8 +541,8 @@ bool InstallationManager::doInstall(GuessedValue<QString> &modName, int modID,
|
||||
return false;
|
||||
}
|
||||
|
||||
QString targetDirectoryNative = m_ModsDirectory + "\\" + modName;
|
||||
QString targetDirectory = QDir::fromNativeSeparators(targetDirectoryNative);
|
||||
QString targetDirectory = QDir(m_ModsDirectory + "/" + modName).canonicalPath();
|
||||
QString targetDirectoryNative = QDir::toNativeSeparators(targetDirectory);
|
||||
|
||||
qDebug("installing to \"%s\"", targetDirectoryNative.toUtf8().constData());
|
||||
|
||||
@@ -545,7 +551,7 @@ 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(),
|
||||
if (!m_CurrentArchive->extract(ToWString("\\\\?\\" + targetDirectoryNative).c_str(),
|
||||
new MethodCallback<InstallationManager, void, float>(this, &InstallationManager::updateProgress),
|
||||
new MethodCallback<InstallationManager, void, LPCWSTR>(this, &InstallationManager::updateProgressFile),
|
||||
new MethodCallback<InstallationManager, void, LPCWSTR>(this, &InstallationManager::report7ZipError))) {
|
||||
@@ -629,7 +635,7 @@ bool InstallationManager::install(const QString &fileName, GuessedValue<QString>
|
||||
{
|
||||
QFileInfo fileInfo(fileName);
|
||||
if (m_SupportedExtensions.find(fileInfo.suffix()) == m_SupportedExtensions.end()) {
|
||||
reportError(tr("File format \"%1\" not supported").arg(fileInfo.completeSuffix()));
|
||||
reportError(tr("File format \"%1\" not supported").arg(fileInfo.suffix()));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -129,7 +129,7 @@ char LogBuffer::msgTypeID(QtMsgType type)
|
||||
void LogBuffer::log(QtMsgType type, const QMessageLogContext &context, const QString &message)
|
||||
{
|
||||
// QMutexLocker doesn't support timeout...
|
||||
if (!s_Mutex.tryLock(50)) {
|
||||
if (!s_Mutex.tryLock(100)) {
|
||||
fprintf(stderr, "failed to log: %s", qPrintable(message));
|
||||
return;
|
||||
}
|
||||
|
||||
+28
-19
@@ -170,6 +170,8 @@ void cleanupDir()
|
||||
"proxy.dll"
|
||||
};
|
||||
|
||||
qDebug("removing obsolete files");
|
||||
|
||||
for (const QString &fileName : fileNames) {
|
||||
QString fullPath = qApp->applicationDirPath() + "/" + fileName;
|
||||
if (QFile::exists(fullPath)
|
||||
@@ -367,23 +369,29 @@ int main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!bootstrap()) { // requires gameinfo to be initialised!
|
||||
return -1;
|
||||
}
|
||||
|
||||
LogBuffer::init(100, QtDebugMsg, qApp->property("dataPath").toString() + "/logs/mo_interface.log");
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
qDebug("ssl support: %d", QSslSocket::supportsSsl());
|
||||
#endif
|
||||
|
||||
qDebug("Working directory: %s", qPrintable(QDir::toNativeSeparators(QDir::currentPath())));
|
||||
qDebug("MO at: %s", qPrintable(QDir::toNativeSeparators(application.applicationDirPath())));
|
||||
QPixmap pixmap(":/MO/gui/splash");
|
||||
QSplashScreen splash(pixmap);
|
||||
splash.show();
|
||||
|
||||
cleanupDir();
|
||||
try {
|
||||
if (!bootstrap()) { // requires gameinfo to be initialised!
|
||||
return -1;
|
||||
}
|
||||
|
||||
LogBuffer::init(100, QtDebugMsg, qApp->property("dataPath").toString() + "/logs/mo_interface.log");
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
qDebug("ssl support: %d", QSslSocket::supportsSsl());
|
||||
#endif
|
||||
|
||||
qDebug("Working directory: %s", qPrintable(QDir::toNativeSeparators(QDir::currentPath())));
|
||||
qDebug("MO at: %s", qPrintable(QDir::toNativeSeparators(application.applicationDirPath())));
|
||||
splash.show();
|
||||
|
||||
cleanupDir();
|
||||
} catch (const std::exception &e) {
|
||||
reportError(e.what());
|
||||
return 1;
|
||||
}
|
||||
|
||||
{ // extend path to include dll directory so plugins don't need a manifest
|
||||
// (using AddDllDirectory would be an alternative to this but it seems fairly complicated esp.
|
||||
@@ -430,9 +438,9 @@ int main(int argc, char *argv[])
|
||||
} // we continue for the primary instance OR if MO has been called with parameters
|
||||
|
||||
QSettings settings(dataPath + "/" + QString::fromStdWString(AppConfig::iniFileName()), QSettings::IniFormat);
|
||||
|
||||
qDebug("initializing core");
|
||||
OrganizerCore organizer(settings);
|
||||
|
||||
qDebug("initialize plugins");
|
||||
PluginContainer pluginContainer(&organizer);
|
||||
pluginContainer.loadPlugins();
|
||||
|
||||
@@ -516,7 +524,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
// if we have a command line parameter, it is either a nxm link or
|
||||
// a binary to start
|
||||
if ((arguments.size() > 1) && (!isNxmLink(arguments.at(1)))) {
|
||||
if ((arguments.size() > 1)
|
||||
&& !isNxmLink(arguments.at(1))) {
|
||||
QString exeName = arguments.at(1);
|
||||
qDebug("starting %s from command line", qPrintable(exeName));
|
||||
arguments.removeFirst(); // remove application name (ModOrganizer.exe)
|
||||
@@ -553,8 +562,8 @@ int main(int argc, char *argv[])
|
||||
qDebug("displaying main window");
|
||||
mainWindow.show();
|
||||
|
||||
if ((arguments.size() > 1) &&
|
||||
(isNxmLink(arguments.at(1)))) {
|
||||
if ((arguments.size() > 1)
|
||||
&& isNxmLink(arguments.at(1))) {
|
||||
qDebug("starting download from command line: %s", qPrintable(arguments.at(1)));
|
||||
organizer.externalMessage(arguments.at(1));
|
||||
}
|
||||
|
||||
+49
-39
@@ -187,8 +187,6 @@ MainWindow::MainWindow(const QString &exeName
|
||||
|
||||
ui->actionEndorseMO->setVisible(false);
|
||||
|
||||
MOBase::QuestionBoxMemory::init(initSettings.fileName());
|
||||
|
||||
updateProblemsButton();
|
||||
|
||||
updateToolBar();
|
||||
@@ -1301,6 +1299,7 @@ static QStringList toStringList(InputIterator current, InputIterator end)
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void MainWindow::updateBSAList(const QStringList &defaultArchives, const QStringList &activeArchives)
|
||||
{
|
||||
m_DefaultArchives = defaultArchives;
|
||||
@@ -1311,33 +1310,31 @@ void MainWindow::updateBSAList(const QStringList &defaultArchives, const QString
|
||||
ui->bsaList->header()->setResizeMode(QHeaderView::ResizeToContents);
|
||||
#endif
|
||||
|
||||
std::vector<std::pair<UINT32, QTreeWidgetItem*> > items;
|
||||
std::vector<std::pair<UINT32, QTreeWidgetItem*>> items;
|
||||
|
||||
std::vector<FileEntry::Ptr> files = m_OrganizerCore.directoryStructure()->getFiles();
|
||||
for (auto iter = files.begin(); iter != files.end(); ++iter) {
|
||||
FileEntry::Ptr current = *iter;
|
||||
for (FileEntry::Ptr current : m_OrganizerCore.directoryStructure()->getFiles()) {
|
||||
QFileInfo fileInfo(ToQString(current->getName().c_str()));
|
||||
|
||||
QString filename = ToQString(current->getName().c_str());
|
||||
QString extension = filename.right(3).toLower();
|
||||
|
||||
if (extension == "bsa") {
|
||||
int index = activeArchives.indexOf(filename);
|
||||
if (fileInfo.suffix().toLower() == "bsa") {
|
||||
int index = activeArchives.indexOf(fileInfo.fileName());
|
||||
if (index == -1) {
|
||||
index = 0xFFFF;
|
||||
}
|
||||
QString basename = filename.left(filename.indexOf("."));
|
||||
QStringList strings(filename);
|
||||
bool isArchive = false;
|
||||
int origin = current->getOrigin(isArchive);
|
||||
strings.append(ToQString(m_OrganizerCore.directoryStructure()->getOriginByID(origin).getName()));
|
||||
QTreeWidgetItem *newItem = new QTreeWidgetItem(strings);
|
||||
|
||||
QString basename = fileInfo.baseName();
|
||||
int originId = current->getOrigin();
|
||||
FilesOrigin &origin = m_OrganizerCore.directoryStructure()->getOriginByID(originId);
|
||||
|
||||
QTreeWidgetItem *newItem = new QTreeWidgetItem(QStringList()
|
||||
<< fileInfo.fileName()
|
||||
<< ToQString(origin.getName()));
|
||||
newItem->setData(0, Qt::UserRole, index);
|
||||
newItem->setData(1, Qt::UserRole, origin);
|
||||
newItem->setData(1, Qt::UserRole, originId);
|
||||
newItem->setFlags(newItem->flags() & ~Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable);
|
||||
newItem->setCheckState(0, (index != -1) ? Qt::Checked : Qt::Unchecked);
|
||||
newItem->setData(0, Qt::UserRole, false);
|
||||
if (m_OrganizerCore.settings().forceEnableCoreFiles()
|
||||
&& defaultArchives.contains(filename)) {
|
||||
&& defaultArchives.contains(fileInfo.fileName())) {
|
||||
newItem->setCheckState(0, Qt::Checked);
|
||||
newItem->setDisabled(true);
|
||||
newItem->setData(0, Qt::UserRole, true);
|
||||
@@ -1356,7 +1353,7 @@ void MainWindow::updateBSAList(const QStringList &defaultArchives, const QString
|
||||
|
||||
if (index < 0) index = 0;
|
||||
|
||||
UINT32 sortValue = ((m_OrganizerCore.directoryStructure()->getOriginByID(origin).getPriority() & 0xFFFF) << 16) | (index & 0xFFFF);
|
||||
UINT32 sortValue = ((origin.getPriority() & 0xFFFF) << 16) | (index & 0xFFFF);
|
||||
items.push_back(std::make_pair(sortValue, newItem));
|
||||
}
|
||||
}
|
||||
@@ -2061,7 +2058,7 @@ void MainWindow::refreshFilters()
|
||||
ui->modList->setCurrentIndex(QModelIndex());
|
||||
|
||||
QStringList selectedItems;
|
||||
foreach (QTreeWidgetItem *item, ui->categoriesList->selectedItems()) {
|
||||
for (QTreeWidgetItem *item : ui->categoriesList->selectedItems()) {
|
||||
selectedItems.append(item->text(0));
|
||||
}
|
||||
|
||||
@@ -2091,7 +2088,7 @@ void MainWindow::refreshFilters()
|
||||
|
||||
addCategoryFilters(nullptr, categoriesUsed, 0);
|
||||
|
||||
foreach (const QString &item, selectedItems) {
|
||||
for (const QString &item : selectedItems) {
|
||||
QList<QTreeWidgetItem*> matches = ui->categoriesList->findItems(item, Qt::MatchFixedString | Qt::MatchRecursive);
|
||||
if (matches.size() > 0) {
|
||||
matches.at(0)->setSelected(true);
|
||||
@@ -2246,8 +2243,9 @@ void MainWindow::resumeDownload(int downloadIndex)
|
||||
} else {
|
||||
QString username, password;
|
||||
if (m_OrganizerCore.settings().getNexusLogin(username, password)) {
|
||||
//m_PostLoginTasks.push_back(boost::bind(&MainWindow::resumeDownload, _1, downloadIndex));
|
||||
m_OrganizerCore.doAfterLogin([this, downloadIndex] () { this->resumeDownload(downloadIndex); });
|
||||
m_OrganizerCore.doAfterLogin([this, downloadIndex] () {
|
||||
this->resumeDownload(downloadIndex);
|
||||
});
|
||||
NexusInterface::instance()->getAccessManager()->login(username, password);
|
||||
} else {
|
||||
MessageDialog::showMessage(tr("You need to be logged in with Nexus to resume a download"), this);
|
||||
@@ -2363,7 +2361,8 @@ void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index,
|
||||
m_OrganizerCore.modList()->modInfoChanged(modInfo);
|
||||
}
|
||||
|
||||
if (m_OrganizerCore.currentProfile()->modEnabled(index)) {
|
||||
if (m_OrganizerCore.currentProfile()->modEnabled(index)
|
||||
&& !modInfo->hasFlag(ModInfo::FLAG_FOREIGN)) {
|
||||
FilesOrigin& origin = m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(modInfo->name()));
|
||||
origin.enable(false);
|
||||
|
||||
@@ -2618,7 +2617,7 @@ void MainWindow::addRemoveCategoriesFromMenu(QMenu *menu, int modRow, int refere
|
||||
{
|
||||
if (referenceRow != -1 && referenceRow != modRow) {
|
||||
ModInfo::Ptr editedModInfo = ModInfo::getByIndex(referenceRow);
|
||||
foreach (QAction* action, menu->actions()) {
|
||||
for (QAction* action : menu->actions()) {
|
||||
if (action->menu() != nullptr) {
|
||||
addRemoveCategoriesFromMenu(action->menu(), modRow, referenceRow);
|
||||
} else {
|
||||
@@ -2648,25 +2647,29 @@ void MainWindow::addRemoveCategories_MenuHandler() {
|
||||
return;
|
||||
}
|
||||
|
||||
QModelIndexList selectedTemp = ui->modList->selectionModel()->selectedRows();
|
||||
QList<QPersistentModelIndex> selected;
|
||||
foreach (const QModelIndex &idx, selectedTemp) {
|
||||
for (const QModelIndex &idx : ui->modList->selectionModel()->selectedRows()) {
|
||||
selected.append(QPersistentModelIndex(idx));
|
||||
}
|
||||
|
||||
if (selected.size() > 0) {
|
||||
foreach (const QPersistentModelIndex &idx, selected) {
|
||||
qDebug("change categories on: %s (ref: %s)", qPrintable(idx.data().toString()), qPrintable(m_ContextIdx.data().toString()));
|
||||
int minRow = INT_MAX;
|
||||
int maxRow = -1;
|
||||
|
||||
for (const QPersistentModelIndex &idx : selected) {
|
||||
qDebug("change categories on: %s", qPrintable(idx.data().toString()));
|
||||
QModelIndex modIdx = mapToModel(m_OrganizerCore.modList(), idx);
|
||||
if (modIdx.row() != m_ContextIdx.row()) {
|
||||
addRemoveCategoriesFromMenu(menu, modIdx.row(), m_ContextIdx.row());
|
||||
}
|
||||
if (idx.row() < minRow) minRow = idx.row();
|
||||
if (idx.row() > maxRow) maxRow = idx.row();
|
||||
}
|
||||
replaceCategoriesFromMenu(menu, m_ContextIdx.row());
|
||||
|
||||
m_OrganizerCore.modList()->notifyChange(-1);
|
||||
m_OrganizerCore.modList()->notifyChange(minRow, maxRow + 1);
|
||||
|
||||
foreach (const QPersistentModelIndex &idx, selected) {
|
||||
for (const QPersistentModelIndex &idx : selected) {
|
||||
ui->modList->selectionModel()->select(idx, QItemSelectionModel::Select | QItemSelectionModel::Rows);
|
||||
}
|
||||
} else {
|
||||
@@ -2685,21 +2688,28 @@ void MainWindow::replaceCategories_MenuHandler() {
|
||||
return;
|
||||
}
|
||||
|
||||
QModelIndexList selected = ui->modList->selectionModel()->selectedRows();
|
||||
QList<QPersistentModelIndex> selected;
|
||||
for (const QModelIndex &idx : ui->modList->selectionModel()->selectedRows()) {
|
||||
selected.append(QPersistentModelIndex(idx));
|
||||
}
|
||||
|
||||
if (selected.size() > 0) {
|
||||
QStringList selectedMods;
|
||||
int minRow = INT_MAX;
|
||||
int maxRow = -1;
|
||||
for (int i = 0; i < selected.size(); ++i) {
|
||||
QModelIndex temp = mapToModel(m_OrganizerCore.modList(), selected.at(i));
|
||||
selectedMods.append(temp.data().toString());
|
||||
replaceCategoriesFromMenu(menu, mapToModel(m_OrganizerCore.modList(), selected.at(i)).row());
|
||||
if (temp.row() < minRow) minRow = temp.row();
|
||||
if (temp.row() > maxRow) maxRow = temp.row();
|
||||
}
|
||||
|
||||
m_OrganizerCore.modList()->notifyChange(-1);
|
||||
m_OrganizerCore.modList()->notifyChange(minRow, maxRow + 1);
|
||||
|
||||
// find mods by their name because indices are invalidated
|
||||
QAbstractItemModel *model = ui->modList->model();
|
||||
Q_FOREACH(const QString &mod, selectedMods) {
|
||||
for (const QString &mod : selectedMods) {
|
||||
QModelIndexList matches = model->match(model->index(0, 0), Qt::DisplayRole, mod, 1,
|
||||
Qt::MatchFixedString | Qt::MatchCaseSensitive | Qt::MatchRecursive);
|
||||
if (matches.size() > 0) {
|
||||
@@ -3457,7 +3467,7 @@ void MainWindow::writeDataToFile()
|
||||
|
||||
int MainWindow::getBinaryExecuteInfo(const QFileInfo &targetInfo, QFileInfo &binaryInfo, QString &arguments)
|
||||
{
|
||||
QString extension = targetInfo.completeSuffix();
|
||||
QString extension = targetInfo.suffix();
|
||||
if ((extension.compare("cmd", Qt::CaseInsensitive) == 0) ||
|
||||
(extension.compare("com", Qt::CaseInsensitive) == 0) ||
|
||||
(extension.compare("bat", Qt::CaseInsensitive) == 0)) {
|
||||
@@ -3712,7 +3722,7 @@ void MainWindow::on_dataTree_customContextMenuRequested(const QPoint &pos)
|
||||
menu.addAction(tr("Add as Executable"), this, SLOT(addAsExecutable()));
|
||||
|
||||
QString fileName = m_ContextItem->text(0);
|
||||
if (m_PluginContainer.previewGenerator().previewSupported(QFileInfo(fileName).completeSuffix())) {
|
||||
if (m_PluginContainer.previewGenerator().previewSupported(QFileInfo(fileName).suffix())) {
|
||||
menu.addAction(tr("Preview"), this, SLOT(previewDataFile()));
|
||||
}
|
||||
|
||||
@@ -4350,7 +4360,7 @@ void MainWindow::on_bossButton_clicked()
|
||||
if (loot != INVALID_HANDLE_VALUE) {
|
||||
bool isJobHandle = true;
|
||||
ULONG lastProcessID;
|
||||
DWORD res = ::MsgWaitForMultipleObjects(1, &loot, false, 1000, QS_KEY | QS_MOUSE);
|
||||
DWORD res = ::MsgWaitForMultipleObjects(1, &loot, false, 100, QS_KEY | QS_MOUSE);
|
||||
while ((res != WAIT_FAILED) && (res != WAIT_OBJECT_0)) {
|
||||
if (isJobHandle) {
|
||||
if (::QueryInformationJobObject(loot, JobObjectBasicProcessIdList, &info, sizeof(info), &retLen) > 0) {
|
||||
@@ -4390,7 +4400,7 @@ void MainWindow::on_bossButton_clicked()
|
||||
std::string lootOut = readFromPipe(stdOutRead);
|
||||
processLOOTOut(lootOut, errorMessages, dialog);
|
||||
|
||||
res = ::MsgWaitForMultipleObjects(1, &loot, false, 1000, QS_KEY | QS_MOUSE);
|
||||
res = ::MsgWaitForMultipleObjects(1, &loot, false, 100, QS_KEY | QS_MOUSE);
|
||||
}
|
||||
|
||||
std::string remainder = readFromPipe(stdOutRead).c_str();
|
||||
|
||||
@@ -102,6 +102,7 @@ bool MOApplication::setStyleFile(const QString &styleName)
|
||||
updateStyle(styleName);
|
||||
}
|
||||
} else {
|
||||
setStyle(new ProxyStyle(QStyleFactory::create(m_DefaultStyle)));
|
||||
setStyleSheet("");
|
||||
}
|
||||
return true;
|
||||
|
||||
+64
-26
@@ -18,6 +18,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "modinfo.h"
|
||||
|
||||
#include "utility.h"
|
||||
#include "installationtester.h"
|
||||
#include "categories.h"
|
||||
@@ -26,6 +27,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "overwriteinfodialog.h"
|
||||
#include "json.h"
|
||||
#include "messagedialog.h"
|
||||
#include "filenamestring.h"
|
||||
|
||||
#include <gameinfo.h>
|
||||
#include <iplugingame.h>
|
||||
@@ -301,6 +303,40 @@ void ModInfo::setVersion(const VersionInfo &version)
|
||||
m_Version = version;
|
||||
}
|
||||
|
||||
void ModInfo::addCategory(const QString &categoryName)
|
||||
{
|
||||
int id = CategoryFactory::instance().getCategoryID(categoryName);
|
||||
if (id == -1) {
|
||||
id = CategoryFactory::instance().addCategory(categoryName, std::vector<int>(), 0);
|
||||
}
|
||||
setCategory(id, true);
|
||||
}
|
||||
|
||||
bool ModInfo::removeCategory(const QString &categoryName)
|
||||
{
|
||||
int id = CategoryFactory::instance().getCategoryID(categoryName);
|
||||
if (id == -1) {
|
||||
return false;
|
||||
}
|
||||
if (!categorySet(id)) {
|
||||
return false;
|
||||
}
|
||||
setCategory(id, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
QStringList ModInfo::categories()
|
||||
{
|
||||
QStringList result;
|
||||
|
||||
CategoryFactory &catFac = CategoryFactory::instance();
|
||||
for (int id : m_Categories) {
|
||||
result.append(catFac.getCategoryName(catFac.getCategoryIndex(id)));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ModInfo::hasFlag(ModInfo::EFlag flag) const
|
||||
{
|
||||
std::vector<EFlag> flags = getFlags();
|
||||
@@ -386,7 +422,8 @@ void ModInfoWithConflictInfo::doConflictCheck() const
|
||||
{
|
||||
m_OverwriteList.clear();
|
||||
m_OverwrittenList.clear();
|
||||
bool regular = false;
|
||||
|
||||
bool providesAnything = false;
|
||||
|
||||
int dataID = 0;
|
||||
if ((*m_DirectoryStructure)->originExists(L"data")) {
|
||||
@@ -394,26 +431,31 @@ void ModInfoWithConflictInfo::doConflictCheck() const
|
||||
}
|
||||
|
||||
std::wstring name = ToWString(this->name());
|
||||
|
||||
m_CurrentConflictState = CONFLICT_NONE;
|
||||
|
||||
if ((*m_DirectoryStructure)->originExists(name)) {
|
||||
FilesOrigin &origin = (*m_DirectoryStructure)->getOriginByName(name);
|
||||
std::vector<FileEntry::Ptr> files = origin.getFiles();
|
||||
// for all files in this origin
|
||||
for (auto iter = files.begin(); iter != files.end(); ++iter) {
|
||||
const std::vector<int> &alternatives = (*iter)->getAlternatives();
|
||||
if ((alternatives.size() == 0)
|
||||
|| (alternatives[0] == dataID)) {
|
||||
for (FileEntry::Ptr file : files) {
|
||||
const std::vector<int> &alternatives = file->getAlternatives();
|
||||
if ((alternatives.size() == 0) || (alternatives[0] == dataID)) {
|
||||
// no alternatives -> no conflict
|
||||
regular = true;
|
||||
providesAnything = true;
|
||||
} else {
|
||||
if ((*iter)->getOrigin() != origin.getID()) {
|
||||
FilesOrigin &altOrigin = (*m_DirectoryStructure)->getOriginByID((*iter)->getOrigin());
|
||||
if (file->getOrigin() != origin.getID()) {
|
||||
FilesOrigin &altOrigin = (*m_DirectoryStructure)->getOriginByID(file->getOrigin());
|
||||
unsigned int altIndex = ModInfo::getIndex(ToQString(altOrigin.getName()));
|
||||
m_OverwrittenList.insert(altIndex);
|
||||
} else {
|
||||
providesAnything = true;
|
||||
}
|
||||
|
||||
// for all non-providing alternative origins
|
||||
for (auto altIter = alternatives.begin(); altIter != alternatives.end(); ++altIter) {
|
||||
if ((*altIter != dataID) && (*altIter != origin.getID())) {
|
||||
FilesOrigin &altOrigin = (*m_DirectoryStructure)->getOriginByID(*altIter);
|
||||
for (int altId : alternatives) {
|
||||
if ((altId != dataID) && (altId != origin.getID())) {
|
||||
FilesOrigin &altOrigin = (*m_DirectoryStructure)->getOriginByID(altId);
|
||||
unsigned int altIndex = ModInfo::getIndex(ToQString(altOrigin.getName()));
|
||||
if (origin.getPriority() > altOrigin.getPriority()) {
|
||||
m_OverwriteList.insert(altIndex);
|
||||
@@ -424,22 +466,19 @@ void ModInfoWithConflictInfo::doConflictCheck() const
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_LastConflictCheck = QTime::currentTime();
|
||||
|
||||
m_LastConflictCheck = QTime::currentTime();
|
||||
|
||||
if (!m_OverwriteList.empty() && !m_OverwrittenList.empty())
|
||||
m_CurrentConflictState = CONFLICT_MIXED;
|
||||
else if (!m_OverwriteList.empty())
|
||||
m_CurrentConflictState = CONFLICT_OVERWRITE;
|
||||
else if (!m_OverwrittenList.empty()) {
|
||||
if (!regular) {
|
||||
m_CurrentConflictState = CONFLICT_REDUNDANT;
|
||||
} else {
|
||||
m_CurrentConflictState = CONFLICT_OVERWRITTEN;
|
||||
if (files.size() != 0) {
|
||||
if (!providesAnything)
|
||||
m_CurrentConflictState = CONFLICT_REDUNDANT;
|
||||
else if (!m_OverwriteList.empty() && !m_OverwrittenList.empty())
|
||||
m_CurrentConflictState = CONFLICT_MIXED;
|
||||
else if (!m_OverwriteList.empty())
|
||||
m_CurrentConflictState = CONFLICT_OVERWRITE;
|
||||
else if (!m_OverwrittenList.empty())
|
||||
m_CurrentConflictState = CONFLICT_OVERWRITTEN;
|
||||
}
|
||||
}
|
||||
else m_CurrentConflictState = CONFLICT_NONE;
|
||||
}
|
||||
|
||||
ModInfoWithConflictInfo::EConflictType ModInfoWithConflictInfo::isConflicted() const
|
||||
@@ -1027,7 +1066,6 @@ ModInfoBackup::ModInfoBackup(const QDir &path, DirectoryEntry **directoryStructu
|
||||
|
||||
|
||||
ModInfoOverwrite::ModInfoOverwrite()
|
||||
: m_StartupTime(QDateTime::currentDateTime())
|
||||
{
|
||||
testValid();
|
||||
}
|
||||
@@ -1069,7 +1107,7 @@ QStringList ModInfoOverwrite::archives() const
|
||||
{
|
||||
QStringList result;
|
||||
QDir dir(this->absolutePath());
|
||||
foreach (const QString &archive, dir.entryList(QStringList("*.bsa"))) {
|
||||
for (const QString &archive : dir.entryList(QStringList("*.bsa"))) {
|
||||
result.append(this->absolutePath() + "/" + archive);
|
||||
}
|
||||
return result;
|
||||
|
||||
+5
-5
@@ -300,6 +300,10 @@ public:
|
||||
*/
|
||||
virtual void addNexusCategory(int categoryID) = 0;
|
||||
|
||||
virtual void addCategory(const QString &categoryName) override;
|
||||
virtual bool removeCategory(const QString &categoryName) override;
|
||||
virtual QStringList categories() override;
|
||||
|
||||
/**
|
||||
* update the endorsement state for the mod. This only changes the
|
||||
* buffered state, it does not sync with Nexus
|
||||
@@ -1041,7 +1045,7 @@ public:
|
||||
virtual bool isEmpty() const;
|
||||
virtual QString name() const { return "Overwrite"; }
|
||||
virtual QString notes() const { return ""; }
|
||||
virtual QDateTime creationTime() const { return m_StartupTime; }
|
||||
virtual QDateTime creationTime() const { return QDateTime(); }
|
||||
virtual QString absolutePath() const;
|
||||
virtual MOBase::VersionInfo getNewestVersion() const { return ""; }
|
||||
virtual QString getInstallationFile() const { return ""; }
|
||||
@@ -1060,10 +1064,6 @@ private:
|
||||
|
||||
ModInfoOverwrite();
|
||||
|
||||
private:
|
||||
|
||||
QDateTime m_StartupTime;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -395,7 +395,6 @@ const int ModInfoDialog::getModID() const
|
||||
return m_Settings->value("modid", 0).toInt();
|
||||
}
|
||||
|
||||
|
||||
void ModInfoDialog::openTab(int tab)
|
||||
{
|
||||
QTabWidget *tabWidget = findChild<QTabWidget*>("tabWidget");
|
||||
@@ -407,16 +406,16 @@ void ModInfoDialog::openTab(int tab)
|
||||
void ModInfoDialog::thumbnailClicked(const QString &fileName)
|
||||
{
|
||||
QLabel *imageLabel = findChild<QLabel*>("imageLabel");
|
||||
imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
|
||||
QImage image(fileName);
|
||||
if (static_cast<float>(image.width()) / static_cast<float>(image.height()) > 1.34) {
|
||||
image = image.scaledToWidth(imageLabel->width());
|
||||
image = image.scaledToWidth(imageLabel->geometry().width());
|
||||
} else {
|
||||
image = image.scaledToHeight(imageLabel->height());
|
||||
image = image.scaledToHeight(imageLabel->geometry().height());
|
||||
}
|
||||
imageLabel->setPixmap(QPixmap::fromImage(image));
|
||||
}
|
||||
|
||||
|
||||
bool ModInfoDialog::allowNavigateFromTXT()
|
||||
{
|
||||
if (ui->saveTXTButton->isEnabled()) {
|
||||
|
||||
+25
-11
@@ -23,6 +23,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "installationtester.h"
|
||||
#include "qtgroupingproxy.h"
|
||||
#include "viewmarkingscrollbar.h"
|
||||
#include "modlistsortproxy.h"
|
||||
#include <gameinfo.h>
|
||||
#include <appconfig.h>
|
||||
#include <utility.h>
|
||||
@@ -83,6 +84,7 @@ void ModList::setProfile(Profile *profile)
|
||||
{
|
||||
m_Profile = profile;
|
||||
}
|
||||
|
||||
int ModList::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (!parent.isValid()) {
|
||||
@@ -245,7 +247,7 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const
|
||||
}
|
||||
} else if (column == COL_INSTALLTIME) {
|
||||
// display installation time for mods that can be updated
|
||||
if (modInfo->canBeUpdated()) {
|
||||
if (modInfo->creationTime().isValid()) {
|
||||
return modInfo->creationTime();
|
||||
} else {
|
||||
return QVariant();
|
||||
@@ -359,11 +361,9 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const
|
||||
if (column == COL_FLAGS) {
|
||||
QString result;
|
||||
|
||||
std::vector<ModInfo::EFlag> flags = modInfo->getFlags();
|
||||
|
||||
for (auto iter = flags.begin(); iter != flags.end(); ++iter) {
|
||||
for (ModInfo::EFlag flag : modInfo->getFlags()) {
|
||||
if (result.length() != 0) result += "<br>";
|
||||
result += getFlagText(*iter, modInfo);
|
||||
result += getFlagText(flag, modInfo);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -451,6 +451,8 @@ bool ModList::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
|
||||
bool result = false;
|
||||
|
||||
emit aboutToChangeData();
|
||||
|
||||
if (role == Qt::CheckStateRole) {
|
||||
bool enabled = value.toInt() == Qt::Checked;
|
||||
if (m_Profile->modEnabled(modID) != enabled) {
|
||||
@@ -510,6 +512,8 @@ bool ModList::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
}
|
||||
}
|
||||
|
||||
emit postDataChanged();
|
||||
|
||||
IModList::ModStates newState = state(modID);
|
||||
if (oldState != newState) {
|
||||
try {
|
||||
@@ -565,7 +569,8 @@ Qt::ItemFlags ModList::flags(const QModelIndex &modelIndex) const
|
||||
}
|
||||
}
|
||||
std::vector<ModInfo::EFlag> flags = modInfo->getFlags();
|
||||
if ((m_DropOnItems) && (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) == flags.end())) {
|
||||
if (m_DropOnItems
|
||||
&& (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) == flags.end())) {
|
||||
result |= Qt::ItemIsDropEnabled;
|
||||
}
|
||||
} else {
|
||||
@@ -654,6 +659,7 @@ void ModList::modInfoChanged(ModInfo::Ptr info)
|
||||
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()));
|
||||
@@ -1089,15 +1095,23 @@ bool ModList::deleteSelection(QAbstractItemView *itemView)
|
||||
|
||||
bool ModList::toggleSelection(QAbstractItemView *itemView)
|
||||
{
|
||||
QAbstractItemModel *model = itemView->model();
|
||||
emit aboutToChangeData();
|
||||
|
||||
QItemSelectionModel *selectionModel = itemView->selectionModel();
|
||||
|
||||
for (QModelIndex idx : selectionModel->selectedRows()) {
|
||||
int oldState = idx.data(Qt::CheckStateRole).toInt();
|
||||
model->setData(idx, oldState == Qt::Unchecked ? Qt::Checked
|
||||
: Qt::Unchecked,
|
||||
Qt::CheckStateRole);
|
||||
int modId = idx.data(Qt::UserRole + 1).toInt();
|
||||
m_Profile->setModEnabled(modId, !m_Profile->modEnabled(modId));
|
||||
emit modlist_changed(idx, 0);
|
||||
}
|
||||
|
||||
m_Modified = true;
|
||||
m_LastCheck.restart();
|
||||
|
||||
emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
|
||||
|
||||
emit postDataChanged();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -237,6 +237,10 @@ signals:
|
||||
*/
|
||||
void fileMoved(const QString &relativePath, const QString &oldOriginName, const QString &newOriginName);
|
||||
|
||||
void aboutToChangeData();
|
||||
|
||||
void postDataChanged();
|
||||
|
||||
protected:
|
||||
|
||||
// event filter, handles event from the header and the tree view itself
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user