source: trunk/tools/shared/findwidget/abstractfindwidget.cpp@ 1028

Last change on this file since 1028 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 9.0 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the tools applications of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this 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 have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/*! \class AbstractFindWidget
43
44 \brief A search bar that is commonly added below a searchable widget.
45
46 \internal
47
48 This widget implements a search bar which becomes visible when the user
49 wants to start searching. It is a modern replacement for the commonly used
50 search dialog. It is usually placed below the target widget using a QVBoxLayout.
51
52 The search is incremental and can be set to case sensitive or whole words
53 using buttons available on the search bar.
54 */
55
56#include "abstractfindwidget.h"
57
58#include <QtCore/QEvent>
59#include <QtCore/QFile>
60#include <QtCore/QTimer>
61
62#include <QtGui/QCheckBox>
63#include <QtGui/QKeyEvent>
64#include <QtGui/QLabel>
65#include <QtGui/QLayout>
66#include <QtGui/QLineEdit>
67#include <QtGui/QSpacerItem>
68#include <QtGui/QToolButton>
69
70QT_BEGIN_NAMESPACE
71
72static QIcon createIconSet(const QString &name)
73{
74 QStringList candidates = QStringList()
75 << (QString::fromUtf8(":/trolltech/shared/images/") + name)
76#ifdef Q_WS_MAC
77 << (QString::fromUtf8(":/trolltech/shared/images/mac/") + name);
78#else
79 << (QString::fromUtf8(":/trolltech/shared/images/win/") + name);
80#endif
81
82 foreach (const QString &f, candidates) {
83 if (QFile::exists(f))
84 return QIcon(f);
85 }
86
87 return QIcon();
88}
89
90/*!
91 Constructs an AbstractFindWidget.
92
93 \a flags can change the layout and turn off certain features.
94 \a parent is passed to the QWidget constructor.
95 */
96AbstractFindWidget::AbstractFindWidget(FindFlags flags, QWidget *parent)
97 : QWidget(parent)
98{
99 QBoxLayout *topLayOut;
100 QBoxLayout *layOut;
101 if (flags & NarrowLayout) {
102 topLayOut = new QVBoxLayout(this);
103 layOut = new QHBoxLayout;
104 topLayOut->addLayout(layOut);
105 } else {
106 topLayOut = layOut = new QHBoxLayout(this);
107 }
108#ifndef Q_OS_MAC
109 topLayOut->setSpacing(6);
110 topLayOut->setMargin(0);
111#endif
112
113 m_toolClose = new QToolButton(this);
114 m_toolClose->setIcon(createIconSet(QLatin1String("closetab.png")));
115 m_toolClose->setAutoRaise(true);
116 layOut->addWidget(m_toolClose);
117 connect(m_toolClose, SIGNAL(clicked()), SLOT(deactivate()));
118
119 m_editFind = new QLineEdit(this);
120 layOut->addWidget(m_editFind);
121 connect(m_editFind, SIGNAL(returnPressed()), SLOT(findNext()));
122 connect(m_editFind, SIGNAL(textChanged(QString)), SLOT(findCurrentText()));
123 connect(m_editFind, SIGNAL(textChanged(QString)), SLOT(updateButtons()));
124
125 m_toolPrevious = new QToolButton(this);
126 m_toolPrevious->setAutoRaise(true);
127 m_toolPrevious->setText(tr("&Previous"));
128 m_toolPrevious->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
129 m_toolPrevious->setIcon(createIconSet(QLatin1String("previous.png")));
130 layOut->addWidget(m_toolPrevious);
131 connect(m_toolPrevious, SIGNAL(clicked()), SLOT(findPrevious()));
132
133 m_toolNext = new QToolButton(this);
134 m_toolNext->setAutoRaise(true);
135 m_toolNext->setText(tr("&Next"));
136 m_toolNext->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
137 m_toolNext->setIcon(createIconSet(QLatin1String("next.png")));
138 layOut->addWidget(m_toolNext);
139 connect(m_toolNext, SIGNAL(clicked()), SLOT(findNext()));
140
141 if (flags & NarrowLayout) {
142 QSizePolicy sp(QSizePolicy::Preferred, QSizePolicy::Fixed);
143 m_toolPrevious->setSizePolicy(sp);
144 m_toolPrevious->setMinimumWidth(m_toolPrevious->minimumSizeHint().height());
145 m_toolNext->setSizePolicy(sp);
146 m_toolNext->setMinimumWidth(m_toolNext->minimumSizeHint().height());
147
148 QSpacerItem *spacerItem =
149 new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum);
150 layOut->addItem(spacerItem);
151
152 layOut = new QHBoxLayout;
153 topLayOut->addLayout(layOut);
154 } else {
155 m_editFind->setMinimumWidth(150);
156 }
157
158 if (!(flags & NoCaseSensitive)) {
159 m_checkCase = new QCheckBox(tr("&Case sensitive"), this);
160 layOut->addWidget(m_checkCase);
161 connect(m_checkCase, SIGNAL(toggled(bool)), SLOT(findCurrentText()));
162 } else {
163 m_checkCase = 0;
164 }
165
166 if (!(flags & NoWholeWords)) {
167 m_checkWholeWords = new QCheckBox(tr("Whole &words"), this);
168 layOut->addWidget(m_checkWholeWords);
169 connect(m_checkWholeWords, SIGNAL(toggled(bool)), SLOT(findCurrentText()));
170 } else {
171 m_checkWholeWords = 0;
172 }
173
174 m_labelWrapped = new QLabel(this);
175 m_labelWrapped->setTextFormat(Qt::RichText);
176 m_labelWrapped->setAlignment(
177 Qt::AlignLeading | Qt::AlignLeft | Qt::AlignVCenter);
178 m_labelWrapped->setText(
179 tr("<img src=\":/trolltech/shared/images/wrap.png\">"
180 "&nbsp;Search wrapped"));
181 m_labelWrapped->hide();
182 layOut->addWidget(m_labelWrapped);
183
184 QSpacerItem *spacerItem =
185 new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum);
186 layOut->addItem(spacerItem);
187
188 setMinimumWidth(minimumSizeHint().width());
189
190 updateButtons();
191 hide();
192}
193
194/*!
195 Destroys the AbstractFindWidget.
196 */
197AbstractFindWidget::~AbstractFindWidget()
198{
199}
200
201/*!
202 Returns the icon set to be used for the action that initiates a search.
203 */
204QIcon AbstractFindWidget::findIconSet()
205{
206 return createIconSet(QLatin1String("searchfind.png"));
207}
208
209/*!
210 Activates the find widget, making it visible and having focus on its input
211 field.
212 */
213void AbstractFindWidget::activate()
214{
215 show();
216 m_editFind->selectAll();
217 m_editFind->setFocus(Qt::ShortcutFocusReason);
218}
219
220/*!
221 Deactivates the find widget, making it invisible and handing focus to any
222 associated QTextEdit.
223 */
224void AbstractFindWidget::deactivate()
225{
226 hide();
227}
228
229void AbstractFindWidget::findNext()
230{
231 findInternal(m_editFind->text(), true, false);
232}
233
234void AbstractFindWidget::findPrevious()
235{
236 findInternal(m_editFind->text(), true, true);
237}
238
239void AbstractFindWidget::findCurrentText()
240{
241 findInternal(m_editFind->text(), false, false);
242}
243
244void AbstractFindWidget::keyPressEvent(QKeyEvent *event)
245{
246 if (event->key() == Qt::Key_Escape) {
247 deactivate();
248 return;
249 }
250
251 QWidget::keyPressEvent(event);
252}
253
254void AbstractFindWidget::updateButtons()
255{
256 const bool en = !m_editFind->text().isEmpty();
257 m_toolPrevious->setEnabled(en);
258 m_toolNext->setEnabled(en);
259}
260
261void AbstractFindWidget::findInternal(const QString &ttf, bool skipCurrent, bool backward)
262{
263 bool found = false;
264 bool wrapped = false;
265 find(ttf, skipCurrent, backward, &found, &wrapped);
266 QPalette p;
267 p.setColor(QPalette::Active, QPalette::Base, found ? Qt::white : QColor(255, 102, 102));
268 m_editFind->setPalette(p);
269 m_labelWrapped->setVisible(wrapped);
270}
271
272bool AbstractFindWidget::caseSensitive() const
273{
274 return m_checkCase && m_checkCase->isChecked();
275}
276
277bool AbstractFindWidget::wholeWords() const
278{
279 return m_checkWholeWords && m_checkWholeWords->isChecked();
280}
281
282bool AbstractFindWidget::eventFilter(QObject *object, QEvent *e)
283{
284 if (isVisible() && e->type() == QEvent::KeyPress) {
285 QKeyEvent *ke = static_cast<QKeyEvent*>(e);
286 if (ke->key() == Qt::Key_Escape) {
287 hide();
288 return true;
289 }
290 }
291
292 return QWidget::eventFilter(object, e);
293}
294
295QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.