RSSListing
package RSSListing;
use strict;
use warnings;
use QtCore4;
use QtGui4;
use QtNetwork4;
use QtCore4::isa qw( Qt::Widget );
use QtCore4::slots
fetch => [],
finished => ['int', 'bool'],
readData => ['const QHttpResponseHeader &'],
itemActivated => ['QTreeWidgetItem *'];
sub xml() {
return this->{xml};
}
sub currentTag() {
return this->{currentTag};
}
sub linkString() {
return this->{linkString};
}
sub titleString() {
return this->{titleString};
}
sub http() {
return this->{http};
}
sub connectionId() {
return this->{connectionId};
}
sub lineEdit() {
return this->{lineEdit};
}
sub treeWidget() {
return this->{treeWidget};
}
sub abortButton() {
return this->{abortButton};
}
sub fetchButton() {
return this->{fetchButton};
}
sub NEW
{
my ($class, $parent) = @_;
$class->SUPER::NEW($parent);
this->{http} = Qt::Http();
this->{xml} = Qt::XmlStreamReader();
this->{lineEdit} = Qt::LineEdit(this);
lineEdit->setText('http://labs.qt.nokia.com/blogs/feed');
this->{fetchButton} = Qt::PushButton(this->tr('Fetch'), this);
this->{abortButton} = Qt::PushButton(this->tr('Abort'), this);
abortButton->setEnabled(0);
this->{treeWidget} = Qt::TreeWidget(this);
this->connect(treeWidget, SIGNAL 'itemActivated(QTreeWidgetItem*,int)',
this, SLOT 'itemActivated(QTreeWidgetItem*)');
my @headerLabels = (this->tr('Title'), this->tr('Link'));
treeWidget->setHeaderLabels(\@headerLabels);
treeWidget->header()->setResizeMode(Qt::HeaderView::ResizeToContents());
this->connect(http, SIGNAL 'readyRead(QHttpResponseHeader)',
this, SLOT 'readData(QHttpResponseHeader)');
this->connect(http, SIGNAL 'requestFinished(int,bool)',
this, SLOT 'finished(int,bool)');
this->connect(lineEdit, SIGNAL 'returnPressed()', this, SLOT 'fetch()');
this->connect(fetchButton, SIGNAL 'clicked()', this, SLOT 'fetch()');
this->connect(abortButton, SIGNAL 'clicked()', http, SLOT 'abort()');
my $layout = Qt::VBoxLayout(this);
my $hboxLayout = Qt::HBoxLayout();
$hboxLayout->addWidget(lineEdit);
$hboxLayout->addWidget(fetchButton);
$hboxLayout->addWidget(abortButton);
$layout->addLayout($hboxLayout);
$layout->addWidget(treeWidget);
setWindowTitle(this->tr('RSS listing example'));
resize(640,480);
}
sub fetch
{
lineEdit->setReadOnly(1);
fetchButton->setEnabled(0);
abortButton->setEnabled(1);
treeWidget->clear();
xml->clear();
my $url = Qt::Url(lineEdit->text());
http->setHost($url->host());
this->{connectionId} = http->get($url->path());
}
sub readData
{
my ($resp) = @_;
if ($resp->statusCode() != 200) {
http->abort();
}
else {
xml->addData(http->readAll());
parseXml();
}
}
sub finished
{
my ($id, $error) = @_;
if ($error) {
print STDERR "Received error during HTTP fetch.\n";
lineEdit->setReadOnly(0);
abortButton->setEnabled(0);
fetchButton->setEnabled(1);
}
elsif ($id == connectionId) {
lineEdit->setReadOnly(0);
abortButton->setEnabled(0);
fetchButton->setEnabled(1);
}
}
sub parseXml()
{
while (!xml->atEnd()) {
xml->readNext();
if (xml->isStartElement()) {
if (xml->name()->toString() eq 'item') {
this->{linkString} = xml->attributes()->value('rss:about')->toString();
}
this->{currentTag} = xml->name()->toString();
} elsif (xml->isEndElement()) {
if (xml->name()->toString() eq 'item') {
my $item = Qt::TreeWidgetItem();
$item->setText(0, titleString);
$item->setText(1, linkString);
treeWidget->addTopLevelItem($item);
this->{titleString} = '';
this->{linkString} = '';
}
} elsif (xml->isCharacters() && !xml->isWhitespace()) {
if (currentTag eq 'title') {
this->{titleString} .= xml->text()->toString();
}
elsif (currentTag eq 'link') {
this->{linkString} .= xml->text()->toString();
}
}
}
if (xml->error() != Qt::XmlStreamReader::NoError() &&
xml->error() != Qt::XmlStreamReader::PrematureEndOfDocumentError()) {
print STDERR 'XML ERROR:' . xml->lineNumber() . ': ' . xml->errorString() . "\n";
http->abort();
}
}
sub itemActivated
{
my ($item) = @_;
Qt::DesktopServices::openUrl(Qt::Url($item->text(1)));
}
1;