From 8de7b79a2b211805a4ba348e490a7ab8eac15eef Mon Sep 17 00:00:00 2001 From: Mikaƫl Capelle Date: Sat, 2 Jan 2021 20:26:39 +0100 Subject: Move markers management for overwrite/overwritten to ModListView. --- src/modelutils.cpp | 34 ---------- src/modelutils.h | 5 -- src/modlist.cpp | 51 +-------------- src/modlist.h | 11 ---- src/modlistbypriorityproxy.cpp | 46 -------------- src/modlistbypriorityproxy.h | 1 - src/modlistview.cpp | 140 +++++++++++++++++++++++++++++++++++++---- src/modlistview.h | 27 +++++++- src/viewmarkingscrollbar.cpp | 22 +++---- src/viewmarkingscrollbar.h | 4 ++ 10 files changed, 168 insertions(+), 173 deletions(-) (limited to 'src') diff --git a/src/modelutils.cpp b/src/modelutils.cpp index 7b54d258..83054806 100644 --- a/src/modelutils.cpp +++ b/src/modelutils.cpp @@ -90,38 +90,4 @@ QModelIndexList indexViewToModel(const QModelIndexList& index, const QAbstractIt return result; } -QColor childrenColor(const QModelIndex& index, QTreeView* view, int role) -{ - auto* model = view->model(); - auto rowIndex = index.sibling(index.row(), 0); - - if (model->hasChildren(rowIndex) && !view->isExpanded(rowIndex)) { - - // this is a non-expanded item - std::vector colors; - for (int i = 0; i < model->rowCount(rowIndex); ++i) { - auto childData = model->data(model->index(i, index.column(), rowIndex), role); - if (childData.isValid() && childData.canConvert()) { - colors.push_back(childData.value()); - } - } - - if (colors.empty()) { - return QColor(); - } - - int r = 0, g = 0, b = 0, a = 0; - for (auto& color : colors) { - r += color.red(); - g += color.green(); - b += color.blue(); - a += color.alpha(); - } - - return QColor(r / colors.size(), g / colors.size(), b / colors.size(), a / colors.size()); - } - - return QColor(); -} - } diff --git a/src/modelutils.h b/src/modelutils.h index cb7c9394..e6510941 100644 --- a/src/modelutils.h +++ b/src/modelutils.h @@ -20,11 +20,6 @@ QModelIndexList indexModelToView(const QModelIndexList& index, const QAbstractIt QModelIndex indexViewToModel(const QModelIndex& index, const QAbstractItemModel* model); QModelIndexList indexViewToModel(const QModelIndexList& index, const QAbstractItemModel* model); -// retrieve the color of the children of the given index for the given, or an invalid -// color if the item is expanded or the children do not have colors for the given role -// -QColor childrenColor(const QModelIndex& index, QTreeView* view, int role); - } #endif diff --git a/src/modlist.cpp b/src/modlist.cpp index a2e59b62..155a094f 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -464,33 +464,11 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const return QVariant(); } else if (role == Qt::BackgroundRole || role == ScrollMarkRole) { - bool overwrite = m_Overwrite.find(modIndex) != m_Overwrite.end(); - bool archiveOverwrite = m_ArchiveOverwrite.find(modIndex) != m_ArchiveOverwrite.end(); - bool archiveLooseOverwrite = m_ArchiveLooseOverwrite.find(modIndex) != m_ArchiveLooseOverwrite.end(); - bool overwritten = m_Overwritten.find(modIndex) != m_Overwritten.end(); - bool archiveOverwritten = m_ArchiveOverwritten.find(modIndex) != m_ArchiveOverwritten.end(); - bool archiveLooseOverwritten = m_ArchiveLooseOverwritten.find(modIndex) != m_ArchiveLooseOverwritten.end(); if (column == COL_NOTES && modInfo->color().isValid()) { return modInfo->color(); } - else if (modInfo->getHighlight() & ModInfo::HIGHLIGHT_PLUGIN) { - return Settings::instance().colors().modlistContainsPlugin(); - } - else if (overwritten || archiveLooseOverwritten) { - return Settings::instance().colors().modlistOverwritingLoose(); - } - else if (overwrite || archiveLooseOverwrite) { - return Settings::instance().colors().modlistOverwrittenLoose(); - } - else if (archiveOverwritten) { - return Settings::instance().colors().modlistOverwritingArchive(); - } - else if (archiveOverwrite) { - return Settings::instance().colors().modlistOverwrittenArchive(); - } else if (modInfo->isSeparator() && modInfo->color().isValid() - && (role != ScrollMarkRole - || Settings::instance().colors().colorSeparatorScrollbar())) { + && (role != ScrollMarkRole || Settings::instance().colors().colorSeparatorScrollbar())) { return modInfo->color(); } else { @@ -851,27 +829,6 @@ void ModList::changeModPriority(int sourceIndex, int newPriority) emit modPrioritiesChanged({ index(sourceIndex, 0) }); } -void ModList::setOverwriteMarkers(const std::set &overwrite, const std::set &overwritten) -{ - m_Overwrite = overwrite; - m_Overwritten = overwritten; - notifyChange(0, rowCount() - 1); -} - -void ModList::setArchiveOverwriteMarkers(const std::set &overwrite, const std::set &overwritten) -{ - m_ArchiveOverwrite = overwrite; - m_ArchiveOverwritten = overwritten; - notifyChange(0, rowCount() - 1); -} - -void ModList::setArchiveLooseOverwriteMarkers(const std::set &overwrite, const std::set &overwritten) -{ - m_ArchiveLooseOverwrite = overwrite; - m_ArchiveLooseOverwritten = overwritten; - notifyChange(0, rowCount() - 1); -} - void ModList::setPluginContainer(PluginContainer *pluginContianer) { m_PluginContainer = pluginContianer; @@ -1393,12 +1350,6 @@ void ModList::notifyChange(int rowStart, int rowEnd) Guard g([&]{ m_InNotifyChange = false; }); if (rowStart < 0) { - m_Overwrite.clear(); - m_Overwritten.clear(); - m_ArchiveOverwrite.clear(); - m_ArchiveOverwritten.clear(); - m_ArchiveLooseOverwrite.clear(); - m_ArchiveLooseOverwritten.clear(); beginResetModel(); endResetModel(); } else { diff --git a/src/modlist.h b/src/modlist.h index 22703923..afbef7af 100644 --- a/src/modlist.h +++ b/src/modlist.h @@ -142,12 +142,8 @@ public: void changeModPriority(int sourceIndex, int newPriority); void changeModPriority(std::vector sourceIndices, int newPriority); - void setOverwriteMarkers(const std::set &overwrite, const std::set &overwritten); void setPluginContainer(PluginContainer *pluginContainer); - void setArchiveOverwriteMarkers(const std::set &overwrite, const std::set &overwritten); - void setArchiveLooseOverwriteMarkers(const std::set &overwrite, const std::set &overwritten); - bool modInfoAboutToChange(ModInfo::Ptr info); void modInfoChanged(ModInfo::Ptr info); @@ -420,13 +416,6 @@ private: QFontMetrics m_FontMetrics; - std::set m_Overwrite; - std::set m_Overwritten; - std::set m_ArchiveOverwrite; - std::set m_ArchiveOverwritten; - std::set m_ArchiveLooseOverwrite; - std::set m_ArchiveLooseOverwritten; - TModInfoChange m_ChangeInfo; SignalModInstalled m_ModInstalled; diff --git a/src/modlistbypriorityproxy.cpp b/src/modlistbypriorityproxy.cpp index 7ef540b0..749991d0 100644 --- a/src/modlistbypriorityproxy.cpp +++ b/src/modlistbypriorityproxy.cpp @@ -181,52 +181,6 @@ bool ModListByPriorityProxy::hasChildren(const QModelIndex& parent) const return item->children.size() > 0; } -QVariant ModListByPriorityProxy::data(const QModelIndex& index, int role) const -{ - auto sourceIndex = mapToSource(index); - if (!sourceIndex.isValid()) { - return QVariant(); - } - - auto sourceData = sourceModel()->data(sourceIndex, role); - if (role != Qt::BackgroundRole && role != ModList::ScrollMarkRole) { - return sourceData; - } - - if (!hasChildren(index)) { - return sourceData; - } - - bool expanded = !m_CollapsedItems.contains(index.sibling(index.row(), 0).data(Qt::DisplayRole).toString()); - - if (expanded) { - return sourceData; - } - - // this is a non-expanded item - std::vector colors; - for (int i = 0; i < rowCount(index); ++i) { - auto childData = sourceModel()->data(mapToSource(this->index(i, index.column(), index)), role); - if (childData.isValid() && childData.canConvert()) { - colors.push_back(childData.value()); - } - } - - if (true || colors.empty()) { - return sourceData; - } - - int r = 0, g = 0, b = 0, a = 0; - for (auto& color : colors) { - r += color.red(); - g += color.green(); - b += color.blue(); - a += color.alpha(); - } - - return QColor(r / colors.size(), g / colors.size(), b / colors.size(), a / colors.size()); -} - bool ModListByPriorityProxy::setData(const QModelIndex& index, const QVariant& value, int role) { // only care about the "name" column diff --git a/src/modlistbypriorityproxy.h b/src/modlistbypriorityproxy.h index 5149b7a2..e5a8adff 100644 --- a/src/modlistbypriorityproxy.h +++ b/src/modlistbypriorityproxy.h @@ -37,7 +37,6 @@ public: int columnCount(const QModelIndex& index) const override; bool hasChildren(const QModelIndex& parent) const override; - QVariant data(const QModelIndex& index, int role) const override; bool setData(const QModelIndex& index, const QVariant& value, int role) override; bool canDropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) const override; bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) override; diff --git a/src/modlistview.cpp b/src/modlistview.cpp index a460e4a4..f7db64e6 100644 --- a/src/modlistview.cpp +++ b/src/modlistview.cpp @@ -75,7 +75,7 @@ public: // compute required color from children, otherwise fallback to the // color from the model, and draw the background here - auto color = childrenColor(index, m_view, Qt::BackgroundRole); + auto color = m_view->markerColor(index); if (!color.isValid()) { color = index.data(Qt::BackgroundRole).value(); } @@ -98,6 +98,24 @@ public: } }; +class ModListViewMarkingScrollBar : public ViewMarkingScrollBar { + ModListView* m_view; +public: + ModListViewMarkingScrollBar(ModListView* view) : + ViewMarkingScrollBar(view, ModList::ScrollMarkRole), m_view(view) { } + + + QColor color(const QModelIndex& index) const override + { + auto color = m_view->markerColor(index); + if (!color.isValid()) { + color = ViewMarkingScrollBar::color(index); + } + return color; + } + +}; + ModListView::ModListView(QWidget* parent) : QTreeView(parent) , m_core(nullptr) @@ -105,7 +123,8 @@ ModListView::ModListView(QWidget* parent) , m_byPriorityProxy(nullptr) , m_byCategoryProxy(nullptr) , m_byNexusIdProxy(nullptr) - , m_scrollbar(new ViewMarkingScrollBar(this, ModList::ScrollMarkRole)) + , m_overwrite{ {}, {}, {}, {}, {}, {} } + , m_scrollbar(new ModListViewMarkingScrollBar(this)) { setVerticalScrollBar(m_scrollbar); MOBase::setCustomizableColumns(this); @@ -386,10 +405,7 @@ void ModListView::onModPrioritiesChanged(const QModelIndexList& indices) } // update conflict check on the moved mod modInfo->doConflictCheck(); - m_core->modList()->setOverwriteMarkers(modInfo->getModOverwrite(), modInfo->getModOverwritten()); - m_core->modList()->setArchiveOverwriteMarkers(modInfo->getModArchiveOverwrite(), modInfo->getModArchiveOverwritten()); - m_core->modList()->setArchiveLooseOverwriteMarkers(modInfo->getModArchiveLooseOverwrite(), modInfo->getModArchiveLooseOverwritten()); - verticalScrollBar()->repaint(); + setOverwriteMarkers(modInfo); } } } @@ -681,6 +697,7 @@ void ModListView::setup(OrganizerCore& core, CategoryFactory& factory, MainWindo connect(core.modList(), &ModList::modPrioritiesChanged, [=](auto&& indices) { onModPrioritiesChanged(indices); }); connect(core.modList(), &ModList::clearOverwrite, [=] { m_actions->clearOverwrite(); }); connect(core.modList(), &ModList::modStatesChanged, [=] { updateModCount(); }); + connect(core.modList(), &ModList::modelReset, [=] { clearOverwriteMarkers(); }); m_byPriorityProxy = new ModListByPriorityProxy(core.currentProfile(), core, this); m_byPriorityProxy->setSourceModel(core.modList()); @@ -935,6 +952,108 @@ void ModListView::onDoubleClicked(const QModelIndex& index) closePersistentEditor(index); } +void ModListView::clearOverwriteMarkers() +{ + m_overwrite.overwrite.clear(); + m_overwrite.overwritten.clear(); + m_overwrite.archiveOverwrite.clear(); + m_overwrite.archiveOverwritten.clear(); + m_overwrite.archiveLooseOverwrite.clear(); + m_overwrite.archiveLooseOverwritten.clear(); +} + +void ModListView::setOverwriteMarkers(const std::set& overwrite, const std::set& overwritten) +{ + m_overwrite.overwrite = overwrite; + m_overwrite.overwritten = overwritten; +} + +void ModListView::setArchiveOverwriteMarkers(const std::set& overwrite, const std::set& overwritten) +{ + m_overwrite.archiveOverwrite = overwrite; + m_overwrite.archiveOverwritten = overwritten; +} + +void ModListView::setArchiveLooseOverwriteMarkers(const std::set& overwrite, const std::set& overwritten) +{ + m_overwrite.archiveLooseOverwrite = overwrite; + m_overwrite.archiveLooseOverwritten = overwritten; +} + +void ModListView::setOverwriteMarkers(ModInfo::Ptr mod) +{ + if (mod) { + setOverwriteMarkers(mod->getModOverwrite(), mod->getModOverwritten()); + setArchiveOverwriteMarkers(mod->getModArchiveOverwrite(), mod->getModArchiveOverwritten()); + setArchiveLooseOverwriteMarkers(mod->getModArchiveLooseOverwrite(), mod->getModArchiveLooseOverwritten()); + } + else { + setOverwriteMarkers({}, {}); + setArchiveOverwriteMarkers({}, {}); + setArchiveLooseOverwriteMarkers({}, {}); + } + dataChanged(model()->index(0, 0), model()->index(model()->rowCount(), model()->columnCount())); + verticalScrollBar()->repaint(); +} + +QColor ModListView::markerColor(const QModelIndex& index) const +{ + unsigned int modIndex = index.data(ModList::IndexRole).toInt(); + ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex); + bool overwrite = m_overwrite.overwrite.find(modIndex) != m_overwrite.overwrite.end(); + bool archiveOverwrite = m_overwrite.archiveOverwrite.find(modIndex) != m_overwrite.archiveOverwrite.end(); + bool archiveLooseOverwrite = m_overwrite.archiveOverwritten.find(modIndex) != m_overwrite.archiveOverwritten.end(); + bool overwritten = m_overwrite.overwritten.find(modIndex) != m_overwrite.overwritten.end(); + bool archiveOverwritten = m_overwrite.archiveOverwritten.find(modIndex) != m_overwrite.archiveOverwritten.end(); + bool archiveLooseOverwritten = m_overwrite.archiveLooseOverwritten.find(modIndex) != m_overwrite.archiveLooseOverwritten.end(); + + // TODO: Move this here + if (modInfo->getHighlight() & ModInfo::HIGHLIGHT_PLUGIN) { + return Settings::instance().colors().modlistContainsPlugin(); + } + else if (overwritten || archiveLooseOverwritten) { + return Settings::instance().colors().modlistOverwritingLoose(); + } + else if (overwrite || archiveLooseOverwrite) { + return Settings::instance().colors().modlistOverwrittenLoose(); + } + else if (archiveOverwritten) { + return Settings::instance().colors().modlistOverwritingArchive(); + } + else if (archiveOverwrite) { + return Settings::instance().colors().modlistOverwrittenArchive(); + } + + // collapsed separator + auto rowIndex = index.sibling(index.row(), 0); + if (hasCollapsibleSeparators() && model()->hasChildren(rowIndex) && !isExpanded(rowIndex)) { + + std::vector colors; + for (int i = 0; i < model()->rowCount(rowIndex); ++i) { + auto childColor = markerColor(model()->index(i, index.column(), rowIndex)); + if (childColor.isValid()) { + colors.push_back(childColor); + } + } + + if (colors.empty()) { + return QColor(); + } + + int r = 0, g = 0, b = 0, a = 0; + for (auto& color : colors) { + r += color.red(); + g += color.green(); + b += color.blue(); + a += color.alpha(); + } + + return QColor(r / colors.size(), g / colors.size(), b / colors.size(), a / colors.size()); + } + + return QColor(); +} + void ModListView::onSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected) { if (hasCollapsibleSeparators()) { @@ -948,16 +1067,11 @@ void ModListView::onSelectionChanged(const QItemSelection& selected, const QItem if (selected.count()) { auto index = selected.indexes().last(); ModInfo::Ptr selectedMod = ModInfo::getByIndex(index.data(ModList::IndexRole).toInt()); - m_core->modList()->setOverwriteMarkers(selectedMod->getModOverwrite(), selectedMod->getModOverwritten()); - m_core->modList()->setArchiveOverwriteMarkers(selectedMod->getModArchiveOverwrite(), selectedMod->getModArchiveOverwritten()); - m_core->modList()->setArchiveLooseOverwriteMarkers(selectedMod->getModArchiveLooseOverwrite(), selectedMod->getModArchiveLooseOverwritten()); + setOverwriteMarkers(selectedMod); } else { - m_core->modList()->setOverwriteMarkers({}, {}); - m_core->modList()->setArchiveOverwriteMarkers({}, {}); - m_core->modList()->setArchiveLooseOverwriteMarkers({}, {}); + setOverwriteMarkers(nullptr); } - verticalScrollBar()->repaint(); } diff --git a/src/modlistview.h b/src/modlistview.h index d67f2940..bf705573 100644 --- a/src/modlistview.h +++ b/src/modlistview.h @@ -166,10 +166,27 @@ protected slots: private: + friend class ModListStyledItemDelegated; + friend class ModListViewMarkingScrollBar; + void onModPrioritiesChanged(const QModelIndexList& indices); void onModInstalled(const QString& modName); void onModFilterActive(bool filterActive); + // overwrite markers + void clearOverwriteMarkers(); + void setOverwriteMarkers(const std::set& overwrite, const std::set& overwritten); + void setArchiveOverwriteMarkers(const std::set& overwrite, const std::set& overwritten); + void setArchiveLooseOverwriteMarkers(const std::set& overwrite, const std::set& overwritten); + + // set overwrite markers from the mod and repaint (if mod is nullptr, clear overwrite and repaint) + // + void setOverwriteMarkers(ModInfo::Ptr mod); + + // retrieve the marker color for the given index + // + QColor markerColor(const QModelIndex& index) const; + // get/set the selected items on the view, this method return/take indices // from the mod list model, not the view, so it's safe to restore // @@ -219,10 +236,18 @@ private: ModListSortProxy* m_sortProxy; ModListByPriorityProxy* m_byPriorityProxy; - QtGroupingProxy* m_byCategoryProxy; QtGroupingProxy* m_byNexusIdProxy; + struct OverwriteInfo { + std::set overwrite; + std::set overwritten; + std::set archiveOverwrite; + std::set archiveOverwritten; + std::set archiveLooseOverwrite; + std::set archiveLooseOverwritten; + } m_overwrite; + ViewMarkingScrollBar* m_scrollbar; bool m_inDragMoveEvent = false; diff --git a/src/viewmarkingscrollbar.cpp b/src/viewmarkingscrollbar.cpp index fb165922..56754237 100644 --- a/src/viewmarkingscrollbar.cpp +++ b/src/viewmarkingscrollbar.cpp @@ -15,6 +15,15 @@ ViewMarkingScrollBar::ViewMarkingScrollBar(QTreeView* view, int role) Q_ASSERT(this->orientation() == Qt::Vertical); } +QColor ViewMarkingScrollBar::color(const QModelIndex& index) const +{ + auto data = index.data(m_role); + if (data.canConvert()) { + return data.value(); + } + return QColor(); +} + void ViewMarkingScrollBar::paintEvent(QPaintEvent* event) { if (m_view->model() == nullptr) { @@ -36,18 +45,7 @@ void ViewMarkingScrollBar::paintEvent(QPaintEvent* event) qreal scale = static_cast(innerRect.height() - 3) / static_cast(indices.size()); for (int i = 0; i < indices.size(); ++i) { - QVariant data = indices[i].data(m_role); - QColor color; - - if (data.canConvert()) { - color = data.value(); - } - - auto childrenColor = MOShared::childrenColor(indices[i], m_view, m_role); - if (childrenColor.isValid()) { - color = childrenColor; - } - + QColor color = this->color(indices[i]); if (color.isValid()) { painter.setPen(color); painter.setBrush(color); diff --git a/src/viewmarkingscrollbar.h b/src/viewmarkingscrollbar.h index 6947a018..01b5a8c0 100644 --- a/src/viewmarkingscrollbar.h +++ b/src/viewmarkingscrollbar.h @@ -13,6 +13,10 @@ public: protected: void paintEvent(QPaintEvent *event) override; + // retrieve the color of the marker for the given index + // + virtual QColor color(const QModelIndex& index) const; + private: QTreeView* m_view; int m_role; -- cgit v1.3.1