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