From d514db9c4a9fc0497588b438c11eca0d4431c92c Mon Sep 17 00:00:00 2001 From: blue Date: Tue, 4 May 2021 17:09:41 +0300 Subject: [PATCH] message context menu began, open and show in folder features --- shared/utils.cpp | 37 +++++++++++++++++++++++++++++++++++++ shared/utils.h | 6 ++++++ ui/models/messagefeed.cpp | 16 ++++++++++++++++ ui/models/messagefeed.h | 1 + ui/utils/feedview.cpp | 12 +++++++++--- ui/widgets/conversation.cpp | 37 ++++++++++++++++++++++++++++++++++--- ui/widgets/conversation.h | 5 +++++ 7 files changed, 108 insertions(+), 6 deletions(-) diff --git a/shared/utils.cpp b/shared/utils.cpp index 924be85..f5f7fa5 100644 --- a/shared/utils.cpp +++ b/shared/utils.cpp @@ -46,3 +46,40 @@ QString Shared::processMessageBody(const QString& msg) processed.replace(urlReg, "\\1"); return "

" + processed + "

"; } + +static const QStringList query = {"query", "default", "inode/directory"}; +static const QRegularExpression dolphinReg("[Dd]olphin"); +static const QRegularExpression nautilusReg("[Nn]autilus"); +static const QRegularExpression cajaReg("[Cc]aja"); +static const QRegularExpression nemoReg("[Nn]emo"); +static const QRegularExpression konquerorReg("kfmclient"); + +void Shared::showInDirectory(const QString& path) +{ + QFileInfo info = path; + if (info.exists()) { + QProcess proc; + proc.start("xdg-mime", query); + proc.waitForFinished(); + QString output = proc.readLine().simplified(); + if (output.contains(dolphinReg)) { + proc.startDetached("dolphin", QStringList() << "--select" << info.canonicalFilePath()); + } else if (output.contains(nautilusReg)) { + proc.startDetached("nautilus", QStringList() << "--no-desktop" << info.canonicalFilePath()); + } else if (output.contains(cajaReg)) { + proc.startDetached("caja", QStringList() << "--no-desktop" << info.canonicalFilePath()); + } else if (output.contains(nemoReg)) { + proc.startDetached("nemo", QStringList() << "--no-desktop" << info.canonicalFilePath()); + } else if (output.contains(konquerorReg)) { + proc.startDetached("konqueror", QStringList() << "--select" << info.canonicalFilePath()); + } else { + QString folder; + if (info.isDir()) { + folder = info.canonicalFilePath(); + } else { + folder = info.canonicalPath(); + } + QDesktopServices::openUrl(QUrl::fromLocalFile(folder)); + } + } +} diff --git a/shared/utils.h b/shared/utils.h index e9e3d29..6bbe978 100644 --- a/shared/utils.h +++ b/shared/utils.h @@ -20,8 +20,13 @@ #define SHARED_UTILS_H #include +#include #include #include +#include +#include +#include +#include #include #include @@ -30,6 +35,7 @@ namespace Shared { QString generateUUID(); QString processMessageBody(const QString& msg); +void showInDirectory(const QString& path); static const std::vector colorPalette = { QColor(244, 27, 63), diff --git a/ui/models/messagefeed.cpp b/ui/models/messagefeed.cpp index 09b11cd..743e64a 100644 --- a/ui/models/messagefeed.cpp +++ b/ui/models/messagefeed.cpp @@ -379,6 +379,22 @@ void Models::MessageFeed::responseArchive(const std::list list, } } +QModelIndex Models::MessageFeed::index(int row, int column, const QModelIndex& parent) const +{ + if (!hasIndex(row, column, parent)) { + return QModelIndex(); + } + + StorageByTime::iterator itr = indexByTime.nth(row); + if (itr != indexByTime.end()) { + Shared::Message* msg = *itr; + + return createIndex(row, column, msg); + } else { + return QModelIndex(); + } +} + QHash Models::MessageFeed::roleNames() const { return roles; diff --git a/ui/models/messagefeed.h b/ui/models/messagefeed.h index cc833fa..abf67ee 100644 --- a/ui/models/messagefeed.h +++ b/ui/models/messagefeed.h @@ -61,6 +61,7 @@ public: bool canFetchMore(const QModelIndex & parent) const override; void fetchMore(const QModelIndex & parent) override; QHash roleNames() const override; + QModelIndex index(int row, int column, const QModelIndex & parent) const override; void responseArchive(const std::list list, bool last); void downloadAttachment(const QString& messageId); diff --git a/ui/utils/feedview.cpp b/ui/utils/feedview.cpp index 226b9a7..fd9669e 100644 --- a/ui/utils/feedview.cpp +++ b/ui/utils/feedview.cpp @@ -68,8 +68,13 @@ QModelIndex FeedView::indexAt(const QPoint& point) const uint32_t y = vh - point.y() + vo; for (std::deque::size_type i = 0; i < hints.size(); ++i) { - if (hints[i].offset + hints[i].height >= y) { - return model()->index(i, 0, rootIndex()); + const Hint& hint = hints[i]; + if (y <= hint.offset + hint.height) { + if (y > hint.offset) { + return model()->index(i, 0, rootIndex()); + } else { + break; + } } } @@ -279,7 +284,8 @@ void FeedView::paintEvent(QPaintEvent* event) for (const QModelIndex& index : toRener) { option.rect = visualRect(index); - option.state.setFlag(QStyle::State_MouseOver, option.rect.contains(cursor)); + bool mouseOver = option.rect.contains(cursor) && vp->rect().contains(cursor); + option.state.setFlag(QStyle::State_MouseOver, mouseOver); itemDelegate(index)->paint(&painter, option, index); } diff --git a/ui/widgets/conversation.cpp b/ui/widgets/conversation.cpp index e678caf..db6a92e 100644 --- a/ui/widgets/conversation.cpp +++ b/ui/widgets/conversation.cpp @@ -47,7 +47,8 @@ Conversation::Conversation(bool muc, Models::Account* acc, Models::Element* el, delegate(new MessageDelegate(this)), manualSliderChange(false), tsb(QApplication::style()->styleHint(QStyle::SH_ScrollBar_Transient) == 1), - shadow(10, 1, Qt::black, this) + shadow(10, 1, Qt::black, this), + contextMenu(new QMenu()) { m_ui->setupUi(this); @@ -55,6 +56,7 @@ Conversation::Conversation(bool muc, Models::Account* acc, Models::Element* el, feed->setItemDelegate(delegate); feed->setFrameShape(QFrame::NoFrame); + feed->setContextMenuPolicy(Qt::CustomContextMenu); delegate->initializeFonts(feed->getFont()); feed->setModel(el->feed); el->feed->incrementObservers(); @@ -62,6 +64,7 @@ Conversation::Conversation(bool muc, Models::Account* acc, Models::Element* el, connect(el->feed, &Models::MessageFeed::newMessage, this, &Conversation::onFeedMessage); connect(feed, &FeedView::resized, this, &Conversation::positionShadow); + connect(feed, &FeedView::customContextMenuRequested, this, &Conversation::onFeedContext); connect(acc, &Models::Account::childChanged, this, &Conversation::onAccountChanged); @@ -88,8 +91,6 @@ Conversation::Conversation(bool muc, Models::Account* acc, Models::Element* el, //m_ui->scrollArea->setBackgroundRole(QPalette::Base); //} - //m_ui->scrollArea->installEventFilter(&scrollResizeCatcher); - //line->setMyAvatarPath(acc->getAvatarPath()); //line->setMyName(acc->getName()); @@ -98,6 +99,8 @@ Conversation::Conversation(bool muc, Models::Account* acc, Models::Element* el, Conversation::~Conversation() { + delete contextMenu; + element->feed->decrementObservers(); } @@ -402,3 +405,31 @@ void Conversation::positionShadow() shadow.move(feed->pos()); shadow.raise(); } + +void Conversation::onFeedContext(const QPoint& pos) +{ + QModelIndex index = feed->indexAt(pos); + if (index.isValid()) { + Shared::Message* item = static_cast(index.internalPointer()); + + contextMenu->clear(); + bool showMenu = false; + QString path = item->getAttachPath(); + if (path.size() > 0) { + showMenu = true; + QAction* open = contextMenu->addAction(Shared::icon("document-new-from-template"), tr("Open")); + connect(open, &QAction::triggered, [path]() { + QDesktopServices::openUrl(QUrl::fromLocalFile(path)); + }); + + QAction* show = contextMenu->addAction(Shared::icon("document-new-from-template"), tr("Show in folder")); + connect(show, &QAction::triggered, [path]() { + Shared::showInDirectory(path); + }); + } + + if (showMenu) { + contextMenu->popup(feed->viewport()->mapToGlobal(pos)); + } + } +} diff --git a/ui/widgets/conversation.h b/ui/widgets/conversation.h index eaec954..690a51c 100644 --- a/ui/widgets/conversation.h +++ b/ui/widgets/conversation.h @@ -25,6 +25,9 @@ #include #include #include +#include +#include +#include #include "shared/message.h" #include "order.h" @@ -103,6 +106,7 @@ protected slots: void onAccountChanged(Models::Item* item, int row, int col); void onFeedMessage(const Shared::Message& msg); void positionShadow(); + void onFeedContext(const QPoint &pos); public: const bool isMuc; @@ -126,6 +130,7 @@ protected: bool tsb; //transient scroll bars ShadowOverlay shadow; + QMenu* contextMenu; }; #endif // CONVERSATION_H