00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
#include "ksubscription.h"
00014
#include "kaccount.h"
00015
00016
#include <qlayout.h>
00017
#include <qtimer.h>
00018
#include <qlabel.h>
00019
#include <qpushbutton.h>
00020
#include <qheader.h>
00021
00022
#include <kseparator.h>
00023
#include <kiconloader.h>
00024
#include <klocale.h>
00025
#include <kdebug.h>
00026
#include <klineedit.h>
00027
00028
00029
00030
00031 KGroupInfo::KGroupInfo(
const QString &name,
const QString &description,
00032
bool newGroup,
bool subscribed,
00033 Status status,
QString path)
00034 : name(name), description(description),
00035 newGroup(newGroup), subscribed(subscribed),
00036 status(status), path(path)
00037 {
00038 }
00039
00040
00041
bool KGroupInfo::operator== (
const KGroupInfo &gi2)
00042 {
00043
return (name == gi2.name);
00044 }
00045
00046
00047
bool KGroupInfo::operator< (
const KGroupInfo &gi2)
00048 {
00049
return (name < gi2.name);
00050 }
00051
00052
00053
00054 GroupItem::GroupItem(
QListView *v,
const KGroupInfo &gi, KSubscription* browser,
00055
bool isCheckItem )
00056 :
QCheckListItem( v, gi.name, isCheckItem ? CheckBox : CheckBoxController ),
00057 mInfo( gi ), mBrowser( browser ), mIsCheckItem( isCheckItem ),
00058 mIgnoreStateChange( false )
00059 {
00060
if (listView()->columns() > 1)
00061 setDescription();
00062 }
00063
00064
00065 GroupItem::GroupItem(
QListViewItem *i,
const KGroupInfo &gi, KSubscription* browser,
00066
bool isCheckItem )
00067 :
QCheckListItem( i, gi.name, isCheckItem ? CheckBox : CheckBoxController ),
00068 mInfo( gi ), mBrowser( browser ), mIsCheckItem( isCheckItem ),
00069 mIgnoreStateChange( false )
00070 {
00071
if (listView()->columns() > 1)
00072 setDescription();
00073 }
00074
00075
00076
void GroupItem::setInfo( KGroupInfo info )
00077 {
00078 mInfo = info;
00079 setText(0, mInfo.name);
00080
if (listView()->columns() > 1)
00081 setDescription();
00082 }
00083
00084
00085
void GroupItem::setDescription()
00086 {
00087 setText(1, mInfo.description);
00088 }
00089
00090
00091
void GroupItem::setOn(
bool on )
00092 {
00093
if (mBrowser->isLoading())
00094 {
00095
00096
00097 mInfo.subscribed = on;
00098 }
00099
if (isCheckItem())
00100 QCheckListItem::setOn(on);
00101 }
00102
00103
00104
void GroupItem::stateChange(
bool on )
00105 {
00106
00107
if ( !mIgnoreStateChange )
00108 mBrowser->changeItemState(
this, on);
00109 }
00110
00111
00112
void GroupItem::setVisible(
bool b )
00113 {
00114
if (b)
00115 {
00116 QListViewItem::setVisible(b);
00117 setEnabled(
true);
00118 }
00119
else
00120 {
00121
if (isCheckItem())
00122 {
00123
bool setInvisible =
true;
00124
for (
QListViewItem * lvchild = firstChild(); lvchild != 0;
00125 lvchild = lvchild->nextSibling())
00126 {
00127
if (lvchild->isVisible())
00128 setInvisible =
false;
00129 }
00130
if (setInvisible)
00131 QListViewItem::setVisible(b);
00132
else
00133 {
00134
00135 setOpen(
true);
00136 setEnabled(
false);
00137 }
00138 }
00139
else
00140 {
00141
00142
QPtrList<QListViewItem> moveItems;
00143
00144
for (
QListViewItem * lvchild = firstChild(); lvchild != 0;
00145 lvchild = lvchild->nextSibling())
00146 {
00147
if (static_cast<GroupItem*>(lvchild)->isCheckItem())
00148 {
00149
00150 moveItems.append(lvchild);
00151 }
00152 }
00153
QPtrListIterator<QListViewItem> it( moveItems );
00154
for ( ; it.current(); ++it)
00155 {
00156
00157
QListViewItem* parent = it.current()->parent();
00158
if (parent) parent->takeItem(it.current());
00159 listView()->insertItem(it.current());
00160 }
00161 QListViewItem::setVisible(
false);
00162 }
00163 }
00164 }
00165
00166
00167
void GroupItem::paintCell(
QPainter * p,
const QColorGroup & cg,
00168
int column,
int width,
int align )
00169 {
00170
if (mIsCheckItem)
00171
return QCheckListItem::paintCell( p, cg, column, width, align );
00172
else
00173
return QListViewItem::paintCell( p, cg, column, width, align );
00174 }
00175
00176
00177
void GroupItem::paintFocus(
QPainter * p,
const QColorGroup & cg,
00178
const QRect & r )
00179 {
00180
if (mIsCheckItem)
00181 QCheckListItem::paintFocus(p, cg, r);
00182
else
00183 QListViewItem::paintFocus(p, cg, r);
00184 }
00185
00186
00187
int GroupItem::width(
const QFontMetrics& fm,
const QListView* lv,
int column)
const
00188
{
00189
if (mIsCheckItem)
00190
return QCheckListItem::width(fm, lv, column);
00191
else
00192
return QListViewItem::width(fm, lv, column);
00193 }
00194
00195
00196
void GroupItem::setup()
00197 {
00198
if (mIsCheckItem)
00199 QCheckListItem::setup();
00200
else
00201 QListViewItem::setup();
00202 }
00203
00204
00205
00206
00207 KSubscription::KSubscription(
QWidget *parent,
const QString &caption,
00208 KAccount * acct,
int buttons,
const QString &user1,
bool descriptionColumn )
00209 : KDialogBase( parent, 0, true, caption, buttons | Help | Ok | Cancel, Ok,
00210 true, i18n(
"Reload &List"), user1 ),
00211 mAcct( acct )
00212 {
00213 mLoading =
true;
00214 setWFlags( getWFlags() | WDestructiveClose );
00215
00216
00217 page =
new QWidget(
this);
00218 setMainWidget(page);
00219
00220 filterEdit =
new KLineEdit(page);
00221
QLabel *l =
new QLabel(filterEdit,i18n(
"S&earch:"), page);
00222
00223
00224 noTreeCB =
new QCheckBox(i18n(
"Disable &tree view"), page);
00225 noTreeCB->setChecked(
false);
00226 subCB =
new QCheckBox(i18n(
"&Subscribed only"), page);
00227 subCB->setChecked(
false);
00228 newCB =
new QCheckBox(i18n(
"&New only"), page);
00229 newCB->setChecked(
false);
00230
00231 KSeparator *sep =
new KSeparator(KSeparator::HLine, page);
00232
00233
00234
QFont fnt = font();
00235 fnt.setBold(
true);
00236 leftLabel =
new QLabel(i18n(
"Loading..."), page);
00237 rightLabel =
new QLabel(i18n(
"Current changes:"), page);
00238 leftLabel->setFont(fnt);
00239 rightLabel->setFont(fnt);
00240
00241
00242 pmRight = BarIcon(
"forward");
00243 pmLeft = BarIcon(
"back");
00244
00245 arrowBtn1 =
new QPushButton(page);
00246 arrowBtn1->setEnabled(
false);
00247 arrowBtn2 =
new QPushButton(page);
00248 arrowBtn2->setEnabled(
false);
00249 arrowBtn1->setPixmap(pmRight);
00250 arrowBtn2->setPixmap(pmRight);
00251 arrowBtn1->setFixedSize(35,30);
00252 arrowBtn2->setFixedSize(35,30);
00253
00254
00255 groupView =
new QListView(page);
00256 groupView->setRootIsDecorated(
true);
00257 groupView->addColumn(i18n(
"Name"));
00258 groupView->setAllColumnsShowFocus(
true);
00259
if (descriptionColumn)
00260 mDescrColumn = groupView->addColumn(i18n(
"Description"));
00261
else
00262 groupView->header()->setStretchEnabled(
true, 0);
00263
00264
00265
QGridLayout *topL =
new QGridLayout(page,3,1,0,5);
00266
QHBoxLayout *filterL =
new QHBoxLayout(10);
00267
QVBoxLayout *arrL =
new QVBoxLayout(10);
00268 listL =
new QGridLayout(2, 3, 5);
00269
00270 topL->addLayout(filterL, 0,0);
00271 topL->addWidget(sep,1,0);
00272 topL->addLayout(listL, 2,0);
00273
00274 filterL->addWidget(l);
00275 filterL->addWidget(filterEdit, 1);
00276 filterL->addWidget(noTreeCB);
00277 filterL->addWidget(subCB);
00278 filterL->addWidget(newCB);
00279
00280 listL->addWidget(leftLabel, 0,0);
00281 listL->addWidget(rightLabel, 0,2);
00282 listL->addWidget(groupView, 1,0);
00283 listL->addLayout(arrL, 1,1);
00284 listL->setRowStretch(1,1);
00285 listL->setColStretch(0,5);
00286 listL->setColStretch(2,2);
00287
00288 arrL->addWidget(arrowBtn1, AlignCenter);
00289 arrL->addWidget(arrowBtn2, AlignCenter);
00290
00291
00292 subView =
new QListView(page);
00293 subView->addColumn(i18n(
"Subscribe To"));
00294 subView->header()->setStretchEnabled(
true, 0);
00295 unsubView =
new QListView(page);
00296 unsubView->addColumn(i18n(
"Unsubscribe From"));
00297 unsubView->header()->setStretchEnabled(
true, 0);
00298
00299
QVBoxLayout *protL =
new QVBoxLayout(3);
00300 listL->addLayout(protL, 1,2);
00301 protL->addWidget(subView);
00302 protL->addWidget(unsubView);
00303
00304
00305 enableButton(User1,
false);
00306 enableButton(User2,
false);
00307 newCB->setEnabled(
false);
00308 noTreeCB->setEnabled(
false);
00309 subCB->setEnabled(
false);
00310
00311 filterEdit->setFocus();
00312
00313
00314 connect(groupView, SIGNAL(clicked(
QListViewItem *)),
00315
this, SLOT(slotChangeButtonState(
QListViewItem*)));
00316 connect(subView, SIGNAL(clicked(
QListViewItem *)),
00317
this, SLOT(slotChangeButtonState(
QListViewItem*)));
00318 connect(unsubView, SIGNAL(clicked(
QListViewItem *)),
00319
this, SLOT(slotChangeButtonState(
QListViewItem*)));
00320
00321
00322 connect(arrowBtn1, SIGNAL(clicked()), SLOT(slotButton1()));
00323 connect(arrowBtn2, SIGNAL(clicked()), SLOT(slotButton2()));
00324 connect(
this, SIGNAL(user1Clicked()), SLOT(slotLoadFolders()));
00325
00326
00327 connect(subCB, SIGNAL(clicked()), SLOT(slotCBToggled()));
00328 connect(newCB, SIGNAL(clicked()), SLOT(slotCBToggled()));
00329 connect(noTreeCB, SIGNAL(clicked()), SLOT(slotCBToggled()));
00330
00331
00332 connect(filterEdit, SIGNAL(textChanged(
const QString&)),
00333 SLOT(slotFilterTextChanged(
const QString&)));
00334
00335
00336 connect(
this, SIGNAL(listChanged()), SLOT(slotUpdateStatusLabel()));
00337 }
00338
00339
00340 KSubscription::~KSubscription()
00341 {
00342 }
00343
00344
00345
void KSubscription::setStartItem(
const KGroupInfo &info )
00346 {
00347
QListViewItemIterator it(groupView);
00348
00349
for ( ; it.current(); ++it)
00350 {
00351
if (static_cast<GroupItem*>(it.current())->info() == info)
00352 {
00353 it.current()->setSelected(
true);
00354 it.current()->setOpen(
true);
00355 }
00356 }
00357 }
00358
00359
00360
void KSubscription::removeListItem(
QListView *view,
const KGroupInfo &gi )
00361 {
00362
if(!view)
return;
00363
QListViewItemIterator it(view);
00364
00365
for ( ; it.current(); ++it)
00366 {
00367
if (static_cast<GroupItem*>(it.current())->info() == gi)
00368 {
00369
delete it.current();
00370
break;
00371 }
00372 }
00373
if (view == groupView)
00374 emit listChanged();
00375 }
00376
00377
00378
QListViewItem* KSubscription::getListItem(
QListView *view,
const KGroupInfo &gi )
00379 {
00380
if(!view)
return 0;
00381
QListViewItemIterator it(view);
00382
00383
for ( ; it.current(); ++it)
00384 {
00385
if (static_cast<GroupItem*>(it.current())->info() == gi)
00386
return (it.current());
00387 }
00388
return 0;
00389 }
00390
00391
00392
bool KSubscription::itemInListView(
QListView *view,
const KGroupInfo &gi )
00393 {
00394
if(!view)
return false;
00395
QListViewItemIterator it(view);
00396
00397
for ( ; it.current(); ++it)
00398
if (static_cast<GroupItem*>(it.current())->info() == gi)
00399
return true;
00400
00401
return false;
00402 }
00403
00404
00405
void KSubscription::setDirectionButton1( Direction dir )
00406 {
00407 mDirButton1 = dir;
00408
if (dir == Left)
00409 arrowBtn1->setPixmap(pmLeft);
00410
else
00411 arrowBtn1->setPixmap(pmRight);
00412 }
00413
00414
00415
void KSubscription::setDirectionButton2( Direction dir )
00416 {
00417 mDirButton2 = dir;
00418
if (dir == Left)
00419 arrowBtn2->setPixmap(pmLeft);
00420
else
00421 arrowBtn2->setPixmap(pmRight);
00422 }
00423
00424
00425
void KSubscription::changeItemState( GroupItem* item,
bool on )
00426 {
00427
00428
if (!item->isCheckItem())
return;
00429
00430
00431
if (mLoading)
return;
00432
if (on)
00433 {
00434
if (!itemInListView(unsubView, item->info()))
00435 {
00436
QListViewItem *p = item->parent();
00437
while (p)
00438 {
00439
00440 GroupItem* pi = static_cast<GroupItem*>(p);
00441
if (pi->isCheckItem() && !pi->isOn())
00442 {
00443 pi->setIgnoreStateChange(
true);
00444 pi->setOn(
true);
00445 pi->setIgnoreStateChange(
false);
00446
new GroupItem(subView, pi->info(),
this);
00447 }
00448 p = p->parent();
00449 }
00450
new GroupItem(subView, item->info(),
this);
00451 }
00452
00453 removeListItem(unsubView, item->info());
00454 }
00455
else {
00456
if (!itemInListView(subView, item->info()))
00457 {
00458
new GroupItem(unsubView, item->info(),
this);
00459 }
00460
00461 removeListItem(subView, item->info());
00462 }
00463
00464 slotChangeButtonState(item);
00465 }
00466
00467
00468
void KSubscription::filterChanged(
QListViewItem* item,
const QString & text )
00469 {
00470
if ( !item && groupView )
00471 item = groupView->firstChild();
00472
if ( !item )
00473
return;
00474
00475
do
00476 {
00477
if ( item->firstChild() )
00478 filterChanged(item->firstChild(), text);
00479
00480 GroupItem* gr = static_cast<GroupItem*>(item);
00481
if (subCB->isChecked() || newCB->isChecked() || !text.isEmpty() ||
00482 noTreeCB->isChecked())
00483 {
00484
00485
if ( subCB->isChecked() &&
00486 (!gr->isCheckItem() ||
00487 (gr->isCheckItem() && !gr->info().subscribed)) )
00488 {
00489
00490 gr->setVisible(
false);
00491
continue;
00492 }
00493
if ( newCB->isChecked() &&
00494 (!gr->isCheckItem() ||
00495 (gr->isCheckItem() && !gr->info().newGroup)) )
00496 {
00497
00498 gr->setVisible(
false);
00499
continue;
00500 }
00501
if ( !text.isEmpty() &&
00502 gr->text(0).find(text, 0,
false) == -1)
00503 {
00504
00505 gr->setVisible(
false);
00506
continue;
00507 }
00508
if ( noTreeCB->isChecked() &&
00509 !gr->isCheckItem() )
00510 {
00511
00512 gr->setVisible(
false);
00513
continue;
00514 }
00515
00516 gr->setVisible(
true);
00517
00518 }
else {
00519 gr->setVisible(
true);
00520 }
00521
00522 }
while ((item = item->nextSibling()));
00523
00524 }
00525
00526
00527 uint KSubscription::activeItemCount()
00528 {
00529
QListViewItemIterator it(groupView);
00530
00531 uint count = 0;
00532
for ( ; it.current(); ++it)
00533 {
00534
if (static_cast<GroupItem*>(it.current())->isCheckItem() &&
00535 it.current()->isVisible() && it.current()->isEnabled())
00536 count++;
00537 }
00538
00539
return count;
00540 }
00541
00542
00543
void KSubscription::restoreOriginalParent()
00544 {
00545
QPtrList<QListViewItem> move;
00546
QListViewItemIterator it(groupView);
00547
for ( ; it.current(); ++it)
00548 {
00549
QListViewItem* origParent = static_cast<GroupItem*>(it.current())->
00550 originalParent();
00551
if (origParent && origParent != it.current()->parent())
00552 {
00553
00554 move.append(it.current());
00555 }
00556 }
00557
QPtrListIterator<QListViewItem> it2( move );
00558
for ( ; it2.current(); ++it2)
00559 {
00560
00561
QListViewItem* origParent = static_cast<GroupItem*>(it2.current())->
00562 originalParent();
00563 groupView->takeItem(it2.current());
00564 origParent->insertItem(it2.current());
00565 }
00566 }
00567
00568
00569
void KSubscription::saveOpenStates()
00570 {
00571
QListViewItemIterator it(groupView);
00572
00573
for ( ; it.current(); ++it)
00574 {
00575 static_cast<GroupItem*>(it.current())->setLastOpenState(
00576 it.current()->isOpen() );
00577 }
00578 }
00579
00580
00581
void KSubscription::restoreOpenStates()
00582 {
00583
QListViewItemIterator it(groupView);
00584
00585
for ( ; it.current(); ++it)
00586 {
00587 it.current()->setOpen(
00588 static_cast<GroupItem*>(it.current())->lastOpenState() );
00589 }
00590 }
00591
00592
00593
void KSubscription::slotLoadingComplete()
00594 {
00595 mLoading =
false;
00596
00597 enableButton(User1,
true);
00598 enableButton(User2,
true);
00599 newCB->setEnabled(
true);
00600 noTreeCB->setEnabled(
true);
00601 subCB->setEnabled(
true);
00602
00603
00604
QListViewItemIterator it(groupView);
00605
for ( ; it.current(); ++it)
00606 {
00607 static_cast<GroupItem*>(it.current())->
00608 setOriginalParent( it.current()->parent() );
00609 }
00610
00611 emit listChanged();
00612 }
00613
00614
00615
void KSubscription::slotChangeButtonState(
QListViewItem *item )
00616 {
00617
if (!item ||
00618 (item->listView() == groupView &&
00619 !static_cast<GroupItem*>(item)->isCheckItem()))
00620 {
00621
00622 arrowBtn1->setEnabled(
false);
00623 arrowBtn2->setEnabled(
false);
00624
return;
00625 }
00626
00627
QListView* currentView = item->listView();
00628
if (currentView == groupView)
00629 {
00630 setDirectionButton1(Right);
00631 setDirectionButton2(Right);
00632
if (static_cast<GroupItem*>(item)->isOn())
00633 {
00634
00635 arrowBtn1->setEnabled(
false);
00636 arrowBtn2->setEnabled(
true);
00637 }
else {
00638
00639 arrowBtn1->setEnabled(
true);
00640 arrowBtn2->setEnabled(
false);
00641 }
00642 }
else if (currentView == subView)
00643 {
00644
00645 setDirectionButton1(Left);
00646
00647 arrowBtn1->setEnabled(
true);
00648 arrowBtn2->setEnabled(
false);
00649 }
else if (currentView == unsubView)
00650 {
00651
00652 setDirectionButton2(Left);
00653
00654 arrowBtn1->setEnabled(
false);
00655 arrowBtn2->setEnabled(
true);
00656 }
00657 }
00658
00659
00660
void KSubscription::slotButton1()
00661 {
00662
if (mDirButton1 == Right)
00663 {
00664
if (groupView->currentItem() &&
00665 static_cast<GroupItem*>(groupView->currentItem())->isCheckItem())
00666 {
00667
00668 GroupItem* item = static_cast<GroupItem*>(groupView->currentItem());
00669 item->setOn(
true);
00670 }
00671 }
00672
else {
00673
if (subView->currentItem())
00674 {
00675 GroupItem* item = static_cast<GroupItem*>(subView->currentItem());
00676
00677
QListViewItem* listitem = getListItem(groupView, item->info());
00678
if (listitem)
00679 {
00680
00681 GroupItem* chk = static_cast<GroupItem*>(listitem);
00682 chk->setOn(
false);
00683 }
00684 }
00685 }
00686 }
00687
00688
00689
void KSubscription::slotButton2()
00690 {
00691
if (mDirButton2 == Right)
00692 {
00693
if (groupView->currentItem() &&
00694 static_cast<GroupItem*>(groupView->currentItem())->isCheckItem())
00695 {
00696
00697 GroupItem* item = static_cast<GroupItem*>(groupView->currentItem());
00698 item->setOn(
false);
00699 }
00700 }
00701
else {
00702
if (unsubView->currentItem())
00703 {
00704 GroupItem* item = static_cast<GroupItem*>(unsubView->currentItem());
00705
00706
QListViewItem* listitem = getListItem(groupView, item->info());
00707
if (listitem)
00708 {
00709
00710 GroupItem* chk = static_cast<GroupItem*>(listitem);
00711 chk->setOn(
true);
00712 }
00713 }
00714 }
00715 }
00716
00717
00718
void KSubscription::slotCBToggled()
00719 {
00720
if (!noTreeCB->isChecked() && !newCB->isChecked() && !subCB->isChecked())
00721 {
00722 restoreOriginalParent();
00723 }
00724
00725 filterChanged(groupView->firstChild());
00726 emit listChanged();
00727 }
00728
00729
00730
void KSubscription::slotFilterTextChanged(
const QString & text )
00731 {
00732
00733
if (mLastText.isEmpty())
00734 saveOpenStates();
00735
00736
if (!mLastText.isEmpty() && text.length() < mLastText.length())
00737 {
00738
00739 restoreOriginalParent();
00740
QListViewItemIterator it(groupView);
00741
for ( ; it.current(); ++it)
00742 {
00743 it.current()->setVisible(
true);
00744 it.current()->setEnabled(
true);
00745 }
00746 }
00747
00748 filterChanged(groupView->firstChild(), text);
00749
00750
if (text.isEmpty())
00751 restoreOpenStates();
00752
00753 emit listChanged();
00754 mLastText = text;
00755 }
00756
00757
00758
void KSubscription::slotUpdateStatusLabel()
00759 {
00760
QString text;
00761
if (mLoading)
00762 text = i18n(
"Loading... (1 matching)",
"Loading... (%n matching)",
00763 activeItemCount());
00764
else
00765 text = i18n(
"%1: (1 matching)",
"%1: (%n matching)", activeItemCount())
00766 .arg(account()->name());
00767
00768 leftLabel->setText(text);
00769 }
00770
00771
00772
void KSubscription::slotLoadFolders()
00773 {
00774 subView->clear();
00775 unsubView->clear();
00776 groupView->clear();
00777 }
00778
00779
#include "ksubscription.moc"