• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdepim
  • Sitemap
  • Contact Us
 

knotes

knoteedit.cpp

Go to the documentation of this file.
00001 /*******************************************************************
00002  KNotes -- Notes for the KDE project
00003 
00004  Copyright (c) 1997-2006, The KNotes Developers
00005 
00006  This program is free software; you can redistribute it and/or
00007  modify it under the terms of the GNU General Public License
00008  as published by the Free Software Foundation; either version 2
00009  of the License, or (at your option) any later version.
00010 
00011  This program 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
00014  GNU General Public License for more details.
00015 
00016  You should have received a copy of the GNU General Public License
00017  along with this program; if not, write to the Free Software
00018  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019 *******************************************************************/
00020 
00021 #include <QFont>
00022 #include <QPixmap>
00023 
00024 #include <kaction.h>
00025 #include <kactioncollection.h>
00026 #include <kcolordialog.h>
00027 #include <kdebug.h>
00028 #include <kfontaction.h>
00029 #include <kfontsizeaction.h>
00030 #include <kicon.h>
00031 #include <klocale.h>
00032 #include <kmenu.h>
00033 #include <kstandardaction.h>
00034 #include <ktoggleaction.h>
00035 #include <kurl.h>
00036 
00037 #include "knoteedit.h"
00038 
00039 static const short SEP = 5;
00040 static const short ICON_SIZE = 10;
00041 
00042 
00043 KNoteEdit::KNoteEdit( KActionCollection *actions, QWidget *parent )
00044   : KTextEdit( parent ), m_editMenu( 0 )
00045 {
00046   setAcceptDrops( true );
00047   setWordWrapMode( QTextOption::WordWrap );
00048   setLineWrapMode( WidgetWidth );
00049   setAutoFormatting( AutoAll );
00050   
00051   // create the actions for the RMB menu
00052   QAction * undo = KStandardAction::undo( this, SLOT( undo() ), actions );
00053   QAction * redo = KStandardAction::redo( this, SLOT( redo() ), actions );
00054   undo->setEnabled( document()->isUndoAvailable() );
00055   redo->setEnabled( document()->isRedoAvailable() );
00056   
00057   m_cut = KStandardAction::cut( this, SLOT( cut() ), actions );
00058   m_copy = KStandardAction::copy( this, SLOT( copy() ), actions );
00059   m_paste = KStandardAction::paste( this, SLOT( paste() ), actions );
00060   
00061   m_cut->setEnabled( false );
00062   m_copy->setEnabled( false );
00063   m_paste->setEnabled( true );
00064   
00065   connect( this, SIGNAL( undoAvailable( bool ) ),
00066            undo, SLOT( setEnabled( bool ) ) );
00067   connect( this, SIGNAL( redoAvailable( bool ) ),
00068            redo, SLOT( setEnabled( bool ) ) );
00069   
00070   connect( this, SIGNAL( copyAvailable( bool ) ),
00071            m_cut, SLOT( setEnabled( bool ) ) );
00072   connect( this, SIGNAL( copyAvailable( bool ) ),
00073            m_copy, SLOT( setEnabled( bool ) ) );
00074   
00075   KStandardAction::clear( this, SLOT( clear() ), actions );
00076   KStandardAction::selectAll( this, SLOT( selectAll() ), actions );
00077   
00078   // create the actions modifying the text format
00079   m_textBold  = new KToggleAction( KIcon( "format-text-bold" ), i18n( "Bold" ),
00080                                    this );
00081   actions->addAction( "format_bold", m_textBold );
00082   m_textBold->setShortcut( QKeySequence( Qt::CTRL + Qt::Key_B ) );
00083   m_textItalic  = new KToggleAction( KIcon( "format-text-italic" ),
00084                                     i18n( "Italic" ), this );
00085   actions->addAction( "format_italic", m_textItalic );
00086   m_textItalic->setShortcut( QKeySequence( Qt::CTRL + Qt::Key_I ) );
00087   m_textUnderline  = new KToggleAction( KIcon( "format-text-underline" ),
00088                                         i18n( "Underline" ), this );
00089   actions->addAction( "format_underline", m_textUnderline );
00090   m_textUnderline->setShortcut( QKeySequence( Qt::CTRL + Qt::Key_U ) );
00091   m_textStrikeOut  = new KToggleAction( KIcon( "format-text-strikethrough" ),
00092                                         i18n( "Strike Out" ), this );
00093   actions->addAction( "format_strikeout", m_textStrikeOut );
00094   m_textStrikeOut->setShortcut( QKeySequence( Qt::CTRL + Qt::Key_S ) );
00095   
00096   connect( m_textBold, SIGNAL( toggled( bool ) ), SLOT( textBold( bool ) ) );
00097   connect( m_textItalic, SIGNAL( toggled( bool ) ),
00098            SLOT( setFontItalic( bool ) ) );
00099   connect( m_textUnderline, SIGNAL( toggled( bool ) ),
00100            SLOT( setFontUnderline( bool ) ) );
00101   connect( m_textStrikeOut, SIGNAL( toggled( bool ) ),
00102            SLOT( textStrikeOut( bool ) ) );
00103   
00104   m_textAlignLeft = new KToggleAction( KIcon( "format-justify-left" ),
00105                                        i18n( "Align Left" ), this );
00106   actions->addAction( "format_alignleft", m_textAlignLeft );
00107   connect( m_textAlignLeft, SIGNAL( triggered( bool ) ),
00108            SLOT( textAlignLeft() ) );
00109   m_textAlignLeft->setShortcut( QKeySequence( Qt::ALT + Qt::Key_L ) );
00110   m_textAlignLeft->setChecked( true ); // just a dummy, will be updated later
00111   m_textAlignCenter  = new KToggleAction( KIcon( "format-justify-center" ),
00112                                           i18n( "Align Center" ), this );
00113   actions->addAction( "format_aligncenter", m_textAlignCenter );
00114   connect( m_textAlignCenter, SIGNAL( triggered( bool ) ),
00115           SLOT( textAlignCenter() ) );
00116   m_textAlignCenter->setShortcut( QKeySequence( Qt::ALT + Qt::Key_C ) );
00117   m_textAlignRight = new KToggleAction( KIcon( "format-justify-right" ),
00118                                         i18n( "Align Right" ), this );
00119   actions->addAction( "format_alignright", m_textAlignRight );
00120   connect( m_textAlignRight, SIGNAL( triggered( bool ) ),
00121            SLOT( textAlignRight() ) );
00122   m_textAlignRight->setShortcut( QKeySequence( Qt::ALT + Qt::Key_R ) );
00123   m_textAlignBlock = new KToggleAction( KIcon( "format-justify-fill" ),
00124                                         i18n( "Align Block" ), this );
00125   actions->addAction( "format_alignblock", m_textAlignBlock );
00126   connect( m_textAlignBlock, SIGNAL( triggered( bool ) ),
00127            SLOT( textAlignBlock() ) );
00128   m_textAlignBlock->setShortcut( QKeySequence( Qt::ALT + Qt::Key_B ) );
00129   
00130   QActionGroup *group = new QActionGroup( this );
00131   group->addAction( m_textAlignLeft );
00132   group->addAction( m_textAlignCenter );
00133   group->addAction( m_textAlignRight );
00134   group->addAction( m_textAlignBlock );
00135   
00136   m_textList  = new KToggleAction( KIcon( "format-list-ordered" ), i18n( "List" ), this );
00137   actions->addAction( "format_list", m_textList );
00138   connect( m_textList, SIGNAL( triggered( bool ) ), SLOT( textList() ) );
00139   
00140   group = new QActionGroup( this );
00141   group->addAction( m_textList );
00142   
00143   m_textSuper  = new KToggleAction( KIcon( "format-text-superscript" ),
00144                                     i18n( "Superscript" ), this );
00145   actions->addAction( "format_super", m_textSuper );
00146   connect( m_textSuper, SIGNAL( triggered( bool ) ),
00147            SLOT( textSuperScript() ) );
00148   m_textSub  = new KToggleAction( KIcon( "format-text-subscript" ), i18n( "Subscript" ),
00149                                   this );
00150   actions->addAction( "format_sub", m_textSub );
00151   connect( m_textSub, SIGNAL( triggered( bool ) ), SLOT( textSubScript() ) );
00152   
00153   group = new QActionGroup( this );
00154   group->addAction( m_textSuper );
00155   group->addAction( m_textSub );
00156   
00157   m_textIncreaseIndent = new KAction( KIcon( "format-indent-more" ),
00158                                       i18n( "Increase Indent" ), this );
00159   actions->addAction( "format_increaseindent", m_textIncreaseIndent );
00160   m_textIncreaseIndent->setShortcut( QKeySequence( Qt::CTRL + Qt::ALT +
00161                                                    Qt::Key_I ) );
00162   connect( m_textIncreaseIndent, SIGNAL( triggered( bool ) ),
00163            SLOT( textIncreaseIndent() ) );
00164   
00165   m_textDecreaseIndent = new KAction(  KIcon( "format-indent-less" ),
00166                                        i18n( "Decrease Indent" ), this );
00167   actions->addAction( "format_decreaseindent", m_textDecreaseIndent );
00168   m_textDecreaseIndent->setShortcut( QKeySequence( Qt::CTRL + Qt::ALT +
00169                                                    Qt::Key_D ) );
00170   connect( m_textDecreaseIndent, SIGNAL( triggered( bool ) ), SLOT(
00171            textDecreaseIndent() ) );
00172   
00173   group = new QActionGroup( this );
00174   group->addAction( m_textIncreaseIndent );
00175   group->addAction( m_textDecreaseIndent );
00176   
00177   QPixmap pix( ICON_SIZE, ICON_SIZE );
00178   pix.fill( Qt::black ); // just a dummy, gets updated before widget is shown
00179   m_textColor  = new KAction( i18n( "Text Color..." ), this );
00180   actions->addAction( "format_color", m_textColor );
00181   ( ( QAction * )m_textColor )->setIcon( pix );
00182   connect( m_textColor, SIGNAL( triggered( bool ) ), SLOT( slotTextColor() ) );
00183   
00184   m_textFont  = new KFontAction( i18n( "Text Font" ), this );
00185   actions->addAction( "format_font", m_textFont );
00186   connect( m_textFont, SIGNAL( triggered( const QString & ) ),
00187            this, SLOT( setFontFamily( const QString & ) ) );
00188   
00189   m_textSize  = new KFontSizeAction( i18n( "Text Size" ), this );
00190   actions->addAction( "format_size", m_textSize );
00191   connect( m_textSize, SIGNAL( fontSizeChanged( int ) ),
00192            this, SLOT( setFontWeight ( int ) ) );
00193   
00194   // QTextEdit connections
00195   connect( this, SIGNAL( currentCharFormatChanged( const QTextCharFormat & ) ),
00196            SLOT( slotCurrentCharFormatChanged( const QTextCharFormat & ) ) );
00197   
00198 #ifdef __GNUC__
00199 #warning moving the cursor through alignment changes does not update the button!
00200 #endif
00201   slotCurrentCharFormatChanged( currentCharFormat() );
00202 }
00203 
00204 KNoteEdit::~KNoteEdit()
00205 {
00206 }
00207 
00208 void KNoteEdit::setText( const QString &text )
00209 {
00210   if ( acceptRichText() && Qt::mightBeRichText( text ) ) {
00211     setHtml( text );
00212   } else {
00213     setPlainText( text );
00214   }
00215 }
00216 
00217 QString KNoteEdit::text() const
00218 {
00219   if ( acceptRichText() ) {
00220     return toHtml();
00221   } else {
00222     return toPlainText();
00223   }
00224 }
00225 
00226 void KNoteEdit::setTextFont( const QFont &font )
00227 {
00228   QTextCharFormat f;
00229   f.setFont( font );
00230   setTextFormat( f );
00231 }
00232 
00233 void KNoteEdit::setTextColor( const QColor &color )
00234 {
00235   QTextCharFormat f;
00236   f.setForeground( QBrush( color ) );
00237   setTextFormat( f );
00238 }
00239 
00240 void KNoteEdit::setTabStop( int tabs )
00241 {
00242   QFontMetrics fm( font() );
00243   setTabStopWidth( fm.width( 'x' ) * tabs );
00244 }
00245 
00246 void KNoteEdit::setAutoIndentMode( bool newmode )
00247 {
00248   m_autoIndentMode = newmode;
00249 }
00250 
00251 
00254 void KNoteEdit::setRichText( bool f )
00255 {
00256   if ( f == acceptRichText() ) {
00257     return;
00258   }
00259   
00260   setAcceptRichText( f );
00261   
00262   QString t = toPlainText();
00263   if ( f ) {
00264     // if the note contains html source try to render it
00265     if ( Qt::mightBeRichText( t ) ) {
00266       setHtml( t );
00267     } else {
00268       setPlainText( t );
00269     }
00270     
00271     enableRichTextActions();
00272   } else {
00273     setPlainText( t );
00274     disableRichTextActions();
00275   }
00276 }
00277 
00278 void KNoteEdit::textBold( bool b )
00279 {
00280   QTextCharFormat f;
00281   f.setFontWeight( b ? QFont::Bold : QFont::Normal );
00282   mergeCurrentCharFormat( f );
00283 }
00284 
00285 void KNoteEdit::textStrikeOut( bool s )
00286 {
00287   QTextCharFormat f;
00288   f.setFontStrikeOut( s );
00289   mergeCurrentCharFormat( f );
00290 }
00291 
00292 void KNoteEdit::slotTextColor()
00293 {
00294   QColor c = textColor();
00295   int ret = KColorDialog::getColor( c, this );
00296   
00297   if ( ret == QDialog::Accepted ) {
00298     setTextColor( c );
00299   }
00300 }
00301 
00302 void KNoteEdit::textAlignLeft()
00303 {
00304   setAlignment( Qt::AlignLeft );
00305   m_textAlignLeft->setChecked( true );
00306 }
00307 
00308 void KNoteEdit::textAlignCenter()
00309 {
00310   setAlignment( Qt::AlignCenter );
00311   m_textAlignCenter->setChecked( true );
00312 }
00313 
00314 void KNoteEdit::textAlignRight()
00315 {
00316   setAlignment( Qt::AlignRight );
00317   m_textAlignRight->setChecked( true );
00318 }
00319 
00320 void KNoteEdit::textAlignBlock()
00321 {
00322   setAlignment( Qt::AlignJustify );
00323   m_textAlignBlock->setChecked( true );
00324 }
00325 
00326 void KNoteEdit::textList()
00327 {
00328   QTextCursor c = textCursor();
00329   c.beginEditBlock();
00330   
00331   if ( m_textList->isChecked() ) {
00332     QTextListFormat lf;
00333     QTextBlockFormat bf = c.blockFormat();
00334     
00335     lf.setIndent( bf.indent() + 1 );
00336     bf.setIndent( 0 );
00337     
00338     lf.setStyle( QTextListFormat::ListDisc );
00339     
00340     c.setBlockFormat( bf );
00341     c.createList( lf );
00342   } else {
00343     QTextBlockFormat bf;
00344     bf.setObjectIndex( -1 );
00345     c.mergeBlockFormat( bf );
00346   }
00347   
00348   c.endEditBlock();
00349 }
00350 
00351 void KNoteEdit::textSuperScript()
00352 {
00353   QTextCharFormat f;
00354   
00355   if ( m_textSuper->isChecked() ) {
00356     f.setVerticalAlignment( QTextCharFormat::AlignSuperScript );
00357   } else {
00358     f.setVerticalAlignment( QTextCharFormat::AlignNormal );
00359   }
00360   mergeCurrentCharFormat( f );
00361 }
00362 
00363 void KNoteEdit::textSubScript()
00364 {
00365   QTextCharFormat f;
00366   
00367   if ( m_textSub->isChecked() ) {
00368     f.setVerticalAlignment( QTextCharFormat::AlignSubScript );
00369   } else {
00370     f.setVerticalAlignment( QTextCharFormat::AlignNormal );
00371   }
00372   mergeCurrentCharFormat( f );
00373 }
00374 
00375 void KNoteEdit::textIncreaseIndent()
00376 {
00377   QTextBlockFormat f = textCursor().blockFormat();
00378   f.setIndent( f.indent() + 1 );
00379   textCursor().setBlockFormat( f );
00380 }
00381 
00382 void KNoteEdit::textDecreaseIndent()
00383 {
00384   QTextBlockFormat f = textCursor().blockFormat();
00385   short int curIndent = f.indent();
00386   
00387   if ( curIndent > 0 ) {
00388     f.setIndent( curIndent - 1 );
00389   }
00390   textCursor().setBlockFormat( f );
00391 }
00392 
00393 
00396 void KNoteEdit::contextMenuEvent( QContextMenuEvent *e )
00397 {
00398   if ( m_editMenu ) {
00399     m_editMenu->popup( e->globalPos() );
00400   }
00401 }
00402 
00403 void KNoteEdit::dragEnterEvent( QDragEnterEvent *e )
00404 {
00405   const QMimeData *md = e->mimeData();
00406   if ( KUrl::List::canDecode( md ) ) {
00407     e->accept();
00408   } else {
00409     KTextEdit::dragEnterEvent( e );
00410   }
00411 }
00412 
00413 void KNoteEdit::dropEvent( QDropEvent *e )
00414 {
00415   const QMimeData *md = e->mimeData();
00416   
00417   if ( KUrl::List::canDecode( md ) ) {
00418     KUrl::List list = KUrl::List::fromMimeData( md );
00419     for ( KUrl::List::Iterator it = list.begin(); it != list.end(); ++it ) {
00420       if ( it != list.begin() ) {
00421         insertPlainText( ", " );
00422       }
00423       insertPlainText( ( *it ).prettyUrl() );
00424     }
00425   } else { KTextEdit::dropEvent( e ); }
00426 }
00427 
00428 void KNoteEdit::keyPressEvent( QKeyEvent *e )
00429 {
00430   KTextEdit::keyPressEvent( e );
00431   
00432   if ( m_autoIndentMode &&
00433        ( ( e->key() == Qt::Key_Return ) || ( e->key() == Qt::Key_Enter ) ) ) {
00434     autoIndent();
00435   }
00436 }
00437 
00438 void KNoteEdit::focusInEvent( QFocusEvent *e )
00439 {
00440   KTextEdit::focusInEvent( e );
00441   
00442   setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded );
00443   setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded );
00444 }
00445 
00446 void KNoteEdit::focusOutEvent( QFocusEvent *e )
00447 {
00448   setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
00449   setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
00450   
00451   KTextEdit::focusOutEvent( e );
00452 }
00453 
00456 void KNoteEdit::slotCurrentCharFormatChanged( const QTextCharFormat &f )
00457 {
00458   // font changes
00459   m_textFont->setFont( f.fontFamily() );
00460   m_textSize->setFontSize( ( int ) f.fontPointSize() );
00461   
00462   m_textBold->setChecked( f.font().bold() );
00463   m_textItalic->setChecked( f.fontItalic() );
00464   m_textUnderline->setChecked( f.fontUnderline() );
00465   m_textStrikeOut->setChecked( f.fontStrikeOut() );
00466   
00467   // color changes
00468   QPixmap pix( ICON_SIZE, ICON_SIZE );
00469   pix.fill( f.foreground().color() );
00470   m_textColor->QAction::setIcon( pix );
00471   
00472   // alignment changes
00473   Qt::Alignment a = alignment();
00474   if ( a & Qt::AlignLeft ) {
00475     m_textAlignLeft->setChecked( true );
00476   } else if ( a & Qt::AlignHCenter ) {
00477     m_textAlignCenter->setChecked( true );
00478   } else if ( a & Qt::AlignRight ) {
00479     m_textAlignRight->setChecked( true );
00480   } else if ( a & Qt::AlignJustify ) {
00481     m_textAlignBlock->setChecked( true );
00482   }
00483   
00484   // vertical alignment changes
00485   QTextCharFormat::VerticalAlignment va = f.verticalAlignment();
00486   if ( va == QTextCharFormat::AlignNormal ) {
00487     m_textSuper->setChecked( false );
00488     m_textSub->setChecked( false );
00489   } else if ( va == QTextCharFormat::AlignSuperScript ) {
00490     m_textSuper->setChecked( true );
00491   } else if ( va == QTextCharFormat::AlignSubScript ) {
00492     m_textSub->setChecked( true );
00493   }
00494 }
00495 
00496 
00499 void KNoteEdit::autoIndent()
00500 {
00501   QTextCursor c = textCursor();
00502   QTextBlock b = c.block();
00503   
00504   QString string;
00505   while ( ( b.previous().length() > 0 ) && string.trimmed().isEmpty() ) {
00506     b = b.previous();
00507     string = b.text();
00508   }
00509   
00510   if ( string.trimmed().isEmpty() ) {
00511     return;
00512   }
00513   
00514   // This routine returns the whitespace before the first non white space
00515   // character in string.
00516   // It is assumed that string contains at least one non whitespace character
00517   // ie \n \r \t \v \f and space
00518   QString indentString;
00519   
00520   int len = string.length();
00521   int i = 0;
00522   while ( i < len && string.at( i ).isSpace() ) {
00523     indentString += string.at( i++ );
00524   }
00525   
00526   if ( !indentString.isEmpty() ) {
00527     c.insertText( indentString );
00528   }
00529 }
00530 
00531 void KNoteEdit::setTextFormat( const QTextCharFormat &f )
00532 {
00533   if ( acceptRichText() ) {
00534     textCursor().mergeCharFormat( f );
00535   } else {
00536     QTextCursor c( document() );
00537     c.movePosition( QTextCursor::Start );
00538     c.movePosition( QTextCursor::End, QTextCursor::KeepAnchor );
00539     c.mergeCharFormat( f );
00540   }
00541 }
00542 
00543 void KNoteEdit::enableRichTextActions()
00544 {
00545   m_textColor->setEnabled( true );
00546   m_textFont->setEnabled( true );
00547   m_textSize->setEnabled( true );
00548   
00549   m_textBold->setEnabled( true );
00550   m_textItalic->setEnabled( true );
00551   m_textUnderline->setEnabled( true );
00552   m_textStrikeOut->setEnabled( true );
00553   
00554   m_textAlignLeft->setEnabled( true );
00555   m_textAlignCenter->setEnabled( true );
00556   m_textAlignRight->setEnabled( true );
00557   m_textAlignBlock->setEnabled( true );
00558   
00559   m_textList->setEnabled( true );
00560   m_textSuper->setEnabled( true );
00561   m_textSub->setEnabled( true );
00562   
00563   m_textIncreaseIndent->setEnabled( true );
00564   m_textDecreaseIndent->setEnabled( true );
00565 }
00566 
00567 void KNoteEdit::disableRichTextActions()
00568 {
00569   m_textColor->setEnabled( false );
00570   m_textFont->setEnabled( false );
00571   m_textSize->setEnabled( false );
00572   
00573   m_textBold->setEnabled( false );
00574   m_textItalic->setEnabled( false );
00575   m_textUnderline->setEnabled( false );
00576   m_textStrikeOut->setEnabled( false );
00577   
00578   m_textAlignLeft->setEnabled( false );
00579   m_textAlignCenter->setEnabled( false );
00580   m_textAlignRight->setEnabled( false );
00581   m_textAlignBlock->setEnabled( false );
00582   
00583   m_textList->setEnabled( false );
00584   m_textSuper->setEnabled( false );
00585   m_textSub->setEnabled( false );
00586   
00587   m_textIncreaseIndent->setEnabled( false );
00588   m_textDecreaseIndent->setEnabled( false );
00589 }
00590 
00591 #include "knoteedit.moc"

knotes

Skip menu "knotes"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members

kdepim

Skip menu "kdepim"
  • akonadi
  •   clients
  •   kabc
  •   kcal
  •   kcm
  • akregator
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt
  • kdgantt1
  • kjots
  • kleopatra
  • kmail
  • kmobiletools
  • knode
  • knotes
  • kontact
  • kontactinterfaces
  • korganizer
  •   korgac
  • kpilot
  • ktimetracker
  • libkdepim
  • libkholidays
  • libkleo
  • libkpgp
  • maildir
Generated for kdepim by doxygen 1.5.4
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