source: branches/vendor/trolltech/qt/current/tools/assistant/lib/qhelpsearchquerywidget.cpp @ 2

Last change on this file since 2 was 2, checked in by Dmitry A. Kuminov, 13 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 11.9 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information (qt-info@nokia.com)
5**
6** This file is part of the Qt Assistant of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file.  Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file.  Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at qt-sales@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qhelpsearchquerywidget.h"
43
44#include <QtCore/QDebug>
45
46#include <QtCore/QObject>
47#include <QtCore/QStringList>
48
49#include <QtGui/QLabel>
50#include <QtGui/QLayout>
51#include <QtGui/QLineEdit>
52#include <QtGui/QFocusEvent>
53#include <QtGui/QPushButton>
54#include <QtGui/QToolButton>
55
56QT_BEGIN_NAMESPACE
57
58class QHelpSearchQueryWidgetPrivate : public QObject
59{
60    Q_OBJECT
61
62private:
63    QHelpSearchQueryWidgetPrivate()
64        : QObject()
65    {
66        searchButton = 0;
67        advancedSearchWidget = 0;
68        showHideAdvancedSearchButton = 0;
69        defaultQuery = 0;
70        exactQuery = 0;
71        similarQuery = 0;
72        withoutQuery = 0;
73        allQuery = 0;
74        atLeastQuery = 0;
75    }
76
77    ~QHelpSearchQueryWidgetPrivate()
78    {
79        // nothing todo
80    }
81
82    QString escapeString(const QString &text)
83    {
84        QString retValue = text;
85        const QString escape(QLatin1String("\\"));
86        QStringList escapableCharsList;
87        escapableCharsList << QLatin1String("\\") << QLatin1String("+")
88            << QLatin1String("-") << QLatin1String("!") << QLatin1String("(")
89            << QLatin1String(")") << QLatin1String(":") << QLatin1String("^")
90            << QLatin1String("[") << QLatin1String("]") << QLatin1String("{")
91            << QLatin1String("}") << QLatin1String("~");
92
93        // make sure we won't end up with an empty string
94        foreach (const QString escapeChar, escapableCharsList) {
95            if (retValue.contains(escapeChar))
96                retValue.replace(escapeChar, QLatin1String(""));
97        }
98        if (retValue.trimmed().isEmpty())
99            return retValue;
100
101        retValue = text; // now realy escape the string...
102        foreach (const QString escapeChar, escapableCharsList) {
103            if (retValue.contains(escapeChar))
104                retValue.replace(escapeChar, escape + escapeChar);
105        }
106        return retValue;
107    }
108
109    QStringList buildTermList(const QString query)
110    {
111        bool s = false;
112        QString phrase;
113        QStringList wordList;
114        QString searchTerm = query;
115
116        for (int i = 0; i < searchTerm.length(); ++i) {
117            if (searchTerm[i] == QLatin1Char('\"') && !s) {
118                s = true;
119                phrase = searchTerm[i];
120                continue;
121            }
122            if (searchTerm[i] != QLatin1Char('\"') && s)
123                phrase += searchTerm[i];
124            if (searchTerm[i] == QLatin1Char('\"') && s) {
125                s = false;
126                phrase += searchTerm[i];
127                wordList.append(phrase);
128                searchTerm.remove(phrase);
129            }
130        }
131        if (s)
132            searchTerm.replace(phrase, phrase.mid(1));
133
134        const QRegExp exp(QLatin1String("\\s+"));
135        wordList += searchTerm.split(exp, QString::SkipEmptyParts);
136        return wordList;
137    }
138
139private slots:
140    void showHideAdvancedSearch()
141    {
142        bool hidden = advancedSearchWidget->isHidden();
143        if (hidden) {
144            advancedSearchWidget->show();
145            showHideAdvancedSearchButton->setText((QLatin1String("-")));
146        } else {
147            advancedSearchWidget->hide();
148            showHideAdvancedSearchButton->setText((QLatin1String("+")));
149        }
150
151        defaultQuery->setEnabled(!hidden);
152    }
153
154private:
155    friend class QHelpSearchQueryWidget;
156
157    QPushButton *searchButton;
158    QWidget* advancedSearchWidget;
159    QToolButton *showHideAdvancedSearchButton;
160    QLineEdit *defaultQuery;
161    QLineEdit *exactQuery;
162    QLineEdit *similarQuery;
163    QLineEdit *withoutQuery;
164    QLineEdit *allQuery;
165    QLineEdit *atLeastQuery;
166};
167
168#include "qhelpsearchquerywidget.moc"
169
170
171/*!
172    \class QHelpSearchQueryWidget
173    \since 4.4
174    \inmodule QtHelp
175    \brief The QHelpSearchQueryWidget class provides a simple line edit or
176    an advanced widget to enable the user to input a search term in a
177    standardized input mask.
178*/
179
180/*!
181    \fn void QHelpSearchQueryWidget::search()
182
183    This signal is emitted when a the user has the search button invoked.
184    After reciving the signal you can ask the QHelpSearchQueryWidget for the build list
185    of QHelpSearchQuery's that you may pass to the QHelpSearchEngine's search() function.
186*/
187
188/*!
189    Constructs a new search query widget with the given \a parent.
190*/
191QHelpSearchQueryWidget::QHelpSearchQueryWidget(QWidget *parent)
192    : QWidget(parent)
193{
194    d = new QHelpSearchQueryWidgetPrivate();
195
196    QVBoxLayout *vLayout = new QVBoxLayout(this);
197    vLayout->setMargin(0);
198
199    QHBoxLayout* hBoxLayout = new QHBoxLayout();
200    QLabel *label = new QLabel(tr("Search for:"), this);
201    d->defaultQuery = new QLineEdit(this);
202    d->searchButton = new QPushButton(tr("Search"), this);
203    hBoxLayout->addWidget(label);
204    hBoxLayout->addWidget(d->defaultQuery);
205    hBoxLayout->addWidget(d->searchButton);
206
207    vLayout->addLayout(hBoxLayout);
208
209    connect(d->searchButton, SIGNAL(clicked()), this, SIGNAL(search()));
210    connect(d->defaultQuery, SIGNAL(returnPressed()), this, SIGNAL(search()));
211
212#if defined(QT_CLUCENE_SUPPORT)
213    hBoxLayout = new QHBoxLayout();
214    d->showHideAdvancedSearchButton = new QToolButton(this);
215    d->showHideAdvancedSearchButton->setText(QLatin1String("+"));
216    d->showHideAdvancedSearchButton->setMinimumSize(25, 20);
217
218    label = new QLabel(tr("Advanced search"), this);
219    QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
220    sizePolicy.setHeightForWidth(label->sizePolicy().hasHeightForWidth());
221    label->setSizePolicy(sizePolicy);
222
223    QFrame* hLine = new QFrame(this);
224    hLine->setFrameStyle(QFrame::HLine);
225    hBoxLayout->addWidget(d->showHideAdvancedSearchButton);
226    hBoxLayout->addWidget(label);
227    hBoxLayout->addWidget(hLine);
228
229    vLayout->addLayout(hBoxLayout);
230
231    // setup advanced search layout
232    d->advancedSearchWidget = new QWidget(this);
233    QGridLayout *gLayout = new QGridLayout(d->advancedSearchWidget);
234    gLayout->setMargin(0);
235
236    label = new QLabel(tr("words <B>similar</B> to:"), this);
237    gLayout->addWidget(label, 0, 0);
238    d->similarQuery = new QLineEdit(this);
239    gLayout->addWidget(d->similarQuery, 0, 1);
240
241    label = new QLabel(tr("<B>without</B> the words:"), this);
242    gLayout->addWidget(label, 1, 0);
243    d->withoutQuery = new QLineEdit(this);
244    gLayout->addWidget(d->withoutQuery, 1, 1);
245
246    label = new QLabel(tr("with <B>exact phrase</B>:"), this);
247    gLayout->addWidget(label, 2, 0);
248    d->exactQuery = new QLineEdit(this);
249    gLayout->addWidget(d->exactQuery, 2, 1);
250
251    label = new QLabel(tr("with <B>all</B> of the words:"), this);
252    gLayout->addWidget(label, 3, 0);
253    d->allQuery = new QLineEdit(this);
254    gLayout->addWidget(d->allQuery, 3, 1);
255
256    label = new QLabel(tr("with <B>at least one</B> of the words:"), this);
257    gLayout->addWidget(label, 4, 0);
258    d->atLeastQuery = new QLineEdit(this);
259    gLayout->addWidget(d->atLeastQuery, 4, 1);
260
261    vLayout->addWidget(d->advancedSearchWidget);
262    d->advancedSearchWidget->hide();
263
264    connect(d->exactQuery, SIGNAL(returnPressed()), this, SIGNAL(search()));
265    connect(d->similarQuery, SIGNAL(returnPressed()), this, SIGNAL(search()));
266    connect(d->withoutQuery, SIGNAL(returnPressed()), this, SIGNAL(search()));
267    connect(d->allQuery, SIGNAL(returnPressed()), this, SIGNAL(search()));
268    connect(d->atLeastQuery, SIGNAL(returnPressed()), this, SIGNAL(search()));
269    connect(d->showHideAdvancedSearchButton, SIGNAL(clicked()),
270        d, SLOT(showHideAdvancedSearch()));
271#endif
272}
273
274/*!
275    Destroys the search query widget.
276*/
277QHelpSearchQueryWidget::~QHelpSearchQueryWidget()
278{
279    delete d;
280}
281
282/*!
283    Returns a list of querys to use in combination with the search engines
284    search(QList<QHelpSearchQuery> &query) function.
285*/
286QList<QHelpSearchQuery> QHelpSearchQueryWidget::query() const
287{
288#if !defined(QT_CLUCENE_SUPPORT)
289    QList<QHelpSearchQuery> queryList;
290    queryList.append(QHelpSearchQuery(QHelpSearchQuery::DEFAULT,
291        QStringList(d->defaultQuery->text())));
292
293    return queryList;
294#else
295    QList<QHelpSearchQuery> queryList;
296    if (d->defaultQuery->isEnabled()) {
297        queryList.append(QHelpSearchQuery(QHelpSearchQuery::DEFAULT,
298            d->buildTermList(d->escapeString(d->defaultQuery->text()))));
299    } else {
300        const QRegExp exp(QLatin1String("\\s+"));
301        QStringList lst = d->similarQuery->text().split(exp, QString::SkipEmptyParts);
302        if (!lst.isEmpty()) {
303            QStringList fuzzy;
304            foreach (const QString term, lst)
305                fuzzy += d->buildTermList(d->escapeString(term));
306            queryList.append(QHelpSearchQuery(QHelpSearchQuery::FUZZY, fuzzy));
307        }
308
309        lst = d->withoutQuery->text().split(exp, QString::SkipEmptyParts);
310        if (!lst.isEmpty()) {
311            QStringList without;
312            foreach (const QString term, lst)
313                without.append(d->escapeString(term));
314            queryList.append(QHelpSearchQuery(QHelpSearchQuery::WITHOUT, without));
315        }
316
317        if (!d->exactQuery->text().isEmpty()) {
318            QString phrase = d->exactQuery->text().remove(QLatin1Char('\"'));
319            phrase = d->escapeString(phrase.simplified());
320            queryList.append(QHelpSearchQuery(QHelpSearchQuery::PHRASE, QStringList(phrase)));
321        }
322
323        lst = d->allQuery->text().split(exp, QString::SkipEmptyParts);
324        if (!lst.isEmpty()) {
325            QStringList all;
326            foreach (const QString term, lst)
327                all.append(d->escapeString(term));
328            queryList.append(QHelpSearchQuery(QHelpSearchQuery::ALL, all));
329        }
330
331        lst = d->atLeastQuery->text().split(exp, QString::SkipEmptyParts);
332        if (!lst.isEmpty()) {
333            QStringList atLeast;
334            foreach (const QString term, lst)
335                atLeast += d->buildTermList(d->escapeString(term));
336            queryList.append(QHelpSearchQuery(QHelpSearchQuery::ATLEAST, atLeast));
337        }
338    }
339    return queryList;
340#endif
341}
342
343/*! \reimp
344*/
345void QHelpSearchQueryWidget::focusInEvent(QFocusEvent *focusEvent)
346{
347    if (focusEvent->reason() != Qt::MouseFocusReason) {
348        d->defaultQuery->selectAll();
349        d->defaultQuery->setFocus();
350    }
351}
352
353QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.