• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kstars

thumbnailpicker.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           thumbnailpicker.cpp  -  description
00003                              -------------------
00004     begin                : Thu Mar 2 2005
00005     copyright            : (C) 2005 by Jason Harris
00006     email                : kstars@30doradus.org
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
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 &current, 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 //Query online sources for images of the object
00081 void ThumbnailPicker::slotFillList() {
00082     //Preload list with object's ImageList:
00083     QStringList ImageList( Object->ImageList );
00084 
00085     //Query Google Image Search:
00086     KURL gURL( "http://images.google.com/images" );
00087     //Search for the primary name, or longname and primary name
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 ); //add the Google-image query string
00093 
00094     //Download the google page and parse it for image URLs
00095     parseGooglePage( ImageList, gURL.prettyURL() );
00096 
00097     //Total Number of images to be loaded:
00098     int nImages = ImageList.count();
00099     if ( nImages ) {
00100         ui->SearchProgress->setTotalSteps( nImages );
00101         ui->SearchLabel->setText( i18n( "Loading images..." ) );
00102     }
00103 
00104     //Add images from the ImageList
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(); //just need filename
00114             JobList.append( KIO::copy( u, KURL( tmpFile->name() ), false ) ); //false = no progress window
00115 #if KDE_IS_VERSION( 3, 3, 90 )
00116             ((KIO::CopyJob*)JobList.current())->setInteractive( false ); // suppress error dialogs
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     //Read the google image page's HTML into the PageHTML QString:
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; //move to end of "?imgurl=" marker
00147 
00148         //Image URL is everything from index to next occurence of "&"
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     //Note: no need to delete the job, it is automatically deleted !
00157 
00158     //Update Progressbar
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     //If there was a problem, just return silently without adding image to list.
00168     if ( job->error() ) {
00169 //      job->showErrorDialog();
00170         return;
00171     }
00172 
00173     KIO::CopyJob *cjob = (KIO::CopyJob*)job;
00174     QFile tmp( cjob->destURL().path() );
00175     tmp.close(); // to get the newest information of the file
00176 
00177     //Add image to list
00178     //If image is taller than desktop, rescale it.
00179     //I tried to use kapp->style().pixelMetric( QStyle::PM_TitleBarHeight )
00180     //for the titlebar height, but this returned zero.
00181     //Hard-coding 25 instead :(
00182     if ( tmp.exists() ) {
00183         QImage im( tmp.name() );
00184 
00185         if ( im.isNull() ) { 
00186           //KMessageBox::sorry( 0, i18n("Failed to load image"), 
00187           //       i18n("Could Not Load Specified Image") );
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 //  this returns zero...
00197 //      //DEBUG
00198 //      kdDebug() << "Title bar height: " << kapp->style().pixelMetric( QStyle::PM_TitleBarHeight ) << endl;
00199 
00200         if ( h > hDesk ) 
00201             im = im.smoothScale( w*hDesk/h, hDesk );
00202 
00203         PixList.append( new QPixmap( im ) );
00204 
00205         //Add 50x50 image and URL to listbox
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     //Prepare variables for rescaling image (if it is larger than 'size')
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" ) ); //in case final image is smaller than 'size'
00234 
00235     if ( pm->width() > size || pm->height() > size ) { //image larger than 'size'?
00236         //convert to QImage so we can smoothscale it
00237         QImage im( pm->convertToImage() );
00238         im = im.smoothScale( w, h );
00239         
00240         //bitBlt sizexsize square section of image
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 { //image is smaller than size x size
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     //Display image in preview pane
00289     QPixmap pm;
00290     pm = shrinkImage( PixList.at(i), 200, true ); //scale image
00291     SelectedImageIndex = i;
00292 
00293     ui->CurrentImage->setPixmap( pm );
00294     ui->CurrentImage->update();
00295     ui->EditButton->setEnabled( true );
00296 
00297     //Set Image to the selected 200x200 pixmap
00298     *Image = pm;
00299     bImageFound = true;
00300 }
00301 
00302 void ThumbnailPicker::slotSetFromURL() {
00303     //Attempt to load the specified URL
00304     KURL u = ui->ImageURLBox->url();
00305 
00306     if ( u.isValid() ) {
00307         if ( u.isLocalFile() ) {
00308             QFile localFile( u.path() );
00309 
00310             //Add image to list
00311             //If image is taller than desktop, rescale it.
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             //Add Image to top of list and 50x50 thumbnail image and URL to top of listbox
00330             PixList.insert( 0, new QPixmap( im ) );
00331             ui->ImageList->insertItem( shrinkImage( PixList.current(), 50 ),
00332                     u.prettyURL(), 0 );
00333 
00334             //Select the new image
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(); //just need filename
00342             JobList.append( KIO::copy( u, KURL( tmpFile->name() ), false ) ); //false = no progress window
00343 #if KDE_IS_VERSION( 3, 3, 90 )
00344             ((KIO::CopyJob*)JobList.current())->setInteractive( false ); // suppress error dialogs
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"

kstars

Skip menu "kstars"
  • Main Page
  • Modules
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • keduca
  • kstars
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal