• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

kstars

  • sources
  • kde-4.12
  • kdeedu
  • kstars
  • kstars
thumbnailpicker.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  thumbnailpicker.cpp - description
3  -------------------
4  begin : Thu Mar 2 2005
5  copyright : (C) 2005 by Jason Harris
6  email : kstars@30doradus.org
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "thumbnailpicker.h"
19 #include "thumbnaileditor.h"
20 
21 #include <QApplication>
22 #include <QDesktopWidget>
23 #include <QTextStream>
24 #include <QPainter>
25 #include <kio/copyjob.h>
26 
27 #include <kdeversion.h>
28 #include <kpushbutton.h>
29 #include <klineedit.h>
30 #include <kmessagebox.h>
31 #include <kurl.h>
32 #include <kurlrequester.h>
33 #include <klocale.h>
34 #include <kstandarddirs.h>
35 
36 #include "ksutils.h"
37 #include "dialogs/detaildialog.h"
38 #include "skyobjects/skyobject.h"
39 
40 ThumbnailPickerUI::ThumbnailPickerUI( QWidget *parent ) : QFrame( parent ) {
41  setupUi( this );
42 }
43 
44 ThumbnailPicker::ThumbnailPicker( SkyObject *o, const QPixmap &current, QWidget *parent, double _w, double _h, QString cap )
45  : KDialog( parent ), SelectedImageIndex(-1), dd((DetailDialog*)parent), Object(o), bImageFound( false )
46 {
47  wid = _w;
48  ht = _h;
49  Image = new QPixmap( current );
50  ImageRect = new QRect( 0, 0, 200, 200 );
51 
52  ui = new ThumbnailPickerUI( this );
53  setMainWidget( ui );
54  setCaption( cap );
55  setButtons( KDialog::Ok|KDialog::Cancel );
56 
57  ui->CurrentImage->setPixmap( *Image );
58 
59  connect( ui->EditButton, SIGNAL( clicked() ), this, SLOT( slotEditImage() ) );
60  connect( ui->UnsetButton, SIGNAL( clicked() ), this, SLOT( slotUnsetImage() ) );
61  connect( ui->ImageList, SIGNAL( currentRowChanged( int ) ),
62  this, SLOT( slotSetFromList( int ) ) );
63  connect( ui->ImageURLBox, SIGNAL( urlSelected( const KUrl& ) ),
64  this, SLOT( slotSetFromURL() ) );
65  connect( ui->ImageURLBox, SIGNAL( returnPressed() ),
66  this, SLOT( slotSetFromURL() ) );
67 
68  ui->ImageURLBox->lineEdit()->setTrapReturnKey( true );
69  ui->EditButton->setEnabled( false );
70 
71  slotFillList();
72 }
73 
74 ThumbnailPicker::~ThumbnailPicker() {
75  while ( ! PixList.isEmpty() ) delete PixList.takeFirst();
76 }
77 
78 //Query online sources for images of the object
79 void ThumbnailPicker::slotFillList() {
80  //Preload ImageList with the URLs in the object's ImageList:
81  QStringList ImageList( Object->ImageList() );
82 
83  //Query Google Image Search:
84  KUrl gURL( "http://images.google.com/images" );
85  //Search for the primary name, or longname and primary name
86  QString sName = QString("\"%1\"").arg( Object->name() );
87  if ( Object->longname() != Object->name() ) {
88  sName = QString("\"%1\" ").arg( Object->longname() ) + sName;
89  }
90  gURL.addQueryItem( "q", sName ); //add the Google-image query string
91 
92  //Download the google page and parse it for image URLs
93  parseGooglePage( ImageList, gURL.prettyUrl() );
94 
95  //Total Number of images to be loaded:
96  int nImages = ImageList.count();
97  if ( nImages ) {
98  ui->SearchProgress->setMinimum( 0 );
99  ui->SearchProgress->setMaximum( nImages-1 );
100  ui->SearchLabel->setText( i18n( "Loading images..." ) );
101  }
102 
103  //Add images from the ImageList
104  for ( int i=0; i<ImageList.size(); ++i ) {
105  QString s( ImageList[i] );
106  KUrl u( ImageList[i] );
107 
108  if ( u.isValid() ) {
109  KIO::StoredTransferJob *j = KIO::storedGet( u, KIO::NoReload, KIO::HideProgressInfo );
110  j->setUiDelegate(0);
111  connect( j, SIGNAL( result(KJob*) ), SLOT( slotJobResult(KJob*) ) );
112  }
113  }
114 }
115 
116 void ThumbnailPicker::slotJobResult( KJob *job ) {
117  KIO::StoredTransferJob *stjob = (KIO::StoredTransferJob*)job;
118 
119  //Update Progressbar
120  if ( ! ui->SearchProgress->isHidden() ) {
121  ui->SearchProgress->setValue(ui->SearchProgress->value()+1);
122  if ( ui->SearchProgress->value() == ui->SearchProgress->maximum() ) {
123  ui->SearchProgress->hide();
124  ui->SearchLabel->setText( i18n( "Search results:" ) );
125  }
126  }
127 
128  //If there was a problem, just return silently without adding image to list.
129  if ( job->error() ) {
130  kDebug() << " error=" << job->error();
131  job->kill();
132  return;
133  }
134 
135  QPixmap *pm = new QPixmap();
136  pm->loadFromData( stjob->data() );
137 
138  uint w = pm->width();
139  uint h = pm->height();
140  uint pad = 0; /*FIXME LATER 4* KDialogBase::marginHint() + 2*ui->SearchLabel->height() + KDialogBase::actionButton( KDialogBase::Ok )->height() + 25;*/
141  uint hDesk = QApplication::desktop()->availableGeometry().height() - pad;
142 
143  if ( h > hDesk )
144  *pm = pm->scaled( w*hDesk/h, hDesk, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
145 
146  PixList.append( pm );
147 
148  //Add 50x50 image and URL to listbox
149  //ui->ImageList->insertItem( shrinkImage( PixList.last(), 50 ),
150  // cjob->srcURLs().first().prettyUrl() );
151  ui->ImageList->addItem( new QListWidgetItem ( QIcon(shrinkImage( PixList.last(), 50 )), stjob->url().prettyUrl() ));
152 }
153 
154 void ThumbnailPicker::parseGooglePage( QStringList &ImList, const QString &URL ) {
155  QString tmpFile;
156  QString PageHTML;
157 
158  //Read the google image page's HTML into the PageHTML QString:
159  if ( KIO::NetAccess::exists(URL, KIO::NetAccess::SourceSide, this) && KIO::NetAccess::download( URL, tmpFile, this ) ) {
160  QFile file( tmpFile );
161  if ( file.open( QIODevice::ReadOnly ) ) {
162  QTextStream instream(&file);
163  PageHTML = instream.readAll();
164  file.close();
165  KIO::NetAccess::removeTempFile( tmpFile );
166  } else {
167  kDebug() << "Could not read local copy of google image page";
168  KIO::NetAccess::removeTempFile( tmpFile );
169  return;
170  }
171  } else {
172  kDebug() << KIO::NetAccess::lastErrorString();
173  return;
174  }
175 
176  int index = PageHTML.indexOf( "?imgurl=", 0 );
177  while ( index >= 0 ) {
178  index += 8; //move to end of "?imgurl=" marker
179 
180  //Image URL is everything from index to next occurrence of "&"
181  ImList.append( PageHTML.mid( index, PageHTML.indexOf( "&", index ) - index ) );
182 
183  index = PageHTML.indexOf( "?imgurl=", index );
184  }
185 }
186 
187 QPixmap ThumbnailPicker::shrinkImage( QPixmap *pm, int size, bool setImage ) {
188  int w( pm->width() ), h( pm->height() );
189  int bigSize( w );
190  int rx(0), ry(0), sx(0), sy(0), bx(0), by(0);
191  if ( size == 0 ) return QPixmap();
192 
193  //Prepare variables for rescaling image (if it is larger than 'size')
194  if ( w > size && w >= h ) {
195  h = size;
196  w = size*pm->width()/pm->height();
197  } else if ( h > size && h > w ) {
198  w = size;
199  h = size*pm->height()/pm->width();
200  }
201  sx = (w - size)/2;
202  sy = (h - size)/2;
203  if ( sx < 0 ) { rx = -sx; sx = 0; }
204  if ( sy < 0 ) { ry = -sy; sy = 0; }
205 
206  if ( setImage ) bigSize = int( 200.*float(pm->width())/float(w) );
207 
208  QPixmap result( size, size );
209  result.fill( QColor( "white" ) ); //in case final image is smaller than 'size'
210 
211  if ( pm->width() > size || pm->height() > size ) { //image larger than 'size'?
212  //convert to QImage so we can smoothscale it
213  QImage im( pm->toImage() );
214  im = im.scaled( w, h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
215 
216  //bitBlt sizexsize square section of image
217  QPainter p;
218  p.begin( &result );
219  p.drawImage( rx, ry, im, sx, sy, size, size );
220  p.end();
221 
222  if ( setImage ) {
223  bx = int( sx*float(pm->width())/float(w) );
224  by = int( sy*float(pm->width())/float(w) );
225  ImageRect->setRect( bx, by, bigSize, bigSize );
226  }
227 
228  } else { //image is smaller than size x size
229  QPainter p;
230  p.begin( &result );
231  p.drawImage( rx, ry, pm->toImage() );
232  p.end();
233 
234  if ( setImage ) {
235  bx = int( rx*float(pm->width())/float(w) );
236  by = int( ry*float(pm->width())/float(w) );
237  ImageRect->setRect( bx, by, bigSize, bigSize );
238  }
239  }
240 
241  return result;
242 }
243 
244 void ThumbnailPicker::slotEditImage() {
245  QPointer<ThumbnailEditor> te = new ThumbnailEditor( this, wid, ht );
246  if ( te->exec() == QDialog::Accepted ) {
247  QPixmap pm = te->thumbnail();
248  *Image = pm;
249  ui->CurrentImage->setPixmap( pm );
250  ui->CurrentImage->update();
251  }
252  delete te;
253 }
254 
255 void ThumbnailPicker::slotUnsetImage() {
256  QFile file;
257  if ( KSUtils::openDataFile( file, "noimage.png" ) ) {
258  file.close();
259  Image->load( file.fileName(), "PNG" );
260  } else {
261  *Image = Image->scaled( dd->thumbnail()->width(), dd->thumbnail()->height() );
262  Image->fill( dd->palette().color( QPalette::Window ) );
263  }
264 
265  ui->EditButton->setEnabled( false );
266  ui->CurrentImage->setPixmap( *Image );
267  ui->CurrentImage->update();
268 
269  bImageFound = false;
270 }
271 
272 void ThumbnailPicker::slotSetFromList( int i ) {
273  //Display image in preview pane
274  QPixmap pm;
275  pm = shrinkImage( PixList[i], 200, true ); //scale image
276  SelectedImageIndex = i;
277 
278  ui->CurrentImage->setPixmap( pm );
279  ui->CurrentImage->update();
280  ui->EditButton->setEnabled( true );
281 
282  *Image = PixList[i]->scaled( wid, ht, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
283  bImageFound = true;
284 }
285 
286 void ThumbnailPicker::slotSetFromURL() {
287  //Attempt to load the specified URL
288  KUrl u = ui->ImageURLBox->url();
289 
290  if ( u.isValid() ) {
291  if ( u.isLocalFile() ) {
292  QFile localFile( u.toLocalFile() );
293 
294  //Add image to list
295  //If image is taller than desktop, rescale it.
296  QImage im( localFile.fileName() );
297 
298  if ( im.isNull() ) {
299  KMessageBox::sorry( 0,
300  i18n("Failed to load image at %1", localFile.fileName() ),
301  i18n("Failed to load image") );
302  return;
303  }
304 
305  uint w = im.width();
306  uint h = im.height();
307  uint pad = 0;/* FIXME later 4*marginHint() + 2*ui->SearchLabel->height() + actionButton( Ok )->height() + 25; */
308  uint hDesk = QApplication::desktop()->availableGeometry().height() - pad;
309 
310  if ( h > hDesk )
311  im = im.scaled( w*hDesk/h, hDesk, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
312 
313  //Add Image to top of list and 50x50 thumbnail image and URL to top of listbox
314  PixList.insert( 0, new QPixmap( QPixmap::fromImage( im ) ) );
315  ui->ImageList->insertItem( 0, new QListWidgetItem ( QIcon(shrinkImage( PixList.last(), 50 )), u.prettyUrl() ));
316 
317  //Select the new image
318  ui->ImageList->setCurrentRow( 0 );
319  slotSetFromList(0);
320 
321  } else {
322  KIO::StoredTransferJob *j = KIO::storedGet( u, KIO::NoReload, KIO::HideProgressInfo );
323  j->setUiDelegate(0);
324  connect( j, SIGNAL( result(KJob*) ), SLOT( slotJobResult(KJob*) ) );
325  }
326  }
327 }
328 
329 #include "thumbnailpicker.moc"
DetailDialog
window showing detailed information for a selected object.
Definition: detaildialog.h:88
ThumbnailEditor
Definition: thumbnaileditor.h:36
ThumbnailPickerUI::ThumbnailPickerUI
ThumbnailPickerUI(QWidget *p)
Definition: thumbnailpicker.cpp:40
detaildialog.h
skyobject.h
SkyObject::longname
virtual QString longname(void) const
Definition: skyobject.h:140
QWidget
KDialog
KSUtils::openDataFile
bool openDataFile(QFile &file, const QString &filename)
Attempt to open the data file named filename, using the QFile object "file".
SkyObject::ImageList
QStringList & ImageList()
Definition: skyobject.h:299
ThumbnailPickerUI
Definition: thumbnailpicker.h:34
QTextStream
thumbnaileditor.h
DetailDialog::thumbnail
QPixmap * thumbnail()
Definition: detaildialog.h:102
thumbnailpicker.h
ThumbnailPicker::ThumbnailPicker
ThumbnailPicker(SkyObject *o, const QPixmap &current, QWidget *parent=0, double w=200, double h=200, QString cap=i18n("Choose Thumbnail Image"))
Definition: thumbnailpicker.cpp:44
ThumbnailPicker::~ThumbnailPicker
~ThumbnailPicker()
Definition: thumbnailpicker.cpp:74
SkyObject::name
virtual QString name(void) const
Definition: skyobject.h:124
ksutils.h
SkyObject
Provides all necessary information about an object in the sky: its coordinates, name(s), type, magnitude, and QStringLists of URLs for images and webpages regarding the object.
Definition: skyobject.h:46
QFrame
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:36:21 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kstars

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

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal