kmail Library API Documentation

subscriptiondialog.cpp

00001 /*  -*- c++ -*-
00002     subscriptiondialog.cpp
00003 
00004     This file is part of KMail, the KDE mail client.
00005     Copyright (C) 2002 Carsten Burghardt <burghardt@kde.org>
00006 
00007     KMail is free software; you can redistribute it and/or modify it
00008     under the terms of the GNU General Public License, version 2, as
00009     published by the Free Software Foundation.
00010 
00011     KMail is distributed in the hope that it will be useful, but
00012     WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020     In addition, as a special exception, the copyright holders give
00021     permission to link the code of this program with any edition of
00022     the Qt library by Trolltech AS, Norway (or with modified versions
00023     of Qt that use the same license as Qt), and distribute linked
00024     combinations including the two.  You must obey the GNU General
00025     Public License in all respects for all of the code used other than
00026     Qt.  If you modify this file, you may extend this exception to
00027     your version of the file, but you are not obligated to do so.  If
00028     you do not wish to do so, delete this exception statement from
00029     your version.
00030 */
00031 
00032 #ifdef HAVE_CONFIG_H
00033 #include <config.h>
00034 #endif
00035 
00036 #include "subscriptiondialog.h"
00037 #include "kmmessage.h"
00038 #include "folderstorage.h"
00039 #include "listjob.h"
00040 using KMail::ListJob;
00041 
00042 #include <klocale.h>
00043 #include <kdebug.h>
00044 
00045 
00046 namespace KMail {
00047 
00048 SubscriptionDialog::SubscriptionDialog( QWidget *parent, const QString &caption,
00049     KAccount *acct, QString startPath )
00050   : KSubscription( parent, caption, acct, User1, QString::null, false ),
00051     mStartPath( startPath )
00052 {
00053   // hide unneeded checkboxes
00054   hideTreeCheckbox();
00055   hideNewOnlyCheckbox();
00056 
00057   // ok-button
00058   connect(this, SIGNAL(okClicked()), SLOT(slotSave()));
00059 
00060   // reload-list button
00061   connect(this, SIGNAL(user1Clicked()), SLOT(slotLoadFolders()));
00062 
00063   // get the folders
00064   slotLoadFolders();
00065 }
00066 
00067 //------------------------------------------------------------------------------
00068 void SubscriptionDialog::slotListDirectory( const QStringList& subfolderNames,
00069                                             const QStringList& subfolderPaths,
00070                                             const QStringList& subfolderMimeTypes,
00071                                             const QStringList& subfolderAttributes,
00072                                             const ImapAccountBase::jobData& jobData )
00073 {
00074   mFolderNames = subfolderNames;
00075   mFolderPaths = subfolderPaths;
00076   mFolderMimeTypes = subfolderMimeTypes;
00077   mFolderAttributes = subfolderAttributes;
00078   mJobData = jobData;
00079 
00080   mCount = 0;
00081   mCheckForExisting = false;
00082 
00083   createItems();
00084 }
00085 
00086 //------------------------------------------------------------------------------
00087 void SubscriptionDialog::createItems()
00088 {
00089   bool onlySubscribed = mJobData.onlySubscribed;
00090   ImapAccountBase* ai = static_cast<ImapAccountBase*>(mAcct);
00091   GroupItem *parent = 0;
00092   uint done = 0;
00093   for (uint i = mCount; i < mFolderNames.count(); ++i)
00094   {
00095     // give the dialog a chance to repaint
00096     if (done == 1000)
00097     {
00098       emit listChanged();
00099       QTimer::singleShot(0, this, SLOT(createItems()));
00100       return;
00101     }
00102     ++mCount;
00103     ++done;
00104     GroupItem *item = 0;
00105     if (!onlySubscribed && mFolderPaths.size() > 0)
00106     {
00107       // the account does not know the delimiter
00108       if (mDelimiter.isEmpty())
00109       {
00110         int start = mFolderPaths[i].findRev(mFolderNames[i]);
00111         if (start > 1)
00112           mDelimiter = mFolderPaths[i].mid(start-1, 1);
00113       }
00114 
00115       // get the parent
00116       GroupItem *oldItem = 0;
00117       QString parentPath;
00118       findParentItem( mFolderNames[i], mFolderPaths[i], parentPath, &parent, &oldItem );
00119 
00120       if (!parent && parentPath != "/")
00121       {
00122         // the parent is not available and it's no root-item
00123         // this happens when the folders do not arrive in hierarchical order
00124         // so we create each parent in advance
00125         // as a result we have to check from now on if the folder already exists
00126         mCheckForExisting = true;
00127         QStringList folders = QStringList::split(mDelimiter, parentPath);
00128         uint i = 0;
00129         for ( QStringList::Iterator it = folders.begin(); it != folders.end(); ++it )
00130         {
00131           QString name = *it;
00132           if (name.startsWith("/"))
00133             name = name.right(name.length()-1);
00134           if (name.endsWith("/"))
00135             name.truncate(name.length()-1);
00136           KGroupInfo info(name);
00137           if (("/"+name+"/") == ai->prefix())
00138           {
00139             ++i;
00140             continue;
00141           }
00142           info.subscribed = false;
00143 
00144           QStringList tmpPath;
00145           for ( uint j = 0; j <= i; ++j )
00146             tmpPath << folders[j];
00147           QString path = tmpPath.join(mDelimiter);
00148           if (!path.startsWith("/"))
00149             path = "/" + path;
00150           if (!path.endsWith("/"))
00151             path = path + "/";
00152           info.path = path;
00153           item = 0;
00154           if (folders.count() > 1)
00155           {
00156             // we have to create more then one level, so better check if this
00157             // folder already exists somewhere
00158             item = mItemDict[path];
00159           }
00160           // as these items are "dummies" we create them non-checkable
00161           if (!item)
00162           {
00163             if (parent)
00164               item = new GroupItem(parent, info, this, false);
00165             else
00166               item = new GroupItem(folderTree(), info, this, false);
00167             mItemDict.insert(info.path, item);
00168           }
00169 
00170           parent = item;
00171           ++i;
00172         } // folders
00173       } // parent
00174 
00175       KGroupInfo info(mFolderNames[i]);
00176       if (mFolderNames[i].upper() == "INBOX" &&
00177           mFolderPaths[i] == "/INBOX/")
00178         info.name = i18n("inbox");
00179       info.subscribed = false;
00180       info.path = mFolderPaths[i];
00181       // only checkable when the folder is selectable
00182       bool checkable = ( mFolderMimeTypes[i] == "inode/directory" ) ? false : true;
00183       // create a new item
00184       if (parent)
00185         item = new GroupItem(parent, info, this, checkable);
00186       else
00187         item = new GroupItem(folderTree(), info, this, checkable);
00188 
00189       if (oldItem) // remove old item
00190         mItemDict.remove(info.path);
00191 
00192       mItemDict.insert(info.path, item);
00193       if (oldItem)
00194       {
00195         // move the old childs to the new item
00196         QPtrList<QListViewItem> itemsToMove;
00197         QListViewItem * myChild = oldItem->firstChild();
00198         while (myChild)
00199         {
00200           itemsToMove.append(myChild);
00201           myChild = myChild->nextSibling();
00202         }
00203         QPtrListIterator<QListViewItem> it( itemsToMove );
00204         QListViewItem *cur;
00205         while ((cur = it.current()))
00206         {
00207           oldItem->takeItem(cur);
00208           item->insertItem(cur);
00209           if ( cur->isSelected() ) // we have new parents so open them
00210             folderTree()->ensureItemVisible( cur );
00211           ++it;
00212         }
00213         delete oldItem;
00214         itemsToMove.clear();
00215       }
00216       // select the start item
00217       if ( mFolderPaths[i] == mStartPath )
00218       {
00219         item->setSelected( true );
00220         folderTree()->ensureItemVisible( item );
00221       }
00222 
00223     } else if (onlySubscribed)
00224     {
00225       // find the item
00226       if ( mItemDict[mFolderPaths[i]] )
00227       {
00228         GroupItem* item = mItemDict[mFolderPaths[i]];
00229         item->setOn( true );
00230       }
00231     }
00232   }
00233   if ( mJobData.inboxOnly )
00234   {
00235     // list again (secondStep=true) with prefix
00236     ImapAccountBase::ListType type = ImapAccountBase::List;
00237     if ( onlySubscribed )
00238       type = ImapAccountBase::ListSubscribedNoCheck;
00239     ListJob* job = new ListJob( 0, ai, type, true, true,
00240         false, ai->prefix() );
00241     connect( job, SIGNAL(receivedFolders(const QStringList&, const QStringList&,
00242             const QStringList&, const QStringList&, const ImapAccountBase::jobData&)),
00243         this, SLOT(slotListDirectory(const QStringList&, const QStringList&,
00244             const QStringList&, const QStringList&, const ImapAccountBase::jobData&)));
00245     job->start();
00246   } else if (!onlySubscribed)
00247   {
00248     // get subscribed folders
00249     // only do a complete listing (*) when the user did not enter a prefix
00250     // otherwise the complete listing will be done in second step
00251     // we use the 'SubscribedNoCheck' feature so that the kioslave doesn't check
00252     // for every folder if it actually exists
00253     bool complete = (ai->prefix() == "/") ? true : false;
00254     ListJob* job = new ListJob( 0, ai, ImapAccountBase::ListSubscribedNoCheck,
00255         false, complete, false, ai->prefix() );
00256     connect( job, SIGNAL(receivedFolders(const QStringList&, const QStringList&,
00257             const QStringList&, const QStringList&, const ImapAccountBase::jobData&)),
00258         this, SLOT(slotListDirectory(const QStringList&, const QStringList&,
00259             const QStringList&, const QStringList&, const ImapAccountBase::jobData&)));
00260     job->start();
00261   } else if (onlySubscribed)
00262   {
00263     // activate buttons and stuff
00264     slotLoadingComplete();
00265   }
00266 }
00267 
00268 //------------------------------------------------------------------------------
00269 void SubscriptionDialog::findParentItem( QString &name, QString &path, QString &parentPath,
00270     GroupItem **parent, GroupItem **oldItem )
00271 {
00272   // remove the name (and the separator) from the path to get the parent path
00273   int start = path.length() - (name.length()+2);
00274   int length = name.length()+1;
00275   if (start < 0) start = 0;
00276   parentPath = path;
00277   parentPath.remove(start, length);
00278 
00279   if (mDelimiter.isEmpty())
00280     return;
00281 
00282   // find the parent by it's path
00283   *parent = mItemDict[parentPath];
00284 
00285   // check if the item already exists
00286   if (mCheckForExisting)
00287     *oldItem = mItemDict[path];
00288 }
00289 
00290 //------------------------------------------------------------------------------
00291 void SubscriptionDialog::slotSave()
00292 {
00293   if (!account())
00294     return;
00295   // subscribe
00296   QListViewItemIterator it(subView);
00297   for ( ; it.current(); ++it)
00298   {
00299     static_cast<ImapAccountBase*>(account())->changeSubscription(true,
00300         static_cast<GroupItem*>(it.current())->info().path);
00301   }
00302 
00303   // unsubscribe
00304   QListViewItemIterator it2(unsubView);
00305   for ( ; it2.current(); ++it2)
00306   {
00307     static_cast<ImapAccountBase*>(account())->changeSubscription(false,
00308         static_cast<GroupItem*>(it2.current())->info().path);
00309   }
00310 }
00311 
00312 //------------------------------------------------------------------------------
00313 void SubscriptionDialog::slotLoadFolders()
00314 {
00315   // clear the views
00316   KSubscription::slotLoadFolders();
00317   if ( !account() )
00318     return;
00319   ImapAccountBase* ai = static_cast<ImapAccountBase*>(account());
00320   if ( ai->prefix().isEmpty() )
00321     return;
00322   mItemDict.clear();
00323   // only do a complete listing (*) when the user did not enter a prefix
00324   // otherwise the complete listing will be done in second step
00325   bool complete = (ai->prefix() == "/") ? true : false;
00326   // get all folders
00327   ListJob* job = new ListJob( 0, ai, ImapAccountBase::List, false,
00328       complete, false, ai->prefix() );
00329   connect( job, SIGNAL(receivedFolders(const QStringList&, const QStringList&,
00330           const QStringList&, const QStringList&, const ImapAccountBase::jobData&)),
00331       this, SLOT(slotListDirectory(const QStringList&, const QStringList&,
00332           const QStringList&, const QStringList&, const ImapAccountBase::jobData&)));
00333   job->start();
00334 }
00335 
00336 } // namespace
00337 
00338 #include "subscriptiondialog.moc"
KDE Logo
This file is part of the documentation for kmail Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Mon Apr 4 04:48:30 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003