00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <kabc/picture.h>
00025 #include <kdebug.h>
00026 #include <kdialog.h>
00027 #include <kfiledialog.h>
00028 #include <kglobalsettings.h>
00029 #include <kiconloader.h>
00030 #include <kimageio.h>
00031 #include <kio/netaccess.h>
00032 #include <klocale.h>
00033 #include <kmessagebox.h>
00034 #include <kurldrag.h>
00035 #include <libkdepim/kpixmapregionselectordialog.h>
00036
00037 #include <librss/loader.h>
00038 #include <librss/document.h>
00039 #include <librss/image.h>
00040
00041 #include <qapplication.h>
00042 #include <qdragobject.h>
00043 #include <qeventloop.h>
00044 #include <qgroupbox.h>
00045 #include <qlabel.h>
00046 #include <qlayout.h>
00047 #include <qpixmap.h>
00048 #include <qpopupmenu.h>
00049
00050 #include <unistd.h>
00051
00052 #include "imagewidget.h"
00053
00054 ImageLoader::ImageLoader()
00055 : QObject( 0, "ImageLoader" ),
00056 mIsLoadingBlog( false )
00057 {
00058 }
00059
00060
00061 KABC::Picture ImageLoader::loadPicture( const KURL &url, bool *ok )
00062 {
00063 KABC::Picture picture;
00064 QString tempFile;
00065
00066 if ( url.isEmpty() )
00067 return picture;
00068
00069 (*ok) = false;
00070
00071 QImage image;
00072 if ( url.isLocalFile() ) {
00073 image.load( url.path() );
00074 picture.setData( image );
00075 (*ok) = true;
00076 } else if ( KIO::NetAccess::download( url, tempFile, 0 ) ) {
00077 image.load( tempFile );
00078 picture.setData( image );
00079 (*ok) = true;
00080 KIO::NetAccess::removeTempFile( tempFile );
00081 }
00082
00083 if ( !(*ok) ) {
00084
00085 KMessageBox::sorry( 0, i18n( "This contact's image cannot be found." ) );
00086 return picture;
00087 }
00088
00089 QPixmap pixmap = picture.data();
00090
00091 QPixmap selectedPixmap = KPIM::KPixmapRegionSelectorDialog::getSelectedImage( pixmap, 100, 140, 0 );
00092 if ( selectedPixmap.isNull() ) {
00093 (*ok) = false;
00094 return picture;
00095 }
00096
00097 image = selectedPixmap;
00098 if ( image.height() != 140 || image.width() != 100 ) {
00099 if ( image.height() > image.width() )
00100 image = image.scaleHeight( 140 );
00101 else
00102 image = image.scaleWidth( 100 );
00103 }
00104
00105 picture.setData( image );
00106 (*ok) = true;
00107
00108 return picture;
00109 }
00110
00111 KABC::Picture ImageLoader::loadBlog( const KURL &url, bool *ok )
00112 {
00113 RSS::Loader *loader = RSS::Loader::create();
00114 connect( loader, SIGNAL( loadingComplete( Loader*, Document, Status ) ),
00115 this, SLOT( loadingComplete( Loader*, Document, Status ) ) );
00116 loader->loadFrom( url, new RSS::FileRetriever );
00117
00118 mIsLoadingBlog = true;
00119 while ( mIsLoadingBlog ) {
00120 qApp->eventLoop()->processEvents( QEventLoop::ExcludeUserInput );
00121 usleep( 500 );
00122 }
00123
00124 if ( mPicture.data().isNull() ) {
00125 KMessageBox::sorry( 0,
00126 i18n( "Blog feed at '%1' does not contain an image." ).arg( url.url() ) );
00127 (*ok) = false;
00128 }
00129 (*ok) = true;
00130
00131 return mPicture;
00132 }
00133
00134 void ImageLoader::loadingComplete( RSS::Loader*,
00135 RSS::Document doc,
00136 RSS::Status status )
00137 {
00138 mIsLoadingBlog = false;
00139
00140 if ( status != RSS::Success ) {
00141 mPicture = KABC::Picture();
00142 return;
00143 }
00144
00145 if ( !doc.image() ) {
00146 mPicture = KABC::Picture();
00147 return;
00148 }
00149
00150 bool ok = false;
00151 KABC::Picture pic = loadPicture( doc.image()->url().url(), &ok );
00152 if ( ok )
00153 mPicture = pic;
00154 }
00155
00156 ImageButton::ImageButton( const QString &title, QWidget *parent )
00157 : QPushButton( title, parent ),
00158 mReadOnly( false ), mImageLoader( 0 )
00159 {
00160 setAcceptDrops( true );
00161
00162 connect( this, SIGNAL( clicked() ), SLOT( load() ) );
00163 }
00164
00165 void ImageButton::setReadOnly( bool readOnly )
00166 {
00167 mReadOnly = readOnly;
00168 }
00169
00170 void ImageButton::setPicture( const KABC::Picture &picture )
00171 {
00172 mPicture = picture;
00173 updateGUI();
00174 }
00175
00176 KABC::Picture ImageButton::picture() const
00177 {
00178 return mPicture;
00179 }
00180
00181 void ImageButton::setImageLoader( ImageLoader *loader )
00182 {
00183 mImageLoader = loader;
00184 }
00185
00186 void ImageButton::setBlogFeed( const KURL &url )
00187 {
00188 mBlogFeed = url;
00189 }
00190
00191 void ImageButton::startDrag()
00192 {
00193 if ( !mPicture.data().isNull() ) {
00194 QImageDrag *drag = new QImageDrag( mPicture.data(), this );
00195 drag->dragCopy();
00196 }
00197 }
00198
00199 void ImageButton::updateGUI()
00200 {
00201 if ( mPicture.data().isNull() )
00202 setPixmap( KGlobal::iconLoader()->iconPath( "personal", KIcon::Desktop ) );
00203 else
00204 setPixmap( mPicture.data() );
00205 }
00206
00207 void ImageButton::dragEnterEvent( QDragEnterEvent *event )
00208 {
00209 bool accepted = false;
00210
00211 if ( QImageDrag::canDecode( event ) )
00212 accepted = true;
00213
00214 if ( QUriDrag::canDecode( event ) )
00215 accepted = true;
00216
00217 event->accept( accepted );
00218 }
00219
00220 void ImageButton::dropEvent( QDropEvent *event )
00221 {
00222 if ( mReadOnly )
00223 return;
00224
00225 if ( QImageDrag::canDecode( event ) ) {
00226 QPixmap pm;
00227
00228 if ( QImageDrag::decode( event, pm ) ) {
00229 mPicture.setData( pm.convertToImage() );
00230 updateGUI();
00231 emit changed();
00232 }
00233 }
00234
00235 if ( QUriDrag::canDecode( event ) ) {
00236 KURL::List urls;
00237 if ( KURLDrag::decode( event, urls ) ) {
00238 if ( urls.isEmpty() ) {
00239 event->accept( false );
00240 return;
00241 }
00242 }
00243
00244 if ( mImageLoader ) {
00245 bool ok = false;
00246 KABC::Picture pic = mImageLoader->loadPicture( urls[ 0 ], &ok );
00247 if ( ok ) {
00248 mPicture = pic;
00249 updateGUI();
00250 emit changed();
00251 }
00252 }
00253 }
00254 }
00255
00256 void ImageButton::mousePressEvent( QMouseEvent *event )
00257 {
00258 mDragStartPos = event->pos();
00259 QPushButton::mousePressEvent( event );
00260 }
00261
00262 void ImageButton::mouseMoveEvent( QMouseEvent *event )
00263 {
00264 if ( (event->state() & LeftButton) &&
00265 (event->pos() - mDragStartPos).manhattanLength() >
00266 KGlobalSettings::dndEventDelay() ) {
00267 startDrag();
00268 }
00269 }
00270
00271 void ImageButton::contextMenuEvent( QContextMenuEvent *event )
00272 {
00273 QPopupMenu menu( this );
00274 menu.insertItem( i18n( "Reset" ), this, SLOT( clear() ) );
00275 if ( mBlogFeed.isValid() )
00276 menu.insertItem( i18n("Get From Blog"), this, SLOT( loadBlog() ) );
00277
00278 menu.exec( event->globalPos() );
00279 }
00280
00281 void ImageButton::load()
00282 {
00283 KURL url = KFileDialog::getOpenURL( QString(), KImageIO::pattern(), this );
00284 if ( url.isValid() ) {
00285 if ( mImageLoader ) {
00286 bool ok = false;
00287 KABC::Picture pic = mImageLoader->loadPicture( url, &ok );
00288 if ( ok ) {
00289 mPicture = pic;
00290 updateGUI();
00291 emit changed();
00292 }
00293 }
00294 }
00295 }
00296
00297 void ImageButton::loadBlog()
00298 {
00299 bool ok = false;
00300 KABC::Picture pic = mImageLoader->loadBlog( mBlogFeed, &ok );
00301 if ( ok ) {
00302 mPicture = pic;
00303 updateGUI();
00304 emit changed();
00305 }
00306 }
00307
00308 void ImageButton::clear()
00309 {
00310 mPicture = KABC::Picture();
00311 updateGUI();
00312
00313 emit changed();
00314 }
00315
00316 ImageBaseWidget::ImageBaseWidget( const QString &title,
00317 QWidget *parent, const char *name )
00318 : QWidget( parent, name ), mReadOnly( false )
00319 {
00320 mImageLoader = new ImageLoader();
00321
00322 QVBoxLayout *topLayout = new QVBoxLayout( this, KDialog::marginHint(),
00323 KDialog::spacingHint() );
00324 QGroupBox *box = new QGroupBox( 0, Qt::Vertical, title, this );
00325 QVBoxLayout *layout = new QVBoxLayout( box->layout(), KDialog::spacingHint() );
00326
00327 mImageButton = new ImageButton( i18n( "Picture" ), box );
00328 mImageButton->setFixedSize( 100, 140 );
00329 mImageButton->setImageLoader( mImageLoader );
00330 layout->addWidget( mImageButton );
00331
00332 topLayout->addWidget( box );
00333
00334 connect( mImageButton, SIGNAL( changed() ), SIGNAL( changed() ) );
00335 }
00336
00337 ImageBaseWidget::~ImageBaseWidget()
00338 {
00339 delete mImageLoader;
00340 mImageLoader = 0;
00341 }
00342
00343 void ImageBaseWidget::setReadOnly( bool readOnly )
00344 {
00345 mReadOnly = readOnly;
00346 mImageButton->setReadOnly( mReadOnly );
00347 }
00348
00349 void ImageBaseWidget::setBlogFeed( const QString &feed )
00350 {
00351 mImageButton->setBlogFeed( feed );
00352 }
00353
00354 void ImageBaseWidget::setImage( const KABC::Picture &photo )
00355 {
00356 mImageButton->setPicture( photo );
00357 }
00358
00359 KABC::Picture ImageBaseWidget::image() const
00360 {
00361 return mImageButton->picture();
00362 }
00363
00364
00365 ImageWidget::ImageWidget( KABC::AddressBook *ab, QWidget *parent, const char *name )
00366 : KAB::ContactEditorWidget( ab, parent, name )
00367 {
00368 QHBoxLayout *layout = new QHBoxLayout( this, KDialog::marginHint(),
00369 KDialog::spacingHint() );
00370
00371 mPhotoWidget = new ImageBaseWidget( KABC::Addressee::photoLabel(), this );
00372 layout->addWidget( mPhotoWidget );
00373
00374 mLogoWidget = new ImageBaseWidget( KABC::Addressee::logoLabel(), this );
00375 layout->addWidget( mLogoWidget );
00376
00377 connect( mPhotoWidget, SIGNAL( changed() ), SLOT( setModified() ) );
00378 connect( mLogoWidget, SIGNAL( changed() ), SLOT( setModified() ) );
00379 }
00380
00381 void ImageWidget::loadContact( KABC::Addressee *addr )
00382 {
00383 mPhotoWidget->setImage( addr->photo() );
00384 mPhotoWidget->setBlogFeed( addr->custom( "KADDRESSBOOK", "BlogFeed" ) );
00385 mLogoWidget->setImage( addr->logo() );
00386 }
00387
00388 void ImageWidget::storeContact( KABC::Addressee *addr )
00389 {
00390 addr->setPhoto( mPhotoWidget->image() );
00391 addr->setLogo( mLogoWidget->image() );
00392 }
00393
00394 void ImageWidget::setReadOnly( bool readOnly )
00395 {
00396 mPhotoWidget->setReadOnly( readOnly );
00397 mLogoWidget->setReadOnly( readOnly );
00398 }
00399
00400 #include "imagewidget.moc"