summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAl12rs <gabriel.cortesi@outlook.com>2018-10-28 02:16:20 +0200
committerAl12rs <gabriel.cortesi@outlook.com>2018-10-28 02:16:20 +0200
commit42d2344f0b81cb1cf8dbe83e8f480b84ed0c3114 (patch)
tree5f349dba87b9a6e34700e4b6dbd4ac6c19e95d42 /src
parent18e49b71b509a7a306d89392cc4486bb3c960e4f (diff)
Added modlist Separators feature:
*New modType separator. *Bold, italic and centralized name without _separator at the end. *Added "create separator" option to context menu. *Added "rename separator" option. *Fixed rename separator issue with priority resetting.
Diffstat (limited to 'src')
-rw-r--r--src/mainwindow.cpp42
-rw-r--r--src/mainwindow.h1
-rw-r--r--src/modinfo.cpp8
-rw-r--r--src/modinfo.h3
-rw-r--r--src/modinfodialog.cpp17
-rw-r--r--src/modinfoseparator.cpp36
-rw-r--r--src/modinfoseparator.h77
-rw-r--r--src/modlist.cpp29
8 files changed, 202 insertions, 11 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 04bd96c7..bc25ab70 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -2629,8 +2629,9 @@ void MainWindow::modOpenNext(int tab)
ModInfo::Ptr mod = ModInfo::getByIndex(m_ContextRow);
std::vector<ModInfo::EFlag> flags = mod->getFlags();
if ((std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end()) ||
- (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP) != flags.end())) {
- // skip overwrite and backups
+ (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP) != flags.end()) ||
+ (std::find(flags.begin(), flags.end(), ModInfo::FLAG_SEPARATOR) != flags.end())) {
+ // skip overwrite and backups and separators
modOpenNext(tab);
} else {
displayModInformation(m_ContextRow,tab);
@@ -2649,8 +2650,9 @@ void MainWindow::modOpenPrev(int tab)
ModInfo::Ptr mod = ModInfo::getByIndex(m_ContextRow);
std::vector<ModInfo::EFlag> flags = mod->getFlags();
if ((std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end()) ||
- (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP) != flags.end())) {
- // skip overwrite and backups
+ (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP) != flags.end()) ||
+ (std::find(flags.begin(), flags.end(), ModInfo::FLAG_SEPARATOR) != flags.end())) {
+ // skip overwrite and backups and separators
modOpenPrev(tab);
} else {
displayModInformation(m_ContextRow,tab);
@@ -2839,6 +2841,33 @@ void MainWindow::createEmptyMod_clicked()
m_OrganizerCore.refreshModList();
}
+void MainWindow::createSeparator_clicked()
+{
+ GuessedValue<QString> name;
+ name.setFilter(&fixDirectoryName);
+ while (name->isEmpty())
+ {
+ bool ok;
+ name.update(QInputDialog::getText(this, tr("Create Separator..."),
+ tr("This will create a new separator.\n"
+ "Please enter a name:"), QLineEdit::Normal, "", &ok),
+ GUESS_USER);
+ if (!ok) { return; }
+ }
+ if (m_OrganizerCore.getMod(name) != nullptr)
+ {
+ reportError(tr("A separator with this name already exists"));
+ return;
+ }
+ name->append("_separator");
+ if (m_OrganizerCore.getMod(name) != nullptr)
+ {
+ return;
+ }
+ if (m_OrganizerCore.createMod(name) == nullptr) { return; }
+ m_OrganizerCore.refreshModList();
+}
+
void MainWindow::createModFromOverwrite()
{
GuessedValue<QString> name;
@@ -3579,6 +3608,8 @@ QMenu *MainWindow::modListContextMenu()
menu->addAction(tr("Create empty mod"), this, SLOT(createEmptyMod_clicked()));
+ menu->addAction(tr("Create separator"), this, SLOT(createSeparator_clicked()));
+
menu->addSeparator();
menu->addAction(tr("Enable all visible"), this, SLOT(enableVisibleMods()));
@@ -3623,6 +3654,9 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos)
} else if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP) != flags.end()) {
menu->addAction(tr("Restore Backup"), this, SLOT(restoreBackup_clicked()));
menu->addAction(tr("Remove Backup..."), this, SLOT(removeMod_clicked()));
+ } else if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_SEPARATOR) != flags.end()){
+ menu->addAction(tr("Rename Separator..."), this, SLOT(renameMod_clicked()));
+ menu->addAction(tr("Remove Separator..."), this, SLOT(removeMod_clicked()));
} else if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_FOREIGN) != flags.end()) {
// nop, nothing to do with this mod
} else {
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 0bf3d3c8..78d374e6 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -404,6 +404,7 @@ private slots:
// modlist context menu
void installMod_clicked();
void createEmptyMod_clicked();
+ void createSeparator_clicked();
void restoreBackup_clicked();
void renameMod_clicked();
void removeMod_clicked();
diff --git a/src/modinfo.cpp b/src/modinfo.cpp
index 8ce40da3..4c41a114 100644
--- a/src/modinfo.cpp
+++ b/src/modinfo.cpp
@@ -23,6 +23,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "modinforegular.h"
#include "modinfoforeign.h"
#include "modinfooverwrite.h"
+#include "modinfoseparator.h"
#include "installationtester.h"
#include "categories.h"
@@ -64,11 +65,14 @@ bool ModInfo::ByName(const ModInfo::Ptr &LHS, const ModInfo::Ptr &RHS)
ModInfo::Ptr ModInfo::createFrom(PluginContainer *pluginContainer, const MOBase::IPluginGame *game, const QDir &dir, DirectoryEntry **directoryStructure)
{
QMutexLocker locker(&s_Mutex);
-// int id = s_NextID++;
+ // int id = s_NextID++;
static QRegExp backupExp(".*backup[0-9]*");
+ static QRegExp separatorExp(".*_separator");
ModInfo::Ptr result;
if (backupExp.exactMatch(dir.dirName())) {
result = ModInfo::Ptr(new ModInfoBackup(pluginContainer, game, dir, directoryStructure));
+ } else if(separatorExp.exactMatch(dir.dirName())){
+ result = Ptr(new ModInfoSeparator(pluginContainer, game, dir, directoryStructure));
} else {
result = ModInfo::Ptr(new ModInfoRegular(pluginContainer, game, dir, directoryStructure));
}
@@ -418,4 +422,4 @@ void ModInfo::testValid()
while (dirIter.hasNext()) {
dirIter.next();
}
-} \ No newline at end of file
+}
diff --git a/src/modinfo.h b/src/modinfo.h
index 895105df..9f6c2fbc 100644
--- a/src/modinfo.h
+++ b/src/modinfo.h
@@ -62,6 +62,7 @@ public:
enum EFlag {
FLAG_INVALID,
FLAG_BACKUP,
+ FLAG_SEPARATOR,
FLAG_OVERWRITE,
FLAG_FOREIGN,
FLAG_NOTENDORSED,
@@ -560,7 +561,7 @@ public:
/**
* @return true if this mod is considered "valid", that is: it contains data used by the game
**/
- bool isValid() const { return m_Valid; }
+ virtual bool isValid() const { return m_Valid; }
/**
* @return true if the file has been endorsed on nexus
diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp
index fedddd6c..54910e41 100644
--- a/src/modinfodialog.cpp
+++ b/src/modinfodialog.cpp
@@ -134,7 +134,22 @@ ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directo
refreshLists();
- if (unmanaged) {
+ if (modInfo->hasFlag(ModInfo::FLAG_SEPARATOR))
+ {
+ ui->tabWidget->setTabEnabled(TAB_TEXTFILES, false);
+ ui->tabWidget->setTabEnabled(TAB_INIFILES, false);
+ ui->tabWidget->setTabEnabled(TAB_IMAGES, false);
+ ui->tabWidget->setTabEnabled(TAB_ESPS, false);
+ ui->tabWidget->setTabEnabled(TAB_CONFLICTS, false);
+ //ui->tabWidget->setTabEnabled(TAB_CATEGORIES, false);
+ addCategories(CategoryFactory::instance(), modInfo->getCategories(), ui->categoriesTree->invisibleRootItem(), 0);
+ refreshPrimaryCategoriesBox();
+ ui->tabWidget->setTabEnabled(TAB_NEXUS, false);
+ //ui->tabWidget->setTabEnabled(TAB_NOTES, false);
+ ui->tabWidget->setTabEnabled(TAB_FILETREE, false);
+ }
+ else if (unmanaged)
+ {
ui->tabWidget->setTabEnabled(TAB_INIFILES, false);
ui->tabWidget->setTabEnabled(TAB_CATEGORIES, false);
ui->tabWidget->setTabEnabled(TAB_NEXUS, false);
diff --git a/src/modinfoseparator.cpp b/src/modinfoseparator.cpp
new file mode 100644
index 00000000..60014f66
--- /dev/null
+++ b/src/modinfoseparator.cpp
@@ -0,0 +1,36 @@
+#include "modinfoseparator.h"
+
+bool ModInfoSeparator::setName(const QString& name)
+{
+ return ModInfoRegular::setName(name);
+}
+
+std::vector<ModInfo::EFlag> ModInfoSeparator::getFlags() const
+{
+ {
+ auto result = ModInfoRegular::getFlags();
+ result.insert(result.begin(), FLAG_SEPARATOR);
+ return result;
+ }
+}
+
+int ModInfoSeparator::getHighlight() const
+{
+ return HIGHLIGHT_CENTER;
+}
+
+QString ModInfoSeparator::getDescription() const
+{
+ return tr("This is a Separator");
+}
+
+QString ModInfoSeparator::name() const
+{
+ return ModInfoRegular::name();
+}
+
+
+ModInfoSeparator::ModInfoSeparator(PluginContainer *pluginContainer, const MOBase::IPluginGame *game, const QDir &path, MOShared::DirectoryEntry **directoryStructure)
+ : ModInfoRegular(pluginContainer, game, path, directoryStructure)
+{
+}
diff --git a/src/modinfoseparator.h b/src/modinfoseparator.h
new file mode 100644
index 00000000..f215fb17
--- /dev/null
+++ b/src/modinfoseparator.h
@@ -0,0 +1,77 @@
+#ifndef MODINFOSEPARATOR_H
+#define MODINFOSEPARATOR_H
+
+#include "modinforegular.h"
+
+class ModInfoSeparator:
+ public ModInfoRegular
+{
+ friend class ModInfo;
+
+public:
+
+ virtual bool updateAvailable() const { return false; }
+ virtual bool updateIgnored() const { return false; }
+ virtual bool downgradeAvailable() const { return false; }
+ virtual bool updateNXMInfo() { return false; }
+ virtual bool isValid() const { return true; }
+ //TODO: Fix renaming method to avoid priority reset
+ virtual bool setName(const QString& name);
+
+ virtual int getNexusID() const { return -1; }
+
+ virtual void setGameName(QString /*gameName*/)
+ {
+ }
+
+ virtual void setNexusID(int /*modID*/)
+ {
+ }
+
+ virtual void endorse(bool /*doEndorse*/)
+ {
+ }
+
+ virtual void ignoreUpdate(bool /*ignore*/)
+ {
+ }
+
+ virtual bool canBeUpdated() const { return false; }
+ virtual bool canBeEnabled() const { return false; }
+ virtual std::vector<QString> getIniTweaks() const { return std::vector<QString>(); }
+
+ virtual std::vector<EFlag> getFlags() const;
+ virtual int getHighlight() const;
+
+ virtual QString getDescription() const;
+ virtual QString name() const;
+ virtual QString getGameName() const { return ""; }
+ virtual QString getInstallationFile() const { return ""; }
+ virtual QString getURL() const { return ""; }
+ virtual QString repository() const { return ""; }
+
+ virtual QDateTime getLastNexusQuery() const { return QDateTime(); }
+ virtual QDateTime creationTime() const { return QDateTime(); }
+
+ virtual void getNexusFiles
+ (
+ QList<MOBase::ModRepositoryFileInfo*>::const_iterator& /*unused*/,
+ QList<MOBase::ModRepositoryFileInfo*>::const_iterator& /*unused*/)
+ {
+ }
+
+ virtual QString getNexusDescription() const { return QString(); }
+
+ virtual void addInstalledFile(int /*modId*/, int /*fileId*/)
+ {
+ }
+
+private:
+
+ ModInfoSeparator
+ (
+ PluginContainer* pluginContainer, const MOBase::IPluginGame* game, const QDir& path,
+ MOShared::DirectoryEntry** directoryStructure);
+};
+
+#endif
diff --git a/src/modlist.cpp b/src/modlist.cpp
index c7f6a53b..31ef9ddc 100644
--- a/src/modlist.cpp
+++ b/src/modlist.cpp
@@ -45,6 +45,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QAbstractItemView>
#include <QSortFilterProxyModel>
#include <QApplication>
+#include <QFontDatabase>
#include <sstream>
#include <stdexcept>
@@ -145,6 +146,7 @@ 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: return QString("<i>%1</i>").arg(modInfo->notes().replace("\n", "<br>"));
@@ -203,7 +205,13 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const
|| (column == COL_CONTENT)) {
return QVariant();
} else if (column == COL_NAME) {
- return modInfo->name();
+ auto flags = modInfo->getFlags();
+ if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_SEPARATOR) != flags.end())
+ {
+ return modInfo->name().replace("_separator", "");
+ }
+ else
+ return modInfo->name();
} else if (column == COL_VERSION) {
VersionInfo verInfo = modInfo->getVersion();
QString version = verInfo.displayString();
@@ -277,6 +285,7 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const
return QVariant();
}
} else if (role == Qt::TextAlignmentRole) {
+ auto flags = modInfo->getFlags();
if (column == COL_NAME) {
if (modInfo->getHighlight() & ModInfo::HIGHLIGHT_CENTER) {
return QVariant(Qt::AlignCenter | Qt::AlignVCenter);
@@ -327,8 +336,15 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const
return modInfo->getGameName();
} else if (role == Qt::FontRole) {
QFont result;
+ auto flags = modInfo->getFlags();
if (column == COL_NAME) {
- if (modInfo->getHighlight() & ModInfo::HIGHLIGHT_INVALID) {
+ if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_SEPARATOR) != flags.end())
+ {
+ //result.setCapitalization(QFont::AllUppercase);
+ result.setItalic(true);
+ //result.setUnderline(true);
+ result.setBold(true);
+ } else if (modInfo->getHighlight() & ModInfo::HIGHLIGHT_INVALID) {
result.setItalic(true);
}
} else if ((column == COL_CATEGORY) && (modInfo->hasFlag(ModInfo::FLAG_FOREIGN))) {
@@ -476,6 +492,7 @@ bool ModList::setData(const QModelIndex &index, const QVariant &value, int role)
ModInfo::Ptr info = ModInfo::getByIndex(modID);
IModList::ModStates oldState = state(modID);
+
bool result = false;
emit aboutToChangeData();
@@ -493,7 +510,13 @@ bool ModList::setData(const QModelIndex &index, const QVariant &value, int role)
} else if (role == Qt::EditRole) {
switch (index.column()) {
case COL_NAME: {
- result = renameMod(modID, value.toString());
+ auto flags = info->getFlags();
+ if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_SEPARATOR) != flags.end())
+ {
+ result = renameMod(modID, value.toString() + "_separator");
+ }
+ else
+ result = renameMod(modID, value.toString());
} break;
case COL_PRIORITY: {
bool ok = false;