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 q->mEditToolBar = new KToolBar( q );
00148 q->mEditToolBar->setToolButtonStyle( Qt::ToolButtonIconOnly );
00149 page_vlay->addWidget( q->mEditToolBar, 0 );
00150
00151 q->mFormatToolBar = new KToolBar( q );
00152 q->mFormatToolBar->setToolButtonStyle( Qt::ToolButtonIconOnly );
00153 page_vlay->addWidget( q->mFormatToolBar, 1 );
00154
00155 q->mTextEdit = new KPIMTextEdit::TextEdit( q );
00156 static_cast<KPIMTextEdit::TextEdit*>( q->mTextEdit )->enableImageActions();
00157 page_vlay->addWidget( q->mTextEdit, 2 );
00158 q->mTextEdit->setWhatsThis( i18n("Use this field to enter an arbitrary static signature."));
00159
00160 q->mTextEdit->setRichTextSupport( KRichTextWidget::FullTextFormattingSupport |
00161 KRichTextWidget::FullListSupport |
00162 KRichTextWidget::SupportAlignment |
00163 KRichTextWidget::SupportRuleLine |
00164 KRichTextWidget::SupportHyperlinks |
00165 KRichTextWidget::SupportFormatPainting );
00166
00167
00168 KActionCollection *actionCollection = new KActionCollection( q );
00169 q->mTextEdit->createActions( actionCollection );
00170 q->mEditToolBar->addAction( actionCollection->action( "format_text_bold" ) );
00171 q->mEditToolBar->addAction( actionCollection->action( "format_text_italic" ) );
00172 q->mEditToolBar->addAction( actionCollection->action( "format_text_underline" ) );
00173 q->mEditToolBar->addAction( actionCollection->action( "format_text_strikeout" ) );
00174 q->mEditToolBar->addAction( actionCollection->action( "format_text_foreground_color" ) );
00175 q->mEditToolBar->addAction( actionCollection->action( "format_text_background_color" ) );
00176 q->mEditToolBar->addAction( actionCollection->action( "format_font_family" ) );
00177 q->mEditToolBar->addAction( actionCollection->action( "format_font_size" ) );
00178
00179 q->mFormatToolBar->addAction( actionCollection->action( "format_list_style" ) );
00180 q->mFormatToolBar->addAction( actionCollection->action( "format_list_indent_more" ) );
00181 q->mFormatToolBar->addAction( actionCollection->action( "format_list_indent_less" ) );
00182 q->mFormatToolBar->addAction( actionCollection->action( "format_list_indent_less" ) );
00183 q->mFormatToolBar->addSeparator();
00184
00185 q->mFormatToolBar->addAction( actionCollection->action( "format_align_left" ) );
00186 q->mFormatToolBar->addAction( actionCollection->action( "format_align_center" ) );
00187 q->mFormatToolBar->addAction( actionCollection->action( "format_align_right" ) );
00188 q->mFormatToolBar->addAction( actionCollection->action( "format_align_justify" ) );
00189 q->mFormatToolBar->addSeparator();
00190
00191 q->mFormatToolBar->addAction( actionCollection->action( "insert_horizontal_rule" ) );
00192 q->mFormatToolBar->addAction( actionCollection->action( "manage_link" ) );
00193 q->mFormatToolBar->addAction( actionCollection->action( "format_painter" ) );
00194
00195 q->mFormatToolBar->addSeparator();
00196 q->mFormatToolBar->addAction( actionCollection->action( "add_image" ) );
00197
00198 hlay = new QHBoxLayout();
00199 page_vlay->addLayout( hlay );
00200 q->mHtmlCheck = new QCheckBox( i18n("&Use HTML"), page );
00201 q->connect( q->mHtmlCheck, SIGNAL(clicked()),
00202 q, SLOT(slotSetHtml()) );
00203 hlay->addWidget( q->mHtmlCheck );
00204 inlinedHtml = true;
00205
00206 widgetStack->setCurrentIndex( 0 );
00207
00208
00209 ++pageno;
00210 page = new QWidget( widgetStack );
00211 widgetStack->insertWidget( pageno, page );
00212 page_vlay = new QVBoxLayout( page );
00213 page_vlay->setMargin( 0 );
00214 hlay = new QHBoxLayout();
00215 page_vlay->addLayout( hlay );
00216 q->mFileRequester = new KUrlRequester( page );
00217 q->mFileRequester->setWhatsThis(
00218 i18n("Use this requester to specify a text file that contains your "
00219 "signature. It will be read every time you create a new mail or "
00220 "append a new signature."));
00221 label = new QLabel( i18n("S&pecify file:"), page );
00222 label->setBuddy( q->mFileRequester );
00223 hlay->addWidget( label );
00224 hlay->addWidget( q->mFileRequester, 1 );
00225 q->mFileRequester->button()->setAutoDefault( false );
00226 q->connect( q->mFileRequester, SIGNAL(textChanged(const QString &)),
00227 q, SLOT(slotEnableEditButton(const QString &)) );
00228 q->mEditButton = new QPushButton( i18n("Edit &File"), page );
00229 q->mEditButton->setWhatsThis( i18n("Opens the specified file in a text editor."));
00230 q->connect( q->mEditButton, SIGNAL(clicked()),
00231 q, SLOT(slotEdit()) );
00232 q->mEditButton->setAutoDefault( false );
00233 q->mEditButton->setEnabled( false );
00234 hlay->addWidget( q->mEditButton );
00235 page_vlay->addStretch( 1 );
00236
00237
00238 ++pageno;
00239 page = new QWidget( widgetStack );
00240 widgetStack->insertWidget( pageno,page );
00241 page_vlay = new QVBoxLayout( page );
00242 page_vlay->setMargin( 0 );
00243 hlay = new QHBoxLayout();
00244 page_vlay->addLayout( hlay );
00245 q->mCommandEdit = new KLineEdit( page );
00246 q->mCommandEdit->setCompletionObject( new KShellCompletion() );
00247 q->mCommandEdit->setAutoDeleteCompletionObject( true );
00248 q->mCommandEdit->setWhatsThis(
00249 i18n("You can add an arbitrary command here, either with or without path "
00250 "depending on whether or not the command is in your Path. For every "
00251 "new mail, KMail will execute the command and use what it outputs (to "
00252 "standard output) as a signature. Usual commands for use with this "
00253 "mechanism are \"fortune\" or \"ksig -random\"."));
00254 label = new QLabel( i18n("S&pecify command:"), page );
00255 label->setBuddy( q->mCommandEdit );
00256 hlay->addWidget( label );
00257 hlay->addWidget( q->mCommandEdit, 1 );
00258 page_vlay->addStretch( 1 );
00259 }
00260
00261 SignatureConfigurator::SignatureConfigurator( QWidget * parent )
00262 : QWidget( parent ), d( new Private( this ) )
00263 {
00264 d->init();
00265 }
00266
00267 SignatureConfigurator::~SignatureConfigurator()
00268 {
00269 delete d;
00270 }
00271
00272 bool SignatureConfigurator::isSignatureEnabled() const
00273 {
00274 return mEnableCheck->isChecked();
00275 }
00276
00277 void SignatureConfigurator::setSignatureEnabled( bool enable )
00278 {
00279 mEnableCheck->setChecked( enable );
00280 }
00281
00282 Signature::Type SignatureConfigurator::signatureType() const
00283 {
00284 if ( !isSignatureEnabled() ) return Signature::Disabled;
00285
00286 switch ( mSourceCombo->currentIndex() ) {
00287 case 0: return Signature::Inlined;
00288 case 1: return Signature::FromFile;
00289 case 2: return Signature::FromCommand;
00290 default: return Signature::Disabled;
00291 }
00292 }
00293
00294 void SignatureConfigurator::setSignatureType( Signature::Type type )
00295 {
00296 setSignatureEnabled( type != Signature::Disabled );
00297
00298 int idx = 0;
00299 switch( type ) {
00300 case Signature::Inlined: idx = 0; break;
00301 case Signature::FromFile: idx = 1; break;
00302 case Signature::FromCommand: idx = 2; break;
00303 default: idx = 0; break;
00304 };
00305
00306 mSourceCombo->setCurrentIndex( idx );
00307 }
00308
00309 void SignatureConfigurator::setInlineText( const QString & text )
00310 {
00311 mTextEdit->setTextOrHtml( text );
00312 }
00313
00314 QString SignatureConfigurator::fileURL() const
00315 {
00316 QString file = mFileRequester->url().path();
00317
00318
00319
00320 if ( !file.isEmpty() && QFileInfo( file ).isRelative() )
00321 file = QDir::home().absolutePath() + QDir::separator() + file;
00322
00323 return file;
00324 }
00325
00326 void SignatureConfigurator::setFileURL( const QString & url )
00327 {
00328 mFileRequester->setUrl( url );
00329 }
00330
00331 QString SignatureConfigurator::commandURL() const
00332 {
00333 return mCommandEdit->text();
00334 }
00335
00336 void SignatureConfigurator::setCommandURL( const QString & url )
00337 {
00338 mCommandEdit->setText( url );
00339 }
00340
00341
00342 Signature SignatureConfigurator::signature() const
00343 {
00344 Signature sig;
00345 const Signature::Type sigType = signatureType();
00346 switch ( sigType ) {
00347 case Signature::Inlined:
00348 sig.setInlinedHtml( d->inlinedHtml );
00349 sig.setText( d->inlinedHtml ? asCleanedHTML() : mTextEdit->textOrHtml() );
00350 if ( d->inlinedHtml ) {
00351 if ( !d->imageLocation.isEmpty() )
00352 sig.setImageLocation( d->imageLocation );
00353 KPIMTextEdit::ImageWithNameList images = static_cast< KPIMTextEdit::TextEdit*>( mTextEdit )->imagesWithName();
00354 foreach( const KPIMTextEdit::ImageWithNamePtr &image, images ) {
00355 sig.addImage( image->image, image->name );
00356 }
00357 }
00358 break;
00359 case Signature::FromCommand:
00360 sig.setUrl( commandURL(), true );
00361 break;
00362 case Signature::FromFile:
00363 sig.setUrl( fileURL(), false );
00364 break;
00365 case Signature::Disabled:
00366
00367 break;
00368 }
00369
00370 sig.setType( sigType );
00371 return sig;
00372 }
00373
00374 void SignatureConfigurator::setSignature( const Signature & sig )
00375 {
00376 setSignatureType( sig.type() );
00377 if ( sig.isInlinedHtml() )
00378 mHtmlCheck->setCheckState( Qt::Checked );
00379 else
00380 mHtmlCheck->setCheckState( Qt::Unchecked );
00381 slotSetHtml();
00382
00383
00384 mTextEdit->clear();
00385 KPIMTextEdit::TextEdit * const pimEdit = static_cast<KPIMTextEdit::TextEdit*>( mTextEdit );
00386 sig.insertIntoTextEdit( KPIMIdentities::Signature::Start, KPIMIdentities::Signature::AddNothing,
00387 pimEdit );
00388
00389 if ( sig.type() == Signature::FromFile )
00390 setFileURL( sig.url() );
00391 else
00392 setFileURL( QString() );
00393
00394 if ( sig.type() == Signature::FromCommand )
00395 setCommandURL( sig.url() );
00396 else
00397 setCommandURL( QString() );
00398 }
00399
00400 void SignatureConfigurator::slotEnableEditButton( const QString & url )
00401 {
00402 mEditButton->setDisabled( url.trimmed().isEmpty() );
00403 }
00404
00405 void SignatureConfigurator::slotEdit()
00406 {
00407 QString url = fileURL();
00408
00409 assert( !url.isEmpty() );
00410
00411 (void)KRun::runUrl( KUrl( url ), QString::fromLatin1("text/plain"), this );
00412 }
00413
00414 QString SignatureConfigurator::asCleanedHTML() const
00415 {
00416 QString text = mTextEdit->toHtml();
00417
00418
00419 QTextDocument textDocument;
00420 QString html = textDocument.toHtml();
00421
00422
00423 foreach( const QString& line, html.split( '\n' ) ){
00424 text.remove( line + '\n' );
00425 }
00426 return text;
00427 }
00428
00429
00430 void SignatureConfigurator::slotSetHtml()
00431 {
00432 if ( mHtmlCheck->checkState() == Qt::Unchecked ) {
00433 mHtmlCheck->setText( i18n("&Use HTML") );
00434 mEditToolBar->setVisible( false );
00435 mEditToolBar->setEnabled( false );
00436 mFormatToolBar->setVisible( false );
00437 mFormatToolBar->setEnabled( false );
00438 mTextEdit->switchToPlainText();
00439 d->inlinedHtml = false;
00440 }
00441 else {
00442 mHtmlCheck->setText( i18n("&Use HTML (disabling removes formatting)") );
00443 d->inlinedHtml = true;
00444 mEditToolBar->setVisible( true );
00445 mEditToolBar->setEnabled( true );
00446 mFormatToolBar->setVisible( true );
00447 mFormatToolBar->setEnabled( true );
00448 mTextEdit->enableRichTextMode();
00449 }
00450 }
00451
00452 void SignatureConfigurator::setImageLocation ( const QString& path )
00453 {
00454 d->imageLocation = path;
00455 }
00456
00457 void SignatureConfigurator::setImageLocation( const Identity &identity )
00458 {
00459 const QString dir = QString( "emailidentities/%1/" ).arg(
00460 QString::number( identity.uoid() ) );
00461 setImageLocation( KStandardDirs::locateLocal( "data", dir ) );
00462 }
00463
00464 }
00465
00466 #include "signatureconfigurator.moc"