libtdepim

completionordereditor.cpp
1 /*
2  * completionordereditor.cpp
3  *
4  * Copyright (c) 2004 David Faure <faure@kde.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  * In addition, as a special exception, the copyright holders give
20  * permission to link the code of this program with any edition of
21  * the TQt library by Trolltech AS, Norway (or with modified versions
22  * of TQt that use the same license as TQt), and distribute linked
23  * combinations including the two. You must obey the GNU General
24  * Public License in all respects for all of the code used other than
25  * TQt. If you modify this file, you may extend this exception to
26  * your version of the file, but you are not obligated to do so. If
27  * you do not wish to do so, delete this exception statement from
28  * your version.
29  */
30 #include <config.h> // FOR TDEPIM_NEW_DISTRLISTS
31 
32 #include "completionordereditor.h"
33 #include "ldapclient.h"
34 #include "resourceabc.h"
35 
36 #include <tdeabc/stdaddressbook.h>
37 #include <tdeabc/resource.h>
38 
39 #include <kdebug.h>
40 #include <tdelocale.h>
41 #include <kiconloader.h>
42 #include <tdelistview.h>
43 #include <kpushbutton.h>
44 
45 #include <tqhbox.h>
46 #include <tqvbox.h>
47 #include <tqheader.h>
48 #include <tqtoolbutton.h>
49 #include <tdeapplication.h>
50 #include <dcopclient.h>
51 
52 /*
53 
54 Several items are used in addresseelineedit's completion object:
55  LDAP servers, KABC resources (imap and non-imap), Recent addresses (in kmail only).
56 
57 The default completion weights are as follow:
58  Recent addresses (kmail) : 10 (see kmail/kmlineeditspell.cpp)
59  LDAP: 50, 49, 48 etc. (see ldapclient.cpp)
60  KABC non-imap resources: 60 (see addresseelineedit.cpp and SimpleCompletionItem here)
61  Distribution lists: 60 (see addresseelineedit.cpp and SimpleCompletionItem here)
62  KABC imap resources: 80 (see tderesources/imap/tdeabc/resourceimap.cpp)
63 
64 This dialog allows to change those weights, by showing one item per:
65  - LDAP server
66  - KABC non-imap resource
67  - KABC imap subresource
68  plus one item for Distribution Lists.
69 
70  Maybe 'recent addresses' should be configurable too, but first it might
71  be better to add support for them in korganizer too.
72 
73 */
74 
75 using namespace KPIM;
76 
77 namespace KPIM {
78 
79 int CompletionItemList::compareItems( TQPtrCollection::Item s1, TQPtrCollection::Item s2 )
80 {
81  int w1 = ( (CompletionItem*)s1 )->completionWeight();
82  int w2 = ( (CompletionItem*)s2 )->completionWeight();
83  // s1 < s2 if it has a higher completion value, i.e. w1 > w2.
84  return w2 - w1;
85 }
86 
87 class LDAPCompletionItem : public CompletionItem
88 {
89 public:
90  LDAPCompletionItem( LdapClient* ldapClient ) : mLdapClient( ldapClient ) {}
91  virtual TQString label() const { return i18n( "LDAP server %1" ).arg( mLdapClient->server().host() ); }
92  virtual int completionWeight() const { return mLdapClient->completionWeight(); }
93  virtual void save( CompletionOrderEditor* );
94 protected:
95  virtual void setCompletionWeight( int weight ) { mWeight = weight; }
96 private:
97  LdapClient* mLdapClient;
98  int mWeight;
99 };
100 
101 void LDAPCompletionItem::save( CompletionOrderEditor* )
102 {
103  TDEConfig * config = LdapSearch::config();
104  config->setGroup( "LDAP" );
105  config->writeEntry( TQString( "SelectedCompletionWeight%1" ).arg( mLdapClient->clientNumber() ),
106  mWeight );
107  config->sync();
108 }
109 
110 // A simple item saved into kpimcompletionorder (no subresources, just name/identifier/weight)
111 class SimpleCompletionItem : public CompletionItem
112 {
113 public:
114  SimpleCompletionItem( CompletionOrderEditor* editor, const TQString& label, const TQString& identifier, int weight )
115  : mLabel( label ), mIdentifier( identifier ) {
116  TDEConfigGroup group( editor->configFile(), "CompletionWeights" );
117  mWeight = group.readNumEntry( mIdentifier, weight );
118  }
119  virtual TQString label() const { return mLabel; }
120  virtual int completionWeight() const { return mWeight; }
121  virtual void save( CompletionOrderEditor* );
122 protected:
123  virtual void setCompletionWeight( int weight ) { mWeight = weight; }
124 private:
125  TQString mLabel, mIdentifier;
126  int mWeight;
127 };
128 
129 void SimpleCompletionItem::save( CompletionOrderEditor* editor )
130 {
131  // Maybe TDEABC::Resource could have a completionWeight setting (for readConfig/writeConfig)
132  // But for tdelibs-3.2 compat purposes I can't do that.
133  TDEConfigGroup group( editor->configFile(), "CompletionWeights" );
134  group.writeEntry( mIdentifier, mWeight );
135 }
136 
137 // An imap subresource for tdeabc
138 class KABCImapSubResCompletionItem : public CompletionItem
139 {
140 public:
141  KABCImapSubResCompletionItem( ResourceABC* resource, const TQString& subResource )
142  : mResource( resource ), mSubResource( subResource ), mWeight( completionWeight() ) {}
143  virtual TQString label() const {
144  return TQString( "%1 %2" ).arg( mResource->resourceName() ).arg( mResource->subresourceLabel( mSubResource ) );
145  }
146  virtual int completionWeight() const {
147  return mResource->subresourceCompletionWeight( mSubResource );
148  }
149  virtual void setCompletionWeight( int weight ) {
150  mWeight = weight;
151  }
152  virtual void save( CompletionOrderEditor* ) {
153  mResource->setSubresourceCompletionWeight( mSubResource, mWeight );
154  }
155 private:
156  ResourceABC* mResource;
157  TQString mSubResource;
158  int mWeight;
159 };
160 
162 
163 class CompletionViewItem : public TQListViewItem
164 {
165 public:
166  CompletionViewItem( TQListView* lv, CompletionItem* item )
167  : TQListViewItem( lv, lv->lastItem(), item->label() ), mItem( item ) {}
168  CompletionItem* item() const { return mItem; }
169  void setItem( CompletionItem* i ) { mItem = i; setText( 0, mItem->label() ); }
170 
171 private:
172  CompletionItem* mItem;
173 };
174 
175 CompletionOrderEditor::CompletionOrderEditor( KPIM::LdapSearch* ldapSearch,
176  TQWidget* parent, const char* name )
177  : KDialogBase( parent, name, true, i18n("Edit Completion Order"), Ok|Cancel, Ok, true ),
178  mConfig( "kpimcompletionorder" ), mDirty( false )
179 {
180  mItems.setAutoDelete( true );
181  // The first step is to gather all the data, creating CompletionItem objects
182  TQValueList< LdapClient* > ldapClients = ldapSearch->clients();
183  for( TQValueList<LdapClient*>::const_iterator it = ldapClients.begin(); it != ldapClients.end(); ++it ) {
184  //kdDebug(5300) << "LDAP: host " << (*it)->host() << " weight " << (*it)->completionWeight() << endl;
185  mItems.append( new LDAPCompletionItem( *it ) );
186  }
187  TDEABC::AddressBook *addressBook = TDEABC::StdAddressBook::self( true );
188  TQPtrList<TDEABC::Resource> resources = addressBook->resources();
189  for( TQPtrListIterator<TDEABC::Resource> resit( resources ); *resit; ++resit ) {
190  //kdDebug(5300) << "KABC Resource: " << (*resit)->className() << endl;
191  ResourceABC* res = dynamic_cast<ResourceABC *>( *resit );
192  if ( res ) { // IMAP KABC resource
193  const TQStringList subresources = res->subresources();
194  for( TQStringList::const_iterator it = subresources.begin(); it != subresources.end(); ++it ) {
195  mItems.append( new KABCImapSubResCompletionItem( res, *it ) );
196  }
197  } else { // non-IMAP KABC resource
198  mItems.append( new SimpleCompletionItem( this, (*resit)->resourceName(),
199  (*resit)->identifier(), 60 ) );
200  }
201  }
202 
203 #ifndef TDEPIM_NEW_DISTRLISTS // new distr lists are normal contact, so no separate item if using them
204  // Add an item for distribution lists
205  mItems.append( new SimpleCompletionItem( this, i18n( "Distribution Lists" ), "DistributionLists" ), 60 );
206 #endif
207 
208  mItems.append( new SimpleCompletionItem( this, i18n( "Recent Addresses" ), "Recent Addresses", 10 ) );
209 
210  // Now sort the items, then create the GUI
211  mItems.sort();
212 
213  TQHBox* page = makeHBoxMainWidget();
214  mListView = new TDEListView( page );
215  mListView->setSorting( -1 );
216  mListView->addColumn( TQString() );
217  mListView->header()->hide();
218 
219  for( TQPtrListIterator<CompletionItem> compit( mItems ); *compit; ++compit ) {
220  new CompletionViewItem( mListView, *compit );
221  kdDebug(5300) << " " << (*compit)->label() << " " << (*compit)->completionWeight() << endl;
222  }
223 
224  TQVBox* upDownBox = new TQVBox( page );
225  mUpButton = new KPushButton( upDownBox, "mUpButton" );
226  mUpButton->setIconSet( BarIconSet( "go-up", TDEIcon::SizeSmall ) );
227  mUpButton->setEnabled( false ); // b/c no item is selected yet
228  mUpButton->setFocusPolicy( TQWidget::StrongFocus );
229 
230  mDownButton = new KPushButton( upDownBox, "mDownButton" );
231  mDownButton->setIconSet( BarIconSet( "go-down", TDEIcon::SizeSmall ) );
232  mDownButton->setEnabled( false ); // b/c no item is selected yet
233  mDownButton->setFocusPolicy( TQWidget::StrongFocus );
234 
235  TQWidget* spacer = new TQWidget( upDownBox );
236  upDownBox->setStretchFactor( spacer, 100 );
237 
238  connect( mListView, TQ_SIGNAL( selectionChanged( TQListViewItem* ) ),
239  TQ_SLOT( slotSelectionChanged( TQListViewItem* ) ) );
240  connect( mUpButton, TQ_SIGNAL( clicked() ), this, TQ_SLOT( slotMoveUp() ) );
241  connect( mDownButton, TQ_SIGNAL( clicked() ), this, TQ_SLOT( slotMoveDown() ) );
242 }
243 
244 CompletionOrderEditor::~CompletionOrderEditor()
245 {
246 }
247 
248 void CompletionOrderEditor::slotSelectionChanged( TQListViewItem *item )
249 {
250  mDownButton->setEnabled( item && item->itemBelow() );
251  mUpButton->setEnabled( item && item->itemAbove() );
252 }
253 
254 static void swapItems( CompletionViewItem *one, CompletionViewItem *other )
255 {
256  CompletionItem* i = one->item();
257  one->setItem( other->item() );
258  other->setItem( i );
259 }
260 
261 void CompletionOrderEditor::slotMoveUp()
262 {
263  CompletionViewItem *item = static_cast<CompletionViewItem *>( mListView->selectedItem() );
264  if ( !item ) return;
265  CompletionViewItem *above = static_cast<CompletionViewItem *>( item->itemAbove() );
266  if ( !above ) return;
267  swapItems( item, above );
268  mListView->setCurrentItem( above );
269  mListView->setSelected( above, true );
270  mDirty = true;
271 }
272 
273 void CompletionOrderEditor::slotMoveDown()
274 {
275  CompletionViewItem *item = static_cast<CompletionViewItem *>( mListView->selectedItem() );
276  if ( !item ) return;
277  CompletionViewItem *below = static_cast<CompletionViewItem *>( item->itemBelow() );
278  if ( !below ) return;
279  swapItems( item, below );
280  mListView->setCurrentItem( below );
281  mListView->setSelected( below, true );
282  mDirty = true;
283 }
284 
285 void CompletionOrderEditor::slotOk()
286 {
287  if ( mDirty ) {
288  int w = 100;
289  for ( TQListViewItem* it = mListView->firstChild(); it; it = it->nextSibling() ) {
290  CompletionViewItem *item = static_cast<CompletionViewItem *>( it );
291  item->item()->setCompletionWeight( w );
292  item->item()->save( this );
293  kdDebug(5300) << "slotOk: " << item->item()->label() << " " << w << endl;
294  --w;
295  }
296 
297  // Emit DCOP signal
298  // The emitter is always set to KPIM::IMAPCompletionOrder, so that the connect works
299  // This is why we can't use k_dcop_signals here, but need to use emitDCOPSignal
300  kapp->dcopClient()->emitDCOPSignal( "KPIM::IMAPCompletionOrder", "orderChanged()", TQByteArray() );
301  }
302  KDialogBase::slotOk();
303 }
304 
305 } // namespace KPIM
306 
307 #include "completionordereditor.moc"
This class is internal.
Definition: ldapclient.h:143
This class is internal.
Definition: ldapclient.h:247
This class is the implementation of subfolder resources for KABC.
Definition: resourceabc.h:45
virtual TQStringList subresources() const
If this resource has subresources, return a TQStringList of them.
Definition: resourceabc.h:66
TDEPIM classes for drag and drop of mails.