akonadi
collectionpathresolver.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "collectionpathresolver_p.h"
00021
00022 #include "collectionfetchjob.h"
00023 #include "job_p.h"
00024
00025 #include <klocale.h>
00026
00027 #include <QtCore/QStringList>
00028
00029 using namespace Akonadi;
00030
00031
00032
00033 class Akonadi::CollectionPathResolverPrivate : public JobPrivate
00034 {
00035 public:
00036 CollectionPathResolverPrivate( CollectionPathResolver *parent )
00037 : JobPrivate( parent )
00038 {
00039 }
00040
00041 void jobResult( KJob* );
00042
00043 QStringList splitPath( const QString &path )
00044 {
00045 if ( path.isEmpty() )
00046 return QStringList();
00047
00048 QStringList rv;
00049 int begin = 0;
00050 for ( int i = 0; i < path.size(); ++i ) {
00051 if ( path[i] == QLatin1Char('/') ) {
00052 QString pathElement = path.mid( begin, i - begin );
00053 pathElement = pathElement.replace( QLatin1String( "\\/" ), QLatin1String( "/" ) );
00054 rv.append( pathElement );
00055 begin = i + 1;
00056 }
00057 if ( i < path.size() - 2 && path[i] == QLatin1Char('\\') && path[i + 1] == QLatin1Char('/') )
00058 ++i;
00059 }
00060 QString pathElement = path.mid( begin );
00061 pathElement = pathElement.replace( QLatin1String( "\\/" ), QLatin1String( "/" ) );
00062 rv.append( pathElement );
00063 return rv;
00064 }
00065
00066 Q_DECLARE_PUBLIC( CollectionPathResolver )
00067
00068 Collection::Id mColId;
00069 QString mPath;
00070 bool mPathToId;
00071 QStringList mPathParts;
00072 Collection mCurrentNode;
00073 };
00074
00075 void CollectionPathResolverPrivate::jobResult(KJob *job )
00076 {
00077 if ( job->error() )
00078 return;
00079
00080 Q_Q( CollectionPathResolver );
00081
00082 CollectionFetchJob *list = static_cast<CollectionFetchJob*>( job );
00083 CollectionFetchJob *nextJob = 0;
00084 const Collection::List cols = list->collections();
00085 if ( cols.isEmpty() ) {
00086 q->setError( CollectionPathResolver::Unknown );
00087 q->setErrorText( i18n( "No such collection.") );
00088 q->emitResult();
00089 return;
00090 }
00091
00092 if ( mPathToId ) {
00093 const QString currentPart = mPathParts.takeFirst();
00094 bool found = false;
00095 foreach ( const Collection &c, cols ) {
00096 if ( c.name() == currentPart ) {
00097 mCurrentNode = c;
00098 found = true;
00099 break;
00100 }
00101 }
00102 if ( !found ) {
00103 q->setError( CollectionPathResolver::Unknown );
00104 q->setErrorText( i18n( "No such collection.") );
00105 q->emitResult();
00106 return;
00107 }
00108 if ( mPathParts.isEmpty() ) {
00109 mColId = mCurrentNode.id();
00110 q->emitResult();
00111 return;
00112 }
00113 nextJob = new CollectionFetchJob( mCurrentNode, CollectionFetchJob::FirstLevel, q );
00114 } else {
00115 Collection col = list->collections().first();
00116 mCurrentNode = col.parentCollection();
00117 mPathParts.prepend( col.name() );
00118 if ( mCurrentNode == Collection::root() ) {
00119 q->emitResult();
00120 return;
00121 }
00122 nextJob = new CollectionFetchJob( mCurrentNode, CollectionFetchJob::Base, q );
00123 }
00124 q->connect( nextJob, SIGNAL(result(KJob*)), q, SLOT(jobResult(KJob*)) );
00125 }
00126
00127 CollectionPathResolver::CollectionPathResolver(const QString & path, QObject * parent)
00128 : Job( new CollectionPathResolverPrivate( this ), parent )
00129 {
00130 Q_D( CollectionPathResolver );
00131
00132 d->mPathToId = true;
00133 d->mPath = path;
00134 if ( d->mPath.startsWith( pathDelimiter() ) )
00135 d->mPath = d->mPath.right( d->mPath.length() - pathDelimiter().length() );
00136 if ( d->mPath.endsWith( pathDelimiter() ) )
00137 d->mPath = d->mPath.left( d->mPath.length() - pathDelimiter().length() );
00138
00139 d->mPathParts = d->splitPath( d->mPath );
00140 d->mCurrentNode = Collection::root();
00141 }
00142
00143 CollectionPathResolver::CollectionPathResolver(const Collection & collection, QObject * parent)
00144 : Job( new CollectionPathResolverPrivate( this ), parent )
00145 {
00146 Q_D( CollectionPathResolver );
00147
00148 d->mPathToId = false;
00149 d->mColId = collection.id();
00150 d->mCurrentNode = collection;
00151 }
00152
00153 CollectionPathResolver::~CollectionPathResolver()
00154 {
00155 }
00156
00157 Collection::Id CollectionPathResolver::collection() const
00158 {
00159 Q_D( const CollectionPathResolver );
00160
00161 return d->mColId;
00162 }
00163
00164 QString CollectionPathResolver::path() const
00165 {
00166 Q_D( const CollectionPathResolver );
00167
00168 if ( d->mPathToId )
00169 return d->mPath;
00170 return d->mPathParts.join( pathDelimiter() );
00171 }
00172
00173 QString CollectionPathResolver::pathDelimiter()
00174 {
00175 return QLatin1String( "/" );
00176 }
00177
00178 void CollectionPathResolver::doStart()
00179 {
00180 Q_D( CollectionPathResolver );
00181
00182 CollectionFetchJob *job = 0;
00183 if ( d->mPathToId ) {
00184 if ( d->mPath.isEmpty() ) {
00185 d->mColId = Collection::root().id();
00186 emitResult();
00187 return;
00188 }
00189 job = new CollectionFetchJob( d->mCurrentNode, CollectionFetchJob::FirstLevel, this );
00190 } else {
00191 if ( d->mColId == 0 ) {
00192 d->mColId = Collection::root().id();
00193 emitResult();
00194 return;
00195 }
00196 job = new CollectionFetchJob( d->mCurrentNode, CollectionFetchJob::Base, this );
00197 }
00198 connect( job, SIGNAL(result(KJob*)), SLOT(jobResult(KJob*)) );
00199 }
00200
00201
00202
00203 #include "collectionpathresolver_p.moc"