• Skip to content
  • Skip to link menu
KDE 4.5 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • Sitemap
  • 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   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   // exclude SupportToPlainText.
00160   q->mTextEdit->setRichTextSupport( KRichTextWidget::FullTextFormattingSupport |
00161       KRichTextWidget::FullListSupport |
00162       KRichTextWidget::SupportAlignment |
00163       KRichTextWidget::SupportRuleLine |
00164       KRichTextWidget::SupportHyperlinks |
00165       KRichTextWidget::SupportFormatPainting );
00166 
00167   // Fill the toolbars.
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(); // inherits spacing
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 ); // since mSourceCombo->currentItem() == 0
00207 
00208   // page 1: "signature file" requester, label, "edit file" button:
00209   ++pageno;
00210   page = new QWidget( widgetStack );
00211   widgetStack->insertWidget( pageno, page ); // force sequential numbers (play safe)
00212   page_vlay = new QVBoxLayout( page );
00213   page_vlay->setMargin( 0 );
00214   hlay = new QHBoxLayout(); // inherits spacing
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 ); // initially nothing to edit
00234   hlay->addWidget( q->mEditButton );
00235   page_vlay->addStretch( 1 ); // spacer
00236 
00237   // page 2: "signature command" requester and label:
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(); // inherits spacing
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 ); // spacer
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     // Force the filename to be relative to ~ instead of $PWD depending
00319     // on the rest of the code (KRun::run in Edit and KFileItem on save)
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       /* do nothing */
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     // Let insertIntoTextEdit() handle setting the text, as that function also adds the images.
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     // slotEnableEditButton should prevent this assert from being hit:
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     // Beautiful little hack to find the html headers produced by Qt.
00419     QTextDocument textDocument;
00420     QString html = textDocument.toHtml();
00421 
00422     // Now remove each line from the text, the result is clean html.
00423     foreach( const QString& line, html.split( '\n' ) ){
00424         text.remove( line + '\n' );
00425     }
00426     return text;
00427   }
00428 
00429   // "use HTML"-checkbox (un)checked
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"

kpimidentities

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

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kblog
  • kcal
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.7.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal