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