You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdepim/libtdepim/completionordereditor.cpp

308 lines
11 KiB

/** -*- c++ -*-
* completionordereditor.cpp
*
* Copyright (c) 2004 David Faure <faure@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of this program with any edition of
* the TQt library by Trolltech AS, Norway (or with modified versions
* of TQt that use the same license as TQt), and distribute linked
* combinations including the two. You must obey the GNU General
* Public License in all respects for all of the code used other than
* TQt. If you modify this file, you may extend this exception to
* your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from
* your version.
*/
#include <config.h> // FOR TDEPIM_NEW_DISTRLISTS
#include "completionordereditor.h"
#include "ldapclient.h"
#include "resourceabc.h"
#include <kabc/stdaddressbook.h>
#include <kabc/resource.h>
#include <kdebug.h>
#include <klocale.h>
#include <kiconloader.h>
#include <tdelistview.h>
#include <kpushbutton.h>
#include <tqhbox.h>
#include <tqvbox.h>
#include <tqheader.h>
#include <tqtoolbutton.h>
#include <kapplication.h>
#include <dcopclient.h>
/*
Several items are used in addresseelineedit's completion object:
LDAP servers, KABC resources (imap and non-imap), Recent addresses (in kmail only).
The default completion weights are as follow:
Recent addresses (kmail) : 10 (see kmail/kmlineeditspell.cpp)
LDAP: 50, 49, 48 etc. (see ldapclient.cpp)
KABC non-imap resources: 60 (see addresseelineedit.cpp and SimpleCompletionItem here)
Distribution lists: 60 (see addresseelineedit.cpp and SimpleCompletionItem here)
KABC imap resources: 80 (see tderesources/imap/kabc/resourceimap.cpp)
This dialog allows to change those weights, by showing one item per:
- LDAP server
- KABC non-imap resource
- KABC imap subresource
plus one item for Distribution Lists.
Maybe 'recent addresses' should be configurable too, but first it might
be better to add support for them in korganizer too.
*/
using namespace KPIM;
namespace KPIM {
int CompletionItemList::compareItems( TQPtrCollection::Item s1, TQPtrCollection::Item s2 )
{
int w1 = ( (CompletionItem*)s1 )->completionWeight();
int w2 = ( (CompletionItem*)s2 )->completionWeight();
// s1 < s2 if it has a higher completion value, i.e. w1 > w2.
return w2 - w1;
}
class LDAPCompletionItem : public CompletionItem
{
public:
LDAPCompletionItem( LdapClient* ldapClient ) : mLdapClient( ldapClient ) {}
virtual TQString label() const { return i18n( "LDAP server %1" ).arg( mLdapClient->server().host() ); }
virtual int completionWeight() const { return mLdapClient->completionWeight(); }
virtual void save( CompletionOrderEditor* );
protected:
virtual void setCompletionWeight( int weight ) { mWeight = weight; }
private:
LdapClient* mLdapClient;
int mWeight;
};
void LDAPCompletionItem::save( CompletionOrderEditor* )
{
TDEConfig * config = LdapSearch::config();
config->setGroup( "LDAP" );
config->writeEntry( TQString( "SelectedCompletionWeight%1" ).arg( mLdapClient->clientNumber() ),
mWeight );
config->sync();
}
// A simple item saved into kpimcompletionorder (no subresources, just name/identifier/weight)
class SimpleCompletionItem : public CompletionItem
{
public:
SimpleCompletionItem( CompletionOrderEditor* editor, const TQString& label, const TQString& identifier, int weight )
: mLabel( label ), mIdentifier( identifier ) {
TDEConfigGroup group( editor->configFile(), "CompletionWeights" );
mWeight = group.readNumEntry( mIdentifier, weight );
}
virtual TQString label() const { return mLabel; }
virtual int completionWeight() const { return mWeight; }
virtual void save( CompletionOrderEditor* );
protected:
virtual void setCompletionWeight( int weight ) { mWeight = weight; }
private:
TQString mLabel, mIdentifier;
int mWeight;
};
void SimpleCompletionItem::save( CompletionOrderEditor* editor )
{
// Maybe KABC::Resource could have a completionWeight setting (for readConfig/writeConfig)
// But for tdelibs-3.2 compat purposes I can't do that.
TDEConfigGroup group( editor->configFile(), "CompletionWeights" );
group.writeEntry( mIdentifier, mWeight );
}
// An imap subresource for kabc
class KABCImapSubResCompletionItem : public CompletionItem
{
public:
KABCImapSubResCompletionItem( ResourceABC* resource, const TQString& subResource )
: mResource( resource ), mSubResource( subResource ), mWeight( completionWeight() ) {}
virtual TQString label() const {
return TQString( "%1 %2" ).arg( mResource->resourceName() ).arg( mResource->subresourceLabel( mSubResource ) );
}
virtual int completionWeight() const {
return mResource->subresourceCompletionWeight( mSubResource );
}
virtual void setCompletionWeight( int weight ) {
mWeight = weight;
}
virtual void save( CompletionOrderEditor* ) {
mResource->setSubresourceCompletionWeight( mSubResource, mWeight );
}
private:
ResourceABC* mResource;
TQString mSubResource;
int mWeight;
};
/////////
class CompletionViewItem : public TQListViewItem
{
public:
CompletionViewItem( TQListView* lv, CompletionItem* item )
: TQListViewItem( lv, lv->lastItem(), item->label() ), mItem( item ) {}
CompletionItem* item() const { return mItem; }
void setItem( CompletionItem* i ) { mItem = i; setText( 0, mItem->label() ); }
private:
CompletionItem* mItem;
};
CompletionOrderEditor::CompletionOrderEditor( KPIM::LdapSearch* ldapSearch,
TQWidget* parent, const char* name )
: KDialogBase( parent, name, true, i18n("Edit Completion Order"), Ok|Cancel, Ok, true ),
mConfig( "kpimcompletionorder" ), mDirty( false )
{
mItems.setAutoDelete( true );
// The first step is to gather all the data, creating CompletionItem objects
TQValueList< LdapClient* > ldapClients = ldapSearch->clients();
for( TQValueList<LdapClient*>::const_iterator it = ldapClients.begin(); it != ldapClients.end(); ++it ) {
//kdDebug(5300) << "LDAP: host " << (*it)->host() << " weight " << (*it)->completionWeight() << endl;
mItems.append( new LDAPCompletionItem( *it ) );
}
KABC::AddressBook *addressBook = KABC::StdAddressBook::self( true );
TQPtrList<KABC::Resource> resources = addressBook->resources();
for( TQPtrListIterator<KABC::Resource> resit( resources ); *resit; ++resit ) {
//kdDebug(5300) << "KABC Resource: " << (*resit)->className() << endl;
ResourceABC* res = dynamic_cast<ResourceABC *>( *resit );
if ( res ) { // IMAP KABC resource
const TQStringList subresources = res->subresources();
for( TQStringList::const_iterator it = subresources.begin(); it != subresources.end(); ++it ) {
mItems.append( new KABCImapSubResCompletionItem( res, *it ) );
}
} else { // non-IMAP KABC resource
mItems.append( new SimpleCompletionItem( this, (*resit)->resourceName(),
(*resit)->identifier(), 60 ) );
}
}
#ifndef TDEPIM_NEW_DISTRLISTS // new distr lists are normal contact, so no separate item if using them
// Add an item for distribution lists
mItems.append( new SimpleCompletionItem( this, i18n( "Distribution Lists" ), "DistributionLists" ), 60 );
#endif
mItems.append( new SimpleCompletionItem( this, i18n( "Recent Addresses" ), "Recent Addresses", 10 ) );
// Now sort the items, then create the GUI
mItems.sort();
TQHBox* page = makeHBoxMainWidget();
mListView = new TDEListView( page );
mListView->setSorting( -1 );
mListView->addColumn( TQString() );
mListView->header()->hide();
for( TQPtrListIterator<CompletionItem> compit( mItems ); *compit; ++compit ) {
new CompletionViewItem( mListView, *compit );
kdDebug(5300) << " " << (*compit)->label() << " " << (*compit)->completionWeight() << endl;
}
TQVBox* upDownBox = new TQVBox( page );
mUpButton = new KPushButton( upDownBox, "mUpButton" );
mUpButton->setIconSet( BarIconSet( "up", TDEIcon::SizeSmall ) );
mUpButton->setEnabled( false ); // b/c no item is selected yet
mUpButton->setFocusPolicy( TQ_StrongFocus );
mDownButton = new KPushButton( upDownBox, "mDownButton" );
mDownButton->setIconSet( BarIconSet( "down", TDEIcon::SizeSmall ) );
mDownButton->setEnabled( false ); // b/c no item is selected yet
mDownButton->setFocusPolicy( TQ_StrongFocus );
TQWidget* spacer = new TQWidget( upDownBox );
upDownBox->setStretchFactor( spacer, 100 );
connect( mListView, TQT_SIGNAL( selectionChanged( TQListViewItem* ) ),
TQT_SLOT( slotSelectionChanged( TQListViewItem* ) ) );
connect( mUpButton, TQT_SIGNAL( clicked() ), this, TQT_SLOT( slotMoveUp() ) );
connect( mDownButton, TQT_SIGNAL( clicked() ), this, TQT_SLOT( slotMoveDown() ) );
}
CompletionOrderEditor::~CompletionOrderEditor()
{
}
void CompletionOrderEditor::slotSelectionChanged( TQListViewItem *item )
{
mDownButton->setEnabled( item && item->itemBelow() );
mUpButton->setEnabled( item && item->itemAbove() );
}
static void swapItems( CompletionViewItem *one, CompletionViewItem *other )
{
CompletionItem* i = one->item();
one->setItem( other->item() );
other->setItem( i );
}
void CompletionOrderEditor::slotMoveUp()
{
CompletionViewItem *item = static_cast<CompletionViewItem *>( mListView->selectedItem() );
if ( !item ) return;
CompletionViewItem *above = static_cast<CompletionViewItem *>( item->itemAbove() );
if ( !above ) return;
swapItems( item, above );
mListView->setCurrentItem( above );
mListView->setSelected( above, true );
mDirty = true;
}
void CompletionOrderEditor::slotMoveDown()
{
CompletionViewItem *item = static_cast<CompletionViewItem *>( mListView->selectedItem() );
if ( !item ) return;
CompletionViewItem *below = static_cast<CompletionViewItem *>( item->itemBelow() );
if ( !below ) return;
swapItems( item, below );
mListView->setCurrentItem( below );
mListView->setSelected( below, true );
mDirty = true;
}
void CompletionOrderEditor::slotOk()
{
if ( mDirty ) {
int w = 100;
for ( TQListViewItem* it = mListView->firstChild(); it; it = it->nextSibling() ) {
CompletionViewItem *item = static_cast<CompletionViewItem *>( it );
item->item()->setCompletionWeight( w );
item->item()->save( this );
kdDebug(5300) << "slotOk: " << item->item()->label() << " " << w << endl;
--w;
}
// Emit DCOP signal
// The emitter is always set to KPIM::IMAPCompletionOrder, so that the connect works
// This is why we can't use k_dcop_signals here, but need to use emitDCOPSignal
kapp->dcopClient()->emitDCOPSignal( "KPIM::IMAPCompletionOrder", "orderChanged()", TQByteArray() );
}
KDialogBase::slotOk();
}
} // namespace KPIM
#include "completionordereditor.moc"