kaddressbook

distributionlisteditor.cpp

00001 /*
00002     This file is part of KAddressBook.
00003     Copyright (c) 2007 Klaralvdalens Datakonsult AB <frank@kdab.net>
00004 
00005     This program is free software; you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018     As a special exception, permission is given to link this program
00019     with any edition of Qt, and distribute the resulting executable,
00020     without including the source code for Qt in the source distribution.
00021 */
00022 
00023 #include "distributionlisteditor.h"
00024 #include "distributionlisteditor_p.h"
00025 
00026 #include <libkdepim/addresseelineedit.h>
00027 #include <libkdepim/distributionlist.h>
00028 #include <libemailfunctions/email.h>
00029 
00030 #include <kabc/addressbook.h>
00031 
00032 #include <kapplication.h>
00033 #include <kdialogbase.h>
00034 #include <kglobal.h>
00035 #include <kiconloader.h>
00036 #include <klineedit.h>
00037 #include <klocale.h>
00038 #include <kmessagebox.h>
00039 
00040 #include <qlabel.h>
00041 #include <qlayout.h>
00042 #include <qsignalmapper.h>
00043 #include <qtoolbutton.h>
00044 #include <qguardedptr.h>
00045 
00046 class KPIM::DistributionListEditor::EditorWidgetPrivate
00047 {
00048 public:
00049     QScrollView* scrollView;
00050     QSignalMapper* mapper;
00051     KABC::AddressBook* addressBook;
00052     QString distListUid;
00053     QLabel* nameLabel;
00054     QLabel* memberListLabel;
00055     KLineEdit* nameLineEdit;
00056     QWidget* memberListWidget;
00057     QVBoxLayout* addresseeLayout;
00058     QValueList<KPIM::DistributionListEditor::Line*> addressees;
00059     QGuardedPtr<KABC::Resource> resource;
00060     KPIM::DistributionList distributionList;
00061     KPIM::DistributionListEditor::Line* addLineForEntry( const KPIM::DistributionList::Entry& entry );
00062     int lastLineId;
00063 };
00064 
00065 
00066 KPIM::DistributionListEditor::Line::Line( KABC::AddressBook* book, QWidget* parent ) : QWidget( parent ), m_addressBook( book )
00067 {
00068     Q_ASSERT( m_addressBook );
00069     QBoxLayout* layout = new QHBoxLayout( this );
00070     layout->setSpacing( KDialog::spacingHint() );
00071     m_lineEdit = new KPIM::DistributionListEditor::LineEdit( this );
00072     connect( m_lineEdit, SIGNAL( textChanged( const QString& ) ),
00073              this, SLOT( textChanged( const QString& ) ) );
00074     layout->addWidget( m_lineEdit );
00075     m_clearButton = new QToolButton( this );
00076     m_clearButton->setIconSet( KApplication::reverseLayout() ? SmallIconSet("locationbar_erase") : SmallIconSet( "clear_left" ) );
00077     m_clearButton->setEnabled( false );
00078     layout->addWidget( m_clearButton );
00079     connect( m_clearButton, SIGNAL( clicked() ), m_lineEdit, SLOT( clear() ) );
00080 }
00081 
00082 void KPIM::DistributionListEditor::Line::textChanged( const QString& text )
00083 {
00084     m_clearButton->setEnabled( !text.isEmpty() );
00085     if ( text.isEmpty() )
00086         emit cleared();
00087     emit textChanged();
00088 }
00089 
00090 void KPIM::DistributionListEditor::Line::setFocusToLineEdit()
00091 {
00092     m_lineEdit->setFocus();
00093 }
00094 
00095 void KPIM::DistributionListEditor::Line::setEntry( const KPIM::DistributionList::Entry& entry )
00096 {
00097     m_uid = entry.addressee.uid();
00098     m_initialText = entry.addressee.fullEmail( entry.email );
00099     m_lineEdit->setText( m_initialText );
00100 }
00101 
00102 KABC::Addressee KPIM::DistributionListEditor::Line::findAddressee( const QString& name, const QString& email ) const
00103 {
00104     if ( name.isEmpty() && email.isEmpty() )
00105         return KABC::Addressee();
00106 
00107     typedef KABC::Addressee::List List;
00108     const List byEmail = m_addressBook->findByEmail( email );
00109     if ( !byEmail.isEmpty() )
00110     {
00111         const List::ConstIterator end = byEmail.end();
00112         for ( List::ConstIterator it = byEmail.begin(); it != end; ++it )
00113         {
00114             if ( (*it).formattedName() == name )
00115                 return *it;
00116         }
00117         return byEmail.first();
00118     }
00119     // no entry found, create new addressee:
00120     KABC::Addressee addressee;
00121     addressee.setUid( KApplication::randomString( 10 ) );
00122     addressee.setFormattedName( name );
00123     addressee.setEmails( email );
00124     m_addressBook->insertAddressee( addressee );
00125     return addressee;
00126 }
00127 
00128 KPIM::DistributionList::Entry KPIM::DistributionListEditor::Line::entry() const
00129 {
00130     const QString text = m_lineEdit->text();
00131     QString name;
00132     QString email;
00133     KPIM::getNameAndMail(m_lineEdit->text(), name, email );
00134 
00135     KPIM::DistributionList::Entry res;
00136     if ( !m_uid.isNull() )
00137     {
00138         const KABC::Addressee addr = m_addressBook->findByUid( m_uid );
00139         if ( m_initialText == text || addr.formattedName() == name )
00140             res.addressee = addr;
00141     }
00142     if ( res.addressee.isEmpty() )
00143         res.addressee = findAddressee( name, email );
00144     res.email = res.addressee.preferredEmail() != email ? email : QString();
00145     return res;
00146 }
00147 
00148 
00149 KPIM::DistributionListEditor::LineEdit::LineEdit( QWidget* parent ) : KPIM::AddresseeLineEdit( parent )
00150 {
00151 }
00152 
00153 
00154 KPIM::DistributionListEditor::EditorWidget::EditorWidget( KABC::AddressBook* book,  QWidget* parent )
00155     : KDialogBase( parent, /*name=*/0, /*modal=*/ true, /*caption=*/QString(), KDialogBase::Ok|KDialogBase::Cancel ), d( new DistributionListEditor::EditorWidgetPrivate )
00156 {
00157     d->addressBook = book;
00158     Q_ASSERT( d->addressBook );
00159     d->lastLineId = 0;
00160     d->mapper = new QSignalMapper( this );
00161     connect( d->mapper, SIGNAL( mapped( int ) ),
00162              this, SLOT( lineTextChanged( int ) ) );
00163     setCaption( i18n( "Edit Distribution List" ) );
00164     QWidget* main = new QWidget( this );
00165     QVBoxLayout* mainLayout = new QVBoxLayout( main );
00166     mainLayout->setMargin( KDialog::marginHint() );
00167     mainLayout->setSpacing( KDialog::spacingHint() );
00168 
00169     QHBoxLayout* nameLayout = new QHBoxLayout;
00170     nameLayout->setSpacing( KDialog::spacingHint() );
00171     d->nameLabel = new QLabel( main );
00172     d->nameLabel->setText( i18n( "Name:" ) );
00173     nameLayout->addWidget( d->nameLabel );
00174 
00175     d->nameLineEdit = new KLineEdit( main );
00176     nameLayout->addWidget( d->nameLineEdit );
00177 
00178     mainLayout->addLayout( nameLayout );
00179     mainLayout->addSpacing( 30 );
00180 
00181     d->memberListLabel = new QLabel( main );
00182     d->memberListLabel->setText( i18n( "Distribution list members:" ) );
00183     mainLayout->addWidget( d->memberListLabel );
00184 
00185     d->scrollView = new QScrollView( main );
00186     d->scrollView->setFrameShape( QFrame::NoFrame );
00187     mainLayout->addWidget( d->scrollView );
00188     d->memberListWidget = new QWidget( d->scrollView->viewport() );
00189     d->memberListWidget->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
00190     QVBoxLayout* memberLayout = new QVBoxLayout( d->memberListWidget );
00191     d->addresseeLayout = new QVBoxLayout;
00192     d->addresseeLayout->setSpacing( KDialog::spacingHint() );
00193     memberLayout->addItem( d->addresseeLayout );
00194     memberLayout->addStretch();
00195     d->scrollView->addChild( d->memberListWidget );
00196     d->scrollView->setResizePolicy( QScrollView::AutoOneFit );
00197 
00198     setMainWidget( main );
00199 
00200     KPIM::DistributionListEditor::Line* const last = d->addLineForEntry( KPIM::DistributionList::Entry() );
00201     const QSize hint = sizeHint();
00202     resize( hint.width() * 1.5, hint.height() );
00203 }
00204 
00205 KPIM::DistributionListEditor::EditorWidget::~EditorWidget()
00206 {
00207     delete d;
00208 }
00209 
00210 void KPIM::DistributionListEditor::EditorWidget::lineTextChanged( int id )
00211 {
00212     if ( id != d->lastLineId )
00213         return;
00214     d->addLineForEntry( KPIM::DistributionList::Entry() );
00215     d->scrollView->updateContents();
00216 }
00217 
00218 void KPIM::DistributionListEditor::EditorWidget::setDistributionList( const KPIM::DistributionList& list )
00219 {
00220     d->distListUid = list.uid();
00221     d->nameLineEdit->setText( list.name() );
00222     d->resource = list.resource();
00223 
00224     using KPIM::DistributionListEditor::Line;
00225     typedef QValueList<Line*>::ConstIterator ListIterator;
00226     for ( ListIterator it = d->addressees.begin(), end = d->addressees.end(); it != end; ++it )
00227     {
00228         delete *it;
00229     }
00230     d->addressees.clear();
00231 
00232     typedef KPIM::DistributionList::Entry Entry;
00233     const Entry::List entries = list.entries( d->addressBook );
00234 
00235     for ( Entry::List::ConstIterator it = entries.begin(), end = entries.end(); it != end; ++it )
00236     {
00237         d->addLineForEntry( *it );
00238     }
00239     KPIM::DistributionListEditor::Line* const last = d->addLineForEntry( Entry() );
00240     last->setFocusToLineEdit();
00241 }
00242 
00243 KPIM::DistributionListEditor::Line* KPIM::DistributionListEditor::EditorWidgetPrivate::addLineForEntry( const KPIM::DistributionList::Entry& entry )
00244 {
00245     KPIM::DistributionListEditor::Line* line = new KPIM::DistributionListEditor::Line( addressBook, memberListWidget );
00246     line->setEntry( entry );
00247     addresseeLayout->addWidget( line );
00248     addressees.append( line );
00249     QObject::connect( line, SIGNAL( textChanged() ),
00250                       mapper, SLOT( map() ) );
00251     mapper->setMapping( line, ++lastLineId );
00252     line->setShown( true );
00253     return line;
00254 }
00255 
00256 void KPIM::DistributionListEditor::EditorWidget::slotOk()
00257 {
00258     const QString name = d->nameLineEdit->text();
00259     const KPIM::DistributionList existing = KPIM::DistributionList::findByName( d->addressBook, name );
00260     if ( !existing.isEmpty() && existing.uid() != d->distListUid )
00261     {
00262         KMessageBox::error( this, i18n( "A distribution list with the name %1 already exists. Please choose another name." ).arg( name ), i18n( "Name in Use" ) );
00263         return;
00264     }
00265 
00266     KPIM::DistributionList list;
00267     list.setUid( d->distListUid.isNull() ? KApplication::randomString( 10 ) :d->distListUid );
00268     list.setName( name );
00269     list.setResource( d->resource );
00270     typedef QValueList<KPIM::DistributionListEditor::Line*>::ConstIterator ListIterator;
00271     for ( ListIterator it = d->addressees.begin(), end = d->addressees.end(); it != end; ++it )
00272     {
00273         const KPIM::DistributionList::Entry entry = (*it)->entry();
00274         if ( entry.addressee.isEmpty() )
00275             continue;
00276         list.insertEntry( entry.addressee, entry.email );
00277     }
00278     d->distributionList = list;
00279     accept();
00280 }
00281 
00282 KPIM::DistributionList KPIM::DistributionListEditor::EditorWidget::distributionList() const
00283 {
00284     return d->distributionList;
00285 }
00286 
00287 #include "distributionlisteditor.moc"
00288 #include "distributionlisteditor_p.moc"