/*
Copyright (C) 2012 Sebastian Herbord. All rights reserved.
This file is part of Mod Organizer.
Mod Organizer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mod Organizer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see .
*/
#include "modlist.h"
#include "messagedialog.h"
#include "installationtester.h"
#include "qtgroupingproxy.h"
#include "viewmarkingscrollbar.h"
#include "modlistsortproxy.h"
#include "pluginlist.h"
#include "settings.h"
#include "modinforegular.h"
#include "shared/directoryentry.h"
#include "shared/fileentry.h"
#include "shared/filesorigin.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace MOBase;
ModList::ModList(PluginContainer *pluginContainer, QObject *parent)
: QAbstractItemModel(parent)
, m_Profile(nullptr)
, m_NexusInterface(nullptr)
, m_Modified(false)
, m_InNotifyChange(false)
, m_FontMetrics(QFont())
, m_DropOnItems(false)
, m_PluginContainer(pluginContainer)
{
m_ContentIcons[ModInfo::CONTENT_PLUGIN] = std::make_tuple(":/MO/gui/content/plugin", QT_TR_NOOP("Game Plugins (ESP/ESM/ESL)"));
m_ContentIcons[ModInfo::CONTENT_INTERFACE] = std::make_tuple(":/MO/gui/content/interface", QT_TR_NOOP("Interface"));
m_ContentIcons[ModInfo::CONTENT_MESH] = std::make_tuple(":/MO/gui/content/mesh", QT_TR_NOOP("Meshes"));
m_ContentIcons[ModInfo::CONTENT_BSA] = std::make_tuple(":/MO/gui/content/bsa", QT_TR_NOOP("Bethesda Archive"));
m_ContentIcons[ModInfo::CONTENT_SCRIPT] = std::make_tuple(":/MO/gui/content/script", QT_TR_NOOP("Scripts (Papyrus)"));
m_ContentIcons[ModInfo::CONTENT_SKSE] = std::make_tuple(":/MO/gui/content/skse", QT_TR_NOOP("Script Extender Plugin"));
m_ContentIcons[ModInfo::CONTENT_SKYPROC] = std::make_tuple(":/MO/gui/content/skyproc", QT_TR_NOOP("SkyProc Patcher"));
m_ContentIcons[ModInfo::CONTENT_SOUND] = std::make_tuple(":/MO/gui/content/sound", QT_TR_NOOP("Sound or Music"));
m_ContentIcons[ModInfo::CONTENT_TEXTURE] = std::make_tuple(":/MO/gui/content/texture", QT_TR_NOOP("Textures"));
m_ContentIcons[ModInfo::CONTENT_MCM] = std::make_tuple(":/MO/gui/content/menu", QT_TR_NOOP("MCM Configuration"));
m_ContentIcons[ModInfo::CONTENT_INI] = std::make_tuple(":/MO/gui/content/inifile", QT_TR_NOOP("INI files"));
m_ContentIcons[ModInfo::CONTENT_MODGROUP] = std::make_tuple(":/MO/gui/content/modgroup", QT_TR_NOOP("ModGroup files"));
m_LastCheck.start();
}
ModList::~ModList()
{
m_ModStateChanged.disconnect_all_slots();
m_ModMoved.disconnect_all_slots();
}
void ModList::setProfile(Profile *profile)
{
m_Profile = profile;
}
int ModList::rowCount(const QModelIndex &parent) const
{
if (!parent.isValid()) {
return ModInfo::getNumMods();
} else {
return 0;
}
}
bool ModList::hasChildren(const QModelIndex &parent) const
{
if (!parent.isValid()) {
return ModInfo::getNumMods() > 0;
} else {
return false;
}
}
int ModList::columnCount(const QModelIndex &) const
{
return COL_LASTCOLUMN + 1;
}
QVariant ModList::getOverwriteData(int column, int role) const
{
switch (role) {
case Qt::DisplayRole: {
if (column == 0) {
return "Overwrite";
} else {
return QVariant();
}
} break;
case Qt::CheckStateRole: {
if (column == 0) {
return Qt::Checked;
} else {
return QVariant();
}
} break;
case Qt::TextAlignmentRole: return QVariant(Qt::AlignCenter | Qt::AlignVCenter);
case Qt::UserRole: return -1;
case Qt::ForegroundRole: return QBrush(Qt::red);
case Qt::ToolTipRole: return tr("This entry contains files that have been created inside the virtual data tree (i.e. by the construction kit)");
default: return QVariant();
}
}
QString ModList::getFlagText(ModInfo::EFlag flag, ModInfo::Ptr modInfo) const
{
switch (flag) {
case ModInfo::FLAG_BACKUP: return tr("Backup");
case ModInfo::FLAG_SEPARATOR: return tr("Separator");
case ModInfo::FLAG_INVALID: return tr("No valid game data");
case ModInfo::FLAG_NOTENDORSED: return tr("Not endorsed yet");
case ModInfo::FLAG_NOTES: {
QStringList output;
if (!modInfo->comments().isEmpty())
output << QString("%1").arg(modInfo->comments());
if (!modInfo->notes().isEmpty())
output << QString("%1").arg(modInfo->notes());
return output.join("");
}
case ModInfo::FLAG_ALTERNATE_GAME: return tr(" This mod is for a different game, "
"make sure it's compatible or it could cause crashes.");
case ModInfo::FLAG_TRACKED: return tr("Mod is being tracked on the website");
case ModInfo::FLAG_HIDDEN_FILES: return tr("Contains hidden files");
default: return "";
}
}
QString ModList::getConflictFlagText(ModInfo::EConflictFlag flag, ModInfo::Ptr modInfo) const
{
switch (flag) {
case ModInfo::FLAG_CONFLICT_OVERWRITE: return tr("Overwrites loose files");
case ModInfo::FLAG_CONFLICT_OVERWRITTEN: return tr("Overwritten loose files");
case ModInfo::FLAG_CONFLICT_MIXED: return tr("Loose files Overwrites & Overwritten");
case ModInfo::FLAG_CONFLICT_REDUNDANT: return tr("Redundant");
case ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITE: return tr("Overwrites an archive with loose files");
case ModInfo::FLAG_ARCHIVE_LOOSE_CONFLICT_OVERWRITTEN: return tr("Archive is overwritten by loose files");
case ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITE: return tr("Overwrites another archive file");
case ModInfo::FLAG_ARCHIVE_CONFLICT_OVERWRITTEN: return tr("Overwritten by another archive file");
case ModInfo::FLAG_ARCHIVE_CONFLICT_MIXED: return tr("Archive files overwrites & overwritten");
default: return "";
}
}
QVariantList ModList::contentsToIcons(const std::vector &contents) const
{
QVariantList result;
std::set contentsSet(contents.begin(), contents.end());
for (auto iter = m_ContentIcons.begin(); iter != m_ContentIcons.end(); ++iter) {
if (contentsSet.find(iter->first) != contentsSet.end()) {
result.append(std::get<0>(iter->second));
} else {
result.append(QString());
}
}
return result;
}
QString ModList::contentsToToolTip(const std::vector &contents) const
{
QString result("
");
std::set contentsSet(contents.begin(), contents.end());
for (auto iter = m_ContentIcons.begin(); iter != m_ContentIcons.end(); ++iter) {
if (contentsSet.find(iter->first) != contentsSet.end()) {
result.append(QString("