libkdepim

completionordereditor.cpp

00001 
00031 #include "completionordereditor.h"
00032 #include "ldapclient.h"
00033 #include "resourceabc.h"
00034 
00035 #include <kabc/stdaddressbook.h>
00036 #include <kabc/resource.h>
00037 
00038 #include <kdebug.h>
00039 #include <klocale.h>
00040 #include <kiconloader.h>
00041 #include <klistview.h>
00042 #include <kpushbutton.h>
00043 
00044 #include <qhbox.h>
00045 #include <qvbox.h>
00046 #include <qheader.h>
00047 #include <qtoolbutton.h>
00048 #include <kapplication.h>
00049 #include <dcopclient.h>
00050 
00051 /*
00052 
00053 Several items are used in addresseelineedit's completion object:
00054   LDAP servers, KABC resources (imap and non-imap), Recent addresses (in kmail only).
00055 
00056 The default completion weights are as follow:
00057   LDAP: 50, 49, 48 etc.          (see ldapclient.cpp)
00058   KABC non-imap resources: 60    (see addresseelineedit.cpp and SimpleCompletionItem here)
00059   Distribution lists: 60         (see addresseelineedit.cpp and SimpleCompletionItem here)
00060   KABC imap resources: 80        (see kresources/imap/kabc/resourceimap.cpp)
00061   Recent addresses (kmail) : 120 (see kmail/kmcomposewin.cpp)
00062 
00063 This dialog allows to change those weights, by showing one item per:
00064  - LDAP server
00065  - KABC non-imap resource
00066  - KABC imap subresource
00067  plus one item for Distribution Lists.
00068 
00069  Maybe 'recent addresses' should be configurable too, but first it might
00070  be better to add support for them in korganizer too.
00071 
00072 */
00073 
00074 using namespace KPIM;
00075 
00076 namespace KPIM {
00077 
00078 int CompletionItemList::compareItems( QPtrCollection::Item s1, QPtrCollection::Item s2 )
00079 {
00080   int w1 = ( (CompletionItem*)s1 )->completionWeight();
00081   int w2 = ( (CompletionItem*)s2 )->completionWeight();
00082   // s1 < s2 if it has a higher completion value, i.e. w1 > w2.
00083   return w2 - w1;
00084 }
00085 
00086 class LDAPCompletionItem : public CompletionItem
00087 {
00088 public:
00089   LDAPCompletionItem( LdapClient* ldapClient ) : mLdapClient( ldapClient ) {}
00090   virtual QString label() const { return i18n( "LDAP server %1" ).arg( mLdapClient->server().host() ); }
00091   virtual int completionWeight() const { return mLdapClient->completionWeight(); }
00092   virtual void save( CompletionOrderEditor* );
00093 protected:
00094   virtual void setCompletionWeight( int weight ) { mWeight = weight; }
00095 private:
00096   LdapClient* mLdapClient;
00097   int mWeight;
00098 };
00099 
00100 void LDAPCompletionItem::save( CompletionOrderEditor* )
00101 {
00102   KConfig config( "kabldaprc" );
00103   config.setGroup( "LDAP" );
00104   config.writeEntry( QString( "SelectedCompletionWeight%1" ).arg( mLdapClient->clientNumber() ),
00105                      mWeight );
00106   config.sync();
00107 }
00108 
00109 // A simple item saved into kpimcompletionorder (no subresources, just name/identifier/weight)
00110 class SimpleCompletionItem : public CompletionItem
00111 {
00112 public:
00113   SimpleCompletionItem( CompletionOrderEditor* editor, const QString& label, const QString& identifier )
00114     : mLabel( label ), mIdentifier( identifier ) {
00115       KConfigGroup group( editor->configFile(), "CompletionWeights" );
00116       mWeight = group.readNumEntry( mIdentifier, 60 );
00117     }
00118   virtual QString label() const { return mLabel; }
00119   virtual int completionWeight() const { return mWeight; }
00120   virtual void save( CompletionOrderEditor* );
00121 protected:
00122   virtual void setCompletionWeight( int weight ) { mWeight = weight; }
00123 private:
00124   QString mLabel, mIdentifier;
00125   int mWeight;
00126 };
00127 
00128 void SimpleCompletionItem::save( CompletionOrderEditor* editor )
00129 {
00130   // Maybe KABC::Resource could have a completionWeight setting (for readConfig/writeConfig)
00131   // But for kdelibs-3.2 compat purposes I can't do that.
00132   KConfigGroup group( editor->configFile(), "CompletionWeights" );
00133   group.writeEntry( mIdentifier, mWeight );
00134 }
00135 
00136 // An imap subresource for kabc
00137 class KABCImapSubResCompletionItem : public CompletionItem
00138 {
00139 public:
00140   KABCImapSubResCompletionItem( ResourceABC* resource, const QString& subResource )
00141     : mResource( resource ), mSubResource( subResource ), mWeight( completionWeight() ) {}
00142   virtual QString label() const {
00143     return QString( "%1 %2" ).arg( mResource->resourceName() ).arg( mResource->subresourceLabel( mSubResource ) );
00144   }
00145   virtual int completionWeight() const {
00146     return mResource->subresourceCompletionWeight( mSubResource );
00147   }
00148   virtual void setCompletionWeight( int weight ) {
00149     mWeight = weight;
00150   }
00151   virtual void save( CompletionOrderEditor* ) {
00152     mResource->setSubresourceCompletionWeight( mSubResource, mWeight );
00153   }
00154 private:
00155   ResourceABC* mResource;
00156   QString mSubResource;
00157   int mWeight;
00158 };
00159 
00161 
00162 class CompletionViewItem : public QListViewItem
00163 {
00164 public:
00165   CompletionViewItem( QListView* lv, CompletionItem* item )
00166     : QListViewItem( lv, lv->lastItem(), item->label() ), mItem( item ) {}
00167   CompletionItem* item() const { return mItem; }
00168   void setItem( CompletionItem* i ) { mItem = i; setText( 0, mItem->label() ); }
00169 
00170 private:
00171   CompletionItem* mItem;
00172 };
00173 
00174 CompletionOrderEditor::CompletionOrderEditor( KPIM::LdapSearch* ldapSearch,
00175                                               QWidget* parent, const char* name )
00176   : KDialogBase( parent, name, true, i18n("Edit Completion Order"), Ok|Cancel, Ok, true ),
00177     mConfig( "kpimcompletionorder" ), mDirty( false )
00178 {
00179   mItems.setAutoDelete( true );
00180   // The first step is to gather all the data, creating CompletionItem objects
00181   QValueList< LdapClient* > ldapClients = ldapSearch->clients();
00182   for( QValueList<LdapClient*>::const_iterator it = ldapClients.begin(); it != ldapClients.end(); ++it ) {
00183     //kdDebug(5300) << "LDAP: host " << (*it)->host() << " weight " << (*it)->completionWeight() << endl;
00184     mItems.append( new LDAPCompletionItem( *it ) );
00185   }
00186   KABC::AddressBook *addressBook = KABC::StdAddressBook::self( true );
00187   QPtrList<KABC::Resource> resources = addressBook->resources();
00188   for( QPtrListIterator<KABC::Resource> resit( resources ); *resit; ++resit ) {
00189     //kdDebug(5300) << "KABC Resource: " << (*resit)->className() << endl;
00190     ResourceABC* res = dynamic_cast<ResourceABC *>( *resit );
00191     if ( res ) { // IMAP KABC resource
00192       const QStringList subresources = res->subresources();
00193       for( QStringList::const_iterator it = subresources.begin(); it != subresources.end(); ++it ) {
00194         mItems.append( new KABCImapSubResCompletionItem( res, *it ) );
00195       }
00196     } else { // non-IMAP KABC resource
00197       mItems.append( new SimpleCompletionItem( this, (*resit)->resourceName(),
00198                                                (*resit)->identifier() ) );
00199     }
00200   }
00201 
00202 #ifndef KDEPIM_NEW_DISTRLISTS // new distr lists are normal contact, so no separate item if using them
00203   // Add an item for distribution lists
00204   mItems.append( new SimpleCompletionItem( this, i18n( "Distribution Lists" ), "DistributionLists" ) );
00205 #endif
00206 
00207   // Now sort the items, then create the GUI
00208   mItems.sort();
00209 
00210   QHBox* page = makeHBoxMainWidget();
00211   mListView = new KListView( page );
00212   mListView->setSorting( -1 );
00213   mListView->addColumn( QString::null );
00214   mListView->header()->hide();
00215 
00216   for( QPtrListIterator<CompletionItem> compit( mItems ); *compit; ++compit ) {
00217     new CompletionViewItem( mListView, *compit );
00218     kdDebug(5300) << "  " << (*compit)->label() << " " << (*compit)->completionWeight() << endl;
00219   }
00220 
00221   QVBox* upDownBox = new QVBox( page );
00222   mUpButton = new KPushButton( upDownBox, "mUpButton" );
00223   mUpButton->setIconSet( BarIconSet( "up", KIcon::SizeSmall ) );
00224   mUpButton->setEnabled( false ); // b/c no item is selected yet
00225   mUpButton->setFocusPolicy( StrongFocus );
00226 
00227   mDownButton = new KPushButton( upDownBox, "mDownButton" );
00228   mDownButton->setIconSet( BarIconSet( "down", KIcon::SizeSmall ) );
00229   mDownButton->setEnabled( false ); // b/c no item is selected yet
00230   mDownButton->setFocusPolicy( StrongFocus );
00231 
00232   QWidget* spacer = new QWidget( upDownBox );
00233   upDownBox->setStretchFactor( spacer, 100 );
00234 
00235   connect( mListView, SIGNAL( selectionChanged( QListViewItem* ) ),
00236            SLOT( slotSelectionChanged( QListViewItem* ) ) );
00237   connect( mUpButton, SIGNAL( clicked() ), this, SLOT( slotMoveUp() ) );
00238   connect( mDownButton, SIGNAL( clicked() ), this, SLOT( slotMoveDown() ) );
00239 }
00240 
00241 CompletionOrderEditor::~CompletionOrderEditor()
00242 {
00243 }
00244 
00245 void CompletionOrderEditor::slotSelectionChanged( QListViewItem *item )
00246 {
00247   mDownButton->setEnabled( item && item->itemBelow() );
00248   mUpButton->setEnabled( item && item->itemAbove() );
00249 }
00250 
00251 static void swapItems( CompletionViewItem *one, CompletionViewItem *other )
00252 {
00253   CompletionItem* i = one->item();
00254   one->setItem( other->item() );
00255   other->setItem( i );
00256 }
00257 
00258 void CompletionOrderEditor::slotMoveUp()
00259 {
00260   CompletionViewItem *item = static_cast<CompletionViewItem *>( mListView->selectedItem() );
00261   if ( !item ) return;
00262   CompletionViewItem *above = static_cast<CompletionViewItem *>( item->itemAbove() );
00263   if ( !above ) return;
00264   swapItems( item, above );
00265   mListView->setCurrentItem( above );
00266   mListView->setSelected( above, true );
00267   mDirty = true;
00268 }
00269 
00270 void CompletionOrderEditor::slotMoveDown()
00271 {
00272   CompletionViewItem *item = static_cast<CompletionViewItem *>( mListView->selectedItem() );
00273   if ( !item ) return;
00274   CompletionViewItem *below = static_cast<CompletionViewItem *>( item->itemBelow() );
00275   if ( !below ) return;
00276   swapItems( item, below );
00277   mListView->setCurrentItem( below );
00278   mListView->setSelected( below, true );
00279   mDirty = true;
00280 }
00281 
00282 void CompletionOrderEditor::slotOk()
00283 {
00284   if ( mDirty ) {
00285     int w = 100;
00286     for ( QListViewItem* it = mListView->firstChild(); it; it = it->nextSibling() ) {
00287       CompletionViewItem *item = static_cast<CompletionViewItem *>( it );
00288       item->item()->setCompletionWeight( w );
00289       item->item()->save( this );
00290       kdDebug(5300) << "slotOk:   " << item->item()->label() << " " << w << endl;
00291       --w;
00292     }
00293 
00294     // Emit DCOP signal
00295     // The emitter is always set to KPIM::IMAPCompletionOrder, so that the connect works
00296     // This is why we can't use k_dcop_signals here, but need to use emitDCOPSignal
00297     kapp->dcopClient()->emitDCOPSignal( "KPIM::IMAPCompletionOrder", "orderChanged()", QByteArray() );
00298   }
00299   KDialogBase::slotOk();
00300 }
00301 
00302 } // namespace KPIM
00303 
00304 #include "completionordereditor.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys