• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.10.5 API Reference
  • KDE Home
  • Contact Us
 

kpimidentities

  • kpimidentities
signatureconfigurator.cpp
1 /* -*- c++ -*-
2  Copyright 2008 Thomas McGuire <Thomas.McGuire@gmx.net>
3  Copyright 2008 Edwin Schepers <yez@familieschepers.nl>
4  Copyright 2004 Marc Mutz <mutz@kde.org>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either
9  version 2.1 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public
17  License along with this library. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 
21 #include "signatureconfigurator.h"
22 #include "identity.h"
23 
24 #include <kactioncollection.h>
25 #include <klocale.h>
26 #include <kdebug.h>
27 #include <kdialog.h>
28 #include <klineedit.h>
29 #include <kurlrequester.h>
30 #include <kshellcompletion.h>
31 #include <ktoolbar.h>
32 #include <krun.h>
33 #include <KComboBox>
34 #include <KStandardDirs>
35 
36 #include <kpimtextedit/textedit.h>
37 
38 #include <QCheckBox>
39 #include <QDir>
40 #include <QFileInfo>
41 #include <QLabel>
42 #include <QLayout>
43 #include <QMimeData>
44 #include <QTextEdit>
45 
46 #include <QStackedWidget>
47 
48 #include <QVBoxLayout>
49 #include <QHBoxLayout>
50 
51 #include <assert.h>
52 
53 using namespace KPIMIdentities;
54 
55 namespace KPIMIdentities {
56 
61 //@cond PRIVATE
62 class SignatureConfigurator::Private
63 {
64  public:
65  Private( SignatureConfigurator *parent );
66  void init();
67 
68  SignatureConfigurator *q;
69  bool inlinedHtml;
70  QString imageLocation;
71 };
72 //@endcond
73 
74 SignatureConfigurator::Private::Private( SignatureConfigurator *parent )
75  :q( parent ), inlinedHtml( true )
76 {
77 }
78 
79 void SignatureConfigurator::Private::init()
80 {
81  // tmp. vars:
82  QLabel * label;
83  QWidget * page;
84  QHBoxLayout * hlay;
85  QVBoxLayout * vlay;
86  QVBoxLayout * page_vlay;
87 
88  vlay = new QVBoxLayout( q );
89  vlay->setObjectName( "main layout" );
90  vlay->setMargin( 0 );
91 
92  // "enable signatue" checkbox:
93  q->mEnableCheck = new QCheckBox( i18n( "&Enable signature" ), q );
94  q->mEnableCheck->setWhatsThis(
95  i18n( "Check this box if you want KMail to append a signature to mails "
96  "written with this identity." ) );
97  vlay->addWidget( q->mEnableCheck );
98 
99  // "obtain signature text from" combo and label:
100  hlay = new QHBoxLayout(); // inherits spacing
101  vlay->addLayout( hlay );
102  q->mSourceCombo = new KComboBox( q );
103  q->mSourceCombo->setEditable( false );
104  q->mSourceCombo->setWhatsThis(
105  i18n( "Click on the widgets below to obtain help on the input methods." ) );
106  q->mSourceCombo->setEnabled( false ); // since !mEnableCheck->isChecked()
107  q->mSourceCombo->addItems( QStringList()
108  << i18nc( "continuation of \"obtain signature text from\"",
109  "Input Field Below" )
110  << i18nc( "continuation of \"obtain signature text from\"",
111  "File" )
112  << i18nc( "continuation of \"obtain signature text from\"",
113  "Output of Command" ) );
114  label = new QLabel( i18n( "Obtain signature &text from:" ), q );
115  label->setBuddy( q->mSourceCombo );
116  label->setEnabled( false ); // since !mEnableCheck->isChecked()
117  hlay->addWidget( label );
118  hlay->addWidget( q->mSourceCombo, 1 );
119 
120  // widget stack that is controlled by the source combo:
121  QStackedWidget * widgetStack = new QStackedWidget( q );
122  widgetStack->setEnabled( false ); // since !mEnableCheck->isChecked()
123  vlay->addWidget( widgetStack, 1 );
124  q->connect( q->mSourceCombo, SIGNAL(currentIndexChanged(int)),
125  widgetStack, SLOT(setCurrentIndex(int)) );
126  q->connect( q->mSourceCombo, SIGNAL(highlighted(int)),
127  widgetStack, SLOT(setCurrentIndex(int)) );
128  // connects for the enabling of the widgets depending on
129  // signatureEnabled:
130  q->connect( q->mEnableCheck, SIGNAL(toggled(bool)),
131  q->mSourceCombo, SLOT(setEnabled(bool)) );
132  q->connect( q->mEnableCheck, SIGNAL(toggled(bool)),
133  widgetStack, SLOT(setEnabled(bool)) );
134  q->connect( q->mEnableCheck, SIGNAL(toggled(bool)),
135  label, SLOT(setEnabled(bool)) );
136  // The focus might be still in the widget that is disabled
137  q->connect( q->mEnableCheck, SIGNAL(clicked()),
138  q->mEnableCheck, SLOT(setFocus()) );
139 
140  int pageno = 0;
141  // page 0: input field for direct entering:
142  page = new QWidget( widgetStack );
143  widgetStack->insertWidget( pageno, page );
144  page_vlay = new QVBoxLayout( page );
145 
146 #ifndef QT_NO_TOOLBAR
147  q->mEditToolBar = new KToolBar( q );
148  q->mEditToolBar->setToolButtonStyle( Qt::ToolButtonIconOnly );
149  page_vlay->addWidget( q->mEditToolBar, 0 );
150 
151  q->mFormatToolBar = new KToolBar( q );
152  q->mFormatToolBar->setToolButtonStyle( Qt::ToolButtonIconOnly );
153  page_vlay->addWidget( q->mFormatToolBar, 1 );
154 #endif
155 
156  q->mTextEdit = new KPIMTextEdit::TextEdit( q );
157  static_cast<KPIMTextEdit::TextEdit*>( q->mTextEdit )->enableImageActions();
158  static_cast<KPIMTextEdit::TextEdit*>( q->mTextEdit )->enableInsertHtmlActions();
159  static_cast<KPIMTextEdit::TextEdit*>( q->mTextEdit )->enableInsertTableActions();
160  page_vlay->addWidget( q->mTextEdit, 2 );
161  q->mTextEdit->setWhatsThis( i18n( "Use this field to enter an arbitrary static signature." ) );
162  // exclude SupportToPlainText.
163  q->mTextEdit->setRichTextSupport( KRichTextWidget::FullTextFormattingSupport |
164  KRichTextWidget::FullListSupport |
165  KRichTextWidget::SupportAlignment |
166  KRichTextWidget::SupportRuleLine |
167  KRichTextWidget::SupportHyperlinks |
168  KRichTextWidget::SupportFormatPainting );
169 
170  // Fill the toolbars.
171  KActionCollection *actionCollection = new KActionCollection( q );
172  q->mTextEdit->createActions( actionCollection );
173 #ifndef QT_NO_TOOLBAR
174  q->mEditToolBar->addAction( actionCollection->action( "format_text_bold" ) );
175  q->mEditToolBar->addAction( actionCollection->action( "format_text_italic" ) );
176  q->mEditToolBar->addAction( actionCollection->action( "format_text_underline" ) );
177  q->mEditToolBar->addAction( actionCollection->action( "format_text_strikeout" ) );
178  q->mEditToolBar->addAction( actionCollection->action( "format_text_foreground_color" ) );
179  q->mEditToolBar->addAction( actionCollection->action( "format_text_background_color" ) );
180  q->mEditToolBar->addAction( actionCollection->action( "format_font_family" ) );
181  q->mEditToolBar->addAction( actionCollection->action( "format_font_size" ) );
182  q->mEditToolBar->addAction( actionCollection->action( "format_reset" ) );
183 
184  q->mFormatToolBar->addAction( actionCollection->action( "format_list_style" ) );
185  q->mFormatToolBar->addAction( actionCollection->action( "format_list_indent_more" ) );
186  q->mFormatToolBar->addAction( actionCollection->action( "format_list_indent_less" ) );
187  q->mFormatToolBar->addAction( actionCollection->action( "format_list_indent_less" ) );
188  q->mFormatToolBar->addSeparator();
189 
190  q->mFormatToolBar->addAction( actionCollection->action( "format_align_left" ) );
191  q->mFormatToolBar->addAction( actionCollection->action( "format_align_center" ) );
192  q->mFormatToolBar->addAction( actionCollection->action( "format_align_right" ) );
193  q->mFormatToolBar->addAction( actionCollection->action( "format_align_justify" ) );
194  q->mFormatToolBar->addSeparator();
195 
196  q->mFormatToolBar->addAction( actionCollection->action( "insert_horizontal_rule" ) );
197  q->mFormatToolBar->addAction( actionCollection->action( "manage_link" ) );
198  q->mFormatToolBar->addAction( actionCollection->action( "format_painter" ) );
199 
200  q->mFormatToolBar->addSeparator();
201  q->mFormatToolBar->addAction( actionCollection->action( "add_image" ) );
202  q->mFormatToolBar->addSeparator();
203  q->mFormatToolBar->addAction( actionCollection->action( "insert_html" ) );
204  q->mFormatToolBar->addAction( actionCollection->action( "insert_table" ) );
205 #endif
206 
207  hlay = new QHBoxLayout(); // inherits spacing
208  page_vlay->addLayout( hlay );
209  q->mHtmlCheck = new QCheckBox( i18n( "&Use HTML" ), page );
210  q->connect( q->mHtmlCheck, SIGNAL(clicked()),
211  q, SLOT(slotSetHtml()) );
212  hlay->addWidget( q->mHtmlCheck );
213  inlinedHtml = true;
214 
215  widgetStack->setCurrentIndex( 0 ); // since mSourceCombo->currentItem() == 0
216 
217  // page 1: "signature file" requester, label, "edit file" button:
218  ++pageno;
219  page = new QWidget( widgetStack );
220  widgetStack->insertWidget( pageno, page ); // force sequential numbers (play safe)
221  page_vlay = new QVBoxLayout( page );
222  page_vlay->setMargin( 0 );
223  hlay = new QHBoxLayout(); // inherits spacing
224  page_vlay->addLayout( hlay );
225  q->mFileRequester = new KUrlRequester( page );
226  q->mFileRequester->setWhatsThis(
227  i18n( "Use this requester to specify a text file that contains your "
228  "signature. It will be read every time you create a new mail or "
229  "append a new signature." ) );
230  label = new QLabel( i18n( "S&pecify file:" ), page );
231  label->setBuddy( q->mFileRequester );
232  hlay->addWidget( label );
233  hlay->addWidget( q->mFileRequester, 1 );
234  q->mFileRequester->button()->setAutoDefault( false );
235  q->connect( q->mFileRequester, SIGNAL(textChanged(QString)),
236  q, SLOT(slotEnableEditButton(QString)) );
237  q->mEditButton = new QPushButton( i18n( "Edit &File" ), page );
238  q->mEditButton->setWhatsThis( i18n( "Opens the specified file in a text editor." ) );
239  q->connect( q->mEditButton, SIGNAL(clicked()),
240  q, SLOT(slotEdit()) );
241  q->mEditButton->setAutoDefault( false );
242  q->mEditButton->setEnabled( false ); // initially nothing to edit
243  hlay->addWidget( q->mEditButton );
244  page_vlay->addStretch( 1 ); // spacer
245 
246  // page 2: "signature command" requester and label:
247  ++pageno;
248  page = new QWidget( widgetStack );
249  widgetStack->insertWidget( pageno, page );
250  page_vlay = new QVBoxLayout( page );
251  page_vlay->setMargin( 0 );
252  hlay = new QHBoxLayout(); // inherits spacing
253  page_vlay->addLayout( hlay );
254  q->mCommandEdit = new KLineEdit( page );
255  q->mCommandEdit->setCompletionObject( new KShellCompletion() );
256  q->mCommandEdit->setAutoDeleteCompletionObject( true );
257  q->mCommandEdit->setWhatsThis(
258  i18n( "You can add an arbitrary command here, either with or without path "
259  "depending on whether or not the command is in your Path. For every "
260  "new mail, KMail will execute the command and use what it outputs (to "
261  "standard output) as a signature. Usual commands for use with this "
262  "mechanism are \"fortune\" or \"ksig -random\"." ) );
263  label = new QLabel( i18n( "S&pecify command:" ), page );
264  label->setBuddy( q->mCommandEdit );
265  hlay->addWidget( label );
266  hlay->addWidget( q->mCommandEdit, 1 );
267  page_vlay->addStretch( 1 ); // spacer
268 }
269 
270  SignatureConfigurator::SignatureConfigurator( QWidget * parent )
271  : QWidget( parent ), d( new Private( this ) )
272  {
273  d->init();
274  }
275 
276  SignatureConfigurator::~SignatureConfigurator()
277  {
278  delete d;
279  }
280 
281  bool SignatureConfigurator::isSignatureEnabled() const
282  {
283  return mEnableCheck->isChecked();
284  }
285 
286  void SignatureConfigurator::setSignatureEnabled( bool enable )
287  {
288  mEnableCheck->setChecked( enable );
289  }
290 
291  Signature::Type SignatureConfigurator::signatureType() const
292  {
293  switch ( mSourceCombo->currentIndex() ) {
294  case 0: return Signature::Inlined;
295  case 1: return Signature::FromFile;
296  case 2: return Signature::FromCommand;
297  default: return Signature::Disabled;
298  }
299  }
300 
301  void SignatureConfigurator::setSignatureType( Signature::Type type )
302  {
303  int idx = 0;
304  switch ( type ) {
305  case Signature::Inlined: idx = 0; break;
306  case Signature::FromFile: idx = 1; break;
307  case Signature::FromCommand: idx = 2; break;
308  default: idx = 0; break;
309  };
310 
311  mSourceCombo->setCurrentIndex( idx );
312  }
313 
314  void SignatureConfigurator::setInlineText( const QString & text )
315  {
316  mTextEdit->setTextOrHtml( text );
317  }
318 
319  QString SignatureConfigurator::fileURL() const
320  {
321  QString file = mFileRequester->url().path();
322 
323  // Force the filename to be relative to ~ instead of $PWD depending
324  // on the rest of the code (KRun::run in Edit and KFileItem on save)
325  if ( !file.isEmpty() && QFileInfo( file ).isRelative() ) {
326  file = QDir::home().absolutePath() + QDir::separator() + file;
327  }
328  return file;
329  }
330 
331  void SignatureConfigurator::setFileURL( const QString & url )
332  {
333  mFileRequester->setUrl( QUrl(url) );
334  }
335 
336  QString SignatureConfigurator::commandURL() const
337  {
338  return mCommandEdit->text();
339  }
340 
341  void SignatureConfigurator::setCommandURL( const QString & url )
342  {
343  mCommandEdit->setText( url );
344  }
345 
346 
347  Signature SignatureConfigurator::signature() const
348  {
349  Signature sig;
350  const Signature::Type sigType = signatureType();
351  switch ( sigType ) {
352  case Signature::Inlined:
353  sig.setInlinedHtml( d->inlinedHtml );
354  sig.setText( d->inlinedHtml ? asCleanedHTML() : mTextEdit->textOrHtml() );
355  if ( d->inlinedHtml ) {
356  if ( !d->imageLocation.isEmpty() ) {
357  sig.setImageLocation( d->imageLocation );
358  }
359  KPIMTextEdit::ImageWithNameList images = static_cast< KPIMTextEdit::TextEdit*>( mTextEdit )->imagesWithName();
360  foreach ( const KPIMTextEdit::ImageWithNamePtr &image, images ) {
361  sig.addImage( image->image, image->name );
362  }
363  }
364  break;
365  case Signature::FromCommand:
366  sig.setUrl( commandURL(), true );
367  break;
368  case Signature::FromFile:
369  sig.setUrl( fileURL(), false );
370  break;
371  case Signature::Disabled:
372  /* do nothing */
373  break;
374  }
375  sig.setEnabledSignature( isSignatureEnabled() );
376  sig.setType( sigType );
377  return sig;
378  }
379 
380  void SignatureConfigurator::setSignature( const Signature & sig )
381  {
382  setSignatureType( sig.type() );
383  setSignatureEnabled( sig.isEnabledSignature() );
384 
385  if ( sig.isInlinedHtml() ) {
386  mHtmlCheck->setCheckState( Qt::Checked );
387  } else {
388  mHtmlCheck->setCheckState( Qt::Unchecked );
389  }
390  slotSetHtml();
391 
392  // Let insertIntoTextEdit() handle setting the text, as that function also adds the images.
393  mTextEdit->clear();
394  KPIMTextEdit::TextEdit * const pimEdit = static_cast<KPIMTextEdit::TextEdit*>( mTextEdit );
395  sig.insertIntoTextEdit( KPIMIdentities::Signature::Start, KPIMIdentities::Signature::AddNothing,
396  pimEdit, true );
397  if ( sig.type() == Signature::FromFile ) {
398  setFileURL( sig.url() );
399  } else {
400  setFileURL( QString() );
401  }
402 
403  if ( sig.type() == Signature::FromCommand ) {
404  setCommandURL( sig.url() );
405  } else {
406  setCommandURL( QString() );
407  }
408  }
409 
410  void SignatureConfigurator::slotEnableEditButton( const QString & url )
411  {
412  mEditButton->setDisabled( url.trimmed().isEmpty() );
413  }
414 
415  void SignatureConfigurator::slotEdit()
416  {
417  QString url = fileURL();
418  // slotEnableEditButton should prevent this assert from being hit:
419  assert( !url.isEmpty() );
420 
421  (void)KRun::runUrl( KUrl( url ), QString::fromLatin1( "text/plain" ), this );
422  }
423 
424  QString SignatureConfigurator::asCleanedHTML() const
425  {
426  QString text = mTextEdit->toHtml();
427 
428  // Beautiful little hack to find the html headers produced by Qt.
429  QTextDocument textDocument;
430  QString html = textDocument.toHtml();
431 
432  // Now remove each line from the text, the result is clean html.
433  foreach ( const QString& line, html.split( '\n' ) ) {
434  text.remove( line + '\n' );
435  }
436  return text;
437  }
438 
439  // "use HTML"-checkbox (un)checked
440  void SignatureConfigurator::slotSetHtml()
441  {
442  if ( mHtmlCheck->checkState() == Qt::Unchecked ) {
443  mHtmlCheck->setText( i18n( "&Use HTML" ) );
444 #ifndef QT_NO_TOOLBAR
445  mEditToolBar->setVisible( false );
446  mEditToolBar->setEnabled( false );
447  mFormatToolBar->setVisible( false );
448  mFormatToolBar->setEnabled( false );
449 #endif
450  mTextEdit->switchToPlainText();
451  d->inlinedHtml = false;
452  }
453  else {
454  mHtmlCheck->setText( i18n( "&Use HTML (disabling removes formatting)" ) );
455  d->inlinedHtml = true;
456 #ifndef QT_NO_TOOLBAR
457  mEditToolBar->setVisible( true );
458  mEditToolBar->setEnabled( true );
459  mFormatToolBar->setVisible( true );
460  mFormatToolBar->setEnabled( true );
461 #endif
462  mTextEdit->enableRichTextMode();
463  }
464  }
465 
466  void SignatureConfigurator::setImageLocation ( const QString& path )
467  {
468  d->imageLocation = path;
469  }
470 
471  void SignatureConfigurator::setImageLocation( const Identity &identity )
472  {
473  const QString dir = QString( "emailidentities/%1/" ).arg(
474  QString::number( identity.uoid() ) );
475  setImageLocation( KStandardDirs::locateLocal( "data", dir ) );
476  }
477 
478 }
479 
This file is part of the KDE documentation.
Documentation copyright © 1996-2013 The KDE developers.
Generated on Sat Jul 13 2013 01:30:05 by doxygen 1.8.3.1 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kpimidentities

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

kdepimlibs-4.10.5 API Reference

Skip menu "kdepimlibs-4.10.5 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal