source: trunk/examples/network/googlesuggest/googlesuggest.cpp

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

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

  • Property svn:eol-style set to native
File size: 6.8 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 examples of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:BSD$
10** You may use this file under the terms of the BSD license as follows:
11**
12** "Redistribution and use in source and binary forms, with or without
13** modification, are permitted provided that the following conditions are
14** met:
15** * Redistributions of source code must retain the above copyright
16** notice, this list of conditions and the following disclaimer.
17** * Redistributions in binary form must reproduce the above copyright
18** notice, this list of conditions and the following disclaimer in
19** the documentation and/or other materials provided with the
20** distribution.
21** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22** the names of its contributors may be used to endorse or promote
23** products derived from this software without specific prior written
24** permission.
25**
26** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41
42//! [1]
43#include "googlesuggest.h"
44
45#define GSUGGEST_URL "http://google.com/complete/search?output=toolbar&q=%1"
46//! [1]
47
48//! [2]
49GSuggestCompletion::GSuggestCompletion(QLineEdit *parent): QObject(parent), editor(parent)
50{
51 popup = new QTreeWidget;
52 popup->setWindowFlags(Qt::Popup);
53 popup->setFocusPolicy(Qt::NoFocus);
54 popup->setFocusProxy(parent);
55 popup->setMouseTracking(true);
56
57 popup->setColumnCount(2);
58 popup->setUniformRowHeights(true);
59 popup->setRootIsDecorated(false);
60 popup->setEditTriggers(QTreeWidget::NoEditTriggers);
61 popup->setSelectionBehavior(QTreeWidget::SelectRows);
62 popup->setFrameStyle(QFrame::Box | QFrame::Plain);
63 popup->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
64 popup->header()->hide();
65
66 popup->installEventFilter(this);
67
68 connect(popup, SIGNAL(itemClicked(QTreeWidgetItem*,int)),
69 SLOT(doneCompletion()));
70
71 timer = new QTimer(this);
72 timer->setSingleShot(true);
73 timer->setInterval(500);
74 connect(timer, SIGNAL(timeout()), SLOT(autoSuggest()));
75 connect(editor, SIGNAL(textEdited(QString)), timer, SLOT(start()));
76
77 connect(&networkManager, SIGNAL(finished(QNetworkReply*)),
78 this, SLOT(handleNetworkData(QNetworkReply*)));
79
80}
81//! [2]
82
83//! [3]
84GSuggestCompletion::~GSuggestCompletion()
85{
86 delete popup;
87}
88//! [3]
89
90//! [4]
91bool GSuggestCompletion::eventFilter(QObject *obj, QEvent *ev)
92{
93 if (obj != popup)
94 return false;
95
96 if (ev->type() == QEvent::MouseButtonPress) {
97 popup->hide();
98 editor->setFocus();
99 return true;
100 }
101
102 if (ev->type() == QEvent::KeyPress) {
103
104 bool consumed = false;
105 int key = static_cast<QKeyEvent*>(ev)->key();
106 switch (key) {
107 case Qt::Key_Enter:
108 case Qt::Key_Return:
109 doneCompletion();
110 consumed = true;
111
112 case Qt::Key_Escape:
113 editor->setFocus();
114 popup->hide();
115 consumed = true;
116
117 case Qt::Key_Up:
118 case Qt::Key_Down:
119 case Qt::Key_Home:
120 case Qt::Key_End:
121 case Qt::Key_PageUp:
122 case Qt::Key_PageDown:
123 break;
124
125 default:
126 editor->setFocus();
127 editor->event(ev);
128 popup->hide();
129 break;
130 }
131
132 return consumed;
133 }
134
135 return false;
136}
137//! [4]
138
139//! [5]
140void GSuggestCompletion::showCompletion(const QStringList &choices, const QStringList &hits)
141{
142
143 if (choices.isEmpty() || choices.count() != hits.count())
144 return;
145
146 const QPalette &pal = editor->palette();
147 QColor color = pal.color(QPalette::Disabled, QPalette::WindowText);
148
149 popup->setUpdatesEnabled(false);
150 popup->clear();
151 for (int i = 0; i < choices.count(); ++i) {
152 QTreeWidgetItem * item;
153 item = new QTreeWidgetItem(popup);
154 item->setText(0, choices[i]);
155 item->setText(1, hits[i]);
156 item->setTextAlignment(1, Qt::AlignRight);
157 item->setTextColor(1, color);
158 }
159 popup->setCurrentItem(popup->topLevelItem(0));
160 popup->resizeColumnToContents(0);
161 popup->resizeColumnToContents(1);
162 popup->adjustSize();
163 popup->setUpdatesEnabled(true);
164
165 int h = popup->sizeHintForRow(0) * qMin(7, choices.count()) + 3;
166 popup->resize(popup->width(), h);
167
168 popup->move(editor->mapToGlobal(QPoint(0, editor->height())));
169 popup->setFocus();
170 popup->show();
171}
172//! [5]
173
174//! [6]
175void GSuggestCompletion::doneCompletion()
176{
177 timer->stop();
178 popup->hide();
179 editor->setFocus();
180 QTreeWidgetItem *item = popup->currentItem();
181 if (item) {
182 editor->setText(item->text(0));
183 QMetaObject::invokeMethod(editor, "returnPressed");
184 }
185}
186//! [6]
187
188//! [7]
189void GSuggestCompletion::autoSuggest()
190{
191 QString str = editor->text();
192 QString url = QString(GSUGGEST_URL).arg(str);
193 networkManager.get(QNetworkRequest(QString(url)));
194}
195//! [7]
196
197//! [8]
198void GSuggestCompletion::preventSuggest()
199{
200 timer->stop();
201}
202//! [8]
203
204//! [9]
205void GSuggestCompletion::handleNetworkData(QNetworkReply *networkReply)
206{
207 QUrl url = networkReply->url();
208 if (!networkReply->error()) {
209 QStringList choices;
210 QStringList hits;
211
212 QByteArray response(networkReply->readAll());
213 QXmlStreamReader xml(response);
214 while (!xml.atEnd()) {
215 xml.readNext();
216 if (xml.tokenType() == QXmlStreamReader::StartElement)
217 if (xml.name() == "suggestion") {
218 QStringRef str = xml.attributes().value("data");
219 choices << str.toString();
220 }
221 if (xml.tokenType() == QXmlStreamReader::StartElement)
222 if (xml.name() == "num_queries") {
223 QStringRef str = xml.attributes().value("int");
224 hits << str.toString();
225 }
226 }
227
228 showCompletion(choices, hits);
229 }
230
231 networkReply->deleteLater();
232}
233//! [9]
234
Note: See TracBrowser for help on using the repository browser.