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 TQt, and distribute the resulting executable,
00020     without including the source code for TQt in the source distribution.
00021 */
00022 
00023 #include "distributionlisteditor.h"
00024 #include "distributionlisteditor_p.h"
00025 
00026 #include <libtdepim/addresseelineedit.h>
00027 #include <libtdepim/distributionlist.h>
00028 #include <libemailfunctions/email.h>
00029 
00030 #include <tdeabc/addressbook.h>
00031 #include <tdeabc/resource.h>
00032 
00033 #include <tdeapplication.h>
00034 #include <kdialogbase.h>
00035 #include <tdeglobal.h>
00036 #include <kiconloader.h>
00037 #include <klineedit.h>
00038 #include <tdelocale.h>
00039 #include <tdemessagebox.h>
00040 
00041 #include <tqlabel.h>
00042 #include <tqlayout.h>
00043 #include <tqsignalmapper.h>
00044 #include <tqtoolbutton.h>
00045 #include <tqguardedptr.h>
00046 
00047 class KPIM::DistributionListEditor::EditorWidgetPrivate
00048 {
00049 public:
00050     TQScrollView* scrollView;
00051     TQSignalMapper* mapper;
00052     TDEABC::AddressBook* addressBook;
00053     TQString distListUid;
00054     TQLabel* nameLabel;
00055     TQLabel* memberListLabel;
00056     KLineEdit* nameLineEdit;
00057     TQWidget* memberListWidget;
00058     TQVBoxLayout* addresseeLayout;
00059     TQValueList<KPIM::DistributionListEditor::Line*> addressees;
00060     TQGuardedPtr<TDEABC::Resource> resource;
00061     KPIM::DistributionList distributionList;
00062     KPIM::DistributionListEditor::Line* addLineForEntry( const KPIM::DistributionList::Entry& entry );
00063     int lastLineId;
00064 };
00065 
00066 
00067 KPIM::DistributionListEditor::Line::Line( TDEABC::AddressBook* book, TQWidget* parent ) : TQWidget( parent ), m_addressBook( book )
00068 {
00069     Q_ASSERT( m_addressBook );
00070     TQBoxLayout* layout = new TQHBoxLayout( this );
00071     layout->setSpacing( KDialog::spacingHint() );
00072     m_lineEdit = new KPIM::DistributionListEditor::LineEdit( this );
00073     connect( m_lineEdit, TQT_SIGNAL( textChanged( const TQString& ) ),
00074              this, TQT_SLOT( textChanged( const TQString& ) ) );
00075     layout->addWidget( m_lineEdit );
00076     m_clearButton = new TQToolButton( this );
00077     m_clearButton->setIconSet( TDEApplication::reverseLayout() ? SmallIconSet("locationbar_erase") : SmallIconSet( "clear_left" ) );
00078     m_clearButton->setEnabled( false );
00079     layout->addWidget( m_clearButton );
00080     connect( m_clearButton, TQT_SIGNAL( clicked() ), m_lineEdit, TQT_SLOT( clear() ) );
00081 }
00082 
00083 void KPIM::DistributionListEditor::Line::textChanged( const TQString& text )
00084 {
00085     m_clearButton->setEnabled( !text.isEmpty() );
00086     if ( text.isEmpty() )
00087         emit cleared();
00088     emit textChanged();
00089 }
00090 
00091 void KPIM::DistributionListEditor::Line::setFocusToLineEdit()
00092 {
00093     m_lineEdit->setFocus();
00094 }
00095 
00096 void KPIM::DistributionListEditor::Line::setEntry( const KPIM::DistributionList::Entry& entry )
00097 {
00098     m_uid = entry.addressee.uid();
00099     m_initialText = entry.addressee.fullEmail( entry.email );
00100     m_lineEdit->setText( m_initialText );
00101 }
00102 
00103 TDEABC::Addressee KPIM::DistributionListEditor::Line::findAddressee( const TQString& name, const TQString& email ) const
00104 {
00105     if ( name.isEmpty() && email.isEmpty() )
00106         return TDEABC::Addressee();
00107 
00108     typedef TDEABC::Addressee::List List;
00109     const List byEmail = m_addressBook->findByEmail( email );
00110     if ( !byEmail.isEmpty() )
00111     {
00112         const List::ConstIterator end = byEmail.end();
00113         for ( List::ConstIterator it = byEmail.begin(); it != end; ++it )
00114         {
00115             if ( (*it).formattedName() == name )
00116                 return *it;
00117         }
00118         return byEmail.first();
00119     }
00120     // no entry found, create new addressee:
00121     TDEABC::Addressee addressee;
00122     addressee.setUid( TDEApplication::randomString( 10 ) );
00123     addressee.setFormattedName( name );
00124     addressee.setEmails( email );
00125     m_addressBook->insertAddressee( addressee );
00126     return addressee;
00127 }
00128 
00129 KPIM::DistributionList::Entry KPIM::DistributionListEditor::Line::entry() const
00130 {
00131     const TQString text = m_lineEdit->text();
00132     TQString name;
00133     TQString email;
00134     KPIM::getNameAndMail(m_lineEdit->text(), name, email );
00135 
00136     KPIM::DistributionList::Entry res;
00137     if ( !m_uid.isNull() )
00138     {
00139         const TDEABC::Addressee addr = m_addressBook->findByUid( m_uid );
00140         if ( m_initialText == text || addr.formattedName() == name )
00141             res.addressee = addr;
00142     }
00143     if ( res.addressee.isEmpty() )
00144         res.addressee = findAddressee( name, email );
00145     res.email = res.addressee.preferredEmail() != email ? email : TQString();
00146     return res;
00147 }
00148 
00149 
00150 KPIM::DistributionListEditor::LineEdit::LineEdit( TQWidget* parent ) : KPIM::AddresseeLineEdit( parent )
00151 {
00152   allowDistributionLists( false );
00153 }
00154 
00155 
00156 KPIM::DistributionListEditor::EditorWidget::EditorWidget( TDEABC::AddressBook* book,  TQWidget* parent )
00157     : KDialogBase( parent, /*name=*/0, /*modal=*/ true, /*caption=*/TQString(), KDialogBase::Ok|KDialogBase::Cancel ), d( new DistributionListEditor::EditorWidgetPrivate )
00158 {
00159     d->addressBook = book;
00160     Q_ASSERT( d->addressBook );
00161     d->lastLineId = 0;
00162     d->mapper = new TQSignalMapper( TQT_TQOBJECT(this) );
00163     connect( d->mapper, TQT_SIGNAL( mapped( int ) ),
00164              this, TQT_SLOT( lineTextChanged( int ) ) );
00165     setCaption( i18n( "Edit Distribution List" ) );
00166     TQWidget* main = new TQWidget( this );
00167     TQVBoxLayout* mainLayout = new TQVBoxLayout( main );
00168     mainLayout->setMargin( KDialog::marginHint() );
00169     mainLayout->setSpacing( KDialog::spacingHint() );
00170 
00171     TQHBoxLayout* nameLayout = new TQHBoxLayout;
00172     nameLayout->setSpacing( KDialog::spacingHint() );
00173     d->nameLabel = new TQLabel( main );
00174     d->nameLabel->setText( i18n( "Name:" ) );
00175     nameLayout->addWidget( d->nameLabel );
00176 
00177     d->nameLineEdit = new KLineEdit( main );
00178     nameLayout->addWidget( d->nameLineEdit );
00179 
00180     mainLayout->addLayout( nameLayout );
00181     mainLayout->addSpacing( 30 );
00182 
00183     d->memberListLabel = new TQLabel( main );
00184     d->memberListLabel->setText( i18n( "Distribution list members:" ) );
00185     mainLayout->addWidget( d->memberListLabel );
00186 
00187     d->scrollView = new TQScrollView( main );
00188     d->scrollView->setFrameShape( TQFrame::NoFrame );
00189     mainLayout->addWidget( d->scrollView );
00190     d->memberListWidget = new TQWidget( d->scrollView->viewport() );
00191     d->memberListWidget->setSizePolicy( TQSizePolicy::MinimumExpanding, TQSizePolicy::MinimumExpanding );
00192     TQVBoxLayout* memberLayout = new TQVBoxLayout( d->memberListWidget );
00193     d->addresseeLayout = new TQVBoxLayout;
00194     d->addresseeLayout->setSpacing( KDialog::spacingHint() );
00195     memberLayout->addItem( d->addresseeLayout );
00196     memberLayout->addStretch();
00197     d->scrollView->addChild( d->memberListWidget );
00198     d->scrollView->setResizePolicy( TQScrollView::AutoOneFit );
00199 
00200     setMainWidget( main );
00201 
00202     KPIM::DistributionListEditor::Line* const last = d->addLineForEntry( KPIM::DistributionList::Entry() );
00203     const TQSize hint = sizeHint();
00204     resize( hint.width() * 3L/2, hint.height() );
00205 }
00206 
00207 KPIM::DistributionListEditor::EditorWidget::~EditorWidget()
00208 {
00209     delete d;
00210 }
00211 
00212 void KPIM::DistributionListEditor::EditorWidget::lineTextChanged( int id )
00213 {
00214     if ( id != d->lastLineId )
00215         return;
00216     d->addLineForEntry( KPIM::DistributionList::Entry() );
00217     d->scrollView->updateContents();
00218 }
00219 
00220 void KPIM::DistributionListEditor::EditorWidget::setDistributionList( const KPIM::DistributionList& list )
00221 {
00222     d->distListUid = list.uid();
00223     d->nameLineEdit->setText( list.name() );
00224     d->resource = list.resource();
00225 
00226     using KPIM::DistributionListEditor::Line;
00227     typedef TQValueList<Line*>::ConstIterator ListIterator;
00228     for ( ListIterator it = d->addressees.begin(), end = d->addressees.end(); it != end; ++it )
00229     {
00230         delete *it;
00231     }
00232     d->addressees.clear();
00233 
00234     typedef KPIM::DistributionList::Entry Entry;
00235     const Entry::List entries = list.entries( d->addressBook );
00236 
00237     for ( Entry::List::ConstIterator it = entries.begin(), end = entries.end(); it != end; ++it )
00238     {
00239         d->addLineForEntry( *it );
00240     }
00241     KPIM::DistributionListEditor::Line* const last = d->addLineForEntry( Entry() );
00242     last->setFocusToLineEdit();
00243 }
00244 
00245 KPIM::DistributionListEditor::Line* KPIM::DistributionListEditor::EditorWidgetPrivate::addLineForEntry( const KPIM::DistributionList::Entry& entry )
00246 {
00247     KPIM::DistributionListEditor::Line* line = new KPIM::DistributionListEditor::Line( addressBook, memberListWidget );
00248     line->setEntry( entry );
00249     addresseeLayout->addWidget( line );
00250     addressees.append( line );
00251     TQObject::connect( line, TQT_SIGNAL( textChanged() ),
00252                       mapper, TQT_SLOT( map() ) );
00253     mapper->setMapping( TQT_TQOBJECT(line), ++lastLineId );
00254     line->setShown( true );
00255     return line;
00256 }
00257 
00258 void KPIM::DistributionListEditor::EditorWidget::slotOk()
00259 {
00260     const TQString name = d->nameLineEdit->text();
00261     const KPIM::DistributionList existing = KPIM::DistributionList::findByName( d->addressBook, name );
00262     if ( !existing.isEmpty() && existing.uid() != d->distListUid )
00263     {
00264         KMessageBox::error( this, i18n( "A distribution list with the name %1 already exists. Please choose another name." ).arg( name ), i18n( "Name in Use" ) );
00265         return;
00266     }
00267 
00268     TDEABC::Ticket *ticket = d->resource->requestSaveTicket();
00269     if ( !ticket ) {
00270         kdWarning(5720) << "Unable to get save ticket!" << endl;
00271         return;
00272     }
00273 
00274     KPIM::DistributionList list;
00275     list.setUid( d->distListUid.isNull() ? TDEApplication::randomString( 10 ) :d->distListUid );
00276     list.setName( name );
00277     list.setResource( d->resource );
00278     typedef TQValueList<KPIM::DistributionListEditor::Line*>::ConstIterator ListIterator;
00279     for ( ListIterator it = d->addressees.begin(), end = d->addressees.end(); it != end; ++it )
00280     {
00281         const KPIM::DistributionList::Entry entry = (*it)->entry();
00282         if ( entry.addressee.isEmpty() )
00283             continue;
00284         list.insertEntry( entry.addressee, entry.email );
00285     }
00286     d->distributionList = list;
00287 
00288     d->addressBook->insertAddressee( d->distributionList );
00289     if ( !d->resource->save( ticket ) ) {
00290         kdWarning(5720) << "Unable to save dist list!" << endl;
00291     }
00292     d->resource->releaseSaveTicket( ticket );
00293 
00294     if ( !KPIM::DistributionList::findByName( d->addressBook, name ).isEmpty() ) {
00295         accept();
00296     }
00297 }
00298 
00299 KPIM::DistributionList KPIM::DistributionListEditor::EditorWidget::distributionList() const
00300 {
00301     return d->distributionList;
00302 }
00303 
00304 #include "distributionlisteditor.moc"
00305 #include "distributionlisteditor_p.moc"