From 0050cb07409d775efe14e728c1cef4a2c33aa1db Mon Sep 17 00:00:00 2001 From: Tannin Date: Mon, 21 Jul 2014 19:14:24 +0200 Subject: - download-list will no longer show a file as having incomplete data if there is no file version - added a new mod column with icons displaying the content of the mod - MO now differentiates between mods using an internal name that disambiguates between foreign and regular mods --- src/aboutdialog.cpp | 7 ++- src/downloadmanager.cpp | 3 +- src/icondelegate.cpp | 17 ------- src/icondelegate.h | 1 - src/mainwindow.cpp | 12 ++++- src/modflagicondelegate.cpp | 17 +++++++ src/modflagicondelegate.h | 1 + src/modinfo.cpp | 26 +++++++++- src/modinfo.h | 32 ++++++++++++ src/modlist.cpp | 74 ++++++++++++++++++++++++++-- src/modlist.h | 10 ++++ src/modlistsortproxy.cpp | 7 +++ src/pluginflagicondelegate.cpp | 27 +++++++--- src/pluginflagicondelegate.h | 27 ++++++++-- src/pluginlist.cpp | 3 -- src/profile.cpp | 21 ++++---- src/resources.qrc | 12 +++++ src/resources/contents/breastplate.png | Bin 0 -> 10578 bytes src/resources/contents/checkbox-tree.png | Bin 0 -> 1144 bytes src/resources/contents/conversation.png | Bin 0 -> 7980 bytes src/resources/contents/double-quaver.png | Bin 0 -> 5877 bytes src/resources/contents/empty-chessboard.png | Bin 0 -> 959 bytes src/resources/contents/hand-of-god.png | Bin 0 -> 7105 bytes src/resources/contents/jigsaw-piece.png | Bin 0 -> 5971 bytes src/resources/contents/lyre.png | Bin 0 -> 9368 bytes src/resources/contents/tinker.png | Bin 0 -> 6475 bytes src/resources/contents/usable.png | Bin 0 -> 9919 bytes 27 files changed, 241 insertions(+), 56 deletions(-) create mode 100644 src/resources/contents/breastplate.png create mode 100644 src/resources/contents/checkbox-tree.png create mode 100644 src/resources/contents/conversation.png create mode 100644 src/resources/contents/double-quaver.png create mode 100644 src/resources/contents/empty-chessboard.png create mode 100644 src/resources/contents/hand-of-god.png create mode 100644 src/resources/contents/jigsaw-piece.png create mode 100644 src/resources/contents/lyre.png create mode 100644 src/resources/contents/tinker.png create mode 100644 src/resources/contents/usable.png (limited to 'src') diff --git a/src/aboutdialog.cpp b/src/aboutdialog.cpp index a8f9b4db..b5bfeb04 100644 --- a/src/aboutdialog.cpp +++ b/src/aboutdialog.cpp @@ -39,13 +39,12 @@ AboutDialog::AboutDialog(const QString &version, QWidget *parent) addLicense("Qt 4.8.5", LICENSE_LGPL3); addLicense("Qt Json", LICENSE_GPL3); addLicense("Boost Library", LICENSE_BOOST); - addLicense("Tango Icon Theme", LICENSE_NONE); - addLicense("RRZE Icon Set", LICENSE_CCBY3); addLicense("7-zip", LICENSE_LGPL3); addLicense("ZLib", LICENSE_ZLIB); addLicense("NIF File Format Library", LICENSE_BSD3); - addLicense("BOSS (modified)", LICENSE_GPL3); - addLicense("Alphanum Algorithm", LICENSE_ZLIB); + addLicense("Tango Icon Theme", LICENSE_NONE); + addLicense("RRZE Icon Set", LICENSE_CCBY3); + addLicense("Icons by Lorc, Delapouite and sbed available on http://game-icons.net", LICENSE_CCBY3); ui->nameLabel->setText(QString("%1 %2").arg(ui->nameLabel->text()).arg(version)); #ifdef HGID diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index 391ac7b9..856ca79c 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -831,7 +831,7 @@ bool DownloadManager::isInfoIncomplete(int index) const // other repositories currently don't support re-querying info anyway return false; } - return (info->m_FileInfo->fileID == 0) || (info->m_FileInfo->modID == 0) || !info->m_FileInfo->version.isValid(); + return (info->m_FileInfo->fileID == 0) || (info->m_FileInfo->modID == 0); } @@ -1181,7 +1181,6 @@ void DownloadManager::nxmFileInfoAvailable(int modID, int fileID, QVariant userD QVariantMap result = resultData.toMap(); info->name = result["name"].toString(); - qDebug("file info received for %s", qPrintable(info->name)); info->version.parse(result["version"].toString()); if (!info->version.isValid()) { info->version = info->newestVersion; diff --git a/src/icondelegate.cpp b/src/icondelegate.cpp index f7cf6977..8c2fe5cc 100644 --- a/src/icondelegate.cpp +++ b/src/icondelegate.cpp @@ -51,20 +51,3 @@ void IconDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, painter->restore(); } - -QSize IconDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &modelIndex) const -{ - int count = getNumIcons(modelIndex); - unsigned int index = modelIndex.data(Qt::UserRole + 1).toInt(); - QSize result; - if (index < ModInfo::getNumMods()) { - result = QSize(count * 40, 20); - } else { - result = QSize(1, 20); - } - if (option.rect.width() > 0) { - result.setWidth(std::min(option.rect.width(), result.width())); - } - return result; -} - diff --git a/src/icondelegate.h b/src/icondelegate.h index 072343bb..b24de102 100644 --- a/src/icondelegate.h +++ b/src/icondelegate.h @@ -33,7 +33,6 @@ public: explicit IconDelegate(QObject *parent = 0); virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; - virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; signals: diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index c3182321..a3887a23 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -209,14 +209,22 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget ui->modList->setModel(m_ModListSortProxy); + GenericIconDelegate *contentDelegate = new GenericIconDelegate(ui->modList, Qt::UserRole + 3, ModList::COL_CONTENT, 150); + connect(ui->modList->header(), SIGNAL(sectionResized(int,int,int)), contentDelegate, SLOT(columnResized(int,int,int))); ui->modList->sortByColumn(ModList::COL_PRIORITY, Qt::AscendingOrder); ui->modList->setItemDelegateForColumn(ModList::COL_FLAGS, new ModFlagIconDelegate(ui->modList)); + ui->modList->setItemDelegateForColumn(ModList::COL_CONTENT, contentDelegate); //ui->modList->setAcceptDrops(true); ui->modList->header()->installEventFilter(&m_ModList); if (initSettings.contains("mod_list_state")) { ui->modList->header()->restoreState(initSettings.value("mod_list_state").toByteArray()); + + // hack: force the resize-signal to be triggered because restoreState doesn't seem to do that + ui->modList->header()->resizeSection(ModList::COL_CONTENT, ui->modList->header()->sectionSize(ModList::COL_CONTENT) + 1); + ui->modList->header()->resizeSection(ModList::COL_CONTENT, ui->modList->header()->sectionSize(ModList::COL_CONTENT) - 1); } else { // hide these columns by default + ui->modList->header()->setSectionHidden(ModList::COL_CONTENT, true); ui->modList->header()->setSectionHidden(ModList::COL_MODID, true); ui->modList->header()->setSectionHidden(ModList::COL_INSTALLTIME, true); } @@ -230,7 +238,7 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget ui->espList->setModel(m_PluginListSortProxy); ui->espList->sortByColumn(PluginList::COL_PRIORITY, Qt::AscendingOrder); - ui->espList->setItemDelegateForColumn(PluginList::COL_FLAGS, new PluginFlagIconDelegate(ui->espList)); + ui->espList->setItemDelegateForColumn(PluginList::COL_FLAGS, new GenericIconDelegate(ui->espList)); if (initSettings.contains("plugin_list_state")) { ui->espList->header()->restoreState(initSettings.value("plugin_list_state").toByteArray()); } @@ -2758,7 +2766,7 @@ void MainWindow::modorder_changed() if (m_CurrentProfile->modEnabled(i)) { ModInfo::Ptr modInfo = ModInfo::getByIndex(i); // priorities in the directory structure are one higher because data is 0 - m_DirectoryStructure->getOriginByName(ToWString(modInfo->name())).setPriority(priority + 1); + m_DirectoryStructure->getOriginByName(ToWString(modInfo->internalName())).setPriority(priority + 1); } } refreshBSAList(); diff --git a/src/modflagicondelegate.cpp b/src/modflagicondelegate.cpp index 914503a1..96b2bd58 100644 --- a/src/modflagicondelegate.cpp +++ b/src/modflagicondelegate.cpp @@ -68,3 +68,20 @@ size_t ModFlagIconDelegate::getNumIcons(const QModelIndex &index) const } } + +QSize ModFlagIconDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &modelIndex) const +{ + int count = getNumIcons(modelIndex); + unsigned int index = modelIndex.data(Qt::UserRole + 1).toInt(); + QSize result; + if (index < ModInfo::getNumMods()) { + result = QSize(count * 40, 20); + } else { + result = QSize(1, 20); + } + if (option.rect.width() > 0) { + result.setWidth(std::min(option.rect.width(), result.width())); + } + return result; +} + diff --git a/src/modflagicondelegate.h b/src/modflagicondelegate.h index b64ca08f..cc652c06 100644 --- a/src/modflagicondelegate.h +++ b/src/modflagicondelegate.h @@ -7,6 +7,7 @@ class ModFlagIconDelegate : public IconDelegate { public: explicit ModFlagIconDelegate(QObject *parent = 0); + virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; private: virtual QList getIcons(const QModelIndex &index) const; virtual size_t getNumIcons(const QModelIndex &index) const; diff --git a/src/modinfo.cpp b/src/modinfo.cpp index b0351cf4..cb20567e 100644 --- a/src/modinfo.cpp +++ b/src/modinfo.cpp @@ -232,7 +232,7 @@ void ModInfo::updateIndices() QRegExp backupRegEx(".*backup[0-9]*$"); for (unsigned int i = 0; i < s_Collection.size(); ++i) { - QString modName = s_Collection[i]->name(); + QString modName = s_Collection[i]->internalName(); int modID = s_Collection[i]->getNexusID(); s_ModsByName[modName] = i; s_ModsByModID[modID].push_back(i); @@ -804,6 +804,28 @@ std::vector ModInfoRegular::getFlags() const } +std::vector ModInfoRegular::getContents() const +{ + std::vector result; + QDir dir(absolutePath()); + if (dir.entryList(QStringList() << "*.esp" << "*.esm").size() > 0) { + result.push_back(CONTENT_PLUGIN); + } + QString sePluginPath = ToQString(GameInfo::instance().getSEName()) + "/plugins"; + if (dir.exists("textures")) result.push_back(CONTENT_TEXTURE); + if (dir.exists("meshes")) result.push_back(CONTENT_MESH); + if (dir.exists("interface") + || dir.exists("menus")) result.push_back(CONTENT_INTERFACE); + if (dir.exists("music")) result.push_back(CONTENT_MUSIC); + if (dir.exists("sound")) result.push_back(CONTENT_SOUND); + if (dir.exists("scripts")) result.push_back(CONTENT_SCRIPT); + if (dir.exists(sePluginPath)) result.push_back(CONTENT_SKSE); + if (dir.exists("strings")) result.push_back(CONTENT_STRING); + if (dir.exists("SkyProc Patchers")) result.push_back(CONTENT_SKYPROC); + return result; +} + + int ModInfoRegular::getHighlight() const { return isValid() ? HIGHLIGHT_NONE: HIGHLIGHT_INVALID; @@ -959,6 +981,8 @@ QStringList ModInfoOverwrite::archives() const return result; } +const char ModInfoForeign::INT_IDENTIFIER[] = "__int__foreign"; + QString ModInfoForeign::name() const { return m_Name; diff --git a/src/modinfo.h b/src/modinfo.h index 0c144936..e2121828 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -68,6 +68,19 @@ public: FLAG_CONFLICT_REDUNDANT }; + enum EContent { + CONTENT_PLUGIN, + CONTENT_TEXTURE, + CONTENT_MESH, + CONTENT_INTERFACE, + CONTENT_MUSIC, + CONTENT_SOUND, + CONTENT_SCRIPT, + CONTENT_SKSE, + CONTENT_SKYPROC, + CONTENT_STRING + }; + enum EHighlight { HIGHLIGHT_NONE = 0, HIGHLIGHT_INVALID = 1, @@ -303,6 +316,13 @@ public: **/ virtual QString name() const = 0; + /** + * @brief getter for an internal name. This is usually the same as the regular name, but with special mod types it might be + * this is used to distinguish between mods that have the same visible name + * @return internal mod name + */ + virtual QString internalName() const { return name(); } + /** * @brief getter for the mod path * @@ -368,6 +388,11 @@ public: */ virtual std::vector getFlags() const = 0; + /** + * @return a list of content types contained in a mod + */ + virtual std::vector getContents() const { return std::vector(); } + /** * @brief test if the specified flag is set for this mod * @param flag the flag to test @@ -798,6 +823,8 @@ public: */ virtual std::vector getFlags() const; + virtual std::vector getContents() const; + /** * @return an indicator if and how this mod should be highlighted by the UI */ @@ -974,6 +1001,10 @@ class ModInfoForeign : public ModInfoWithConflictInfo friend class ModInfo; +public: + + static const char INT_IDENTIFIER[]; + public: virtual bool updateAvailable() const { return false; } @@ -994,6 +1025,7 @@ public: virtual void endorse(bool) {} virtual bool isEmpty() const { return false; } virtual QString name() const; + virtual QString internalName() const { return name() + INT_IDENTIFIER; } virtual QString notes() const { return ""; } virtual QDateTime creationTime() const; virtual QString absolutePath() const; diff --git a/src/modlist.cpp b/src/modlist.cpp index ff126faa..ca173b18 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -52,15 +52,23 @@ ModList::ModList(QObject *parent) : QAbstractItemModel(parent), m_Profile(NULL), m_Modified(false), m_FontMetrics(QFont()), m_DropOnItems(false) { + m_ContentIcons[ModInfo::CONTENT_PLUGIN] = std::make_tuple(QIcon(":/MO/gui/content/plugin"), ":/MO/gui/content/plugin", tr("Game plugins (esp/esm)")); + m_ContentIcons[ModInfo::CONTENT_INTERFACE] = std::make_tuple(QIcon(":/MO/gui/content/interface"), ":/MO/gui/content/interface", tr("Interface")); + m_ContentIcons[ModInfo::CONTENT_MESH] = std::make_tuple(QIcon(":/MO/gui/content/mesh"), ":/MO/gui/content/mesh", tr("Meshes")); + m_ContentIcons[ModInfo::CONTENT_MUSIC] = std::make_tuple(QIcon(":/MO/gui/content/music"), ":/MO/gui/content/music", tr("Music")); + m_ContentIcons[ModInfo::CONTENT_SCRIPT] = std::make_tuple(QIcon(":/MO/gui/content/script"), ":/MO/gui/content/script", tr("Scripts (Papyrus)")); + m_ContentIcons[ModInfo::CONTENT_SKSE] = std::make_tuple(QIcon(":/MO/gui/content/skse"), ":/MO/gui/content/skse", tr("Script Extender Plugin")); + m_ContentIcons[ModInfo::CONTENT_SKYPROC] = std::make_tuple(QIcon(":/MO/gui/content/skyproc"), ":/MO/gui/content/skyproc", tr("SkyProc Patcher")); + m_ContentIcons[ModInfo::CONTENT_SOUND] = std::make_tuple(QIcon(":/MO/gui/content/sound"), ":/MO/gui/content/sound", tr("Sound")); + m_ContentIcons[ModInfo::CONTENT_STRING] = std::make_tuple(QIcon(":/MO/gui/content/string"), ":/MO/gui/content/string", tr("Strings")); + m_ContentIcons[ModInfo::CONTENT_TEXTURE] = std::make_tuple(QIcon(":/MO/gui/content/texture"), ":/MO/gui/content/texture", tr("Textures")); } - void ModList::setProfile(Profile *profile) { m_Profile = profile; } - int ModList::rowCount(const QModelIndex &parent) const { if (!parent.isValid()) { @@ -70,7 +78,6 @@ int ModList::rowCount(const QModelIndex &parent) const } } - bool ModList::hasChildren(const QModelIndex &parent) const { if (!parent.isValid()) { @@ -129,6 +136,35 @@ QString ModList::getFlagText(ModInfo::EFlag flag, ModInfo::Ptr modInfo) const } +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(QIcon()); + } + } + 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("").arg(std::get<1>(iter->second)).arg(std::get<2>(iter->second))); + } + } + result.append("
%2
"); + return result; +} + + QVariant ModList::data(const QModelIndex &modelIndex, int role) const { if (m_Profile == NULL) return QVariant(); @@ -139,7 +175,8 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex); if ((role == Qt::DisplayRole) || (role == Qt::EditRole)) { - if (column == COL_FLAGS) { + if ((column == COL_FLAGS) + || (column == COL_CONTENT)) { return QVariant(); } else if (column == COL_NAME) { return modInfo->name(); @@ -252,6 +289,8 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const case COL_PRIORITY: return QtGroupingProxy::AGGR_MIN; default: return QtGroupingProxy::AGGR_NONE; } + } else if (role == Qt::UserRole + 3) { + return contentsToIcons(modInfo->getContents()); } else if (role == Qt::FontRole) { QFont result; if (column == COL_NAME) { @@ -313,6 +352,8 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const } return result; + } else if (column == COL_CONTENT) { + return contentsToToolTip(modInfo->getContents()); } else if (column == COL_NAME) { try { return modInfo->getDescription(); @@ -560,7 +601,6 @@ void ModList::changeModPriority(std::vector sourceIndices, int newPriority) break; } } - for (std::vector::const_iterator iter = sourceIndices.begin(); iter != sourceIndices.end(); ++iter) { int oldPriority = m_Profile->getModPriority(*iter); @@ -640,6 +680,17 @@ IModList::ModStates ModList::state(unsigned int modIndex) const return result; } +QString ModList::displayName(const QString &internalName) const +{ + unsigned int modIndex = ModInfo::getIndex(internalName); + if (modIndex == UINT_MAX) { + // might be better to throw an exception? + return internalName; + } else { + return ModInfo::getByIndex(modIndex)->name(); + } +} + IModList::ModStates ModList::state(const QString &name) const { unsigned int modIndex = ModInfo::getIndex(name); @@ -880,6 +931,7 @@ QString ModList::getColumnName(int column) { switch (column) { case COL_FLAGS: return tr("Flags"); + case COL_CONTENT: return tr("Content"); case COL_NAME: return tr("Mod Name"); case COL_VERSION: return tr("Version"); case COL_PRIORITY: return tr("Priority"); @@ -901,6 +953,18 @@ QString ModList::getColumnToolTip(int column) case COL_CATEGORY: return tr("Category of the mod."); case COL_MODID: return tr("Id of the mod as used on Nexus."); case COL_FLAGS: return tr("Emblemes to highlight things that might require attention."); + case COL_CONTENT: return tr("Depicts the content of the mod:
" + "Game plugins (esp/esm)
" + "interface
" + "Meshes
" + "Textures
" + "Sounds
" + "Music
" + "Strings
" + "Scripts (Papyrus)
" + "Script Extender plugins
" + "SkyProc Patcher
" + ); case COL_INSTALLTIME: return tr("Time this mod was installed"); default: return tr("unknown"); } diff --git a/src/modlist.h b/src/modlist.h index 2e8d6a84..6116a913 100644 --- a/src/modlist.h +++ b/src/modlist.h @@ -52,6 +52,7 @@ public: enum EColumn { COL_NAME, COL_FLAGS, + COL_CONTENT, COL_CATEGORY, COL_MODID, COL_VERSION, @@ -104,6 +105,9 @@ public: public: + /// \copydoc MOBase::IModList::displayName + virtual QString displayName(const QString &internalName) const; + /// \copydoc MOBase::IModList::state virtual ModStates state(const QString &name) const; @@ -234,6 +238,10 @@ private: static QString getColumnToolTip(int column); + QVariantList contentsToIcons(const std::vector &content) const; + + QString contentsToToolTip(const std::vector &contents) const; + ModList::EColumn getEnabledColumn(int index) const; QVariant categoryData(int categoryID, int column, int role) const; @@ -287,6 +295,8 @@ private: SignalModStateChanged m_ModStateChanged; SignalModMoved m_ModMoved; + std::map > m_ContentIcons; + }; #endif // MODLIST_H diff --git a/src/modlistsortproxy.cpp b/src/modlistsortproxy.cpp index 77702689..d790e277 100644 --- a/src/modlistsortproxy.cpp +++ b/src/modlistsortproxy.cpp @@ -159,6 +159,13 @@ bool ModListSortProxy::lessThan(const QModelIndex &left, if (leftMod->getFlags().size() != rightMod->getFlags().size()) lt = leftMod->getFlags().size() < rightMod->getFlags().size(); } break; + case ModList::COL_CONTENT: { + int lLen = leftMod->getContents().size(); + int rLen = rightMod->getContents().size(); + if (lLen != rLen) { + lt = lLen < rLen; + } + } break; case ModList::COL_NAME: { int comp = QString::compare(leftMod->name(), rightMod->name(), Qt::CaseInsensitive); if (comp != 0) diff --git a/src/pluginflagicondelegate.cpp b/src/pluginflagicondelegate.cpp index 761555d7..a4f66c04 100644 --- a/src/pluginflagicondelegate.cpp +++ b/src/pluginflagicondelegate.cpp @@ -3,24 +3,37 @@ #include -PluginFlagIconDelegate::PluginFlagIconDelegate(QObject *parent) +GenericIconDelegate::GenericIconDelegate(QObject *parent, int role, int logicalIndex, int compactSize) : IconDelegate(parent) + , m_Role(role) + , m_LogicalIndex(logicalIndex) + , m_CompactSize(compactSize) + , m_Compact(false) { } -QList PluginFlagIconDelegate::getIcons(const QModelIndex &index) const +void GenericIconDelegate::columnResized(int logicalIndex, int, int newSize) +{ + if (logicalIndex == m_LogicalIndex) { + m_Compact = newSize < m_CompactSize; + } +} + +QList GenericIconDelegate::getIcons(const QModelIndex &index) const { QList result; if (index.isValid()) { - foreach (const QVariant &var, index.data(Qt::UserRole + 1).toList()) { - result.append(var.value()); + foreach (const QVariant &var, index.data(m_Role).toList()) { + QIcon icon = var.value(); + if (!m_Compact || !icon.isNull()) { + result.append(icon); + } } } return result; } -size_t PluginFlagIconDelegate::getNumIcons(const QModelIndex &index) const +size_t GenericIconDelegate::getNumIcons(const QModelIndex &index) const { - return index.data(Qt::UserRole + 1).toList().count(); + return index.data(m_Role).toList().count(); } - diff --git a/src/pluginflagicondelegate.h b/src/pluginflagicondelegate.h index 554e968b..3c05db72 100644 --- a/src/pluginflagicondelegate.h +++ b/src/pluginflagicondelegate.h @@ -3,15 +3,34 @@ #include "icondelegate.h" -class PluginFlagIconDelegate : public IconDelegate +/** + * @brief an icon delegate that takes the list of icons from a user-defines data role + */ +class GenericIconDelegate : public IconDelegate { +Q_OBJECT public: - PluginFlagIconDelegate(QObject *parent = NULL); - - // IconDelegate interface + /** + * @brief constructor + * @param parent parent object + * @param role role of the itemmodel from which the icon list can be queried (as a QVariantList) + * @param logicalIndex logical index within the model. This is part of a "hack". Normally "empty" icons will be allocated the same + * space as a regular icon. This way the model can use empty icons as spacers and thus align same icons horizontally. + * Now, if you set the logical Index to a valid column and connect the columnResized slot to the sectionResized signal + * of the view, the delegate will turn off this behaviour if the column is smaller than "compactSize" + * @param compactSize see explanation of logicalIndex + */ + GenericIconDelegate(QObject *parent = NULL, int role = Qt::UserRole + 1, int logicalIndex = -1, int compactSize = 150); +public slots: + void columnResized(int logicalIndex, int oldSize, int newSize); private: virtual QList getIcons(const QModelIndex &index) const; virtual size_t getNumIcons(const QModelIndex &index) const; +private: + int m_Role; + int m_LogicalIndex; + int m_CompactSize; + bool m_Compact; }; #endif // PLUGINFLAGICONDELEGATE_H diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index 4794414a..5159871d 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -844,9 +844,6 @@ QVariant PluginList::data(const QModelIndex &modelIndex, int role) const if (!bossInfoIter->second.m_Messages.isEmpty()) { result.append(QIcon(":/MO/gui/information")); } - /*if (bossInfoIter->second.m_LOOTUnrecognized) { - result.append(QIcon(":/MO/gui/help")); - }*/ } if (m_ESPs[index].m_HasIni) { result.append(QIcon(":/MO/gui/attachment")); diff --git a/src/profile.cpp b/src/profile.cpp index fbfb3266..ca47d327 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -265,22 +265,23 @@ void Profile::refreshModStatus() modName = QString::fromUtf8(line.trimmed().constData()); } if (modName.size() > 0) { - if (namesRead.find(modName) != namesRead.end()) { + QString lookupName = modName + (line.at(0) == '*' ? ModInfoForeign::INT_IDENTIFIER : ""); + if (namesRead.find(lookupName) != namesRead.end()) { continue; } else { - namesRead.insert(modName); + namesRead.insert(lookupName); } - unsigned int modindex = ModInfo::getIndex(modName); - if (modindex != UINT_MAX) { - ModInfo::Ptr info = ModInfo::getByIndex(modindex); - if ((modindex < m_ModStatus.size()) + unsigned int modIndex = ModInfo::getIndex(lookupName); + if (modIndex != UINT_MAX) { + ModInfo::Ptr info = ModInfo::getByIndex(modIndex); + if ((modIndex < m_ModStatus.size()) && (info->getFixedPriority() == INT_MIN)) { - m_ModStatus[modindex].m_Enabled = enabled || info->alwaysEnabled(); - if (m_ModStatus[modindex].m_Priority == -1) { + m_ModStatus[modIndex].m_Enabled = enabled || info->alwaysEnabled(); + if (m_ModStatus[modIndex].m_Priority == -1) { if (static_cast(index) >= m_ModStatus.size()) { throw MyException(tr("invalid index %1").arg(index)); } - m_ModStatus[modindex].m_Priority = index++; + m_ModStatus[modIndex].m_Priority = index++; } } else { qDebug("mod \"%s\" (profile \"%s\") not found", @@ -381,7 +382,7 @@ std::vector > Profile::getActiveMods() iter != m_ModIndexByPriority.end(); ++iter) { if ((*iter != UINT_MAX) && m_ModStatus[*iter].m_Enabled) { ModInfo::Ptr modInfo = ModInfo::getByIndex(*iter); - result.push_back(std::make_tuple(modInfo->name(), modInfo->absolutePath(), m_ModStatus[*iter].m_Priority)); + result.push_back(std::make_tuple(modInfo->internalName(), modInfo->absolutePath(), m_ModStatus[*iter].m_Priority)); } } diff --git a/src/resources.qrc b/src/resources.qrc index 3287ad5d..20b0e3fe 100644 --- a/src/resources.qrc +++ b/src/resources.qrc @@ -66,4 +66,16 @@ resources/badge_9.png resources/badge_more.png + + resources/contents/jigsaw-piece.png + resources/contents/hand-of-god.png + resources/contents/empty-chessboard.png + resources/contents/double-quaver.png + resources/contents/lyre.png + resources/contents/usable.png + resources/contents/checkbox-tree.png + resources/contents/tinker.png + resources/contents/breastplate.png + resources/contents/conversation.png + diff --git a/src/resources/contents/breastplate.png b/src/resources/contents/breastplate.png new file mode 100644 index 00000000..e42d0888 Binary files /dev/null and b/src/resources/contents/breastplate.png differ diff --git a/src/resources/contents/checkbox-tree.png b/src/resources/contents/checkbox-tree.png new file mode 100644 index 00000000..ba6da286 Binary files /dev/null and b/src/resources/contents/checkbox-tree.png differ diff --git a/src/resources/contents/conversation.png b/src/resources/contents/conversation.png new file mode 100644 index 00000000..73e5980e Binary files /dev/null and b/src/resources/contents/conversation.png differ diff --git a/src/resources/contents/double-quaver.png b/src/resources/contents/double-quaver.png new file mode 100644 index 00000000..a7e06c72 Binary files /dev/null and b/src/resources/contents/double-quaver.png differ diff --git a/src/resources/contents/empty-chessboard.png b/src/resources/contents/empty-chessboard.png new file mode 100644 index 00000000..1ccbbd12 Binary files /dev/null and b/src/resources/contents/empty-chessboard.png differ diff --git a/src/resources/contents/hand-of-god.png b/src/resources/contents/hand-of-god.png new file mode 100644 index 00000000..9d55580e Binary files /dev/null and b/src/resources/contents/hand-of-god.png differ diff --git a/src/resources/contents/jigsaw-piece.png b/src/resources/contents/jigsaw-piece.png new file mode 100644 index 00000000..0f276ea0 Binary files /dev/null and b/src/resources/contents/jigsaw-piece.png differ diff --git a/src/resources/contents/lyre.png b/src/resources/contents/lyre.png new file mode 100644 index 00000000..1ee4765f Binary files /dev/null and b/src/resources/contents/lyre.png differ diff --git a/src/resources/contents/tinker.png b/src/resources/contents/tinker.png new file mode 100644 index 00000000..8ac7bfdd Binary files /dev/null and b/src/resources/contents/tinker.png differ diff --git a/src/resources/contents/usable.png b/src/resources/contents/usable.png new file mode 100644 index 00000000..dbbf6619 Binary files /dev/null and b/src/resources/contents/usable.png differ -- cgit v1.3.1