File indexing completed on 2024-05-12 15:39:37

0001 /* This file is part of the KDE project
0002  *
0003  * Copyright (C) 2008 Bernhard Beschow <bbeschow cs tu berlin de>
0004  *           (C) 2008 Germain Garand <germain@ebooksfrance.org>
0005  *
0006  * This library is free software; you can redistribute it and/or
0007  * modify it under the terms of the GNU Library General Public
0008  * License as published by the Free Software Foundation; either
0009  * version 2 of the License, or (at your option) any later version.
0010  *
0011  * This library is distributed in the hope that it will be useful,
0012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014  * Library General Public License for more details.
0015  *
0016  * You should have received a copy of the GNU Library General Public License
0017  * along with this library; see the file COPYING.LIB.  If not, write to
0018  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0019  * Boston, MA 02110-1301, USA.
0020  */
0021 
0022 #include "khtmlfindbar.h"
0023 
0024 #include "khtml_part.h"
0025 
0026 #include <kfind.h>
0027 #include <kcolorscheme.h>
0028 
0029 #include <QKeyEvent>
0030 #include <QMenu>
0031 #include <QLineEdit>
0032 
0033 #define d this
0034 
0035 KHTMLFindBar::KHTMLFindBar(QWidget *parent) :
0036     KHTMLViewBarWidget(true, parent),
0037     m_enabled(KFind::WholeWordsOnly | KFind::FromCursor | KFind::SelectedText | KFind::CaseSensitive | KFind::FindBackwards | KFind::RegularExpression | KHTMLPart::FindLinksOnly)
0038 {
0039     setupUi(centralWidget());
0040 
0041     m_next->setIcon(QIcon::fromTheme("go-down-search"));
0042     m_previous->setIcon(QIcon::fromTheme("go-up-search"));
0043     m_next->setDisabled(true);
0044     m_previous->setDisabled(true);
0045 
0046     // Fill options menu
0047     m_incMenu = new QMenu(this);
0048     m_options->setMenu(m_incMenu);
0049     m_caseSensitive = m_incMenu->addAction(i18n("C&ase sensitive"));
0050     m_caseSensitive->setCheckable(true);
0051     m_wholeWordsOnly = m_incMenu->addAction(i18n("&Whole words only"));
0052     m_wholeWordsOnly->setCheckable(true);
0053     m_fromCursor = m_incMenu->addAction(i18n("From c&ursor"));
0054     m_fromCursor->setCheckable(true);
0055     m_selectedText = m_incMenu->addAction(i18n("&Selected text"));
0056     m_selectedText->setCheckable(true);
0057     m_regExp = m_incMenu->addAction(i18n("Regular e&xpression"));
0058     m_regExp->setCheckable(true);
0059     m_findLinksOnly = m_incMenu->addAction(i18n("Find &links only"));
0060     m_findLinksOnly->setCheckable(true);
0061 
0062     m_atEnd = false;
0063 
0064     m_find->setDuplicatesEnabled(false);
0065     centralWidget()->setFocusProxy(m_find);
0066 
0067     connect(m_selectedText, SIGNAL(toggled(bool)), this, SLOT(slotSelectedTextToggled(bool)));
0068     connect(m_find, SIGNAL(editTextChanged(QString)), this, SIGNAL(searchChanged()));
0069     connect(m_find->lineEdit(), SIGNAL(clearButtonClicked()), this, SLOT(slotAddPatternToHistory()));
0070     connect(this, SIGNAL(hideMe()), this, SLOT(slotAddPatternToHistory()));
0071     connect(this, SIGNAL(searchChanged()), this, SLOT(slotSearchChanged()));
0072     connect(m_next, SIGNAL(clicked()), this, SIGNAL(findNextClicked()));
0073     connect(m_previous, SIGNAL(clicked()), this, SIGNAL(findPreviousClicked()));
0074     connect(m_caseSensitive, SIGNAL(changed()), this, SIGNAL(searchChanged()));
0075     connect(m_wholeWordsOnly, SIGNAL(changed()), this, SIGNAL(searchChanged()));
0076     connect(m_fromCursor, SIGNAL(changed()), this, SIGNAL(searchChanged()));
0077     connect(m_regExp, SIGNAL(changed()), this, SIGNAL(searchChanged()));
0078     connect(m_findLinksOnly, SIGNAL(changed()), this, SIGNAL(searchChanged()));
0079 
0080     m_find->setFocus();
0081 }
0082 
0083 QStringList KHTMLFindBar::findHistory() const
0084 {
0085     return d->m_find->historyItems();
0086 }
0087 
0088 long KHTMLFindBar::options() const
0089 {
0090     long options = 0;
0091 
0092     if (d->m_caseSensitive->isChecked()) {
0093         options |= KFind::CaseSensitive;
0094     }
0095     if (d->m_wholeWordsOnly->isChecked()) {
0096         options |= KFind::WholeWordsOnly;
0097     }
0098     if (d->m_fromCursor->isChecked()) {
0099         options |= KFind::FromCursor;
0100     }
0101     if (d->m_selectedText->isChecked()) {
0102         options |= KFind::SelectedText;
0103     }
0104     if (d->m_regExp->isChecked()) {
0105         options |= KFind::RegularExpression;
0106     }
0107     if (d->m_findLinksOnly->isChecked()) {
0108         options |= KHTMLPart::FindLinksOnly;
0109     }
0110     return options | KHTMLPart::FindNoPopups /* | KFind::FindIncremental */;
0111 }
0112 
0113 QString KHTMLFindBar::pattern() const
0114 {
0115     return m_find->currentText();
0116 }
0117 
0118 void KHTMLFindBar::slotSearchChanged()
0119 {
0120     // reset background color of the combo box
0121     if (pattern().isEmpty()) {
0122         d->m_find->setPalette(QPalette());
0123         m_next->setDisabled(true);
0124         m_previous->setDisabled(true);
0125         m_statusLabel->clear();
0126     } else {
0127         m_prevPattern = pattern();
0128         m_next->setDisabled(false);
0129         m_previous->setDisabled(false);
0130     }
0131 }
0132 
0133 bool KHTMLFindBar::restoreLastPatternFromHistory()
0134 {
0135     if (d->m_find->historyItems().isEmpty()) {
0136         return false;
0137     }
0138     d->m_find->lineEdit()->setText(d->m_find->historyItems().first());
0139     return true;
0140 }
0141 
0142 void KHTMLFindBar::setFindHistory(const QStringList &strings)
0143 {
0144     if (strings.count() > 0) {
0145         d->m_find->setHistoryItems(strings, true);
0146         //d->m_find->lineEdit()->setText( strings.first() );
0147         //d->m_find->lineEdit()->selectAll();
0148     } else {
0149         d->m_find->clearHistory();
0150     }
0151 }
0152 
0153 void KHTMLFindBar::setHasSelection(bool hasSelection)
0154 {
0155     if (hasSelection) {
0156         d->m_enabled |= KFind::SelectedText;
0157     } else {
0158         d->m_enabled &= ~KFind::SelectedText;
0159     }
0160     d->m_selectedText->setEnabled(hasSelection);
0161     if (!hasSelection) {
0162         d->m_selectedText->setChecked(false);
0163         slotSelectedTextToggled(hasSelection);
0164     }
0165 }
0166 
0167 void KHTMLFindBar::slotAddPatternToHistory()
0168 {
0169     bool patternIsEmpty = pattern().isEmpty();
0170     if (!patternIsEmpty || !m_prevPattern.isEmpty()) {
0171         d->m_find->addToHistory(pattern().isEmpty() ? m_prevPattern : pattern());
0172         if (patternIsEmpty && !pattern().isEmpty()) {
0173             // ### Hack - addToHistory sometimes undo the clearing of the lineEdit
0174             // with clear button. Clear it again.
0175             bool sb = d->m_find->blockSignals(true);
0176             d->m_find->lineEdit()->setText(QString());
0177             d->m_find->blockSignals(sb);
0178         }
0179         m_prevPattern.clear();
0180     }
0181 }
0182 
0183 void KHTMLFindBar::slotSelectedTextToggled(bool selec)
0184 {
0185     // From cursor doesn't make sense if we have a selection
0186     m_fromCursor->setEnabled(!selec && (m_enabled & KFind::FromCursor));
0187     if (selec) { // uncheck if disabled
0188         m_fromCursor->setChecked(false);
0189     }
0190 }
0191 
0192 void KHTMLFindBar::setHasCursor(bool hasCursor)
0193 {
0194     if (hasCursor) {
0195         d->m_enabled |= KFind::FromCursor;
0196     } else {
0197         d->m_enabled &= ~KFind::FromCursor;
0198     }
0199     d->m_fromCursor->setEnabled(hasCursor);
0200     d->m_fromCursor->setChecked(hasCursor && (options() & KFind::FromCursor));
0201 }
0202 
0203 void KHTMLFindBar::setOptions(long options)
0204 {
0205     d->m_caseSensitive->setChecked((d->m_enabled & KFind::CaseSensitive) && (options & KFind::CaseSensitive));
0206     d->m_wholeWordsOnly->setChecked((d->m_enabled & KFind::WholeWordsOnly) && (options & KFind::WholeWordsOnly));
0207     d->m_fromCursor->setChecked((d->m_enabled & KFind::FromCursor) && (options & KFind::FromCursor));
0208     d->m_selectedText->setChecked((d->m_enabled & KFind::SelectedText) && (options & KFind::SelectedText));
0209     d->m_regExp->setChecked((d->m_enabled & KFind::RegularExpression) && (options & KFind::RegularExpression));
0210     d->m_findLinksOnly->setChecked((d->m_enabled & KHTMLPart::FindLinksOnly) && (options & KHTMLPart::FindLinksOnly));
0211 }
0212 
0213 void KHTMLFindBar::setFoundMatch(bool match)
0214 {
0215     if (pattern().isEmpty()) {
0216         m_find->setPalette(QPalette());
0217         m_next->setDisabled(true);
0218         m_previous->setDisabled(true);
0219         m_statusLabel->clear();
0220     } else if (!match) {
0221         QPalette newPal(m_find->palette());
0222         KColorScheme::adjustBackground(newPal, KColorScheme::NegativeBackground);
0223         m_find->setPalette(newPal);
0224         m_statusLabel->setText(i18n("Not found"));
0225     } else {
0226         QPalette newPal(m_find->palette());
0227         KColorScheme::adjustBackground(newPal, KColorScheme::PositiveBackground);
0228         m_find->setPalette(newPal);
0229         m_statusLabel->clear();
0230     }
0231 }
0232 
0233 void KHTMLFindBar::setAtEnd(bool atEnd)
0234 {
0235     if (atEnd == m_atEnd) {
0236         return;
0237     }
0238     if (atEnd) {
0239         m_statusLabel->setText(i18n("No more matches for this search direction."));
0240     } else {
0241         m_statusLabel->clear();
0242     }
0243     m_atEnd = atEnd;
0244 }
0245 
0246 void KHTMLFindBar::setVisible(bool visible)
0247 {
0248     KHTMLViewBarWidget::setVisible(visible);
0249 
0250     if (visible) {
0251         m_find->setFocus(Qt::ActiveWindowFocusReason);
0252         m_find->lineEdit()->selectAll();
0253     }
0254 }
0255 
0256 bool KHTMLFindBar::event(QEvent *e)
0257 {
0258     // Close the bar when pressing Escape.
0259     // Not using a QShortcut for this because it could conflict with
0260     // window-global actions (e.g. Emil Sedgh binds Esc to "close tab").
0261     // With a shortcut override we can catch this before it gets to kactions.
0262     if (e->type() == QEvent::ShortcutOverride) {
0263         QKeyEvent *kev = static_cast<QKeyEvent * >(e);
0264         if (kev->key() == Qt::Key_Escape) {
0265             e->accept();
0266             emit hideMe();
0267             return true;
0268         }
0269     }
0270     return KHTMLViewBarWidget::event(e);
0271 }
0272 
0273 #include "moc_khtmlfindbar.cpp"