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