summaryrefslogtreecommitdiffstats
path: root/kmail/subscriptiondialog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kmail/subscriptiondialog.cpp')
-rw-r--r--kmail/subscriptiondialog.cpp444
1 files changed, 444 insertions, 0 deletions
diff --git a/kmail/subscriptiondialog.cpp b/kmail/subscriptiondialog.cpp
new file mode 100644
index 000000000..ac5909936
--- /dev/null
+++ b/kmail/subscriptiondialog.cpp
@@ -0,0 +1,444 @@
+/* -*- c++ -*-
+ subscriptiondialog.cpp
+
+ This file is part of KMail, the KDE mail client.
+ Copyright (C) 2002 Carsten Burghardt <burghardt@kde.org>
+
+ KMail is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License, version 2, as
+ published by the Free Software Foundation.
+
+ KMail is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "subscriptiondialog.h"
+#include "folderstorage.h"
+#include "listjob.h"
+#include "imapaccountbase.h"
+
+#include <klocale.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+
+
+namespace KMail {
+
+SubscriptionDialogBase::SubscriptionDialogBase( QWidget *parent, const QString &caption,
+ KAccount *acct, QString startPath )
+ : KSubscription( parent, caption, acct, User1, QString::null, false ),
+ mStartPath( startPath ), mSubscribed( false ), mForceSubscriptionEnable( false)
+{
+ // hide unneeded checkboxes
+ hideTreeCheckbox();
+ hideNewOnlyCheckbox();
+
+ // ok-button
+ connect(this, SIGNAL(okClicked()), SLOT(slotSave()));
+
+ // reload-list button
+ connect(this, SIGNAL(user1Clicked()), SLOT(slotLoadFolders()));
+
+ // get the folders, delayed execution style, otherwise there's bother
+ // with virtuals from ctors and whatnot
+ QTimer::singleShot(0, this, SLOT(slotLoadFolders()));
+}
+
+//------------------------------------------------------------------------------
+void SubscriptionDialogBase::slotListDirectory( const QStringList& subfolderNames,
+ const QStringList& subfolderPaths,
+ const QStringList& subfolderMimeTypes,
+ const QStringList& subfolderAttributes,
+ const ImapAccountBase::jobData& jobData )
+{
+ mFolderNames = subfolderNames;
+ mFolderPaths = subfolderPaths;
+ mFolderMimeTypes = subfolderMimeTypes;
+ mFolderAttributes = subfolderAttributes;
+ mJobData = jobData;
+
+ mCount = 0;
+
+ processFolderListing();
+}
+
+void SubscriptionDialogBase::moveChildrenToNewParent( GroupItem *oldItem, GroupItem *item )
+{
+ if ( !oldItem || !item ) return;
+
+ QPtrList<QListViewItem> itemsToMove;
+ QListViewItem * myChild = oldItem->firstChild();
+ while (myChild)
+ {
+ itemsToMove.append(myChild);
+ myChild = myChild->nextSibling();
+ }
+ QPtrListIterator<QListViewItem> it( itemsToMove );
+ QListViewItem *cur;
+ while ((cur = it.current()))
+ {
+ oldItem->takeItem(cur);
+ item->insertItem(cur);
+ if ( cur->isSelected() ) // we have new parents so open them
+ folderTree()->ensureItemVisible( cur );
+ ++it;
+ }
+ delete oldItem;
+ itemsToMove.clear();
+}
+
+void SubscriptionDialogBase::createListViewItem( int i )
+{
+ GroupItem *item = 0;
+ GroupItem *parent = 0;
+
+ // get the parent
+ GroupItem *oldItem = 0;
+ QString parentPath;
+ findParentItem( mFolderNames[i], mFolderPaths[i], parentPath, &parent, &oldItem );
+
+ if (!parent && parentPath != "/")
+ {
+ // the parent is not available and it's no root-item
+ // this happens when the folders do not arrive in hierarchical order
+ // so we create each parent in advance
+ QStringList folders = QStringList::split(mDelimiter, parentPath);
+ uint i = 0;
+ for ( QStringList::Iterator it = folders.begin(); it != folders.end(); ++it )
+ {
+ QString name = *it;
+ if (name.startsWith("/"))
+ name = name.right(name.length()-1);
+ if (name.endsWith("/"))
+ name.truncate(name.length()-1);
+ KGroupInfo info(name);
+ info.subscribed = false;
+
+ QStringList tmpPath;
+ for ( uint j = 0; j <= i; ++j )
+ tmpPath << folders[j];
+ QString path = tmpPath.join(mDelimiter);
+ if (!path.startsWith("/"))
+ path = "/" + path;
+ if (!path.endsWith("/"))
+ path = path + "/";
+ info.path = path;
+ item = 0;
+ if (folders.count() > 1)
+ {
+ // we have to create more then one level, so better check if this
+ // folder already exists somewhere
+ item = mItemDict[path];
+ }
+ // as these items are "dummies" we create them non-checkable
+ if (!item)
+ {
+ if (parent)
+ item = new GroupItem(parent, info, this, false);
+ else
+ item = new GroupItem(folderTree(), info, this, false);
+ mItemDict.insert(info.path, item);
+ }
+
+ parent = item;
+ ++i;
+ } // folders
+ } // parent
+
+ KGroupInfo info(mFolderNames[i]);
+ if (mFolderNames[i].upper() == "INBOX" &&
+ mFolderPaths[i] == "/INBOX/")
+ info.name = i18n("inbox");
+ info.subscribed = false;
+ info.path = mFolderPaths[i];
+ // only checkable when the folder is selectable
+ bool checkable = ( mFolderMimeTypes[i] == "inode/directory" ) ? false : true;
+ // create a new item
+ if (parent)
+ item = new GroupItem(parent, info, this, checkable);
+ else
+ item = new GroupItem(folderTree(), info, this, checkable);
+
+ if (oldItem) // remove old item
+ mItemDict.remove(info.path);
+
+ mItemDict.insert(info.path, item);
+ if (oldItem)
+ moveChildrenToNewParent( oldItem, item );
+
+ // select the start item
+ if ( mFolderPaths[i] == mStartPath )
+ {
+ item->setSelected( true );
+ folderTree()->ensureItemVisible( item );
+ }
+}
+
+
+
+//------------------------------------------------------------------------------
+void SubscriptionDialogBase::findParentItem( QString &name, QString &path, QString &parentPath,
+ GroupItem **parent, GroupItem **oldItem )
+{
+ // remove the name (and the separator) from the path to get the parent path
+ int start = path.length() - (name.length()+2);
+ int length = name.length()+1;
+ if (start < 0) start = 0;
+ parentPath = path;
+ parentPath.remove(start, length);
+
+ // find the parent by it's path
+ *parent = mItemDict[parentPath];
+
+ // check if the item already exists
+ *oldItem = mItemDict[path];
+}
+
+//------------------------------------------------------------------------------
+void SubscriptionDialogBase::slotSave()
+{
+ doSave();
+}
+
+//------------------------------------------------------------------------------
+void SubscriptionDialogBase::slotLoadFolders()
+{
+ ImapAccountBase* ai = static_cast<ImapAccountBase*>(account());
+ // we need a connection
+ if ( ai->makeConnection() == ImapAccountBase::Error )
+ {
+ kdWarning(5006) << "SubscriptionDialog - got no connection" << endl;
+ return;
+ } else if ( ai->makeConnection() == ImapAccountBase::Connecting )
+ {
+ // We'll wait for the connectionResult signal from the account.
+ kdDebug(5006) << "SubscriptionDialog - waiting for connection" << endl;
+ connect( ai, SIGNAL( connectionResult(int, const QString&) ),
+ this, SLOT( slotConnectionResult(int, const QString&) ) );
+ return;
+ }
+ // clear the views
+ KSubscription::slotLoadFolders();
+ mItemDict.clear();
+ mSubscribed = false;
+ mLoading = true;
+
+ // first step is to load a list of all available folders and create listview
+ // items for them
+ listAllAvailableAndCreateItems();
+}
+
+//------------------------------------------------------------------------------
+void SubscriptionDialogBase::processNext()
+{
+ if ( mPrefixList.isEmpty() )
+ {
+ if ( !mSubscribed )
+ {
+ mSubscribed = true;
+ initPrefixList();
+ if ( mPrefixList.isEmpty() )
+ {
+ // still empty? then we have nothing to do here as this is an error
+ loadingComplete();
+ return;
+ }
+ } else {
+ loadingComplete();
+ return;
+ }
+ }
+ ImapAccountBase* ai = static_cast<ImapAccountBase*>(account());
+ ImapAccountBase::ListType type = ( mSubscribed ?
+ ImapAccountBase::ListSubscribedNoCheck : ImapAccountBase::List );
+
+ bool completeListing = true;
+ mCurrentNamespace = mPrefixList.first();
+ mDelimiter = ai->delimiterForNamespace( mCurrentNamespace );
+ mPrefixList.pop_front();
+ if ( mCurrentNamespace == "/INBOX/" )
+ {
+ type = mSubscribed ?
+ ImapAccountBase::ListFolderOnlySubscribed : ImapAccountBase::ListFolderOnly;
+ completeListing = false;
+ }
+
+// kdDebug(5006) << "process " << mCurrentNamespace << ",subscribed=" << mSubscribed << endl;
+ ListJob* job = new ListJob( ai, type, 0, ai->addPathToNamespace( mCurrentNamespace ), completeListing );
+ connect( job, SIGNAL(receivedFolders(const QStringList&, const QStringList&,
+ const QStringList&, const QStringList&, const ImapAccountBase::jobData&)),
+ this, SLOT(slotListDirectory(const QStringList&, const QStringList&,
+ const QStringList&, const QStringList&, const ImapAccountBase::jobData&)));
+ job->start();
+}
+
+void SubscriptionDialogBase::loadingComplete()
+{
+ slotLoadingComplete();
+}
+
+
+//------------------------------------------------------------------------------
+// implementation for server side subscription
+//------------------------------------------------------------------------------
+
+SubscriptionDialog::SubscriptionDialog( QWidget *parent, const QString &caption,
+ KAccount *acct, QString startPath )
+ : SubscriptionDialogBase( parent, caption, acct, startPath )
+{
+}
+
+/* virtual */
+SubscriptionDialog::~SubscriptionDialog()
+{
+
+}
+
+/* virtual */
+void SubscriptionDialog::listAllAvailableAndCreateItems()
+{
+ initPrefixList();
+ processNext();
+}
+
+//------------------------------------------------------------------------------
+void SubscriptionDialogBase::initPrefixList()
+{
+ ImapAccountBase* ai = static_cast<ImapAccountBase*>(account());
+ ImapAccountBase::nsMap map = ai->namespaces();
+ mPrefixList.clear();
+
+ bool hasInbox = false;
+ const QStringList ns = map[ImapAccountBase::PersonalNS];
+ for ( QStringList::ConstIterator it = ns.begin(); it != ns.end(); ++it )
+ {
+ if ( (*it).isEmpty() )
+ hasInbox = true;
+ }
+ if ( !hasInbox && !ns.isEmpty() )
+ {
+ // the namespaces includes no listing for the root so start a special
+ // listing for the INBOX to make sure we get it
+ mPrefixList += "/INBOX/";
+ }
+
+ mPrefixList += map[ImapAccountBase::PersonalNS];
+ mPrefixList += map[ImapAccountBase::OtherUsersNS];
+ mPrefixList += map[ImapAccountBase::SharedNS];
+}
+
+void SubscriptionDialogBase::slotConnectionResult( int errorCode, const QString& errorMsg )
+{
+ Q_UNUSED( errorMsg );
+ if ( !errorCode )
+ slotLoadFolders();
+}
+
+void SubscriptionDialogBase::show()
+{
+ KDialogBase::show();
+}
+
+// =======
+/* virtual */
+void SubscriptionDialog::processFolderListing()
+{
+ processItems();
+}
+
+/* virtual */
+void SubscriptionDialog::doSave()
+{
+ KMail::ImapAccountBase *a = static_cast<KMail::ImapAccountBase*>(mAcct);
+ if( !a->onlySubscribedFolders() ) {
+ int result = KMessageBox::questionYesNoCancel( this,
+ i18n("Currently subscriptions are not used for server %1\ndo you want to enable subscriptions?")
+ .arg( a->name() ),
+ i18n("Enable Subscriptions?"), i18n("Enable"), i18n("Do Not Enable"));
+ switch(result) {
+ case KMessageBox::Yes:
+ mForceSubscriptionEnable = true;
+ break;
+ case KMessageBox::No:
+ break;
+ case KMessageBox::Cancel:
+ cancel();
+ }
+ }
+
+ // subscribe
+ QListViewItemIterator it(subView);
+ for ( ; it.current(); ++it)
+ {
+ static_cast<ImapAccountBase*>(account())->changeSubscription(true,
+ static_cast<GroupItem*>(it.current())->info().path);
+ }
+
+ // unsubscribe
+ QListViewItemIterator it2(unsubView);
+ for ( ; it2.current(); ++it2)
+ {
+ static_cast<ImapAccountBase*>(account())->changeSubscription(false,
+ static_cast<GroupItem*>(it2.current())->info().path);
+ }
+
+ if ( mForceSubscriptionEnable ) {
+ a->setOnlySubscribedFolders(true);
+ }
+}
+
+void SubscriptionDialog::processItems()
+{
+ bool onlySubscribed = mJobData.onlySubscribed;
+ uint done = 0;
+ for (uint i = mCount; i < mFolderNames.count(); ++i)
+ {
+ // give the dialog a chance to repaint
+ if (done == 1000)
+ {
+ emit listChanged();
+ QTimer::singleShot(0, this, SLOT(processItems()));
+ return;
+ }
+ ++mCount;
+ ++done;
+ if (!onlySubscribed && mFolderPaths.size() > 0)
+ {
+ createListViewItem( i );
+ } else if (onlySubscribed)
+ {
+ // find the item
+ if ( mItemDict[mFolderPaths[i]] )
+ {
+ GroupItem* item = mItemDict[mFolderPaths[i]];
+ item->setOn( true );
+ }
+ }
+ }
+
+ processNext();
+}
+} // namespace
+
+#include "subscriptiondialog.moc"