diff options
| author | Mikaël Capelle <capelle.mikael@gmail.com> | 2020-12-31 21:24:29 +0100 |
|---|---|---|
| committer | Mikaël Capelle <capelle.mikael@gmail.com> | 2021-01-02 15:38:18 +0100 |
| commit | 25a2123e5ffe66715d0a1ec09297ee91a9fcbe1c (patch) | |
| tree | b13f943d76833b1c331d63397cf6ed553eeb27c0 /src | |
| parent | f2d8469ed6cd0fafc22097cdba2ee8f325f00513 (diff) | |
Move keyboard event to PluginListView.
Diffstat (limited to 'src')
| -rw-r--r-- | src/mainwindow.cpp | 9 | ||||
| -rw-r--r-- | src/pluginlist.cpp | 145 | ||||
| -rw-r--r-- | src/pluginlist.h | 17 | ||||
| -rw-r--r-- | src/pluginlistview.cpp | 60 | ||||
| -rw-r--r-- | src/pluginlistview.h | 15 |
5 files changed, 141 insertions, 105 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 60e2a1e0..38417df5 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2868,12 +2868,14 @@ void MainWindow::disableSelectedPlugins_clicked() void MainWindow::sendSelectedPluginsToTop_clicked() { - m_OrganizerCore.pluginList()->sendToPriority(ui->espList->selectionModel(), 0); + m_OrganizerCore.pluginList()->sendToPriority( + ui->espList->indexViewToModel(ui->espList->selectionModel()->selectedRows()), 0); } void MainWindow::sendSelectedPluginsToBottom_clicked() { - m_OrganizerCore.pluginList()->sendToPriority(ui->espList->selectionModel(), INT_MAX); + m_OrganizerCore.pluginList()->sendToPriority( + ui->espList->indexViewToModel(ui->espList->selectionModel()->selectedRows()), INT_MAX); } void MainWindow::sendSelectedPluginsToPriority_clicked() @@ -2884,7 +2886,8 @@ void MainWindow::sendSelectedPluginsToPriority_clicked() 0, 0, INT_MAX, 1, &ok); if (!ok) return; - m_OrganizerCore.pluginList()->sendToPriority(ui->espList->selectionModel(), newPriority); + m_OrganizerCore.pluginList()->sendToPriority( + ui->espList->indexViewToModel(ui->espList->selectionModel()->selectedRows()), newPriority); } void MainWindow::updateAvailable() diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index 504b17c5..053f91b3 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -412,20 +412,60 @@ void PluginList::disableAll() }
}
-void PluginList::sendToPriority(const QItemSelectionModel *selectionModel, int newPriority)
+void PluginList::sendToPriority(const QModelIndexList& indices, int newPriority)
{
- if (selectionModel->hasSelection()) {
- std::vector<int> pluginsToMove;
- for (auto row: selectionModel->selectedRows(COL_PRIORITY)) {
- int rowIndex = findPluginByPriority(row.data().toInt());
- if (!m_ESPs[rowIndex].forceEnabled) {
- pluginsToMove.push_back(rowIndex);
- }
+ std::vector<int> pluginsToMove;
+ for (auto& idx : indices) {
+ int rowIndex = findPluginByPriority(idx.row());
+ if (!m_ESPs[rowIndex].forceEnabled) {
+ pluginsToMove.push_back(rowIndex);
+ }
+ }
+ if (pluginsToMove.size()) {
+ changePluginPriority(pluginsToMove, newPriority);
+ }
+}
+
+void PluginList::shiftPluginsPriority(const QModelIndexList& indices, int offset)
+{
+ // retrieve the mod index and sort them by priority to avoid issue
+ // when moving them
+ std::vector<int> allIndex;
+ for (auto& idx : indices) {
+ allIndex.push_back(idx.row());
+ }
+ std::sort(allIndex.begin(), allIndex.end(), [=](int lhs, int rhs) {
+ bool cmp = m_ESPs[lhs].priority < m_ESPs[rhs].priority;
+ return offset > 0 ? !cmp : cmp;
+ });
+
+ emit layoutAboutToBeChanged();
+ for (auto index : allIndex) {
+ int newPriority = m_ESPs[index].priority + offset;
+ if (newPriority >= 0 && newPriority < rowCount()) {
+ setPluginPriority(index, newPriority);
+ }
+ }
+ emit layoutChanged();
+
+ refreshLoadOrder();
+}
+
+void PluginList::toggleState(const QModelIndexList& indices)
+{
+ QModelIndex minRow, maxRow;
+ for (auto& idx : indices) {
+ if (!minRow.isValid() || (idx.row() < minRow.row())) {
+ minRow = idx;
}
- if (pluginsToMove.size()) {
- changePluginPriority(pluginsToMove, newPriority);
+ if (!maxRow.isValid() || (idx.row() > maxRow.row())) {
+ maxRow = idx;
}
+ int oldState = idx.data(Qt::CheckStateRole).toInt();
+ setData(idx, oldState == Qt::Unchecked ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
}
+
+ emit dataChanged(minRow, maxRow);
}
bool PluginList::isEnabled(const QString &name)
@@ -541,7 +581,6 @@ void PluginList::writeLockedOrder(const QString &fileName) const file.commit();
}
-
void PluginList::saveTo(const QString &lockedOrderFileName
, const QString& deleterFileName
, bool hideUnchecked) const
@@ -898,13 +937,11 @@ boost::signals2::connection PluginList::onRefreshed(const std::function<void ()> return m_Refreshed.connect(callback);
}
-
boost::signals2::connection PluginList::onPluginMoved(const std::function<void (const QString &, int, int)> &func)
{
return m_PluginMoved.connect(func);
}
-
void PluginList::updateIndices()
{
m_ESPsByName.clear();
@@ -951,7 +988,6 @@ void PluginList::generatePluginIndexes() emit esplist_changed();
}
-
int PluginList::rowCount(const QModelIndex &parent) const
{
if (!parent.isValid()) {
@@ -966,7 +1002,6 @@ int PluginList::columnCount(const QModelIndex &) const return COL_LASTCOLUMN + 1;
}
-
void PluginList::testMasters()
{
std::set<QString> enabledMasters;
@@ -1371,7 +1406,6 @@ bool PluginList::setData(const QModelIndex &modIndex, const QVariant &value, int return result;
}
-
QVariant PluginList::headerData(int section, Qt::Orientation orientation,
int role) const
{
@@ -1385,7 +1419,6 @@ QVariant PluginList::headerData(int section, Qt::Orientation orientation, return QAbstractItemModel::headerData(section, orientation, role);
}
-
Qt::ItemFlags PluginList::flags(const QModelIndex &modelIndex) const
{
int index = modelIndex.row();
@@ -1406,7 +1439,6 @@ Qt::ItemFlags PluginList::flags(const QModelIndex &modelIndex) const return result;
}
-
void PluginList::setPluginPriority(int row, int &newPriority)
{
int newPriorityTemp = newPriority;
@@ -1464,7 +1496,6 @@ void PluginList::setPluginPriority(int row, int &newPriority) updateIndices();
}
-
void PluginList::changePluginPriority(std::vector<int> rows, int newPriority)
{
ChangeBracket<PluginList> layoutChange(this);
@@ -1562,82 +1593,6 @@ QModelIndex PluginList::parent(const QModelIndex&) const return QModelIndex();
}
-
-bool PluginList::eventFilter(QObject *obj, QEvent *event)
-{
- if (event->type() == QEvent::KeyPress) {
- QAbstractItemView *itemView = qobject_cast<QAbstractItemView*>(obj);
-
- if (itemView == nullptr) {
- return QAbstractItemModel::eventFilter(obj, event);
- }
-
- QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
- // ctrl+up and ctrl+down -> increase or decrease priority of selected plugins
- if ((keyEvent->modifiers() == Qt::ControlModifier) &&
- ((keyEvent->key() == Qt::Key_Up) || (keyEvent->key() == Qt::Key_Down))) {
- QItemSelectionModel *selectionModel = itemView->selectionModel();
- const QSortFilterProxyModel *proxyModel = qobject_cast<const QSortFilterProxyModel*>(selectionModel->model());
- if (proxyModel != nullptr) {
- int diff = -1;
- if (((keyEvent->key() == Qt::Key_Up) && (proxyModel->sortOrder() == Qt::DescendingOrder)) ||
- ((keyEvent->key() == Qt::Key_Down) && (proxyModel->sortOrder() == Qt::AscendingOrder))) {
- diff = 1;
- }
- QModelIndexList rows = selectionModel->selectedRows();
- // remove elements that aren't supposed to be movable
- QMutableListIterator<QModelIndex> iter(rows);
- while (iter.hasNext()) {
- if ((iter.next().flags() & Qt::ItemIsDragEnabled) == 0) {
- iter.remove();
- }
- }
- if (keyEvent->key() == Qt::Key_Down) {
- for (int i = 0; i < rows.size() / 2; ++i) {
- rows.swapItemsAt(i, rows.size() - i - 1);
- }
- }
- for (QModelIndex idx : rows) {
- idx = proxyModel->mapToSource(idx);
- int newPriority = m_ESPs[idx.row()].priority + diff;
- if ((newPriority >= 0) && (newPriority < rowCount())) {
- setPluginPriority(idx.row(), newPriority);
- }
- }
- refreshLoadOrder();
- }
- return true;
- } else if (keyEvent->key() == Qt::Key_Space) {
- QItemSelectionModel *selectionModel = itemView->selectionModel();
- const QSortFilterProxyModel *proxyModel = qobject_cast<const QSortFilterProxyModel*>(selectionModel->model());
- QList<QPersistentModelIndex> indices;
- for (QModelIndex idx : selectionModel->selectedRows()) {
- indices.append(idx);
- }
-
- QModelIndex minRow, maxRow;
- for (QModelIndex idx : indices) {
- if (proxyModel != nullptr) {
- idx = proxyModel->mapToSource(idx);
- }
- if (!minRow.isValid() || (idx.row() < minRow.row())) {
- minRow = idx;
- }
- if (!maxRow.isValid() || (idx.row() > maxRow.row())) {
- maxRow = idx;
- }
- int oldState = idx.data(Qt::CheckStateRole).toInt();
- setData(idx, oldState == Qt::Unchecked ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
- }
- emit dataChanged(minRow, maxRow);
-
- return true;
- }
- }
- return QAbstractItemModel::eventFilter(obj, event);
-}
-
-
PluginList::ESPInfo::ESPInfo(const QString &name, bool enabled,
const QString &originName, const QString &fullPath,
bool hasIni, std::set<QString> archives, bool lightPluginsAreSupported)
diff --git a/src/pluginlist.h b/src/pluginlist.h index 5f0cef3d..3a5f5412 100644 --- a/src/pluginlist.h +++ b/src/pluginlist.h @@ -214,8 +214,6 @@ public: bool isESPLocked(int index) const;
void lockESPIndex(int index, bool lock);
- bool eventFilter(QObject *obj, QEvent *event);
-
static QString getColumnName(int column);
static QString getColumnToolTip(int column);
@@ -279,10 +277,17 @@ public slots: **/
void disableAll();
- /**
- * @brief moves selected plugins to specified priority
- **/
- void sendToPriority(const QItemSelectionModel *selectionModel, int priority);
+ // send plugins to the given priority
+ //
+ void sendToPriority(const QModelIndexList& selectionModel, int priority);
+
+ // shift the priority of mods at the given indices by the given offset
+ //
+ void shiftPluginsPriority(const QModelIndexList& indices, int offset);
+
+ // toggle the active state of mods at the given indices
+ //
+ void toggleState(const QModelIndexList& indices);
/**
* @brief The currently managed game has changed
diff --git a/src/pluginlistview.cpp b/src/pluginlistview.cpp index a401ab06..70b3ebc1 100644 --- a/src/pluginlistview.cpp +++ b/src/pluginlistview.cpp @@ -117,6 +117,20 @@ void PluginListView::onFilterChanged(const QString& filter) updatePluginCount(); } +std::pair<QModelIndex, QModelIndexList> PluginListView::selected() const +{ + return { indexViewToModel(currentIndex()), indexViewToModel(selectionModel()->selectedRows()) }; +} + +void PluginListView::setSelected(const QModelIndex& current, const QModelIndexList& selected) +{ + setCurrentIndex(indexModelToView(current)); + for (auto idx : selected) { + selectionModel()->select(indexModelToView(idx), QItemSelectionModel::Select | QItemSelectionModel::Rows); + } +} + + void PluginListView::setup(OrganizerCore& core, MainWindow* mw, Ui::MainWindow* mwui) { m_core = &core; @@ -128,9 +142,53 @@ void PluginListView::setup(OrganizerCore& core, MainWindow* mw, Ui::MainWindow* sortByColumn(PluginList::COL_PRIORITY, Qt::AscendingOrder); setItemDelegateForColumn(PluginList::COL_FLAGS, new GenericIconDelegate(this)); - installEventFilter(core.pluginList()); connect(ui.filter, &QLineEdit::textChanged, m_sortProxy, &PluginListSortProxy::updateFilter); connect(ui.filter, &QLineEdit::textChanged, this, &PluginListView::onFilterChanged); } + +bool PluginListView::moveSelection(int key) +{ + auto [cindex, sourceRows] = selected(); + + int offset = key == Qt::Key_Up ? -1 : 1; + if (m_sortProxy->sortOrder() == Qt::DescendingOrder) { + offset = -offset; + } + + m_core->pluginList()->shiftPluginsPriority(sourceRows, offset); + + // reset the selection and the index + setSelected(cindex, sourceRows); + + return true; +} + +bool PluginListView::toggleSelectionState() +{ + if (!selectionModel()->hasSelection()) { + return true; + } + m_core->pluginList()->toggleState(indexViewToModel(selectionModel()->selectedRows())); + return true; +} + +bool PluginListView::event(QEvent* event) +{ + Profile* profile = m_core->currentProfile(); + if (event->type() == QEvent::KeyPress && profile) { + QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event); + + if (keyEvent->modifiers() == Qt::ControlModifier + && (sortColumn() == PluginList::COL_PRIORITY || sortColumn() == PluginList::COL_MODINDEX) + && (keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down)) { + return moveSelection(keyEvent->key()); + } + else if (keyEvent->key() == Qt::Key_Space) { + return toggleSelectionState(); + } + return QTreeView::event(event); + } + return QTreeView::event(event); +} diff --git a/src/pluginlistview.h b/src/pluginlistview.h index 95450ffd..92f03588 100644 --- a/src/pluginlistview.h +++ b/src/pluginlistview.h @@ -43,6 +43,21 @@ protected slots: void onFilterChanged(const QString& filter); +protected: + + // method to react to various key events + // + bool moveSelection(int key); + bool toggleSelectionState(); + + // 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 + // + std::pair<QModelIndex, QModelIndexList> selected() const; + void setSelected(const QModelIndex& current, const QModelIndexList& selected); + + bool event(QEvent* event) override; + private: struct PluginListViewUi |
