00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "signatureconfigurator.h"
00022 #include "identity.h"
00023
00024 #include <kactioncollection.h>
00025 #include <klocale.h>
00026 #include <kdebug.h>
00027 #include <kdialog.h>
00028 #include <klineedit.h>
00029 #include <kurlrequester.h>
00030 #include <kshellcompletion.h>
00031 #include <ktoolbar.h>
00032 #include <krun.h>
00033 #include <KComboBox>
00034 #include <KStandardDirs>
00035
00036 #include <kpimtextedit/textedit.h>
00037
00038 #include <QCheckBox>
00039 #include <QDir>
00040 #include <QFileInfo>
00041 #include <QLabel>
00042 #include <QLayout>
00043 #include <QMimeData>
00044 #include <QTextEdit>
00045
00046 #include <QStackedWidget>
00047
00048 #include <QVBoxLayout>
00049 #include <QHBoxLayout>
00050
00051 #include <assert.h>
00052
00053 using namespace KPIMIdentities;
00054
00055 namespace KPIMIdentities {
00056
00061
00062 class SignatureConfigurator::Private
00063 {
00064 public:
00065 Private( SignatureConfigurator *parent );
00066 void init();
00067
00068 SignatureConfigurator *q;
00069 bool inlinedHtml;
00070 QString imageLocation;
00071 };
00072
00073
00074 SignatureConfigurator::Private::Private( SignatureConfigurator *parent )
00075 :q( parent )
00076 {
00077 }
00078
00079 void SignatureConfigurator::Private::init()
00080 {
00081
00082 QLabel * label;
00083 QWidget * page;
00084 QHBoxLayout * hlay;
00085 QVBoxLayout * vlay;
00086 QVBoxLayout * page_vlay;
00087
00088 vlay = new QVBoxLayout( q );
00089 vlay->setObjectName( "main layout" );
00090 vlay->setMargin( 0 );
00091
00092
00093 q->mEnableCheck = new QCheckBox( i18n("&Enable signature"), q );
00094 q->mEnableCheck->setWhatsThis(
00095 i18n("Check this box if you want KMail to append a signature to mails "
00096 "written with this identity."));
00097 vlay->addWidget( q->mEnableCheck );
00098
00099
00100 hlay = new QHBoxLayout();
00101 vlay->addLayout( hlay );
00102 q->mSourceCombo = new KComboBox( q );
00103 q->mSourceCombo->setEditable( false );
00104 q->mSourceCombo->setWhatsThis(
00105 i18n("Click on the widgets below to obtain help on the input methods."));
00106 q->mSourceCombo->setEnabled( false );
00107 q->mSourceCombo->addItems( QStringList()
00108 << i18nc("continuation of \"obtain signature text from\"",
00109 "Input Field Below")
00110 << i18nc("continuation of \"obtain signature text from\"",
00111 "File")
00112 << i18nc("continuation of \"obtain signature text from\"",
00113 "Output of Command")
00114 );
00115 label = new QLabel( i18n("Obtain signature &text from:"), q );
00116 label->setBuddy( q->mSourceCombo );
00117 label->setEnabled( false );
00118 hlay->addWidget( label );
00119 hlay->addWidget( q->mSourceCombo, 1 );
00120
00121
00122 QStackedWidget * widgetStack = new QStackedWidget( q );
00123 widgetStack->setEnabled( false );
00124 vlay->addWidget( widgetStack, 1 );
00125 q->connect( q->mSourceCombo, SIGNAL(currentIndexChanged(int)),
00126 widgetStack, SLOT(setCurrentIndex (int)) );
00127 q->connect( q->mSourceCombo, SIGNAL(highlighted(int)),
00128 widgetStack, SLOT(setCurrentIndex (int)) );
00129
00130
00131 q->connect( q->mEnableCheck, SIGNAL(toggled(bool)),
00132 q->mSourceCombo, SLOT(setEnabled(bool)) );
00133 q->connect( q->mEnableCheck, SIGNAL(toggled(bool)),
00134 widgetStack, SLOT(setEnabled(bool)) );
00135 q->connect( q->mEnableCheck, SIGNAL(toggled(bool)),
00136 label, SLOT(setEnabled(bool)) );
00137
00138 q->connect( q->mEnableCheck, SIGNAL(clicked()),
00139 q->mEnableCheck, SLOT(setFocus()) );
00140
00141 int pageno = 0;
00142
00143 page = new QWidget( widgetStack );
00144 widgetStack->insertWidget( pageno, page );
00145 page_vlay = new QVBoxLayout( page );
00146
00147 #ifndef QT_NO_TOOLBAR
00148 q->mEditToolBar = new KToolBar( q );
00149 q->mEditToolBar->setToolButtonStyle( Qt::ToolButtonIconOnly );
00150 page_vlay->addWidget( q->mEditToolBar, 0 );
00151
00152 q->mFormatToolBar = new KToolBar( q );
00153 q->mFormatToolBar->setToolButtonStyle( Qt::ToolButtonIconOnly );
00154 page_vlay->addWidget( q->mFormatToolBar, 1 );
00155 #endif
00156
00157 q->mTextEdit = new KPIMTextEdit::TextEdit( q );
00158 static_cast<KPIMTextEdit::TextEdit*>( q->mTextEdit )->enableImageActions();
00159 page_vlay->addWidget( q->mTextEdit, 2 );
00160 q->mTextEdit->setWhatsThis( i18n("Use this field to enter an arbitrary static signature."));
00161
00162 q->mTextEdit->setRichTextSupport( KRichTextWidget::FullTextFormattingSupport |
00163 KRichTextWidget::FullListSupport |
00164 KRichTextWidget::SupportAlignment |
00165 KRichTextWidget::SupportRuleLine |
00166 KRichTextWidget::SupportHyperlinks |
00167 KRichTextWidget::SupportFormatPainting );
00168
00169
00170 KActionCollection *actionCollection = new KActionCollection( q );
00171 q->mTextEdit->createActions( actionCollection );
00172 #ifndef QT_NO_TOOLBAR
00173 q->mEditToolBar->addAction( actionCollection->action( "format_text_bold" ) );
00174 q->mEditToolBar->addAction( actionCollection->action( "format_text_italic" ) );
00175 q->mEditToolBar->addAction( actionCollection->action( "format_text_underline" ) );
00176 q->mEditToolBar->addAction( actionCollection->action( "format_text_strikeout" ) );
00177 q->mEditToolBar->addAction( actionCollection->action( "format_text_foreground_color" ) );
00178 q->mEditToolBar->addAction( actionCollection->action( "format_text_background_color" ) );
00179 q->mEditToolBar->addAction( actionCollection->action( "format_font_family" ) );
00180 q->mEditToolBar->addAction( actionCollection->action( "format_font_size" ) );
00181
00182 q->mFormatToolBar->addAction( actionCollection->action( "format_list_style" ) );
00183 q->mFormatToolBar->addAction( actionCollection->action( "format_list_indent_more" ) );
00184 q->mFormatToolBar->addAction( actionCollection->action( "format_list_indent_less" ) );
00185 q->mFormatToolBar->addAction( actionCollection->action( "format_list_indent_less" ) );
00186 q->mFormatToolBar->addSeparator();
00187
00188 q->mFormatToolBar->addAction( actionCollection->action( "format_align_left" ) );
00189 q->mFormatToolBar->addAction( actionCollection->action( "format_align_center" ) );
00190 q->mFormatToolBar->addAction( actionCollection->action( "format_align_right" ) );
00191 q->mFormatToolBar->addAction( actionCollection->action( "format_align_justify" ) );
00192 q->mFormatToolBar->addSeparator();
00193
00194 q->mFormatToolBar->addAction( actionCollection->action( "insert_horizontal_rule" ) );
00195 q->mFormatToolBar->addAction( actionCollection->action( "manage_link" ) );
00196 q->mFormatToolBar->addAction( actionCollection->action( "format_painter" ) );
00197
00198 q->mFormatToolBar->addSeparator();
00199 q->mFormatToolBar->addAction( actionCollection->action( "add_image" ) );
00200 #endif
00201
00202 hlay = new QHBoxLayout();
00203 page_vlay->addLayout( hlay );
00204 q->mHtmlCheck = new QCheckBox( i18n("&Use HTML"), page );
00205 q->connect( q->mHtmlCheck, SIGNAL(clicked()),
00206 q, SLOT(slotSetHtml()) );
00207 hlay->addWidget( q->mHtmlCheck );
00208 inlinedHtml = true;
00209
00210 widgetStack->setCurrentIndex( 0 );
00211
00212
00213 ++pageno;
00214 page = new QWidget( widgetStack );
00215 widgetStack->insertWidget( pageno, page );
00216 page_vlay = new QVBoxLayout( page );
00217 page_vlay->setMargin( 0 );
00218 hlay = new QHBoxLayout();
00219 page_vlay->addLayout( hlay );
00220 q->mFileRequester = new KUrlRequester( page );
00221 q->mFileRequester->setWhatsThis(
00222 i18n("Use this requester to specify a text file that contains your "
00223 "signature. It will be read every time you create a new mail or "
00224 "append a new signature."));
00225 label = new QLabel( i18n("S&pecify file:"), page );
00226 label->setBuddy( q->mFileRequester );
00227 hlay->addWidget( label );
00228 hlay->addWidget( q->mFileRequester, 1 );
00229 q->mFileRequester->button()->setAutoDefault( false );
00230 q->connect( q->mFileRequester, SIGNAL(textChanged(const QString &)),
00231 q, SLOT(slotEnableEditButton(const QString &)) );
00232 q->mEditButton = new QPushButton( i18n("Edit &File"), page );
00233 q->mEditButton->setWhatsThis( i18n("Opens the specified file in a text editor."));
00234 q->connect( q->mEditButton, SIGNAL(clicked()),
00235 q, SLOT(slotEdit()) );
00236 q->mEditButton->setAutoDefault( false );
00237 q->mEditButton->setEnabled( false );
00238 hlay->addWidget( q->mEditButton );
00239 page_vlay->addStretch( 1 );
00240
00241
00242 ++pageno;
00243 page = new QWidget( widgetStack );
00244 widgetStack->insertWidget( pageno,page );
00245 page_vlay = new QVBoxLayout( page );
00246 page_vlay->setMargin( 0 );
00247 hlay = new QHBoxLayout();
00248 page_vlay->addLayout( hlay );
00249 q->mCommandEdit = new KLineEdit( page );
00250 q->mCommandEdit->setCompletionObject( new KShellCompletion() );
00251 q->mCommandEdit->setAutoDeleteCompletionObject( true );
00252 q->mCommandEdit->setWhatsThis(
00253 i18n("You can add an arbitrary command here, either with or without path "
00254 "depending on whether or not the command is in your Path. For every "
00255 "new mail, KMail will execute the command and use what it outputs (to "
00256 "standard output) as a signature. Usual commands for use with this "
00257 "mechanism are \"fortune\" or \"ksig -random\"."));
00258 label = new QLabel( i18n("S&pecify command:"), page );
00259 label->setBuddy( q->mCommandEdit );
00260 hlay->addWidget( label );
00261 hlay->addWidget( q->mCommandEdit, 1 );
00262 page_vlay->addStretch( 1 );
00263 }
00264
00265 SignatureConfigurator::SignatureConfigurator( QWidget * parent )
00266 : QWidget( parent ), d( new Private( this ) )
00267 {
00268 d->init();
00269 }
00270
00271 SignatureConfigurator::~SignatureConfigurator()
00272 {
00273 delete d;
00274 }
00275
00276 bool SignatureConfigurator::isSignatureEnabled() const
00277 {
00278 return mEnableCheck->isChecked();
00279 }
00280
00281 void SignatureConfigurator::setSignatureEnabled( bool enable )
00282 {
00283 mEnableCheck->setChecked( enable );
00284 }
00285
00286 Signature::Type SignatureConfigurator::signatureType() const
00287 {
00288 if ( !isSignatureEnabled() ) return Signature::Disabled;
00289
00290 switch ( mSourceCombo->currentIndex() ) {
00291 case 0: return Signature::Inlined;
00292 case 1: return Signature::FromFile;
00293 case 2: return Signature::FromCommand;
00294 default: return Signature::Disabled;
00295 }
00296 }
00297
00298 void SignatureConfigurator::setSignatureType( Signature::Type type )
00299 {
00300 setSignatureEnabled( type != Signature::Disabled );
00301
00302 int idx = 0;
00303 switch( type ) {
00304 case Signature::Inlined: idx = 0; break;
00305 case Signature::FromFile: idx = 1; break;
00306 case Signature::FromCommand: idx = 2; break;
00307 default: idx = 0; break;
00308 };
00309
00310 mSourceCombo->setCurrentIndex( idx );
00311 }
00312
00313 void SignatureConfigurator::setInlineText( const QString & text )
00314 {
00315 mTextEdit->setTextOrHtml( text );
00316 }
00317
00318 QString SignatureConfigurator::fileURL() const
00319 {
00320 QString file = mFileRequester->url().path();
00321
00322
00323
00324 if ( !file.isEmpty() && QFileInfo( file ).isRelative() )
00325 file = QDir::home().absolutePath() + QDir::separator() + file;
00326
00327 return file;
00328 }
00329
00330 void SignatureConfigurator::setFileURL( const QString & url )
00331 {
00332 mFileRequester->setUrl( url );
00333 }
00334
00335 QString SignatureConfigurator::commandURL() const
00336 {
00337 return mCommandEdit->text();
00338 }
00339
00340 void SignatureConfigurator::setCommandURL( const QString & url )
00341 {
00342 mCommandEdit->setText( url );
00343 }
00344
00345
00346 Signature SignatureConfigurator::signature() const
00347 {
00348 Signature sig;
00349 const Signature::Type sigType = signatureType();
00350 switch ( sigType ) {
00351 case Signature::Inlined:
00352 sig.setInlinedHtml( d->inlinedHtml );
00353 sig.setText( d->inlinedHtml ? asCleanedHTML() : mTextEdit->textOrHtml() );
00354 if ( d->inlinedHtml ) {
00355 if ( !d->imageLocation.isEmpty() )
00356 sig.setImageLocation( d->imageLocation );
00357 KPIMTextEdit::ImageWithNameList images = static_cast< KPIMTextEdit::TextEdit*>( mTextEdit )->imagesWithName();
00358 foreach( const KPIMTextEdit::ImageWithNamePtr &image, images ) {
00359 sig.addImage( image->image, image->name );
00360 }
00361 }
00362 break;
00363 case Signature::FromCommand:
00364 sig.setUrl( commandURL(), true );
00365 break;
00366 case Signature::FromFile:
00367 sig.setUrl( fileURL(), false );
00368 break;
00369 case Signature::Disabled:
00370
00371 break;
00372 }
00373
00374 sig.setType( sigType );
00375 return sig;
00376 }
00377
00378 void SignatureConfigurator::setSignature( const Signature & sig )
00379 {
00380 setSignatureType( sig.type() );
00381 if ( sig.isInlinedHtml() )
00382 mHtmlCheck->setCheckState( Qt::Checked );
00383 else
00384 mHtmlCheck->setCheckState( Qt::Unchecked );
00385 slotSetHtml();
00386
00387
00388 mTextEdit->clear();
00389 KPIMTextEdit::TextEdit * const pimEdit = static_cast<KPIMTextEdit::TextEdit*>( mTextEdit );
00390 sig.insertIntoTextEdit( KPIMIdentities::Signature::Start, KPIMIdentities::Signature::AddNothing,
00391 pimEdit );
00392
00393 if ( sig.type() == Signature::FromFile )
00394 setFileURL( sig.url() );
00395 else
00396 setFileURL( QString() );
00397
00398 if ( sig.type() == Signature::FromCommand )
00399 setCommandURL( sig.url() );
00400 else
00401 setCommandURL( QString() );
00402 }
00403
00404 void SignatureConfigurator::slotEnableEditButton( const QString & url )
00405 {
00406 mEditButton->setDisabled( url.trimmed().isEmpty() );
00407 }
00408
00409 void SignatureConfigurator::slotEdit()
00410 {
00411 QString url = fileURL();
00412
00413 assert( !url.isEmpty() );
00414
00415 (void)KRun::runUrl( KUrl( url ), QString::fromLatin1("text/plain"), this );
00416 }
00417
00418 QString SignatureConfigurator::asCleanedHTML() const
00419 {
00420 QString text = mTextEdit->toHtml();
00421
00422
00423 QTextDocument textDocument;
00424 QString html = textDocument.toHtml();
00425
00426
00427 foreach( const QString& line, html.split( '\n' ) ){
00428 text.remove( line + '\n' );
00429 }
00430 return text;
00431 }
00432
00433
00434 void SignatureConfigurator::slotSetHtml()
00435 {
00436 if ( mHtmlCheck->checkState() == Qt::Unchecked ) {
00437 mHtmlCheck->setText( i18n("&Use HTML") );
00438 #ifndef QT_NO_TOOLBAR
00439 mEditToolBar->setVisible( false );
00440 mEditToolBar->setEnabled( false );
00441 mFormatToolBar->setVisible( false );
00442 mFormatToolBar->setEnabled( false );
00443 #endif
00444 mTextEdit->switchToPlainText();
00445 d->inlinedHtml = false;
00446 }
00447 else {
00448 mHtmlCheck->setText( i18n("&Use HTML (disabling removes formatting)") );
00449 d->inlinedHtml = true;
00450 #ifndef QT_NO_TOOLBAR
00451 mEditToolBar->setVisible( true );
00452 mEditToolBar->setEnabled( true );
00453 mFormatToolBar->setVisible( true );
00454 mFormatToolBar->setEnabled( true );
00455 #endif
00456 mTextEdit->enableRichTextMode();
00457 }
00458 }
00459
00460 void SignatureConfigurator::setImageLocation ( const QString& path )
00461 {
00462 d->imageLocation = path;
00463 }
00464
00465 void SignatureConfigurator::setImageLocation( const Identity &identity )
00466 {
00467 const QString dir = QString( "emailidentities/%1/" ).arg(
00468 QString::number( identity.uoid() ) );
00469 setImageLocation( KStandardDirs::locateLocal( "data", dir ) );
00470 }
00471
00472 }
00473
00474 #include "signatureconfigurator.moc"