/src/item/itemwidget.cpp
C++ | 304 lines | 224 code | 57 blank | 23 comment | 26 complexity | 628fd71ff40fa06a922abf691a96312b MD5 | raw file
Possible License(s): GPL-3.0, BSD-3-Clause
- /*
- Copyright (c) 2020, Lukas Holecek <hluk@email.cz>
- This file is part of CopyQ.
- CopyQ is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- CopyQ is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with CopyQ. If not, see <http://www.gnu.org/licenses/>.
- */
- #include "itemwidget.h"
- #include "common/command.h"
- #include "common/contenttype.h"
- #include "common/mimetypes.h"
- #include "item/itemeditor.h"
- #include <QAbstractItemModel>
- #include <QApplication>
- #include <QDesktopServices>
- #include <QEvent>
- #include <QMimeData>
- #include <QModelIndex>
- #include <QMouseEvent>
- #include <QTextEdit>
- #include <QUrl>
- #include <QWidget>
- namespace {
- bool canMouseInteract(const QMouseEvent &event)
- {
- return event.modifiers() & Qt::ShiftModifier;
- }
- } // namespace
- ItemWidget::ItemWidget(QWidget *widget)
- : m_widget(widget)
- {
- Q_ASSERT(widget != nullptr);
- // Object name for style sheet.
- widget->setObjectName("item");
- // Item widgets are not focusable.
- widget->setFocusPolicy(Qt::NoFocus);
- // Limit size of items.
- widget->setMaximumSize(2048, 2048);
- // Disable drag'n'drop by default.
- widget->setAcceptDrops(false);
- }
- void ItemWidget::updateSize(QSize maximumSize, int idealWidth)
- {
- QWidget *w = widget();
- w->setMaximumSize(maximumSize);
- const int idealHeight = w->heightForWidth(idealWidth);
- const int maximumHeight = w->heightForWidth(maximumSize.width());
- if (idealHeight <= 0 && maximumHeight <= 0)
- w->resize(w->sizeHint());
- else if (idealHeight != maximumHeight)
- w->setFixedSize( maximumSize.width(), maximumHeight );
- else
- w->setFixedSize(idealWidth, idealHeight);
- }
- void ItemWidget::setCurrent(bool current)
- {
- // Propagate mouse events to item list until the item is selected.
- widget()->setAttribute(Qt::WA_TransparentForMouseEvents, !current);
- }
- bool ItemWidget::filterMouseEvents(QTextEdit *edit, QEvent *event)
- {
- const auto type = event->type();
- bool allowMouseInteraction = true;
- switch (type) {
- case QEvent::Enter:
- edit->setMouseTracking(true);
- edit->viewport()->setCursor( QCursor() );
- return false;
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonDblClick: {
- QMouseEvent *e = static_cast<QMouseEvent*>(event);
- if ( !canMouseInteract(*e) )
- allowMouseInteraction = false;
- else if (e->button() == Qt::LeftButton)
- edit->setTextCursor( edit->cursorForPosition(e->pos()) );
- break;
- }
- case QEvent::MouseMove: {
- QMouseEvent *e = static_cast<QMouseEvent*>(event);
- if ( !canMouseInteract(*e) )
- allowMouseInteraction = false;
- break;
- }
- case QEvent::MouseButtonRelease: {
- QMouseEvent *e = static_cast<QMouseEvent*>(event);
- if ( canMouseInteract(*e) && edit->textCursor().hasSelection() )
- edit->copy();
- allowMouseInteraction = false;
- break;
- }
- default:
- return false;
- }
- Qt::TextInteractionFlags flags = edit->textInteractionFlags();
- if (allowMouseInteraction) {
- flags |= Qt::TextSelectableByMouse;
- flags |= Qt::LinksAccessibleByMouse;
- } else {
- flags &= ~Qt::TextSelectableByMouse;
- flags &= ~Qt::LinksAccessibleByMouse;
- }
- edit->setTextInteractionFlags(flags);
- if (type == QEvent::MouseButtonPress || type == QEvent::MouseMove) {
- const auto e = static_cast<QMouseEvent*>(event);
- if (allowMouseInteraction) {
- const auto anchor = edit->anchorAt(e->pos());
- if ( anchor.isEmpty() ) {
- edit->viewport()->setCursor( QCursor(Qt::IBeamCursor) );
- } else {
- edit->viewport()->setCursor( QCursor(Qt::PointingHandCursor) );
- if (type == QEvent::MouseButtonPress) {
- QDesktopServices::openUrl( QUrl(anchor) );
- e->accept();
- return true;
- }
- }
- } else {
- edit->viewport()->setCursor( QCursor() );
- }
- }
- return false;
- }
- QVariant ItemScriptable::call(const QString &method, const QVariantList &arguments)
- {
- QVariant result;
- QMetaObject::invokeMethod(
- m_scriptable, "call", Qt::DirectConnection,
- Q_RETURN_ARG(QVariant, result),
- Q_ARG(QString, method),
- Q_ARG(QVariantList, arguments));
- return result;
- }
- QVariant ItemScriptable::eval(const QString &script)
- {
- return call("eval", QVariantList() << script);
- }
- QVariantList ItemScriptable::currentArguments()
- {
- QVariantList arguments;
- QMetaObject::invokeMethod(
- m_scriptable, "currentArguments", Qt::DirectConnection,
- Q_RETURN_ARG(QVariantList, arguments) );
- return arguments;
- }
- void ItemScriptable::throwError(const QString &message)
- {
- QMetaObject::invokeMethod(
- m_scriptable, "throwException", Qt::DirectConnection,
- Q_ARG(QString, message) );
- }
- bool ItemSaverInterface::saveItems(const QString &, const QAbstractItemModel &, QIODevice *)
- {
- return false;
- }
- bool ItemSaverInterface::canRemoveItems(const QList<QModelIndex> &, QString *)
- {
- return true;
- }
- bool ItemSaverInterface::canDropItem(const QModelIndex &)
- {
- return true;
- }
- bool ItemSaverInterface::canMoveItems(const QList<QModelIndex> &)
- {
- return true;
- }
- void ItemSaverInterface::itemsRemovedByUser(const QList<QModelIndex> &)
- {
- }
- QVariantMap ItemSaverInterface::copyItem(const QAbstractItemModel &, const QVariantMap &itemData)
- {
- return itemData;
- }
- void ItemSaverInterface::setFocus(bool)
- {
- }
- ItemWidget *ItemLoaderInterface::create(const QVariantMap &, QWidget *, bool) const
- {
- return nullptr;
- }
- bool ItemLoaderInterface::canLoadItems(QIODevice *) const
- {
- return false;
- }
- bool ItemLoaderInterface::canSaveItems(const QString &) const
- {
- return false;
- }
- ItemSaverPtr ItemLoaderInterface::loadItems(const QString &, QAbstractItemModel *, QIODevice *, int)
- {
- return nullptr;
- }
- ItemSaverPtr ItemLoaderInterface::initializeTab(const QString &, QAbstractItemModel *, int)
- {
- return nullptr;
- }
- ItemWidget *ItemLoaderInterface::transform(ItemWidget *, const QVariantMap &)
- {
- return nullptr;
- }
- ItemSaverPtr ItemLoaderInterface::transformSaver(const ItemSaverPtr &saver, QAbstractItemModel *)
- {
- return saver;
- }
- bool ItemLoaderInterface::matches(const QModelIndex &, const ItemFilter &) const
- {
- return false;
- }
- QObject *ItemLoaderInterface::tests(const TestInterfacePtr &) const
- {
- return nullptr;
- }
- const QObject *ItemLoaderInterface::signaler() const
- {
- return nullptr;
- }
- ItemScriptable *ItemLoaderInterface::scriptableObject()
- {
- return nullptr;
- }
- QVector<Command> ItemLoaderInterface::commands() const
- {
- return QVector<Command>();
- }
- bool ItemLoaderInterface::data(QVariantMap *, const QModelIndex &) const
- {
- return true;
- }
- bool ItemLoaderInterface::setData(const QVariantMap &, const QModelIndex &, QAbstractItemModel *) const
- {
- return false;
- }
- QObject *ItemLoaderInterface::createExternalEditor(const QModelIndex &, const QVariantMap &, QWidget *) const
- {
- return nullptr;
- }