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 
00045 class KPIM::DistributionListEditor::EditorWidgetPrivate
00046 {
00047 public:
00048     QScrollView* scrollView;
00049     QSignalMapper* mapper;
00050     KABC::AddressBook* addressBook;
00051     QString distListUid;
00052     QLabel* nameLabel;
00053     QLabel* memberListLabel;
00054     KLineEdit* nameLineEdit;
00055     QWidget* memberListWidget;
00056     QVBoxLayout* addresseeLayout;
00057     QValueList<KPIM::DistributionListEditor::Line*> addressees;
00058     KPIM::DistributionList distributionList;
00059     KPIM::DistributionListEditor::Line* addLineForEntry( const KPIM::DistributionList::Entry& entry );
00060     int lastLineId;
00061 };
00062 
00063 
00064 KPIM::DistributionListEditor::Line::Line( KABC::AddressBook* book, QWidget* parent ) : QWidget( parent ), m_addressBook( book )
00065 {
00066     Q_ASSERT( m_addressBook );
00067     QBoxLayout* layout = new QHBoxLayout( this );
00068     layout->setSpacing( KDialog::spacingHint() );
00069     m_lineEdit = new KPIM::DistributionListEditor::LineEdit( this );
00070     connect( m_lineEdit, SIGNAL( textChanged( const QString& ) ),
00071              this, SLOT( textChanged( const QString& ) ) );
00072     layout->addWidget( m_lineEdit );
00073     m_clearButton = new QToolButton( this );
00074     m_clearButton->setIconSet( KApplication::reverseLayout() ? SmallIconSet("locationbar_erase") : SmallIconSet( "clear_left" ) );
00075     m_clearButton->setEnabled( false );
00076     layout->addWidget( m_clearButton );
00077     connect( m_clearButton, SIGNAL( clicked() ), m_lineEdit, SLOT( clear() ) );
00078 }
00079 
00080 void KPIM::DistributionListEditor::Line::textChanged( const QString& text )
00081 {
00082     m_clearButton->setEnabled( !text.isEmpty() );
00083     if ( text.isEmpty() )
00084         emit cleared();
00085     emit textChanged();
00086 }
00087 
00088 void KPIM::DistributionListEditor::Line::setFocusToLineEdit()
00089 {
00090     m_lineEdit->setFocus();
00091 }
00092 
00093 void KPIM::DistributionListEditor::Line::setEntry( const KPIM::DistributionList::Entry& entry )
00094 {
00095     m_uid = entry.addressee.uid();
00096     m_initialText = entry.addressee.fullEmail( entry.email );
00097     m_lineEdit->setText( m_initialText ); 
00098 }
00099 
00100 KABC::Addressee KPIM::DistributionListEditor::Line::findAddressee( const QString& name, const QString& email ) const
00101 {
00102     if ( name.isEmpty() && email.isEmpty() )
00103         return KABC::Addressee();
00104 
00105     typedef KABC::Addressee::List List;
00106     const List byEmail = m_addressBook->findByEmail( email );
00107     if ( !byEmail.isEmpty() )
00108     {        
00109         const List::ConstIterator end = byEmail.end();
00110         for ( List::ConstIterator it = byEmail.begin(); it != end; ++it )
00111         {
00112             if ( (*it).formattedName() == name )
00113                 return *it;
00114         }
00115         return byEmail.first();
00116     }
00117     // no entry found, create new addressee:
00118     KABC::Addressee addressee;
00119     addressee.setUid( KApplication::randomString( 10 ) );
00120     addressee.setFormattedName( name );
00121     addressee.setEmails( email );
00122     m_addressBook->insertAddressee( addressee );
00123     return addressee;
00124 }
00125 
00126 KPIM::DistributionList::Entry KPIM::DistributionListEditor::Line::entry() const
00127 {
00128     const QString text = m_lineEdit->text();
00129     QString name;
00130     QString email;
00131     KPIM::getNameAndMail(m_lineEdit->text(), name, email );
00132 
00133     KPIM::DistributionList::Entry res;
00134     if ( !m_uid.isNull() )
00135     {
00136         const KABC::Addressee addr = m_addressBook->findByUid( m_uid );
00137         if ( m_initialText == text || addr.formattedName() == name )
00138             res.addressee = addr;
00139     }
00140     if ( res.addressee.isEmpty() )
00141         res.addressee = findAddressee( name, email ); 
00142     res.email = res.addressee.preferredEmail() != email ? email : QString();
00143     return res;
00144 }
00145 
00146 
00147 KPIM::DistributionListEditor::LineEdit::LineEdit( QWidget* parent ) : KPIM::AddresseeLineEdit( parent )
00148 {
00149 }
00150 
00151 
00152 KPIM::DistributionListEditor::EditorWidget::EditorWidget( KABC::AddressBook* book,  QWidget* parent ) 
00153     : KDialogBase( parent, /*name=*/0, /*modal=*/ true, /*caption=*/QString(), KDialogBase::Ok|KDialogBase::Cancel ), d( new DistributionListEditor::EditorWidgetPrivate )
00154 {
00155     d->addressBook = book;
00156     Q_ASSERT( d->addressBook );
00157     d->lastLineId = 0;
00158     d->mapper = new QSignalMapper( this );
00159     connect( d->mapper, SIGNAL( mapped( int ) ), 
00160              this, SLOT( lineTextChanged( int ) ) ); 
00161     setCaption( i18n( "Edit Distribution List" ) );
00162     QWidget* main = new QWidget( this );
00163     QVBoxLayout* mainLayout = new QVBoxLayout( main );
00164     mainLayout->setMargin( KDialog::marginHint() );
00165     mainLayout->setSpacing( KDialog::spacingHint() );
00166 
00167     QHBoxLayout* nameLayout = new QHBoxLayout;
00168     nameLayout->setSpacing( KDialog::spacingHint() );
00169     d->nameLabel = new QLabel( main );
00170     d->nameLabel->setText( i18n( "Name:" ) );
00171     nameLayout->addWidget( d->nameLabel );
00172 
00173     d->nameLineEdit = new KLineEdit( main );
00174     nameLayout->addWidget( d->nameLineEdit );
00175 
00176     mainLayout->addLayout( nameLayout );
00177     mainLayout->addSpacing( 30 );
00178 
00179     d->memberListLabel = new QLabel( main );
00180     d->memberListLabel->setText( i18n( "Distribution list members:" ) );
00181     mainLayout->addWidget( d->memberListLabel );
00182 
00183     d->scrollView = new QScrollView( main );
00184     d->scrollView->setFrameShape( QFrame::NoFrame );
00185     mainLayout->addWidget( d->scrollView );
00186     d->memberListWidget = new QWidget( d->scrollView->viewport() );
00187     d->memberListWidget->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
00188     QVBoxLayout* memberLayout = new QVBoxLayout( d->memberListWidget );
00189     d->addresseeLayout = new QVBoxLayout;
00190     d->addresseeLayout->setSpacing( KDialog::spacingHint() );
00191     memberLayout->addItem( d->addresseeLayout );
00192     memberLayout->addStretch();
00193     d->scrollView->addChild( d->memberListWidget );
00194     d->scrollView->setResizePolicy( QScrollView::AutoOneFit );
00195     
00196     setMainWidget( main );
00197 
00198     KPIM::DistributionListEditor::Line* const last = d->addLineForEntry( KPIM::DistributionList::Entry() );
00199     const QSize hint = sizeHint();
00200     resize( hint.width() * 1.5, hint.height() );
00201 }
00202 
00203 KPIM::DistributionListEditor::EditorWidget::~EditorWidget()
00204 {
00205     delete d;
00206 }
00207 
00208 void KPIM::DistributionListEditor::EditorWidget::lineTextChanged( int id )
00209 {
00210     if ( id != d->lastLineId )
00211         return;
00212     d->addLineForEntry( KPIM::DistributionList::Entry() );
00213     d->scrollView->updateContents();
00214 }
00215 
00216 void KPIM::DistributionListEditor::EditorWidget::setDistributionList( const KPIM::DistributionList& list )
00217 {
00218     d->distListUid = list.uid();
00219     d->nameLineEdit->setText( list.name() );
00220 
00221     using KPIM::DistributionListEditor::Line;
00222     typedef QValueList<Line*>::ConstIterator ListIterator;
00223     for ( ListIterator it = d->addressees.begin(), end = d->addressees.end(); it != end; ++it )
00224     {
00225         delete *it;
00226     }
00227     d->addressees.clear();
00228 
00229     typedef KPIM::DistributionList::Entry Entry;
00230     const Entry::List entries = list.entries( d->addressBook );
00231 
00232     for ( Entry::List::ConstIterator it = entries.begin(), end = entries.end(); it != end; ++it )
00233     {
00234         d->addLineForEntry( *it );
00235     }
00236     KPIM::DistributionListEditor::Line* const last = d->addLineForEntry( Entry() );
00237     last->setFocusToLineEdit();
00238 }
00239 
00240 KPIM::DistributionListEditor::Line* KPIM::DistributionListEditor::EditorWidgetPrivate::addLineForEntry( const KPIM::DistributionList::Entry& entry )
00241 {  
00242     KPIM::DistributionListEditor::Line* line = new KPIM::DistributionListEditor::Line( addressBook, memberListWidget );
00243     line->setEntry( entry );
00244     addresseeLayout->addWidget( line );
00245     addressees.append( line );
00246     QObject::connect( line, SIGNAL( textChanged() ), 
00247                       mapper, SLOT( map() ) );
00248     mapper->setMapping( line, ++lastLineId );
00249     line->setShown( true );
00250     return line;
00251 }
00252 
00253 void KPIM::DistributionListEditor::EditorWidget::slotOk()
00254 {
00255     const QString name = d->nameLineEdit->text();
00256     const KPIM::DistributionList existing = KPIM::DistributionList::findByName( d->addressBook, name );
00257     if ( !existing.isEmpty() && existing.uid() != d->distListUid )
00258     {
00259         KMessageBox::error( this, i18n( "A distribution list with the name %1 already exists. Please choose another name." ).arg( name ), i18n( "Name in Use" ) ); 
00260         return;
00261     }
00262 
00263     KPIM::DistributionList list;
00264     list.setUid( d->distListUid.isNull() ? KApplication::randomString( 10 ) :d->distListUid );
00265     list.setName( name );
00266     typedef QValueList<KPIM::DistributionListEditor::Line*>::ConstIterator ListIterator;
00267     for ( ListIterator it = d->addressees.begin(), end = d->addressees.end(); it != end; ++it )
00268     { 
00269         const KPIM::DistributionList::Entry entry = (*it)->entry();
00270         if ( entry.addressee.isEmpty() )
00271             continue;
00272         list.insertEntry( entry.addressee, entry.email );
00273     }
00274     d->distributionList = list;
00275     accept();
00276 }
00277 
00278 KPIM::DistributionList KPIM::DistributionListEditor::EditorWidget::distributionList() const
00279 {
00280     return d->distributionList;
00281 }
00282 
00283 #include "distributionlisteditor.moc"
00284 #include "distributionlisteditor_p.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys