examples/xml/rsslisting/rsslisting.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the examples of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    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 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 /*
       
    43 rsslisting.cpp
       
    44 
       
    45 Provides a widget for displaying news items from RDF news sources.
       
    46 RDF is an XML-based format for storing items of information (see
       
    47 http://www.w3.org/RDF/ for details).
       
    48 
       
    49 The widget itself provides a simple user interface for specifying
       
    50 the URL of a news source, and controlling the downloading of news.
       
    51 
       
    52 The widget downloads and parses the XML asynchronously, feeding the
       
    53 data to an XML reader in pieces. This allows the user to interrupt
       
    54 its 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 
       
    75 RSSListing::RSSListing(QWidget *parent)
       
    76     : QWidget(parent)
       
    77 {
       
    78     lineEdit = new QLineEdit(this);
       
    79     lineEdit->setText("http://labs.qt.nokia.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 
       
   134 void 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 
       
   158 void 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 
       
   181 void 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 */
       
   200 void 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 */
       
   236 void RSSListing::itemActivated(QTreeWidgetItem * item)
       
   237 {
       
   238     QDesktopServices::openUrl(QUrl(item->text(1)));
       
   239 }