diff options
| author | Mikaël Capelle <capelle.mikael@gmail.com> | 2021-01-03 12:51:54 +0100 |
|---|---|---|
| committer | Mikaël Capelle <capelle.mikael@gmail.com> | 2021-01-03 12:51:54 +0100 |
| commit | 3366d9f192ef88cccc2d901c666e15061db20b4e (patch) | |
| tree | d65ce6bfdcd6ddbc4ce48df453613057eca18b1e | |
| parent | c36d1126df94d879181a95d63862117a62d5ff60 (diff) | |
Create CopyEventFilter. Add Ctrl+C to the plugin list.
| -rw-r--r-- | src/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/copyeventfilter.cpp | 51 | ||||
| -rw-r--r-- | src/copyeventfilter.h | 43 | ||||
| -rw-r--r-- | src/modlistcontextmenu.cpp | 2 | ||||
| -rw-r--r-- | src/modlistview.cpp | 48 | ||||
| -rw-r--r-- | src/modlistview.h | 1 | ||||
| -rw-r--r-- | src/pluginlistview.cpp | 2 |
7 files changed, 114 insertions, 34 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 663ebcbc..4b74137e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -236,6 +236,7 @@ add_filter(NAME src/widgets GROUPS texteditor viewmarkingscrollbar modelutils + copyeventfilter ) diff --git a/src/copyeventfilter.cpp b/src/copyeventfilter.cpp new file mode 100644 index 00000000..bbde13e6 --- /dev/null +++ b/src/copyeventfilter.cpp @@ -0,0 +1,51 @@ +#include "copyeventfilter.h" + +#include <QClipboard> +#include <QGuiApplication> +#include <QKeyEvent> + +CopyEventFilter::CopyEventFilter(QAbstractItemView* view, int role) : + CopyEventFilter(view, [=](auto& index) { return index.data(role).toString(); }) +{ + +} + +CopyEventFilter::CopyEventFilter( + QAbstractItemView* view, std::function<QString(const QModelIndex&)> format) : + QObject(view), m_view(view), m_format(format) +{ + +} + +bool CopyEventFilter::copySelection() const +{ + if (!m_view->selectionModel()->hasSelection()) { + return true; + } + + // sort to reflect the visual order + QModelIndexList selectedRows = m_view->selectionModel()->selectedRows(); + std::sort(selectedRows.begin(), selectedRows.end(), [=](const auto& lidx, const auto& ridx) { + return m_view->visualRect(lidx).top() < m_view->visualRect(ridx).top(); + }); + + QStringList rows; + for (auto& idx : selectedRows) { + rows.append(m_format(idx)); + } + + QGuiApplication::clipboard()->setText(rows.join("\n")); + return true; +} + +bool CopyEventFilter::eventFilter(QObject* sender, QEvent* event) +{ + if (sender == m_view && event->type() == QEvent::KeyPress) { + QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event); + if (keyEvent->modifiers() == Qt::ControlModifier + && keyEvent->key() == Qt::Key_C) { + return copySelection(); + } + } + return QObject::eventFilter(sender, event); +} diff --git a/src/copyeventfilter.h b/src/copyeventfilter.h new file mode 100644 index 00000000..1243630b --- /dev/null +++ b/src/copyeventfilter.h @@ -0,0 +1,43 @@ +#ifndef COPY_EVENT_FILTER_H +#define COPY_EVENT_FILTER_H + +#include <functional> + +#include <QAbstractItemView> +#include <QModelIndex> +#include <QObject> + +// this small class provides copy on Ctrl+C and also +// exposes a method to actual copy the selection +// +// the way the selection is copied can be customized by +// passing a functor to format each index, by default +// it only extracts the display role +// +// only works for view that selects whole row since it only +// considers the first cell in each row +// +class CopyEventFilter : public QObject +{ + Q_OBJECT + +public: + + CopyEventFilter(QAbstractItemView* view, int role = Qt::DisplayRole); + CopyEventFilter(QAbstractItemView* view, std::function<QString(const QModelIndex&)> format); + + // copy the selection of the view associated with this + // event filter into the clipboard + // + bool copySelection() const; + + bool eventFilter(QObject* sender, QEvent* event) override; + +private: + + QAbstractItemView* m_view; + std::function<QString(const QModelIndex&)> m_format; + +}; + +#endif diff --git a/src/modlistcontextmenu.cpp b/src/modlistcontextmenu.cpp index f20586c4..c1ee4f74 100644 --- a/src/modlistcontextmenu.cpp +++ b/src/modlistcontextmenu.cpp @@ -29,7 +29,7 @@ ModListGlobalContextMenu::ModListGlobalContextMenu(OrganizerCore& core, ModListV addSeparator(); - addAction(tr("Enable all parent"), [=]() { + addAction(tr("Enable all visible"), [=]() { if (QMessageBox::question(view, tr("Confirm"), tr("Really enable all visible mods?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { view->enableAllVisible(); diff --git a/src/modlistview.cpp b/src/modlistview.cpp index bc6b5a65..29c68165 100644 --- a/src/modlistview.cpp +++ b/src/modlistview.cpp @@ -22,6 +22,7 @@ #include "modlistdropinfo.h"
#include "modlistcontextmenu.h"
#include "genericicondelegate.h"
+#include "copyeventfilter.h"
#include "shared/fileentry.h"
#include "shared/directoryentry.h"
#include "shared/filesorigin.h"
@@ -135,6 +136,21 @@ ModListView::ModListView(QWidget* parent) connect(this, &ModListView::doubleClicked, this, &ModListView::onDoubleClicked);
connect(this, &ModListView::customContextMenuRequested, this, &ModListView::onCustomContextMenuRequested);
+
+ installEventFilter(new CopyEventFilter(this, [=](auto& index) {
+ QVariant mIndex = index.data(ModList::IndexRole);
+ QString name = index.data(Qt::DisplayRole).toString();
+ if (mIndex.isValid() && hasCollapsibleSeparators()) {
+ ModInfo::Ptr info = ModInfo::getByIndex(mIndex.toInt());
+ if (info->isSeparator()) {
+ name = "[" + name + "]";
+ }
+ }
+ else if (model()->hasChildren(index)) {
+ name = "[" + name + "]";
+ }
+ return name;
+ }));
}
void ModListView::refresh()
@@ -615,35 +631,6 @@ bool ModListView::toggleSelectionState() return m_core->modList()->toggleState(indexViewToModel(selectionModel()->selectedRows()));
}
-bool ModListView::copySelection()
-{
- if (!selectionModel()->hasSelection()) {
- return true;
- }
-
- // sort to reflect the visual order
- QModelIndexList selectedRows = selectionModel()->selectedRows();
- std::sort(selectedRows.begin(), selectedRows.end(), [=](const auto& lidx, const auto& ridx) {
- return visualRect(lidx).top() < visualRect(ridx).top();
- });
-
- QStringList rows;
- for (auto& idx : selectedRows) {
- ModInfo::Ptr info = ModInfo::getByIndex(idx.data(ModList::IndexRole).toInt());
- QString name = idx.data(Qt::DisplayRole).toString();
- if (model()->hasChildren(idx) || (
- sortColumn() == ModList::COL_PRIORITY
- && (groupByMode() == GroupByMode::NONE || groupByMode() == GroupByMode::SEPARATOR)
- && info->isSeparator())) {
- name = "[" + name + "]";
- }
- rows.append(name);
- }
-
- QGuiApplication::clipboard()->setText(rows.join("\n"));
- return true;
-}
-
void ModListView::updateGroupByProxy(int groupIndex)
{
// if the index is -1, we do not refresh unless we are grouping
@@ -1225,9 +1212,6 @@ bool ModListView::event(QEvent* event) && (keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down)) {
return moveSelection(keyEvent->key());
}
- else if (keyEvent->key() == Qt::Key_C) {
- return copySelection();
- }
}
else if (keyEvent->modifiers() == Qt::ShiftModifier) {
// shift+enter expand
diff --git a/src/modlistview.h b/src/modlistview.h index 2aa48140..9712deab 100644 --- a/src/modlistview.h +++ b/src/modlistview.h @@ -149,7 +149,6 @@ protected: bool moveSelection(int key);
bool removeSelection();
bool toggleSelectionState();
- bool copySelection();
// re-implemented to fix indentation with collapsible separators
//
diff --git a/src/pluginlistview.cpp b/src/pluginlistview.cpp index 7388ae40..e27d7e66 100644 --- a/src/pluginlistview.cpp +++ b/src/pluginlistview.cpp @@ -12,6 +12,7 @@ #include "pluginlistsortproxy.h" #include "pluginlistcontextmenu.h" #include "modlistview.h" +#include "copyeventfilter.h" #include "modlistviewactions.h" #include "genericicondelegate.h" #include "modelutils.h" @@ -26,6 +27,7 @@ PluginListView::PluginListView(QWidget *parent) { setVerticalScrollBar(m_Scrollbar); MOBase::setCustomizableColumns(this); + installEventFilter(new CopyEventFilter(this)); } int PluginListView::sortColumn() const |
