[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [kdepim/akregator_port] /: support parsing of the outline hierarchy
From: Frank Osterfeld <frank.osterfeld () kdemail ! net>
Date: 2011-07-27 12:12:12
Message-ID: 20110727121212.E68C9A60D1 () git ! kde ! org
[Download RAW message or body]
Git commit 04b548d7763190b28052841ea9f71e0e3c9ed74e by Frank Osterfeld.
Committed on 08/11/2009 at 12:13.
Pushed by cgiboudeaux into branch 'akregator_port'.
support parsing of the outline hierarchy from OPML, to not lose the folder structure
svn path=/branches/work/akonadi-ports/kdepim/; revision=1046299
M +69 -19 krssresource/opmlparser.h
M +185 -137 krssresource/opmlparser.cpp
M +8 -5 resources/opmlresource/opmljobs.cpp
M +16 -10 krssresource/importopmljob.cpp
http://commits.kde.org/kdepim/04b548d7763190b28052841ea9f71e0e3c9ed74e
diff --git a/krssresource/importopmljob.cpp b/krssresource/importopmljob.cpp
index 74c8f79..80ada00 100644
--- a/krssresource/importopmljob.cpp
+++ b/krssresource/importopmljob.cpp
@@ -38,7 +38,7 @@
#include <cassert>
using namespace KRssResource;
-using boost::shared_ptr;
+using namespace boost;
ImportOpmlJob::ImportOpmlJob( const KUrl& path, QObject *parent )
: KJob( parent ), m_backendJob( 0 ), m_path( path ), m_pendingJobs( 0 )
@@ -208,22 +208,28 @@ void ImportOpmlJob::slotTagsCreated( KJob *job )
const TagsCreateJob * const tjob = qobject_cast<const TagsCreateJob*>( job );
assert( job );
const QList<KRss::Tag> tags = tjob->tags();
+ QHash<QString,KRss::Tag> tagByLabel;
- int currentFeed = 0;
- const QList<ParsedFeed> parsedFeeds = m_opmlReader.feeds();
+ Q_FOREACH ( const KRss::Tag& i, tags )
+ tagByLabel.insert( i.label(), i );
+
+ const QList<shared_ptr<const ParsedFeed> > parsedFeeds = m_opmlReader.feeds();
QList<Akonadi::Collection> feedsToImport;
- Q_FOREACH( const ParsedFeed& parsedFeed, parsedFeeds ) {
- KRss::FeedCollection feed = parsedFeed.toAkonadiCollection();
+ Q_FOREACH( const shared_ptr<const ParsedFeed>& parsedFeed, parsedFeeds ) {
+ KRss::FeedCollection feed = parsedFeed->toAkonadiCollection();
feed.setParent( m_rootCollection );
- const QList<int> tagIndexes = m_opmlReader.tagsForFeeds().value( currentFeed \
); kDebug() << "Current feed:" << feed.title();
- Q_FOREACH( int tagIndex, tagIndexes ) {
- kDebug() << "Adding tag:" << tags.at( tagIndex ).label() << ", id:" << \
tags.at( tagIndex ).id();
- feed.addTag( tags.at( tagIndex ).id() );
+ QStringList folderTitles = parsedFeed->parentFolderTitles();
+ folderTitles.erase( std::unique( folderTitles.begin(), folderTitles.end() ), \
folderTitles.end() ); + Q_FOREACH( const QString& i, folderTitles ) {
+ const KRss::Tag tag = tagByLabel.value( i );
+ if ( tag.isNull() )
+ continue;
+ kDebug() << "Adding tag:" << tag.label() << ", id:" << tag.id();
+ feed.addTag( tag.id() );
}
if ( !m_defaultTag.isEmpty() )
feed.addTag( tags.last().id() ); // the last one is the default tag
- ++currentFeed;
feedsToImport.append( feed );
}
diff --git a/krssresource/opmlparser.cpp b/krssresource/opmlparser.cpp
index be67290..df1c897 100644
--- a/krssresource/opmlparser.cpp
+++ b/krssresource/opmlparser.cpp
@@ -26,93 +26,104 @@
#include <QtXml/QXmlAttributes>
#include <memory>
+using namespace boost;
using namespace KRssResource;
-class ParsedFeed::Private : public QSharedData
-{
+class ParsedNode::Private {
public:
- Private() {}
+ QString title;
+ QHash<QString, QString> attributes;
+ weak_ptr<ParsedFolder> parent;
+};
- Private( const Private& other );
+ParsedNode::ParsedNode() : d( new Private ) {
+}
- bool operator!=( const Private& other ) const
- {
- return !( *this == other );
- }
+weak_ptr<ParsedFolder> ParsedNode::parent() const {
+ return d->parent;
+}
- bool operator==( const Private& other ) const
- {
- return title == other.title
- && xmlUrl == other.xmlUrl
- && htmlUrl == other.htmlUrl
- && description == other.description
- && type == other.type
- && attributes == other.attributes;
- }
+void ParsedNode::setParent( const weak_ptr<ParsedFolder>& parent ) {
+ d->parent = parent;
+}
- QString title;
- QString xmlUrl;
- QString htmlUrl;
- QString description;
- QString type;
- QHash<QString, QString> attributes;
-};
+ParsedNode::~ParsedNode() {
+ delete d;
+}
-ParsedFeed::Private::Private( const Private& other )
- : QSharedData( other ),
- title( other.title ),
- xmlUrl( other.xmlUrl ),
- htmlUrl( other.htmlUrl ),
- description( other.description ),
- type( other.type ),
- attributes( other.attributes )
-{
+QString ParsedNode::title() const {
+ return d->title;
}
-ParsedFeed::ParsedFeed() : d( new Private )
-{
+void ParsedNode::setTitle( const QString& title ) {
+ d->title = title;
}
-ParsedFeed::~ParsedFeed()
+QString ParsedNode::attribute( const QString& key ) const {
+ return d->attributes.value( key );
+}
+
+QHash<QString, QString> ParsedNode::attributes() const
{
+ return d->attributes;
}
-void ParsedFeed::swap( ParsedFeed& other )
+void ParsedNode::setAttribute( const QString& key, const QString& value )
{
- std::swap( d, other.d );
+ d->attributes.insert( key, value );
}
-ParsedFeed& ParsedFeed::operator=( const ParsedFeed& other )
+void ParsedNode::setAttributes( const QHash<QString, QString>& attributes )
{
- ParsedFeed copy( other );
- swap( copy );
- return *this;
+ d->attributes = attributes;
}
-bool ParsedFeed::operator==( const ParsedFeed& other ) const
+QStringList ParsedNode::parentFolderTitles() const {
+ QStringList labels;
+ shared_ptr<ParsedNode> it = parent().lock();
+ while ( it ) {
+ labels.push_back( it->title() );
+ it = it->parent().lock();
+ }
+ return labels;
+}
+
+class ParsedFeed::Private
+{
+public:
+ Private() {}
+
+ QString xmlUrl;
+ QString htmlUrl;
+ QString description;
+ QString type;
+};
+
+ParsedFeed::ParsedFeed() : d( new Private )
{
- return *d == *(other.d);
}
-bool ParsedFeed::operator!=( const ParsedFeed& other ) const
+ParsedFeed::~ParsedFeed()
{
- return *d != *(other.d);
+ delete d;
}
-ParsedFeed::ParsedFeed( const ParsedFeed& other ) : d( other.d )
+bool ParsedFeed::isFolder() const
{
+ return false;
}
-QString ParsedFeed::title() const
+QList<shared_ptr<const ParsedFeed> > ParsedFeed::feeds() const
{
- return d->title;
+ return QList<shared_ptr<const ParsedFeed> >() << static_pointer_cast<const \
ParsedFeed>( shared_from_this() ); }
-void ParsedFeed::setTitle( const QString& title )
+QList<shared_ptr<const ParsedFolder> > ParsedFeed::folders() const
{
- d->title = title;
+ return QList<shared_ptr<const ParsedFolder> >();
}
+
QString ParsedFeed::xmlUrl() const
{
return d->xmlUrl;
@@ -153,48 +164,78 @@ void ParsedFeed::setType( const QString& type )
d->type = type;
}
-QHash<QString, QString> ParsedFeed::attributes() const
-{
- return d->attributes;
-}
-
-void ParsedFeed::setAttribute( const QString& key, const QString& value )
-{
- d->attributes.insert( key, value );
-}
-
-void ParsedFeed::setAttributes( const QHash<QString, QString>& attributes )
-{
- d->attributes = attributes;
-}
Akonadi::Collection ParsedFeed::toAkonadiCollection() const
{
KRss::FeedCollection feed;
- feed.setRemoteId( d->attributes.value( QLatin1String("remoteid") ) );
- feed.setTitle( d->title );
+ feed.setRemoteId( attribute( QLatin1String("remoteid") ) );
+ feed.setTitle( title() );
feed.setXmlUrl( d->xmlUrl );
feed.setHtmlUrl( d->htmlUrl );
feed.setDescription( d->description );
feed.setFeedType( d->type );
- feed.setName( d->title );
+ feed.setName( title() );
feed.setContentMimeTypes( QStringList( QLatin1String("application/rss+xml") ) );
return feed;
}
-ParsedFeed ParsedFeed::fromAkonadiCollection( const Akonadi::Collection& collection \
) +shared_ptr<ParsedFeed> ParsedFeed::fromAkonadiCollection( const \
Akonadi::Collection& collection ) {
const KRss::FeedCollection feedCollection = collection;
- ParsedFeed parsedFeed;
- parsedFeed.d->title = feedCollection.title();
- parsedFeed.d->xmlUrl = feedCollection.xmlUrl();
- parsedFeed.d->htmlUrl = feedCollection.htmlUrl();
- parsedFeed.d->description = feedCollection.description();
- parsedFeed.d->type = feedCollection.feedType();
- parsedFeed.d->attributes.insert( QLatin1String("remoteid"), \
feedCollection.remoteId() ); + shared_ptr<ParsedFeed> parsedFeed( new ParsedFeed \
); + parsedFeed->setTitle( feedCollection.title() );
+ parsedFeed->d->xmlUrl = feedCollection.xmlUrl();
+ parsedFeed->d->htmlUrl = feedCollection.htmlUrl();
+ parsedFeed->d->description = feedCollection.description();
+ parsedFeed->d->type = feedCollection.feedType();
+ parsedFeed->setAttribute( QLatin1String("remoteid"), feedCollection.remoteId() \
); return parsedFeed;
}
+class ParsedFolder::Private {
+public:
+ QList<shared_ptr<ParsedNode> > children;
+};
+
+ParsedFolder::ParsedFolder() : d( new Private ) {
+
+}
+
+ParsedFolder::~ParsedFolder() {
+ delete d;
+}
+
+bool ParsedFolder::isFolder() const {
+ return true;
+}
+
+QList<shared_ptr<const ParsedFeed> > ParsedFolder::feeds() const {
+ QList<shared_ptr<const ParsedFeed> > f;
+ Q_FOREACH( const shared_ptr<const ParsedNode>& i, d->children )
+ f << i->feeds();
+ return f;
+}
+
+QList<shared_ptr<const ParsedFolder> > ParsedFolder::folders() const {
+ QList<shared_ptr<const ParsedFolder> > f;
+ f << static_pointer_cast<const ParsedFolder>( shared_from_this() );
+ Q_FOREACH( const shared_ptr<const ParsedNode>& i, d->children )
+ f << i->folders();
+ return f;
+}
+
+QList<shared_ptr<ParsedNode> > ParsedFolder::children() const {
+ return d->children;
+}
+
+void ParsedFolder::setChildren( const QList<shared_ptr<ParsedNode> >& children ) {
+ d->children = children;
+}
+
+void ParsedFolder::addChild( const shared_ptr<ParsedNode>& child ) {
+ d->children.push_back( child );
+}
+
class OpmlReader::Private
{
public:
@@ -202,12 +243,10 @@ public:
QStringRef attributeValue( const QXmlStreamAttributes& attributes, const \
QString& name ); void readBody( QXmlStreamReader& reader );
- void readOutline( QXmlStreamReader& reader, QStringList& currentTags );
+ void readOutline( QXmlStreamReader& reader, const shared_ptr<ParsedFolder> \
&parent ); void readUnknownElement( QXmlStreamReader& reader );
- QList<ParsedFeed> m_feeds;
- QList<QString > m_tags;
- QHash<int, QList<int> > m_tagsForFeeds;
+ QList<shared_ptr<ParsedNode> > m_topNodes;
};
QStringRef OpmlReader::Private::attributeValue( const QXmlStreamAttributes& \
attributes, const QString& name ) @@ -233,8 +272,7 @@ void \
OpmlReader::Private::readBody( QXmlStreamReader& reader )
if ( reader.isStartElement() ) {
if ( reader.name().toString().toLower() == QLatin1String("outline") ) {
- QStringList currentTags;
- readOutline( reader, currentTags );
+ readOutline( reader, shared_ptr<ParsedFolder>() );
}
else {
readUnknownElement( reader );
@@ -243,22 +281,30 @@ void OpmlReader::Private::readBody( QXmlStreamReader& reader )
}
}
-void OpmlReader::Private::readOutline( QXmlStreamReader& reader, QStringList& \
currentTags ) +void OpmlReader::Private::readOutline( QXmlStreamReader& reader, const \
shared_ptr<ParsedFolder>& parent ) {
Q_ASSERT( reader.isStartElement() && reader.name().toString().toLower() == \
QLatin1String("outline") );
- bool isFolder = false;
+ shared_ptr<ParsedNode> newNode;
const QString xmlUrl = attributeValue( reader.attributes(), \
QLatin1String("xmlurl") ).toString();
if ( xmlUrl.isEmpty() ) {
const QStringRef textAttribute = attributeValue( reader.attributes(), \
QLatin1String("text") ); if ( !textAttribute.isEmpty() ) {
// this attribute seem to represent a folder
- isFolder = true;
- if ( !currentTags.contains( textAttribute.toString() ) )
- currentTags.append( textAttribute.toString() );
+ shared_ptr<ParsedFolder> newFolder( new ParsedFolder );
+ newNode = newFolder;
+ const QXmlStreamAttributes attrs = reader.attributes();
- kDebug() << "Current tags:" << currentTags;
+ Q_FOREACH( const QXmlStreamAttribute& attr, attrs ) {
+ if ( attr.name().toString().toLower() == QLatin1String("title") )
+ newFolder->setTitle( attr.value().toString() );
+ else if ( newFolder->title().isEmpty() && \
attr.name().toString().toLower() == QLatin1String("text") ) + \
newFolder->setTitle( attr.value().toString() ); + else {
+ newFolder->setAttribute( attr.name().toString(), \
attr.value().toString() ); + }
+ }
}
else {
kDebug() << "Encountered an empty outline";
@@ -271,54 +317,49 @@ void OpmlReader::Private::readOutline( QXmlStreamReader& \
reader, QStringList& cu else {
// this is a feed
kDebug() << "Feed:" << xmlUrl;
- isFolder = false;
- ParsedFeed feed;
+ shared_ptr<ParsedFeed> newFeed( new ParsedFeed );
+ newNode = newFeed;
const QXmlStreamAttributes attrs = reader.attributes();
Q_FOREACH( const QXmlStreamAttribute& attr, attrs ) {
if ( attr.name().toString().toLower() == QLatin1String("title") )
- feed.setTitle( attr.value().toString() );
- else if ( attr.name().toString().toLower() == QLatin1String("text") && \
feed.title().isEmpty() )
- feed.setTitle( attr.value().toString() );
+ newFeed->setTitle( attr.value().toString() );
+ else if ( newFeed->title().isEmpty() && attr.name().toString().toLower() \
== QLatin1String("text") ) + newFeed->setTitle( \
attr.value().toString() );
else if ( attr.name().toString().toLower() == QLatin1String("htmlurl") )
- feed.setHtmlUrl( attr.value().toString() );
+ newFeed->setHtmlUrl( attr.value().toString() );
else if ( attr.name().toString().toLower() == QLatin1String("xmlurl") )
- feed.setXmlUrl( attr.value().toString() );
+ newFeed->setXmlUrl( attr.value().toString() );
else if ( attr.name().toString().toLower() == \
QLatin1String("description") )
- feed.setDescription( attr.value().toString() );
+ newFeed->setDescription( attr.value().toString() );
else if ( attr.name().toString().toLower() == QLatin1String("type") )
- feed.setType( attr.value().toString() );
+ newFeed->setType( attr.value().toString() );
else if ( attr.name().toString().toLower() == QLatin1String("category") \
) {
const QStringList categories = attr.value().toString().split( \
QRegExp( QLatin1String("[,/]") ), QString::SkipEmptyParts ); +#if 0
Q_FOREACH( const QString& category, categories ) {
if ( !currentTags.contains( category ) )
currentTags.append( category );
}
+#endif
}
else {
- feed.setAttribute( attr.name().toString(), attr.value().toString() \
); + newFeed->setAttribute( attr.name().toString(), \
attr.value().toString() ); }
}
- if ( feed.title().isEmpty() )
- feed.setTitle( xmlUrl );
+ if ( newFeed->title().isEmpty() )
+ newFeed->setTitle( xmlUrl );
- if ( feed.type().isEmpty() )
- feed.setType( QLatin1String("rss") );
-
- // everything is parsed
- QList<int> currentTagIds;
- Q_FOREACH( const QString& tag, currentTags ) {
- int index = m_tags.indexOf( tag );
- if ( index == -1 ) {
- m_tags.append( tag );
- index = m_tags.count() - 1;
- }
- currentTagIds.append( index );
- }
+ if ( newFeed->type().isEmpty() )
+ newFeed->setType( QLatin1String("rss") );
+ }
- m_feeds.append( feed );
- m_tagsForFeeds.insert( m_feeds.count() - 1, currentTagIds );
+ if ( parent ) {
+ parent->addChild( newNode );
+ newNode->setParent( parent );
}
+ else
+ m_topNodes.append( newNode );
while ( !reader.atEnd() ) {
reader.readNext();
@@ -327,17 +368,12 @@ void OpmlReader::Private::readOutline( QXmlStreamReader& \
reader, QStringList& cu break;
if ( reader.isStartElement() ) {
- if ( reader.name().toString().toLower() == QLatin1String("outline") && \
isFolder )
- readOutline( reader, currentTags );
+ if ( reader.name().toString().toLower() == QLatin1String("outline") && \
newNode->isFolder() ) + readOutline( reader, \
static_pointer_cast<ParsedFolder>( newNode ) ); else
readUnknownElement( reader );
}
}
-
- // once we are back from recursion remove the added tag
- // from the top of the list
- if ( isFolder )
- currentTags.removeLast();
}
void OpmlReader::Private::readUnknownElement( QXmlStreamReader& reader )
@@ -365,19 +401,31 @@ OpmlReader::~OpmlReader()
delete d;
}
-QList<ParsedFeed> OpmlReader::feeds() const
+QList<shared_ptr<const ParsedFeed> > OpmlReader::feeds() const
{
- return d->m_feeds;
+ QList<shared_ptr<const ParsedFeed> > f;
+ Q_FOREACH ( const shared_ptr<const ParsedNode>& i, d->m_topNodes )
+ f << i->feeds();
+ return f;
}
-QList<QString> OpmlReader::tags() const
+QList<shared_ptr<const ParsedNode> > OpmlReader::topLevelNodes() const
{
- return d->m_tags;
+ QList<shared_ptr<const ParsedNode> > l;
+ Q_FOREACH( const shared_ptr<ParsedNode>& i, d->m_topNodes )
+ l << i;
+ return l;
}
-QHash<int, QList<int> > OpmlReader::tagsForFeeds() const
+QStringList OpmlReader::tags() const
{
- return d->m_tagsForFeeds;
+ QStringList titles;
+ QList<shared_ptr<const ParsedFolder> > f;
+ Q_FOREACH ( const shared_ptr<const ParsedNode>& i, d->m_topNodes )
+ f << i->folders();
+ Q_FOREACH ( const shared_ptr<const ParsedFolder>& i, f )
+ titles << i->title();
+ return titles;
}
void OpmlReader::readOpml( QXmlStreamReader& reader )
@@ -404,28 +452,28 @@ void OpmlReader::readOpml( QXmlStreamReader& reader )
}
}
-void OpmlWriter::writeOpml( QXmlStreamWriter& writer, const QList<ParsedFeed>& feeds \
) +void OpmlWriter::writeOpml( QXmlStreamWriter& writer, const \
QList<shared_ptr<ParsedFeed> >& feeds ) {
writer.writeStartElement( QLatin1String("opml") );
writer.writeAttribute( QLatin1String("version"), QLatin1String("2.0") );
writer.writeEmptyElement( QLatin1String("head") );
writer.writeStartElement( QLatin1String("body") );
- Q_FOREACH( const ParsedFeed& feed, feeds ) {
+ Q_FOREACH( const shared_ptr<ParsedFeed>& feed, feeds ) {
writeOutline( writer, feed );
}
writer.writeEndElement(); // body
writer.writeEndElement(); // opml
}
-void OpmlWriter::writeOutline( QXmlStreamWriter& writer, const ParsedFeed& feed )
+void OpmlWriter::writeOutline( QXmlStreamWriter& writer, const \
shared_ptr<ParsedFeed>& feed ) {
writer.writeStartElement( QLatin1String("outline") );
- writer.writeAttribute( QLatin1String("text"), feed.title() );
- writer.writeAttribute( QLatin1String("title"), feed.title() );
- writer.writeAttribute( QLatin1String("description"), feed.description() );
- writer.writeAttribute( QLatin1String("htmlUrl"), feed.htmlUrl() );
- writer.writeAttribute( QLatin1String("xmlUrl"), feed.xmlUrl() );
- QHashIterator<QString, QString> it( feed.attributes() );
+ writer.writeAttribute( QLatin1String("text"), feed->title() );
+ writer.writeAttribute( QLatin1String("title"), feed->title() );
+ writer.writeAttribute( QLatin1String("description"), feed->description() );
+ writer.writeAttribute( QLatin1String("htmlUrl"), feed->htmlUrl() );
+ writer.writeAttribute( QLatin1String("xmlUrl"), feed->xmlUrl() );
+ QHashIterator<QString, QString> it( feed->attributes() );
while ( it.hasNext() ) {
it.next();
writer.writeAttribute( it.key(), it.value() );
diff --git a/krssresource/opmlparser.h b/krssresource/opmlparser.h
index 696eb57..c393fb8 100644
--- a/krssresource/opmlparser.h
+++ b/krssresource/opmlparser.h
@@ -24,28 +24,60 @@
#include <QtCore/QString>
#include <QtCore/QList>
#include <QtCore/QHash>
-#include <QtCore/QSharedDataPointer>
+#include <QtCore/QStringList>
#include <QtCore/QXmlStreamReader>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+#include <boost/weak_ptr.hpp>
+
class QXmlStreamWriter;
class QXmlStreamAttributes;
namespace KRssResource {
-class KRSSRESOURCE_EXPORT ParsedFeed
+class ParsedFeed;
+class ParsedFolder;
+
+class KRSSRESOURCE_EXPORT ParsedNode : public \
boost::enable_shared_from_this<ParsedNode> {
public:
- ParsedFeed();
- ParsedFeed( const ParsedFeed& other );
- ~ParsedFeed();
+ ParsedNode();
+ virtual ~ParsedNode();
- void swap( ParsedFeed& other );
- ParsedFeed& operator=( const ParsedFeed& other );
- bool operator==( const ParsedFeed& other ) const;
- bool operator!=( const ParsedFeed& other ) const;
+ boost::weak_ptr<ParsedFolder> parent() const;
+ void setParent( const boost::weak_ptr<ParsedFolder>& parent );
+ virtual bool isFolder() const = 0;
+ virtual QList<boost::shared_ptr<const ParsedFeed> > feeds() const = 0;
+ virtual QList<boost::shared_ptr<const ParsedFolder> > folders() const = 0;
QString title() const;
void setTitle( const QString& title );
+
+ QString attribute( const QString& key ) const;
+ QHash<QString, QString> attributes() const;
+ void setAttribute( const QString& key, const QString& value );
+ void setAttributes( const QHash<QString, QString>& attributes );
+
+ QStringList parentFolderTitles() const;
+
+private:
+ Q_DISABLE_COPY(ParsedNode);
+ class Private;
+ Private* const d;
+};
+
+class KRSSRESOURCE_EXPORT ParsedFeed : public ParsedNode
+{
+public:
+ ParsedFeed();
+ ~ParsedFeed();
+
+ /* reimp */ bool isFolder() const;
+ /* reimp */ QList<boost::shared_ptr<const ParsedFeed> > feeds() const;
+ /* reimp */ QList<boost::shared_ptr<const ParsedFolder> > folders() const;
+
QString xmlUrl() const;
void setXmlUrl( const QString& xmlUrl );
QString htmlUrl() const;
@@ -54,16 +86,33 @@ public:
void setDescription( const QString& description );
QString type() const;
void setType( const QString& type );
- QHash<QString, QString> attributes() const;
- void setAttribute( const QString& key, const QString& value );
- void setAttributes( const QHash<QString, QString>& attributes );
Akonadi::Collection toAkonadiCollection() const;
- static ParsedFeed fromAkonadiCollection( const Akonadi::Collection& collection \
); + static boost::shared_ptr<ParsedFeed> fromAkonadiCollection( const \
Akonadi::Collection& collection );
private:
+ Q_DISABLE_COPY(ParsedFeed);
class Private;
- QSharedDataPointer<Private> d;
+ Private* const d;
+};
+
+class KRSSRESOURCE_EXPORT ParsedFolder : public ParsedNode
+{
+public:
+ ParsedFolder();
+ ~ParsedFolder();
+
+ /* reimp */ bool isFolder() const;
+ /* reimp */ QList<boost::shared_ptr<const ParsedFeed> > feeds() const;
+ /* reimp */ QList<boost::shared_ptr<const ParsedFolder> > folders() const;
+
+ QList<boost::shared_ptr<ParsedNode> > children() const;
+ void setChildren( const QList<boost::shared_ptr<ParsedNode> >& children );
+ void addChild( const boost::shared_ptr<ParsedNode>& child );
+
+private:
+ class Private;
+ Private* const d;
};
class KRSSRESOURCE_EXPORT OpmlReader
@@ -74,9 +123,10 @@ public:
void readOpml( QXmlStreamReader& reader );
- QList<ParsedFeed> feeds() const;
- QList<QString> tags() const;
- QHash<int, QList<int> > tagsForFeeds() const;
+ QList<boost::shared_ptr<const ParsedFeed> > feeds() const;
+ QList<boost::shared_ptr<const ParsedNode> > topLevelNodes() const;
+
+ QStringList tags() const;
private:
class Private;
@@ -87,8 +137,8 @@ private:
class KRSSRESOURCE_EXPORT OpmlWriter
{
public:
- static void writeOpml( QXmlStreamWriter& writer, const QList<ParsedFeed>& feeds \
);
- static void writeOutline( QXmlStreamWriter& writer, const ParsedFeed& feed );
+ static void writeOpml( QXmlStreamWriter& writer, const \
QList<boost::shared_ptr<ParsedFeed> >& feeds ); + static void writeOutline( \
QXmlStreamWriter& writer, const boost::shared_ptr<ParsedFeed>& feed ); };
} //namespace KRssResource
diff --git a/resources/opmlresource/opmljobs.cpp \
b/resources/opmlresource/opmljobs.cpp index 520f18c..c953638 100644
--- a/resources/opmlresource/opmljobs.cpp
+++ b/resources/opmlresource/opmljobs.cpp
@@ -28,14 +28,17 @@
#include <QtCore/QXmlStreamReader>
#include <QtCore/QUuid>
+#include <boost/shared_ptr.hpp>
+
+using namespace boost;
using namespace KRss;
using namespace KRssResource;
namespace {
-static QList<ParsedFeed> toParsedFeedList( const QList<Akonadi::Collection>& feeds )
+static QList<shared_ptr<ParsedFeed> > toParsedFeedList( const \
QList<Akonadi::Collection>& feeds ) {
- QList<ParsedFeed> parsedFeeds;
+ QList<shared_ptr<ParsedFeed> > parsedFeeds;
Q_FOREACH( const Akonadi::Collection& feed, feeds ) {
if ( feed.parent() != Akonadi::Collection::root().id() )
parsedFeeds.append( ParsedFeed::fromAkonadiCollection( feed ) );
@@ -150,9 +153,9 @@ void OpmlFeedsRetrieveJob::slotGetFinished( KJob *job )
m_feedsCache.insert( top.remoteId(), top );
bool needsPut = false;
- const QList<ParsedFeed> parsedFeeds = opmlReader.feeds();
- Q_FOREACH( const ParsedFeed& parsedFeed, parsedFeeds ) {
- FeedCollection feed = parsedFeed.toAkonadiCollection();
+ const QList<shared_ptr<const ParsedFeed> > parsedFeeds = opmlReader.feeds();
+ Q_FOREACH( const shared_ptr<const ParsedFeed>& parsedFeed, parsedFeeds ) {
+ FeedCollection feed = parsedFeed->toAkonadiCollection();
if ( feed.remoteId().isEmpty() ) {
feed.setRemoteId( QUuid::createUuid().toString() );
needsPut = true;
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic