123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873 |
- #include "Menu.h"
- #include "Common/StyleSheet.h"
- #include "Common/Icon.h"
- #include "Common/SmoothScroll.h"
- #include "QFluentWidgets.h"
- #include <QApplication>
- #include <QClipboard>
- #include <QMimeData>
- #include <QScreen>
- #include <QEvent>
- #include <QPainter>
- #include <QTimer>
- #include <QDebug>
- #include <QMouseEvent>
- CustomMenuStyle::CustomMenuStyle(int iconSize) : QProxyStyle(), m_iconSize(iconSize) { }
- int CustomMenuStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
- {
- if (metric == QStyle::PM_SmallIconSize) {
- return m_iconSize;
- }
- return QProxyStyle::pixelMetric(metric, option, widget);
- }
- DWMMenu::DWMMenu(const QString &title, QWidget *parent) : QMenu(title, parent), m_customMenuStyle(new CustomMenuStyle)
- {
- // WindowEffect 阴影效果
- setWindowFlags(Qt::FramelessWindowHint | Qt::Popup | Qt::NoDropShadowWindowHint);
- setAttribute(Qt::WA_StyledBackground);
- setStyle(m_customMenuStyle.data());
- FluentStyleSheet::apply("MENU", this);
- }
- bool DWMMenu::event(QEvent *event)
- {
- if (event->type() == QEvent::WinIdChange) {
- // windowEffect.addMenuShadowEffect(self.winId())
- }
- return QMenu::event(event);
- }
- MenuSeparator::MenuSeparator(QWidget *parent) : QWidget(parent)
- {
- setFixedHeight(9);
- }
- void MenuSeparator::paintEvent(QPaintEvent * /*event*/)
- {
- QPainter painter(this);
- int c = QFWIns.isDarkTheme() ? 255 : 0;
- QPen pen(QColor(c, c, c, 25), 1);
- pen.setCosmetic(true);
- painter.setPen(pen);
- painter.drawLine(0, 4, width(), 4);
- }
- /**
- * @brief Round corner menu
- * @param parent
- */
- RoundMenu::RoundMenu(const QString &title, QWidget *parent)
- : QWidget(parent),
- m_title(title),
- m_isSubMenu(false),
- m_parentMenu(nullptr),
- m_menuItem(nullptr),
- m_lastHoverItem(nullptr),
- m_lastHoverSubMenuItem(nullptr),
- m_isHideBySystem(true),
- m_itemHeight(28),
- m_hBoxLayout(new QHBoxLayout(this)),
- m_view(new MenuActionListWidget(this)),
- m_ani(new QPropertyAnimation(this, "pos", this)),
- m_timer(new QTimer(this)),
- m_shadowEffect(nullptr),
- m_eventLoop(nullptr)
- {
- initWidgets();
- }
- /// add shadow to dialog
- void RoundMenu::setShadowEffect(qreal blurRadius, const QPointF &offset, const QColor &color)
- {
- m_shadowEffect = new QGraphicsDropShadowEffect(m_view);
- m_shadowEffect->setBlurRadius(blurRadius);
- m_shadowEffect->setOffset(offset);
- m_shadowEffect->setColor(color);
- m_view->setGraphicsEffect(nullptr);
- m_view->setGraphicsEffect(m_shadowEffect);
- }
- void RoundMenu::initWidgets()
- {
- setWindowFlags(Qt::Popup | Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint);
- setAttribute(Qt::WA_TranslucentBackground);
- setMouseTracking(true);
- m_timer->setSingleShot(true);
- m_timer->setInterval(400);
- connect(m_timer, &QTimer::timeout, this, &RoundMenu::onShowMenuTimeOut);
- setShadowEffect();
- m_hBoxLayout->setContentsMargins(12, 8, 12, 20);
- m_hBoxLayout->addWidget(m_view, 1, Qt::AlignCenter);
- setLayout(m_hBoxLayout);
- FluentStyleSheet::apply("MENU", this);
- connect(m_view, &MenuActionListWidget::itemClicked, this, &RoundMenu::onItemClicked);
- connect(m_view, &MenuActionListWidget::itemEntered, this, &RoundMenu::onItemEntered);
- connect(m_ani, &QPropertyAnimation::valueChanged, this, &RoundMenu::onSlideValueChanged);
- }
- QString RoundMenu::title() const
- {
- return m_title;
- }
- QIcon RoundMenu::icon() const
- {
- return m_icon;
- }
- void RoundMenu::setIcon(const QIcon &icon)
- {
- m_icon = icon;
- }
- /// clear all actions
- void RoundMenu::clear()
- {
- while (!m_actions.isEmpty()) {
- removeAction(m_actions.last());
- }
- }
- /// remove action from menu
- void RoundMenu::removeAction(QAction *action)
- {
- if (!m_actions.contains(action)) {
- return;
- }
- int index = m_actions.indexOf(action);
- m_actions.removeAt(index);
- action->setProperty("item", 0);
- QListWidgetItem *item = m_view->takeItem(index);
- item->setData(Qt::UserRole, 0);
- // delete widget
- QWidget *widget = m_view->itemWidget(item);
- if (widget) {
- widget->deleteLater();
- widget = nullptr;
- }
- delete item;
- action->deleteLater();
- }
- /// add action to menu
- void RoundMenu::addAction(QAction *const action)
- {
- QListWidgetItem *item = createActionItem(action);
- if (!item) {
- return;
- }
- m_view->addItem(item);
- adjustSize();
- }
- void RoundMenu::insertAction(QAction *const before, QAction *const action)
- {
- if (!m_actions.contains(before)) {
- return;
- }
- QListWidgetItem *beforeItem = before->property("item").value<QListWidgetItem *>();
- if (!beforeItem) {
- return;
- }
- int index = m_view->row(beforeItem);
- QListWidgetItem *item = createActionItem(action, before);
- m_view->insertItem(index, item);
- adjustSize();
- }
- void RoundMenu::addActions(const QList<QAction *> &actions)
- {
- for (auto a : actions) {
- addAction(a);
- }
- }
- void RoundMenu::insertActions(QAction *const before, const QList<QAction *> &actions)
- {
- for (auto a : actions) {
- insertAction(before, a);
- }
- }
- void RoundMenu::setDefaultAction(QAction *const action)
- {
- if (!m_actions.contains(action)) {
- return;
- }
- int index = m_actions.indexOf(action);
- m_view->setCurrentRow(index);
- }
- void RoundMenu::addMenu(RoundMenu *const menu)
- {
- if (!menu) {
- return;
- }
- auto itemW = createSubMenuItem(menu);
- if (itemW.first == nullptr || itemW.second == nullptr) {
- return;
- }
- m_view->addItem(itemW.first);
- m_view->setItemWidget(itemW.first, itemW.second);
- this->adjustSize();
- }
- void RoundMenu::insertMenu(QAction *const before, RoundMenu *const menu)
- {
- if (!menu) {
- qCritical() << "`menu` should be an instance of `RoundMenu`.";
- return;
- }
- if (!m_actions.contains(before)) {
- qCritical() << "`before` should be in menu action list";
- return;
- }
- auto itemW = createSubMenuItem(menu);
- if (itemW.first == nullptr || itemW.second == nullptr) {
- return;
- }
- m_view->insertItem(m_view->row(before->property("item").value<QListWidgetItem *>()), itemW.first);
- m_view->setItemWidget(itemW.first, itemW.second);
- this->adjustSize();
- }
- void RoundMenu::setItemHeight(int itemHeight)
- {
- if (m_itemHeight == itemHeight) {
- return;
- }
- m_itemHeight = itemHeight;
- m_view->setItemHeight(itemHeight);
- }
- void RoundMenu::adjustSize()
- {
- QMargins m = this->layout()->contentsMargins();
- int w = m_view->width() + m.left() + m.right();
- int h = m_view->height() + m.top() + m.bottom();
- setFixedSize(w, h);
- }
- void RoundMenu::setParentMenu(RoundMenu *parent, QListWidgetItem *item)
- {
- m_parentMenu = parent;
- m_menuItem = item;
- m_isSubMenu = parent == nullptr ? false : true;
- }
- QListWidgetItem *RoundMenu::createActionItem(QAction *const action, QAction *const before)
- {
- if (!before) {
- m_actions.append(action);
- } else if (m_actions.contains(before)) {
- int index = m_actions.indexOf(before);
- m_actions.insert(index, action);
- } else {
- qCritical() << QString("`before` is not in the action list");
- return nullptr;
- }
- QListWidgetItem *item = new QListWidgetItem(createItemIcon(action), action->text());
- int w = 0;
- if (!hasItemIcon()) {
- w = 28 + m_view->fontMetrics().width(action->text());
- } else {
- // add a blank character to increase space between icon and text
- item->setText(" " + item->text());
- w = 60 + m_view->fontMetrics().width(item->text());
- }
- item->setSizeHint(QSize(w, m_itemHeight));
- item->setData(Qt::UserRole, QVariant::fromValue<QAction *>(action));
- action->setProperty("item", QVariant::fromValue<QListWidgetItem *>(item));
- connect(action, &QAction::changed, this, &RoundMenu::onActionChanged);
- return item;
- }
- bool RoundMenu::hasItemIcon()
- {
- for (auto a : m_actions) {
- if (!a->icon().isNull()) {
- return true;
- }
- }
- for (auto m : m_subMenus) {
- if (!m->icon().isNull()) {
- return true;
- }
- }
- return false;
- }
- QIcon RoundMenu::createItemIcon(QAction *const action)
- {
- bool hasIcon = hasItemIcon();
- if (hasIcon && action->icon().isNull()) {
- QPixmap pixmap(m_view->iconSize());
- pixmap.fill(Qt::transparent);
- return QIcon(pixmap);
- } else if (!hasIcon) {
- return QIcon();
- }
- QIcon icon(new MenuIconEngine(action->icon()));
- return icon;
- }
- QIcon RoundMenu::createItemIcon(RoundMenu *const menu)
- {
- bool hasIcon = hasItemIcon();
- if (hasIcon && menu->icon().isNull()) {
- QPixmap pixmap(m_view->iconSize());
- pixmap.fill(Qt::transparent);
- return QIcon(pixmap);
- } else if (!hasIcon) {
- return QIcon();
- }
- QIcon icon(new MenuIconEngine(menu->icon()));
- return icon;
- }
- QPair<QListWidgetItem *, SubMenuItemWidget *> RoundMenu::createSubMenuItem(RoundMenu *const menu)
- {
- if (!menu) {
- return QPair<QListWidgetItem *, SubMenuItemWidget *>(nullptr, nullptr);
- }
- m_subMenus.append(menu);
- QListWidgetItem *item = new QListWidgetItem(createItemIcon(menu), menu->title());
- int w = 0;
- if (!hasItemIcon()) {
- w = 48 + m_view->fontMetrics().width(menu->title());
- } else {
- // add a blank character to increase space between icon and text
- item->setText(" " + item->text());
- w = 60 + m_view->fontMetrics().width(item->text());
- }
- // add submenu item
- menu->setParentMenu(this, item);
- item->setSizeHint(QSize(w, m_itemHeight));
- item->setData(Qt::UserRole, QVariant::fromValue<RoundMenu *>(menu));
- SubMenuItemWidget *subw = new SubMenuItemWidget(menu, item, this);
- connect(subw, &SubMenuItemWidget::showMenuSig, this, &RoundMenu::showSubMenu);
- subw->resize(item->sizeHint());
- return QPair<QListWidgetItem *, SubMenuItemWidget *>(item, subw);
- }
- void RoundMenu::hideMenu(bool hideBySystem)
- {
- m_isHideBySystem = hideBySystem;
- m_view->clearSelection();
- if (m_isSubMenu) {
- hide();
- } else {
- close();
- }
- }
- void RoundMenu::closeParentMenu()
- {
- RoundMenu *menu = this;
- while (menu->m_parentMenu) {
- menu->close();
- menu = menu->parentMenu();
- }
- menu->close();
- }
- void RoundMenu::mouseMoveEvent(QMouseEvent *event)
- {
- if (!m_isSubMenu) {
- return;
- }
- // hide submenu when mouse moves out of submenu item
- QPoint pos = event->globalPos();
- MenuActionListWidget *view = m_parentMenu->view();
- // get the rect of menu item
- QMargins margin = view->viewportMargins();
- QRect rect = view->visualItemRect(m_menuItem).translated(view->mapToGlobal(QPoint()));
- rect = rect.translated(margin.left(), margin.top() + 2);
- if (m_parentMenu->geometry().contains(pos) && !rect.contains(pos) && !this->geometry().contains(pos)) {
- view->clearSelection();
- hideMenu(false);
- // update style
- int index = view->row(m_menuItem);
- if (index > 0) {
- view->item(index - 1)->setFlags(Qt::ItemIsEnabled);
- }
- if (index < view->count() - 1) {
- view->item(index + 1)->setFlags(Qt::ItemIsEnabled);
- }
- }
- }
- void RoundMenu::closeEvent(QCloseEvent *event)
- {
- // 关闭窗口时结束事件循环,在exec()方法中返回选择结果;
- if (m_eventLoop != nullptr) {
- m_eventLoop->exit();
- }
- event->accept();
- emit closedSignal();
- }
- void RoundMenu::hideEvent(QHideEvent *event)
- {
- if (m_isHideBySystem && m_isSubMenu) {
- closeParentMenu();
- }
- m_isHideBySystem = true;
- event->accept();
- }
- void RoundMenu::onShowMenuTimeOut()
- {
- if ((m_lastHoverSubMenuItem == nullptr) || (m_lastHoverItem == m_lastHoverSubMenuItem)) {
- return;
- }
- SubMenuItemWidget *sub = qobject_cast<SubMenuItemWidget *>(m_view->itemWidget(m_lastHoverSubMenuItem));
- RoundMenu *w = sub->roundMenu();
- if (w && w->parentMenu()->isHidden()) {
- return;
- }
- QPoint pos = w->mapToGlobal(QPoint(w->width() + 5, -5));
- w->exec(pos);
- }
- void RoundMenu::onItemClicked(QListWidgetItem *item)
- {
- QAction *action = item->data(Qt::UserRole).value<QAction *>();
- if (!m_actions.contains(action)) {
- return;
- }
- hideMenu();
- if (!m_isSubMenu) {
- action->trigger();
- return;
- }
- // close parent menu
- closeParentMenu();
- action->trigger();
- }
- void RoundMenu::onItemEntered(QListWidgetItem *item)
- {
- m_lastHoverItem = item;
- RoundMenu *menu = item->data(Qt::UserRole).value<RoundMenu *>();
- if (!menu) {
- return;
- }
- showSubMenu(item);
- }
- void RoundMenu::onSlideValueChanged(const QVariant &value)
- {
- QMargins m = this->layout()->contentsMargins();
- int w = m_view->width() + m.left() + m.right() + 120;
- int h = m_view->height() + m.top() + m.bottom() + 20;
- int y = m_ani->endValue().toPoint().y() - value.toPoint().y();
- this->setMask(QRegion(0, y, w, h));
- }
- void RoundMenu::onActionChanged()
- {
- QAction *action = static_cast<QAction *>(sender());
- QListWidgetItem *item = action->property("item").value<QListWidgetItem *>();
- item->setIcon(createItemIcon(action));
- int w = 0;
- if (!hasItemIcon()) {
- item->setText(action->text());
- w = 28 + m_view->fontMetrics().width(action->text());
- } else {
- // add a blank character to increase space between icon and text
- item->setText(" " + action->text());
- w = 60 + m_view->fontMetrics().width(item->text());
- }
- item->setSizeHint(QSize(w, m_itemHeight));
- m_view->adjustSize();
- this->adjustSize();
- }
- void RoundMenu::showSubMenu(QListWidgetItem *const item)
- {
- m_lastHoverItem = item;
- m_lastHoverSubMenuItem = item;
- // delay 400 ms to anti-shake
- m_timer->stop();
- m_timer->start();
- }
- QList<QAction *> RoundMenu::menuActions() const
- {
- return m_actions;
- }
- MenuActionListWidget *RoundMenu::view() const
- {
- return m_view;
- }
- void RoundMenu::addSeparator()
- {
- QMargins m = m_view->viewportMargins();
- int w = m_view->width() - m.left() - m.right();
- // icon separator
- MenuSeparator *separator = new MenuSeparator(m_view);
- separator->resize(w, separator->height());
- // add separator to list widget
- QListWidgetItem *item = new QListWidgetItem(m_view);
- item->setFlags(Qt::NoItemFlags);
- item->setSizeHint(QSize(w, separator->height()));
- m_view->addItem(item);
- m_view->setItemWidget(item, separator);
- this->adjustSize();
- }
- RoundMenu *RoundMenu::parentMenu() const
- {
- return m_parentMenu;
- }
- /**
- * @brief show menu
- * @param pos: pop-up position
- * @param ani: Whether to show pop-up animation
- */
- void RoundMenu::exec(const QPoint &pos, bool ani)
- {
- if (isVisible()) {
- return;
- }
- QPoint showPos;
- QRect rect = QApplication::screenAt(QCursor::pos())->availableGeometry();
- int w = width() + 5;
- int h = height() + 5;
- showPos.setX(qMin(pos.x() - layout()->contentsMargins().left(), rect.right() - w));
- showPos.setY(qMin(pos.y() - 4, rect.bottom() - h));
- if (ani) {
- m_ani->setStartValue(showPos - QPoint(0, int(h / 2)));
- m_ani->setEndValue(pos);
- m_ani->setDuration(250);
- m_ani->setEasingCurve(QEasingCurve::OutQuad);
- m_ani->start();
- } else {
- move(showPos);
- }
- this->setWindowModality(Qt::ApplicationModal); // 设置为模态状态
- show();
- if (m_isSubMenu) {
- m_menuItem->setSelected(true);
- // temporarily disable item to change style
- MenuActionListWidget *view = m_parentMenu->view();
- int index = view->row(m_menuItem);
- if (index > 0) {
- view->item(index - 1)->setFlags(Qt::NoItemFlags);
- }
- if (index < view->count() - 1) {
- view->item(index + 1)->setFlags(Qt::NoItemFlags);
- }
- }
- // 使用事件循环QEventLoop
- // ,不让exec()方法结束,在用户选择确定或者取消后,关闭窗口结束事件循环,并返回最后用户选择的结果;
- // 根据返回结果得到用户按下了确定还是取消,采取相应的操作。从而模拟出QDialog类的exec()方法;
- m_eventLoop = new QEventLoop(this);
- m_eventLoop->exec();
- }
- SubMenuItemWidget::SubMenuItemWidget(QMenu *menu, QListWidgetItem *item, QWidget *parent)
- : QWidget(parent), m_menu(menu), m_roundMenu(nullptr), m_item(item)
- {
- }
- SubMenuItemWidget::SubMenuItemWidget(RoundMenu *menu, QListWidgetItem *item, QWidget *parent)
- : QWidget(parent), m_menu(nullptr), m_roundMenu(menu), m_item(item)
- {
- }
- void SubMenuItemWidget::enterEvent(QEvent *event)
- {
- QWidget::enterEvent(event);
- emit showMenuSig(m_item);
- }
- void SubMenuItemWidget::paintEvent(QPaintEvent * /*event*/)
- {
- QPainter painter(this);
- painter.setRenderHints(QPainter::Antialiasing);
- // draw right arrow
- // NOTE: 未完成
- QScopedPointer<FluentIcon> ficon(NEWFLICON(FluentIcon, CHEVRON_RIGHT));
- ficon->render(&painter, QRect(width() - 10, height() / 2 - 9 / 2, 9, 9));
- }
- RoundMenu *SubMenuItemWidget::roundMenu() const
- {
- return m_roundMenu;
- }
- MenuActionListWidget::MenuActionListWidget(QWidget *parent) : QListWidget(parent)
- {
- setViewportMargins(5, 6, 5, 6);
- setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- setTextElideMode(Qt::ElideNone);
- setDragEnabled(false);
- setMouseTracking(true);
- setVerticalScrollMode(ScrollPerPixel);
- setIconSize(QSize(14, 14));
- m_smoothScroll.reset(new SmoothScroll(this, Qt::Vertical));
- setStyleSheet("MenuActionListWidget{font: 14px \"Segoe UI\", \"Microsoft YaHei\"}");
- }
- void MenuActionListWidget::insertItem(int row, QListWidgetItem *item)
- {
- QListWidget::insertItem(row, item);
- adjustSize();
- }
- void MenuActionListWidget::addItem(QListWidgetItem *item)
- {
- QListWidget::addItem(item);
- adjustSize();
- }
- QListWidgetItem *MenuActionListWidget::takeItem(int row)
- {
- QListWidgetItem *item = QListWidget::takeItem(row);
- adjustSize();
- return item;
- }
- void MenuActionListWidget::adjustSize()
- {
- QSize size;
- for (int i = 0; i < this->count(); i++) {
- QSize s = this->item(i)->sizeHint();
- size.setWidth(qMax(s.width(), size.width()));
- size.setHeight(size.height() + s.height());
- }
- // adjust the height of viewport
- QSize ss = QApplication::screenAt(QCursor::pos())->availableSize();
- int w = ss.width() - 100;
- int h = ss.height() - 100;
- QSize vSize(qMin(w - 12, size.width()), qMin(h - 12, size.height()));
- viewport()->adjustSize();
- // adjust the height of list widget
- QMargins m = viewportMargins();
- size += QSize(m.left() + m.right() + 2, m.top() + m.bottom());
- size.setHeight(qMin(h, size.height() + 3));
- size.setWidth(qMin(w, size.width()));
- setFixedSize(size);
- }
- void MenuActionListWidget::setItemHeight(int height)
- {
- for (int i = 0; i < this->count(); ++i) {
- QListWidgetItem *item = this->item(i);
- item->setSizeHint(QSize(item->sizeHint().width(), height));
- }
- this->adjustSize();
- }
- void MenuActionListWidget::wheelEvent(QWheelEvent *event)
- {
- // only process the wheel events triggered by mouse
- if ((m_smoothScroll->smoothMode() == SmoothMode::NO_SMOOTH) || (abs(event->angleDelta().y()) % 120 != 0)) {
- QListWidget::wheelEvent(event);
- } else {
- m_smoothScroll->wheelEvent(event);
- }
- }
- EditMenu::EditMenu(QWidget *parent)
- : RoundMenu("", parent),
- cutAct(nullptr),
- copyAct(nullptr),
- pasteAct(nullptr),
- cancelAct(nullptr),
- selectAllAct(nullptr)
- {
- createActions();
- }
- void EditMenu::createActions()
- {
- cutAct = new QAction(QIcon(":/qfluentwidgets/images/icons/Cut_black.svg"), tr("Cut"), this);
- cutAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_X));
- copyAct = new QAction(QIcon(":/qfluentwidgets/images/icons/Copy_black.svg"), tr("Copy"), this);
- copyAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_C));
- pasteAct = new QAction(QIcon(":/qfluentwidgets/images/icons/Paste_black.svg"), tr("Paste"), this);
- pasteAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_V));
- cancelAct = new QAction(QIcon(":/qfluentwidgets/images/icons/Cancel_black.svg"), tr("Cancel"), this);
- cancelAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Z));
- selectAllAct = new QAction(tr("Select all"), this);
- selectAllAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_A));
- actionList << cutAct << copyAct << pasteAct << cancelAct << selectAllAct;
- }
- void EditMenu::exec(const QPoint &pos, bool ani)
- {
- // clear();
- // createActions();
- if (QApplication::clipboard()->mimeData()->hasText()) {
- if (!parentText().isEmpty()) {
- if (!parentSelectedText().isEmpty()) {
- addActions(actionList);
- } else {
- for (int i = 2; i < actionList.count(); ++i) {
- addAction(actionList.at(i));
- }
- }
- } else {
- addAction(pasteAct);
- }
- } else {
- if (!parentText().isEmpty()) {
- if (!parentSelectedText().isEmpty()) {
- for (int i = 0; i < actionList.count(); ++i) {
- if (i != 2) {
- addAction(actionList.at(i));
- }
- }
- } else {
- for (int i = 3; i < actionList.count(); ++i) {
- addAction(actionList.at(i));
- }
- }
- } else {
- return;
- }
- }
- RoundMenu::exec(pos, ani);
- }
- LineEditMenu::LineEditMenu(QLineEdit *parent) : EditMenu(parent)
- {
- m_selectionStart = parent->selectionStart();
- m_selectionLength = parent->selectionLength();
- }
- void LineEditMenu::onItemClicked(QListWidgetItem *item)
- {
- QLineEdit *p = qobject_cast<QLineEdit *>(parent());
- if (m_selectionStart >= 0) {
- p->setSelection(m_selectionStart, m_selectionLength);
- }
- EditMenu::onItemClicked(item);
- }
- QString LineEditMenu::parentText()
- {
- QLineEdit *p = qobject_cast<QLineEdit *>(parent());
- return p->text();
- }
- QString LineEditMenu::parentSelectedText()
- {
- QLineEdit *p = qobject_cast<QLineEdit *>(parent());
- return p->selectedText();
- }
- TextEditMenu::TextEditMenu(QTextEdit *parent) : EditMenu(parent), m_textEdit(parent), m_plainTextEdit(nullptr)
- {
- m_selectionStart = parent->textCursor().selectionStart();
- m_selectionLength = parent->textCursor().selectionEnd() - parent->textCursor().selectionStart() + 1;
- }
- TextEditMenu::TextEditMenu(QPlainTextEdit *parent) : EditMenu(parent), m_textEdit(nullptr), m_plainTextEdit(parent)
- {
- m_selectionStart = parent->textCursor().selectionStart();
- m_selectionLength = parent->textCursor().selectionEnd() - parent->textCursor().selectionStart() + 1;
- }
- void TextEditMenu::onItemClicked(QListWidgetItem *item)
- {
- if (m_selectionStart >= 0) {
- QTextCursor cursor;
- if (m_textEdit) {
- cursor = m_textEdit->textCursor();
- } else {
- cursor = m_plainTextEdit->textCursor();
- }
- cursor.setPosition(m_selectionStart);
- cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, m_selectionLength);
- }
- EditMenu::onItemClicked(item);
- }
- QString TextEditMenu::parentText()
- {
- if (m_textEdit) {
- return m_textEdit->toPlainText();
- } else {
- return m_plainTextEdit->toPlainText();
- }
- }
- QString TextEditMenu::parentSelectedText()
- {
- if (m_textEdit) {
- return m_textEdit->textCursor().selectedText();
- } else {
- return m_plainTextEdit->textCursor().selectedText();
- }
- }
|