1 /*
2 SPDX-FileCopyrightText: 2007 Pino Toscano <pino@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "presentationsearchbar.h"
8
9 #include <qevent.h>
10 #include <qlayout.h>
11 #include <qpushbutton.h>
12 #include <qstyle.h>
13 #include <qstyleoption.h>
14 #include <qstylepainter.h>
15 #include <qtoolbutton.h>
16
17 #include <KLocalizedString>
18 #include <QIcon>
19
20 #include "searchlineedit.h"
21
22 #define SNAP_DELTA 15
23
24 class HandleDrag : public QWidget
25 {
26 Q_OBJECT
27
28 public:
HandleDrag(QWidget * parent=Q_NULLPTR)29 explicit HandleDrag(QWidget *parent = Q_NULLPTR)
30 : QWidget(parent)
31 {
32 setCursor(Qt::SizeAllCursor);
33 setFixedWidth(style()->pixelMetric(QStyle::PM_ToolBarHandleExtent));
34 }
35
paintEvent(QPaintEvent *)36 void paintEvent(QPaintEvent *) override
37 {
38 QStyleOption opt;
39 opt.initFrom(this);
40 opt.state |= QStyle::State_Horizontal;
41 QStylePainter p(this);
42 p.drawPrimitive(QStyle::PE_IndicatorToolBarHandle, opt);
43 }
44 };
45
PresentationSearchBar(Okular::Document * document,QWidget * anchor,QWidget * parent)46 PresentationSearchBar::PresentationSearchBar(Okular::Document *document, QWidget *anchor, QWidget *parent)
47 : QWidget(parent)
48 , m_anchor(anchor)
49 , m_snapped(true)
50 {
51 setAutoFillBackground(true);
52
53 QHBoxLayout *lay = new QHBoxLayout(this);
54 lay->setContentsMargins(0, 0, 0, 0);
55
56 m_handle = new HandleDrag(this);
57 m_handle->installEventFilter(this);
58 lay->addWidget(m_handle);
59
60 QToolButton *closeBtn = new QToolButton(this);
61 closeBtn->setIcon(QIcon::fromTheme(QStringLiteral("dialog-close")));
62 closeBtn->setIconSize(QSize(24, 24));
63 closeBtn->setToolTip(i18n("Close"));
64 closeBtn->setAutoRaise(true);
65 lay->addWidget(closeBtn);
66
67 m_search = new SearchLineEdit(this, document);
68 m_search->setClearButtonEnabled(true);
69 m_search->setSearchCaseSensitivity(Qt::CaseInsensitive);
70 m_search->setSearchMinimumLength(0);
71 m_search->setSearchType(Okular::Document::NextMatch);
72 m_search->setSearchId(PRESENTATION_SEARCH_ID);
73 m_search->setSearchColor(qRgb(255, 255, 64));
74 m_search->setSearchMoveViewport(true);
75 lay->addWidget(m_search);
76
77 QPushButton *findNextBtn = new QPushButton(QIcon::fromTheme(QStringLiteral("go-down-search")), i18n("Find Next"), this);
78 lay->addWidget(findNextBtn);
79
80 m_anchor->installEventFilter(this);
81
82 connect(closeBtn, &QAbstractButton::clicked, this, &QWidget::close);
83 connect(findNextBtn, &QPushButton::clicked, m_search, &SearchLineEdit::findNext);
84 }
85
~PresentationSearchBar()86 PresentationSearchBar::~PresentationSearchBar()
87 {
88 }
89
forceSnap()90 void PresentationSearchBar::forceSnap()
91 {
92 m_point = QPoint(m_anchor->width() / 2, m_anchor->height());
93 m_snapped = true;
94 move(m_point.x() - width() / 2, m_point.y() - height());
95 }
96
focusOnSearchEdit()97 void PresentationSearchBar::focusOnSearchEdit()
98 {
99 m_search->setFocus();
100 }
101
resizeEvent(QResizeEvent *)102 void PresentationSearchBar::resizeEvent(QResizeEvent *)
103 {
104 // if in snap mode, then force the snap and place ourselves correctly again
105 if (m_snapped)
106 forceSnap();
107 }
108
eventFilter(QObject * obj,QEvent * e)109 bool PresentationSearchBar::eventFilter(QObject *obj, QEvent *e)
110 {
111 if (obj == m_handle && (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease || e->type() == QEvent::MouseMove)) {
112 QMouseEvent *me = (QMouseEvent *)e;
113 if (e->type() == QEvent::MouseButtonPress) {
114 m_drag = m_handle->mapTo(this, me->pos());
115 } else if (e->type() == QEvent::MouseButtonRelease) {
116 m_drag = QPoint();
117 } else if (e->type() == QEvent::MouseMove) {
118 QPoint snapdelta(width() / 2, height());
119 QPoint delta = m_handle->mapTo(this, me->pos()) - m_drag;
120 QPoint newpostemp = pos() + delta;
121 QPoint tmp = newpostemp + snapdelta - m_point;
122 QPoint newpos = abs(tmp.x()) < SNAP_DELTA && abs(tmp.y()) < SNAP_DELTA ? m_point - snapdelta : newpostemp;
123 m_snapped = newpos == (m_point - snapdelta);
124 move(newpos);
125 }
126 return true;
127 }
128 if (obj == m_anchor && e->type() == QEvent::Resize) {
129 m_point = QPoint(m_anchor->width() / 2, m_anchor->height());
130
131 if (m_snapped)
132 move(m_point.x() - width() / 2, m_point.y() - height());
133 }
134
135 return false;
136 }
137
138 #include "presentationsearchbar.moc"
139