• Skip to content
  • Skip to link menu
KDE 4.2 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 
00023 #include <kactioncollection.h>
00024 #include <klocale.h>
00025 #include <kdebug.h>
00026 #include <kdialog.h>
00027 #include <klineedit.h>
00028 #include <kurlrequester.h>
00029 #include <krichtextwidget.h>
00030 #include <kshellcompletion.h>
00031 #include <ktoolbar.h>
00032 #include <krun.h>
00033 #include <KComboBox>
00034 
00035 #include <QCheckBox>
00036 #include <QDir>
00037 #include <QFileInfo>
00038 #include <QLabel>
00039 #include <QLayout>
00040 #include <QMimeData>
00041 #include <QTextEdit>
00042 
00043 #include <QStackedWidget>
00044 
00045 #include <QVBoxLayout>
00046 #include <QHBoxLayout>
00047 
00048 #include <assert.h>
00049 
00050 using namespace KPIMIdentities;
00051 
00052 namespace KPIMIdentities {
00053 
00058 //@cond PRIVATE
00059 class KPIMIdentities::SignatureConfigurator::Private
00060 {
00061   public:
00062     bool inlinedHtml;
00063 };
00064 //@endcond
00065 
00066 SignatureConfigurator::SignatureConfigurator( QWidget * parent )
00067     : QWidget( parent ), d( new Private )
00068   {
00069     // tmp. vars:
00070     QLabel * label;
00071     QWidget * page;
00072     QHBoxLayout * hlay;
00073     QVBoxLayout * vlay;
00074     QVBoxLayout * page_vlay;
00075 
00076     vlay = new QVBoxLayout( this );
00077     vlay->setObjectName( "main layout" );
00078     vlay->setSpacing( KDialog::spacingHint() );
00079     vlay->setMargin( 0 );
00080 
00081     // "enable signatue" checkbox:
00082     mEnableCheck = new QCheckBox( i18n("&Enable signature"), this );
00083     mEnableCheck->setWhatsThis(
00084         i18n("Check this box if you want KMail to append a signature to mails "
00085              "written with this identity."));
00086     vlay->addWidget( mEnableCheck );
00087 
00088     // "obtain signature text from" combo and label:
00089     hlay = new QHBoxLayout(); // inherits spacing
00090     vlay->addLayout( hlay );
00091     mSourceCombo = new KComboBox( this );
00092     mSourceCombo->setEditable( false );
00093     mSourceCombo->setWhatsThis(
00094         i18n("Click on the widgets below to obtain help on the input methods."));
00095     mSourceCombo->setEnabled( false ); // since !mEnableCheck->isChecked()
00096     mSourceCombo->addItems( QStringList()
00097                    << i18nc("continuation of \"obtain signature text from\"",
00098                            "Input Field Below")
00099                    << i18nc("continuation of \"obtain signature text from\"",
00100                            "File")
00101                    << i18nc("continuation of \"obtain signature text from\"",
00102                            "Output of Command")
00103                    );
00104     label = new QLabel( i18n("Obtain signature &text from:"), this );
00105     label->setBuddy( mSourceCombo );
00106     label->setEnabled( false ); // since !mEnableCheck->isChecked()
00107     hlay->addWidget( label );
00108     hlay->addWidget( mSourceCombo, 1 );
00109 
00110     // widget stack that is controlled by the source combo:
00111     QStackedWidget * widgetStack = new QStackedWidget( this );
00112     widgetStack->setEnabled( false ); // since !mEnableCheck->isChecked()
00113     vlay->addWidget( widgetStack, 1 );
00114     connect( mSourceCombo, SIGNAL(currentIndexChanged(int)),
00115              widgetStack, SLOT(setCurrentIndex (int)) );
00116     connect( mSourceCombo, SIGNAL(highlighted(int)),
00117              widgetStack, SLOT(setCurrentIndex (int)) );
00118     // connects for the enabling of the widgets depending on
00119     // signatureEnabled:
00120     connect( mEnableCheck, SIGNAL(toggled(bool)),
00121              mSourceCombo, SLOT(setEnabled(bool)) );
00122     connect( mEnableCheck, SIGNAL(toggled(bool)),
00123              widgetStack, SLOT(setEnabled(bool)) );
00124     connect( mEnableCheck, SIGNAL(toggled(bool)),
00125              label, SLOT(setEnabled(bool)) );
00126     // The focus might be still in the widget that is disabled
00127     connect( mEnableCheck, SIGNAL(clicked()),
00128              mEnableCheck, SLOT(setFocus()) );
00129 
00130     int pageno = 0;
00131     // page 0: input field for direct entering:
00132     page = new QWidget( widgetStack );
00133     widgetStack->insertWidget( pageno, page );
00134     page_vlay = new QVBoxLayout( page );
00135 
00136     mEditToolBar = new KToolBar( this );
00137     mEditToolBar->setToolButtonStyle( Qt::ToolButtonIconOnly );
00138     page_vlay->addWidget( mEditToolBar, 0 );
00139 
00140     mFormatToolBar = new KToolBar( this );
00141     mFormatToolBar->setToolButtonStyle( Qt::ToolButtonIconOnly );
00142     page_vlay->addWidget( mFormatToolBar, 1 );
00143 
00144     mTextEdit = new KRichTextWidget( this );
00145     page_vlay->addWidget( mTextEdit, 2 );
00146     mTextEdit->setWhatsThis( i18n("Use this field to enter an arbitrary static signature."));
00147     // exclude SupportToPlainText.
00148     mTextEdit->setRichTextSupport( KRichTextWidget::FullTextFormattingSupport |
00149         KRichTextWidget::FullListSupport |
00150         KRichTextWidget::SupportAlignment |
00151         KRichTextWidget::SupportRuleLine |
00152         KRichTextWidget::SupportHyperlinks |
00153         KRichTextWidget::SupportFormatPainting );
00154 
00155     // Fill the toolbars.
00156     KActionCollection *actionCollection = new KActionCollection(this);
00157     mTextEdit->createActions( actionCollection );
00158     mEditToolBar->addAction( actionCollection->action( "format_text_bold" ) );
00159     mEditToolBar->addAction( actionCollection->action( "format_text_italic" ) );
00160     mEditToolBar->addAction( actionCollection->action( "format_text_underline" ) );
00161     mEditToolBar->addAction( actionCollection->action( "format_text_strikeout" ) );
00162     mEditToolBar->addAction( actionCollection->action( "format_text_foreground_color" ) );
00163     mEditToolBar->addAction( actionCollection->action( "format_text_background_color" ) );
00164     mEditToolBar->addAction( actionCollection->action( "format_font_family" ) );
00165     mEditToolBar->addAction( actionCollection->action( "format_font_size" ) );
00166 
00167     mFormatToolBar->addAction( actionCollection->action( "format_list_style" ) );
00168     mFormatToolBar->addAction( actionCollection->action( "format_list_indent_more" ) );
00169     mFormatToolBar->addAction( actionCollection->action( "format_list_indent_less" ) );
00170     mFormatToolBar->addAction( actionCollection->action( "format_list_indent_less" ) );
00171     mFormatToolBar->addSeparator();
00172 
00173     mFormatToolBar->addAction( actionCollection->action( "format_align_left" ) );
00174     mFormatToolBar->addAction( actionCollection->action( "format_align_center" ) );
00175     mFormatToolBar->addAction( actionCollection->action( "format_align_right" ) );
00176     mFormatToolBar->addAction( actionCollection->action( "format_align_justify" ) );
00177     mFormatToolBar->addSeparator();
00178 
00179     mFormatToolBar->addAction( actionCollection->action( "insert_horizontal_rule" ) );
00180     mFormatToolBar->addAction( actionCollection->action( "manage_link" ) );
00181     mFormatToolBar->addAction( actionCollection->action( "format_painter" ) );
00182 
00183     hlay = new QHBoxLayout(); // inherits spacing
00184     page_vlay->addLayout( hlay );
00185     mHtmlCheck = new QCheckBox( i18n("&Use HTML"), page );
00186     connect( mHtmlCheck, SIGNAL(clicked()),
00187              this, SLOT(slotSetHtml()) );
00188     hlay->addWidget( mHtmlCheck );
00189     d->inlinedHtml = true;
00190 
00191     widgetStack->setCurrentIndex( 0 ); // since mSourceCombo->currentItem() == 0
00192 
00193     // page 1: "signature file" requester, label, "edit file" button:
00194     ++pageno;
00195     page = new QWidget( widgetStack );
00196     widgetStack->insertWidget( pageno, page ); // force sequential numbers (play safe)
00197     page_vlay = new QVBoxLayout( page );
00198     page_vlay->setMargin( 0 );
00199     page_vlay->setSpacing( KDialog::spacingHint() );
00200     hlay = new QHBoxLayout(); // inherits spacing
00201     page_vlay->addLayout( hlay );
00202     mFileRequester = new KUrlRequester( page );
00203     mFileRequester->setWhatsThis(
00204         i18n("Use this requester to specify a text file that contains your "
00205              "signature. It will be read every time you create a new mail or "
00206              "append a new signature."));
00207     label = new QLabel( i18n("S&pecify file:"), page );
00208     label->setBuddy( mFileRequester );
00209     hlay->addWidget( label );
00210     hlay->addWidget( mFileRequester, 1 );
00211     mFileRequester->button()->setAutoDefault( false );
00212     connect( mFileRequester, SIGNAL(textChanged(const QString &)),
00213              this, SLOT(slotEnableEditButton(const QString &)) );
00214     mEditButton = new QPushButton( i18n("Edit &File"), page );
00215     mEditButton->setWhatsThis( i18n("Opens the specified file in a text editor."));
00216     connect( mEditButton, SIGNAL(clicked()), SLOT(slotEdit()) );
00217     mEditButton->setAutoDefault( false );
00218     mEditButton->setEnabled( false ); // initially nothing to edit
00219     hlay->addWidget( mEditButton );
00220     page_vlay->addStretch( 1 ); // spacer
00221 
00222     // page 2: "signature command" requester and label:
00223     ++pageno;
00224     page = new QWidget( widgetStack );
00225     widgetStack->insertWidget( pageno,page );
00226     page_vlay = new QVBoxLayout( page  );
00227     page_vlay->setMargin( 0 );
00228     page_vlay->setSpacing( KDialog::spacingHint() );
00229     hlay = new QHBoxLayout(); // inherits spacing
00230     page_vlay->addLayout( hlay );
00231     mCommandEdit = new KLineEdit( page );
00232     mCommandEdit->setCompletionObject( new KShellCompletion() );
00233     mCommandEdit->setAutoDeleteCompletionObject( true );
00234     mCommandEdit->setWhatsThis(
00235         i18n("You can add an arbitrary command here, either with or without path "
00236              "depending on whether or not the command is in your Path. For every "
00237              "new mail, KMail will execute the command and use what it outputs (to "
00238              "standard output) as a signature. Usual commands for use with this "
00239              "mechanism are \"fortune\" or \"ksig -random\"."));
00240     label = new QLabel( i18n("S&pecify command:"), page );
00241     label->setBuddy( mCommandEdit );
00242     hlay->addWidget( label );
00243     hlay->addWidget( mCommandEdit, 1 );
00244     page_vlay->addStretch( 1 ); // spacer
00245   }
00246 
00247   SignatureConfigurator::~SignatureConfigurator()
00248   {
00249     delete d;
00250   }
00251 
00252   bool SignatureConfigurator::isSignatureEnabled() const
00253   {
00254     return mEnableCheck->isChecked();
00255   }
00256 
00257   void SignatureConfigurator::setSignatureEnabled( bool enable )
00258   {
00259     mEnableCheck->setChecked( enable );
00260   }
00261 
00262   Signature::Type SignatureConfigurator::signatureType() const
00263   {
00264     if ( !isSignatureEnabled() ) return Signature::Disabled;
00265 
00266     switch ( mSourceCombo->currentIndex() ) {
00267     case 0:  return Signature::Inlined;
00268     case 1:  return Signature::FromFile;
00269     case 2:  return Signature::FromCommand;
00270     default: return Signature::Disabled;
00271     }
00272   }
00273 
00274   void SignatureConfigurator::setSignatureType( Signature::Type type )
00275   {
00276     setSignatureEnabled( type != Signature::Disabled );
00277 
00278     int idx = 0;
00279     switch( type ) {
00280     case Signature::Inlined:     idx = 0; break;
00281     case Signature::FromFile:    idx = 1; break;
00282     case Signature::FromCommand: idx = 2; break;
00283     default:                     idx = 0; break;
00284     };
00285 
00286     mSourceCombo->setCurrentIndex( idx );
00287   }
00288 
00289   void SignatureConfigurator::setInlineText( const QString & text )
00290   {
00291     mTextEdit->setTextOrHtml( text );
00292   }
00293 
00294   QString SignatureConfigurator::fileURL() const
00295   {
00296     QString file = mFileRequester->url().path();
00297 
00298     // Force the filename to be relative to ~ instead of $PWD depending
00299     // on the rest of the code (KRun::run in Edit and KFileItem on save)
00300     if ( !file.isEmpty() && QFileInfo( file ).isRelative() )
00301         file = QDir::home().absolutePath() + QDir::separator() + file;
00302 
00303     return file;
00304   }
00305 
00306   void SignatureConfigurator::setFileURL( const QString & url )
00307   {
00308     mFileRequester->setUrl( url );
00309   }
00310 
00311   QString SignatureConfigurator::commandURL() const
00312   {
00313     return mCommandEdit->text();
00314   }
00315 
00316   void SignatureConfigurator::setCommandURL( const QString & url )
00317   {
00318     mCommandEdit->setText( url );
00319   }
00320 
00321 
00322   Signature SignatureConfigurator::signature() const
00323   {
00324     Signature sig;
00325     sig.setType( signatureType() );
00326     sig.setInlinedHtml( d->inlinedHtml );
00327     sig.setText( d->inlinedHtml ? asCleanedHTML() : mTextEdit->textOrHtml() );
00328     if ( signatureType() == Signature::FromCommand )
00329       sig.setUrl( commandURL(), true );
00330     if ( signatureType() == Signature::FromFile )
00331       sig.setUrl( fileURL(), false );
00332     return sig;
00333   }
00334 
00335   void SignatureConfigurator::setSignature( const Signature & sig )
00336   {
00337     setSignatureType( sig.type() );
00338     if ( sig.isInlinedHtml() )
00339       mHtmlCheck->setCheckState( Qt::Checked );
00340     else
00341       mHtmlCheck->setCheckState( Qt::Unchecked );
00342     slotSetHtml();
00343     setInlineText( sig.text() );
00344 
00345     if ( sig.type() == Signature::FromFile )
00346       setFileURL( sig.url() );
00347     else
00348       setFileURL( QString() );
00349 
00350     if ( sig.type() == Signature::FromCommand )
00351       setCommandURL( sig.url() );
00352     else
00353       setCommandURL( QString() );
00354   }
00355 
00356   void SignatureConfigurator::slotEnableEditButton( const QString & url )
00357   {
00358     mEditButton->setDisabled( url.trimmed().isEmpty() );
00359   }
00360 
00361   void SignatureConfigurator::slotEdit()
00362   {
00363     QString url = fileURL();
00364     // slotEnableEditButton should prevent this assert from being hit:
00365     assert( !url.isEmpty() );
00366 
00367     (void)KRun::runUrl( KUrl( url ), QString::fromLatin1("text/plain"), this );
00368   }
00369 
00370   QString SignatureConfigurator::asCleanedHTML() const
00371   {
00372     QString text = mTextEdit->toHtml();
00373 
00374     // Beautiful little hack to find the html headers produced by Qt.
00375     QTextDocument textDocument;
00376     QString html = textDocument.toHtml();
00377 
00378     // Now remove each line from the text, the result is clean html.
00379     foreach( const QString& line, html.split( '\n' ) ){
00380         text.remove( line + '\n' );
00381     }
00382     return text;
00383   }
00384 
00385   // "use HTML"-checkbox (un)checked
00386   void SignatureConfigurator::slotSetHtml()
00387   {
00388     if ( mHtmlCheck->checkState() == Qt::Unchecked ) {
00389       mHtmlCheck->setText( i18n("&Use HTML") );
00390       mEditToolBar->setVisible( false );
00391       mEditToolBar->setEnabled( false );
00392       mFormatToolBar->setVisible( false );
00393       mFormatToolBar->setEnabled( false );
00394       mTextEdit->switchToPlainText();
00395       d->inlinedHtml = false;
00396     }
00397     else {
00398       mHtmlCheck->setText( i18n("&Use HTML (disabling removes formatting)") );
00399       d->inlinedHtml = true;
00400       mEditToolBar->setVisible( true );
00401       mEditToolBar->setEnabled( true );
00402       mFormatToolBar->setVisible( true );
00403       mFormatToolBar->setEnabled( true );
00404       mTextEdit->enableRichTextMode();
00405     }
00406   }
00407 
00408 }
00409 
00410 #include "signatureconfigurator.moc"

kpimidentities

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

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  • kabc
  • kblog
  • kcal
  • kimap
  • kioslave
  •   imap4
  •   mbox
  • kldap
  • kmime
  • kpimidentities
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.5.6
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