00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "showimg.h"
00026 #include "ImageFileSelector.h"
00027 #include "settingsdialog.h"
00028
00029
00030 #include <opie2/odebug.h>
00031 #include <opie2/ofiledialog.h>
00032 #include <qpe/qpeapplication.h>
00033 #include <qpe/config.h>
00034 #include <qpe/resource.h>
00035 using namespace Opie::Core;
00036 using namespace Opie::Ui;
00037
00038
00039 #include <qtoolbar.h>
00040 #include <qaction.h>
00041 #include <qfiledialog.h>
00042 #include <qmenubar.h>
00043 #include <qspinbox.h>
00044
00045
00046 #include <math.h>
00047
00048 ControlsDialog::ControlsDialog(const QString &caption,QImage image,int *brightness,QWidget *parent)
00049 : QDialog(parent,0,true)
00050 {
00051 setCaption(caption);
00052
00053 if ( parent ) {
00054 setPalette(parent->palette());
00055 }
00056
00057 b=brightness;
00058 img=image;
00059
00060 setMinimumSize(140,80);
00061
00062 QGridLayout *gl= new QGridLayout(this,2,2,4,4);
00063
00064 pixmap =new ImageWidget(this);;
00065 QPixmap pm;
00066 pm.convertFromImage(img);
00067 pixmap->setPixmap(pm);
00068 pixmap->setMinimumSize(pm.width(),pm.height());
00069 gl->addMultiCellWidget(pixmap,0,0,0,2,AlignCenter);
00070 QLabel *l=new QLabel(tr("Brightness")+":",this);
00071 gl->addWidget(l,1,0,AlignLeft);
00072 spb=new QSpinBox(-100,100,2,this);
00073 gl->addWidget(spb,1,1,AlignRight);
00074
00075 spb->setValue(0);
00076
00077 connect(spb,SIGNAL(valueChanged(int)),this, SLOT(bValueChanged(int)));
00078
00079 }
00080
00081 void ControlsDialog::bValueChanged(int value)
00082 {
00083 QImage nImage=img;
00084 nImage.detach();
00085 ImageViewer::intensity(nImage, (float)value/100);
00086 QPixmap pm;
00087 pm.convertFromImage(nImage);
00088 pixmap->setPixmap(pm);
00089 pixmap->repaint(false);
00090
00091
00092 }
00093
00094 void ControlsDialog::accept()
00095 {
00096 *b=spb->value();
00097 done(1);
00098 }
00099
00100
00101
00102 InfoDialog::InfoDialog(const QString &caption, const QStringList text,QWidget *parent)
00103 : QDialog(parent,0,true)
00104 {
00105 setCaption(caption);
00106
00107 if ( parent )
00108 {
00109 setPalette(parent->palette());
00110 }
00111
00112
00113
00114 QString labels[]={ tr("File Name"),tr("Format"),tr("File Size"),tr("Size"),tr("Colors"),tr("Alpha") };
00115
00116 setMinimumSize(180,80);
00117 int num=ImageViewer::LAST+1;
00118 if ( text[ImageViewer::ALPHA].isEmpty() )
00119 num--;
00120 QGridLayout *gl= new QGridLayout(this,num,2,4,2);
00121 QLabel *l;
00122 int count=0;
00123 for ( int i=0;i<num;i++ )
00124 {
00125 if ( i==1 )
00126 {
00127 QFrame *frm=new QFrame(this);
00128 frm->setFrameStyle(QFrame::HLine|QFrame::Sunken);
00129 gl->addMultiCellWidget(frm,i,i,0,1);
00130 }
00131 else
00132 {
00133 l=new QLabel( tr( labels[count] )+":",this);
00134 gl->addWidget(l,i,0,AlignLeft);
00135 l=new QLabel(text[count],this);
00136 gl->addWidget(l,i,1,AlignRight);
00137 count++;
00138 }
00139
00140 }
00141
00142 }
00143
00144 void InfoDialog::displayInfo(const QString &caption, const QStringList text, QWidget *parent)
00145 {
00146 InfoDialog *dlg=new InfoDialog(caption,text,parent);
00147 dlg->exec();
00148 delete dlg;
00149 }
00150
00151
00152
00153
00154 ImagePane::ImagePane( QWidget *parent ) : QWidget( parent )
00155 {
00156 vb = new QVBoxLayout( this );
00157
00158 image = new QScrollView(this,0,WResizeNoErase|WNorthWestGravity);
00159 pic=new ImageWidget(image);
00160 image->addChild(pic);
00161
00162 connect(pic, SIGNAL( clicked() ), this, SLOT( imageClicked() ));
00163
00164 vb->addWidget( image );
00165
00166 }
00167
00168 void ImagePane::setPixmap( const QPixmap &pm )
00169 {
00170 pic->setPixmap( pm );
00171 pic->resize(pm.width(),pm.height());
00172 image->updateScrollBars ();
00173 pic->repaint(false);
00174 }
00175
00176 void ImagePane::imageClicked()
00177 {
00178 emit clicked();
00179 }
00180
00181
00182
00183
00184
00185 void ImageWidget::paintEvent( QPaintEvent *e )
00186 {
00187 QPainter painter(this);
00188
00189 painter.setClipRect(e->rect());
00190 painter.fillRect(0,0,width(),height(),QColor(0,0,0));
00191
00192 if ( pixmap.size() != QSize( 0, 0 ) )
00193 {
00194 painter.drawPixmap((width() - pixmap.width()) / 2, (height() - pixmap.height()) / 2, pixmap);
00195 }
00196 }
00197
00198 void ImageWidget::mouseReleaseEvent(QMouseEvent *)
00199 {
00200 emit clicked();
00201 }
00202
00203
00204
00205 ImageViewer::ImageViewer( QWidget *parent, const char *name, int )
00206 : QMainWindow( parent, name, WResizeNoErase ), filename( 0 ), bFromDocView( FALSE )
00207 {
00208 setCaption( tr("Image Viewer") );
00209 setIcon( Resource::loadPixmap( "ImageViewer" ) );
00210
00211
00212 Config cfg("Image Viewer");
00213 cfg.setGroup("Image Viewer");
00214
00215 showThumbView=cfg.readBoolEntry("ShowThumbnails",false);
00216 isSized=cfg.readBoolEntry("SizeToScreen",true);
00217
00218 isFullScreen = FALSE;
00219
00220 setToolBarsMovable( FALSE );
00221
00222 toolBar = new QToolBar( this );
00223 toolBar->setHorizontalStretchable( TRUE );
00224
00225 menuBar = new QMenuBar( toolBar );
00226
00227 current=menuBar;
00228
00229
00230
00231 fileMenuFile = new QPopupMenu(this);
00232
00233 fileMenuFile->insertItem(tr("Open"),
00234 this, SLOT(openFile()), 0);
00235
00236 viewMenuFile = new QPopupMenu( this );
00237
00238 viewMenuFile->insertItem( tr("Thumbnail View"),
00239 this, SLOT(switchThumbView()), 0, SHOW_THUMBNAILS );
00240
00241 viewMenuFile->setItemChecked ( SHOW_THUMBNAILS, showThumbView );
00242
00243
00244
00245
00246 optionsMenuFile = new QPopupMenu( this);
00247
00248 slideAction = new QAction( tr( "Slide show" ), Resource::loadIconSet( "slideshow" ),
00249 QString::null, 0, this, 0 );
00250 slideAction->setToggleAction( TRUE );
00251 connect( slideAction, SIGNAL( toggled(bool) ), this, SLOT( slideShow(bool) ) );
00252 slideAction->addTo( optionsMenuFile);
00253
00254
00255
00256
00257 optionsMenuFile->insertSeparator();
00258 optionsMenuFile->insertItem( tr("Preferences.."), this, SLOT(settings()), 0);
00259
00260
00261 QStrList fmt = QImage::outputFormats();
00262
00263
00264 fileMenuView = new QPopupMenu( this );
00265
00266 fileMenuView->insertItem( tr("Image Info ..."),this, SLOT(displayInfoDialog()),0 );
00267 fileMenuView->insertSeparator();
00268
00269 viewMenuView = new QPopupMenu(this );
00270 viewMenuView->setCheckable ( true );
00271
00272
00273 viewMenuView->insertItem(tr("Horizontal flip"), this, SLOT(hFlip()), 0);
00274 viewMenuView->insertItem(tr("Vertical flip"), this, SLOT(vFlip()), 0);
00275
00276 stack = new QWidgetStack( this );
00277 stack->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
00278 setCentralWidget( stack );
00279
00280
00281 imagePanel = new ImagePane( stack );
00282 connect(imagePanel, SIGNAL(clicked()), this, SLOT(normalView()));
00283
00284
00285 ImageFileSelector::CURRENT_VIEW cv;
00286 if(showThumbView)
00287 cv=ImageFileSelector::THUMBNAIL;
00288 else
00289 cv=ImageFileSelector::DETAILED;
00290
00291 odebug << "cv = " << cv << "" << oendl;
00292
00293 fileSelector = new ImageFileSelector( cv,stack, "fs");
00294
00295
00296
00297
00298
00299
00300
00301 connect( fileSelector, SIGNAL( closeMe() ), this, SLOT( closeFileSelector() ) );
00302 connect( fileSelector, SIGNAL( fileSelected(const DocLnk&) ),
00303 this, SLOT( openFile(const DocLnk&) ) );
00304
00305 imageList = fileSelector->fileList();
00306 slideAction->setEnabled( imageList.count() != 0);
00307
00308 iconToolBar = new QToolBar(this);
00309
00310 QAction *a;
00311
00312 a = new QAction( tr( "Open ..." ), Resource::loadPixmap( "fileopen" ), QString::null, 0, this, 0 );
00313 connect( a, SIGNAL( activated() ), this, SLOT( open() ) );
00314 a->addTo( fileMenuView);
00315 a->addTo( iconToolBar );
00316
00317
00318 a = new QAction( tr( "Rotate 90"), Resource::loadPixmap( "rotate90" ), QString::null, 0, this, 0);
00319 connect( a, SIGNAL( activated() ), this, SLOT( rot90() ) );
00320 a->addTo( iconToolBar );
00321 a->addTo( viewMenuView );
00322
00323 a = new QAction( tr( "Rotate 180" ), Resource::loadPixmap( "repeat" ), QString::null, 0, this, 0 );
00324 connect( a, SIGNAL( activated() ), this, SLOT( rot180() ) );
00325 a->addTo( iconToolBar );
00326 a->addTo( viewMenuView );
00327
00328
00329 a = new QAction( tr( "Rotate 270"), Resource::loadPixmap( "rotate270" ), QString::null, 0, this, 0);
00330 connect( a, SIGNAL( activated() ), this, SLOT( rot270() ) );
00331
00332 a->addTo( viewMenuView );
00333
00334
00335
00336 viewMenuView->insertSeparator();
00337 viewMenuView->insertItem(tr("Brightness ..."), this, SLOT(displayControlsDialog()), 0);
00338 viewMenuView->insertItem(tr("Black And White"), this, SLOT(blackAndWhite()), 0,BLACKANDWHITE);
00339 viewMenuView->insertSeparator();
00340
00341
00342 sss = new QAction( tr( "Scale to Screen"), Resource::loadPixmap( "scale" ), QString::null, 0, this, 0,true);
00343 connect( sss, SIGNAL( activated() ), this, SLOT( switchSizeToScreen() ) );
00344 sss->addTo( iconToolBar );
00345 sss->addTo( viewMenuView );
00346
00347 sss->setOn(isSized);
00348 viewMenuView->insertSeparator();
00349
00350
00351 a = new QAction( tr( "Fullscreen" ), Resource::loadPixmap( "fullscreen" ),
00352 QString::null, 0, this, 0 );
00353 connect( a, SIGNAL( activated() ), this, SLOT( fullScreen() ) );
00354 a->addTo( iconToolBar );
00355 a->addTo( viewMenuView);
00356
00357 a = new QAction( tr( "Stop Slideshow" ), Resource::loadPixmap( "quit_icon" ),
00358 QString::null, 0, this, 0 );
00359 connect( a, SIGNAL( activated() ), this, SLOT( stopSlideShow() ) );
00360 a->addTo( iconToolBar );
00361 a->addTo( viewMenuView);
00362
00363
00364 Config config( "ImageViewer" );
00365 config.setGroup( "SlideShow" );
00366 slideDelay = config.readNumEntry( "Delay", 2);
00367 slideRepeat = config.readBoolEntry( "Repeat", FALSE );
00368 slideReverse = config.readBoolEntry("Reverse", FALSE);
00369
00370 config.setGroup("Default");
00371 rotateOnLoad = config.readBoolEntry("Rotate", FALSE);
00372 fastLoad = config.readBoolEntry("FastLoad", TRUE);
00373 slideTimer = new QTimer( this );
00374 connect( slideTimer, SIGNAL(timeout()), this, SLOT(slideUpdate()) );
00375
00376 switchToFileSelector();
00377
00378 setMouseTracking( TRUE );
00379
00380
00381 }
00382
00383 ImageViewer::~ImageViewer()
00384 {
00385 Config cfg("Image Viewer");
00386 cfg.setGroup("Image Viewer");
00387
00388 cfg.writeEntry("ShowThumbnails",(int)showThumbView);
00389 cfg.writeEntry("SizeToScreen",(int)isSized);
00390
00391 cfg.setGroup( "SlideShow" );
00392 cfg.writeEntry( "Delay", slideDelay);
00393 cfg.writeEntry( "Repeat", slideRepeat );
00394 cfg.writeEntry("Reverse", slideReverse);
00395
00396 cfg.setGroup("Default");
00397 cfg.writeEntry("Rotate", rotateOnLoad);
00398 cfg.writeEntry("FastLoad", fastLoad);
00399
00400 delete imagePanel;
00401 }
00402
00403 void ImageViewer::help() {
00404
00405 }
00406
00407
00408 void ImageViewer::settings()
00409 {
00410 SettingsDialog dlg( this, 0, TRUE );
00411 dlg.setDelay( slideDelay );
00412 dlg.setRepeat( slideRepeat );
00413 dlg.setReverse( slideReverse );
00414 dlg.setRotate(rotateOnLoad);
00415 dlg.setFastLoad(fastLoad);
00416
00417 if ( QPEApplication::execDialog(&dlg) == QDialog::Accepted ) {
00418 odebug << "<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>" << oendl;
00419 slideDelay = dlg.delay();
00420 slideRepeat = dlg.repeat();
00421 slideReverse = dlg.reverse();
00422 rotateOnLoad = dlg.rotate();
00423 fastLoad = dlg.fastLoad();
00424
00425 Config config( "ImageViewer" );
00426 config.setGroup( "SlideShow" );
00427 config.writeEntry( "Delay", slideDelay );
00428 config.writeEntry( "Repeat", slideRepeat );
00429 config.writeEntry("Reverse", slideReverse);
00430
00431 config.setGroup("Default");
00432 config.writeEntry("Rotate", rotateOnLoad);
00433 config.writeEntry("FastLoad", fastLoad);
00434 }
00435 }
00436
00437 void ImageViewer::switchSizeToScreen()
00438 {
00439 isSized=!isSized;
00440 sss->setOn(isSized);
00441 updateImage();
00442 }
00443
00444 void ImageViewer::updateImage()
00445 {
00446 if ( isSized ) {
00447 imagePanel->setPixmap(pmScaled);
00448 } else {
00449 imagePanel->setPixmap(pm);
00450 }
00451 }
00452
00453 void ImageViewer::switchThumbView()
00454 {
00455
00456 showThumbView=!showThumbView;
00457 viewMenuFile->setItemChecked ( SHOW_THUMBNAILS, showThumbView );
00458 fileSelector->switchView();
00459
00460 }
00461
00462 void ImageViewer::switchToFileSelector()
00463 {
00464 stack->raiseWidget(fileSelector);
00465 menuBar->clear();
00466 menuBar->insertItem( tr("File"), fileMenuFile );
00467 menuBar->insertItem( tr("View"), viewMenuFile );
00468 menuBar->insertItem( tr("Options"), optionsMenuFile );
00469 iconToolBar->hide();
00470 imagePanel->disable();
00471 slideShow(false);
00472
00473 }
00474
00475 void ImageViewer::switchToImageView()
00476 {
00477 stack->raiseWidget(imagePanel);
00478
00479 menuBar->clear();
00480 menuBar->insertItem( tr("File"), fileMenuView );
00481 menuBar->insertItem( tr("View"), viewMenuView );
00482 viewMenuView->setItemEnabled(BLACKANDWHITE,true);
00483 iconToolBar->show();
00484
00485 imagePanel->setPosition(0,0);
00486
00487 }
00488
00489
00490 void ImageViewer::setDocument(const QString& fileref)
00491 {
00492 delayLoad = fileref;
00493 switchToImageView();
00494 QTimer::singleShot( 0, this, SLOT(doDelayedLoad()) );
00495 }
00496
00497 void ImageViewer::doDelayedLoad()
00498 {
00499 show(delayLoad);
00500 }
00501
00502 void ImageViewer::show()
00503 {
00504 normalView();
00505 QMainWindow::show();
00506 }
00507
00508 void ImageViewer::show(const QString& fileref)
00509 {
00510
00511 bFromDocView = TRUE;
00512 closeFileSelector();
00513 DocLnk link(fileref);
00514 if ( link.isValid() ) {
00515 openFile(link);
00516 } else {
00517 filename = fileref;
00518 updateCaption( fileref );
00519 loadImage( fileref );
00520 }
00521 }
00522
00523 void ImageViewer::openFile() {
00524 MimeTypes types;
00525 QStringList image;
00526 image << "image/*";
00527 types.insert("Images", image);
00528
00529 QString str = OFileDialog::getOpenFileName( 1,QPEApplication::documentDir(),"", types, 0 );
00530 DocLnk link(str);
00531
00532 openFile(link);
00533
00534 }
00535
00536 void ImageViewer::openFile( const DocLnk &link )
00537 {
00538 closeFileSelector();
00539
00540 odebug << "open "+link.name() << oendl;
00541 updateCaption( link.name() );
00542 loadImage( link.file() );
00543 if (slideTimer->isActive()) {
00544 slideTimer->start(slideDelay * 1000, FALSE);
00545 }
00546
00547 }
00548
00549 void ImageViewer::open()
00550 {
00551 switchToFileSelector();
00552 }
00553
00554 void ImageViewer::closeFileSelector()
00555 {
00556 switchToImageView();
00557 }
00558
00559 void ImageViewer::updateCaption( QString name )
00560 {
00561 int sep = name.findRev( '/' );
00562 if ( sep >= 0 )
00563 name = name.mid( sep+1 );
00564 setCaption( name + tr(" - Image Viewer") );
00565 }
00566
00567
00568
00569
00570
00571 void ImageViewer::loadImage( const char *fileName )
00572 {
00573 filename = fileName;
00574 if ( filename ) {
00575 QApplication::setOverrideCursor( waitCursor );
00576
00577 qApp->processEvents();
00578 bool ok = image.load(filename, 0);
00579 if ( ok ) {
00580 ok = reconvertImage();
00581 updateImageInfo(filename);
00582 }
00583 if ( !ok ) {
00584 pm.resize(0,0);
00585 update();
00586 }
00587 QApplication::restoreOverrideCursor();
00588 }
00589
00590
00591
00592
00593
00594
00595 rotated90 = FALSE;
00596
00597 if (rotateOnLoad) {
00598 rotated90 = TRUE;
00599 rot90();
00600
00601 }
00602
00603 switchToImageView();
00604 updateImage();
00605
00606 }
00607
00608 bool ImageViewer::loadSelected()
00609 {
00610 bool ok = false;
00611 if ( stack->visibleWidget() == fileSelector )
00612 {
00613 const DocLnk *link = fileSelector->selected();
00614 if ( link )
00615 {
00616 if ( link->file() != filename )
00617 {
00618 updateCaption( link->name() );
00619 filename = link->file();
00620 qApp->processEvents();
00621 ok = image.load(filename, 0);
00622 if ( ok )
00623 {
00624 updateImageInfo(filename);
00625 ok = reconvertImage();
00626 }
00627 if ( !ok )
00628 pm.resize(0,0);
00629 }
00630 }
00631 }
00632 if ( !image.isNull() )
00633 {
00634 ok = true;
00635 closeFileSelector();
00636 }
00637
00638 return ok;
00639 }
00640
00641 bool ImageViewer::reconvertImage()
00642 {
00643 bool success = FALSE;
00644
00645 if ( image.isNull() ) return FALSE;
00646
00647 QApplication::setOverrideCursor( waitCursor );
00648 if ( pm.convertFromImage(image ) )
00649 {
00650 pmScaled = QPixmap();
00651 scale();
00652 success = TRUE;
00653 }
00654 else
00655 {
00656 pm.resize(0,0);
00657 }
00658 QApplication::restoreOverrideCursor();
00659
00660 return success;
00661 }
00662
00663
00664 int ImageViewer::calcHeight()
00665 {
00666 if ( !isFullScreen )
00667 return imagePanel->paneHeight();
00668 else
00669 return qApp->desktop()->height();
00670 }
00671
00672
00673
00674
00675 void ImageViewer::scale()
00676 {
00677 int h = calcHeight();
00678 if ( image.isNull() ) return;
00679
00680 QApplication::setOverrideCursor( waitCursor );
00681 if ( imagePanel->paneWidth() == pm.width() && h == pm.height() )
00682 {
00683 pmScaled = pm;
00684 }
00685 else
00686 {
00687 double hs = (double)h / (double)image.height();
00688 double ws = (double)imagePanel->paneWidth() / (double)image.width();
00689 double scaleFactor = (hs > ws) ? ws : hs;
00690 int smoothW = (int)(scaleFactor * image.width());
00691 int smoothH = (int)(scaleFactor * image.height());
00692
00693 pmScaled.convertFromImage( image.smoothScale( smoothW, smoothH ) );
00694 }
00695 QApplication::restoreOverrideCursor();
00696 }
00697
00698
00699
00700
00701
00702
00703 void ImageViewer::resizeEvent( QResizeEvent * )
00704 {
00705
00706 if ( pm.size() == QSize( 0, 0 ) )
00707 return;
00708
00709 int h = calcHeight();
00710
00711 if ( imagePanel->paneWidth() != pmScaled.width() || h != pmScaled.height() )
00712 {
00713 scale();
00714 }
00715 if ( image.hasAlphaBuffer() )
00716 erase();
00717 }
00718
00719
00720 void ImageViewer::hFlip()
00721 {
00722
00723
00724 setImage(image.mirror(TRUE,FALSE));
00725 }
00726
00727 void ImageViewer::vFlip()
00728 {
00729
00730 setImage(image.mirror(FALSE,TRUE));
00731 }
00732
00733 void ImageViewer::rot180()
00734 {
00735
00736 setImage(image.mirror(TRUE,TRUE));
00737 }
00738
00739 void ImageViewer::rot90()
00740 {
00741 QImage oldimage;
00742 oldimage = image.convertDepth(32);
00743
00744 setImage(rotate(oldimage,Rotate90));
00745
00746 }
00747 void ImageViewer::rot270()
00748 {
00749
00750 QImage oldimage;
00751 oldimage = image.convertDepth(32);
00752
00753 setImage(rotate(oldimage,Rotate270));
00754
00755 }
00756
00757 void ImageViewer::blackAndWhite()
00758 {
00759
00760 viewMenuView->setItemEnabled(BLACKANDWHITE,false);
00761 setImage(toGray(image,false));
00762 }
00763
00764 void ImageViewer::displayControlsDialog()
00765 {
00766 int w=80;
00767 int h=w;
00768 QImage small;
00769
00770 if ( image.width()<w ||image.height()<h )
00771 small=image.smoothScale(w,h);
00772 else
00773 small=image.copy(0,0,w,h);
00774
00775 int newB=0;
00776 ControlsDialog *dlg=new ControlsDialog("Image Viewer",small,&newB,this);
00777 dlg->exec();
00778 if ( newB ) {
00779 intensity(image,(float)newB/100);
00780 setImage(image);
00781 }
00782
00783 }
00784
00785
00786 void ImageViewer::displayInfoDialog()
00787 {
00788
00789 QStringList ls;
00790
00791 for ( int i=0;i<LAST;i++ )
00792 ls.append(imageInfo[i]);
00793
00794 InfoDialog::displayInfo("Image Viewer",ls,this);
00795 }
00796 void ImageViewer::normalView()
00797 {
00798 if ( !imagePanel->parentWidget() )
00799 {
00800
00801 isFullScreen = FALSE;
00802 stack->addWidget( imagePanel, 1 );
00803 switchToImageView();
00804 if ( isSized )
00805 scale();
00806
00807 updateImage();
00808
00809 }
00810 }
00811
00812 void ImageViewer::stopSlideShow() {
00813 if (slideTimer->isActive())
00814 slideTimer->stop();
00815 }
00816
00817 void ImageViewer::fullScreen()
00818 {
00819
00820
00821 if ( imagePanel->parentWidget() && loadSelected() )
00822 {
00823 isFullScreen = TRUE;
00824 imagePanel->reparent(0,QPoint(0,0));
00825 imagePanel->resize(qApp->desktop()->width(), qApp->desktop()->height());
00826
00827 if ( isSized )
00828 scale();
00829 updateImage();
00830 imagePanel->showFullScreen();
00831 }
00832 }
00833
00834 void ImageViewer::setImage(const QImage& newimage)
00835 {
00836 image = newimage;
00837 reconvertImage();
00838 updateImage();
00839 }
00840
00841 void ImageViewer::updateImageInfo(QString &filePath)
00842 {
00843
00844 for ( int i=0;i<LAST;i++ )
00845 {
00846 imageInfo[i]="";
00847 }
00848
00849 imageInfo[FORMAT]=QImage::imageFormat (filePath );
00850 QFileInfo fi(filePath);
00851 imageInfo[PATH]=fi.fileName();
00852 imageInfo[FILE_SIZE]=QString::number(fi.size())+" (bytes)";
00853 QString message("%1x%2");
00854 imageInfo[SIZE]=QString("%1x%2");
00855 imageInfo[SIZE]=imageInfo[SIZE].arg(image.width()).arg(image.height());
00856 if ( image.numColors() > 0 )
00857 {
00858 imageInfo[COLORS]=tr("%1 colors").arg(image.numColors());
00859 }
00860 else if ( image.depth() >= 16 )
00861 {
00862 imageInfo[COLORS]=tr(" True color");
00863 }
00864 if ( image.hasAlphaBuffer() )
00865 {
00866 if ( image.depth() == 8 )
00867 {
00868 int i;
00869 bool alpha[256];
00870 int nalpha=0;
00871
00872 for ( i=0; i<256; i++ )
00873 alpha[i] = FALSE;
00874
00875 for ( i=0; i<image.numColors(); i++ )
00876 {
00877 int alevel = image.color(i) >> 24;
00878 if ( !alpha[alevel] )
00879 {
00880 alpha[alevel] = TRUE;
00881 nalpha++;
00882 }
00883 }
00884 imageInfo[ALPHA]=tr("%1 alpha levels").arg(nalpha);
00885 }
00886 else
00887 {
00888 imageInfo[ALPHA]=tr("8-bit alpha channel");
00889 }
00890 }
00891
00892 }
00893
00894 void ImageViewer::closeEvent( QCloseEvent *e )
00895 {
00896 if ( stack->visibleWidget() == imagePanel && !bFromDocView )
00897 {
00898 e->ignore();
00899 open();
00900 }
00901 else
00902 {
00903 bFromDocView = FALSE;
00904 e->accept();
00905 }
00906 }
00907
00908
00909
00910
00911 QImage& ImageViewer::intensity(QImage &image, float percent)
00912 {
00913
00914 int segColors = image.depth() > 8 ? 256 : image.numColors();
00915 unsigned char *segTbl = new unsigned char[segColors];
00916 int pixels = image.depth() > 8 ? image.width()*image.height() :
00917 image.numColors();
00918 unsigned int *data = image.depth() > 8 ? (unsigned int *)image.bits() :
00919 (unsigned int *)image.colorTable();
00920
00921 bool brighten = (percent >= 0);
00922 if ( percent < 0 )
00923 percent = -percent;
00924
00925 if ( brighten )
00926 {
00927 for ( int i=0; i < segColors; ++i )
00928 {
00929 int tmp = (int)(i*percent);
00930 if ( tmp > 255 )
00931 tmp = 255;
00932 segTbl[i] = tmp;
00933 }
00934 }
00935 else
00936 {
00937 for ( int i=0; i < segColors; ++i )
00938 {
00939 int tmp = (int)(i*percent);
00940 if ( tmp < 0 )
00941 tmp = 0;
00942 segTbl[i] = tmp;
00943 }
00944 }
00945
00946 if ( brighten )
00947 {
00948 for ( int i=0; i < pixels; ++i )
00949 {
00950 int r = qRed(data[i]);
00951 int g = qGreen(data[i]);
00952 int b = qBlue(data[i]);
00953 int a = qAlpha(data[i]);
00954 r = r + segTbl[r] > 255 ? 255 : r + segTbl[r];
00955 g = g + segTbl[g] > 255 ? 255 : g + segTbl[g];
00956 b = b + segTbl[b] > 255 ? 255 : b + segTbl[b];
00957 data[i] = qRgba(r, g, b,a);
00958 }
00959 }
00960 else
00961 {
00962 for ( int i=0; i < pixels; ++i )
00963 {
00964 int r = qRed(data[i]);
00965 int g = qGreen(data[i]);
00966 int b = qBlue(data[i]);
00967 int a = qAlpha(data[i]);
00968 r = r - segTbl[r] < 0 ? 0 : r - segTbl[r];
00969 g = g - segTbl[g] < 0 ? 0 : g - segTbl[g];
00970 b = b - segTbl[b] < 0 ? 0 : b - segTbl[b];
00971 data[i] = qRgba(r, g, b, a);
00972 }
00973 }
00974 delete [] segTbl;
00975
00976 return image;
00977 }
00978
00979 QImage& ImageViewer::toGray(QImage &img, bool fast)
00980 {
00981 if ( img.width() == 0 || img.height() == 0 )
00982 return img;
00983
00984 if ( fast )
00985 {
00986 if ( img.depth() == 32 )
00987 {
00988 register uchar * r(img.bits());
00989 register uchar * g(img.bits() + 1);
00990 register uchar * b(img.bits() + 2);
00991
00992 uchar * end(img.bits() + img.numBytes());
00993
00994 while ( r != end )
00995 {
00996
00997 *r = *g = *b = (((*r + *g) >> 1) + *b) >> 1;
00998
00999 r += 4;
01000 g += 4;
01001 b += 4;
01002 }
01003 }
01004 else
01005 {
01006 for ( int i = 0; i < img.numColors(); i++ )
01007 {
01008 register uint r = qRed(img.color(i));
01009 register uint g = qGreen(img.color(i));
01010 register uint b = qBlue(img.color(i));
01011
01012 register uint gray = (((r + g) >> 1) + b) >> 1;
01013 img.setColor(i, qRgba(gray, gray, gray, qAlpha(img.color(i))));
01014 }
01015 }
01016 }
01017 else
01018 {
01019 int pixels = img.depth() > 8 ? img.width()*img.height() :
01020 img.numColors();
01021 unsigned int *data = img.depth() > 8 ? (unsigned int *)img.bits() :
01022 (unsigned int *)img.colorTable();
01023 int val, i;
01024 for ( i=0; i < pixels; ++i )
01025 {
01026 val = qGray(data[i]);
01027 data[i] = qRgba(val, val, val, qAlpha(data[i]));
01028 }
01029 }
01030 return img;
01031 }
01032
01033
01034 QImage ImageViewer::rotate(QImage &img, RotateDirection r)
01035 {
01036 QImage dest;
01037 int x, y;
01038 if ( img.depth() > 8 )
01039 {
01040 unsigned int *srcData, *destData;
01041 switch ( r )
01042 {
01043 case Rotate90:
01044 dest.create(img.height(), img.width(), img.depth());
01045 for ( y=0; y < img.height(); ++y )
01046 {
01047 srcData = (unsigned int *)img.scanLine(y);
01048 for ( x=0; x < img.width(); ++x )
01049 {
01050 destData = (unsigned int *)dest.scanLine(x);
01051 destData[img.height()-y-1] = srcData[x];
01052 }
01053 }
01054 break;
01055 case Rotate180:
01056 dest.create(img.width(), img.height(), img.depth());
01057 for ( y=0; y < img.height(); ++y )
01058 {
01059 srcData = (unsigned int *)img.scanLine(y);
01060 destData = (unsigned int *)dest.scanLine(img.height()-y-1);
01061 for ( x=0; x < img.width(); ++x )
01062 destData[img.width()-x-1] = srcData[x];
01063 }
01064 break;
01065 case Rotate270:
01066 dest.create(img.height(), img.width(), img.depth());
01067 for ( y=0; y < img.height(); ++y )
01068 {
01069 srcData = (unsigned int *)img.scanLine(y);
01070 for ( x=0; x < img.width(); ++x )
01071 {
01072 destData = (unsigned int *)dest.scanLine(img.width()-x-1);
01073 destData[y] = srcData[x];
01074 }
01075 }
01076 break;
01077 default:
01078 dest = img;
01079 break;
01080 }
01081 }
01082 else
01083 {
01084 unsigned char *srcData, *destData;
01085 unsigned int *srcTable, *destTable;
01086 switch ( r )
01087 {
01088 case Rotate90:
01089 dest.create(img.height(), img.width(), img.depth());
01090 dest.setNumColors(img.numColors());
01091 srcTable = (unsigned int *)img.colorTable();
01092 destTable = (unsigned int *)dest.colorTable();
01093 for ( x=0; x < img.numColors(); ++x )
01094 destTable[x] = srcTable[x];
01095 for ( y=0; y < img.height(); ++y )
01096 {
01097 srcData = (unsigned char *)img.scanLine(y);
01098 for ( x=0; x < img.width(); ++x )
01099 {
01100 destData = (unsigned char *)dest.scanLine(x);
01101 destData[img.height()-y-1] = srcData[x];
01102 }
01103 }
01104 break;
01105 case Rotate180:
01106 dest.create(img.width(), img.height(), img.depth());
01107 dest.setNumColors(img.numColors());
01108 srcTable = (unsigned int *)img.colorTable();
01109 destTable = (unsigned int *)dest.colorTable();
01110 for ( x=0; x < img.numColors(); ++x )
01111 destTable[x] = srcTable[x];
01112 for ( y=0; y < img.height(); ++y )
01113 {
01114 srcData = (unsigned char *)img.scanLine(y);
01115 destData = (unsigned char *)dest.scanLine(img.height()-y-1);
01116 for ( x=0; x < img.width(); ++x )
01117 destData[img.width()-x-1] = srcData[x];
01118 }
01119 break;
01120 case Rotate270:
01121 dest.create(img.height(), img.width(), img.depth());
01122 dest.setNumColors(img.numColors());
01123 srcTable = (unsigned int *)img.colorTable();
01124 destTable = (unsigned int *)dest.colorTable();
01125 for ( x=0; x < img.numColors(); ++x )
01126 destTable[x] = srcTable[x];
01127 for ( y=0; y < img.height(); ++y )
01128 {
01129 srcData = (unsigned char *)img.scanLine(y);
01130 for ( x=0; x < img.width(); ++x )
01131 {
01132 destData = (unsigned char *)dest.scanLine(img.width()-x-1);
01133 destData[y] = srcData[x];
01134 }
01135 }
01136 break;
01137 default:
01138 dest = img;
01139 break;
01140 }
01141
01142 }
01143 return (dest);
01144 }
01145
01146 void ImageViewer::slideShow( bool on )
01147 {
01148 if (on) {
01149 if (!imageList.isEmpty()) {
01150 slideTimer->start(slideDelay * 1000, FALSE);
01151 filename = "";
01152 slideReverse ? prevImage() : nextImage();
01153 }
01154 } else {
01155 slideTimer->stop();
01156 slideAction->setOn( false);
01157 }
01158 }
01159
01160 void ImageViewer::slideUpdate()
01161 {
01162 bool final_image = slideReverse ? prevImage() : nextImage();
01163
01164 if (final_image && !slideRepeat) {
01165 slideTimer->stop();
01166 slideAction->setOn(FALSE);
01167 }
01168 }
01169
01170
01171
01172
01173
01174
01175 bool ImageViewer::nextImage(void)
01176 {
01177 int idx = 0;
01178
01179 if (imageList.count() > 0) {
01180 idx = imageIndex();
01181 if (idx != -1) {
01182 if (idx == int(imageList.count() - 1)) {
01183 idx = 0;
01184 } else {
01185 idx++;
01186 }
01187 } else {
01188 idx = 0;
01189 }
01190 openFile(imageList[idx]);
01191 }
01192
01193 return idx == int(imageList.count() - 1) ? TRUE : FALSE;
01194 }
01195
01196
01197
01198
01199
01200
01201 bool ImageViewer::prevImage(void)
01202 {
01203 int idx = -1;
01204
01205 if (imageList.count() > 0) {
01206 idx = imageIndex();
01207 if (idx != -1) {
01208 if (idx == 0) {
01209 idx = imageList.count() - 1;
01210 } else {
01211 idx--;
01212 }
01213 } else {
01214 idx = imageList.count() - 1;
01215 }
01216 openFile(imageList[idx]);
01217 }
01218
01219 return idx == 0 ? TRUE : FALSE;
01220 }
01221
01222
01223
01224
01225
01226 int ImageViewer::imageIndex(void)
01227 {
01228 QValueListConstIterator<DocLnk> i;
01229 int index;
01230
01231 if (imageList.count() == 0) {
01232 return -1;
01233 }
01234
01235 for (index = 0, i = imageList.begin(); i != imageList.end(); ++i, index++) {
01236 if ((*i).file() == filename) {
01237 return index;
01238 }
01239 }
01240
01241 return -1;
01242 }