summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMikaël Capelle <capelle.mikael@gmail.com>2020-12-31 21:24:29 +0100
committerMikaël Capelle <capelle.mikael@gmail.com>2021-01-02 15:38:18 +0100
commit25a2123e5ffe66715d0a1ec09297ee91a9fcbe1c (patch)
treeb13f943d76833b1c331d63397cf6ed553eeb27c0 /src
parentf2d8469ed6cd0fafc22097cdba2ee8f325f00513 (diff)
Move keyboard event to PluginListView.
Diffstat (limited to 'src')
-rw-r--r--src/mainwindow.cpp9
-rw-r--r--src/pluginlist.cpp145
-rw-r--r--src/pluginlist.h17
-rw-r--r--src/pluginlistview.cpp60
-rw-r--r--src/pluginlistview.h15
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