Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

showimg.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2000 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of Qtopia Environment.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00015 **
00016 ** Contact info@trolltech.com if any conditions of this licensing are
00017 ** not clear to you.
00018 **
00019 **********************************************************************/
00020 
00021 //
00022 // Full-screen and rotation options contributed by Robert Wittams <robert@wittams.com>
00023 //
00024 
00025 #include "showimg.h"
00026 #include "ImageFileSelector.h"
00027 #include "settingsdialog.h"
00028 
00029 /* OPIE */
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 /* QT */
00039 #include <qtoolbar.h>
00040 #include <qaction.h>
00041 #include <qfiledialog.h>
00042 #include <qmenubar.h>
00043 #include <qspinbox.h>
00044 
00045 /* STD */
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   Draws the portion of the scaled pixmap that needs to be updated
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     { // is an image loaded?
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 /*wFlags*/ )
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     //menuBarmenubarFile->insertItem( tr("File"), fileMenu );
00233     fileMenuFile->insertItem(tr("Open"),
00234                             this, SLOT(openFile()), 0);
00235 
00236     viewMenuFile = new QPopupMenu( this );
00237     //menubarFile->insertItem( tr("View"), viewMenu );
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     //menubarFile->insertItem( tr("Options"),optionsMenu );
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 //     slideAction->addTo( toolBar );
00254 
00255 
00256 //     optionsMenuFile->insertItem( tr("Slideshow") );
00257     optionsMenuFile->insertSeparator();
00258     optionsMenuFile->insertItem( tr("Preferences.."), this, SLOT(settings()), 0);
00259 //    optionsMenuFile->insertItem( tr("Help"), this, SLOT(help()), 0);
00260 
00261     QStrList fmt = QImage::outputFormats();
00262 
00263 
00264     fileMenuView = new QPopupMenu( this );
00265     //menubarView->insertItem( tr("File"),fileMenu );
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     //menubarView->insertItem( tr("View"),viewMenu );
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     //switchThumbView();
00296 
00297 
00298     //fileSelector = new ImageFileSelector("image/*", stack, "fs");
00299     //fileSelector->setNewVisible(FALSE);
00300     //fileSelector->setCloseVisible(FALSE);
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     //a->addTo( iconToolBar );
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; // in case it is fullscreen
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 //    odebug << "Show "+fileref << oendl; 
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 //    if ( link.isValid() )
00532         openFile(link);
00533 
00534 }
00535 
00536 void ImageViewer::openFile( const DocLnk &link )
00537 {
00538     closeFileSelector();
00539 //    DocLnk link(file);
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   This function loads an image from a file.
00569 */
00570 
00571 void ImageViewer::loadImage( const char *fileName )
00572 {
00573     filename = fileName;
00574     if ( filename )  {
00575         QApplication::setOverrideCursor( waitCursor ); // this might take time
00576         //imagePanel->statusLabel()->setText( tr("Loading image...") );
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);             // couldn't load image
00585             update();
00586         }
00587         QApplication::restoreOverrideCursor();  // restore original cursor
00588     }
00589 
00590 //    fastLoad ? ", Fast" : "",
00591 //    fastLoad ? QMAX(imagewidth/maxsize, imageheight/maxsize) : 1);
00592 
00593 
00594 //    matrix.reset();
00595     rotated90 = FALSE;
00596 
00597     if (rotateOnLoad) {
00598         rotated90 = TRUE;
00599         rot90();
00600 //        matrix.rotate( -90.0 );
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 ); // this might take time
00648     if ( pm.convertFromImage(image /*, conversion_flags */ ) )
00649     {
00650         pmScaled = QPixmap();
00651         scale();
00652         success = TRUE;             // load successful
00653     }
00654     else
00655     {
00656         pm.resize(0,0);             // couldn't load image
00657     }
00658     QApplication::restoreOverrideCursor();  // restore original cursor
00659 
00660     return success;             // TRUE if loaded OK
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   This functions scales the pixmap in the member variable "pm" to fit the
00673   widget size and  puts the resulting pixmap in the member variable "pmScaled".
00674 */
00675 void ImageViewer::scale()
00676 {
00677     int h = calcHeight();
00678     if ( image.isNull() ) return;
00679 
00680     QApplication::setOverrideCursor( waitCursor ); // this might take time
00681     if ( imagePanel->paneWidth() == pm.width() && h == pm.height() )
00682     { // no need to scale if widget
00683         pmScaled = pm;              // size equals pixmap size
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 ) /*, conversion_flags */ );
00694     }
00695     QApplication::restoreOverrideCursor();  // restore original cursor
00696 }
00697 
00698 /*
00699   The resize event handler, if a valid pixmap was loaded it will call
00700   scale() to fit the pixmap to the new widget size.
00701 */
00702 
00703 void ImageViewer::resizeEvent( QResizeEvent * )
00704 {
00705 
00706     if ( pm.size() == QSize( 0, 0 ) )       // we couldn't load the image
00707         return;
00708 
00709     int h = calcHeight();
00710 
00711     if ( imagePanel->paneWidth() != pmScaled.width() || h != pmScaled.height() )
00712     {                       // if new size,
00713         scale();                // scale pmScaled to window
00714     }
00715     if ( image.hasAlphaBuffer() )
00716         erase();
00717 }
00718 
00719 
00720 void ImageViewer::hFlip()
00721 {
00722 //    matrix.scale( -1.0, 1.0 );
00723 
00724     setImage(image.mirror(TRUE,FALSE));
00725 }
00726 
00727 void ImageViewer::vFlip()
00728 {
00729 //    matrix.scale( 1.0, -1.0 );
00730     setImage(image.mirror(FALSE,TRUE));
00731 }
00732 
00733 void ImageViewer::rot180()
00734 {
00735 //    matrix.rotate( 180.0 );
00736     setImage(image.mirror(TRUE,TRUE));
00737 }
00738 
00739 void ImageViewer::rot90()
00740 {
00741     QImage oldimage;
00742     oldimage = image.convertDepth(32);
00743 //    matrix.rotate( -90.0 );
00744     setImage(rotate(oldimage,Rotate90));
00745 
00746 }
00747 void ImageViewer::rot270()
00748 {
00749 
00750     QImage oldimage;
00751     oldimage = image.convertDepth(32);
00752 //    matrix.rotate(90.0);
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     // Full-screen option
00820     // contributed by Robert Wittams <robert@wittams.com>
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 // Intensity,toGray and rotate code courtesy of KDE project.
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     { // keep overflow check out of loops
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     { // same here
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; // (r + b + g) / 3
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 = "";    // force restart
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 // Display the image after the current one in the image list.
01172 // Return TRUE if the next call to nextImage() will wrap around to the
01173 // first image in the list (ie. we're now viewing the last image in the list).
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 // Display the image preceeding the current one in the image list.
01198 // Return TRUE if the next call to prevImage() will wrap around to the last
01199 // image in the list (ie. we're now viewing the first image in the list).
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 // Return the index into the imageList of the currently viewed
01224 // image (ie. ImageViewer::filename in ImageViewer::imageList).
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 }

Generated on Sat Nov 5 16:18:18 2005 for OPIE by  doxygen 1.4.2