• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • Sitemap
  • Contact Us
 

kpimidentities

signature.cpp

00001 /*
00002     Copyright (c) 2002-2004 Marc Mutz <mutz@kde.org>
00003     Copyright (c) 2007 Tom Albers <tomalbers@kde.nl>
00004 
00005     This library is free software; you can redistribute it and/or modify it
00006     under the terms of the GNU Library General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or (at your
00008     option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful, but WITHOUT
00011     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013     License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to the
00017     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00018     02110-1301, USA.
00019 */
00020 
00021 #include "signature.h"
00022 
00023 #include <kdebug.h>
00024 #include <klocale.h>
00025 #include <kmessagebox.h>
00026 #include <kconfiggroup.h>
00027 #include <kurl.h>
00028 #include <kprocess.h>
00029 #include <KRichTextEdit>
00030 #include <kpimutils/kfileio.h>
00031 
00032 #include <QFileInfo>
00033 #include <assert.h>
00034 
00035 using namespace KPIMIdentities;
00036 
00037 Signature::Signature()
00038   : mType( Disabled ),
00039     mInlinedHtml( false )
00040 {}
00041 
00042 Signature::Signature( const QString &text )
00043   : mText( text ),
00044     mType( Inlined ),
00045     mInlinedHtml( false )
00046 {}
00047 
00048 Signature::Signature( const QString &url, bool isExecutable )
00049   : mUrl( url ),
00050     mType( isExecutable ? FromCommand : FromFile ),
00051     mInlinedHtml( false )
00052 {}
00053 
00054 QString Signature::rawText( bool *ok ) const
00055 {
00056   switch ( mType ) {
00057   case Disabled:
00058     if ( ok ) {
00059       *ok = true;
00060     }
00061     return QString();
00062   case Inlined:
00063     if ( ok ) {
00064       *ok = true;
00065     }
00066     return mText;
00067   case FromFile:
00068     return textFromFile( ok );
00069   case FromCommand:
00070     return textFromCommand( ok );
00071   };
00072   kFatal(5325) << "Signature::type() returned unknown value!";
00073   return QString(); // make compiler happy
00074 }
00075 
00076 QString Signature::textFromCommand( bool *ok ) const
00077 {
00078   assert( mType == FromCommand );
00079 
00080   // handle pathological cases:
00081   if ( mUrl.isEmpty() ) {
00082     if ( ok ) {
00083       *ok = true;
00084     }
00085     return QString();
00086   }
00087 
00088   // create a shell process:
00089   KProcess proc;
00090   proc.setOutputChannelMode( KProcess::SeparateChannels );
00091   proc.setShellCommand( mUrl );
00092   int rc = proc.execute();
00093 
00094   // handle errors, if any:
00095   if ( rc != 0 ) {
00096     if ( ok ) {
00097       *ok = false;
00098     }
00099     QString wmsg = i18n( "<qt>Failed to execute signature script<p><b>%1</b>:</p>"
00100                          "<p>%2</p></qt>", mUrl, QString( proc.readAllStandardError() ) );
00101     KMessageBox::error( 0, wmsg );
00102     return QString();
00103   }
00104 
00105   // no errors:
00106   if ( ok ) {
00107     *ok = true;
00108   }
00109 
00110   // get output:
00111   QByteArray output = proc.readAllStandardOutput();
00112 
00113   // TODO: hmm, should we allow other encodings, too?
00114   return QString::fromLocal8Bit( output.data(), output.size() );
00115 }
00116 
00117 QString Signature::textFromFile( bool *ok ) const
00118 {
00119   assert( mType == FromFile );
00120 
00121   // TODO: Use KIO::NetAccess to download non-local files!
00122   if ( !KUrl( mUrl ).isLocalFile() &&
00123        !( QFileInfo( mUrl ).isRelative() &&
00124           QFileInfo( mUrl ).exists() ) ) {
00125     kDebug(5325) << "Signature::textFromFile:"
00126     << "non-local URLs are unsupported";
00127     if ( ok ) {
00128       *ok = false;
00129     }
00130     return QString();
00131   }
00132 
00133   if ( ok ) {
00134     *ok = true;
00135   }
00136 
00137   // TODO: hmm, should we allow other encodings, too?
00138   const QByteArray ba = KPIMUtils::kFileToByteArray( mUrl, false );
00139   return QString::fromLocal8Bit( ba.data(), ba.size() );
00140 }
00141 
00142 QString Signature::withSeparator( bool *ok ) const
00143 {
00144   QString signature = rawText( ok );
00145   if ( ok && (*ok) == false )
00146     return QString();
00147 
00148   if ( signature.isEmpty() ) {
00149     return signature; // don't add a separator in this case
00150   }
00151 
00152   QString newline = ( isInlinedHtml() && mType == Inlined ) ? "<br>" : "\n";
00153   if ( signature.startsWith( QString::fromLatin1( "-- " ) + newline )
00154     || ( signature.indexOf( newline + QString::fromLatin1( "-- " ) +
00155                             newline ) != -1 ) ) {
00156     // already have signature separator at start of sig or inside sig:
00157     return signature;
00158   } else {
00159     // need to prepend one:
00160     return QString::fromLatin1( "-- " ) + newline + signature;
00161   }
00162 }
00163 
00164 void Signature::setUrl( const QString &url, bool isExecutable )
00165 {
00166   mUrl = url;
00167   mType = isExecutable ? FromCommand : FromFile;
00168 }
00169 
00170 void Signature::setInlinedHtml( bool isHtml )
00171 {
00172   mInlinedHtml = isHtml;
00173 }
00174 
00175 bool Signature::isInlinedHtml() const
00176 {
00177   return mInlinedHtml;
00178 }
00179 
00180 // config keys and values:
00181 static const char sigTypeKey[] = "Signature Type";
00182 static const char sigTypeInlineValue[] = "inline";
00183 static const char sigTypeFileValue[] = "file";
00184 static const char sigTypeCommandValue[] = "command";
00185 static const char sigTypeDisabledValue[] = "disabled";
00186 static const char sigTextKey[] = "Inline Signature";
00187 static const char sigFileKey[] = "Signature File";
00188 static const char sigCommandKey[] = "Signature Command";
00189 static const char sigTypeInlinedHtmlKey[] = "Inlined Html";
00190 
00191 void Signature::readConfig( const KConfigGroup &config )
00192 {
00193   QString sigType = config.readEntry( sigTypeKey );
00194   if ( sigType == sigTypeInlineValue ) {
00195     mType = Inlined;
00196     mInlinedHtml = config.readEntry( sigTypeInlinedHtmlKey, false );
00197   } else if ( sigType == sigTypeFileValue ) {
00198     mType = FromFile;
00199     mUrl = config.readPathEntry( sigFileKey, QString() );
00200   } else if ( sigType == sigTypeCommandValue ) {
00201     mType = FromCommand;
00202     mUrl = config.readPathEntry( sigCommandKey, QString() );
00203   } else {
00204     mType = Disabled;
00205   }
00206   mText = config.readEntry( sigTextKey );
00207 }
00208 
00209 void Signature::writeConfig( KConfigGroup &config ) const
00210 {
00211   switch ( mType ) {
00212     case Inlined:
00213       config.writeEntry( sigTypeKey, sigTypeInlineValue );
00214       config.writeEntry( sigTypeInlinedHtmlKey, mInlinedHtml );
00215       break;
00216     case FromFile:
00217       config.writeEntry( sigTypeKey, sigTypeFileValue );
00218       config.writePathEntry( sigFileKey, mUrl );
00219       break;
00220     case FromCommand:
00221       config.writeEntry( sigTypeKey, sigTypeCommandValue );
00222       config.writePathEntry( sigCommandKey, mUrl );
00223       break;
00224     case Disabled:
00225       config.writeEntry( sigTypeKey, sigTypeDisabledValue );
00226     default:
00227       break;
00228   }
00229   config.writeEntry( sigTextKey, mText );
00230 }
00231 
00232 void Signature::insertIntoTextEdit( KRichTextEdit *textEdit,
00233                                     Placement placement, bool addSeparator )
00234 {
00235   QString signature;
00236   if ( addSeparator )
00237     signature = withSeparator();
00238   else
00239     signature = rawText();
00240 
00241   insertPlainSignatureIntoTextEdit( signature, textEdit, placement,
00242                    ( isInlinedHtml() &&
00243                      type() == KPIMIdentities::Signature::Inlined ) );
00244 }
00245 
00246 void Signature::insertPlainSignatureIntoTextEdit( const QString &signature, KRichTextEdit *textEdit,
00247                                                   Signature::Placement placement, bool isHtml )
00248 {
00249   if ( !signature.isEmpty() ) {
00250 
00251     // Save the modified state of the document, as inserting a signature
00252     // shouldn't change this. Restore it at the end of this function.
00253     bool isModified = textEdit->document()->isModified();
00254 
00255     // Move to the desired position, where the signature should be inserted
00256     QTextCursor cursor = textEdit->textCursor();
00257     QTextCursor oldCursor = cursor;
00258     cursor.beginEditBlock();
00259 
00260     if ( placement == End )
00261       cursor.movePosition( QTextCursor::End );
00262     else if ( placement == Start )
00263       cursor.movePosition( QTextCursor::Start );
00264     textEdit->setTextCursor( cursor );
00265 
00266     // Insert the signature and newlines depending on where it was inserted.
00267     bool hackForCursorsAtEnd = false;
00268     int oldCursorPos = -1;
00269     if ( placement == End ) {
00270 
00271       if ( oldCursor.position() == textEdit->toPlainText().length() ) {
00272         hackForCursorsAtEnd = true;
00273         oldCursorPos = oldCursor.position();
00274       }
00275 
00276       if ( isHtml ) {
00277         textEdit->insertHtml( QLatin1String( "<br>" ) + signature );
00278       } else {
00279         textEdit->insertPlainText( QLatin1Char( '\n' ) + signature );
00280       }
00281     } else if ( placement == Start || placement == AtCursor ) {
00282       if ( isHtml ) {
00283         textEdit->insertHtml( QLatin1String( "<br>" ) + signature + QLatin1String( "<br>" ) );
00284       } else {
00285         textEdit->insertPlainText( QLatin1Char( '\n' ) + signature + QLatin1Char( '\n' ) );
00286       }
00287     }
00288 
00289     cursor.endEditBlock();
00290 
00291     // There is one special case when re-setting the old cursor: The cursor
00292     // was at the end. In this case, QTextEdit has no way to know
00293     // if the signature was added before or after the cursor, and just decides
00294     // that it was added before (and the cursor moves to the end, but it should
00295     // not when appending a signature). See bug 167961
00296     if ( hackForCursorsAtEnd )
00297       oldCursor.setPosition( oldCursorPos );
00298 
00299     textEdit->setTextCursor( oldCursor );
00300     textEdit->ensureCursorVisible();
00301 
00302     textEdit->document()->setModified( isModified );
00303 
00304     if ( isHtml )
00305       textEdit->enableRichTextMode();
00306   }
00307 }
00308 
00309 // --------------------- Operators -------------------//
00310 
00311 QDataStream &KPIMIdentities::operator<<
00312 ( QDataStream &stream, const KPIMIdentities::Signature &sig )
00313 {
00314   return stream << static_cast<quint8>( sig.mType ) << sig.mUrl << sig.mText;
00315 }
00316 
00317 QDataStream &KPIMIdentities::operator>>
00318 ( QDataStream &stream, KPIMIdentities::Signature &sig )
00319 {
00320   quint8 s;
00321   stream >> s  >> sig.mUrl >> sig.mText;
00322   sig.mType = static_cast<Signature::Type>( s );
00323   return stream;
00324 }
00325 
00326 bool Signature::operator== ( const Signature &other ) const
00327 {
00328   if ( mType != other.mType ) {
00329     return false;
00330   }
00331 
00332   switch ( mType ) {
00333   case Inlined:
00334     return mText == other.mText;
00335   case FromFile:
00336   case FromCommand:
00337     return mUrl == other.mUrl;
00338   default:
00339   case Disabled:
00340     return true;
00341   }
00342 }
00343 
00344 // --------------- Getters -----------------------//
00345 
00346 QString Signature::text() const
00347 {
00348   return mText;
00349 }
00350 
00351 QString Signature::url() const
00352 {
00353   return mUrl;
00354 }
00355 
00356 Signature::Type Signature::type() const
00357 {
00358   return mType;
00359 }
00360 
00361 // --------------- Setters -----------------------//
00362 
00363 void Signature::setText( const QString &text )
00364 {
00365   mText = text;
00366   mType = Inlined;
00367 }
00368 
00369 void Signature::setType( Type type )
00370 {
00371   mType = type;
00372 }

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.8
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