2 This file is part of KMail.
4 Copyright (c) 2004 Jakob Schr�er <js@camaya.net>
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
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 Library General Public License for more details.
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
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
21 In addition, as a special exception, the copyright holders give
22 permission to link the code of this program with any edition of
23 the Qt library by Trolltech AS, Norway (or with modified versions
24 of Qt that use the same license as Qt), and distribute linked
25 combinations including the two. You must obey the GNU General
26 Public License in all respects for all of the code used other than
27 Qt. If you modify this file, you may extend this exception to
28 your version of the file, but you are not obligated to do so. If
29 you do not wish to do so, delete this exception statement from
33 #include "xfaceconfigurator.h"
35 #include <akonadi/contact/contactsearchjob.h>
36 #include <kabc/addressee.h>
37 #include <kcombobox.h>
39 #include <kfiledialog.h>
40 #include <kglobalsettings.h>
42 #include <kio/netaccess.h>
44 #include <kmessagebox.h>
45 #include <kpimidentities/identity.h>
46 #include <kpimidentities/identitymanager.h>
47 #include <ktextedit.h>
49 #include <messageviewer/kxface.h>
52 #include <QHBoxLayout>
54 #include <QPushButton>
55 #include <QStackedWidget>
56 #include <QVBoxLayout>
58 // #include <assert.h>
61 using namespace KMail
;
62 using namespace MessageViewer
;
66 XFaceConfigurator::XFaceConfigurator( QWidget
* parent
)
76 QVBoxLayout
* page_vlay
;
77 QPushButton
* mFromFileBtn
;
78 QPushButton
* mFromAddrbkBtn
;
80 vlay
= new QVBoxLayout( this );
81 vlay
->setObjectName( "main layout" );
82 vlay
->setSpacing( KDialog::spacingHint() );
84 hlay
= new QHBoxLayout();
85 vlay
->addLayout( hlay
);
87 // "enable X-Face" checkbox:
88 mEnableCheck
= new QCheckBox( i18n("&Send picture with every message"), this );
89 mEnableCheck
->setWhatsThis(
90 i18n( "Check this box if you want KMail to add a so-called X-Face header to messages "
91 "written with this identity. An X-Face is a small (48x48 pixels) black and "
92 "white image that some mail clients are able to display." ) );
93 hlay
->addWidget( mEnableCheck
, Qt::AlignLeft
| Qt::AlignVCenter
);
95 mXFaceLabel
= new QLabel( this );
96 mXFaceLabel
->setWhatsThis(
97 i18n( "This is a preview of the picture selected/entered below." ) );
98 mXFaceLabel
->setFixedSize(48, 48);
99 mXFaceLabel
->setFrameShape( QFrame::Box
);
100 hlay
->addWidget( mXFaceLabel
);
102 // label1 = new QLabel( "X-Face:", this );
103 // vlay->addWidget( label1 );
105 // "obtain X-Face from" combo and label:
106 hlay
= new QHBoxLayout(); // inherits spacing
107 vlay
->addLayout( hlay
);
108 mSourceCombo
= new KComboBox( this );
109 mSourceCombo
->setEditable( false );
110 mSourceCombo
->setWhatsThis(
111 i18n("Click on the widgets below to obtain help on the input methods."));
112 mSourceCombo
->setEnabled( false ); // since !mEnableCheck->isChecked()
113 mSourceCombo
->addItems( QStringList()
114 << i18nc( "continuation of \"obtain picture from\"",
116 << i18nc( "continuation of \"obtain picture from\"",
117 "Input Field Below" ) );
118 label
= new QLabel( i18n("Obtain pic&ture from:"), this );
119 label
->setBuddy( mSourceCombo
);
120 label
->setEnabled( false ); // since !mEnableCheck->isChecked()
121 hlay
->addWidget( label
);
122 hlay
->addWidget( mSourceCombo
, 1 );
124 // widget stack that is controlled by the source combo:
125 QStackedWidget
* widgetStack
= new QStackedWidget( this );
126 widgetStack
->setEnabled( false ); // since !mEnableCheck->isChecked()
127 vlay
->addWidget( widgetStack
, 1 );
128 connect( mSourceCombo
, SIGNAL(highlighted(int)),
129 widgetStack
, SLOT(setCurrentIndex(int)) );
130 connect( mSourceCombo
, SIGNAL(activated(int)),
131 widgetStack
, SLOT(setCurrentIndex (int)) );
132 connect( mEnableCheck
, SIGNAL(toggled(bool)),
133 mSourceCombo
, SLOT(setEnabled(bool)) );
134 connect( mEnableCheck
, SIGNAL(toggled(bool)),
135 widgetStack
, SLOT(setEnabled(bool)) );
136 connect( mEnableCheck
, SIGNAL(toggled(bool)),
137 label
, SLOT(setEnabled(bool)) );
138 // The focus might be still in the widget that is disabled
139 connect( mEnableCheck
, SIGNAL(clicked()),
140 mEnableCheck
, SLOT(setFocus()) );
143 // page 0: create X-Face from image file or address book entry
144 page
= new QWidget( widgetStack
);
145 widgetStack
->insertWidget( pageno
, page
); // force sequential numbers (play safe)
146 page_vlay
= new QVBoxLayout( page
);
147 page_vlay
->setMargin( 0 );
148 page_vlay
->setSpacing( KDialog::spacingHint() );
149 hlay
= new QHBoxLayout(); // inherits spacing ??? FIXME really?
150 page_vlay
->addLayout( hlay
);
151 mFromFileBtn
= new QPushButton( i18n("Select File..."), page
);
152 mFromFileBtn
->setWhatsThis(
153 i18n("Use this to select an image file to create the picture from. "
154 "The image should be of high contrast and nearly quadratic shape. "
155 "A light background helps improve the result." ) );
156 mFromFileBtn
->setAutoDefault( false );
157 page_vlay
->addWidget( mFromFileBtn
, 1 );
158 connect( mFromFileBtn
, SIGNAL(released()),
159 this, SLOT(slotSelectFile()) );
160 mFromAddrbkBtn
= new QPushButton( i18n("Set From Address Book"), page
);
161 mFromAddrbkBtn
->setWhatsThis(
162 i18n( "You can use a scaled-down version of the picture "
163 "you have set in your address book entry." ) );
164 mFromAddrbkBtn
->setAutoDefault( false );
165 page_vlay
->addWidget( mFromAddrbkBtn
, 1 );
166 connect( mFromAddrbkBtn
, SIGNAL(released()),
167 this, SLOT(slotSelectFromAddressbook()) );
168 label1
= new QLabel( i18n("<qt>KMail can send a small (48x48 pixels), low-quality, "
169 "monochrome picture with every message. "
170 "For example, this could be a picture of you or a glyph. "
171 "It is shown in the recipient's mail client (if supported).</qt>" ), page
);
172 label1
->setAlignment( Qt::AlignVCenter
);
173 label1
->setWordWrap( true );
174 page_vlay
->addWidget( label1
);
176 widgetStack
->setCurrentIndex( 0 ); // since mSourceCombo->currentItem() == 0
178 // page 1: input field for direct entering
180 page
= new QWidget( widgetStack
);
181 widgetStack
->insertWidget( pageno
,page
);
182 page_vlay
= new QVBoxLayout( page
);
183 page_vlay
->setMargin( 0 );
184 page_vlay
->setSpacing( KDialog::spacingHint() );
185 mTextEdit
= new KTextEdit( page
);
186 page_vlay
->addWidget( mTextEdit
);
187 mTextEdit
->setWhatsThis( i18n( "Use this field to enter an arbitrary X-Face string." ) );
188 mTextEdit
->setFont( KGlobalSettings::fixedFont() );
189 mTextEdit
->setWordWrapMode( QTextOption::WrapAnywhere
);
190 mTextEdit
->setAcceptRichText( false );
191 label2
= new QLabel( i18n("Examples are available at <a "
192 "href=\"http://www.xs4all.nl/~ace/X-Faces/\">"
193 "http://www.xs4all.nl/~ace/X-Faces/</a>."), page
);
194 label2
->setOpenExternalLinks(true);
195 label2
->setTextInteractionFlags(Qt::TextBrowserInteraction
);
197 page_vlay
->addWidget( label2
);
200 connect(mTextEdit
, SIGNAL(textChanged()), this, SLOT(slotUpdateXFace()));
203 XFaceConfigurator::~XFaceConfigurator() {
207 bool XFaceConfigurator::isXFaceEnabled() const {
208 return mEnableCheck
->isChecked();
211 void XFaceConfigurator::setXFaceEnabled( bool enable
) {
212 mEnableCheck
->setChecked( enable
);
215 QString
XFaceConfigurator::xface() const {
216 return mTextEdit
->toPlainText();
219 void XFaceConfigurator::setXFace( const QString
& text
) {
220 mTextEdit
->setText( text
);
223 void XFaceConfigurator::setXfaceFromFile( const KUrl
&url
)
226 if( KIO::NetAccess::download( url
, tmpFile
, this ) )
229 mTextEdit
->setText( xf
.fromImage( QImage( tmpFile
) ) );
230 KIO::NetAccess::removeTempFile( tmpFile
);
232 KMessageBox::error(this, KIO::NetAccess::lastErrorString() );
236 void XFaceConfigurator::slotSelectFile()
238 QStringList mimeTypes
= KImageIO::mimeTypes (KImageIO::Reading
);
239 const QString filter
= mimeTypes
.join (" ");
240 const KUrl url
= KFileDialog::getOpenUrl( QString(), filter
, this, QString() );
241 if ( !url
.isEmpty() )
242 setXfaceFromFile( url
);
245 void XFaceConfigurator::slotSelectFromAddressbook()
247 using namespace KPIMIdentities
;
249 IdentityManager
manager( true );
250 const Identity defaultIdentity
= manager
.defaultIdentity();
251 const QString email
= defaultIdentity
.emailAddr();
253 Akonadi::ContactSearchJob
*job
= new Akonadi::ContactSearchJob( this );
255 job
->setQuery( Akonadi::ContactSearchJob::Email
, email
, Akonadi::ContactSearchJob::ExactMatch
);
256 connect( job
, SIGNAL( result( KJob
* ) ), SLOT( slotDelayedSelectFromAddressbook( KJob
* ) ) );
259 void XFaceConfigurator::slotDelayedSelectFromAddressbook( KJob
*job
)
261 const Akonadi::ContactSearchJob
*searchJob
= qobject_cast
<Akonadi::ContactSearchJob
*>( job
);
263 if ( searchJob
->contacts().isEmpty() ) {
264 KMessageBox::information( this, i18n("You do not have your own contact defined in the address book."), i18n("No Picture") );
268 const Addressee contact
= searchJob
->contacts().first();
269 if ( contact
.photo().isIntern() )
271 const QImage photo
= contact
.photo().data();
272 if ( !photo
.isNull() )
275 mTextEdit
->setText( xf
.fromImage( photo
) );
278 KMessageBox::information( this, i18n("No picture set for your address book entry."), i18n("No Picture") );
283 const KUrl url
= contact
.photo().url();
285 setXfaceFromFile( url
);
287 KMessageBox::information( this, i18n("No picture set for your address book entry."), i18n("No Picture") );
291 void XFaceConfigurator::slotUpdateXFace()
293 QString str
= mTextEdit
->toPlainText();
295 if ( !str
.isEmpty() )
297 if ( str
.startsWith( QLatin1String("x-face:"), Qt::CaseInsensitive
) )
299 str
= str
.remove( "x-face:", Qt::CaseInsensitive
);
300 mTextEdit
->setText(str
);
303 const QPixmap p
= QPixmap::fromImage( xf
.toImage(str
) );
304 mXFaceLabel
->setPixmap( p
);
308 mXFaceLabel
->clear();
314 #include "xfaceconfigurator.moc"