1 | /* |
2 | Copyright (c) 2002-2004 Marc Mutz <mutz@kde.org> |
3 | Copyright (c) 2007 Tom Albers <tomalbers@kde.nl> |
4 | Copyright (c) 2009 Thomas McGuire <mcguire@kde.org> |
5 | |
6 | This library is free software; you can redistribute it and/or modify it |
7 | under the terms of the GNU Library General Public License as published by |
8 | the Free Software Foundation; either version 2 of the License, or (at your |
9 | option) any later version. |
10 | |
11 | This library is distributed in the hope that it will be useful, but WITHOUT |
12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public |
14 | License for more details. |
15 | |
16 | You should have received a copy of the GNU Library General Public License |
17 | along with this library; see the file COPYING.LIB. If not, write to the |
18 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
19 | 02110-1301, USA. |
20 | */ |
21 | |
22 | #include "signature.h" |
23 | |
24 | #include <kdebug.h> |
25 | #include <klocalizedstring.h> |
26 | #include <kmessagebox.h> |
27 | #include <kconfiggroup.h> |
28 | #include <kurl.h> |
29 | #include <kprocess.h> |
30 | #include <KRichTextEdit> |
31 | #include <kpimutils/kfileio.h> |
32 | |
33 | #include <QFileInfo> |
34 | #include <QSharedPointer> |
35 | #include <QImage> |
36 | |
37 | #include <assert.h> |
38 | #include <QtCore/QDir> |
39 | #include <kpimtextedit/textedit.h> |
40 | |
41 | using namespace KPIMIdentities; |
42 | |
43 | class SignaturePrivate |
44 | { |
45 | public: |
46 | SignaturePrivate() |
47 | :enabled( false ) |
48 | { |
49 | } |
50 | struct EmbeddedImage |
51 | { |
52 | QImage image; |
53 | QString name; |
54 | }; |
55 | typedef QSharedPointer<EmbeddedImage> EmbeddedImagePtr; |
56 | |
57 | /// List of images that belong to this signature. Either added by addImage() or |
58 | /// by readConfig(). |
59 | QList<EmbeddedImagePtr> embeddedImages; |
60 | |
61 | /// The directory where the images will be saved to. |
62 | QString saveLocation; |
63 | bool enabled; |
64 | }; |
65 | |
66 | QDataStream &operator<< ( QDataStream &stream, const SignaturePrivate::EmbeddedImagePtr &img ) |
67 | { |
68 | return stream << img->image << img->name; |
69 | } |
70 | |
71 | QDataStream &operator>> ( QDataStream &stream, SignaturePrivate::EmbeddedImagePtr &img ) |
72 | { |
73 | return stream >> img->image >> img->name; |
74 | } |
75 | |
76 | // TODO: KDE5: BIC: Add a real d-pointer. |
77 | // This QHash is just a workaround around BIC issues, for more info see |
78 | // http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C++ |
79 | typedef QHash<const Signature*,SignaturePrivate*> SigPrivateHash; |
80 | Q_GLOBAL_STATIC( SigPrivateHash, d_func ) |
81 | |
82 | static SignaturePrivate* d( const Signature *sig ) |
83 | { |
84 | SignaturePrivate *ret = d_func()->value( sig, 0 ); |
85 | if ( !ret ) { |
86 | ret = new SignaturePrivate; |
87 | d_func()->insert( sig, ret ); |
88 | } |
89 | return ret; |
90 | } |
91 | |
92 | static void delete_d( const Signature* sig ) |
93 | { |
94 | SignaturePrivate *ret = d_func()->value( sig, 0 ); |
95 | delete ret; |
96 | d_func()->remove( sig ); |
97 | } |
98 | |
99 | Signature::Signature() |
100 | : mType( Disabled ), |
101 | mInlinedHtml( false ) |
102 | {} |
103 | |
104 | Signature::Signature( const QString &text ) |
105 | : mText( text ), |
106 | mType( Inlined ), |
107 | mInlinedHtml( false ) |
108 | {} |
109 | |
110 | Signature::Signature( const QString &url, bool isExecutable ) |
111 | : mUrl( url ), |
112 | mType( isExecutable ? FromCommand : FromFile ), |
113 | mInlinedHtml( false ) |
114 | {} |
115 | |
116 | void Signature::assignFrom ( const KPIMIdentities::Signature &that ) |
117 | { |
118 | mUrl = that.mUrl; |
119 | mInlinedHtml = that.mInlinedHtml; |
120 | mText = that.mText; |
121 | mType = that.mType; |
122 | d( this )->enabled = d( &that )->enabled; |
123 | d( this )->saveLocation = d( &that )->saveLocation; |
124 | d( this )->embeddedImages = d( &that )->embeddedImages; |
125 | } |
126 | |
127 | Signature::Signature ( const Signature &that ) |
128 | { |
129 | assignFrom( that ); |
130 | } |
131 | |
132 | Signature& Signature::operator= ( const KPIMIdentities::Signature & that ) |
133 | { |
134 | if ( this == &that ) { |
135 | return *this; |
136 | } |
137 | |
138 | assignFrom( that ); |
139 | return *this; |
140 | } |
141 | |
142 | Signature::~Signature() |
143 | { |
144 | delete_d( this ); |
145 | } |
146 | |
147 | QString Signature::rawText( bool *ok ) const |
148 | { |
149 | switch ( mType ) { |
150 | case Disabled: |
151 | if ( ok ) { |
152 | *ok = true; |
153 | } |
154 | return QString(); |
155 | case Inlined: |
156 | if ( ok ) { |
157 | *ok = true; |
158 | } |
159 | return mText; |
160 | case FromFile: |
161 | return textFromFile( ok ); |
162 | case FromCommand: |
163 | return textFromCommand( ok ); |
164 | }; |
165 | kFatal( 5325 ) << "Signature::type() returned unknown value!" ; |
166 | return QString(); // make compiler happy |
167 | } |
168 | |
169 | QString Signature::textFromCommand( bool *ok ) const |
170 | { |
171 | assert( mType == FromCommand ); |
172 | |
173 | // handle pathological cases: |
174 | if ( mUrl.isEmpty() ) { |
175 | if ( ok ) { |
176 | *ok = true; |
177 | } |
178 | return QString(); |
179 | } |
180 | |
181 | // create a shell process: |
182 | KProcess proc; |
183 | proc.setOutputChannelMode( KProcess::SeparateChannels ); |
184 | proc.setShellCommand( mUrl ); |
185 | int rc = proc.execute(); |
186 | |
187 | // handle errors, if any: |
188 | if ( rc != 0 ) { |
189 | if ( ok ) { |
190 | *ok = false; |
191 | } |
192 | QString wmsg = i18n( "<qt>Failed to execute signature script<p><b>%1</b>:</p>" |
193 | "<p>%2</p></qt>" , mUrl, QLatin1String( proc.readAllStandardError() ) ); |
194 | KMessageBox::error( 0, wmsg ); |
195 | return QString(); |
196 | } |
197 | |
198 | // no errors: |
199 | if ( ok ) { |
200 | *ok = true; |
201 | } |
202 | |
203 | // get output: |
204 | QByteArray output = proc.readAllStandardOutput(); |
205 | |
206 | // TODO: hmm, should we allow other encodings, too? |
207 | return QString::fromLocal8Bit( output.data(), output.size() ); |
208 | } |
209 | |
210 | QString Signature::textFromFile( bool *ok ) const |
211 | { |
212 | assert( mType == FromFile ); |
213 | |
214 | // TODO: Use KIO::NetAccess to download non-local files! |
215 | if ( !KUrl( mUrl ).isLocalFile() && |
216 | !( QFileInfo( mUrl ).isRelative() && |
217 | QFileInfo( mUrl ).exists() ) ) { |
218 | kDebug( 5325 ) << "Signature::textFromFile:" |
219 | << "non-local URLs are unsupported" ; |
220 | if ( ok ) { |
221 | *ok = false; |
222 | } |
223 | return QString(); |
224 | } |
225 | |
226 | if ( ok ) { |
227 | *ok = true; |
228 | } |
229 | |
230 | // TODO: hmm, should we allow other encodings, too? |
231 | const QByteArray ba = KPIMUtils::kFileToByteArray( mUrl, false ); |
232 | return QString::fromLocal8Bit( ba.data(), ba.size() ); |
233 | } |
234 | |
235 | QString Signature::withSeparator( bool *ok ) const |
236 | { |
237 | QString signature = rawText( ok ); |
238 | if ( ok && ( *ok ) == false ) { |
239 | return QString(); |
240 | } |
241 | |
242 | if ( signature.isEmpty() ) { |
243 | return signature; // don't add a separator in this case |
244 | } |
245 | |
246 | const bool htmlSig = ( isInlinedHtml() && mType == Inlined ); |
247 | QString newline = htmlSig ? QLatin1String("<br>" ) : QLatin1String("\n" ); |
248 | if ( htmlSig && signature.startsWith( QLatin1String( "<p" ) ) ) { |
249 | newline.clear(); |
250 | } |
251 | |
252 | if ( signature.startsWith( QString::fromLatin1( "-- " ) + newline ) || |
253 | ( signature.indexOf( newline + QString::fromLatin1( "-- " ) + newline ) != -1 ) ) { |
254 | // already have signature separator at start of sig or inside sig: |
255 | return signature; |
256 | } else { |
257 | // need to prepend one: |
258 | return QString::fromLatin1( "-- " ) + newline + signature; |
259 | } |
260 | } |
261 | |
262 | void Signature::setUrl( const QString &url, bool isExecutable ) |
263 | { |
264 | mUrl = url; |
265 | mType = isExecutable ? FromCommand : FromFile; |
266 | } |
267 | |
268 | void Signature::setInlinedHtml( bool isHtml ) |
269 | { |
270 | mInlinedHtml = isHtml; |
271 | } |
272 | |
273 | bool Signature::isInlinedHtml() const |
274 | { |
275 | return mInlinedHtml; |
276 | } |
277 | |
278 | // config keys and values: |
279 | static const char sigTypeKey[] = "Signature Type" ; |
280 | static const char sigTypeInlineValue[] = "inline" ; |
281 | static const char sigTypeFileValue[] = "file" ; |
282 | static const char sigTypeCommandValue[] = "command" ; |
283 | static const char sigTypeDisabledValue[] = "disabled" ; |
284 | static const char sigTextKey[] = "Inline Signature" ; |
285 | static const char sigFileKey[] = "Signature File" ; |
286 | static const char sigCommandKey[] = "Signature Command" ; |
287 | static const char sigTypeInlinedHtmlKey[] = "Inlined Html" ; |
288 | static const char sigImageLocation[] = "Image Location" ; |
289 | static const char sigEnabled[] ="Signature Enabled" ; |
290 | |
291 | // Returns the names of all images in the HTML code |
292 | static QStringList findImageNames( const QString &htmlCode ) |
293 | { |
294 | QStringList ret; |
295 | |
296 | // To complicated for us, so cheat and let a text edit do the hard work |
297 | KPIMTextEdit::TextEdit edit; |
298 | edit.setHtml( htmlCode ); |
299 | foreach ( const KPIMTextEdit::ImageWithNamePtr &image, edit.imagesWithName() ) { |
300 | ret << image->name; |
301 | } |
302 | return ret; |
303 | } |
304 | |
305 | void Signature::cleanupImages() const |
306 | { |
307 | // Remove any images from the internal structure that are no longer there |
308 | if ( isInlinedHtml() ) { |
309 | foreach ( const SignaturePrivate::EmbeddedImagePtr &imageInList, d( this )->embeddedImages ) { |
310 | bool found = false; |
311 | foreach ( const QString &imageInHtml, findImageNames( mText ) ) { |
312 | if ( imageInHtml == imageInList->name ) { |
313 | found = true; |
314 | break; |
315 | } |
316 | } |
317 | if ( !found ) { |
318 | d( this )->embeddedImages.removeAll( imageInList ); |
319 | } |
320 | } |
321 | } |
322 | |
323 | // Delete all the old image files |
324 | if ( !d( this )->saveLocation.isEmpty() ) { |
325 | QDir dir( d( this )->saveLocation ); |
326 | foreach ( const QString &fileName, dir.entryList( QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks ) ) { |
327 | if ( fileName.toLower().endsWith( QLatin1String( ".png" ) ) ) { |
328 | kDebug() << "Deleting old image" << dir.path() + fileName; |
329 | dir.remove( fileName ); |
330 | } |
331 | } |
332 | } |
333 | } |
334 | |
335 | void Signature::saveImages() const |
336 | { |
337 | if ( isInlinedHtml() && !d( this )->saveLocation.isEmpty() ) { |
338 | foreach ( const SignaturePrivate::EmbeddedImagePtr &image, d( this )->embeddedImages ) { |
339 | QString location = d( this )->saveLocation + QLatin1Char('/') + image->name; |
340 | if ( !image->image.save( location, "PNG" ) ) { |
341 | kWarning() << "Failed to save image" << location; |
342 | } |
343 | } |
344 | } |
345 | } |
346 | |
347 | void Signature::readConfig( const KConfigGroup &config ) |
348 | { |
349 | QString sigType = config.readEntry( sigTypeKey ); |
350 | if ( sigType == QLatin1String(sigTypeInlineValue) ) { |
351 | mType = Inlined; |
352 | mInlinedHtml = config.readEntry( sigTypeInlinedHtmlKey, false ); |
353 | } else if ( sigType == QLatin1String(sigTypeFileValue) ) { |
354 | mType = FromFile; |
355 | mUrl = config.readPathEntry( sigFileKey, QString() ); |
356 | } else if ( sigType == QLatin1String(sigTypeCommandValue) ) { |
357 | mType = FromCommand; |
358 | mUrl = config.readPathEntry( sigCommandKey, QString() ); |
359 | } else if ( sigType == QLatin1String(sigTypeDisabledValue) ) { |
360 | d( this )->enabled = false; |
361 | } |
362 | if ( mType != Disabled ) { |
363 | d( this )->enabled = config.readEntry( sigEnabled, true ); |
364 | } |
365 | |
366 | mText = config.readEntry( sigTextKey ); |
367 | d( this )->saveLocation = config.readEntry( sigImageLocation ); |
368 | |
369 | if ( isInlinedHtml() && !d( this )->saveLocation.isEmpty() ) { |
370 | QDir dir( d( this )->saveLocation ); |
371 | foreach ( const QString &fileName, dir.entryList( QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks ) ) { |
372 | if ( fileName.toLower().endsWith( QLatin1String( ".png" ) ) ) { |
373 | QImage image; |
374 | if ( image.load( dir.path() + QLatin1Char('/') + fileName ) ) { |
375 | addImage( image, fileName ); |
376 | } |
377 | else { |
378 | kWarning() << "Unable to load image" << dir.path() + QLatin1Char('/') + fileName; |
379 | } |
380 | } |
381 | } |
382 | } |
383 | } |
384 | |
385 | void Signature::writeConfig( KConfigGroup &config ) const |
386 | { |
387 | switch ( mType ) { |
388 | case Inlined: |
389 | config.writeEntry( sigTypeKey, sigTypeInlineValue ); |
390 | config.writeEntry( sigTypeInlinedHtmlKey, mInlinedHtml ); |
391 | break; |
392 | case FromFile: |
393 | config.writeEntry( sigTypeKey, sigTypeFileValue ); |
394 | config.writePathEntry( sigFileKey, mUrl ); |
395 | break; |
396 | case FromCommand: |
397 | config.writeEntry( sigTypeKey, sigTypeCommandValue ); |
398 | config.writePathEntry( sigCommandKey, mUrl ); |
399 | break; |
400 | default: |
401 | break; |
402 | } |
403 | config.writeEntry( sigTextKey, mText ); |
404 | config.writeEntry( sigImageLocation, d( this )->saveLocation ); |
405 | config.writeEntry( sigEnabled, d( this )->enabled ); |
406 | |
407 | cleanupImages(); |
408 | saveImages(); |
409 | } |
410 | |
411 | static bool isCursorAtEndOfLine( const QTextCursor &cursor ) |
412 | { |
413 | QTextCursor testCursor = cursor; |
414 | testCursor.movePosition( QTextCursor::EndOfLine, QTextCursor::KeepAnchor ); |
415 | return !testCursor.hasSelection(); |
416 | } |
417 | |
418 | static void insertSignatureHelper( const QString &signature, |
419 | KRichTextEdit *textEdit, |
420 | Signature::Placement placement, |
421 | bool isHtml, |
422 | bool addNewlines ) |
423 | { |
424 | if ( !signature.isEmpty() ) { |
425 | |
426 | // Save the modified state of the document, as inserting a signature |
427 | // shouldn't change this. Restore it at the end of this function. |
428 | bool isModified = textEdit->document()->isModified(); |
429 | |
430 | // Move to the desired position, where the signature should be inserted |
431 | QTextCursor cursor = textEdit->textCursor(); |
432 | QTextCursor oldCursor = cursor; |
433 | cursor.beginEditBlock(); |
434 | |
435 | if ( placement == Signature::End ) { |
436 | cursor.movePosition( QTextCursor::End ); |
437 | } else if ( placement == Signature::Start ) { |
438 | cursor.movePosition( QTextCursor::Start ); |
439 | } else if ( placement == Signature::AtCursor ) { |
440 | cursor.movePosition( QTextCursor::StartOfLine ); |
441 | } |
442 | textEdit->setTextCursor( cursor ); |
443 | |
444 | |
445 | QString lineSep; |
446 | if ( addNewlines ) { |
447 | if ( isHtml ) { |
448 | lineSep = QLatin1String( "<br>" ); |
449 | } else { |
450 | lineSep = QLatin1Char( '\n' ); |
451 | } |
452 | } |
453 | |
454 | // Insert the signature and newlines depending on where it was inserted. |
455 | bool hackForCursorsAtEnd = false; |
456 | int oldCursorPos = -1; |
457 | if ( placement == Signature::End ) { |
458 | |
459 | if ( oldCursor.position() == textEdit->toPlainText().length() ) { |
460 | hackForCursorsAtEnd = true; |
461 | oldCursorPos = oldCursor.position(); |
462 | } |
463 | if ( isHtml ) { |
464 | textEdit->insertHtml( lineSep + signature ); |
465 | } else { |
466 | textEdit->insertPlainText( lineSep + signature ); |
467 | } |
468 | } else if ( placement == Signature::Start || placement == Signature::AtCursor ) { |
469 | if ( isHtml ) { |
470 | if ( isCursorAtEndOfLine( cursor ) ) { |
471 | textEdit->insertHtml( signature ); |
472 | } else { |
473 | textEdit->insertHtml( signature + lineSep ); |
474 | } |
475 | } else { |
476 | if ( isCursorAtEndOfLine( cursor ) ) { |
477 | textEdit->insertPlainText( signature ); |
478 | } else { |
479 | textEdit->insertPlainText( signature + lineSep ); |
480 | } |
481 | } |
482 | } |
483 | |
484 | cursor.endEditBlock(); |
485 | |
486 | // There is one special case when re-setting the old cursor: The cursor |
487 | // was at the end. In this case, QTextEdit has no way to know |
488 | // if the signature was added before or after the cursor, and just decides |
489 | // that it was added before (and the cursor moves to the end, but it should |
490 | // not when appending a signature). See bug 167961 |
491 | if ( hackForCursorsAtEnd ) { |
492 | oldCursor.setPosition( oldCursorPos ); |
493 | } |
494 | |
495 | textEdit->setTextCursor( oldCursor ); |
496 | textEdit->ensureCursorVisible(); |
497 | |
498 | textEdit->document()->setModified( isModified ); |
499 | |
500 | if ( isHtml ) { |
501 | textEdit->enableRichTextMode(); |
502 | } |
503 | } |
504 | } |
505 | |
506 | void Signature::insertIntoTextEdit( KRichTextEdit *textEdit, |
507 | Placement placement, bool addSeparator ) |
508 | { |
509 | if ( !isEnabledSignature() ) { |
510 | return; |
511 | } |
512 | QString signature; |
513 | if ( addSeparator ) { |
514 | signature = withSeparator(); |
515 | } else { |
516 | signature = rawText(); |
517 | } |
518 | insertSignatureHelper( signature, textEdit, placement, |
519 | ( isInlinedHtml() && |
520 | type() == KPIMIdentities::Signature::Inlined ), |
521 | true ); |
522 | } |
523 | |
524 | void Signature::insertIntoTextEdit( Placement placement, AddedText addedText, |
525 | KPIMTextEdit::TextEdit *textEdit ) const |
526 | { |
527 | insertSignatureText( placement, addedText, textEdit, false ); |
528 | } |
529 | |
530 | void Signature::insertIntoTextEdit( Placement placement, AddedText addedText, |
531 | KPIMTextEdit::TextEdit *textEdit, bool forceDisplay ) const |
532 | { |
533 | insertSignatureText( placement, addedText, textEdit, forceDisplay ); |
534 | } |
535 | |
536 | void Signature::insertSignatureText(Placement placement, AddedText addedText, KPIMTextEdit::TextEdit *textEdit, bool forceDisplay) const |
537 | { |
538 | if ( !forceDisplay ) { |
539 | if ( !isEnabledSignature() ) { |
540 | return; |
541 | } |
542 | } |
543 | QString signature; |
544 | if ( addedText & AddSeparator ) { |
545 | signature = withSeparator(); |
546 | } else { |
547 | signature = rawText(); |
548 | } |
549 | insertSignatureHelper( signature, textEdit, placement, |
550 | ( isInlinedHtml() && |
551 | type() == KPIMIdentities::Signature::Inlined ), |
552 | ( addedText & AddNewLines ) ); |
553 | |
554 | // We added the text of the signature above, now it is time to add the images as well. |
555 | if ( isInlinedHtml() ) { |
556 | foreach ( const SignaturePrivate::EmbeddedImagePtr &image, d( this )->embeddedImages ) { |
557 | textEdit->loadImage( image->image, image->name, image->name ); |
558 | } |
559 | } |
560 | } |
561 | |
562 | |
563 | void Signature::insertPlainSignatureIntoTextEdit( const QString &signature, KRichTextEdit *textEdit, |
564 | Signature::Placement placement, bool isHtml ) |
565 | { |
566 | insertSignatureHelper( signature, textEdit, placement, isHtml, true ); |
567 | } |
568 | |
569 | // --------------------- Operators -------------------// |
570 | |
571 | QDataStream &KPIMIdentities::operator<< |
572 | ( QDataStream &stream, const KPIMIdentities::Signature &sig ) |
573 | { |
574 | return stream << static_cast<quint8>( sig.mType ) << sig.mUrl << sig.mText |
575 | << d( &sig )->saveLocation << d( &sig )->embeddedImages << d( &sig )->enabled; |
576 | } |
577 | |
578 | QDataStream &KPIMIdentities::operator>> |
579 | ( QDataStream &stream, KPIMIdentities::Signature &sig ) |
580 | { |
581 | quint8 s; |
582 | stream >> s >> sig.mUrl >> sig.mText >> d( &sig )->saveLocation >> d( &sig )->embeddedImages >>d( &sig )->enabled; |
583 | sig.mType = static_cast<Signature::Type>( s ); |
584 | return stream; |
585 | } |
586 | |
587 | bool Signature::operator== ( const Signature &other ) const |
588 | { |
589 | if ( mType != other.mType ) { |
590 | return false; |
591 | } |
592 | |
593 | if ( d( this )->enabled != d( &other )->enabled ) { |
594 | return false; |
595 | } |
596 | |
597 | if ( mType == Inlined && mInlinedHtml ) { |
598 | if ( d( this )->saveLocation != d( &other )->saveLocation ) { |
599 | return false; |
600 | } |
601 | if ( d( this )->embeddedImages != d( &other )->embeddedImages ) { |
602 | return false; |
603 | } |
604 | } |
605 | |
606 | switch ( mType ) { |
607 | case Inlined: |
608 | return mText == other.mText; |
609 | case FromFile: |
610 | case FromCommand: |
611 | return mUrl == other.mUrl; |
612 | default: |
613 | case Disabled: |
614 | return true; |
615 | } |
616 | } |
617 | |
618 | QString Signature::toPlainText() const |
619 | { |
620 | QString sigText = rawText(); |
621 | if ( !sigText.isEmpty() && isInlinedHtml() && type() == Inlined ) { |
622 | // Use a QTextDocument as a helper, it does all the work for us and |
623 | // strips all HTML tags. |
624 | QTextDocument helper; |
625 | QTextCursor helperCursor( &helper ); |
626 | helperCursor.insertHtml( sigText ); |
627 | sigText = helper.toPlainText(); |
628 | } |
629 | return sigText; |
630 | } |
631 | |
632 | void Signature::addImage ( const QImage& imageData, const QString& imageName ) |
633 | { |
634 | Q_ASSERT( !( d( this )->saveLocation.isEmpty() ) ); |
635 | SignaturePrivate::EmbeddedImagePtr image( new SignaturePrivate::EmbeddedImage() ); |
636 | image->image = imageData; |
637 | image->name = imageName; |
638 | d( this )->embeddedImages.append( image ); |
639 | } |
640 | |
641 | void Signature::setImageLocation ( const QString& path ) |
642 | { |
643 | d( this )->saveLocation = path; |
644 | } |
645 | |
646 | // --------------- Getters -----------------------// |
647 | |
648 | QString Signature::text() const |
649 | { |
650 | return mText; |
651 | } |
652 | |
653 | QString Signature::url() const |
654 | { |
655 | return mUrl; |
656 | } |
657 | |
658 | Signature::Type Signature::type() const |
659 | { |
660 | return mType; |
661 | } |
662 | |
663 | // --------------- Setters -----------------------// |
664 | |
665 | void Signature::setText( const QString &text ) |
666 | { |
667 | mText = text; |
668 | mType = Inlined; |
669 | } |
670 | |
671 | void Signature::setType( Type type ) |
672 | { |
673 | mType = type; |
674 | } |
675 | |
676 | |
677 | void Signature::setEnabledSignature(bool enabled) |
678 | { |
679 | d( this )->enabled = enabled; |
680 | } |
681 | |
682 | bool Signature::isEnabledSignature() const |
683 | { |
684 | return d( this )->enabled; |
685 | } |
686 | |