File indexing completed on 2024-04-28 15:51:55

0001 /*
0002     SPDX-FileCopyrightText: 2007 Pino Toscano <pino@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "presentationsearchbar.h"
0008 
0009 #include <qevent.h>
0010 #include <qlayout.h>
0011 #include <qpushbutton.h>
0012 #include <qstyle.h>
0013 #include <qstyleoption.h>
0014 #include <qstylepainter.h>
0015 #include <qtoolbutton.h>
0016 
0017 #include <KLocalizedString>
0018 #include <QIcon>
0019 
0020 #include "searchlineedit.h"
0021 
0022 #define SNAP_DELTA 15
0023 
0024 class HandleDrag : public QWidget
0025 {
0026     Q_OBJECT
0027 
0028 public:
0029     explicit HandleDrag(QWidget *parent = Q_NULLPTR)
0030         : QWidget(parent)
0031     {
0032         setCursor(Qt::SizeAllCursor);
0033         setFixedWidth(style()->pixelMetric(QStyle::PM_ToolBarHandleExtent));
0034     }
0035 
0036     void paintEvent(QPaintEvent *) override
0037     {
0038         QStyleOption opt;
0039         opt.initFrom(this);
0040         opt.state |= QStyle::State_Horizontal;
0041         QStylePainter p(this);
0042         p.drawPrimitive(QStyle::PE_IndicatorToolBarHandle, opt);
0043     }
0044 };
0045 
0046 PresentationSearchBar::PresentationSearchBar(Okular::Document *document, QWidget *anchor, QWidget *parent)
0047     : QWidget(parent)
0048     , m_anchor(anchor)
0049     , m_snapped(true)
0050 {
0051     setAutoFillBackground(true);
0052 
0053     QHBoxLayout *lay = new QHBoxLayout(this);
0054     lay->setContentsMargins(0, 0, 0, 0);
0055 
0056     m_handle = new HandleDrag(this);
0057     m_handle->installEventFilter(this);
0058     lay->addWidget(m_handle);
0059 
0060     QToolButton *closeBtn = new QToolButton(this);
0061     closeBtn->setIcon(QIcon::fromTheme(QStringLiteral("dialog-close")));
0062     closeBtn->setIconSize(QSize(24, 24));
0063     closeBtn->setToolTip(i18n("Close"));
0064     closeBtn->setAutoRaise(true);
0065     lay->addWidget(closeBtn);
0066 
0067     m_search = new SearchLineEdit(this, document);
0068     m_search->setClearButtonEnabled(true);
0069     m_search->setSearchCaseSensitivity(Qt::CaseInsensitive);
0070     m_search->setSearchMinimumLength(0);
0071     m_search->setSearchType(Okular::Document::NextMatch);
0072     m_search->setSearchId(PRESENTATION_SEARCH_ID);
0073     m_search->setSearchColor(qRgb(255, 255, 64));
0074     m_search->setSearchMoveViewport(true);
0075     lay->addWidget(m_search);
0076 
0077     QPushButton *findNextBtn = new QPushButton(QIcon::fromTheme(QStringLiteral("go-down-search")), i18n("Find Next"), this);
0078     lay->addWidget(findNextBtn);
0079 
0080     m_anchor->installEventFilter(this);
0081 
0082     connect(closeBtn, &QAbstractButton::clicked, this, &QWidget::close);
0083     connect(findNextBtn, &QPushButton::clicked, m_search, &SearchLineEdit::findNext);
0084 }
0085 
0086 PresentationSearchBar::~PresentationSearchBar()
0087 {
0088 }
0089 
0090 void PresentationSearchBar::forceSnap()
0091 {
0092     m_point = QPoint(m_anchor->width() / 2, m_anchor->height());
0093     m_snapped = true;
0094     move(m_point.x() - width() / 2, m_point.y() - height());
0095 }
0096 
0097 void PresentationSearchBar::focusOnSearchEdit()
0098 {
0099     m_search->setFocus();
0100 }
0101 
0102 void PresentationSearchBar::resizeEvent(QResizeEvent *)
0103 {
0104     // if in snap mode, then force the snap and place ourselves correctly again
0105     if (m_snapped) {
0106         forceSnap();
0107     }
0108 }
0109 
0110 bool PresentationSearchBar::eventFilter(QObject *obj, QEvent *e)
0111 {
0112     if (obj == m_handle && (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease || e->type() == QEvent::MouseMove)) {
0113         QMouseEvent *me = (QMouseEvent *)e;
0114         if (e->type() == QEvent::MouseButtonPress) {
0115             m_drag = m_handle->mapTo(this, me->pos());
0116         } else if (e->type() == QEvent::MouseButtonRelease) {
0117             m_drag = QPoint();
0118         } else if (e->type() == QEvent::MouseMove) {
0119             QPoint snapdelta(width() / 2, height());
0120             QPoint delta = m_handle->mapTo(this, me->pos()) - m_drag;
0121             QPoint newpostemp = pos() + delta;
0122             QPoint tmp = newpostemp + snapdelta - m_point;
0123             QPoint newpos = abs(tmp.x()) < SNAP_DELTA && abs(tmp.y()) < SNAP_DELTA ? m_point - snapdelta : newpostemp;
0124             m_snapped = newpos == (m_point - snapdelta);
0125             move(newpos);
0126         }
0127         return true;
0128     }
0129     if (obj == m_anchor && e->type() == QEvent::Resize) {
0130         m_point = QPoint(m_anchor->width() / 2, m_anchor->height());
0131 
0132         if (m_snapped) {
0133             move(m_point.x() - width() / 2, m_point.y() - height());
0134         }
0135     }
0136 
0137     return false;
0138 }
0139 
0140 #include "presentationsearchbar.moc"