• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.9.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 )
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  );
115  label = new QLabel( i18n("Obtain signature &text from:"), q );
116  label->setBuddy( q->mSourceCombo );
117  label->setEnabled( false ); // since !mEnableCheck->isChecked()
118  hlay->addWidget( label );
119  hlay->addWidget( q->mSourceCombo, 1 );
120 
121  // widget stack that is controlled by the source combo:
122  QStackedWidget * widgetStack = new QStackedWidget( q );
123  widgetStack->setEnabled( false ); // since !mEnableCheck->isChecked()
124  vlay->addWidget( widgetStack, 1 );
125  q->connect( q->mSourceCombo, SIGNAL(currentIndexChanged(int)),
126  widgetStack, SLOT(setCurrentIndex(int)) );
127  q->connect( q->mSourceCombo, SIGNAL(highlighted(int)),
128  widgetStack, SLOT(setCurrentIndex(int)) );
129  // connects for the enabling of the widgets depending on
130  // signatureEnabled:
131  q->connect( q->mEnableCheck, SIGNAL(toggled(bool)),
132  q->mSourceCombo, SLOT(setEnabled(bool)) );
133  q->connect( q->mEnableCheck, SIGNAL(toggled(bool)),
134  widgetStack, SLOT(setEnabled(bool)) );
135  q->connect( q->mEnableCheck, SIGNAL(toggled(bool)),
136  label, SLOT(setEnabled(bool)) );
137  // The focus might be still in the widget that is disabled
138  q->connect( q->mEnableCheck, SIGNAL(clicked()),
139  q->mEnableCheck, SLOT(setFocus()) );
140 
141  int pageno = 0;
142  // page 0: input field for direct entering:
143  page = new QWidget( widgetStack );
144  widgetStack->insertWidget( pageno, page );
145  page_vlay = new QVBoxLayout( page );
146 
147 #ifndef QT_NO_TOOLBAR
148  q->mEditToolBar = new KToolBar( q );
149  q->mEditToolBar->setToolButtonStyle( Qt::ToolButtonIconOnly );
150  page_vlay->addWidget( q->mEditToolBar, 0 );
151 
152  q->mFormatToolBar = new KToolBar( q );
153  q->mFormatToolBar->setToolButtonStyle( Qt::ToolButtonIconOnly );
154  page_vlay->addWidget( q->mFormatToolBar, 1 );
155 #endif
156 
157  q->mTextEdit = new KPIMTextEdit::TextEdit( q );
158  static_cast<KPIMTextEdit::TextEdit*>( q->mTextEdit )->enableImageActions();
159  page_vlay->addWidget( q->mTextEdit, 2 );
160  q->mTextEdit->setWhatsThis( i18n("Use this field to enter an arbitrary static signature."));
161  // exclude SupportToPlainText.
162  q->mTextEdit->setRichTextSupport( KRichTextWidget::FullTextFormattingSupport |
163  KRichTextWidget::FullListSupport |
164  KRichTextWidget::SupportAlignment |
165  KRichTextWidget::SupportRuleLine |
166  KRichTextWidget::SupportHyperlinks |
167  KRichTextWidget::SupportFormatPainting );
168 
169  // Fill the toolbars.
170  KActionCollection *actionCollection = new KActionCollection( q );
171  q->mTextEdit->createActions( actionCollection );
172 #ifndef QT_NO_TOOLBAR
173  q->mEditToolBar->addAction( actionCollection->action( "format_text_bold" ) );
174  q->mEditToolBar->addAction( actionCollection->action( "format_text_italic" ) );
175  q->mEditToolBar->addAction( actionCollection->action( "format_text_underline" ) );
176  q->mEditToolBar->addAction( actionCollection->action( "format_text_strikeout" ) );
177  q->mEditToolBar->addAction( actionCollection->action( "format_text_foreground_color" ) );
178  q->mEditToolBar->addAction( actionCollection->action( "format_text_background_color" ) );
179  q->mEditToolBar->addAction( actionCollection->action( "format_font_family" ) );
180  q->mEditToolBar->addAction( actionCollection->action( "format_font_size" ) );
181 
182  q->mFormatToolBar->addAction( actionCollection->action( "format_list_style" ) );
183  q->mFormatToolBar->addAction( actionCollection->action( "format_list_indent_more" ) );
184  q->mFormatToolBar->addAction( actionCollection->action( "format_list_indent_less" ) );
185  q->mFormatToolBar->addAction( actionCollection->action( "format_list_indent_less" ) );
186  q->mFormatToolBar->addSeparator();
187 
188  q->mFormatToolBar->addAction( actionCollection->action( "format_align_left" ) );
189  q->mFormatToolBar->addAction( actionCollection->action( "format_align_center" ) );
190  q->mFormatToolBar->addAction( actionCollection->action( "format_align_right" ) );
191  q->mFormatToolBar->addAction( actionCollection->action( "format_align_justify" ) );
192  q->mFormatToolBar->addSeparator();
193 
194  q->mFormatToolBar->addAction( actionCollection->action( "insert_horizontal_rule" ) );
195  q->mFormatToolBar->addAction( actionCollection->action( "manage_link" ) );
196  q->mFormatToolBar->addAction( actionCollection->action( "format_painter" ) );
197 
198  q->mFormatToolBar->addSeparator();
199  q->mFormatToolBar->addAction( actionCollection->action( "add_image" ) );
200 #endif
201 
202  hlay = new QHBoxLayout(); // inherits spacing
203  page_vlay->addLayout( hlay );
204  q->mHtmlCheck = new QCheckBox( i18n("&Use HTML"), page );
205  q->connect( q->mHtmlCheck, SIGNAL(clicked()),
206  q, SLOT(slotSetHtml()) );
207  hlay->addWidget( q->mHtmlCheck );
208  inlinedHtml = true;
209 
210  widgetStack->setCurrentIndex( 0 ); // since mSourceCombo->currentItem() == 0
211 
212  // page 1: "signature file" requester, label, "edit file" button:
213  ++pageno;
214  page = new QWidget( widgetStack );
215  widgetStack->insertWidget( pageno, page ); // force sequential numbers (play safe)
216  page_vlay = new QVBoxLayout( page );
217  page_vlay->setMargin( 0 );
218  hlay = new QHBoxLayout(); // inherits spacing
219  page_vlay->addLayout( hlay );
220  q->mFileRequester = new KUrlRequester( page );
221  q->mFileRequester->setWhatsThis(
222  i18n("Use this requester to specify a text file that contains your "
223  "signature. It will be read every time you create a new mail or "
224  "append a new signature."));
225  label = new QLabel( i18n("S&pecify file:"), page );
226  label->setBuddy( q->mFileRequester );
227  hlay->addWidget( label );
228  hlay->addWidget( q->mFileRequester, 1 );
229  q->mFileRequester->button()->setAutoDefault( false );
230  q->connect( q->mFileRequester, SIGNAL(textChanged(QString)),
231  q, SLOT(slotEnableEditButton(QString)) );
232  q->mEditButton = new QPushButton( i18n("Edit &File"), page );
233  q->mEditButton->setWhatsThis( i18n("Opens the specified file in a text editor."));
234  q->connect( q->mEditButton, SIGNAL(clicked()),
235  q, SLOT(slotEdit()) );
236  q->mEditButton->setAutoDefault( false );
237  q->mEditButton->setEnabled( false ); // initially nothing to edit
238  hlay->addWidget( q->mEditButton );
239  page_vlay->addStretch( 1 ); // spacer
240 
241  // page 2: "signature command" requester and label:
242  ++pageno;
243  page = new QWidget( widgetStack );
244  widgetStack->insertWidget( pageno,page );
245  page_vlay = new QVBoxLayout( page );
246  page_vlay->setMargin( 0 );
247  hlay = new QHBoxLayout(); // inherits spacing
248  page_vlay->addLayout( hlay );
249  q->mCommandEdit = new KLineEdit( page );
250  q->mCommandEdit->setCompletionObject( new KShellCompletion() );
251  q->mCommandEdit->setAutoDeleteCompletionObject( true );
252  q->mCommandEdit->setWhatsThis(
253  i18n("You can add an arbitrary command here, either with or without path "
254  "depending on whether or not the command is in your Path. For every "
255  "new mail, KMail will execute the command and use what it outputs (to "
256  "standard output) as a signature. Usual commands for use with this "
257  "mechanism are \"fortune\" or \"ksig -random\"."));
258  label = new QLabel( i18n("S&pecify command:"), page );
259  label->setBuddy( q->mCommandEdit );
260  hlay->addWidget( label );
261  hlay->addWidget( q->mCommandEdit, 1 );
262  page_vlay->addStretch( 1 ); // spacer
263 }
264 
265  SignatureConfigurator::SignatureConfigurator( QWidget * parent )
266  : QWidget( parent ), d( new Private( this ) )
267  {
268  d->init();
269  }
270 
271  SignatureConfigurator::~SignatureConfigurator()
272  {
273  delete d;
274  }
275 
276  bool SignatureConfigurator::isSignatureEnabled() const
277  {
278  return mEnableCheck->isChecked();
279  }
280 
281  void SignatureConfigurator::setSignatureEnabled( bool enable )
282  {
283  mEnableCheck->setChecked( enable );
284  }
285 
286  Signature::Type SignatureConfigurator::signatureType() const
287  {
288  switch ( mSourceCombo->currentIndex() ) {
289  case 0: return Signature::Inlined;
290  case 1: return Signature::FromFile;
291  case 2: return Signature::FromCommand;
292  default: return Signature::Disabled;
293  }
294  }
295 
296  void SignatureConfigurator::setSignatureType( Signature::Type type )
297  {
298  int idx = 0;
299  switch( type ) {
300  case Signature::Inlined: idx = 0; break;
301  case Signature::FromFile: idx = 1; break;
302  case Signature::FromCommand: idx = 2; break;
303  default: idx = 0; break;
304  };
305 
306  mSourceCombo->setCurrentIndex( idx );
307  }
308 
309  void SignatureConfigurator::setInlineText( const QString & text )
310  {
311  mTextEdit->setTextOrHtml( text );
312  }
313 
314  QString SignatureConfigurator::fileURL() const
315  {
316  QString file = mFileRequester->url().path();
317 
318  // Force the filename to be relative to ~ instead of $PWD depending
319  // on the rest of the code (KRun::run in Edit and KFileItem on save)
320  if ( !file.isEmpty() && QFileInfo( file ).isRelative() )
321  file = QDir::home().absolutePath() + QDir::separator() + file;
322 
323  return file;
324  }
325 
326  void SignatureConfigurator::setFileURL( const QString & url )
327  {
328  mFileRequester->setUrl( url );
329  }
330 
331  QString SignatureConfigurator::commandURL() const
332  {
333  return mCommandEdit->text();
334  }
335 
336  void SignatureConfigurator::setCommandURL( const QString & url )
337  {
338  mCommandEdit->setText( url );
339  }
340 
341 
342  Signature SignatureConfigurator::signature() const
343  {
344  Signature sig;
345  const Signature::Type sigType = signatureType();
346  switch ( sigType ) {
347  case Signature::Inlined:
348  sig.setInlinedHtml( d->inlinedHtml );
349  sig.setText( d->inlinedHtml ? asCleanedHTML() : mTextEdit->textOrHtml() );
350  if ( d->inlinedHtml ) {
351  if ( !d->imageLocation.isEmpty() )
352  sig.setImageLocation( d->imageLocation );
353  KPIMTextEdit::ImageWithNameList images = static_cast< KPIMTextEdit::TextEdit*>( mTextEdit )->imagesWithName();
354  foreach( const KPIMTextEdit::ImageWithNamePtr &image, images ) {
355  sig.addImage( image->image, image->name );
356  }
357  }
358  break;
359  case Signature::FromCommand:
360  sig.setUrl( commandURL(), true );
361  break;
362  case Signature::FromFile:
363  sig.setUrl( fileURL(), false );
364  break;
365  case Signature::Disabled:
366  /* do nothing */
367  break;
368  }
369  sig.setEnabledSignature(isSignatureEnabled());
370  sig.setType( sigType );
371  return sig;
372  }
373 
374  void SignatureConfigurator::setSignature( const Signature & sig )
375  {
376  setSignatureType( sig.type() );
377  setSignatureEnabled( sig.isEnabledSignature() );
378 
379  if ( sig.isInlinedHtml() )
380  mHtmlCheck->setCheckState( Qt::Checked );
381  else
382  mHtmlCheck->setCheckState( Qt::Unchecked );
383  slotSetHtml();
384 
385  // Let insertIntoTextEdit() handle setting the text, as that function also adds the images.
386  mTextEdit->clear();
387  KPIMTextEdit::TextEdit * const pimEdit = static_cast<KPIMTextEdit::TextEdit*>( mTextEdit );
388  sig.insertIntoTextEdit( KPIMIdentities::Signature::Start, KPIMIdentities::Signature::AddNothing,
389  pimEdit,true );
390  if ( sig.type() == Signature::FromFile )
391  setFileURL( sig.url() );
392  else
393  setFileURL( QString() );
394 
395  if ( sig.type() == Signature::FromCommand )
396  setCommandURL( sig.url() );
397  else
398  setCommandURL( QString() );
399  }
400 
401  void SignatureConfigurator::slotEnableEditButton( const QString & url )
402  {
403  mEditButton->setDisabled( url.trimmed().isEmpty() );
404  }
405 
406  void SignatureConfigurator::slotEdit()
407  {
408  QString url = fileURL();
409  // slotEnableEditButton should prevent this assert from being hit:
410  assert( !url.isEmpty() );
411 
412  (void)KRun::runUrl( KUrl( url ), QString::fromLatin1("text/plain"), this );
413  }
414 
415  QString SignatureConfigurator::asCleanedHTML() const
416  {
417  QString text = mTextEdit->toHtml();
418 
419  // Beautiful little hack to find the html headers produced by Qt.
420  QTextDocument textDocument;
421  QString html = textDocument.toHtml();
422 
423  // Now remove each line from the text, the result is clean html.
424  foreach( const QString& line, html.split( '\n' ) ){
425  text.remove( line + '\n' );
426  }
427  return text;
428  }
429 
430  // "use HTML"-checkbox (un)checked
431  void SignatureConfigurator::slotSetHtml()
432  {
433  if ( mHtmlCheck->checkState() == Qt::Unchecked ) {
434  mHtmlCheck->setText( i18n("&Use HTML") );
435 #ifndef QT_NO_TOOLBAR
436  mEditToolBar->setVisible( false );
437  mEditToolBar->setEnabled( false );
438  mFormatToolBar->setVisible( false );
439  mFormatToolBar->setEnabled( false );
440 #endif
441  mTextEdit->switchToPlainText();
442  d->inlinedHtml = false;
443  }
444  else {
445  mHtmlCheck->setText( i18n("&Use HTML (disabling removes formatting)") );
446  d->inlinedHtml = true;
447 #ifndef QT_NO_TOOLBAR
448  mEditToolBar->setVisible( true );
449  mEditToolBar->setEnabled( true );
450  mFormatToolBar->setVisible( true );
451  mFormatToolBar->setEnabled( true );
452 #endif
453  mTextEdit->enableRichTextMode();
454  }
455  }
456 
457  void SignatureConfigurator::setImageLocation ( const QString& path )
458  {
459  d->imageLocation = path;
460  }
461 
462  void SignatureConfigurator::setImageLocation( const Identity &identity )
463  {
464  const QString dir = QString( "emailidentities/%1/" ).arg(
465  QString::number( identity.uoid() ) );
466  setImageLocation( KStandardDirs::locateLocal( "data", dir ) );
467  }
468 
469 }
470 
471 #include "signatureconfigurator.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2013 The KDE developers.
Generated on Sat Jan 5 2013 19:48:09 by doxygen 1.8.1.2 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.9.5 API Reference

Skip menu "kdepimlibs-4.9.5 API Reference"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • 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