From f682f82db5d8ba514e927c9d7e88107348d5c32a Mon Sep 17 00:00:00 2001 From: Tannin Date: Fri, 29 Mar 2013 10:25:38 +0100 Subject: some improvements to the grouped modlist views --- src/mainwindow.cpp | 2 +- src/modlist.cpp | 23 ++- src/modlist.h | 424 ++++++++++++++++++++++++------------------------ src/qtgroupingproxy.cpp | 27 ++- src/qtgroupingproxy.h | 13 +- 5 files changed, 272 insertions(+), 217 deletions(-) (limited to 'src') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 37d041c0..43694c32 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -3969,7 +3969,7 @@ void MainWindow::on_groupCombo_currentIndexChanged(int index) QAbstractProxyModel *newModel = NULL; switch (index) { case 1: { - newModel = new QtGroupingProxy(m_ModListSortProxy, QModelIndex(), ModList::COL_CATEGORY); + newModel = new QtGroupingProxy(m_ModListSortProxy, QModelIndex(), ModList::COL_CATEGORY, Qt::UserRole); } break; case 2: { newModel = new QtGroupingProxy(m_ModListSortProxy, QModelIndex(), ModList::COL_MODID); diff --git a/src/modlist.cpp b/src/modlist.cpp index 9b99b488..06f468b1 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -197,7 +197,21 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const return QVariant(Qt::AlignCenter | Qt::AlignVCenter); } } else if (role == Qt::UserRole) { - return modInfo->getNexusID(); + if (column == COL_CATEGORY) { + QVariantList categoryNames; + std::set categories = modInfo->getCategories(); + CategoryFactory &categoryFactory = CategoryFactory::instance(); + for (auto iter = categories.begin(); iter != categories.end(); ++iter) { + categoryNames.append(categoryFactory.getCategoryName(categoryFactory.getCategoryIndex(*iter))); + } + if (categoryNames.count() != 0) { + return categoryNames; + } else { + return QVariant(); + } + } else { + return modInfo->getNexusID(); + } } else if (role == Qt::UserRole + 1) { return modIndex; } else if (role == Qt::FontRole) { @@ -590,6 +604,13 @@ QModelIndex ModList::parent(const QModelIndex&) const return QModelIndex(); } +QMap ModList::itemData(const QModelIndex &index) const +{ + QMap result = QAbstractItemModel::itemData(index); + result[Qt::UserRole] = data(index, Qt::UserRole); + return result; +} + QString ModList::getColumnName(int column) { diff --git a/src/modlist.h b/src/modlist.h index 7c37f4d5..86255bfb 100644 --- a/src/modlist.h +++ b/src/modlist.h @@ -17,214 +17,216 @@ You should have received a copy of the GNU General Public License along with Mod Organizer. If not, see . */ -#ifndef MODLIST_H -#define MODLIST_H - - -#include "categories.h" -#include "nexusinterface.h" -#include "modinfo.h" -#include "profile.h" - -#include -#include -#include -#include - -#include -#include -#include - - -/** - * Model presenting an overview of the installed mod - * 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 -{ - Q_OBJECT - -public: - - enum EColumn { - COL_NAME, - COL_FLAGS, - COL_CATEGORY, - COL_MODID, - COL_VERSION, - COL_PRIORITY, - - COL_LASTCOLUMN = COL_PRIORITY - }; - -public: - - /** - * @brief constructor - * @todo ensure this view works without a profile set, otherwise there are intransparent dependencies on the initialisation order - **/ - ModList(QObject *parent = NULL); - - /** - * @brief set the profile used for status information - * - * @param profile the profile to use - **/ - void setProfile(Profile *profile); - - /** - * @brief retrieve the current sorting mode - * @note this is used to store the sorting mode between sessions - * @return current sorting mode, encoded to be compatible to previous versions - **/ - int getCurrentSortingMode() const; - - /** - * @brief force a refresh of the mod list - **/ - void refresh(); - - /** - * @brief remove the specified mod without asking for confirmation - * @param row the row to remove - */ - void removeRowForce(int row); - - void notifyChange(int row); - - static QString getColumnName(int column); - - void changeModPriority(int sourceIndex, int newPriority); - -public: // implementation of virtual functions of QAbstractItemModel - - virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; - virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - virtual Qt::ItemFlags flags(const QModelIndex &modelIndex) const; - virtual Qt::DropActions supportedDropActions() const { return Qt::MoveAction; } - virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); - virtual void removeRow(int row, const QModelIndex &parent); - - - virtual QModelIndex index(int row, int column, - const QModelIndex &parent = QModelIndex()) const; - virtual QModelIndex parent(const QModelIndex &child) const; - -public slots: - -signals: - - /** - * @brief emitted whenever the sorting in the list was changed by the user - * - * the sorting of the list can only be manually changed if the list is sorted by priority - * in which case the move is intended to change the priority of a mod - **/ - void modorder_changed(); - - /** - * @brief emitted when the model wants a text to be displayed by the UI - * - * @param message the message to display - **/ - void showMessage(const QString &message); - - /** - * @brief signals change to the count of headers - */ - void resizeHeaders(); - - /** - * @brief requestColumnSelect is emitted whenever the user requested a menu to select visible columns - * @param pos the position to display the menu at - */ - void requestColumnSelect(QPoint pos); - - /** - * @brief emitted to remove a file origin - * @param name name of the orign to remove - */ - void removeOrigin(const QString &name); - - /** - * @brief emitted after a mod has been renamed - * This signal MUST be used to fix the mod names in profiles (except the active one) and to invalidate/refresh other - * structures that may have become invalid with the rename - * - * @param oldName the old name of the mod - * @param newName new name of the mod - */ - void modRenamed(const QString &oldName, const QString &newName); - - /** - * @brief emitted whenever a row in the list has changed - * - * @param row the row that changed - * @note this signal must only be emitted if the row really did change. - * Slots handling this signal therefore do not have to verify that a change has happened - * @note this signal is currently only used in tutorials - **/ - void modlist_changed(int row); - - /** - * @brief emitted to have all selected mods deleted - */ - void removeSelectedMods(); - -protected: - - // event filter, handles event from the header and the tree view itself - bool eventFilter(QObject *obj, QEvent *event); - -private: - - bool testValid(const QString &modDir); - - void changeModPriority(std::vector sourceIndices, int newPriority); - - QVariant getOverwriteData(int column, int role) const; - - QString getFlagText(ModInfo::EFlag flag, ModInfo::Ptr modInfo) const; - - static QString getColumnToolTip(int column); - - ModList::EColumn getEnabledColumn(int index) const; - - QVariant categoryData(int categoryID, int column, int role) const; - QVariant modData(int modID, int modelColumn, int role) const; - - bool renameMod(int index, const QString &newName); - -private slots: - -private: - - struct TModInfo { - TModInfo(unsigned int index, ModInfo::Ptr modInfo) - : modInfo(modInfo), nameOrder(index) {} - ModInfo::Ptr modInfo; - unsigned int nameOrder; - unsigned int priorityOrder; - unsigned int modIDOrder; - unsigned int categoryOrder; - }; - -private: - - Profile *m_Profile; - - NexusInterface *m_NexusInterface; - std::set m_RequestIDs; - - mutable bool m_Modified; - - QFontMetrics m_FontMetrics; - -}; - -#endif // MODLIST_H - +#ifndef MODLIST_H +#define MODLIST_H + + +#include "categories.h" +#include "nexusinterface.h" +#include "modinfo.h" +#include "profile.h" + +#include +#include +#include +#include + +#include +#include +#include + + +/** + * Model presenting an overview of the installed mod + * 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 +{ + Q_OBJECT + +public: + + enum EColumn { + COL_NAME, + COL_FLAGS, + COL_CATEGORY, + COL_MODID, + COL_VERSION, + COL_PRIORITY, + + COL_LASTCOLUMN = COL_PRIORITY + }; + +public: + + /** + * @brief constructor + * @todo ensure this view works without a profile set, otherwise there are intransparent dependencies on the initialisation order + **/ + ModList(QObject *parent = NULL); + + /** + * @brief set the profile used for status information + * + * @param profile the profile to use + **/ + void setProfile(Profile *profile); + + /** + * @brief retrieve the current sorting mode + * @note this is used to store the sorting mode between sessions + * @return current sorting mode, encoded to be compatible to previous versions + **/ + int getCurrentSortingMode() const; + + /** + * @brief force a refresh of the mod list + **/ + void refresh(); + + /** + * @brief remove the specified mod without asking for confirmation + * @param row the row to remove + */ + void removeRowForce(int row); + + void notifyChange(int row); + + static QString getColumnName(int column); + + void changeModPriority(int sourceIndex, int newPriority); + +public: // implementation of virtual functions of QAbstractItemModel + + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; + virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + virtual Qt::ItemFlags flags(const QModelIndex &modelIndex) const; + virtual Qt::DropActions supportedDropActions() const { return Qt::MoveAction; } + virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); + virtual void removeRow(int row, const QModelIndex &parent); + + + virtual QModelIndex index(int row, int column, + const QModelIndex &parent = QModelIndex()) const; + virtual QModelIndex parent(const QModelIndex &child) const; + + virtual QMap itemData(const QModelIndex &index) const; + +public slots: + +signals: + + /** + * @brief emitted whenever the sorting in the list was changed by the user + * + * the sorting of the list can only be manually changed if the list is sorted by priority + * in which case the move is intended to change the priority of a mod + **/ + void modorder_changed(); + + /** + * @brief emitted when the model wants a text to be displayed by the UI + * + * @param message the message to display + **/ + void showMessage(const QString &message); + + /** + * @brief signals change to the count of headers + */ + void resizeHeaders(); + + /** + * @brief requestColumnSelect is emitted whenever the user requested a menu to select visible columns + * @param pos the position to display the menu at + */ + void requestColumnSelect(QPoint pos); + + /** + * @brief emitted to remove a file origin + * @param name name of the orign to remove + */ + void removeOrigin(const QString &name); + + /** + * @brief emitted after a mod has been renamed + * This signal MUST be used to fix the mod names in profiles (except the active one) and to invalidate/refresh other + * structures that may have become invalid with the rename + * + * @param oldName the old name of the mod + * @param newName new name of the mod + */ + void modRenamed(const QString &oldName, const QString &newName); + + /** + * @brief emitted whenever a row in the list has changed + * + * @param row the row that changed + * @note this signal must only be emitted if the row really did change. + * Slots handling this signal therefore do not have to verify that a change has happened + * @note this signal is currently only used in tutorials + **/ + void modlist_changed(int row); + + /** + * @brief emitted to have all selected mods deleted + */ + void removeSelectedMods(); + +protected: + + // event filter, handles event from the header and the tree view itself + bool eventFilter(QObject *obj, QEvent *event); + +private: + + bool testValid(const QString &modDir); + + void changeModPriority(std::vector sourceIndices, int newPriority); + + QVariant getOverwriteData(int column, int role) const; + + QString getFlagText(ModInfo::EFlag flag, ModInfo::Ptr modInfo) const; + + static QString getColumnToolTip(int column); + + ModList::EColumn getEnabledColumn(int index) const; + + QVariant categoryData(int categoryID, int column, int role) const; + QVariant modData(int modID, int modelColumn, int role) const; + + bool renameMod(int index, const QString &newName); + +private slots: + +private: + + struct TModInfo { + TModInfo(unsigned int index, ModInfo::Ptr modInfo) + : modInfo(modInfo), nameOrder(index) {} + ModInfo::Ptr modInfo; + unsigned int nameOrder; + unsigned int priorityOrder; + unsigned int modIDOrder; + unsigned int categoryOrder; + }; + +private: + + Profile *m_Profile; + + NexusInterface *m_NexusInterface; + std::set m_RequestIDs; + + mutable bool m_Modified; + + QFontMetrics m_FontMetrics; + +}; + +#endif // MODLIST_H + diff --git a/src/qtgroupingproxy.cpp b/src/qtgroupingproxy.cpp index 5c1e0275..95a4aad0 100644 --- a/src/qtgroupingproxy.cpp +++ b/src/qtgroupingproxy.cpp @@ -14,6 +14,9 @@ * this program. If not, see . * ****************************************************************************************/ +// Modifications 2013-03-27 to 2013-03-28 by Sebastian Herbord + + #include "QtGroupingProxy.h" #include @@ -28,10 +31,12 @@ \ingroup model-view */ -QtGroupingProxy::QtGroupingProxy( QAbstractItemModel *model, QModelIndex rootNode, int groupedColumn ) +QtGroupingProxy::QtGroupingProxy(QAbstractItemModel *model, QModelIndex rootNode, int groupedColumn, Qt::ItemDataRole groupedRole, unsigned int flags ) : QAbstractProxyModel() , m_rootNode( rootNode ) , m_groupedColumn( 0 ) + , m_groupedRole( groupedRole ) + , m_flags( flags ) { setSourceModel( model ); @@ -84,14 +89,23 @@ QtGroupingProxy::belongsTo( const QModelIndex &idx ) //get all the data for this index from the model ItemData itemData = sourceModel()->itemData( idx ); + if (m_groupedRole != Qt::DisplayRole) { + itemData[Qt::DisplayRole] = itemData[m_groupedRole]; + } + + // invalid value in grouped role -> ungrouped + if (!itemData[Qt::DisplayRole].isValid()) { + return rowDataList; + } + QMapIterator i( itemData ); while( i.hasNext() ) { i.next(); int role = i.key(); QVariant variant = i.value(); - // qDebug() << "role " << role << " : (" << variant.typeName() << ") : "<< variant; - if( variant.type() == QVariant::List ) + qDebug() << "role " << role << " : (" << variant.typeName() << ") : "<< variant; + if ( variant.type() == QVariant::List ) { //a list of variants get's expanded to multiple rows QVariantList list = variant.toList(); @@ -111,6 +125,7 @@ QtGroupingProxy::belongsTo( const QModelIndex &idx ) rowData.insert( m_groupedColumn, indexData ); rowDataList.insert( i, rowData ); } + break; } else if( !variant.isNull() ) { @@ -155,8 +170,13 @@ QtGroupingProxy::buildTree() } //dumpGroups(); + if (m_flags & FLAG_NOSINGLE) { + + } + endResetModel(); + // restore expand-state for( int row = 0; row < rowCount(); row++ ) { QModelIndex idx = index( row, 0, QModelIndex() ); if (m_expandedItems.contains(idx.data(Qt::UserRole).toString())) { @@ -326,6 +346,7 @@ QtGroupingProxy::rowCount( const QModelIndex &index ) const if( !index.isValid() ) { //the number of top level groups + the number of non-grouped items + qDebug("groups: %d - ungrouped: %d", m_groupMaps.count(), m_groupHash.value(std::numeric_limits::max()).count()); int rows = m_groupMaps.count() + m_groupHash.value( std::numeric_limits::max() ).count(); //qDebug() << rows << " in root group"; return rows; diff --git a/src/qtgroupingproxy.h b/src/qtgroupingproxy.h index 6ec34481..a7f151ce 100644 --- a/src/qtgroupingproxy.h +++ b/src/qtgroupingproxy.h @@ -14,6 +14,8 @@ * this program. If not, see . * ****************************************************************************************/ +// Modifications 2013-03-27 to 2013-03-28 by Sebastian Herbord + #ifndef GROUPINGPROXY_H #define GROUPINGPROXY_H @@ -30,9 +32,16 @@ typedef QMap RowData; class QtGroupingProxy : public QAbstractProxyModel { Q_OBJECT + +public: + + static const unsigned int FLAG_NOSINGLE = 1; + static const unsigned int FLAG_NAMETOPITEM = 2; + public: explicit QtGroupingProxy( QAbstractItemModel *model, QModelIndex rootNode = QModelIndex(), - int groupedColumn = -1 ); + int groupedColumn = -1, Qt::ItemDataRole groupedRole = Qt::DisplayRole, + unsigned int flags = 0); ~QtGroupingProxy(); void setGroupedColumn( int groupedColumn ); @@ -139,6 +148,8 @@ protected: private: QSet m_expandedItems; + unsigned int m_flags; + int m_groupedRole; }; #endif //GROUPINGPROXY_H -- cgit v1.3.1