• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.8.3 API Reference
  • KDE Home
  • Contact Us
 

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 Tue May 8 2012 00:09:58 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kpimidentities

Skip menu "kpimidentities"
  • Main Page
  • Alphabetical List
  • Class List
  • Class Members
  • File List
  • Related Pages

kdepimlibs-4.8.3 API Reference

Skip menu "kdepimlibs-4.8.3 API Reference"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal