diff options
Diffstat (limited to 'examples/xml/rsslisting')
-rw-r--r-- | examples/xml/rsslisting/main.cpp | 63 | ||||
-rw-r--r-- | examples/xml/rsslisting/rsslisting.cpp | 247 | ||||
-rw-r--r-- | examples/xml/rsslisting/rsslisting.h | 90 | ||||
-rw-r--r-- | examples/xml/rsslisting/rsslisting.pro | 12 |
4 files changed, 412 insertions, 0 deletions
diff --git a/examples/xml/rsslisting/main.cpp b/examples/xml/rsslisting/main.cpp new file mode 100644 index 0000000000..011569f2b6 --- /dev/null +++ b/examples/xml/rsslisting/main.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* +main.cpp + +Provides the main function for the RSS news reader example. +*/ + +#include <QtGui> + +#include "rsslisting.h" + +/*! + Create an application and a main widget. Open the main widget for + user input, and exit with an appropriate return value when it is + closed. +*/ + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + RSSListing *rsslisting = new RSSListing; + rsslisting->show(); + return app.exec(); +} diff --git a/examples/xml/rsslisting/rsslisting.cpp b/examples/xml/rsslisting/rsslisting.cpp new file mode 100644 index 0000000000..5840f08d09 --- /dev/null +++ b/examples/xml/rsslisting/rsslisting.cpp @@ -0,0 +1,247 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* +rsslisting.cpp + +Provides a widget for displaying news items from RDF news sources. +RDF is an XML-based format for storing items of information (see +http://www.w3.org/RDF/ for details). + +The widget itself provides a simple user interface for specifying +the URL of a news source, and controlling the downloading of news. + +The widget downloads and parses the XML asynchronously, feeding the +data to an XML reader in pieces. This allows the user to interrupt +its operation, and also allows very large data sources to be read. +*/ + + +#include <QtCore> +#include <QtGui> +#include <QtNetwork> + +#include "rsslisting.h" + + +/* + Constructs an RSSListing widget with a simple user interface, and sets + up the XML reader to use a custom handler class. + + The user interface consists of a line edit, a push button, and a + list view widget. The line edit is used for entering the URLs of news + sources; the push button starts the process of reading the + news. +*/ + +RSSListing::RSSListing(QWidget *parent) + : QWidget(parent), currentReply(0) +{ + lineEdit = new QLineEdit(this); + lineEdit->setText("http://labs.qt.nokia.com/blogs/feed"); + + fetchButton = new QPushButton(tr("Fetch"), this); + + treeWidget = new QTreeWidget(this); + connect(treeWidget, SIGNAL(itemActivated(QTreeWidgetItem*,int)), + this, SLOT(itemActivated(QTreeWidgetItem*))); + QStringList headerLabels; + headerLabels << tr("Title") << tr("Link"); + treeWidget->setHeaderLabels(headerLabels); + treeWidget->header()->setResizeMode(QHeaderView::ResizeToContents); + + connect(&manager, SIGNAL(finished(QNetworkReply*)), + this, SLOT(finished(QNetworkReply*))); + + connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(fetch())); + connect(fetchButton, SIGNAL(clicked()), this, SLOT(fetch())); + + QVBoxLayout *layout = new QVBoxLayout(this); + + QHBoxLayout *hboxLayout = new QHBoxLayout; + + hboxLayout->addWidget(lineEdit); + hboxLayout->addWidget(fetchButton); + + layout->addLayout(hboxLayout); + layout->addWidget(treeWidget); + + setWindowTitle(tr("RSS listing example")); + resize(640,480); +} + +/* + Starts the network request and connects the needed signals +*/ +void RSSListing::get(const QUrl &url) +{ + QNetworkRequest request(url); + if (currentReply) { + currentReply->disconnect(this); + currentReply->deleteLater(); + } + currentReply = manager.get(request); + connect(currentReply, SIGNAL(readyRead()), this, SLOT(readyRead())); + connect(currentReply, SIGNAL(metaDataChanged()), this, SLOT(metaDataChanged())); + connect(currentReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(error(QNetworkReply::NetworkError))); +} + +/* + Starts fetching data from a news source specified in the line + edit widget. + + The line edit is made read only to prevent the user from modifying its + contents during the fetch; this is only for cosmetic purposes. + The fetch button is disabled, the list view is cleared, and we + define the last list view item to be 0, meaning that there are no + existing items in the list. + + A URL is created with the raw contents of the line edit and + a get is initiated. +*/ + +void RSSListing::fetch() +{ + lineEdit->setReadOnly(true); + fetchButton->setEnabled(false); + treeWidget->clear(); + + xml.clear(); + + QUrl url(lineEdit->text()); + get(url); +} + +void RSSListing::metaDataChanged() +{ + QUrl redirectionTarget = currentReply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); + if (redirectionTarget.isValid()) { + get(redirectionTarget); + } +} + +/* + Reads data received from the RDF source. + + We read all the available data, and pass it to the XML + stream reader. Then we call the XML parsing function. +*/ + +void RSSListing::readyRead() +{ + int statusCode = currentReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + if (statusCode >= 200 && statusCode < 300) { + QByteArray data = currentReply->readAll(); + xml.addData(data); + parseXml(); + } +} + +/* + Finishes processing an HTTP request. + + The default behavior is to keep the text edit read only. + + If an error has occurred, the user interface is made available + to the user for further input, allowing a new fetch to be + started. + + If the HTTP get request has finished, we make the + user interface available to the user for further input. +*/ + +void RSSListing::finished(QNetworkReply *reply) +{ + Q_UNUSED(reply); + lineEdit->setReadOnly(false); + fetchButton->setEnabled(true); +} + + +/* + Parses the XML data and creates treeWidget items accordingly. +*/ +void RSSListing::parseXml() +{ + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement()) { + if (xml.name() == "item") + linkString = xml.attributes().value("rss:about").toString(); + currentTag = xml.name().toString(); + } else if (xml.isEndElement()) { + if (xml.name() == "item") { + + QTreeWidgetItem *item = new QTreeWidgetItem; + item->setText(0, titleString); + item->setText(1, linkString); + treeWidget->addTopLevelItem(item); + + titleString.clear(); + linkString.clear(); + } + + } else if (xml.isCharacters() && !xml.isWhitespace()) { + if (currentTag == "title") + titleString += xml.text().toString(); + else if (currentTag == "link") + linkString += xml.text().toString(); + } + } + if (xml.error() && xml.error() != QXmlStreamReader::PrematureEndOfDocumentError) { + qWarning() << "XML ERROR:" << xml.lineNumber() << ": " << xml.errorString(); + } +} + +/* + Open the link in the browser +*/ +void RSSListing::itemActivated(QTreeWidgetItem * item) +{ + QDesktopServices::openUrl(QUrl(item->text(1))); +} + +void RSSListing::error(QNetworkReply::NetworkError) +{ + qWarning("error retrieving RSS feed"); + currentReply->disconnect(this); + currentReply->deleteLater(); + currentReply = 0; +} diff --git a/examples/xml/rsslisting/rsslisting.h b/examples/xml/rsslisting/rsslisting.h new file mode 100644 index 0000000000..98254f839b --- /dev/null +++ b/examples/xml/rsslisting/rsslisting.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef RSSLISTING_H +#define RSSLISTING_H + +#include <QNetworkAccessManager> +#include <QNetworkReply> +#include <QWidget> +#include <QBuffer> +#include <QXmlStreamReader> +#include <QUrl> + +QT_BEGIN_NAMESPACE +class QLineEdit; +class QTreeWidget; +class QTreeWidgetItem; +class QPushButton; +QT_END_NAMESPACE + +class RSSListing : public QWidget +{ + Q_OBJECT +public: + RSSListing(QWidget *widget = 0); + +public slots: + void fetch(); + void finished(QNetworkReply *reply); + void readyRead(); + void metaDataChanged(); + void itemActivated(QTreeWidgetItem * item); + void error(QNetworkReply::NetworkError); + +private: + void parseXml(); + void get(const QUrl &url); + + QXmlStreamReader xml; + QString currentTag; + QString linkString; + QString titleString; + + QNetworkAccessManager manager; + QNetworkReply *currentReply; + + QLineEdit *lineEdit; + QTreeWidget *treeWidget; + QPushButton *fetchButton; +}; + +#endif + diff --git a/examples/xml/rsslisting/rsslisting.pro b/examples/xml/rsslisting/rsslisting.pro new file mode 100644 index 0000000000..01bc9e2ad6 --- /dev/null +++ b/examples/xml/rsslisting/rsslisting.pro @@ -0,0 +1,12 @@ +HEADERS += rsslisting.h +SOURCES += main.cpp rsslisting.cpp +QT += network xml + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/xml/rsslisting +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS rsslisting.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/xml/rsslisting +INSTALLS += target sources + +symbian: include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) + |