New "add to address book" filter type. Based on a commit from

Christian Schaarschmidt on the 3.5.5+ branch.
BUG: 47333

svn path=/trunk/KDE/kdepim/; revision=1003568
wilder-work
Bruno Bigras 17 years ago
parent e1d39a956f
commit 731e9cf3da
  1. 273
      kmfilteraction.cpp
  2. 52
      kmfilterdlg.cpp
  3. 27
      kmfilterdlg.h

@ -44,6 +44,9 @@ using KMail::RegExpLineEdit;
#include <Phonon/MediaObject>
#include <kshell.h>
#include <kprocess.h>
#include <kabc/addressbook.h>
#include <kabc/stdaddressbook.h>
#include <kabc/resource.h>
#ifdef Nepomuk_FOUND
#include <nepomuk/tag.h>
#endif
@ -2103,6 +2106,275 @@ const QString KMFilterActionWithUrl::displayString() const
return label() + " \"" + Qt::escape( argsAsString() ) + "\"";
}
//=============================================================================
// KMFilterActionAddToAddressBook
// - add email address from header to address book
//=============================================================================
class KMFilterActionAddToAddressBook: public KMFilterActionWithStringList
{
public:
KMFilterActionAddToAddressBook();
virtual ReturnCode process( KMMessage* msg ) const;
static KMFilterAction* newAction();
virtual bool isEmpty() const { return false; }
virtual QWidget* createParamWidget( QWidget* parent ) const;
virtual void setParamWidgetValue( QWidget* paramWidget ) const;
virtual void applyParamWidgetValue( QWidget* paramWidget );
virtual void clearParamWidget( QWidget* paramWidget ) const;
virtual const QString argsAsString() const;
virtual void argsFromString( const QString &argsStr );
private:
void updateResourceMaps();
QString mCategory, mResourceName;
QMap<QString, KABC::Resource*> mResourceByName, mResourceByID;
const QString mStdResourceStr, mFromStr, mToStr, mCCStr, mBCCStr;
};
KMFilterAction* KMFilterActionAddToAddressBook::newAction()
{
return ( new KMFilterActionAddToAddressBook );
}
KMFilterActionAddToAddressBook::KMFilterActionAddToAddressBook()
: KMFilterActionWithStringList( "add to address book", i18n( "Add to Address Book" ) ),
mStdResourceStr( i18n( "<placeholder>Default</placeholder>" ) ), mFromStr( i18nc( "Email sender", "From" ) ),
mToStr( i18nc( "Email recipient", "To" ) ), mCCStr( i18n( "CC" ) ), mBCCStr( i18n( "BCC" ) )
{
mParameterList.append( mFromStr );
mParameterList.append( mToStr );
mParameterList.append( mCCStr );
mParameterList.append( mBCCStr );
mParameter = mParameterList.at( 0 );
updateResourceMaps();
mResourceName = mStdResourceStr;
mCategory = i18n( "KMail Filter" );
}
void KMFilterActionAddToAddressBook::updateResourceMaps()
{
//find resources in standard addressbook
//and prepare lookups
mResourceByID.clear();
mResourceByName.clear();
const QList<KABC::Resource*> list = KABC::StdAddressBook::self()->resources();
foreach( KABC::Resource* const res, list ) {
if ( !res->readOnly() && res->isOpen() ) {
mResourceByID.insert( res->identifier(), res );
mResourceByName.insert( res->resourceName(), res );
}
}
}
KMFilterAction::ReturnCode KMFilterActionAddToAddressBook::process( KMMessage* msg ) const
{
QString headerLine;
if ( mParameter == mFromStr )
headerLine = msg->from();
else if ( mParameter == mToStr )
headerLine = msg->to();
else if ( mParameter == mCCStr )
headerLine = msg->cc();
else if ( mParameter == mBCCStr )
headerLine = msg->bcc();
const QStringList emails = KPIMUtils::splitAddressList( headerLine );
KABC::AddressBook *ab = KABC::StdAddressBook::self();
// force a reload of the address book file so that changes that were made
// by other programs are loaded
ab->load();
QString email;
QString name;
QMap<QString, KABC::Resource*>::const_iterator it = mResourceByName.find( mResourceName );
KABC::Resource* res = 0;
//if it==end(), then the resouce has been removed from addressbook
//or default has been selected, in either case store in default resource
if ( it != mResourceByName.end() )
res = it.value();
KABC::Ticket *ticket = ab->requestSaveTicket( res );
if ( ticket ) {
foreach ( const QString singleEmail, emails ) {
KABC::Addressee::parseEmailAddress( singleEmail, name, email );
KABC::Addressee::List addressees = ab->findByEmail( email );
if ( addressees.isEmpty() ) {
KABC::Addressee a;
a.setNameFromString( name );
a.insertEmail( email, true );
if ( !mCategory.isEmpty() )
a.insertCategory( mCategory );
if ( res )
a.setResource( res );
ab->insertAddressee( a );
}
}
if ( !ab->save( ticket ) ) {
ab->error( i18n( "Can't save new addresses to address book." ) );
return ErrorButGoOn;
}
} else {
ab->error( i18n( "Can't save to address book. Address book is locked." ) );
return ErrorButGoOn;
}
return GoOn;
}
QWidget* KMFilterActionAddToAddressBook::createParamWidget( QWidget* parent ) const
{
QWidget *w = new QWidget( parent );
QGridLayout *gridlayout = new QGridLayout ( w );
KComboBox *cb = new KComboBox( w );
cb->setObjectName( "FilterTargetCombo" );
cb->setInsertPolicy( QComboBox::InsertAtBottom );
gridlayout->addWidget( cb, 0, 0, 2, 1, Qt::AlignVCenter );
QLabel *l = new QLabel( i18n( "with category" ), w );
gridlayout->addWidget( l, 0, 1 );
KLineEdit *le = new KLineEdit( w );
le->setObjectName( "ledit" );
gridlayout->addWidget( le, 0, 2 );
l = new QLabel( i18n( "in addressbook" ), w );
gridlayout->addWidget( l, 1, 1 );
KComboBox *cbAdressBook = new KComboBox( w );
cbAdressBook->setObjectName( "AddressBookCombo" );
cbAdressBook->setToolTip( i18n( "<p>This defines the preferred addressbook.<br />"
"If it is not accessible, the filter will fallback to the default addressbook.</p>" ) );
cbAdressBook->setInsertPolicy( QComboBox::InsertAtBottom );
gridlayout->addWidget( cbAdressBook, 1, 2 );
setParamWidgetValue( w );
return w;
}
void KMFilterActionAddToAddressBook::setParamWidgetValue( QWidget* paramWidget ) const
{
KComboBox *cb = paramWidget->findChild<KComboBox*>( "FilterTargetCombo" );
Q_ASSERT( cb );
cb->clear();
cb->addItems( mParameterList );
int idx = mParameterList.indexOf( mParameter );
if ( idx < 0 ) {
kDebug() << "unknown mParameter. strange???";
cb->addItem( mParameter );
cb->setCurrentIndex( cb->count() - 1 );
} else {
cb->setCurrentIndex( idx );
}
KLineEdit *le = paramWidget->findChild<KLineEdit*>( "ledit" );
Q_ASSERT( le );
le->setText( mCategory );
QStringList list = mResourceByName.keys();
idx = list.indexOf( mResourceName );
KComboBox *cbAdressBook = paramWidget->findChild<KComboBox*>( "AddressBookCombo" );
Q_ASSERT( cbAdressBook );
cbAdressBook->clear();
cbAdressBook->addItem( mStdResourceStr );
cbAdressBook->addItems( mResourceByName.keys() );
if ( idx < 0 ) {
cbAdressBook->setCurrentIndex( 0 );
} else {
cbAdressBook->setCurrentIndex( idx + 1 /*mStdResourceStr is not in keys() */ );
}
}
void KMFilterActionAddToAddressBook::applyParamWidgetValue( QWidget* paramWidget )
{
KComboBox *cb = paramWidget->findChild<KComboBox*>( "FilterTargetCombo" );
Q_ASSERT( cb );
mParameter = cb->currentText();
KLineEdit *le = paramWidget->findChild<KLineEdit*>( "ledit" );
Q_ASSERT( le );
mCategory = le->text();
KComboBox *cbAdressBook = paramWidget->findChild<KComboBox*>( "AddressBookCombo" );
Q_ASSERT( cbAdressBook );
mResourceName = cbAdressBook->currentText();
}
void KMFilterActionAddToAddressBook::clearParamWidget( QWidget* paramWidget ) const
{
KComboBox *cb = paramWidget->findChild<KComboBox*>( "FilterTargetCombo" );
Q_ASSERT( cb );
cb->setCurrentItem( 0 );
KLineEdit *le = paramWidget->findChild<KLineEdit*>( "ledit" );
Q_ASSERT( le );
le->setText( mCategory );
KComboBox *cbAdressBook = paramWidget->findChild<KComboBox*>( "AddressBookCombo" );
Q_ASSERT( cbAdressBook );
cbAdressBook->setCurrentItem( 0 );
}
const QString KMFilterActionAddToAddressBook::argsAsString() const
{
QString result;
if ( mParameter == mFromStr )
result = "From";
else if ( mParameter == mToStr )
result = "To";
else if ( mParameter == mCCStr )
result = "CC";
else if ( mParameter == mBCCStr )
result = "BCC";
result += '\t';
QMap<QString, KABC::Resource*>::const_iterator it = mResourceByName.find( mResourceName );
if ( it != mResourceByName.end() )
result += it.value()->identifier();
else
result += mStdResourceStr;
result += '\t';
result += mCategory;
return result;
}
void KMFilterActionAddToAddressBook::argsFromString( const QString &argsStr )
{
updateResourceMaps();
QStringList l = argsStr.split( '\t', QString::KeepEmptyParts );
mParameter = l[0];
if ( l.count() >= 2 ) {
QMap<QString, KABC::Resource*>::iterator it = mResourceByID.find( l[1] );
if ( it != mResourceByID.end() )
mResourceName = it.value()->resourceName();
else
mResourceName = mStdResourceStr;
} else {
mResourceName = mStdResourceStr;
}
if ( l.count() < 3 )
mCategory.clear();
else
mCategory = l[2];
}
//=============================================================================
//
@ -2133,6 +2405,7 @@ void KMFilterActionDict::init(void)
insert( KMFilterActionAddHeader::newAction );
insert( KMFilterActionRewriteHeader::newAction );
insert( KMFilterActionExecSound::newAction );
insert( KMFilterActionAddToAddressBook::newAction );
// Register custom filter actions below this line.
}
// The int in the QDict constructor (41) must be a prime

@ -51,7 +51,6 @@ using KMail::FilterImporterExporter;
#include <QGridLayout>
#include <QLabel>
#include <QListWidget>
#include <QStackedWidget>
#include <QVBoxLayout>
#include <QTreeWidget>
@ -1148,11 +1147,13 @@ KMFilterActionWidget::KMFilterActionWidget( QWidget *parent, const char* name )
int i;
mComboBox = new KComboBox( this );
QWidget *w = new QWidget( this );
gl = new QGridLayout( w );
gl->setContentsMargins( 0, 0, 0, 0 );
mComboBox = new KComboBox( gl );
mComboBox->setEditable( false );
assert( mComboBox );
mWidgetStack = new QStackedWidget(this);
assert( mWidgetStack );
gl->addWidget( mComboBox, 1, 1 );
setSpacing( 4 );
@ -1163,14 +1164,10 @@ KMFilterActionWidget::KMFilterActionWidget( QWidget *parent, const char* name )
KMFilterAction *a = (*it)->create();
// append to the list of actions:
mActionList.append( a );
// add parameter widget to widget stack:
mWidgetStack->insertWidget( i, a->createParamWidget( mWidgetStack ) );
// add (i18n-ized) name to combo box
mComboBox->addItem( (*it)->label );
}
// widget for the case where no action is selected.
mWidgetStack->insertWidget( i,new QLabel( i18n("Please select an action."), mWidgetStack ) );
mWidgetStack->setCurrentIndex(i);
mComboBox->addItem( " " );
mComboBox->setCurrentIndex(i);
@ -1189,8 +1186,26 @@ KMFilterActionWidget::KMFilterActionWidget( QWidget *parent, const char* name )
setFocusProxy( mComboBox );
// now connect the combo box and the widget stack
connect( mComboBox, SIGNAL(activated(int)),
mWidgetStack, SLOT(setCurrentIndex (int)) );
connect( mComboBox, SIGNAL( activated( int ) ),
this, SLOT( slotFilterTypeChanged( int ) ) );
setFilterAction();
}
void KMFilterActionWidget::setFilterAction( QWidget* w )
{
if ( gl->itemAtPosition( 1, 2 ) )
delete gl->itemAtPosition( 1, 2 )->widget();
if ( w )
gl->addWidget( w, 1, 2/*, Qt::AlignTop*/ );
else
gl->addWidget( new QLabel( i18n( "Please select an action." ), this ), 1, 2 );
}
void KMFilterActionWidget::slotFilterTypeChanged( int newIdx )
{
setFilterAction( newIdx < mActionList.count() ? mActionList.at( newIdx )->createParamWidget( this ) : 0 );
}
KMFilterActionWidget::~KMFilterActionWidget()
@ -1206,23 +1221,25 @@ void KMFilterActionWidget::setAction( const KMFilterAction* aAction )
// find the index of typeOf(aAction) in mComboBox
// and clear the other widgets on the way.
for ( int i = 0; i < count ; i++ )
for ( int i = 0; i < count ; i++ ) {
if ( aAction && mComboBox->itemText(i) == label ) {
setFilterAction( mActionList.at( i )->createParamWidget( this ) );
//...set the parameter widget to the settings
// of aAction...
aAction->setParamWidgetValue( mWidgetStack->widget(i) );
aAction->setParamWidgetValue( gl->itemAtPosition( 1, 2 )->widget() );
//...and show the correct entry of
// the combo box
mComboBox->setCurrentIndex(i); // (mm) also raise the widget, but doesn't
mWidgetStack->setCurrentIndex(i);
found = true;
} else // clear the parameter widget
mActionList.at(i)->clearParamWidget( mWidgetStack->widget(i) );
}
}
if ( found ) return;
// not found, so set the empty widget
setFilterAction();
mComboBox->setCurrentIndex( count ); // last item
mWidgetStack->setCurrentIndex( count) ;
}
KMFilterAction * KMFilterActionWidget::action() const
@ -1235,11 +1252,10 @@ KMFilterAction * KMFilterActionWidget::action() const
KMFilterAction *fa = desc->create();
if ( fa ) {
// ...and apply the setting of the parameter widget.
fa->applyParamWidgetValue( mWidgetStack->currentWidget() );
fa->applyParamWidgetValue( gl->itemAtPosition( 1, 2 )->widget() );
return fa;
}
}
return 0;
}

@ -33,12 +33,12 @@
#include <QMap>
#include <QRadioButton>
#include <QString>
#include <QGridLayout>
class KMSearchPatternEdit;
class QLabel;
class QListWidget;
class QPushButton;
class QStackedWidget;
class QCheckBox;
class QTreeWidget;
class KComboBox;
@ -185,18 +185,14 @@ private:
/** This widgets allows to edit a single KMFilterAction (in fact
any derived class that is registered in
KMFilterActionDict). It consists of a combo box which allows to
select the type of actions this widget should act upon and a
QWidgetStack, which holds the parameter widgets for the different
rule types.
select the type of actions this widget should act upon.
You can load a KMFilterAction into this widget with setAction,
and retrieve the result of user action with action.
The widget will copy it's setting into the corresponding
parameter widget. For that, it internally creates an instance of
every KMFilterAction in KMFilterActionDict and asks each
one to create a parameter widget. The parameter widgets are put on
the widget stack and are raised when their corresponding action
type is selected in the combo box.
one to create a parameter widget.
@short A widget to edit a single KMFilterAction.
@author Marc Mutz <Marc@Mutz.com>
@ -221,22 +217,25 @@ public:
/** Retrieve the action. This method is necessary because the type
of actions can change during editing. Therefore the widget
always creates a new action object from the data in the combo
box and the widget stack and returns that. */
box and returns that. */
KMFilterAction *action() const;
private slots:
void slotFilterTypeChanged( int newIdx );
private:
/** This list holds an instance of every KMFilterAction
subclass. The only reason that these 'slave' actions exist is
that they are 'forced' to create parameter widgets for the
widget stack and to clear them on setAction. */
that they are 'forced' to create parameter widgets
and to clear them on setAction. */
QList<KMFilterAction*> mActionList;
/** The combo box that contains the labels of all KMFilterActions.
It's @p activated(int) signal is internally
connected to the @p raiseWidget(int) slot of @p mWidgetStack. */
connected to the @p slotCboAction(int) slot of @p KMFilterActionWidget. */
KComboBox *mComboBox;
/** The widget stack that holds all the parameter widgets for the
filter actions. */
QStackedWidget *mWidgetStack;
void setFilterAction( QWidget* w=0 );
QGridLayout *gl;
};
class KMPopFilterActionWidget : public QGroupBox

Loading…
Cancel
Save