kpimidentities
signatureconfigurator.cpp
00001 /* -*- c++ -*- 00002 Copyright 2008 Thomas McGuire <Thomas.McGuire@gmx.net> 00003 Copyright 2008 Edwin Schepers <yez@familieschepers.nl> 00004 Copyright 2004 Marc Mutz <mutz@kde.org> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Lesser General Public 00008 License as published by the Free Software Foundation; either 00009 version 2.1 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Lesser General Public License for more details. 00015 00016 You should have received a copy of the GNU Lesser General Public 00017 License along with this library. If not, see <http://www.gnu.org/licenses/>. 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 //@cond PRIVATE 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 //@endcond 00073 00074 SignatureConfigurator::Private::Private( SignatureConfigurator *parent ) 00075 :q( parent ) 00076 { 00077 } 00078 00079 void SignatureConfigurator::Private::init() 00080 { 00081 // tmp. vars: 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 // "enable signatue" checkbox: 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 // "obtain signature text from" combo and label: 00100 hlay = new QHBoxLayout(); // inherits spacing 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 ); // since !mEnableCheck->isChecked() 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 ); // since !mEnableCheck->isChecked() 00118 hlay->addWidget( label ); 00119 hlay->addWidget( q->mSourceCombo, 1 ); 00120 00121 // widget stack that is controlled by the source combo: 00122 QStackedWidget * widgetStack = new QStackedWidget( q ); 00123 widgetStack->setEnabled( false ); // since !mEnableCheck->isChecked() 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 // connects for the enabling of the widgets depending on 00130 // signatureEnabled: 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 // The focus might be still in the widget that is disabled 00138 q->connect( q->mEnableCheck, SIGNAL(clicked()), 00139 q->mEnableCheck, SLOT(setFocus()) ); 00140 00141 int pageno = 0; 00142 // page 0: input field for direct entering: 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 // exclude SupportToPlainText. 00162 q->mTextEdit->setRichTextSupport( KRichTextWidget::FullTextFormattingSupport | 00163 KRichTextWidget::FullListSupport | 00164 KRichTextWidget::SupportAlignment | 00165 KRichTextWidget::SupportRuleLine | 00166 KRichTextWidget::SupportHyperlinks | 00167 KRichTextWidget::SupportFormatPainting ); 00168 00169 // Fill the toolbars. 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(); // inherits spacing 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 ); // since mSourceCombo->currentItem() == 0 00211 00212 // page 1: "signature file" requester, label, "edit file" button: 00213 ++pageno; 00214 page = new QWidget( widgetStack ); 00215 widgetStack->insertWidget( pageno, page ); // force sequential numbers (play safe) 00216 page_vlay = new QVBoxLayout( page ); 00217 page_vlay->setMargin( 0 ); 00218 hlay = new QHBoxLayout(); // inherits spacing 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(QString)), 00231 q, SLOT(slotEnableEditButton(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 ); // initially nothing to edit 00238 hlay->addWidget( q->mEditButton ); 00239 page_vlay->addStretch( 1 ); // spacer 00240 00241 // page 2: "signature command" requester and label: 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(); // inherits spacing 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 ); // spacer 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 // Force the filename to be relative to ~ instead of $PWD depending 00323 // on the rest of the code (KRun::run in Edit and KFileItem on save) 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 /* do nothing */ 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 // Let insertIntoTextEdit() handle setting the text, as that function also adds the images. 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 // slotEnableEditButton should prevent this assert from being hit: 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 // Beautiful little hack to find the html headers produced by Qt. 00423 QTextDocument textDocument; 00424 QString html = textDocument.toHtml(); 00425 00426 // Now remove each line from the text, the result is clean html. 00427 foreach( const QString& line, html.split( '\n' ) ){ 00428 text.remove( line + '\n' ); 00429 } 00430 return text; 00431 } 00432 00433 // "use HTML"-checkbox (un)checked 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"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Aug 27 2012 22:10:34 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Aug 27 2012 22:10:34 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.