2 This file is part of KMail.
4 Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 As a special exception, permission is given to link this program
21 with any edition of Qt, and distribute the resulting executable,
22 without including the source code for Qt in the source distribution.
26 #include "recipientseditor.h"
28 #include "recipientspicker.h"
29 #include "kwindowpositioner.h"
30 #include "distributionlistdialog.h"
31 #include "globalsettings.h"
32 #include "autoqpointer.h"
34 #include <kpimutils/email.h>
38 #include <KCompletionBox>
39 #include <KMessageBox>
44 #include <QPushButton>
45 #include <QResizeEvent>
49 Recipient::Recipient( const QString
&email
, Recipient::Type type
)
50 : mEmail( email
), mType( type
)
54 void Recipient::setType( Type type
)
59 Recipient::Type
Recipient::type() const
64 void Recipient::setEmail( const QString
&email
)
69 QString
Recipient::email() const
74 bool Recipient::isEmpty() const
76 return mEmail
.isEmpty();
79 int Recipient::typeToId( Recipient::Type type
)
81 return static_cast<int>( type
);
84 Recipient::Type
Recipient::idToType( int id
)
86 return static_cast<Type
>( id
);
89 QString
Recipient::typeLabel() const
91 return typeLabel( mType
);
94 QString
Recipient::typeLabel( Recipient::Type type
)
98 return i18nc("@label:listbox Recipient of an email message.", "To");
100 return i18nc("@label:listbox Carbon Copy recipient of an email message.", "CC");
102 return i18nc("@label:listbox Blind carbon copy recipient of an email message.", "BCC");
107 return i18nc("@label:listbox", "<placeholder>Undefined Recipient Type</placeholder>");
110 QStringList
Recipient::allTypeLabels()
113 types
.append( typeLabel( To
) );
114 types
.append( typeLabel( Cc
) );
115 types
.append( typeLabel( Bcc
) );
120 RecipientComboBox::RecipientComboBox( QWidget
*parent
)
121 : KComboBox( parent
)
125 void RecipientComboBox::keyPressEvent( QKeyEvent
*ev
)
127 if ( ev
->key() == Qt::Key_Right
) emit
rightPressed();
128 else KComboBox::keyPressEvent( ev
);
132 void RecipientLineEdit::keyPressEvent( QKeyEvent
*ev
)
134 if ( ev
->key() == Qt::Key_Backspace
&& text().isEmpty() ) {
137 } else if ( ev
->key() == Qt::Key_Left
&& cursorPosition() == 0 &&
138 !ev
->modifiers().testFlag( Qt::ShiftModifier
) ) { // Shift would be pressed during selection
140 } else if ( ev
->key() == Qt::Key_Right
&& cursorPosition() == (int)text().length() &&
141 !ev
->modifiers().testFlag( Qt::ShiftModifier
) ) { // Shift would be pressed during selection
144 KMLineEdit::keyPressEvent( ev
);
148 RecipientLine::RecipientLine( QWidget
*parent
)
149 : QWidget( parent
), mRecipientsCount( 0 ), mModified( false )
151 setSizePolicy( QSizePolicy::Expanding
, QSizePolicy::Fixed
);
153 QBoxLayout
*topLayout
= new QHBoxLayout( this );
154 topLayout
->setSpacing( KDialog::spacingHint() );
155 topLayout
->setMargin( 0 );
157 QStringList recipientTypes
= Recipient::allTypeLabels();
159 mCombo
= new RecipientComboBox( this );
160 mCombo
->addItems( recipientTypes
);
161 topLayout
->addWidget( mCombo
);
162 mCombo
->setToolTip( i18nc("@label:listbox","Select type of recipient") );
164 mEdit
= new RecipientLineEdit( this );
165 mEdit
->setClearButtonShown( true );
166 topLayout
->addWidget( mEdit
);
167 connect( mEdit
, SIGNAL( returnPressed() ), SLOT( slotReturnPressed() ) );
168 connect( mEdit
, SIGNAL( deleteMe() ), SLOT( slotPropagateDeletion() ) );
169 connect( mEdit
, SIGNAL( textChanged( const QString
& ) ),
170 SLOT( analyzeLine( const QString
& ) ) );
171 connect( mEdit
, SIGNAL( focusUp() ), SLOT( slotFocusUp() ) );
172 connect( mEdit
, SIGNAL( focusDown() ), SLOT( slotFocusDown() ) );
173 connect( mEdit
, SIGNAL( rightPressed() ), SIGNAL( rightPressed() ) );
175 connect( mEdit
, SIGNAL( leftPressed() ), mCombo
, SLOT( setFocus() ) );
176 connect( mEdit
, SIGNAL( editingFinished() ), SLOT( slotEditingFinished() ) );
177 connect( mEdit
, SIGNAL( clearButtonClicked() ), SLOT( slotPropagateDeletion() ) );
178 connect( mCombo
, SIGNAL( rightPressed() ), mEdit
, SLOT( setFocus() ) );
180 connect( mCombo
, SIGNAL( activated ( int ) ),
181 this, SLOT( slotTypeModified() ) );
184 void RecipientLine::slotFocusUp()
186 emit
upPressed( this );
189 void RecipientLine::slotFocusDown()
191 emit
downPressed( this );
194 void RecipientLine::slotTypeModified()
198 emit
typeModified( this );
201 void RecipientLine::analyzeLine( const QString
&text
)
203 QStringList r
= KPIMUtils::splitAddressList( text
);
204 if ( int( r
.count() ) != mRecipientsCount
) {
205 mRecipientsCount
= r
.count();
210 int RecipientLine::recipientsCount() const
212 return mRecipientsCount
;
215 void RecipientLine::setRecipient( const Recipient
&rec
)
217 mEdit
->setText( rec
.email() );
218 mCombo
->setCurrentIndex( Recipient::typeToId( rec
.type() ) );
221 void RecipientLine::setRecipient( const QString
&email
)
223 setRecipient( Recipient( email
) );
226 Recipient
RecipientLine::recipient() const
228 return Recipient( mEdit
->text(),
229 Recipient::idToType( mCombo
->currentIndex() ) );
232 void RecipientLine::setRecipientType( Recipient::Type type
)
234 mCombo
->setCurrentIndex( Recipient::typeToId( type
) );
237 Recipient::Type
RecipientLine::recipientType() const
239 return Recipient::idToType( mCombo
->currentIndex() );
242 void RecipientLine::activate()
247 bool RecipientLine::isActive() const
249 return mEdit
->hasFocus();
252 bool RecipientLine::isEmpty() const
254 return mEdit
->text().isEmpty();
257 bool RecipientLine::isModified()
259 return mModified
|| mEdit
->isModified();
262 void RecipientLine::clearModified()
265 mEdit
->setModified( false );
268 void RecipientLine::slotReturnPressed()
270 emit
returnPressed( this );
273 void RecipientLine::slotPropagateDeletion()
275 emit
deleteLine( this );
278 void RecipientLine::slotEditingFinished()
280 if ( mEdit
->text().isEmpty() ) {
281 emit
deleteLine( this );
285 void RecipientLine::keyPressEvent( QKeyEvent
*ev
)
287 if ( ev
->key() == Qt::Key_Up
) {
288 emit
upPressed( this );
289 } else if ( ev
->key() == Qt::Key_Down
) {
290 emit
downPressed( this );
294 int RecipientLine::setComboWidth( int w
)
296 w
= qMax( w
, mCombo
->sizeHint().width() );
297 mCombo
->setFixedWidth( w
);
298 mCombo
->updateGeometry();
299 parentWidget()->updateGeometry();
303 void RecipientLine::fixTabOrder( QWidget
*previous
)
305 setTabOrder( previous
, mCombo
);
306 setTabOrder( mCombo
, mEdit
);
309 QWidget
*RecipientLine::tabOut() const
314 void RecipientLine::clear()
319 void RecipientLine::setEditFont( const QFont
& font
)
321 mEdit
->setFont( font
);
324 // ------------ RecipientsView ---------------------
326 RecipientsView::RecipientsView( QWidget
*parent
)
327 : QScrollArea( parent
), mCurDelLine( 0 ),
328 mLineHeight( 0 ), mFirstColumnWidth( 0 ),
331 mCompletionMode
= KGlobalSettings::completionMode();
333 setWidgetResizable( true );
334 setFrameStyle( QFrame::NoFrame
);
336 mEditFont
= KGlobalSettings::generalFont();
339 mPage
->setSizePolicy( QSizePolicy::Expanding
, QSizePolicy::Fixed
);
342 mTopLayout
= new QVBoxLayout
;
343 mTopLayout
->setMargin( 0 );
344 mTopLayout
->setSpacing( 0 );
345 mPage
->setLayout( mTopLayout
);
350 RecipientLine
*RecipientsView::activeLine() const
352 return mLines
.last();
355 RecipientLine
*RecipientsView::emptyLine() const
358 foreach( line
, mLines
) {
359 if ( line
->isEmpty() )
366 RecipientLine
*RecipientsView::addLine()
368 RecipientLine
*line
= new RecipientLine( widget() );
369 line
->setEditFont( mEditFont
);
370 //addChild( line, 0, mLines.count() * mLineHeight );
371 mTopLayout
->addWidget( line
);
372 line
->mEdit
->setCompletionMode( mCompletionMode
);
374 connect( line
, SIGNAL( returnPressed( RecipientLine
* ) ),
375 SLOT( slotReturnPressed( RecipientLine
* ) ) );
376 connect( line
, SIGNAL( upPressed( RecipientLine
* ) ),
377 SLOT( slotUpPressed( RecipientLine
* ) ) );
378 connect( line
, SIGNAL( downPressed( RecipientLine
* ) ),
379 SLOT( slotDownPressed( RecipientLine
* ) ) );
380 connect( line
, SIGNAL( rightPressed() ), SIGNAL( focusRight() ) );
381 connect( line
, SIGNAL( deleteLine( RecipientLine
* ) ),
382 SLOT( slotDecideLineDeletion( RecipientLine
* ) ) );
383 connect( line
, SIGNAL( countChanged() ), SLOT( calculateTotal() ) );
384 connect( line
, SIGNAL( typeModified( RecipientLine
* ) ),
385 SLOT( slotTypeModified( RecipientLine
* ) ) );
386 connect( line
->mEdit
, SIGNAL( completionModeChanged( KGlobalSettings::Completion
) ),
387 SLOT( setCompletionMode( KGlobalSettings::Completion
) ) );
388 connect( line
->mEdit
, SIGNAL( textChanged ( const QString
& ) ),
389 SLOT( calculateTotal() ) );
391 if ( !mLines
.isEmpty() ) {
392 if ( mLines
.count() == 1 ) {
393 if ( GlobalSettings::self()->secondRecipientTypeDefault() ==
394 GlobalSettings::EnumSecondRecipientTypeDefault::To
) {
395 line
->setRecipientType( Recipient::To
);
397 if ( mLines
.last()->recipientType() == Recipient::Bcc
) {
398 line
->setRecipientType( Recipient::To
);
400 line
->setRecipientType( Recipient::Cc
);
404 line
->setRecipientType( mLines
.last()->recipientType() );
406 line
->fixTabOrder( mLines
.last()->tabOut() );
409 mLines
.append( line
);
411 mFirstColumnWidth
= line
->setComboWidth( mFirstColumnWidth
);
413 mLineHeight
= line
->minimumSizeHint().height();
415 line
->resize( viewport()->width(), mLineHeight
);
421 ensureVisible( 0, mLines
.count() * mLineHeight
, 0, 0 );
423 QTimer::singleShot( 0, this, SLOT(moveScrollBarToEnd()) );
428 void RecipientsView::moveScrollBarToEnd()
431 verticalScrollBar()->triggerAction( QAbstractSlider::SliderToMaximum
);
434 void RecipientsView::slotTypeModified( RecipientLine
*line
)
436 if ( mLines
.count() == 2 ||
437 ( mLines
.count() == 3 && mLines
.at( 2 )->isEmpty() ) ) {
438 if ( mLines
.at( 1 ) == line
) {
439 if ( line
->recipientType() == Recipient::To
) {
440 GlobalSettings::self()->setSecondRecipientTypeDefault(
441 GlobalSettings::EnumSecondRecipientTypeDefault::To
);
442 } else if ( line
->recipientType() == Recipient::Cc
) {
443 GlobalSettings::self()->setSecondRecipientTypeDefault(
444 GlobalSettings::EnumSecondRecipientTypeDefault::Cc
);
449 //Update the total tooltip
453 void RecipientsView::calculateTotal()
459 foreach( line
, mLines
) {
460 if ( line
->isEmpty() ) ++empty
;
461 else count
+= line
->recipientsCount();
464 if ( empty
== 0 ) addLine();
466 emit
totalChanged( count
, mLines
.count() );
469 void RecipientsView::slotReturnPressed( RecipientLine
*line
)
471 if ( !line
->recipient().isEmpty() ) {
472 RecipientLine
*empty
= emptyLine();
473 if ( !empty
) empty
= addLine();
474 activateLine( empty
);
478 void RecipientsView::slotDownPressed( RecipientLine
*line
)
480 int pos
= mLines
.indexOf( line
);
481 if ( pos
>= (int)mLines
.count() - 1 ) {
483 } else if ( pos
>= 0 ) {
484 activateLine( mLines
.at( pos
+ 1 ) );
488 void RecipientsView::slotUpPressed( RecipientLine
*line
)
490 int pos
= mLines
.indexOf( line
);
492 activateLine( mLines
.at( pos
- 1 ) );
498 void RecipientsView::slotDecideLineDeletion( RecipientLine
*line
)
500 if ( !line
->isEmpty() )
502 if ( mLines
.count() == 1 ) {
504 } else if ( mLines
.indexOf( line
) != mLines
.count() - 1 ) {
506 QTimer::singleShot( 0, this, SLOT( slotDeleteLine( ) ) );
510 void RecipientsView::slotDeleteLine()
515 RecipientLine
*line
= mCurDelLine
;
516 int pos
= mLines
.indexOf( line
);
518 if ( mCurDelLine
->isActive() ) {
520 if ( pos
== 0 ) newPos
= pos
+ 1;
521 else newPos
= pos
- 1;
523 // if there is something left to activate, do so
524 if ( mLines
.at( newPos
) )
525 mLines
.at( newPos
)->activate();
528 mLines
.removeAll( line
);
529 line
->setParent( 0 );
532 bool atLeastOneToLine
= false;
534 for( int i
= pos
; i
< mLines
.count(); ++i
) {
535 RecipientLine
*line
= mLines
.at( i
);
536 if ( line
->recipientType() == Recipient::To
)
537 atLeastOneToLine
= true;
538 else if ( ( line
->recipientType() == Recipient::Cc
) && ( firstCC
< 0 ) )
542 if ( !atLeastOneToLine
&& ( firstCC
>= 0 ) )
543 mLines
.at( firstCC
)->setRecipientType( Recipient::To
);
550 void RecipientsView::resizeView()
552 if ( mLines
.count() < 6 ) {
553 setMinimumHeight( mLineHeight
* mLines
.count() );
555 setMinimumHeight( mLineHeight
* 5 );
556 setMaximumHeight( mLineHeight
* mLines
.count() );
559 parentWidget()->layout()->activate();
560 emit
sizeHintChanged();
561 QTimer::singleShot( 0, this, SLOT(moveCompletionPopup()) );
564 void RecipientsView::activateLine( RecipientLine
*line
)
567 ensureWidgetVisible( line
);
570 void RecipientsView::resizeEvent ( QResizeEvent
*ev
)
572 QScrollArea::resizeEvent(ev
);
573 for( int i
= 0; i
< mLines
.count(); ++i
) {
574 mLines
.at( i
)->resize( ev
->size().width(), mLineHeight
);
576 ensureVisible( 0, mLines
.count() * mLineHeight
, 0, 0 );
579 QSize
RecipientsView::sizeHint() const
581 return QSize( 200, mLineHeight
* mLines
.count() );
584 QSize
RecipientsView::minimumSizeHint() const
588 if ( mLines
.count() < numLines
) height
= mLineHeight
* mLines
.count();
589 else height
= mLineHeight
* numLines
;
590 return QSize( 200, height
);
593 Recipient::List
RecipientsView::recipients() const
595 Recipient::List recipients
;
597 QListIterator
<RecipientLine
*> it( mLines
);
599 while( it
.hasNext()) {
601 if ( !line
->recipient().isEmpty() ) {
602 recipients
.append( line
->recipient() );
609 void RecipientsView::setCompletionMode ( KGlobalSettings::Completion mode
)
611 if ( mCompletionMode
== mode
)
613 mCompletionMode
= mode
;
615 QListIterator
<RecipientLine
*> it( mLines
);
616 while( it
.hasNext() ) {
617 RecipientLine
*line
= it
.next();
618 line
->mEdit
->blockSignals( true );
619 line
->mEdit
->setCompletionMode( mode
);
620 line
->mEdit
->blockSignals( false );
622 emit
completionModeChanged( mode
); //report change to RecipientsEditor
625 void RecipientsView::removeRecipient( const QString
& recipient
,
626 Recipient::Type type
)
628 // search a line which matches recipient and type
629 QListIterator
<RecipientLine
*> it( mLines
);
630 RecipientLine
*line
= 0;
631 while (it
.hasNext()) {
633 if ( ( line
->recipient().email() == recipient
) &&
634 ( line
->recipientType() == type
) ) {
639 line
->slotPropagateDeletion();
642 bool RecipientsView::isModified()
647 QListIterator
<RecipientLine
*> it( mLines
);
649 while( it
.hasNext()) {
651 if ( line
->isModified() ) {
659 void RecipientsView::clearModified()
663 QListIterator
<RecipientLine
*> it( mLines
);
665 while( it
.hasNext() ) {
667 line
->clearModified();
671 void RecipientsView::setFocus()
673 if ( !mLines
.empty() && mLines
.last()->isActive() )
679 void RecipientsView::setFocusTop()
681 if ( !mLines
.empty() ) {
682 RecipientLine
*line
= mLines
.first();
683 if ( line
) line
->activate();
684 else kWarning() <<"No first";
686 else kWarning() <<"No first";
689 void RecipientsView::setFocusBottom()
691 RecipientLine
*line
= mLines
.last();
693 ensureWidgetVisible( line
);
696 else kWarning() <<"No last";
699 int RecipientsView::setFirstColumnWidth( int w
)
701 mFirstColumnWidth
= w
;
703 QListIterator
<RecipientLine
*> it( mLines
);
705 while(it
.hasNext()) {
707 mFirstColumnWidth
= line
->setComboWidth( mFirstColumnWidth
);
711 return mFirstColumnWidth
;
714 void RecipientsView::setEditFont( const QFont
& font
)
717 foreach ( RecipientLine
*line
, mLines
) {
718 line
->setEditFont( mEditFont
);
722 void RecipientsView::moveCompletionPopup()
724 foreach ( RecipientLine
*const line
, mLines
) {
725 if ( line
->lineEdit()->completionBox( false ) ) {
726 if ( line
->lineEdit()->completionBox()->isVisible() ) {
727 // ### trigger moving, is there a nicer way to do that?
728 line
->lineEdit()->completionBox()->hide();
729 line
->lineEdit()->completionBox()->show();
736 SideWidget::SideWidget( RecipientsView
*view
, QWidget
*parent
)
737 : QWidget( parent
), mView( view
), mRecipientPicker( 0 )
739 QBoxLayout
*topLayout
= new QVBoxLayout( this );
741 topLayout
->setSpacing( KDialog::spacingHint() );
742 topLayout
->setMargin( 0 );
743 topLayout
->addStretch( 1 );
745 mTotalLabel
= new QLabel( this );
746 mTotalLabel
->setAlignment( Qt::AlignCenter
);
747 topLayout
->addWidget( mTotalLabel
);
750 topLayout
->addStretch( 1 );
752 mDistributionListButton
= new QPushButton(
753 i18nc("@action:button","Save List..."), this );
754 topLayout
->addWidget( mDistributionListButton
);
755 mDistributionListButton
->hide();
756 connect( mDistributionListButton
, SIGNAL( clicked() ),
757 SIGNAL( saveDistributionList() ) );
758 mDistributionListButton
->setToolTip(
759 i18nc( "@info:tooltip", "Save recipients as distribution list") );
761 mSelectButton
= new QPushButton(
762 i18nc( "@action:button Open recipient selection dialog.", "Se&lect..."), this );
763 topLayout
->addWidget( mSelectButton
);
764 connect( mSelectButton
, SIGNAL( clicked() ), SLOT( pickRecipient() ) );
765 mSelectButton
->setToolTip( i18nc("@info:tooltip","Select recipients from address book") );
766 updateTotalToolTip();
769 SideWidget::~SideWidget()
773 RecipientsPicker
* SideWidget::picker() const
775 if ( !mRecipientPicker
) {
776 // hacks to allow picker() to be const in the presence of lazy loading
777 SideWidget
*non_const_this
= const_cast<SideWidget
*>( this );
778 mRecipientPicker
= new RecipientsPicker( non_const_this
);
779 connect( mRecipientPicker
, SIGNAL( pickedRecipient( const Recipient
& ) ),
780 non_const_this
, SIGNAL( pickedRecipient( const Recipient
& ) ) );
781 mPickerPositioner
= new KWindowPositioner( mSelectButton
, mRecipientPicker
);
783 return mRecipientPicker
;
786 void SideWidget::setFocus()
788 mSelectButton
->setFocus();
791 void SideWidget::setTotal( int recipients
, int lines
)
794 if ( recipients
== 0 ) labelText
= i18nc("@info:status No recipients selected"
796 else labelText
= i18ncp("@info:status Number of recipients selected"
797 , "1 recipient","%1 recipients", recipients
);
798 mTotalLabel
->setText( labelText
);
800 if ( lines
> 3 ) mTotalLabel
->show();
801 else mTotalLabel
->hide();
803 if ( lines
> 2 ) mDistributionListButton
->show();
804 else mDistributionListButton
->hide();
806 updateTotalToolTip();
809 void SideWidget::updateTotalToolTip()
811 QString text
= "<qt>";
817 Recipient::List recipients
= mView
->recipients();
818 Recipient::List::ConstIterator it
;
819 for( it
= recipients
.constBegin(); it
!= recipients
.constEnd(); ++it
) {
820 QString emailLine
= " " + Qt::escape( (*it
).email() ) + "<br/>";
821 switch( (*it
).type() ) {
836 text
+= i18nc("@info:tooltip %1 list of emails", "<interface>To:</interface><nl/>%1", to
);
837 if ( !cc
.isEmpty() ) {
838 text
+= i18nc("@info:tooltip %1 list of emails", "<interface>CC:</interface><nl/>%1", cc
);
840 if ( !bcc
.isEmpty() ) {
841 text
+= i18nc("@info:tooltip %1 list of emails", "<interface>BCC:</interface><nl/>%1", bcc
);
844 text
.append( "</qt>" );
845 mTotalLabel
->setToolTip( text
);
848 void SideWidget::pickRecipient()
850 RecipientsPicker
*p
= picker();
851 p
->setDefaultType( mView
->activeLine()->recipientType() );
852 p
->setRecipients( mView
->recipients() );
853 mPickerPositioner
->reposition();
858 RecipientsEditor::RecipientsEditor( QWidget
*parent
)
859 : QWidget( parent
), mModified( false )
861 QBoxLayout
*topLayout
= new QHBoxLayout();
862 topLayout
->setSpacing( KDialog::spacingHint() );
863 topLayout
->setMargin( 0 );
864 setLayout( topLayout
);
866 mRecipientsView
= new RecipientsView( this );
867 topLayout
->addWidget( mRecipientsView
);
868 connect( mRecipientsView
, SIGNAL( focusUp() ), SIGNAL( focusUp() ) );
869 connect( mRecipientsView
, SIGNAL( focusDown() ), SIGNAL( focusDown() ) );
870 connect( mRecipientsView
, SIGNAL( completionModeChanged( KGlobalSettings::Completion
) ),
871 SIGNAL( completionModeChanged( KGlobalSettings::Completion
) ) );
873 mSideWidget
= new SideWidget( mRecipientsView
, this );
874 topLayout
->addWidget( mSideWidget
);
875 connect( mSideWidget
, SIGNAL( pickedRecipient( const Recipient
& ) ),
876 SLOT( slotPickedRecipient( const Recipient
& ) ) );
877 connect( mSideWidget
, SIGNAL( saveDistributionList() ),
878 SLOT( saveDistributionList() ) );
880 connect( mRecipientsView
, SIGNAL( totalChanged( int, int ) ),
881 mSideWidget
, SLOT( setTotal( int, int ) ) );
882 connect( mRecipientsView
, SIGNAL( focusRight() ),
883 mSideWidget
, SLOT( setFocus() ) );
885 connect( mRecipientsView
, SIGNAL(sizeHintChanged()),
886 SIGNAL(sizeHintChanged()) );
889 RecipientsEditor::~RecipientsEditor()
893 RecipientsPicker
* RecipientsEditor::picker() const
895 return mSideWidget
->picker();
898 void RecipientsEditor::slotPickedRecipient( const Recipient
&rec
)
900 RecipientLine
*line
= mRecipientsView
->activeLine();
901 if ( !line
->isEmpty() ) line
= mRecipientsView
->addLine();
904 if ( r
.type() == Recipient::Undefined
) {
905 r
.setType( line
->recipientType() );
908 line
->setRecipient( r
);
912 void RecipientsEditor::saveDistributionList()
914 AutoQPointer
<DistributionListDialog
> dlg( new DistributionListDialog( this ) );
915 dlg
->setRecipients( mRecipientsView
->recipients() );
919 Recipient::List
RecipientsEditor::recipients() const
921 return mRecipientsView
->recipients();
924 void RecipientsEditor::setRecipientString( const QString
&str
,
925 Recipient::Type type
)
931 QStringList r
= KPIMUtils::splitAddressList( str
);
932 QStringList::ConstIterator it
;
933 for( it
= r
.constBegin(); it
!= r
.constEnd(); ++it
) {
934 if ( count
++ > GlobalSettings::self()->maximumRecipients() ) {
935 KMessageBox::sorry( this,
936 i18nc("@info:status", "Truncating recipients list to %1 of %2 entries.",
937 GlobalSettings::self()->maximumRecipients(),
941 addRecipient( *it
, type
);
945 QString
RecipientsEditor::recipientString( Recipient::Type type
)
949 Recipient::List recipients
= mRecipientsView
->recipients();
950 if ( !recipients
.isEmpty() ) {
951 Recipient::List::ConstIterator it
;
952 for( it
= recipients
.constBegin(); it
!= recipients
.constEnd(); ++it
) {
953 if ( (*it
).type() == type
) {
954 if ( !str
.isEmpty() ) str
+= ", ";
955 str
.append( (*it
).email() );
962 void RecipientsEditor::addRecipient( const QString
& recipient
,
963 Recipient::Type type
)
965 RecipientLine
*line
= mRecipientsView
->emptyLine();
966 if ( !line
) line
= mRecipientsView
->addLine();
967 line
->setRecipient( Recipient( recipient
, type
) );
970 void RecipientsEditor::removeRecipient( const QString
& recipient
,
971 Recipient::Type type
)
973 mRecipientsView
->removeRecipient( recipient
, type
);
976 bool RecipientsEditor::isModified()
978 return mModified
|| mRecipientsView
->isModified();
981 void RecipientsEditor::clearModified()
984 mRecipientsView
->clearModified();
987 void RecipientsEditor::clear()
991 void RecipientsEditor::setFocus()
993 mRecipientsView
->setFocus();
996 void RecipientsEditor::setFocusTop()
998 mRecipientsView
->setFocusTop();
1001 void RecipientsEditor::setFocusBottom()
1003 mRecipientsView
->setFocusBottom();
1006 int RecipientsEditor::setFirstColumnWidth( int w
)
1008 return mRecipientsView
->setFirstColumnWidth( w
);
1011 void RecipientsEditor::selectRecipients()
1013 mSideWidget
->pickRecipient();
1016 void RecipientsEditor::setCompletionMode( KGlobalSettings::Completion mode
)
1018 mRecipientsView
->setCompletionMode( mode
);
1021 void RecipientsEditor::setEditFont( const QFont
& font
)
1023 mRecipientsView
->setEditFont( font
);
1026 #include "recipientseditor.moc"