1 /***************************************************************************
2  *   Copyright (C) 2011 by Francesco Nwokeka <francesco.nwokeka@gmail.com> *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  *                                                                         *
9  *   This program is distributed in the hope that it will be useful,       *
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12  *   GNU General Public License for more details.                          *
13  *                                                                         *
14  *   You should have received a copy of the GNU General Public License     *
15  *   along with this program; if not, write to the                         *
16  *   Free Software Foundation, Inc.,                                       *
17  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
18  ***************************************************************************/
19 
20 #include "chat-search-bar.h"
21 
22 #include <KColorScheme>
23 #include <KLocalizedString>
24 
25 #include <QPushButton>
26 #include <QLineEdit>
27 #include <QAction>
28 #include <QCheckBox>
29 #include <QDebug>
30 #include <QHBoxLayout>
31 #include <QToolButton>
32 
33 #include <QKeyEvent>
34 
ChatSearchBar(QWidget * parent)35 ChatSearchBar::ChatSearchBar(QWidget *parent)
36     : QWidget(parent)
37     , m_searchInput(new QLineEdit(this))
38     , m_closeButton(new QToolButton(this))
39     , m_nextButton(new QPushButton(QIcon::fromTheme(QStringLiteral("go-down-search")), i18nc("Next search result" ,"&Next"), this))
40     , m_previousButton(new QPushButton(QIcon::fromTheme(QStringLiteral("go-up-search")), i18nc("Previous search result" ,"&Previous"), this))
41     , m_caseSensitive(false)
42 {
43     // close button setup
44     m_closeButton->setAutoRaise(true);
45     m_closeButton->setIcon(QIcon::fromTheme(QStringLiteral("dialog-close")));
46     connect(m_closeButton, SIGNAL(clicked(bool)), this, SLOT(toggleView(bool)));
47 
48     // search line setup
49     m_searchInput->setPlaceholderText(i18n("Insert search text..."));
50 
51     // search arrows, start disabled
52     enableSearchButtons(false);
53 
54     connect(m_nextButton, SIGNAL(clicked()), this, SLOT(onNextButtonClicked()));
55     connect(m_previousButton, SIGNAL(clicked()), this, SLOT(onPreviousButtonClicked()));
56 
57     // options for search criteria
58     QCheckBox *caseSensitiveAction = new QCheckBox(i18n("Case sensitive"), this);
59 
60     connect(caseSensitiveAction, SIGNAL(clicked(bool)), this, SLOT(toggleCaseSensitive(bool)));
61 
62     // text changed signal
63     connect(m_searchInput, SIGNAL(textChanged(QString)), this, SLOT(textChanged(QString)));
64 
65     QHBoxLayout *layout = new QHBoxLayout(this);
66     layout->setContentsMargins(2, 0, 2, 0);
67     layout->addWidget(m_closeButton);
68     layout->setAlignment(m_closeButton, Qt::AlignLeft | Qt::AlignTop);
69 
70     layout->addWidget(m_searchInput);
71     layout->addWidget(m_nextButton);
72     layout->addWidget(m_previousButton);
73     layout->addWidget(caseSensitiveAction);
74 
75     setLayout(layout);
76 
77     // start hidden
78     hide();
79 }
80 
~ChatSearchBar()81 ChatSearchBar::~ChatSearchBar()
82 {
83 
84 }
85 
enableSearchButtons(bool enable)86 void ChatSearchBar::enableSearchButtons(bool enable)
87 {
88     m_nextButton->setEnabled(enable);
89     m_previousButton->setEnabled(enable);
90     Q_EMIT enableSearchButtonsSignal(enable);
91 }
92 
findFlags()93 QWebEnginePage::FindFlags ChatSearchBar::findFlags()
94 {
95     QWebEnginePage::FindFlags flags;
96 
97     if(m_caseSensitive) {
98         flags |= QWebEnginePage::FindCaseSensitively;
99     }
100     return flags;
101 }
102 
searchBar() const103 QLineEdit *ChatSearchBar::searchBar() const
104 {
105     return m_searchInput;
106 }
107 
onNextButtonClicked()108 void ChatSearchBar::onNextButtonClicked()
109 {
110     // no need to call this if search bar is hidden
111     if(isVisible()) {
112         Q_EMIT findNextSignal(m_searchInput->text(), findFlags());
113     }
114 }
115 
onPreviousButtonClicked()116 void ChatSearchBar::onPreviousButtonClicked()
117 {
118     // no need to call this if search bar is hidden
119     if(isVisible()) {
120         Q_EMIT findPreviousSignal(m_searchInput->text(), findFlags());
121     }
122 }
123 
onSearchTextComplete(bool found)124 void ChatSearchBar::onSearchTextComplete(bool found)
125 {
126     if(found || m_searchInput->text().isEmpty()) {
127         KColorScheme scheme(QPalette::Active, KColorScheme::View);
128         QColor background = scheme.background(KColorScheme::NormalBackground).color();
129 
130         if(m_searchInput->palette().color(QPalette::Base) != background) {
131             QPalette p = m_searchInput->palette();
132             p.setColor(QPalette::Base, background);
133             m_searchInput->setPalette(p);
134         }
135     } else {
136         KColorScheme scheme(QPalette::Active, KColorScheme::Window);
137         QColor background = scheme.foreground(KColorScheme::ActiveText).color();
138 
139         // check for empty text as well. It's not to be considered as "text not found"
140         if(m_searchInput->palette().color(QPalette::Base) != background && !m_searchInput->text().isEmpty()) {
141             QPalette p = m_searchInput->palette();
142             p.setColor(QPalette::Base, background);
143             m_searchInput->setPalette(p);
144         }
145     }
146 }
147 
toggleView(bool toggle)148 void ChatSearchBar::toggleView(bool toggle)
149 {
150     if(!toggle) {
151         m_searchInput->clear();
152         hide();
153     } else {
154         show();
155         m_searchInput->setFocus();
156     }
157 }
158 
event(QEvent * e)159 bool ChatSearchBar::event(QEvent *e)
160 {
161     if (e->type() == QEvent::ShortcutOverride && static_cast<QKeyEvent*>(e)->key() == Qt::Key_Escape) {
162         if (isVisible()) {
163             setVisible(false);
164             e->accept();
165             return true;
166         }
167     }
168     return QWidget::event(e);
169 }
170 
textChanged(const QString & text)171 void ChatSearchBar::textChanged(const QString& text)
172 {
173     // enable/disable next and previous buttons
174     if (!m_searchInput->text().isEmpty()) {
175         enableSearchButtons(true);
176     } else {
177         enableSearchButtons(false);
178     }
179     Q_EMIT findTextSignal(text, findFlags());
180 }
181 
toggleCaseSensitive(bool toggle)182 void ChatSearchBar::toggleCaseSensitive(bool toggle)
183 {
184     m_caseSensitive = toggle;
185     Q_EMIT flagsChangedSignal(m_searchInput->text(), findFlags());
186 }
187