source: trunk/examples/xml/rsslisting/rsslisting.cpp@ 63

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

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

File size: 7.7 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the examples 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 [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/*
43rsslisting.cpp
44
45Provides a widget for displaying news items from RDF news sources.
46RDF is an XML-based format for storing items of information (see
47http://www.w3.org/RDF/ for details).
48
49The widget itself provides a simple user interface for specifying
50the URL of a news source, and controlling the downloading of news.
51
52The widget downloads and parses the XML asynchronously, feeding the
53data to an XML reader in pieces. This allows the user to interrupt
54its operation, and also allows very large data sources to be read.
55*/
56
57
58#include <QtCore>
59#include <QtGui>
60#include <QtNetwork>
61
62#include "rsslisting.h"
63
64
65/*
66 Constructs an RSSListing widget with a simple user interface, and sets
67 up the XML reader to use a custom handler class.
68
69 The user interface consists of a line edit, two push buttons, and a
70 list view widget. The line edit is used for entering the URLs of news
71 sources; the push buttons start and abort the process of reading the
72 news.
73*/
74
75RSSListing::RSSListing(QWidget *parent)
76 : QWidget(parent)
77{
78 lineEdit = new QLineEdit(this);
79 lineEdit->setText("http://labs.trolltech.com/blogs/feed");
80
81 fetchButton = new QPushButton(tr("Fetch"), this);
82 abortButton = new QPushButton(tr("Abort"), this);
83 abortButton->setEnabled(false);
84
85 treeWidget = new QTreeWidget(this);
86 connect(treeWidget, SIGNAL(itemActivated(QTreeWidgetItem*, int)),
87 this, SLOT(itemActivated(QTreeWidgetItem*)));
88 QStringList headerLabels;
89 headerLabels << tr("Title") << tr("Link");
90 treeWidget->setHeaderLabels(headerLabels);
91 treeWidget->header()->setResizeMode(QHeaderView::ResizeToContents);
92
93 connect(&http, SIGNAL(readyRead(const QHttpResponseHeader &)),
94 this, SLOT(readData(const QHttpResponseHeader &)));
95
96 connect(&http, SIGNAL(requestFinished(int, bool)),
97 this, SLOT(finished(int, bool)));
98
99 connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(fetch()));
100 connect(fetchButton, SIGNAL(clicked()), this, SLOT(fetch()));
101 connect(abortButton, SIGNAL(clicked()), &http, SLOT(abort()));
102
103 QVBoxLayout *layout = new QVBoxLayout(this);
104
105 QHBoxLayout *hboxLayout = new QHBoxLayout;
106
107 hboxLayout->addWidget(lineEdit);
108 hboxLayout->addWidget(fetchButton);
109 hboxLayout->addWidget(abortButton);
110
111 layout->addLayout(hboxLayout);
112 layout->addWidget(treeWidget);
113
114 setWindowTitle(tr("RSS listing example"));
115 resize(640,480);
116}
117
118/*
119 Starts fetching data from a news source specified in the line
120 edit widget.
121
122 The line edit is made read only to prevent the user from modifying its
123 contents during the fetch; this is only for cosmetic purposes.
124 The fetch button is disabled, and the abort button is enabled to allow
125 the user to interrupt processing. The list view is cleared, and we
126 define the last list view item to be 0, meaning that there are no
127 existing items in the list.
128
129 The HTTP handler is supplied with the raw contents of the line edit and
130 a fetch is initiated. We keep the ID value returned by the HTTP handler
131 for future reference.
132*/
133
134void RSSListing::fetch()
135{
136 lineEdit->setReadOnly(true);
137 fetchButton->setEnabled(false);
138 abortButton->setEnabled(true);
139 treeWidget->clear();
140
141 xml.clear();
142
143 QUrl url(lineEdit->text());
144
145 http.setHost(url.host());
146 connectionId = http.get(url.path());
147}
148
149/*
150 Reads data received from the RDF source.
151
152 We read all the available data, and pass it to the XML
153 stream reader. Then we call the XML parsing function.
154
155 If parsing fails for any reason, we abort the fetch.
156*/
157
158void RSSListing::readData(const QHttpResponseHeader &resp)
159{
160 if (resp.statusCode() != 200)
161 http.abort();
162 else {
163 xml.addData(http.readAll());
164 parseXml();
165 }
166}
167
168/*
169 Finishes processing an HTTP request.
170
171 The default behavior is to keep the text edit read only.
172
173 If an error has occurred, the user interface is made available
174 to the user for further input, allowing a new fetch to be
175 started.
176
177 If the HTTP get request has finished, we make the
178 user interface available to the user for further input.
179*/
180
181void RSSListing::finished(int id, bool error)
182{
183 if (error) {
184 qWarning("Received error during HTTP fetch.");
185 lineEdit->setReadOnly(false);
186 abortButton->setEnabled(false);
187 fetchButton->setEnabled(true);
188 }
189 else if (id == connectionId) {
190 lineEdit->setReadOnly(false);
191 abortButton->setEnabled(false);
192 fetchButton->setEnabled(true);
193 }
194}
195
196
197/*
198 Parses the XML data and creates treeWidget items accordingly.
199*/
200void RSSListing::parseXml()
201{
202 while (!xml.atEnd()) {
203 xml.readNext();
204 if (xml.isStartElement()) {
205 if (xml.name() == "item")
206 linkString = xml.attributes().value("rss:about").toString();
207 currentTag = xml.name().toString();
208 } else if (xml.isEndElement()) {
209 if (xml.name() == "item") {
210
211 QTreeWidgetItem *item = new QTreeWidgetItem;
212 item->setText(0, titleString);
213 item->setText(1, linkString);
214 treeWidget->addTopLevelItem(item);
215
216 titleString.clear();
217 linkString.clear();
218 }
219
220 } else if (xml.isCharacters() && !xml.isWhitespace()) {
221 if (currentTag == "title")
222 titleString += xml.text().toString();
223 else if (currentTag == "link")
224 linkString += xml.text().toString();
225 }
226 }
227 if (xml.error() && xml.error() != QXmlStreamReader::PrematureEndOfDocumentError) {
228 qWarning() << "XML ERROR:" << xml.lineNumber() << ": " << xml.errorString();
229 http.abort();
230 }
231}
232
233/*
234 Open the link in the browser
235*/
236void RSSListing::itemActivated(QTreeWidgetItem * item)
237{
238 QDesktopServices::openUrl(QUrl(item->text(1)));
239}
Note: See TracBrowser for help on using the repository browser.