[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [kdepim-runtime/KDE/4.11] resources/imap: Fix support for IMAP servers with non-standard path separa
From:       Dan_Vrátil <dvratil () redhat ! com>
Date:       2013-09-24 11:43:43
Message-ID: E1VOR1r-0000fy-QY () scm ! kde ! org
[Download RAW message or body]

Git commit ed7a89ac5d45948114e7f15cba64972a9cf903a6 by Dan Vrátil.
Committed on 24/09/2013 at 09:55.
Pushed by dvratil into branch 'KDE/4.11'.

Fix support for IMAP servers with non-standard path separators

REVIEW: 112761
BUG: 324219
FIXED-IN: 4.11.2

M  +10   -0    resources/imap/imapresource.cpp
M  +3    -0    resources/imap/imapresource.h
M  +10   -23   resources/imap/resourcestate.cpp
M  +3    -1    resources/imap/resourcestate.h
M  +23   -1    resources/imap/resourcestateinterface.cpp
M  +4    -1    resources/imap/resourcestateinterface.h
M  +26   -6    resources/imap/resourcetask.cpp
M  +1    -0    resources/imap/resourcetask.h
M  +6    -0    resources/imap/retrievecollectionstask.cpp

http://commits.kde.org/kdepim-runtime/ed7a89ac5d45948114e7f15cba64972a9cf903a6

diff --git a/resources/imap/imapresource.cpp b/resources/imap/imapresource.cpp
index a2f16fd..3506d3b 100644
--- a/resources/imap/imapresource.cpp
+++ b/resources/imap/imapresource.cpp
@@ -541,6 +541,16 @@ void ImapResource::doSetOnline(bool online)
   ResourceBase::doSetOnline( online );
 }
 
+QChar ImapResource::separatorCharacter() const
+{
+    return m_separatorCharacter;
+}
+
+void ImapResource::setSeparatorCharacter( const QChar &separator )
+{
+    m_separatorCharacter = separator;
+}
+
 bool ImapResource::needsNetwork() const
 {
   const QString hostName = Settings::self()->imapServer().section( ':', 0, 0 );
diff --git a/resources/imap/imapresource.h b/resources/imap/imapresource.h
index a137497..6fe6402 100644
--- a/resources/imap/imapresource.h
+++ b/resources/imap/imapresource.h
@@ -100,6 +100,8 @@ protected:
 
   virtual void doSetOnline(bool online);
 
+  QChar separatorCharacter() const;
+  void setSeparatorCharacter( const QChar &separator );
 
 private Q_SLOTS:
   void reconnect();
@@ -139,6 +141,7 @@ private:
   bool m_fastSync;
   Akonadi::Session *m_bodyCheckSession;
   QTimer *m_statusMessageTimer;
+  QChar m_separatorCharacter;
 };
 
 #endif
diff --git a/resources/imap/resourcestate.cpp b/resources/imap/resourcestate.cpp
index 5d521a5..195d87d 100644
--- a/resources/imap/resourcestate.cpp
+++ b/resources/imap/resourcestate.cpp
@@ -307,29 +307,6 @@ QString ResourceState::rootRemoteId() const
   return Settings::self()->rootRemoteId();
 }
 
-QString ResourceState::mailBoxForCollection( const Akonadi::Collection &collection, \
                bool showWarnings ) const
-{
-  if ( collection.remoteId().isEmpty() ) { //This should never happen, investigate \
                why a collection without remoteId made it this far
-    if ( showWarnings )
-      kWarning() << "Got incomplete ancestor chain due to empty remoteId:" << \
                collection;
-    return QString();
-  }
-
-  if ( collection.parentCollection() == Akonadi::Collection::root() ) {
-    if ( showWarnings )
-      kWarning( collection.remoteId() != rootRemoteId() ) << "RID mismatch, is " << \
                collection.remoteId() << " expected " << rootRemoteId();
-    return QString( "" );
-  }
-  const QString parentMailbox = mailBoxForCollection( collection.parentCollection() \
                );
-  if ( parentMailbox.isNull() ) // invalid, != isEmpty() here!
-    return QString();
-
-  const QString mailbox =  parentMailbox + collection.remoteId();
-  if ( parentMailbox.isEmpty() )
-    return mailbox.mid( 1 ); // strip of the separator on top-level mailboxes
-  return mailbox;
-}
-
 void ResourceState::setIdleCollection( const Akonadi::Collection &collection )
 {
   QStringList ridPath;
@@ -506,6 +483,16 @@ void ResourceState::scheduleConnectionAttempt()
   m_resource->scheduleConnectionAttempt();
 }
 
+QChar ResourceState::separatorCharacter() const
+{
+  return m_resource->separatorCharacter();
+}
+
+void ResourceState::setSeparatorCharacter( const QChar &separator )
+{
+  m_resource->setSeparatorCharacter( separator );
+}
+
 void ResourceState::showInformationDialog( const QString &message, const QString \
&title, const QString &dontShowAgainName )  {
   KMessageBox::information( 0, message, title, dontShowAgainName );
diff --git a/resources/imap/resourcestate.h b/resources/imap/resourcestate.h
index 87e9811..9154716 100644
--- a/resources/imap/resourcestate.h
+++ b/resources/imap/resourcestate.h
@@ -113,7 +113,6 @@ public:
   virtual QSet<QByteArray> removedFlags() const;
 
   virtual QString rootRemoteId() const;
-  virtual QString mailBoxForCollection( const Akonadi::Collection &collection, bool \
showWarnings = true ) const;  
   virtual void setIdleCollection( const Akonadi::Collection &collection );
   virtual void applyCollectionChanges( const Akonadi::Collection &collection );
@@ -147,6 +146,9 @@ public:
   virtual void synchronizeCollectionTree();
   virtual void scheduleConnectionAttempt();
 
+  virtual QChar separatorCharacter() const;
+  virtual void setSeparatorCharacter( const QChar &separator );
+
   virtual void showInformationDialog( const QString &message, const QString &title, \
const QString &dontShowAgainName );  
 private:
diff --git a/resources/imap/resourcestateinterface.cpp \
b/resources/imap/resourcestateinterface.cpp index d4dbff0..4784668 100644
--- a/resources/imap/resourcestateinterface.cpp
+++ b/resources/imap/resourcestateinterface.cpp
@@ -26,4 +26,26 @@ ResourceStateInterface::~ResourceStateInterface()
 
 }
 
-
+QString ResourceStateInterface::mailBoxForCollection( const Akonadi::Collection \
&collection, bool showWarnings ) +{
+  if ( collection.remoteId().isEmpty() ) { //This should never happen, investigate \
why a collection without remoteId made it this far +    if ( showWarnings )
+      kWarning() << "Got incomplete ancestor chain due to empty remoteId:" << \
collection; +    return QString();
+  }
+
+  if ( collection.parentCollection() == Akonadi::Collection::root() ) {
+    /*if ( showWarnings )
+      kWarning( collection.remoteId() != rootRemoteId() ) << "RID mismatch, is " << \
collection.remoteId() << " expected " << rootRemoteId(); +    */
+    return QLatin1String( "" ); // see below, this intentionally not just QString()!
+  }
+  const QString parentMailbox = mailBoxForCollection( collection.parentCollection() \
); +  if ( parentMailbox.isNull() ) // invalid, != isEmpty() here!
+    return QString();
+
+  const QString mailbox =  parentMailbox + collection.remoteId();
+  if ( parentMailbox.isEmpty() )
+    return mailbox.mid( 1 ); // strip of the separator on top-level mailboxes
+  return mailbox;
+}
diff --git a/resources/imap/resourcestateinterface.h \
b/resources/imap/resourcestateinterface.h index 7bfe5a3..397d627 100644
--- a/resources/imap/resourcestateinterface.h
+++ b/resources/imap/resourcestateinterface.h
@@ -62,7 +62,7 @@ public:
   virtual QSet<QByteArray> removedFlags() const = 0;
 
   virtual QString rootRemoteId() const = 0;
-  virtual QString mailBoxForCollection( const Akonadi::Collection &collection, bool \
showWarnings = true ) const = 0; +  QString mailBoxForCollection( const \
Akonadi::Collection &collection, bool showWarnings = true );  
   virtual void setIdleCollection( const Akonadi::Collection &collection ) = 0;
   virtual void applyCollectionChanges( const Akonadi::Collection &collection ) = 0;
@@ -96,6 +96,9 @@ public:
   virtual void synchronizeCollectionTree() = 0;
   virtual void scheduleConnectionAttempt() = 0;
 
+  virtual QChar separatorCharacter() const = 0;
+  virtual void setSeparatorCharacter( const QChar &separator ) = 0;
+
   virtual void showInformationDialog( const QString &message, const QString &title, \
const QString &dontShowAgainName ) = 0;  };
 
diff --git a/resources/imap/resourcetask.cpp b/resources/imap/resourcetask.cpp
index 30f93be..a41e884 100644
--- a/resources/imap/resourcetask.cpp
+++ b/resources/imap/resourcetask.cpp
@@ -400,12 +400,32 @@ void ResourceTask::kill()
 
 const QChar ResourceTask::separatorCharacter() const
 {
-  //If we create a toplevel folder, assume the separator to be '/'. This is not \
                perfect, but detecting the right
-  //IMAP separator is not straightforward for toplevel folders, and fixes bug 292418 \
                and maybe other, where
-  //subfolders end up with remote id's starting with "i" (the first letter of \
                imap:// ...)
-  const QString parentRemoteId = parentCollection().remoteId();
-  const QChar separator = ( ( parentRemoteId != rootRemoteId() ) && \
                !parentRemoteId.isEmpty() ) ? parentRemoteId.at( 0 ) : '/';
-  return separator;
+  const QChar separator = m_resource->separatorCharacter();
+  if ( !separator.isNull() ) {
+    return separator;
+  } else {
+    //If we request the separator before first folder listing, then try to guess
+    //the separator:
+    //If we create a toplevel folder, assume the separator to be '/'. This is not \
perfect, but detecting the right +    //IMAP separator is not straightforward for \
toplevel folders, and fixes bug 292418 and maybe other, where +    //subfolders end \
up with remote id's starting with "i" (the first letter of imap:// ...) +
+    QString remoteId;
+    // We don't always have parent collection set (for example for \
CollectionChangeTask), +    // in such cases however we can use current collection's \
remoteId to get the separator +    const Akonadi::Collection parent = \
parentCollection(); +    if ( parent.isValid() ) {
+        remoteId = parent.remoteId();
+    } else {
+        remoteId = collection().remoteId();
+    }
+    return ( ( remoteId != rootRemoteId() ) && !remoteId.isEmpty() ) ? remoteId.at( \
0 ) : QLatin1Char('/'); +  }
+}
+
+void ResourceTask::setSeparatorCharacter( const QChar& separator )
+{
+    m_resource->setSeparatorCharacter( separator );
 }
 
 
diff --git a/resources/imap/resourcetask.h b/resources/imap/resourcetask.h
index 4a121fb..f2bfed0 100644
--- a/resources/imap/resourcetask.h
+++ b/resources/imap/resourcetask.h
@@ -123,6 +123,7 @@ protected:
   void showInformationDialog( const QString &message, const QString &title, const \
QString &dontShowAgainName );  
   const QChar separatorCharacter() const;
+  void setSeparatorCharacter( const QChar &separator );
 
   static QList<QByteArray> toAkonadiFlags( const QList<QByteArray> &flags );
   static QList<QByteArray> fromAkonadiFlags( const QList<QByteArray> &flags );
diff --git a/resources/imap/retrievecollectionstask.cpp \
b/resources/imap/retrievecollectionstask.cpp index 5afebe5..e3a1a28 100644
--- a/resources/imap/retrievecollectionstask.cpp
+++ b/resources/imap/retrievecollectionstask.cpp
@@ -103,6 +103,12 @@ void RetrieveCollectionsTask::onMailBoxesReceived( const QList< \
KIMAP::MailBoxDe  QStringList contentTypes;
   contentTypes << KMime::Message::mimeType() << Akonadi::Collection::mimeType();
 
+  if ( !descriptors.isEmpty() ) {
+      // This is still not optimal way of getting the separator, but it's better
+      // than guessing every time from RID of parent collection
+      setSeparatorCharacter( descriptors.first().separator );
+  }
+
   for ( int i=0; i<descriptors.size(); ++i ) {
     KIMAP::MailBoxDescriptor descriptor = descriptors[i];
 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic