00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "recipientseditor.h"
00026
00027 #include "recipientspicker.h"
00028 #include "kwindowpositioner.h"
00029 #include "distributionlistdialog.h"
00030 #include "globalsettings.h"
00031
00032 #include <libemailfunctions/email.h>
00033
00034 #include <kapplication.h>
00035 #include <kcompletionbox.h>
00036 #include <kdebug.h>
00037 #include <kinputdialog.h>
00038 #include <klocale.h>
00039 #include <kiconloader.h>
00040 #include <kmessagebox.h>
00041
00042 #include <qlayout.h>
00043 #include <qlabel.h>
00044 #include <qscrollview.h>
00045 #include <qcombobox.h>
00046 #include <qhbox.h>
00047 #include <qtimer.h>
00048 #include <qpushbutton.h>
00049 #include <qstylesheet.h>
00050
00051 Recipient::Recipient( const QString &email, Recipient::Type type )
00052 : mEmail( email ), mType( type )
00053 {
00054 }
00055
00056 void Recipient::setType( Type type )
00057 {
00058 mType = type;
00059 }
00060
00061 Recipient::Type Recipient::type() const
00062 {
00063 return mType;
00064 }
00065
00066 void Recipient::setEmail( const QString &email )
00067 {
00068 mEmail = email;
00069 }
00070
00071 QString Recipient::email() const
00072 {
00073 return mEmail;
00074 }
00075
00076 bool Recipient::isEmpty() const
00077 {
00078 return mEmail.isEmpty();
00079 }
00080
00081 int Recipient::typeToId( Recipient::Type type )
00082 {
00083 return static_cast<int>( type );
00084 }
00085
00086 Recipient::Type Recipient::idToType( int id )
00087 {
00088 return static_cast<Type>( id );
00089 }
00090
00091 QString Recipient::typeLabel() const
00092 {
00093 return typeLabel( mType );
00094 }
00095
00096 QString Recipient::typeLabel( Recipient::Type type )
00097 {
00098 switch( type ) {
00099 case To:
00100 return i18n("To");
00101 case Cc:
00102 return i18n("CC");
00103 case Bcc:
00104 return i18n("BCC");
00105 case Undefined:
00106 break;
00107 }
00108
00109 return i18n("<Undefined RecipientType>");
00110 }
00111
00112 QStringList Recipient::allTypeLabels()
00113 {
00114 QStringList types;
00115 types.append( typeLabel( To ) );
00116 types.append( typeLabel( Cc ) );
00117 types.append( typeLabel( Bcc ) );
00118 return types;
00119 }
00120
00121
00122 RecipientComboBox::RecipientComboBox( QWidget *parent )
00123 : QComboBox( parent )
00124 {
00125 }
00126
00127 void RecipientComboBox::keyPressEvent( QKeyEvent *ev )
00128 {
00129 if ( ev->key() == Key_Right ) emit rightPressed();
00130 else QComboBox::keyPressEvent( ev );
00131 }
00132
00133
00134 void RecipientLineEdit::keyPressEvent( QKeyEvent *ev )
00135 {
00136 if ( ev->key() == Key_Backspace && text().isEmpty() ) {
00137 ev->accept();
00138 emit deleteMe();
00139 } else if ( ev->key() == Key_Left && cursorPosition() == 0 ) {
00140 emit leftPressed();
00141 } else if ( ev->key() == Key_Right && cursorPosition() == (int)text().length() ) {
00142 emit rightPressed();
00143 } else {
00144 KMLineEdit::keyPressEvent( ev );
00145 }
00146 }
00147
00148 RecipientLine::RecipientLine( QWidget *parent )
00149 : QWidget( parent ), mRecipientsCount( 0 ), mModified( false )
00150 {
00151 QBoxLayout *topLayout = new QHBoxLayout( this );
00152 topLayout->setSpacing( KDialog::spacingHint() );
00153
00154 QStringList recipientTypes = Recipient::allTypeLabels();
00155
00156 mCombo = new RecipientComboBox( this );
00157 mCombo->insertStringList( recipientTypes );
00158 topLayout->addWidget( mCombo );
00159 QToolTip::add( mCombo, i18n("Select type of recipient") );
00160
00161 mEdit = new RecipientLineEdit( this );
00162 topLayout->addWidget( mEdit );
00163 connect( mEdit, SIGNAL( returnPressed() ), SLOT( slotReturnPressed() ) );
00164 connect( mEdit, SIGNAL( deleteMe() ), SLOT( slotPropagateDeletion() ) );
00165 connect( mEdit, SIGNAL( textChanged( const QString & ) ),
00166 SLOT( analyzeLine( const QString & ) ) );
00167 connect( mEdit, SIGNAL( focusUp() ), SLOT( slotFocusUp() ) );
00168 connect( mEdit, SIGNAL( focusDown() ), SLOT( slotFocusDown() ) );
00169 connect( mEdit, SIGNAL( rightPressed() ), SIGNAL( rightPressed() ) );
00170
00171 connect( mEdit, SIGNAL( leftPressed() ), mCombo, SLOT( setFocus() ) );
00172 connect( mCombo, SIGNAL( rightPressed() ), mEdit, SLOT( setFocus() ) );
00173
00174 connect( mCombo, SIGNAL( activated ( int ) ),
00175 this, SLOT( slotTypeModified() ) );
00176
00177 mRemoveButton = new QPushButton( this );
00178 mRemoveButton->setIconSet( KApplication::reverseLayout() ? SmallIconSet("locationbar_erase") : SmallIconSet( "clear_left" ) );
00179 topLayout->addWidget( mRemoveButton );
00180 connect( mRemoveButton, SIGNAL( clicked() ), SLOT( slotPropagateDeletion() ) );
00181 QToolTip::add( mRemoveButton, i18n("Remove recipient line") );
00182 }
00183
00184 void RecipientLine::slotFocusUp()
00185 {
00186 emit upPressed( this );
00187 }
00188
00189 void RecipientLine::slotFocusDown()
00190 {
00191 emit downPressed( this );
00192 }
00193
00194 void RecipientLine::slotTypeModified()
00195 {
00196 mModified = true;
00197
00198 emit typeModified( this );
00199 }
00200
00201 void RecipientLine::analyzeLine( const QString &text )
00202 {
00203 QStringList r = KPIM::splitEmailAddrList( text );
00204 if ( int( r.count() ) != mRecipientsCount ) {
00205 mRecipientsCount = r.count();
00206 emit countChanged();
00207 }
00208 }
00209
00210 int RecipientLine::recipientsCount()
00211 {
00212 return mRecipientsCount;
00213 }
00214
00215 void RecipientLine::setRecipient( const Recipient &rec )
00216 {
00217 mEdit->setText( rec.email() );
00218 mCombo->setCurrentItem( Recipient::typeToId( rec.type() ) );
00219 }
00220
00221 void RecipientLine::setRecipient( const QString &email )
00222 {
00223 setRecipient( Recipient( email ) );
00224 }
00225
00226 Recipient RecipientLine::recipient() const
00227 {
00228 return Recipient( mEdit->text(),
00229 Recipient::idToType( mCombo->currentItem() ) );
00230 }
00231
00232 void RecipientLine::setRecipientType( Recipient::Type type )
00233 {
00234 mCombo->setCurrentItem( Recipient::typeToId( type ) );
00235 }
00236
00237 Recipient::Type RecipientLine::recipientType() const
00238 {
00239 return Recipient::idToType( mCombo->currentItem() );
00240 }
00241
00242 void RecipientLine::activate()
00243 {
00244 mEdit->setFocus();
00245 }
00246
00247 bool RecipientLine::isActive()
00248 {
00249 return mEdit->hasFocus();
00250 }
00251
00252 bool RecipientLine::isEmpty()
00253 {
00254 return mEdit->text().isEmpty();
00255 }
00256
00257 bool RecipientLine::isModified()
00258 {
00259 return mModified || mEdit->isModified();
00260 }
00261
00262 void RecipientLine::clearModified()
00263 {
00264 mModified = false;
00265 mEdit->clearModified();
00266 }
00267
00268 void RecipientLine::slotReturnPressed()
00269 {
00270 emit returnPressed( this );
00271 }
00272
00273 void RecipientLine::slotPropagateDeletion()
00274 {
00275 emit deleteLine( this );
00276 }
00277
00278 void RecipientLine::keyPressEvent( QKeyEvent *ev )
00279 {
00280 if ( ev->key() == Key_Up ) {
00281 emit upPressed( this );
00282 } else if ( ev->key() == Key_Down ) {
00283 emit downPressed( this );
00284 }
00285 }
00286
00287 int RecipientLine::setComboWidth( int w )
00288 {
00289 w = QMAX( w, mCombo->sizeHint().width() );
00290 mCombo->setFixedWidth( w );
00291 mCombo->updateGeometry();
00292 parentWidget()->updateGeometry();
00293 return w;
00294 }
00295
00296 void RecipientLine::fixTabOrder( QWidget *previous )
00297 {
00298 setTabOrder( previous, mCombo );
00299 setTabOrder( mCombo, mEdit );
00300 setTabOrder( mEdit, mRemoveButton );
00301 }
00302
00303 QWidget *RecipientLine::tabOut() const
00304 {
00305 return mRemoveButton;
00306 }
00307
00308 void RecipientLine::clear()
00309 {
00310 mEdit->clear();
00311 }
00312
00313 void RecipientLine::setRemoveLineButtonEnabled( bool b )
00314 {
00315 mRemoveButton->setEnabled( b );
00316 }
00317
00318
00319
00320
00321 RecipientsView::RecipientsView( QWidget *parent )
00322 : QScrollView( parent ), mCurDelLine( 0 ),
00323 mLineHeight( 0 ), mFirstColumnWidth( 0 ),
00324 mModified( false )
00325 {
00326 mCompletionMode = KGlobalSettings::completionMode();
00327 setHScrollBarMode( AlwaysOff );
00328 setLineWidth( 0 );
00329
00330 addLine();
00331 setResizePolicy( QScrollView::Manual );
00332 setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
00333
00334 viewport()->setPaletteBackgroundColor( paletteBackgroundColor() );
00335 }
00336
00337 RecipientLine *RecipientsView::activeLine()
00338 {
00339 return mLines.last();
00340 }
00341
00342 RecipientLine *RecipientsView::emptyLine()
00343 {
00344 RecipientLine *line;
00345 for( line = mLines.first(); line; line = mLines.next() ) {
00346 if ( line->isEmpty() ) return line;
00347 }
00348
00349 return 0;
00350 }
00351
00352 RecipientLine *RecipientsView::addLine()
00353 {
00354 RecipientLine *line = new RecipientLine( viewport() );
00355 addChild( line, 0, mLines.count() * mLineHeight );
00356 line->mEdit->setCompletionMode( mCompletionMode );
00357 line->show();
00358 connect( line, SIGNAL( returnPressed( RecipientLine * ) ),
00359 SLOT( slotReturnPressed( RecipientLine * ) ) );
00360 connect( line, SIGNAL( upPressed( RecipientLine * ) ),
00361 SLOT( slotUpPressed( RecipientLine * ) ) );
00362 connect( line, SIGNAL( downPressed( RecipientLine * ) ),
00363 SLOT( slotDownPressed( RecipientLine * ) ) );
00364 connect( line, SIGNAL( rightPressed() ), SIGNAL( focusRight() ) );
00365 connect( line, SIGNAL( deleteLine( RecipientLine * ) ),
00366 SLOT( slotDecideLineDeletion( RecipientLine * ) ) );
00367 connect( line, SIGNAL( countChanged() ), SLOT( calculateTotal() ) );
00368 connect( line, SIGNAL( typeModified( RecipientLine * ) ),
00369 SLOT( slotTypeModified( RecipientLine * ) ) );
00370 connect( line->mEdit, SIGNAL( completionModeChanged( KGlobalSettings::Completion ) ),
00371 SLOT( setCompletionMode( KGlobalSettings::Completion ) ) );
00372
00373 if ( mLines.last() ) {
00374 if ( mLines.count() == 1 ) {
00375 if ( GlobalSettings::self()->secondRecipientTypeDefault() ==
00376 GlobalSettings::EnumSecondRecipientTypeDefault::To ) {
00377 line->setRecipientType( Recipient::To );
00378 } else {
00379 if ( mLines.last()->recipientType() == Recipient::Bcc ) {
00380 line->setRecipientType( Recipient::To );
00381 } else {
00382 line->setRecipientType( Recipient::Cc );
00383 }
00384 }
00385 } else {
00386 line->setRecipientType( mLines.last()->recipientType() );
00387 }
00388 line->fixTabOrder( mLines.last()->tabOut() );
00389 }
00390
00391 mLines.append( line );
00392
00393 if ( mLines.count() == 1 ) {
00394 mLines.first()->setRemoveLineButtonEnabled( false );
00395 } else {
00396 mLines.first()->setRemoveLineButtonEnabled( true );
00397 }
00398
00399 mFirstColumnWidth = line->setComboWidth( mFirstColumnWidth );
00400
00401 mLineHeight = line->minimumSizeHint().height();
00402
00403 line->resize( viewport()->width(), mLineHeight );
00404
00405 resizeView();
00406
00407 calculateTotal();
00408
00409 ensureVisible( 0, mLines.count() * mLineHeight );
00410
00411 return line;
00412 }
00413
00414 void RecipientsView::slotTypeModified( RecipientLine *line )
00415 {
00416 if ( mLines.count() == 2 ||
00417 ( mLines.count() == 3 && mLines.at( 2 )->isEmpty() ) ) {
00418 if ( mLines.at( 1 ) == line ) {
00419 if ( line->recipientType() == Recipient::To ) {
00420 GlobalSettings::self()->setSecondRecipientTypeDefault(
00421 GlobalSettings::EnumSecondRecipientTypeDefault::To );
00422 } else if ( line->recipientType() == Recipient::Cc ) {
00423 GlobalSettings::self()->setSecondRecipientTypeDefault(
00424 GlobalSettings::EnumSecondRecipientTypeDefault::Cc );
00425 }
00426 }
00427 }
00428 }
00429
00430 void RecipientsView::calculateTotal()
00431 {
00432 int count = 0;
00433 int empty = 0;
00434
00435 RecipientLine *line;
00436 for( line = mLines.first(); line; line = mLines.next() ) {
00437 if ( line->isEmpty() ) ++empty;
00438 else count += line->recipientsCount();
00439 }
00440
00441 if ( empty == 0 ) addLine();
00442
00443 emit totalChanged( count, mLines.count() );
00444 }
00445
00446 void RecipientsView::slotReturnPressed( RecipientLine *line )
00447 {
00448 if ( !line->recipient().isEmpty() ) {
00449 RecipientLine *empty = emptyLine();
00450 if ( !empty ) empty = addLine();
00451 activateLine( empty );
00452 }
00453 }
00454
00455 void RecipientsView::slotDownPressed( RecipientLine *line )
00456 {
00457 int pos = mLines.find( line );
00458 if ( pos >= (int)mLines.count() - 1 ) {
00459 emit focusDown();
00460 } else if ( pos >= 0 ) {
00461 activateLine( mLines.at( pos + 1 ) );
00462 }
00463 }
00464
00465 void RecipientsView::slotUpPressed( RecipientLine *line )
00466 {
00467 int pos = mLines.find( line );
00468 if ( pos > 0 ) {
00469 activateLine( mLines.at( pos - 1 ) );
00470 } else {
00471 emit focusUp();
00472 }
00473 }
00474
00475 void RecipientsView::slotDecideLineDeletion( RecipientLine *line )
00476 {
00477 if ( !line->isEmpty() )
00478 mModified = true;
00479 if ( mLines.count() == 1 ) {
00480 line->clear();
00481 } else {
00482 mCurDelLine = line;
00483 QTimer::singleShot( 0, this, SLOT( slotDeleteLine( ) ) );
00484 }
00485 }
00486
00487 void RecipientsView::slotDeleteLine()
00488 {
00489 if ( !mCurDelLine )
00490 return;
00491
00492 RecipientLine *line = mCurDelLine;
00493 int pos = mLines.find( line );
00494
00495 int newPos;
00496 if ( pos == 0 ) newPos = pos + 1;
00497 else newPos = pos - 1;
00498
00499
00500 if ( mLines.at( newPos ) )
00501 mLines.at( newPos )->activate();
00502
00503 mLines.remove( line );
00504 removeChild( line );
00505 delete line;
00506
00507 bool atLeastOneToLine = false;
00508 unsigned int firstCC = 0;
00509 for( uint i = pos; i < mLines.count(); ++i ) {
00510 RecipientLine *line = mLines.at( i );
00511 moveChild( line, childX( line ), childY( line ) - mLineHeight );
00512 if ( line->recipientType() == Recipient::To )
00513 atLeastOneToLine = true;
00514 else if ( ( line->recipientType() == Recipient::Cc ) && ( i == 0 ) )
00515 firstCC = i;
00516 }
00517
00518 if ( mLines.count() == 1 )
00519 mLines.first()->setRemoveLineButtonEnabled( false );
00520
00521 if ( !atLeastOneToLine )
00522 mLines.at( firstCC )->setRecipientType( Recipient::To );
00523
00524 calculateTotal();
00525
00526 resizeView();
00527 }
00528
00529 void RecipientsView::resizeView()
00530 {
00531 resizeContents( width(), mLines.count() * mLineHeight );
00532
00533 if ( mLines.count() < 6 ) {
00534
00535 }
00536
00537 parentWidget()->layout()->activate();
00538 emit sizeHintChanged();
00539 QTimer::singleShot( 0, this, SLOT(moveCompletionPopup()) );
00540 }
00541
00542 void RecipientsView::activateLine( RecipientLine *line )
00543 {
00544 line->activate();
00545 ensureVisible( 0, childY( line ) );
00546 }
00547
00548 void RecipientsView::viewportResizeEvent ( QResizeEvent *ev )
00549 {
00550 for( uint i = 0; i < mLines.count(); ++i ) {
00551 mLines.at( i )->resize( ev->size().width(), mLineHeight );
00552 }
00553 ensureVisible( 0, mLines.count() * mLineHeight );
00554 }
00555
00556 QSize RecipientsView::sizeHint() const
00557 {
00558 return QSize( 200, mLineHeight * mLines.count() );
00559 }
00560
00561 QSize RecipientsView::minimumSizeHint() const
00562 {
00563 int height;
00564 uint numLines = 5;
00565 if ( mLines.count() < numLines ) height = mLineHeight * mLines.count();
00566 else height = mLineHeight * numLines;
00567 return QSize( 200, height );
00568 }
00569
00570 Recipient::List RecipientsView::recipients() const
00571 {
00572 Recipient::List recipients;
00573
00574 QPtrListIterator<RecipientLine> it( mLines );
00575 RecipientLine *line;
00576 while( ( line = it.current() ) ) {
00577 if ( !line->recipient().isEmpty() ) {
00578 recipients.append( line->recipient() );
00579 }
00580
00581 ++it;
00582 }
00583
00584 return recipients;
00585 }
00586
00587 void RecipientsView::setCompletionMode ( KGlobalSettings::Completion mode )
00588 {
00589 if ( mCompletionMode == mode )
00590 return;
00591 mCompletionMode = mode;
00592
00593 QPtrListIterator<RecipientLine> it( mLines );
00594 RecipientLine *line;
00595 while( ( line = it.current() ) ) {
00596 line->mEdit->blockSignals( true );
00597 line->mEdit->setCompletionMode( mode );
00598 line->mEdit->blockSignals( false );
00599 ++it;
00600 }
00601 emit completionModeChanged( mode );
00602 }
00603
00604 void RecipientsView::removeRecipient( const QString & recipient,
00605 Recipient::Type type )
00606 {
00607
00608 QPtrListIterator<RecipientLine> it( mLines );
00609 RecipientLine *line;
00610 while( ( line = it.current() ) ) {
00611 if ( ( line->recipient().email() == recipient ) &&
00612 ( line->recipientType() == type ) ) {
00613 break;
00614 }
00615 ++it;
00616 }
00617 if ( line )
00618 line->slotPropagateDeletion();
00619 }
00620
00621 bool RecipientsView::isModified()
00622 {
00623 if ( mModified )
00624 return true;
00625
00626 QPtrListIterator<RecipientLine> it( mLines );
00627 RecipientLine *line;
00628 while( ( line = it.current() ) ) {
00629 if ( line->isModified() ) {
00630 return true;
00631 }
00632 ++it;
00633 }
00634
00635 return false;
00636 }
00637
00638 void RecipientsView::clearModified()
00639 {
00640 mModified = false;
00641
00642 QPtrListIterator<RecipientLine> it( mLines );
00643 RecipientLine *line;
00644 while( ( line = it.current() ) ) {
00645 line->clearModified();
00646 ++it;
00647 }
00648 }
00649
00650 void RecipientsView::setFocus()
00651 {
00652 if ( mLines.last()->isActive() ) setFocusBottom();
00653 else setFocusTop();
00654 }
00655
00656 void RecipientsView::setFocusTop()
00657 {
00658 RecipientLine *line = mLines.first();
00659 if ( line ) line->activate();
00660 else kdWarning() << "No first" << endl;
00661 }
00662
00663 void RecipientsView::setFocusBottom()
00664 {
00665 RecipientLine *line = mLines.last();
00666 if ( line ) line->activate();
00667 else kdWarning() << "No last" << endl;
00668 }
00669
00670 int RecipientsView::setFirstColumnWidth( int w )
00671 {
00672 mFirstColumnWidth = w;
00673
00674 QPtrListIterator<RecipientLine> it( mLines );
00675 RecipientLine *line;
00676 while( ( line = it.current() ) ) {
00677 mFirstColumnWidth = line->setComboWidth( mFirstColumnWidth );
00678 ++it;
00679 }
00680
00681 resizeView();
00682 return mFirstColumnWidth;
00683 }
00684
00685 void RecipientsView::moveCompletionPopup()
00686 {
00687 for( RecipientLine* line = mLines.first(); line; line = mLines.next() ) {
00688 if ( line->lineEdit()->completionBox( false ) ) {
00689 if ( line->lineEdit()->completionBox()->isVisible() ) {
00690
00691 line->lineEdit()->completionBox()->hide();
00692 line->lineEdit()->completionBox()->show();
00693 }
00694 }
00695 }
00696
00697 }
00698
00699 RecipientsToolTip::RecipientsToolTip( RecipientsView *view, QWidget *parent )
00700 : QToolTip( parent ), mView( view )
00701 {
00702 }
00703
00704 QString RecipientsToolTip::line( const Recipient &r )
00705 {
00706 QString txt = r.email();
00707
00708 return " " + QStyleSheet::escape( txt ) + "<br/>";
00709 }
00710
00711 void RecipientsToolTip::maybeTip( const QPoint & p )
00712 {
00713 QString text = "<qt>";
00714
00715 QString to;
00716 QString cc;
00717 QString bcc;
00718
00719 Recipient::List recipients = mView->recipients();
00720 Recipient::List::ConstIterator it;
00721 for( it = recipients.begin(); it != recipients.end(); ++it ) {
00722 switch( (*it).type() ) {
00723 case Recipient::To:
00724 to += line( *it );
00725 break;
00726 case Recipient::Cc:
00727 cc += line( *it );
00728 break;
00729 case Recipient::Bcc:
00730 bcc += line( *it );
00731 break;
00732 default:
00733 break;
00734 }
00735 }
00736
00737 text += i18n("<b>To:</b><br/>") + to;
00738 if ( !cc.isEmpty() ) text += i18n("<b>CC:</b><br/>") + cc;
00739 if ( !bcc.isEmpty() ) text += i18n("<b>BCC:</b><br/>") + bcc;
00740
00741 text.append( "</qt>" );
00742
00743 QRect geometry( p + QPoint( 2, 2 ), QPoint( 400, 100 ) );
00744
00745 tip( QRect( p.x() - 20, p.y() - 20, 40, 40 ), text, geometry );
00746 }
00747
00748
00749 SideWidget::SideWidget( RecipientsView *view, QWidget *parent )
00750 : QWidget( parent ), mView( view ), mRecipientPicker( 0 )
00751 {
00752 QBoxLayout *topLayout = new QVBoxLayout( this );
00753
00754 topLayout->setSpacing( KDialog::spacingHint() );
00755 topLayout->addStretch( 1 );
00756
00757 mTotalLabel = new QLabel( this );
00758 mTotalLabel->setAlignment( AlignCenter );
00759 topLayout->addWidget( mTotalLabel );
00760 mTotalLabel->hide();
00761
00762 topLayout->addStretch( 1 );
00763
00764 new RecipientsToolTip( view, mTotalLabel );
00765
00766 mDistributionListButton = new QPushButton( i18n("Save List..."), this );
00767 topLayout->addWidget( mDistributionListButton );
00768 mDistributionListButton->hide();
00769 connect( mDistributionListButton, SIGNAL( clicked() ),
00770 SIGNAL( saveDistributionList() ) );
00771 QToolTip::add( mDistributionListButton,
00772 i18n("Save recipients as distribution list") );
00773
00774 mSelectButton = new QPushButton( i18n("Se&lect..."), this );
00775 topLayout->addWidget( mSelectButton );
00776 connect( mSelectButton, SIGNAL( clicked() ), SLOT( pickRecipient() ) );
00777 QToolTip::add( mSelectButton, i18n("Select recipients from address book") );
00778 }
00779
00780 SideWidget::~SideWidget()
00781 {
00782 }
00783
00784 RecipientsPicker* SideWidget::picker() const
00785 {
00786 if ( !mRecipientPicker ) {
00787
00788 SideWidget *non_const_this = const_cast<SideWidget*>( this );
00789 mRecipientPicker = new RecipientsPicker( non_const_this );
00790 connect( mRecipientPicker, SIGNAL( pickedRecipient( const Recipient & ) ),
00791 non_const_this, SIGNAL( pickedRecipient( const Recipient & ) ) );
00792 mPickerPositioner = new KWindowPositioner( non_const_this, mRecipientPicker );
00793 }
00794 return mRecipientPicker;
00795 }
00796
00797 void SideWidget::setFocus()
00798 {
00799 mSelectButton->setFocus();
00800 }
00801
00802 void SideWidget::setTotal( int recipients, int lines )
00803 {
00804 #if 0
00805 kdDebug() << "SideWidget::setTotal() recipients: " << recipients <<
00806 " lines: " << lines << endl;
00807 #endif
00808
00809 QString labelText;
00810 if ( recipients == 0 ) labelText = i18n("No recipients");
00811 else labelText = i18n("1 recipient","%n recipients", recipients );
00812 mTotalLabel->setText( labelText );
00813
00814 if ( lines > 3 ) mTotalLabel->show();
00815 else mTotalLabel->hide();
00816
00817 if ( lines > 2 ) mDistributionListButton->show();
00818 else mDistributionListButton->hide();
00819 }
00820
00821 void SideWidget::pickRecipient()
00822 {
00823 #if 0
00824 QString rec = KInputDialog::getText( "Pick Recipient",
00825 "Email address of recipient" );
00826 if ( !rec.isEmpty() ) emit pickedRecipient( rec );
00827 #else
00828 RecipientsPicker *p = picker();
00829 p->setDefaultType( mView->activeLine()->recipientType() );
00830 p->setRecipients( mView->recipients() );
00831 p->show();
00832 mPickerPositioner->reposition();
00833 p->raise();
00834 #endif
00835 }
00836
00837
00838 RecipientsEditor::RecipientsEditor( QWidget *parent )
00839 : QWidget( parent ), mModified( false )
00840 {
00841 QBoxLayout *topLayout = new QHBoxLayout( this );
00842 topLayout->setSpacing( KDialog::spacingHint() );
00843
00844 mRecipientsView = new RecipientsView( this );
00845 topLayout->addWidget( mRecipientsView );
00846 connect( mRecipientsView, SIGNAL( focusUp() ), SIGNAL( focusUp() ) );
00847 connect( mRecipientsView, SIGNAL( focusDown() ), SIGNAL( focusDown() ) );
00848 connect( mRecipientsView, SIGNAL( completionModeChanged( KGlobalSettings::Completion ) ),
00849 SIGNAL( completionModeChanged( KGlobalSettings::Completion ) ) );
00850
00851 mSideWidget = new SideWidget( mRecipientsView, this );
00852 topLayout->addWidget( mSideWidget );
00853 connect( mSideWidget, SIGNAL( pickedRecipient( const Recipient & ) ),
00854 SLOT( slotPickedRecipient( const Recipient & ) ) );
00855 connect( mSideWidget, SIGNAL( saveDistributionList() ),
00856 SLOT( saveDistributionList() ) );
00857
00858 connect( mRecipientsView, SIGNAL( totalChanged( int, int ) ),
00859 mSideWidget, SLOT( setTotal( int, int ) ) );
00860 connect( mRecipientsView, SIGNAL( focusRight() ),
00861 mSideWidget, SLOT( setFocus() ) );
00862
00863 connect( mRecipientsView, SIGNAL(sizeHintChanged()),
00864 SIGNAL(sizeHintChanged()) );
00865 }
00866
00867 RecipientsEditor::~RecipientsEditor()
00868 {
00869 }
00870
00871 RecipientsPicker* RecipientsEditor::picker() const
00872 {
00873 return mSideWidget->picker();
00874 }
00875
00876 void RecipientsEditor::slotPickedRecipient( const Recipient &rec )
00877 {
00878 RecipientLine *line = mRecipientsView->activeLine();
00879 if ( !line->isEmpty() ) line = mRecipientsView->addLine();
00880
00881 Recipient r = rec;
00882 if ( r.type() == Recipient::Undefined ) {
00883 r.setType( line->recipientType() );
00884 }
00885
00886 line->setRecipient( r );
00887 mModified = true;
00888 }
00889
00890 void RecipientsEditor::saveDistributionList()
00891 {
00892 DistributionListDialog *dlg = new DistributionListDialog( this );
00893 dlg->setRecipients( mRecipientsView->recipients() );
00894 dlg->show();
00895 }
00896
00897 Recipient::List RecipientsEditor::recipients() const
00898 {
00899 return mRecipientsView->recipients();
00900 }
00901
00902 void RecipientsEditor::setRecipientString( const QString &str,
00903 Recipient::Type type )
00904 {
00905 clear();
00906
00907 int count = 1;
00908
00909 QStringList r = KPIM::splitEmailAddrList( str );
00910 QStringList::ConstIterator it;
00911 for( it = r.begin(); it != r.end(); ++it ) {
00912 if ( count++ > GlobalSettings::self()->maximumRecipients() ) {
00913 KMessageBox::sorry( this,
00914 i18n("Truncating recipients list to %1 of %2 entries.")
00915 .arg( GlobalSettings::self()->maximumRecipients() )
00916 .arg( r.count() ) );
00917 break;
00918 }
00919 addRecipient( *it, type );
00920 }
00921 }
00922
00923 QString RecipientsEditor::recipientString( Recipient::Type type )
00924 {
00925 QString str;
00926
00927 Recipient::List recipients = mRecipientsView->recipients();
00928 Recipient::List::ConstIterator it;
00929 for( it = recipients.begin(); it != recipients.end(); ++it ) {
00930 if ( (*it).type() == type ) {
00931 if ( !str.isEmpty() ) str += ", ";
00932 str.append( (*it).email() );
00933 }
00934 }
00935
00936 return str;
00937 }
00938
00939 void RecipientsEditor::addRecipient( const QString & recipient,
00940 Recipient::Type type )
00941 {
00942 RecipientLine *line = mRecipientsView->emptyLine();
00943 if ( !line ) line = mRecipientsView->addLine();
00944 line->setRecipient( Recipient( recipient, type ) );
00945 }
00946
00947 void RecipientsEditor::removeRecipient( const QString & recipient,
00948 Recipient::Type type )
00949 {
00950 mRecipientsView->removeRecipient( recipient, type );
00951 }
00952
00953 bool RecipientsEditor::isModified()
00954 {
00955 return mModified || mRecipientsView->isModified();
00956 }
00957
00958 void RecipientsEditor::clearModified()
00959 {
00960 mModified = false;
00961 mRecipientsView->clearModified();
00962 }
00963
00964 void RecipientsEditor::clear()
00965 {
00966 }
00967
00968 void RecipientsEditor::setFocus()
00969 {
00970 mRecipientsView->setFocus();
00971 }
00972
00973 void RecipientsEditor::setFocusTop()
00974 {
00975 mRecipientsView->setFocusTop();
00976 }
00977
00978 void RecipientsEditor::setFocusBottom()
00979 {
00980 mRecipientsView->setFocusBottom();
00981 }
00982
00983 int RecipientsEditor::setFirstColumnWidth( int w )
00984 {
00985 return mRecipientsView->setFirstColumnWidth( w );
00986 }
00987
00988 void RecipientsEditor::selectRecipients()
00989 {
00990 mSideWidget->pickRecipient();
00991 }
00992
00993 void RecipientsEditor::setCompletionMode( KGlobalSettings::Completion mode )
00994 {
00995 mRecipientsView->setCompletionMode( mode );
00996 }
00997
00998 #include "recipientseditor.moc"