~ubuntu-branches/ubuntu/karmic/kdepim/karmic-backports

« back to all changes in this revision

Viewing changes to akonadi/resources/imap/subscriptiondialog.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Christian Mangold
  • Date: 2009-07-10 06:34:50 UTC
  • mfrom: (1.1.40 upstream)
  • Revision ID: james.westby@ubuntu.com-20090710063450-neojgew2fh0n3y0u
Tags: 4:4.2.96-0ubuntu1
* New upstream release
* Bump kde build-deps to 4.2.96

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  -*- c++ -*-
2
 
    subscriptiondialog.cpp
3
 
 
4
 
    This file is part of KMail, the KDE mail client.
5
 
    Copyright (C) 2002 Carsten Burghardt <burghardt@kde.org>
6
 
    Copyright (C) 2009 Kevin Ottens <ervin@kde.org>
7
 
 
8
 
    KMail is free software; you can redistribute it and/or modify it
9
 
    under the terms of the GNU General Public License, version 2, as
10
 
    published by the Free Software Foundation.
11
 
 
12
 
    KMail is distributed in the hope that it will be useful, but
13
 
    WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 
    General Public License for more details.
16
 
 
17
 
    You should have received a copy of the GNU General Public License
18
 
    along with this program; if not, write to the Free Software
19
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20
 
 
21
 
    In addition, as a special exception, the copyright holders give
22
 
    permission to link the code of this program with any edition of
23
 
    the Qt library by Trolltech AS, Norway (or with modified versions
24
 
    of Qt that use the same license as Qt), and distribute linked
25
 
    combinations including the two.  You must obey the GNU General
26
 
    Public License in all respects for all of the code used other than
27
 
    Qt.  If you modify this file, you may extend this exception to
28
 
    your version of the file, but you are not obligated to do so.  If
29
 
    you do not wish to do so, delete this exception statement from
30
 
    your version.
31
 
*/
32
 
 
33
 
#include "subscriptiondialog.h"
34
 
 
35
 
#include <QtCore/QTimer>
36
 
 
37
 
#include <klocale.h>
38
 
#include <kdebug.h>
39
 
#include <kmessagebox.h>
40
 
 
41
 
#include <kimap/session.h>
42
 
#include <kimap/listjob.h>
43
 
#include <kimap/unsubscribejob.h>
44
 
#include <kimap/subscribejob.h>
45
 
 
46
 
SubscriptionDialogBase::SubscriptionDialogBase( QWidget *parent, const QString &caption,
47
 
    KAccount *acct, bool &selectionChanged, const QString &startPath )
48
 
  : KSubscription( parent, caption, acct, User1, QString(), false ),
49
 
    mStartPath( startPath ), mSubscribed( false ), mForceSubscriptionEnable( false ), mSelectionChanged( selectionChanged )
50
 
{
51
 
  // hide unneeded checkboxes
52
 
  hideTreeCheckbox();
53
 
  hideNewOnlyCheckbox();
54
 
 
55
 
  // reload-list button
56
 
  connect(this, SIGNAL(user1Clicked()), SLOT(slotLoadFolders()));
57
 
 
58
 
  // get the folders, delayed execution style, otherwise there's bother
59
 
  // with virtuals from ctors and whatnot
60
 
  QTimer::singleShot(0, this, SLOT(slotLoadFolders()));
61
 
}
62
 
 
63
 
//------------------------------------------------------------------------------
64
 
void SubscriptionDialogBase::slotListDirectory( KJob *job )
65
 
{
66
 
  KIMAP::ListJob *list = static_cast<KIMAP::ListJob*>( job );
67
 
 
68
 
  QList<KIMAP::MailBoxDescriptor> mailBoxes = list->mailBoxes();
69
 
 
70
 
  foreach ( const KIMAP::MailBoxDescriptor &mailBox, mailBoxes ) {
71
 
    mDelimiters << mailBox.separator;
72
 
    mFolderPaths << mailBox.name;
73
 
    mFolderNames << mailBox.name.split(mailBox.separator).last();
74
 
    mFolderSelectable << !list->flags()[mailBox].contains("\\NoSelect");
75
 
  }
76
 
 
77
 
  mOnlySubscribed = !list->isIncludeUnsubscribed();
78
 
  mCount = 0;
79
 
 
80
 
  processFolderListing();
81
 
}
82
 
 
83
 
void SubscriptionDialogBase::slotButtonClicked( int button )
84
 
{
85
 
  if ( button == KDialog::Ok ) {
86
 
    if ( doSave() ) {
87
 
      accept();
88
 
    }
89
 
  }
90
 
  else {
91
 
    KDialog::slotButtonClicked( button );
92
 
  }
93
 
}
94
 
 
95
 
void SubscriptionDialogBase::moveChildrenToNewParent( GroupItem *oldItem, GroupItem *item  )
96
 
{
97
 
  if ( !oldItem || !item ) return;
98
 
 
99
 
  QList<QTreeWidgetItem*> itemsToMove;
100
 
  int childIndex = 0;
101
 
  while ( QTreeWidgetItem* curItem = oldItem->QTreeWidgetItem::child( childIndex++ ) ) {
102
 
    itemsToMove.append( curItem );
103
 
    }
104
 
 
105
 
  foreach( QTreeWidgetItem *cur, itemsToMove ) {
106
 
    QTreeWidgetItem *taken = oldItem->takeChild( oldItem->indexOfChild( cur ) );
107
 
    Q_ASSERT( taken );
108
 
    item->QTreeWidgetItem::insertChild( 0, taken );
109
 
    if ( taken->isSelected() ) // we have new parents so open them
110
 
      folderTree()->scrollToItem( taken );
111
 
  }
112
 
 
113
 
  // Delete the old item
114
 
  QTreeWidgetItem *oldItemParent = oldItem->QTreeWidgetItem::parent();
115
 
  if ( oldItemParent )
116
 
    delete oldItemParent->takeChild( oldItemParent->indexOfChild( oldItem ) );
117
 
  else {
118
 
    QTreeWidget *treeWidget = oldItem->treeWidget();
119
 
    delete treeWidget->takeTopLevelItem( treeWidget->indexOfTopLevelItem( oldItem ) );
120
 
  }
121
 
  itemsToMove.clear();
122
 
}
123
 
 
124
 
void SubscriptionDialogBase::createListViewItem( int i )
125
 
{
126
 
  GroupItem *item = 0;
127
 
  GroupItem *parent = 0;
128
 
 
129
 
  // get the parent
130
 
  GroupItem *oldItem = 0;
131
 
  QString parentPath;
132
 
  findParentItem( mFolderNames[i], mFolderPaths[i], parentPath, &parent, &oldItem );
133
 
 
134
 
  if (!parent && !parentPath.isEmpty())
135
 
  {
136
 
    // the parent is not available and it's no root-item
137
 
    // this happens when the folders do not arrive in hierarchical order
138
 
    // so we create each parent in advance
139
 
    QStringList folders = parentPath.split( mDelimiters[i], QString::SkipEmptyParts );
140
 
    uint i = 0;
141
 
    for ( QStringList::Iterator it = folders.begin(); it != folders.end(); ++it )
142
 
    {
143
 
      KGroupInfo info(*it);
144
 
      info.subscribed = false;
145
 
 
146
 
      QStringList tmpPath;
147
 
      for ( uint j = 0; j <= i; ++j )
148
 
        tmpPath << folders[j];
149
 
      QString path = tmpPath.join(mDelimiters[i]);
150
 
      info.path = path;
151
 
      item = mItemDict[path];
152
 
      // as these items are "dummies" we create them non-checkable
153
 
      if (!item)
154
 
      {
155
 
        if (parent) {
156
 
          item = new GroupItem(parent, info, this, false);
157
 
        }
158
 
        else {
159
 
          item = new GroupItem(folderTree(), info, this, false);
160
 
        }
161
 
        mItemDict.insert(info.path, item);
162
 
      }
163
 
 
164
 
      parent = item;
165
 
      ++i;
166
 
    } // folders
167
 
  } // parent
168
 
 
169
 
  KGroupInfo info(mFolderNames[i]);
170
 
  if (mFolderNames[i].toUpper() == "INBOX" &&
171
 
      mFolderPaths[i] == "INBOX")
172
 
    info.name = "Inbox";
173
 
  info.subscribed = false;
174
 
  info.path = mFolderPaths[i];
175
 
  // only checkable when the folder is selectable
176
 
  bool checkable = mFolderSelectable[i];
177
 
  // create a new item
178
 
  if ( parent ) {
179
 
    item = new GroupItem(parent, info, this, checkable);
180
 
  }
181
 
  else {
182
 
    item = new GroupItem(folderTree(), info, this, checkable);
183
 
  }
184
 
 
185
 
  if (oldItem) // remove old item
186
 
    mItemDict.remove(info.path);
187
 
 
188
 
  mItemDict.insert(info.path, item);
189
 
  if (oldItem)
190
 
    moveChildrenToNewParent( oldItem, item );
191
 
 
192
 
  // select the start item
193
 
  if ( mFolderPaths[i] == mStartPath )
194
 
  {
195
 
    item->setSelected( true );
196
 
    folderTree()->scrollToItem( item );
197
 
  }
198
 
}
199
 
 
200
 
 
201
 
 
202
 
//------------------------------------------------------------------------------
203
 
void SubscriptionDialogBase::findParentItem( QString &name, QString &path, QString &parentPath,
204
 
    GroupItem **parent, GroupItem **oldItem )
205
 
{
206
 
  // remove the name (and the separator) from the path to get the parent path
207
 
  int start = path.length() - (name.length()+1);
208
 
  int length = name.length()+1;
209
 
  if (start < 0) start = 0;
210
 
  parentPath = path;
211
 
  parentPath.remove(start, length);
212
 
 
213
 
  // find the parent by it's path
214
 
  QMap<QString, GroupItem*>::Iterator it = mItemDict.find( parentPath );
215
 
  if ( it != mItemDict.end() )
216
 
    *parent = ( *it );
217
 
 
218
 
  // check if the item already exists
219
 
  it = mItemDict.find( path );
220
 
  if ( it != mItemDict.end() )
221
 
    *oldItem = ( *it );
222
 
}
223
 
 
224
 
//------------------------------------------------------------------------------
225
 
void SubscriptionDialogBase::slotLoadFolders()
226
 
{
227
 
  ImapAccount* ai = static_cast<ImapAccount*>(account());
228
 
  // we need a connection
229
 
  if ( !ai->session() || ai->session()->state() != KIMAP::Session::Authenticated )
230
 
  {
231
 
    kWarning() <<"SubscriptionDialog - got no connection";
232
 
    return;
233
 
  }
234
 
 
235
 
  // clear the views
236
 
  KSubscription::slotLoadFolders();
237
 
  mItemDict.clear();
238
 
  mSubscribed = false;
239
 
  mLoading = true;
240
 
 
241
 
  // first step is to load a list of all available folders and create listview
242
 
  // items for them
243
 
  listAllAvailableAndCreateItems();
244
 
}
245
 
 
246
 
//------------------------------------------------------------------------------
247
 
void SubscriptionDialogBase::processNext()
248
 
{
249
 
  mDelimiters.clear();
250
 
  mFolderNames.clear();
251
 
  mFolderPaths.clear();
252
 
  mFolderSelectable.clear();
253
 
 
254
 
  ImapAccount* ai = static_cast<ImapAccount*>(account());
255
 
 
256
 
  KIMAP::ListJob *list = new KIMAP::ListJob( ai->session() );
257
 
  list->setIncludeUnsubscribed( !mSubscribed );
258
 
  connect( list, SIGNAL( result(KJob*) ), this, SLOT( slotListDirectory(KJob*) ) );
259
 
  list->start();
260
 
}
261
 
 
262
 
void SubscriptionDialogBase::loadingComplete()
263
 
{
264
 
  slotLoadingComplete();
265
 
}
266
 
 
267
 
 
268
 
//------------------------------------------------------------------------------
269
 
// implementation for server side subscription
270
 
//------------------------------------------------------------------------------
271
 
 
272
 
SubscriptionDialog::SubscriptionDialog( QWidget *parent, const QString &caption,
273
 
    KAccount *acct, bool &selectionChanged, const QString & startPath )
274
 
  : SubscriptionDialogBase( parent, caption, acct, selectionChanged, startPath )
275
 
{
276
 
}
277
 
 
278
 
/* virtual */
279
 
SubscriptionDialog::~SubscriptionDialog()
280
 
{
281
 
}
282
 
 
283
 
/* virtual */
284
 
void SubscriptionDialog::listAllAvailableAndCreateItems()
285
 
{
286
 
  processNext();
287
 
}
288
 
 
289
 
//------------------------------------------------------------------------------
290
 
void SubscriptionDialogBase::slotConnectionSuccess()
291
 
{
292
 
  slotLoadFolders();
293
 
}
294
 
 
295
 
bool SubscriptionDialogBase::checkIfSubscriptionsEnabled()
296
 
{
297
 
  ImapAccount *account = static_cast<ImapAccount*>(mAcct);
298
 
  if( !account )
299
 
    return true;
300
 
  if( subscriptionOptionEnabled( account ) )
301
 
    return true;
302
 
 
303
 
  int result = KMessageBox::questionYesNoCancel( this,
304
 
      subscriptionOptionQuestion( account->server() ),
305
 
      i18n("Enable Subscriptions?"), KGuiItem( i18n("Enable") ), KGuiItem( i18n("Do Not Enable") ) );
306
 
 
307
 
  switch(result) {
308
 
    case KMessageBox::Yes:
309
 
        mForceSubscriptionEnable = true;
310
 
        break;
311
 
    case KMessageBox::No:
312
 
        break;
313
 
    case KMessageBox::Cancel:
314
 
        return false;
315
 
        break;
316
 
  }
317
 
 
318
 
  return true;
319
 
}
320
 
 
321
 
// =======
322
 
/* virtual */
323
 
void SubscriptionDialog::processFolderListing()
324
 
{
325
 
  processItems();
326
 
}
327
 
 
328
 
/* virtual */
329
 
bool SubscriptionDialog::doSave()
330
 
{
331
 
  if ( !checkIfSubscriptionsEnabled() )
332
 
    return false;
333
 
 
334
 
  ImapAccount *ai = static_cast<ImapAccount*>(account());
335
 
 
336
 
  // subscribe
337
 
  QTreeWidgetItemIterator it(subView);
338
 
  for ( ; *it; ++it)
339
 
  {
340
 
    KIMAP::SubscribeJob *subscribe = new KIMAP::SubscribeJob( ai->session() );
341
 
    subscribe->setMailBox(
342
 
      static_cast<GroupItem*>(*it)->info().path
343
 
    );
344
 
    subscribe->exec();
345
 
    mSelectionChanged = true;
346
 
  }
347
 
 
348
 
  // unsubscribe
349
 
  QTreeWidgetItemIterator it2(unsubView);
350
 
  for ( ; *it2; ++it2)
351
 
  {
352
 
    KIMAP::UnsubscribeJob *unsubscribe = new KIMAP::UnsubscribeJob( ai->session() );
353
 
    unsubscribe->setMailBox(
354
 
      static_cast<GroupItem*>(*it2)->info().path
355
 
    );
356
 
    unsubscribe->exec();
357
 
    mSelectionChanged = true;
358
 
  }
359
 
 
360
 
  if ( mForceSubscriptionEnable ) {
361
 
    ai->setSubscriptionEnabled( true );
362
 
  }
363
 
 
364
 
  return true;
365
 
}
366
 
 
367
 
bool SubscriptionDialog::subscriptionOptionEnabled( const ImapAccount *account ) const
368
 
{
369
 
  return account->isSubscriptionEnabled();
370
 
}
371
 
 
372
 
QString SubscriptionDialog::subscriptionOptionQuestion( const QString &accountName ) const
373
 
{
374
 
  return i18nc( "@info", "Currently subscriptions are not used for server <resource>%1</resource>.<nl/>"
375
 
                         "\nDo you want to enable subscriptions?", accountName );
376
 
}
377
 
 
378
 
void SubscriptionDialog::processItems()
379
 
{
380
 
  bool onlySubscribed = mOnlySubscribed;
381
 
  uint done = 0;
382
 
  for (int i = mCount; i < mFolderNames.count(); ++i)
383
 
  {
384
 
    // give the dialog a chance to repaint
385
 
    if (done == 1000)
386
 
    {
387
 
      emit listChanged();
388
 
      QTimer::singleShot(0, this, SLOT(processItems()));
389
 
      return;
390
 
    }
391
 
    ++mCount;
392
 
    ++done;
393
 
    if (!onlySubscribed && mFolderPaths.size() > 0)
394
 
    {
395
 
      createListViewItem( i );
396
 
    } else if (onlySubscribed)
397
 
    {
398
 
      // find the item
399
 
      if ( mItemDict[mFolderPaths[i]] )
400
 
      {
401
 
        GroupItem* item = mItemDict[mFolderPaths[i]];
402
 
        item->setOn( true );
403
 
      }
404
 
    }
405
 
  }
406
 
 
407
 
  if ( !mSubscribed ) {
408
 
    mSubscribed = true;
409
 
    processNext();
410
 
  } else {
411
 
    loadingComplete();
412
 
  }
413
 
}
414
 
 
415
 
#include "subscriptiondialog.moc"