summaryrefslogtreecommitdiff
authorwarmi <warmi>2002-08-15 03:19:32 (UTC)
committer warmi <warmi>2002-08-15 03:19:32 (UTC)
commitacdedf093413a37a3e2c1ab5b12c1ab0a95b670b (patch) (unidiff)
treee5ffc814ae6b7e0787b24347e3e98c16fa3ca68c
parent92640e4094075342138796065040441210348c76 (diff)
downloadopie-acdedf093413a37a3e2c1ab5b12c1ab0a95b670b.zip
opie-acdedf093413a37a3e2c1ab5b12c1ab0a95b670b.tar.gz
opie-acdedf093413a37a3e2c1ab5b12c1ab0a95b670b.tar.bz2
Bunch of new GUI features ( brightness control, ability to view unscaled images ..)
Qte image handling issues are still not fixed though.
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--noncore/multimedia/showimg/showimg.cpp845
1 files changed, 666 insertions, 179 deletions
diff --git a/noncore/multimedia/showimg/showimg.cpp b/noncore/multimedia/showimg/showimg.cpp
index 24218e6..d7d53ec 100644
--- a/noncore/multimedia/showimg/showimg.cpp
+++ b/noncore/multimedia/showimg/showimg.cpp
@@ -23,11 +23,14 @@
23// 23//
24 24
25#include "showimg.h" 25#include "showimg.h"
26#include "ImageFileSelector.h"
26 27
28#include <qpe/config.h>
27#include <qpe/resource.h> 29#include <qpe/resource.h>
28#include <qpe/fileselector.h> 30#include <qpe/fileselector.h>
29#include <qpe/applnk.h> 31#include <qpe/applnk.h>
30 32#include <qfileinfo.h>
33#include <math.h>
31#include <qpe/qpemenubar.h> 34#include <qpe/qpemenubar.h>
32#include <qwidgetstack.h> 35#include <qwidgetstack.h>
33#include <qpe/qpetoolbar.h> 36#include <qpe/qpetoolbar.h>
@@ -35,57 +38,144 @@
35#include <qfiledialog.h> 38#include <qfiledialog.h>
36#include <qmessagebox.h> 39#include <qmessagebox.h>
37#include <qpopupmenu.h> 40#include <qpopupmenu.h>
41#include <qscrollview.h>
38#include <qlabel.h> 42#include <qlabel.h>
39#include <qpainter.h> 43#include <qpainter.h>
40#include <qkeycode.h> 44#include <qkeycode.h>
41#include <qapplication.h> 45#include <qapplication.h>
42#include <qclipboard.h> 46#include <qclipboard.h>
43#include <qtimer.h> 47#include <qtimer.h>
48#include <qspinbox.h>
44 49
45 50
46ImagePane::ImagePane( QWidget *parent ) : QWidget( parent ) 51
52ControlsDialog::ControlsDialog(const QString &caption,QImage image,int *brightness,QWidget *parent):QDialog(parent,0,true)
47{ 53{
48 vb = new QVBoxLayout( this ); 54 setCaption(caption);
55
56 if ( parent )
57 {
58 setPalette(parent->palette());
59 }
49 60
50 image = new ImageWidget( this ); 61 b=brightness;
51 connect(image, SIGNAL( clicked() ), this, SLOT( imageClicked() )); 62 img=image;
52 63
53 vb->addWidget( image ); 64 setMinimumSize(140,80);
65
66 QGridLayout *gl= new QGridLayout(this,2,2,4,4);
67
68 pixmap =new ImageWidget(this);;
69 QPixmap pm;
70 pm.convertFromImage(img);
71 pixmap->setPixmap(pm);
72 pixmap->setMinimumSize(pm.width(),pm.height());
73 gl->addMultiCellWidget(pixmap,0,0,0,2,AlignCenter);
74 QLabel *l=new QLabel(tr("Brightness")+":",this);
75 gl->addWidget(l,1,0,AlignLeft);
76 spb=new QSpinBox(-100,100,2,this);
77 gl->addWidget(spb,1,1,AlignRight);
78
79 spb->setValue(0);
80
81 connect(spb,SIGNAL(valueChanged(int)),this, SLOT(bValueChanged(int)));
54 82
55 status = new QLabel( this );
56 status->setFixedHeight( fontMetrics().height() + 4 );
57 vb->addWidget( status );
58} 83}
59 84
60void ImagePane::setPixmap( const QPixmap &pm ) 85void ControlsDialog::bValueChanged(int value)
61{ 86{
62 image->setPixmap( pm ); 87 QImage nImage=img;
63 image->repaint( false ); 88 nImage.detach();
89 ImageViewer::intensity(nImage, (float)value/100);
90 QPixmap pm;
91 pm.convertFromImage(nImage);
92 pixmap->setPixmap(pm);
93 pixmap->repaint(false);
94
95
64} 96}
65 97
66void ImagePane::imageClicked() 98void ControlsDialog::accept()
67{ 99{
68 emit clicked(); 100 *b=spb->value();
101 done(1);
69} 102}
70 103
71void ImagePane::showStatus() 104
105
106InfoDialog::InfoDialog(const QString &caption, const QStringList text,QWidget *parent):QDialog(parent,0,true)
72{ 107{
73 delete vb; 108 setCaption(caption);
74 vb = new QVBoxLayout( this ); 109
75 vb->addWidget( image ); 110 if ( parent )
76 status->show(); 111 {
77 vb->addWidget( status ); 112 setPalette(parent->palette());
78} 113}
79 114
115 const char *labels[]={"File Name","Format","File Size","Size","Colors","Alpha"};
116
117 setMinimumSize(180,80);
118 int num=ImageViewer::LAST+1;
119 if ( text[ImageViewer::ALPHA].isEmpty() )
120 num--;
121 QGridLayout *gl= new QGridLayout(this,num,2,4,2);
122 QLabel *l;
123 int count=0;
124 for ( int i=0;i<num;i++ )
125 {
126 if ( i==1 )
127 {
128 QFrame *frm=new QFrame(this);
129 frm->setFrameStyle(QFrame::HLine|QFrame::Sunken);
130 gl->addMultiCellWidget(frm,i,i,0,1);
131 }
132 else
133 {
134 l=new QLabel(tr(labels[count])+":",this);
135 gl->addWidget(l,i,0,AlignLeft);
136 l=new QLabel(text[count],this);
137 gl->addWidget(l,i,1,AlignRight);
138 count++;
139 }
80 140
81void ImagePane::hideStatus() 141 }
142
143}
144
145void InfoDialog::displayInfo(const QString &caption, const QStringList text, QWidget *parent)
146{
147 InfoDialog *dlg=new InfoDialog(caption,text,parent);
148 dlg->exec();
149 delete dlg;
150}
151
152
153ImagePane::ImagePane( QWidget *parent ) : QWidget( parent )
82{ 154{
83 delete vb;
84 vb = new QVBoxLayout( this ); 155 vb = new QVBoxLayout( this );
156
157 image = new QScrollView(this,0,WResizeNoErase|WNorthWestGravity);
158 pic=new ImageWidget(image);
159 image->addChild(pic);
160
161 connect(pic, SIGNAL( clicked() ), this, SLOT( imageClicked() ));
162
85 vb->addWidget( image ); 163 vb->addWidget( image );
86 status->hide(); 164
165}
166
167void ImagePane::setPixmap( const QPixmap &pm )
168{
169 pic->setPixmap( pm );
170 pic->resize(pm.width(),pm.height());
171 image->updateScrollBars ();
172 pic->repaint(false);
87} 173}
88 174
175void ImagePane::imageClicked()
176{
177 emit clicked();
178}
89//=========================================================================== 179//===========================================================================
90/* 180/*
91 Draws the portion of the scaled pixmap that needs to be updated 181 Draws the portion of the scaled pixmap that needs to be updated
@@ -96,10 +186,10 @@ void ImageWidget::paintEvent( QPaintEvent *e )
96 QPainter painter(this); 186 QPainter painter(this);
97 187
98 painter.setClipRect(e->rect()); 188 painter.setClipRect(e->rect());
99 painter.setBrush( black ); 189 painter.fillRect(0,0,width(),height(),QColor(0,0,0));
100 painter.drawRect( 0, 0, width(), height() );
101 190
102 if ( pixmap.size() != QSize( 0, 0 ) ) { // is an image loaded? 191 if ( pixmap.size() != QSize( 0, 0 ) )
192 { // is an image loaded?
103 painter.drawPixmap((width() - pixmap.width()) / 2, (height() - pixmap.height()) / 2, pixmap); 193 painter.drawPixmap((width() - pixmap.width()) / 2, (height() - pixmap.height()) / 2, pixmap);
104 } 194 }
105} 195}
@@ -109,16 +199,21 @@ void ImageWidget::mouseReleaseEvent(QMouseEvent *)
109 emit clicked(); 199 emit clicked();
110} 200}
111 201
112
113//=========================================================================== 202//===========================================================================
114 203
115ImageViewer::ImageViewer( QWidget *parent, const char *name, int wFlags ) 204ImageViewer::ImageViewer( QWidget *parent, const char *name, int wFlags )
116 : QMainWindow( parent, name, wFlags ), filename( 0 ), 205: QMainWindow( parent, name, wFlags ), filename( 0 ), bFromDocView( FALSE )
117 pickx( -1 ), picky( -1 ), clickx( -1 ), clicky( -1 ), bFromDocView( FALSE )
118{ 206{
119 setCaption( tr("Image Viewer") ); 207 setCaption( tr("Image Viewer") );
120 setIcon( Resource::loadPixmap( "ImageViewer" ) ); 208 setIcon( Resource::loadPixmap( "ImageViewer" ) );
121 209
210
211 Config cfg("Image Viewer");
212 cfg.setGroup("Image Viewer");
213
214 showThumbView=cfg.readBoolEntry("ShowThumbnails",false);
215 isSized=cfg.readBoolEntry("SizeToScreen",true);
216
122 isFullScreen = FALSE; 217 isFullScreen = FALSE;
123 218
124 setToolBarsMovable( FALSE ); 219 setToolBarsMovable( FALSE );
@@ -126,69 +221,203 @@ ImageViewer::ImageViewer( QWidget *parent, const char *name, int wFlags )
126 toolBar = new QPEToolBar( this ); 221 toolBar = new QPEToolBar( this );
127 toolBar->setHorizontalStretchable( TRUE ); 222 toolBar->setHorizontalStretchable( TRUE );
128 223
129 menubar = new QPEMenuBar( toolBar ); 224 menuBar = new QPEMenuBar( toolBar );
225
226 current=menuBar;
227
228
229
230 fileMenuFile = new QPopupMenu(this);
231 //menuBarmenubarFile->insertItem( tr("File"), fileMenu );
232 fileMenuFile->insertItem(tr("Open"), this, SLOT(openFile()), 0);
233
234 viewMenuFile = new QPopupMenu( this );
235 //menubarFile->insertItem( tr("View"), viewMenu );
236 viewMenuFile->insertItem( tr("Thumbnail View"), this, SLOT(switchThumbView()), 0, SHOW_THUMBNAILS );
237
238 viewMenuFile->setItemChecked ( SHOW_THUMBNAILS, showThumbView );
239
240
241
242
243 optionsMenuFile = new QPopupMenu( this);
244 //menubarFile->insertItem( tr("Options"),optionsMenu );
245 optionsMenuFile->insertItem( tr("Slideshow") );
246 optionsMenuFile->insertSeparator();
247 optionsMenuFile->insertItem( tr("Preferences.."));
248 optionsMenuFile->insertItem( tr("Help"));
249
250
251
130 252
131 QStrList fmt = QImage::outputFormats(); 253 QStrList fmt = QImage::outputFormats();
132 254
133 QPopupMenu *edit = new QPopupMenu( menubar );
134 QPopupMenu *view = new QPopupMenu( menubar );
135 255
136 menubar->insertItem(tr("Edit"), edit ); 256 fileMenuView = new QPopupMenu( this );
137 menubar->insertItem(tr("View"), view ); 257 //menubarView->insertItem( tr("File"),fileMenu );
258 fileMenuView->insertItem( tr("Image Info ..."),this, SLOT(displayInfoDialog()),0 );
259 fileMenuView->insertSeparator();
260
261 viewMenuView = new QPopupMenu(this );
262 viewMenuView->setCheckable ( true );
138 263
139 edit->insertItem(tr("Horizontal flip"), this, SLOT(hFlip()), 0); 264 //menubarView->insertItem( tr("View"),viewMenu );
140 edit->insertItem(tr("Vertical flip"), this, SLOT(vFlip()), 0); 265 viewMenuView->insertItem(tr("Horizontal flip"), this, SLOT(hFlip()), 0);
266 viewMenuView->insertItem(tr("Vertical flip"), this, SLOT(vFlip()), 0);
141 267
142 stack = new QWidgetStack( this ); 268 stack = new QWidgetStack( this );
143 stack->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) ); 269 stack->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
144 setCentralWidget( stack ); 270 setCentralWidget( stack );
145 271
272
146 imagePanel = new ImagePane( stack ); 273 imagePanel = new ImagePane( stack );
147 connect(imagePanel, SIGNAL(clicked()), this, SLOT(normalView())); 274 connect(imagePanel, SIGNAL(clicked()), this, SLOT(normalView()));
148 275
149 fileSelector = new FileSelector("image/*", stack, "fs"); 276
150 fileSelector->setNewVisible(FALSE); 277 ImageFileSelector::CURRENT_VIEW cv;
151 fileSelector->setCloseVisible(FALSE); 278 if(showThumbView)
279 cv=ImageFileSelector::THUMBNAIL;
280 else
281 cv=ImageFileSelector::DETAILED;
282
283 qDebug("cv = %d",cv);
284
285 fileSelector = new ImageFileSelector( cv,stack, "fs");
286
287 //switchThumbView();
288
289
290 //fileSelector = new ImageFileSelector("image/*", stack, "fs");
291 //fileSelector->setNewVisible(FALSE);
292 //fileSelector->setCloseVisible(FALSE);
152 connect( fileSelector, SIGNAL( closeMe() ), this, SLOT( closeFileSelector() ) ); 293 connect( fileSelector, SIGNAL( closeMe() ), this, SLOT( closeFileSelector() ) );
153 connect( fileSelector, SIGNAL( fileSelected( const DocLnk &) ), this, SLOT( openFile( const DocLnk & ) ) ); 294 connect( fileSelector, SIGNAL( fileSelected( const DocLnk &) ), this, SLOT( openFile( const DocLnk & ) ) );
154 295
155 toolBar = new QPEToolBar( this ); 296 iconToolBar = new QPEToolBar(this);
156 297
157 QAction *a; 298 QAction *a;
158 299
159 a = new QAction( tr( "Open" ), Resource::loadPixmap( "fileopen" ), QString::null, 0, this, 0 ); 300 a = new QAction( tr( "Open ..." ), Resource::loadPixmap( "fileopen" ), QString::null, 0, this, 0 );
160 connect( a, SIGNAL( activated() ), this, SLOT( open() ) ); 301 connect( a, SIGNAL( activated() ), this, SLOT( open() ) );
161 a->addTo( toolBar ); 302 a->addTo( fileMenuView);
303 a->addTo( iconToolBar );
162 304
163 a = new QAction( tr( "Rotate 180" ), Resource::loadPixmap( "repeat" ), QString::null, 0, this, 0 );
164 connect( a, SIGNAL( activated() ), this, SLOT( rot180() ) );
165 a->addTo( toolBar );
166 a->addTo( edit );
167 305
168 a = new QAction( tr( "Rotate 90"), Resource::loadPixmap( "rotate90" ), QString::null, 0, this, 0); 306 a = new QAction( tr( "Rotate 90"), Resource::loadPixmap( "rotate90" ), QString::null, 0, this, 0);
169 connect( a, SIGNAL( activated() ), this, SLOT( rot90() ) ); 307 connect( a, SIGNAL( activated() ), this, SLOT( rot90() ) );
170 a->addTo( toolBar ); 308 a->addTo( iconToolBar );
171 a->addTo( edit ); 309 a->addTo( viewMenuView );
310
311 a = new QAction( tr( "Rotate 180" ), Resource::loadPixmap( "repeat" ), QString::null, 0, this, 0 );
312 connect( a, SIGNAL( activated() ), this, SLOT( rot180() ) );
313 a->addTo( iconToolBar );
314 a->addTo( viewMenuView );
315
316
317 a = new QAction( tr( "Rotate 270"), Resource::loadPixmap( "rotate270" ), QString::null, 0, this, 0);
318 connect( a, SIGNAL( activated() ), this, SLOT( rot270() ) );
319 //a->addTo( iconToolBar );
320 a->addTo( viewMenuView );
321
322
323
324 viewMenuView->insertSeparator();
325 viewMenuView->insertItem(tr("Brightness ..."), this, SLOT(displayControlsDialog()), 0);
326 viewMenuView->insertItem(tr("Black And White"), this, SLOT(blackAndWhite()), 0,BLACKANDWHITE);
327 viewMenuView->insertSeparator();
328
329
330 sss = new QAction( tr( "Scale to Screen"), Resource::loadPixmap( "scale" ), QString::null, 0, this, 0,true);
331 connect( sss, SIGNAL( activated() ), this, SLOT( switchSizeToScreen() ) );
332 sss->addTo( iconToolBar );
333 sss->addTo( viewMenuView );
334
335 sss->setOn(isSized);
336 viewMenuView->insertSeparator();
337
172 338
173 a = new QAction( tr( "Fullscreen" ), Resource::loadPixmap( "fullscreen" ), QString::null, 0, this, 0 ); 339 a = new QAction( tr( "Fullscreen" ), Resource::loadPixmap( "fullscreen" ), QString::null, 0, this, 0 );
174 connect( a, SIGNAL( activated() ), this, SLOT( fullScreen() ) ); 340 connect( a, SIGNAL( activated() ), this, SLOT( fullScreen() ) );
175 a->addTo( toolBar ); 341 a->addTo( iconToolBar );
176 a->addTo( view); 342 a->addTo( viewMenuView);
177 343
178 stack->raiseWidget( fileSelector ); 344 switchToFileSelector();
179 345
180 setMouseTracking( TRUE ); 346 setMouseTracking( TRUE );
347
348
181} 349}
182 350
183ImageViewer::~ImageViewer() 351ImageViewer::~ImageViewer()
184{ 352{
353 Config cfg("Image Viewer");
354 cfg.setGroup("Image Viewer");
355
356 cfg.writeEntry("ShowThumbnails",(int)showThumbView);
357 cfg.writeEntry("SizeToScreen",(int)isSized);
358
185 delete imagePanel; // in case it is fullscreen 359 delete imagePanel; // in case it is fullscreen
186} 360}
187 361
362void ImageViewer::switchSizeToScreen()
363{
364 isSized=!isSized;
365 sss->setOn(isSized);
366 updateImage();
367}
368
369void ImageViewer::updateImage()
370{
371 if ( isSized )
372 {
373 imagePanel->setPixmap(pmScaled);
374 }
375 else
376 {
377 imagePanel->setPixmap(pm);
378 }
379}
380
381void ImageViewer::switchThumbView()
382{
383
384 showThumbView=!showThumbView;
385 viewMenuFile->setItemChecked ( SHOW_THUMBNAILS, showThumbView );
386 fileSelector->switchView();
387
388}
389
390void ImageViewer::switchToFileSelector()
391{
392 stack->raiseWidget(fileSelector);
393 menuBar->clear();
394 menuBar->insertItem( tr("File"), fileMenuFile );
395 menuBar->insertItem( tr("View"), viewMenuFile );
396 menuBar->insertItem( tr("Options"), optionsMenuFile );
397 iconToolBar->hide();
398 imagePanel->disable();
399
400}
401
402void ImageViewer::switchToImageView()
403{
404 stack->raiseWidget(imagePanel);
405
406 menuBar->clear();
407 menuBar->insertItem( tr("File"), fileMenuView );
408 menuBar->insertItem( tr("View"), viewMenuView );
409 viewMenuView->setItemEnabled(BLACKANDWHITE,true);
410 iconToolBar->show();
411
412 imagePanel->setPosition(0,0);
413
414}
415
416
188void ImageViewer::setDocument(const QString& fileref) 417void ImageViewer::setDocument(const QString& fileref)
189{ 418{
190 delayLoad = fileref; 419 delayLoad = fileref;
191 stack->raiseWidget(imagePanel); 420 switchToImageView();
192 QTimer::singleShot( 0, this, SLOT(doDelayedLoad()) ); 421 QTimer::singleShot( 0, this, SLOT(doDelayedLoad()) );
193} 422}
194 423
@@ -208,9 +437,12 @@ void ImageViewer::show(const QString& fileref)
208 bFromDocView = TRUE; 437 bFromDocView = TRUE;
209 closeFileSelector(); 438 closeFileSelector();
210 DocLnk link(fileref); 439 DocLnk link(fileref);
211 if ( link.isValid() ) { 440 if ( link.isValid() )
441 {
212 openFile(link); 442 openFile(link);
213 } else { 443 }
444 else
445 {
214 filename = fileref; 446 filename = fileref;
215 updateCaption( fileref ); 447 updateCaption( fileref );
216 loadImage( fileref ); 448 loadImage( fileref );
@@ -227,12 +459,12 @@ void ImageViewer::openFile( const DocLnk &file )
227 459
228void ImageViewer::open() 460void ImageViewer::open()
229{ 461{
230 stack->raiseWidget(fileSelector); 462 switchToFileSelector();
231} 463}
232 464
233void ImageViewer::closeFileSelector() 465void ImageViewer::closeFileSelector()
234{ 466{
235 stack->raiseWidget(imagePanel); 467 switchToImageView();
236} 468}
237 469
238void ImageViewer::updateCaption( QString name ) 470void ImageViewer::updateCaption( QString name )
@@ -250,46 +482,55 @@ void ImageViewer::updateCaption( QString name )
250void ImageViewer::loadImage( const char *fileName ) 482void ImageViewer::loadImage( const char *fileName )
251{ 483{
252 filename = fileName; 484 filename = fileName;
253 if ( filename ) { 485 if ( filename )
486 {
254 QApplication::setOverrideCursor( waitCursor ); // this might take time 487 QApplication::setOverrideCursor( waitCursor ); // this might take time
255 imagePanel->statusLabel()->setText( tr("Loading image...") ); 488 //imagePanel->statusLabel()->setText( tr("Loading image...") );
256 qApp->processEvents(); 489 qApp->processEvents();
257 bool ok = image.load(filename, 0); 490 bool ok = image.load(filename, 0);
258 pickx = -1;
259 clickx = -1;
260 if ( ok ) 491 if ( ok )
492 {
261 ok = reconvertImage(); 493 ok = reconvertImage();
262 if ( !ok ) { 494 updateImageInfo(filename);
495 }
496 if ( !ok )
497 {
263 pm.resize(0,0); // couldn't load image 498 pm.resize(0,0); // couldn't load image
264 update(); 499 update();
265 } 500 }
266 QApplication::restoreOverrideCursor();// restore original cursor 501 QApplication::restoreOverrideCursor();// restore original cursor
267 } 502 }
268 updateStatus(); 503 switchToImageView();
269 imagePanel->setPixmap( pmScaled ); 504 updateImage();
270 stack->raiseWidget(imagePanel); 505
271} 506}
272 507
273bool ImageViewer::loadSelected() 508bool ImageViewer::loadSelected()
274{ 509{
275 bool ok = false; 510 bool ok = false;
276 if ( stack->visibleWidget() == fileSelector ) { 511 if ( stack->visibleWidget() == fileSelector )
512 {
277 const DocLnk *link = fileSelector->selected(); 513 const DocLnk *link = fileSelector->selected();
278 if ( link ) { 514 if ( link )
279 if ( link->file() != filename ) { 515 {
516 if ( link->file() != filename )
517 {
280 updateCaption( link->name() ); 518 updateCaption( link->name() );
281 filename = link->file(); 519 filename = link->file();
282 imagePanel->statusLabel()->setText( tr("Loading image...") );
283 qApp->processEvents(); 520 qApp->processEvents();
284 ok = image.load(filename, 0); 521 ok = image.load(filename, 0);
285 if ( ok ) 522 if ( ok )
523 {
524 updateImageInfo(filename);
286 ok = reconvertImage(); 525 ok = reconvertImage();
526 }
287 if ( !ok ) 527 if ( !ok )
288 pm.resize(0,0); 528 pm.resize(0,0);
289 } 529 }
290 } 530 }
291 } 531 }
292 if ( !image.isNull() ) { 532 if ( !image.isNull() )
533 {
293 ok = true; 534 ok = true;
294 closeFileSelector(); 535 closeFileSelector();
295 } 536 }
@@ -309,7 +550,9 @@ bool ImageViewer::reconvertImage()
309 pmScaled = QPixmap(); 550 pmScaled = QPixmap();
310 scale(); 551 scale();
311 success = TRUE; // load successful 552 success = TRUE; // load successful
312 } else { 553 }
554 else
555 {
313 pm.resize(0,0); // couldn't load image 556 pm.resize(0,0); // couldn't load image
314 } 557 }
315 QApplication::restoreOverrideCursor();// restore original cursor 558 QApplication::restoreOverrideCursor();// restore original cursor
@@ -321,8 +564,7 @@ bool ImageViewer::reconvertImage()
321int ImageViewer::calcHeight() 564int ImageViewer::calcHeight()
322{ 565{
323 if ( !isFullScreen) 566 if ( !isFullScreen)
324 return height() - menubar->heightForWidth( width() ) 567 return imagePanel->paneHeight();
325 - imagePanel->statusLabel()->height();
326 else 568 else
327 return qApp->desktop()->height(); 569 return qApp->desktop()->height();
328} 570}
@@ -330,18 +572,20 @@ int ImageViewer::calcHeight()
330 This functions scales the pixmap in the member variable "pm" to fit the 572 This functions scales the pixmap in the member variable "pm" to fit the
331 widget size and puts the resulting pixmap in the member variable "pmScaled". 573 widget size and puts the resulting pixmap in the member variable "pmScaled".
332*/ 574*/
333
334void ImageViewer::scale() 575void ImageViewer::scale()
335{ 576{
336 int h = calcHeight(); 577 int h = calcHeight();
337 if ( image.isNull() ) return; 578 if ( image.isNull() ) return;
338 579
339 QApplication::setOverrideCursor( waitCursor ); // this might take time 580 QApplication::setOverrideCursor( waitCursor ); // this might take time
340 if ( width() == pm.width() && h == pm.height() ) { // no need to scale if widget 581 if ( imagePanel->paneWidth() == pm.width() && h == pm.height() )
582 { // no need to scale if widget
341 pmScaled = pm; // size equals pixmap size 583 pmScaled = pm; // size equals pixmap size
342 } else { 584 }
585 else
586 {
343 double hs = (double)h / (double)image.height(); 587 double hs = (double)h / (double)image.height();
344 double ws = (double)width() / (double)image.width(); 588 double ws = (double)imagePanel->paneWidth() / (double)image.width();
345 double scaleFactor = (hs > ws) ? ws : hs; 589 double scaleFactor = (hs > ws) ? ws : hs;
346 int smoothW = (int)(scaleFactor * image.width()); 590 int smoothW = (int)(scaleFactor * image.width());
347 int smoothH = (int)(scaleFactor * image.height()); 591 int smoothH = (int)(scaleFactor * image.height());
@@ -358,122 +602,124 @@ void ImageViewer::scale()
358 602
359void ImageViewer::resizeEvent( QResizeEvent * ) 603void ImageViewer::resizeEvent( QResizeEvent * )
360{ 604{
361 imagePanel->statusLabel()->setGeometry(0, height() - imagePanel->statusLabel()->height(),
362 width(), imagePanel->statusLabel()->height());
363 605
364 if ( pm.size() == QSize( 0, 0 ) ) // we couldn't load the image 606 if ( pm.size() == QSize( 0, 0 ) ) // we couldn't load the image
365 return; 607 return;
366 608
367 int h = calcHeight(); 609 int h = calcHeight();
368 610
369 if ( width() != pmScaled.width() || h != pmScaled.height()) 611 if ( imagePanel->paneWidth() != pmScaled.width() || h != pmScaled.height() )
370 { // if new size, 612 { // if new size,
371 scale(); // scale pmScaled to window 613 scale(); // scale pmScaled to window
372 updateStatus();
373 } 614 }
374 if ( image.hasAlphaBuffer() ) 615 if ( image.hasAlphaBuffer() )
375 erase(); 616 erase();
376} 617}
377 618
378void ImageViewer::convertEvent( QMouseEvent* e, int& x, int& y)
379{
380 if ( pm.size() != QSize( 0, 0 ) ) {
381 int h = height() - menubar->heightForWidth( width() ) - imagePanel->statusLabel()->height();
382 int nx = e->x() * image.width() / width();
383 int ny = (e->y()-menubar->heightForWidth( width() )) * image.height() / h;
384 if (nx != x || ny != y ) {
385 x = nx;
386 y = ny;
387 updateStatus();
388 }
389 }
390}
391
392void ImageViewer::mousePressEvent( QMouseEvent *e )
393{
394 convertEvent(e, clickx, clicky);
395}
396
397void ImageViewer::mouseMoveEvent( QMouseEvent *e )
398{
399 convertEvent( e, pickx, picky );
400}
401 619
402void ImageViewer::hFlip() 620void ImageViewer::hFlip()
403{ 621{
404 if ( loadSelected() )
405 setImage(image.mirror(TRUE,FALSE)); 622 setImage(image.mirror(TRUE,FALSE));
406} 623}
407 624
408void ImageViewer::vFlip() 625void ImageViewer::vFlip()
409{ 626{
410 if ( loadSelected() )
411 setImage(image.mirror(FALSE,TRUE)); 627 setImage(image.mirror(FALSE,TRUE));
412} 628}
413 629
414void ImageViewer::rot180() 630void ImageViewer::rot180()
415{ 631{
416 if ( loadSelected() ) 632
417 setImage(image.mirror(TRUE,TRUE)); 633 setImage(image.mirror(TRUE,TRUE));
418} 634}
419 635
420void ImageViewer::rot90() 636void ImageViewer::rot90()
421{ 637{
422 if ( loadSelected() ) { 638 QImage oldimage;
423 QImage oldimage, newimage; 639 oldimage = image.convertDepth(32);
424 uchar *oldbits, *newbits; 640 setImage(rotate(oldimage,Rotate90));
425 int i, j, p; 641
426 int w, h; 642}
643void ImageViewer::rot270()
644{
427 645
646 QImage oldimage;
428 oldimage = image.convertDepth(32); 647 oldimage = image.convertDepth(32);
429 w = oldimage.height(); 648 setImage(rotate(oldimage,Rotate270));
430 h = oldimage.width();
431 newimage = QImage( w, h, 32);
432 649
433 oldbits = oldimage.bits(); 650}
434 newbits = newimage.bits(); 651
652void ImageViewer::blackAndWhite()
653{
654
655 viewMenuView->setItemEnabled(BLACKANDWHITE,false);
656 setImage(toGray(image,false));
435 657
436 for (i=0; i < w ; i++)
437 for (j=0; j < h; j++)
438 for (p = 0 ; p < 4 ; p++)
439 newbits[(j * w + i) * 4 + p] = oldbits[ ((i + 1) * h - j ) * 4 + p];
440 658
441 setImage(newimage);
442 } 659 }
660
661void ImageViewer::displayControlsDialog()
662{
663 int w=80;
664 int h=w;
665 QImage small;
666
667 if ( image.width()<w ||image.height()<h )
668 small=image.smoothScale(w,h);
669 else
670 small=image.copy(0,0,w,h);
671
672 int newB=0;
673 ControlsDialog *dlg=new ControlsDialog("Image Viewer",small,&newB,this);
674 dlg->exec();
675 if ( newB )
676 {
677 intensity(image,(float)newB/100);
678 setImage(image);
443} 679}
444 680
681}
682
683
684void ImageViewer::displayInfoDialog()
685{
686
687 QStringList ls;
445 688
689 for ( int i=0;i<LAST;i++ )
690 ls.append(imageInfo[i]);
446 691
692 InfoDialog::displayInfo("Image Viewer",ls,this);
693}
447void ImageViewer::normalView() 694void ImageViewer::normalView()
448{ 695{
449 if ( !imagePanel->parentWidget() ) { 696 if ( !imagePanel->parentWidget() )
697 {
698
450 isFullScreen = FALSE; 699 isFullScreen = FALSE;
451 stack->addWidget( imagePanel, 1 ); 700 stack->addWidget( imagePanel, 1 );
452 //imagePanel->reparent(stack,0,QPoint(0,0),FALSE); 701 switchToImageView();
453 //imagePanel->resize(width(), calcHeight()); 702 if ( isSized )
454 scale(); 703 scale();
455 updateStatus(); 704
456 imagePanel->setPixmap( pmScaled ); 705 updateImage();
457 imagePanel->showStatus(); 706
458 //imagePanel->show();
459 stack->raiseWidget( imagePanel );
460 } 707 }
461} 708}
462 709
463void ImageViewer::fullScreen() 710void ImageViewer::fullScreen()
464{ 711{
465 // Full-screen and rotation options 712 // Full-screen option
466 // contributed by Robert Wittams <robert@wittams.com> 713 // contributed by Robert Wittams <robert@wittams.com>
467 714 if ( imagePanel->parentWidget() && loadSelected() )
468 if ( imagePanel->parentWidget() && loadSelected() ) { 715 {
469 isFullScreen = TRUE; 716 isFullScreen = TRUE;
470 imagePanel->reparent(0,QPoint(0,0)); 717 imagePanel->reparent(0,QPoint(0,0));
471 imagePanel->resize(qApp->desktop()->width(), qApp->desktop()->height()); 718 imagePanel->resize(qApp->desktop()->width(), qApp->desktop()->height());
472 719
720 if ( isSized )
473 scale(); 721 scale();
474 updateStatus(); 722 updateImage();
475 imagePanel->hideStatus();
476 imagePanel->setPixmap( pmScaled );
477 imagePanel->showFullScreen(); 723 imagePanel->showFullScreen();
478 } 724 }
479} 725}
@@ -481,46 +727,37 @@ void ImageViewer::fullScreen()
481void ImageViewer::setImage(const QImage& newimage) 727void ImageViewer::setImage(const QImage& newimage)
482{ 728{
483 image = newimage; 729 image = newimage;
484 pickx = -1;
485 clickx = -1;
486 reconvertImage(); 730 reconvertImage();
487 imagePanel->setPixmap( pmScaled ); 731 updateImage();
488 updateStatus();
489} 732}
490 733
491void ImageViewer::updateStatus() 734void ImageViewer::updateImageInfo(QString &filePath)
492{ 735{
493 if ( pm.size() == QSize( 0, 0 ) ) { 736
494 if ( filename ) 737 for ( int i=0;i<LAST;i++ )
495 imagePanel->statusLabel()->setText( tr("Could not load image") ); 738 {
496 else 739 imageInfo[i]="";
497 imagePanel->statusLabel()->setText( tr("No image - select Open from File menu.") ); 740 }
498 } else { 741
742 imageInfo[FORMAT]=QImage::imageFormat (filePath );
743 QFileInfo fi(filePath);
744 imageInfo[PATH]=fi.fileName();
745 imageInfo[FILE_SIZE]=QString::number(fi.size())+" (bytes)";
499 QString message("%1x%2"); 746 QString message("%1x%2");
500 message = message.arg(image.width()).arg(image.height()); 747 imageInfo[SIZE]=QString("%1x%2");
501 if ( pm.size() != pmScaled.size() ) 748 imageInfo[SIZE]=imageInfo[SIZE].arg(image.width()).arg(image.height());
502 message += QString(" [%1x%2]").arg(pmScaled.width()).arg(pmScaled.height()); 749 if ( image.numColors() > 0 )
503 if (image.valid(pickx,picky)) { 750 {
504 QString moremsg; 751 imageInfo[COLORS]=tr("%1 colors").arg(image.numColors());
505 moremsg.sprintf("(%d,%d)=#%0*x ", 752 }
506 pickx, picky, 753 else if ( image.depth() >= 16 )
507 image.hasAlphaBuffer() ? 8 : 6, 754 {
508 image.pixel(pickx,picky)); 755 imageInfo[COLORS]=tr(" True color");
509 message += moremsg; 756 }
510 } 757 if ( image.hasAlphaBuffer() )
511 if ( image.numColors() > 0 ) { 758 {
512 if (image.valid(pickx,picky)) { 759 if ( image.depth() == 8 )
513 message += tr(", %1/%2 colors") 760 {
514 .arg(image.pixelIndex(pickx,picky))
515 .arg(image.numColors());
516 } else {
517 message += tr(", %1 colors").arg(image.numColors());
518 }
519 } else if ( image.depth() >= 16 ) {
520 message += tr(" True color");
521 }
522 if ( image.hasAlphaBuffer() ) {
523 if ( image.depth() == 8 ) {
524 int i; 761 int i;
525 bool alpha[256]; 762 bool alpha[256];
526 int nalpha=0; 763 int nalpha=0;
@@ -528,30 +765,280 @@ void ImageViewer::updateStatus()
528 for (i=0; i<256; i++) 765 for (i=0; i<256; i++)
529 alpha[i] = FALSE; 766 alpha[i] = FALSE;
530 767
531 for (i=0; i<image.numColors(); i++) { 768 for ( i=0; i<image.numColors(); i++ )
769 {
532 int alevel = image.color(i) >> 24; 770 int alevel = image.color(i) >> 24;
533 if (!alpha[alevel]) { 771 if ( !alpha[alevel] )
772 {
534 alpha[alevel] = TRUE; 773 alpha[alevel] = TRUE;
535 nalpha++; 774 nalpha++;
536 } 775 }
537 } 776 }
538 message += tr(", %1 alpha levels").arg(nalpha); 777 imageInfo[ALPHA]=tr("%1 alpha levels").arg(nalpha);
539 } else {
540 // Too many pixels to bother counting.
541 message += tr(", 8-bit alpha channel");
542 } 778 }
779 else
780 {
781 imageInfo[ALPHA]=tr("8-bit alpha channel");
543 } 782 }
544 imagePanel->statusLabel()->setText(message);
545 } 783 }
784
546} 785}
547 786
548void ImageViewer::closeEvent( QCloseEvent *e ) 787void ImageViewer::closeEvent( QCloseEvent *e )
549{ 788{
550 if ( stack->visibleWidget() == imagePanel && !bFromDocView ) { 789 if ( stack->visibleWidget() == imagePanel && !bFromDocView )
790 {
551 e->ignore(); 791 e->ignore();
552 open(); 792 open();
553 } else { 793 }
794 else
795 {
554 bFromDocView = FALSE; 796 bFromDocView = FALSE;
555 e->accept(); 797 e->accept();
556 } 798 }
557} 799}
800
801// Intensity,toGray and rotate code courtesy of KDE project.
802
803
804QImage& ImageViewer::intensity(QImage &image, float percent)
805{
806
807 int segColors = image.depth() > 8 ? 256 : image.numColors();
808 unsigned char *segTbl = new unsigned char[segColors];
809 int pixels = image.depth() > 8 ? image.width()*image.height() :
810 image.numColors();
811 unsigned int *data = image.depth() > 8 ? (unsigned int *)image.bits() :
812 (unsigned int *)image.colorTable();
813
814 bool brighten = (percent >= 0);
815 if ( percent < 0 )
816 percent = -percent;
817
818 if ( brighten )
819 { // keep overflow check out of loops
820 for ( int i=0; i < segColors; ++i )
821 {
822 int tmp = (int)(i*percent);
823 if ( tmp > 255 )
824 tmp = 255;
825 segTbl[i] = tmp;
826 }
827 }
828 else
829 {
830 for ( int i=0; i < segColors; ++i )
831 {
832 int tmp = (int)(i*percent);
833 if ( tmp < 0 )
834 tmp = 0;
835 segTbl[i] = tmp;
836 }
837 }
838
839 if ( brighten )
840 { // same here
841 for ( int i=0; i < pixels; ++i )
842 {
843 int r = qRed(data[i]);
844 int g = qGreen(data[i]);
845 int b = qBlue(data[i]);
846 int a = qAlpha(data[i]);
847 r = r + segTbl[r] > 255 ? 255 : r + segTbl[r];
848 g = g + segTbl[g] > 255 ? 255 : g + segTbl[g];
849 b = b + segTbl[b] > 255 ? 255 : b + segTbl[b];
850 data[i] = qRgba(r, g, b,a);
851 }
852 }
853 else
854 {
855 for ( int i=0; i < pixels; ++i )
856 {
857 int r = qRed(data[i]);
858 int g = qGreen(data[i]);
859 int b = qBlue(data[i]);
860 int a = qAlpha(data[i]);
861 r = r - segTbl[r] < 0 ? 0 : r - segTbl[r];
862 g = g - segTbl[g] < 0 ? 0 : g - segTbl[g];
863 b = b - segTbl[b] < 0 ? 0 : b - segTbl[b];
864 data[i] = qRgba(r, g, b, a);
865 }
866 }
867 delete [] segTbl;
868
869 return image;
870}
871
872QImage& ImageViewer::toGray(QImage &img, bool fast)
873{
874 if ( img.width() == 0 || img.height() == 0 )
875 return img;
876
877 if ( fast )
878 {
879 if ( img.depth() == 32 )
880 {
881 register uchar * r(img.bits());
882 register uchar * g(img.bits() + 1);
883 register uchar * b(img.bits() + 2);
884
885 uchar * end(img.bits() + img.numBytes());
886
887 while ( r != end )
888 {
889
890 *r = *g = *b = (((*r + *g) >> 1) + *b) >> 1; // (r + b + g) / 3
891
892 r += 4;
893 g += 4;
894 b += 4;
895 }
896 }
897 else
898 {
899 for ( int i = 0; i < img.numColors(); i++ )
900 {
901 register uint r = qRed(img.color(i));
902 register uint g = qGreen(img.color(i));
903 register uint b = qBlue(img.color(i));
904
905 register uint gray = (((r + g) >> 1) + b) >> 1;
906 img.setColor(i, qRgba(gray, gray, gray, qAlpha(img.color(i))));
907 }
908 }
909 }
910 else
911 {
912 int pixels = img.depth() > 8 ? img.width()*img.height() :
913 img.numColors();
914 unsigned int *data = img.depth() > 8 ? (unsigned int *)img.bits() :
915 (unsigned int *)img.colorTable();
916 int val, i;
917 for ( i=0; i < pixels; ++i )
918 {
919 val = qGray(data[i]);
920 data[i] = qRgba(val, val, val, qAlpha(data[i]));
921 }
922 }
923 return img;
924}
925
926
927QImage ImageViewer::rotate(QImage &img, RotateDirection r)
928{
929 QImage dest;
930 int x, y;
931 if ( img.depth() > 8 )
932 {
933 unsigned int *srcData, *destData;
934 switch ( r )
935 {
936 case Rotate90:
937 dest.create(img.height(), img.width(), img.depth());
938 for ( y=0; y < img.height(); ++y )
939 {
940 srcData = (unsigned int *)img.scanLine(y);
941 for ( x=0; x < img.width(); ++x )
942 {
943 destData = (unsigned int *)dest.scanLine(x);
944 destData[img.height()-y-1] = srcData[x];
945 }
946 }
947 break;
948 case Rotate180:
949 dest.create(img.width(), img.height(), img.depth());
950 for ( y=0; y < img.height(); ++y )
951 {
952 srcData = (unsigned int *)img.scanLine(y);
953 destData = (unsigned int *)dest.scanLine(img.height()-y-1);
954 for ( x=0; x < img.width(); ++x )
955 destData[img.width()-x-1] = srcData[x];
956 }
957 break;
958 case Rotate270:
959 dest.create(img.height(), img.width(), img.depth());
960 for ( y=0; y < img.height(); ++y )
961 {
962 srcData = (unsigned int *)img.scanLine(y);
963 for ( x=0; x < img.width(); ++x )
964 {
965 destData = (unsigned int *)dest.scanLine(img.width()-x-1);
966 destData[y] = srcData[x];
967 }
968 }
969 break;
970 default:
971 dest = img;
972 break;
973 }
974 }
975 else
976 {
977 unsigned char *srcData, *destData;
978 unsigned int *srcTable, *destTable;
979 switch ( r )
980 {
981 case Rotate90:
982 dest.create(img.height(), img.width(), img.depth());
983 dest.setNumColors(img.numColors());
984 srcTable = (unsigned int *)img.colorTable();
985 destTable = (unsigned int *)dest.colorTable();
986 for ( x=0; x < img.numColors(); ++x )
987 destTable[x] = srcTable[x];
988 for ( y=0; y < img.height(); ++y )
989 {
990 srcData = (unsigned char *)img.scanLine(y);
991 for ( x=0; x < img.width(); ++x )
992 {
993 destData = (unsigned char *)dest.scanLine(x);
994 destData[img.height()-y-1] = srcData[x];
995 }
996 }
997 break;
998 case Rotate180:
999 dest.create(img.width(), img.height(), img.depth());
1000 dest.setNumColors(img.numColors());
1001 srcTable = (unsigned int *)img.colorTable();
1002 destTable = (unsigned int *)dest.colorTable();
1003 for ( x=0; x < img.numColors(); ++x )
1004 destTable[x] = srcTable[x];
1005 for ( y=0; y < img.height(); ++y )
1006 {
1007 srcData = (unsigned char *)img.scanLine(y);
1008 destData = (unsigned char *)dest.scanLine(img.height()-y-1);
1009 for ( x=0; x < img.width(); ++x )
1010 destData[img.width()-x-1] = srcData[x];
1011 }
1012 break;
1013 case Rotate270:
1014 dest.create(img.height(), img.width(), img.depth());
1015 dest.setNumColors(img.numColors());
1016 srcTable = (unsigned int *)img.colorTable();
1017 destTable = (unsigned int *)dest.colorTable();
1018 for ( x=0; x < img.numColors(); ++x )
1019 destTable[x] = srcTable[x];
1020 for ( y=0; y < img.height(); ++y )
1021 {
1022 srcData = (unsigned char *)img.scanLine(y);
1023 for ( x=0; x < img.width(); ++x )
1024 {
1025 destData = (unsigned char *)dest.scanLine(img.width()-x-1);
1026 destData[y] = srcData[x];
1027 }
1028 }
1029 break;
1030 default:
1031 dest = img;
1032 break;
1033 }
1034
1035 }
1036 return (dest);
1037
1038
1039}
1040
1041
1042
1043
1044