00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <qframe.h>
00019 #include <qlayout.h>
00020 #include <qlabel.h>
00021 #include <qimage.h>
00022 #include <qpixmap.h>
00023 #include <qfile.h>
00024 #include <qrect.h>
00025 #include <qstyle.h>
00026
00027 #include <kapplication.h>
00028 #include <kdeversion.h>
00029 #include <kpushbutton.h>
00030 #include <klineedit.h>
00031 #include <klistbox.h>
00032 #include <kmessagebox.h>
00033 #include <kprogress.h>
00034 #include <kurl.h>
00035 #include <kurlrequester.h>
00036 #include <klocale.h>
00037 #include <ktempfile.h>
00038
00039 #include "thumbnailpicker.h"
00040 #include "thumbnailpickerui.h"
00041 #include "thumbnaileditor.h"
00042 #include "ksutils.h"
00043 #include "detaildialog.h"
00044 #include "skyobject.h"
00045
00046 ThumbnailPicker::ThumbnailPicker( SkyObject *o, const QPixmap ¤t, QWidget *parent, const char *name )
00047 : KDialogBase( KDialogBase::Plain, i18n( "Choose Thumbnail Image" ), Ok|Cancel, Ok, parent, name ),
00048 SelectedImageIndex(-1), dd((DetailDialog*)parent), Object(o), bImageFound( false )
00049 {
00050 Image = new QPixmap( current );
00051 ImageRect = new QRect( 0, 0, 200, 200 );
00052
00053 QFrame *page = plainPage();
00054 QVBoxLayout *vlay = new QVBoxLayout( page, 0, 0 );
00055 ui = new ThumbnailPickerUI( page );
00056 vlay->addWidget( ui );
00057
00058 ui->CurrentImage->setPixmap( *Image );
00059
00060 PixList.setAutoDelete( true );
00061
00062 connect( ui->EditButton, SIGNAL( clicked() ), this, SLOT( slotEditImage() ) );
00063 connect( ui->UnsetButton, SIGNAL( clicked() ), this, SLOT( slotUnsetImage() ) );
00064 connect( ui->ImageList, SIGNAL( highlighted( int ) ),
00065 this, SLOT( slotSetFromList( int ) ) );
00066 connect( ui->ImageURLBox, SIGNAL( urlSelected( const QString& ) ),
00067 this, SLOT( slotSetFromURL() ) );
00068 connect( ui->ImageURLBox, SIGNAL( returnPressed() ),
00069 this, SLOT( slotSetFromURL() ) );
00070
00071 ui->ImageURLBox->lineEdit()->setTrapReturnKey( true );
00072 ui->EditButton->setEnabled( false );
00073
00074 slotFillList();
00075 }
00076
00077 ThumbnailPicker::~ThumbnailPicker()
00078 {}
00079
00080
00081 void ThumbnailPicker::slotFillList() {
00082
00083 QStringList ImageList( Object->ImageList );
00084
00085
00086 KURL gURL( "http://images.google.com/images" );
00087
00088 QString sName = QString("\"%1\"").arg( Object->name() );
00089 if ( Object->longname() != Object->name() ) {
00090 sName = QString("\"%1\" ").arg( Object->longname() ) + sName;
00091 }
00092 gURL.addQueryItem( "q", sName );
00093
00094
00095 parseGooglePage( ImageList, gURL.prettyURL() );
00096
00097
00098 int nImages = ImageList.count();
00099 if ( nImages ) {
00100 ui->SearchProgress->setTotalSteps( nImages );
00101 ui->SearchLabel->setText( i18n( "Loading images..." ) );
00102 }
00103
00104
00105 QStringList::Iterator itList = ImageList.begin();
00106 QStringList::Iterator itListEnd = ImageList.end();
00107 for ( ; itList != itListEnd; ++itList ) {
00108 QString s( *itList );
00109 KURL u( s );
00110 if ( u.isValid() && KIO::NetAccess::exists(u, true, this) ) {
00111 KTempFile ktf;
00112 QFile *tmpFile = ktf.file();
00113 ktf.unlink();
00114 JobList.append( KIO::copy( u, KURL( tmpFile->name() ), false ) );
00115 #if KDE_IS_VERSION( 3, 3, 90 )
00116 ((KIO::CopyJob*)JobList.current())->setInteractive( false );
00117 #endif
00118 connect (JobList.current(), SIGNAL (result(KIO::Job *)), SLOT (downloadReady (KIO::Job *)));
00119
00120 }
00121 }
00122 }
00123
00124 void ThumbnailPicker::parseGooglePage( QStringList &ImList, QString URL ) {
00125 QString tmpFile;
00126 QString PageHTML;
00127
00128
00129 if ( KIO::NetAccess::exists(URL, true, this) && KIO::NetAccess::download( URL, tmpFile ) ) {
00130 QFile file( tmpFile );
00131 if ( file.open( IO_ReadOnly ) ) {
00132 QTextStream instream(&file);
00133 PageHTML = instream.read();
00134 file.close();
00135 } else {
00136 kdDebug() << "Could not read local copy of google image page" << endl;
00137 return;
00138 }
00139 } else {
00140 kdDebug() << KIO::NetAccess::lastErrorString() << endl;
00141 return;
00142 }
00143
00144 int index = PageHTML.find( "?imgurl=", 0 );
00145 while ( index >= 0 ) {
00146 index += 8;
00147
00148
00149 ImList.append( PageHTML.mid( index, PageHTML.find( "&", index ) - index ) );
00150
00151 index = PageHTML.find( "?imgurl=", index );
00152 }
00153 }
00154
00155 void ThumbnailPicker::downloadReady(KIO::Job *job) {
00156
00157
00158
00159 if ( ! ui->SearchProgress->isHidden() ) {
00160 ui->SearchProgress->advance(1);
00161 if ( ui->SearchProgress->progress() == ui->SearchProgress->totalSteps() ) {
00162 ui->SearchProgress->hide();
00163 ui->SearchLabel->setText( i18n( "Search results:" ) );
00164 }
00165 }
00166
00167
00168 if ( job->error() ) {
00169
00170 return;
00171 }
00172
00173 KIO::CopyJob *cjob = (KIO::CopyJob*)job;
00174 QFile tmp( cjob->destURL().path() );
00175 tmp.close();
00176
00177
00178
00179
00180
00181
00182 if ( tmp.exists() ) {
00183 QImage im( tmp.name() );
00184
00185 if ( im.isNull() ) {
00186
00187
00188 return;
00189 }
00190
00191 uint w = im.width();
00192 uint h = im.height();
00193 uint pad = 4*marginHint() + 2*ui->SearchLabel->height() + actionButton( Ok )->height() + 25;
00194 uint hDesk = kapp->desktop()->availableGeometry().height() - pad;
00195
00196
00197
00198
00199
00200 if ( h > hDesk )
00201 im = im.smoothScale( w*hDesk/h, hDesk );
00202
00203 PixList.append( new QPixmap( im ) );
00204
00205
00206 ui->ImageList->insertItem( shrinkImage( PixList.current(), 50 ),
00207 cjob->srcURLs().first().prettyURL() );
00208 }
00209 }
00210
00211 QPixmap ThumbnailPicker::shrinkImage( QPixmap *pm, int size, bool setImage ) {
00212 int w( pm->width() ), h( pm->height() );
00213 int bigSize( w );
00214 int rx(0), ry(0), sx(0), sy(0), bx(0), by(0);
00215 if ( size == 0 ) return QPixmap();
00216
00217
00218 if ( w > size && w >= h ) {
00219 h = size;
00220 w = size*pm->width()/pm->height();
00221 } else if ( h > size && h > w ) {
00222 w = size;
00223 h = size*pm->height()/pm->width();
00224 }
00225 sx = (w - size)/2;
00226 sy = (h - size)/2;
00227 if ( sx < 0 ) { rx = -sx; sx = 0; }
00228 if ( sy < 0 ) { ry = -sy; sy = 0; }
00229
00230 if ( setImage ) bigSize = int( 200.*float(pm->width())/float(w) );
00231
00232 QPixmap result( size, size );
00233 result.fill( QColor( "white" ) );
00234
00235 if ( pm->width() > size || pm->height() > size ) {
00236
00237 QImage im( pm->convertToImage() );
00238 im = im.smoothScale( w, h );
00239
00240
00241 bitBlt( &result, rx, ry, &im, sx, sy, size, size );
00242 if ( setImage ) {
00243 bx = int( sx*float(pm->width())/float(w) );
00244 by = int( sy*float(pm->width())/float(w) );
00245 ImageRect->setRect( bx, by, bigSize, bigSize );
00246 }
00247
00248 } else {
00249 bitBlt( &result, rx, ry, pm );
00250 if ( setImage ) {
00251 bx = int( rx*float(pm->width())/float(w) );
00252 by = int( ry*float(pm->width())/float(w) );
00253 ImageRect->setRect( bx, by, bigSize, bigSize );
00254 }
00255 }
00256
00257 return result;
00258 }
00259
00260 void ThumbnailPicker::slotEditImage() {
00261 ThumbnailEditor te( this );
00262 if ( te.exec() == QDialog::Accepted ) {
00263 QPixmap pm = te.thumbnail();
00264 *Image = pm;
00265 ui->CurrentImage->setPixmap( pm );
00266 ui->CurrentImage->update();
00267 }
00268 }
00269
00270 void ThumbnailPicker::slotUnsetImage() {
00271 QFile file;
00272 if ( KSUtils::openDataFile( file, "noimage.png" ) ) {
00273 file.close();
00274 Image->load( file.name(), "PNG" );
00275 } else {
00276 Image->resize( dd->thumbnail()->width(), dd->thumbnail()->height() );
00277 Image->fill( dd->paletteBackgroundColor() );
00278 }
00279
00280 ui->EditButton->setEnabled( false );
00281 ui->CurrentImage->setPixmap( *Image );
00282 ui->CurrentImage->update();
00283
00284 bImageFound = false;
00285 }
00286
00287 void ThumbnailPicker::slotSetFromList( int i ) {
00288
00289 QPixmap pm;
00290 pm = shrinkImage( PixList.at(i), 200, true );
00291 SelectedImageIndex = i;
00292
00293 ui->CurrentImage->setPixmap( pm );
00294 ui->CurrentImage->update();
00295 ui->EditButton->setEnabled( true );
00296
00297
00298 *Image = pm;
00299 bImageFound = true;
00300 }
00301
00302 void ThumbnailPicker::slotSetFromURL() {
00303
00304 KURL u = ui->ImageURLBox->url();
00305
00306 if ( u.isValid() ) {
00307 if ( u.isLocalFile() ) {
00308 QFile localFile( u.path() );
00309
00310
00311
00312 QImage im( localFile.name() );
00313
00314 if ( im.isNull() ) {
00315 KMessageBox::sorry( 0,
00316 i18n("Failed to load image at %1").arg( localFile.name() ),
00317 i18n("Failed to Load Image") );
00318 return;
00319 }
00320
00321 uint w = im.width();
00322 uint h = im.height();
00323 uint pad = 4*marginHint() + 2*ui->SearchLabel->height() + actionButton( Ok )->height() + 25;
00324 uint hDesk = kapp->desktop()->availableGeometry().height() - pad;
00325
00326 if ( h > hDesk )
00327 im = im.smoothScale( w*hDesk/h, hDesk );
00328
00329
00330 PixList.insert( 0, new QPixmap( im ) );
00331 ui->ImageList->insertItem( shrinkImage( PixList.current(), 50 ),
00332 u.prettyURL(), 0 );
00333
00334
00335 ui->ImageList->setCurrentItem( 0 );
00336 slotSetFromList(0);
00337
00338 } else if ( KIO::NetAccess::exists(u, true, this) ) {
00339 KTempFile ktf;
00340 QFile *tmpFile = ktf.file();
00341 ktf.unlink();
00342 JobList.append( KIO::copy( u, KURL( tmpFile->name() ), false ) );
00343 #if KDE_IS_VERSION( 3, 3, 90 )
00344 ((KIO::CopyJob*)JobList.current())->setInteractive( false );
00345 #endif
00346 connect (JobList.current(), SIGNAL (result(KIO::Job *)), SLOT (downloadReady (KIO::Job *)));
00347
00348
00349 }
00350 }
00351 }
00352
00353
00354 #include "thumbnailpicker.moc"