Diffstat (limited to 'noncore/unsupported/showimg/showimg.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/unsupported/showimg/showimg.cpp | 1242 |
1 files changed, 1242 insertions, 0 deletions
diff --git a/noncore/unsupported/showimg/showimg.cpp b/noncore/unsupported/showimg/showimg.cpp new file mode 100644 index 0000000..24377ed --- a/dev/null +++ b/noncore/unsupported/showimg/showimg.cpp | |||
@@ -0,0 +1,1242 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | |||
21 | // | ||
22 | // Full-screen and rotation options contributed by Robert Wittams <robert@wittams.com> | ||
23 | // | ||
24 | |||
25 | #include "showimg.h" | ||
26 | #include "ImageFileSelector.h" | ||
27 | #include "settingsdialog.h" | ||
28 | |||
29 | /* OPIE */ | ||
30 | #include <opie2/odebug.h> | ||
31 | #include <opie2/ofiledialog.h> | ||
32 | #include <qpe/qpeapplication.h> | ||
33 | #include <qpe/config.h> | ||
34 | #include <qpe/resource.h> | ||
35 | using namespace Opie::Core; | ||
36 | using namespace Opie::Ui; | ||
37 | |||
38 | /* QT */ | ||
39 | #include <qtoolbar.h> | ||
40 | #include <qaction.h> | ||
41 | #include <qfiledialog.h> | ||
42 | #include <qmenubar.h> | ||
43 | #include <qspinbox.h> | ||
44 | |||
45 | /* STD */ | ||
46 | #include <math.h> | ||
47 | |||
48 | ControlsDialog::ControlsDialog(const QString &caption,QImage image,int *brightness,QWidget *parent) | ||
49 | : QDialog(parent,0,true) | ||
50 | { | ||
51 | setCaption(caption); | ||
52 | |||
53 | if ( parent ) { | ||
54 | setPalette(parent->palette()); | ||
55 | } | ||
56 | |||
57 | b=brightness; | ||
58 | img=image; | ||
59 | |||
60 | setMinimumSize(140,80); | ||
61 | |||
62 | QGridLayout *gl= new QGridLayout(this,2,2,4,4); | ||
63 | |||
64 | pixmap =new ImageWidget(this);; | ||
65 | QPixmap pm; | ||
66 | pm.convertFromImage(img); | ||
67 | pixmap->setPixmap(pm); | ||
68 | pixmap->setMinimumSize(pm.width(),pm.height()); | ||
69 | gl->addMultiCellWidget(pixmap,0,0,0,2,AlignCenter); | ||
70 | QLabel *l=new QLabel(tr("Brightness")+":",this); | ||
71 | gl->addWidget(l,1,0,AlignLeft); | ||
72 | spb=new QSpinBox(-100,100,2,this); | ||
73 | gl->addWidget(spb,1,1,AlignRight); | ||
74 | |||
75 | spb->setValue(0); | ||
76 | |||
77 | connect(spb,SIGNAL(valueChanged(int)),this, SLOT(bValueChanged(int))); | ||
78 | |||
79 | } | ||
80 | |||
81 | void ControlsDialog::bValueChanged(int value) | ||
82 | { | ||
83 | QImage nImage=img; | ||
84 | nImage.detach(); | ||
85 | ImageViewer::intensity(nImage, (float)value/100); | ||
86 | QPixmap pm; | ||
87 | pm.convertFromImage(nImage); | ||
88 | pixmap->setPixmap(pm); | ||
89 | pixmap->repaint(false); | ||
90 | |||
91 | |||
92 | } | ||
93 | |||
94 | void ControlsDialog::accept() | ||
95 | { | ||
96 | *b=spb->value(); | ||
97 | done(1); | ||
98 | } | ||
99 | |||
100 | //=========================================================================== | ||
101 | |||
102 | InfoDialog::InfoDialog(const QString &caption, const QStringList text,QWidget *parent) | ||
103 | : QDialog(parent,0,true) | ||
104 | { | ||
105 | setCaption(caption); | ||
106 | |||
107 | if ( parent ) | ||
108 | { | ||
109 | setPalette(parent->palette()); | ||
110 | } | ||
111 | |||
112 | |||
113 | |||
114 | QString labels[]={ tr("File Name"),tr("Format"),tr("File Size"),tr("Size"),tr("Colors"),tr("Alpha") }; | ||
115 | |||
116 | setMinimumSize(180,80); | ||
117 | int num=ImageViewer::LAST+1; | ||
118 | if ( text[ImageViewer::ALPHA].isEmpty() ) | ||
119 | num--; | ||
120 | QGridLayout *gl= new QGridLayout(this,num,2,4,2); | ||
121 | QLabel *l; | ||
122 | int count=0; | ||
123 | for ( int i=0;i<num;i++ ) | ||
124 | { | ||
125 | if ( i==1 ) | ||
126 | { | ||
127 | QFrame *frm=new QFrame(this); | ||
128 | frm->setFrameStyle(QFrame::HLine|QFrame::Sunken); | ||
129 | gl->addMultiCellWidget(frm,i,i,0,1); | ||
130 | } | ||
131 | else | ||
132 | { | ||
133 | l=new QLabel( tr( labels[count] )+":",this); | ||
134 | gl->addWidget(l,i,0,AlignLeft); | ||
135 | l=new QLabel(text[count],this); | ||
136 | gl->addWidget(l,i,1,AlignRight); | ||
137 | count++; | ||
138 | } | ||
139 | |||
140 | } | ||
141 | |||
142 | } | ||
143 | |||
144 | void InfoDialog::displayInfo(const QString &caption, const QStringList text, QWidget *parent) | ||
145 | { | ||
146 | InfoDialog *dlg=new InfoDialog(caption,text,parent); | ||
147 | dlg->exec(); | ||
148 | delete dlg; | ||
149 | } | ||
150 | |||
151 | //=========================================================================== | ||
152 | |||
153 | |||
154 | ImagePane::ImagePane( QWidget *parent ) : QWidget( parent ) | ||
155 | { | ||
156 | vb = new QVBoxLayout( this ); | ||
157 | |||
158 | image = new QScrollView(this,0,WResizeNoErase|WNorthWestGravity); | ||
159 | pic=new ImageWidget(image); | ||
160 | image->addChild(pic); | ||
161 | |||
162 | connect(pic, SIGNAL( clicked() ), this, SLOT( imageClicked() )); | ||
163 | |||
164 | vb->addWidget( image ); | ||
165 | |||
166 | } | ||
167 | |||
168 | void ImagePane::setPixmap( const QPixmap &pm ) | ||
169 | { | ||
170 | pic->setPixmap( pm ); | ||
171 | pic->resize(pm.width(),pm.height()); | ||
172 | image->updateScrollBars (); | ||
173 | pic->repaint(false); | ||
174 | } | ||
175 | |||
176 | void ImagePane::imageClicked() | ||
177 | { | ||
178 | emit clicked(); | ||
179 | } | ||
180 | //=========================================================================== | ||
181 | /* | ||
182 | Draws the portion of the scaled pixmap that needs to be updated | ||
183 | */ | ||
184 | |||
185 | void ImageWidget::paintEvent( QPaintEvent *e ) | ||
186 | { | ||
187 | QPainter painter(this); | ||
188 | |||
189 | painter.setClipRect(e->rect()); | ||
190 | painter.fillRect(0,0,width(),height(),QColor(0,0,0)); | ||
191 | |||
192 | if ( pixmap.size() != QSize( 0, 0 ) ) | ||
193 | { // is an image loaded? | ||
194 | painter.drawPixmap((width() - pixmap.width()) / 2, (height() - pixmap.height()) / 2, pixmap); | ||
195 | } | ||
196 | } | ||
197 | |||
198 | void ImageWidget::mouseReleaseEvent(QMouseEvent *) | ||
199 | { | ||
200 | emit clicked(); | ||
201 | } | ||
202 | |||
203 | //=========================================================================== | ||
204 | |||
205 | ImageViewer::ImageViewer( QWidget *parent, const char *name, int /*wFlags*/ ) | ||
206 | : QMainWindow( parent, name, WResizeNoErase ), filename( 0 ), bFromDocView( FALSE ) | ||
207 | { | ||
208 | setCaption( tr("Image Viewer") ); | ||
209 | setIcon( Resource::loadPixmap( "ImageViewer" ) ); | ||
210 | |||
211 | |||
212 | Config cfg("Image Viewer"); | ||
213 | cfg.setGroup("Image Viewer"); | ||
214 | |||
215 | showThumbView=cfg.readBoolEntry("ShowThumbnails",false); | ||
216 | isSized=cfg.readBoolEntry("SizeToScreen",true); | ||
217 | |||
218 | isFullScreen = FALSE; | ||
219 | |||
220 | setToolBarsMovable( FALSE ); | ||
221 | |||
222 | toolBar = new QToolBar( this ); | ||
223 | toolBar->setHorizontalStretchable( TRUE ); | ||
224 | |||
225 | menuBar = new QMenuBar( toolBar ); | ||
226 | |||
227 | current=menuBar; | ||
228 | |||
229 | |||
230 | |||
231 | fileMenuFile = new QPopupMenu(this); | ||
232 | //menuBarmenubarFile->insertItem( tr("File"), fileMenu ); | ||
233 | fileMenuFile->insertItem(tr("Open"), | ||
234 | this, SLOT(openFile()), 0); | ||
235 | |||
236 | viewMenuFile = new QPopupMenu( this ); | ||
237 | //menubarFile->insertItem( tr("View"), viewMenu ); | ||
238 | viewMenuFile->insertItem( tr("Thumbnail View"), | ||
239 | this, SLOT(switchThumbView()), 0, SHOW_THUMBNAILS ); | ||
240 | |||
241 | viewMenuFile->setItemChecked ( SHOW_THUMBNAILS, showThumbView ); | ||
242 | |||
243 | |||
244 | |||
245 | |||
246 | optionsMenuFile = new QPopupMenu( this); | ||
247 | //menubarFile->insertItem( tr("Options"),optionsMenu ); | ||
248 | slideAction = new QAction( tr( "Slide show" ), Resource::loadIconSet( "slideshow" ), | ||
249 | QString::null, 0, this, 0 ); | ||
250 | slideAction->setToggleAction( TRUE ); | ||
251 | connect( slideAction, SIGNAL( toggled(bool) ), this, SLOT( slideShow(bool) ) ); | ||
252 | slideAction->addTo( optionsMenuFile); | ||
253 | // slideAction->addTo( toolBar ); | ||
254 | |||
255 | |||
256 | // optionsMenuFile->insertItem( tr("Slideshow") ); | ||
257 | optionsMenuFile->insertSeparator(); | ||
258 | optionsMenuFile->insertItem( tr("Preferences.."), this, SLOT(settings()), 0); | ||
259 | // optionsMenuFile->insertItem( tr("Help"), this, SLOT(help()), 0); | ||
260 | |||
261 | QStrList fmt = QImage::outputFormats(); | ||
262 | |||
263 | |||
264 | fileMenuView = new QPopupMenu( this ); | ||
265 | //menubarView->insertItem( tr("File"),fileMenu ); | ||
266 | fileMenuView->insertItem( tr("Image Info ..."),this, SLOT(displayInfoDialog()),0 ); | ||
267 | fileMenuView->insertSeparator(); | ||
268 | |||
269 | viewMenuView = new QPopupMenu(this ); | ||
270 | viewMenuView->setCheckable ( true ); | ||
271 | |||
272 | //menubarView->insertItem( tr("View"),viewMenu ); | ||
273 | viewMenuView->insertItem(tr("Horizontal flip"), this, SLOT(hFlip()), 0); | ||
274 | viewMenuView->insertItem(tr("Vertical flip"), this, SLOT(vFlip()), 0); | ||
275 | |||
276 | stack = new QWidgetStack( this ); | ||
277 | stack->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) ); | ||
278 | setCentralWidget( stack ); | ||
279 | |||
280 | |||
281 | imagePanel = new ImagePane( stack ); | ||
282 | connect(imagePanel, SIGNAL(clicked()), this, SLOT(normalView())); | ||
283 | |||
284 | |||
285 | ImageFileSelector::CURRENT_VIEW cv; | ||
286 | if(showThumbView) | ||
287 | cv=ImageFileSelector::THUMBNAIL; | ||
288 | else | ||
289 | cv=ImageFileSelector::DETAILED; | ||
290 | |||
291 | odebug << "cv = " << cv << "" << oendl; | ||
292 | |||
293 | fileSelector = new ImageFileSelector( cv,stack, "fs"); | ||
294 | |||
295 | //switchThumbView(); | ||
296 | |||
297 | |||
298 | //fileSelector = new ImageFileSelector("image/*", stack, "fs"); | ||
299 | //fileSelector->setNewVisible(FALSE); | ||
300 | //fileSelector->setCloseVisible(FALSE); | ||
301 | connect( fileSelector, SIGNAL( closeMe() ), this, SLOT( closeFileSelector() ) ); | ||
302 | connect( fileSelector, SIGNAL( fileSelected(const DocLnk&) ), | ||
303 | this, SLOT( openFile(const DocLnk&) ) ); | ||
304 | |||
305 | imageList = fileSelector->fileList(); | ||
306 | slideAction->setEnabled( imageList.count() != 0); | ||
307 | |||
308 | iconToolBar = new QToolBar(this); | ||
309 | |||
310 | QAction *a; | ||
311 | |||
312 | a = new QAction( tr( "Open ..." ), Resource::loadPixmap( "fileopen" ), QString::null, 0, this, 0 ); | ||
313 | connect( a, SIGNAL( activated() ), this, SLOT( open() ) ); | ||
314 | a->addTo( fileMenuView); | ||
315 | a->addTo( iconToolBar ); | ||
316 | |||
317 | |||
318 | a = new QAction( tr( "Rotate 90"), Resource::loadPixmap( "rotate90" ), QString::null, 0, this, 0); | ||
319 | connect( a, SIGNAL( activated() ), this, SLOT( rot90() ) ); | ||
320 | a->addTo( iconToolBar ); | ||
321 | a->addTo( viewMenuView ); | ||
322 | |||
323 | a = new QAction( tr( "Rotate 180" ), Resource::loadPixmap( "repeat" ), QString::null, 0, this, 0 ); | ||
324 | connect( a, SIGNAL( activated() ), this, SLOT( rot180() ) ); | ||
325 | a->addTo( iconToolBar ); | ||
326 | a->addTo( viewMenuView ); | ||
327 | |||
328 | |||
329 | a = new QAction( tr( "Rotate 270"), Resource::loadPixmap( "rotate270" ), QString::null, 0, this, 0); | ||
330 | connect( a, SIGNAL( activated() ), this, SLOT( rot270() ) ); | ||
331 | //a->addTo( iconToolBar ); | ||
332 | a->addTo( viewMenuView ); | ||
333 | |||
334 | |||
335 | |||
336 | viewMenuView->insertSeparator(); | ||
337 | viewMenuView->insertItem(tr("Brightness ..."), this, SLOT(displayControlsDialog()), 0); | ||
338 | viewMenuView->insertItem(tr("Black And White"), this, SLOT(blackAndWhite()), 0,BLACKANDWHITE); | ||
339 | viewMenuView->insertSeparator(); | ||
340 | |||
341 | |||
342 | sss = new QAction( tr( "Scale to Screen"), Resource::loadPixmap( "scale" ), QString::null, 0, this, 0,true); | ||
343 | connect( sss, SIGNAL( activated() ), this, SLOT( switchSizeToScreen() ) ); | ||
344 | sss->addTo( iconToolBar ); | ||
345 | sss->addTo( viewMenuView ); | ||
346 | |||
347 | sss->setOn(isSized); | ||
348 | viewMenuView->insertSeparator(); | ||
349 | |||
350 | |||
351 | a = new QAction( tr( "Fullscreen" ), Resource::loadPixmap( "fullscreen" ), | ||
352 | QString::null, 0, this, 0 ); | ||
353 | connect( a, SIGNAL( activated() ), this, SLOT( fullScreen() ) ); | ||
354 | a->addTo( iconToolBar ); | ||
355 | a->addTo( viewMenuView); | ||
356 | |||
357 | a = new QAction( tr( "Stop Slideshow" ), Resource::loadPixmap( "quit_icon" ), | ||
358 | QString::null, 0, this, 0 ); | ||
359 | connect( a, SIGNAL( activated() ), this, SLOT( stopSlideShow() ) ); | ||
360 | a->addTo( iconToolBar ); | ||
361 | a->addTo( viewMenuView); | ||
362 | |||
363 | |||
364 | Config config( "ImageViewer" ); | ||
365 | config.setGroup( "SlideShow" ); | ||
366 | slideDelay = config.readNumEntry( "Delay", 2); | ||
367 | slideRepeat = config.readBoolEntry( "Repeat", FALSE ); | ||
368 | slideReverse = config.readBoolEntry("Reverse", FALSE); | ||
369 | |||
370 | config.setGroup("Default"); | ||
371 | rotateOnLoad = config.readBoolEntry("Rotate", FALSE); | ||
372 | fastLoad = config.readBoolEntry("FastLoad", TRUE); | ||
373 | slideTimer = new QTimer( this ); | ||
374 | connect( slideTimer, SIGNAL(timeout()), this, SLOT(slideUpdate()) ); | ||
375 | |||
376 | switchToFileSelector(); | ||
377 | |||
378 | setMouseTracking( TRUE ); | ||
379 | |||
380 | |||
381 | } | ||
382 | |||
383 | ImageViewer::~ImageViewer() | ||
384 | { | ||
385 | Config cfg("Image Viewer"); | ||
386 | cfg.setGroup("Image Viewer"); | ||
387 | |||
388 | cfg.writeEntry("ShowThumbnails",(int)showThumbView); | ||
389 | cfg.writeEntry("SizeToScreen",(int)isSized); | ||
390 | |||
391 | cfg.setGroup( "SlideShow" ); | ||
392 | cfg.writeEntry( "Delay", slideDelay); | ||
393 | cfg.writeEntry( "Repeat", slideRepeat ); | ||
394 | cfg.writeEntry("Reverse", slideReverse); | ||
395 | |||
396 | cfg.setGroup("Default"); | ||
397 | cfg.writeEntry("Rotate", rotateOnLoad); | ||
398 | cfg.writeEntry("FastLoad", fastLoad); | ||
399 | |||
400 | delete imagePanel; // in case it is fullscreen | ||
401 | } | ||
402 | |||
403 | void ImageViewer::help() { | ||
404 | |||
405 | } | ||
406 | |||
407 | |||
408 | void ImageViewer::settings() | ||
409 | { | ||
410 | SettingsDialog dlg( this, 0, TRUE ); | ||
411 | dlg.setDelay( slideDelay ); | ||
412 | dlg.setRepeat( slideRepeat ); | ||
413 | dlg.setReverse( slideReverse ); | ||
414 | dlg.setRotate(rotateOnLoad); | ||
415 | dlg.setFastLoad(fastLoad); | ||
416 | |||
417 | if ( QPEApplication::execDialog(&dlg) == QDialog::Accepted ) { | ||
418 | odebug << "<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>" << oendl; | ||
419 | slideDelay = dlg.delay(); | ||
420 | slideRepeat = dlg.repeat(); | ||
421 | slideReverse = dlg.reverse(); | ||
422 | rotateOnLoad = dlg.rotate(); | ||
423 | fastLoad = dlg.fastLoad(); | ||
424 | |||
425 | Config config( "ImageViewer" ); | ||
426 | config.setGroup( "SlideShow" ); | ||
427 | config.writeEntry( "Delay", slideDelay ); | ||
428 | config.writeEntry( "Repeat", slideRepeat ); | ||
429 | config.writeEntry("Reverse", slideReverse); | ||
430 | |||
431 | config.setGroup("Default"); | ||
432 | config.writeEntry("Rotate", rotateOnLoad); | ||
433 | config.writeEntry("FastLoad", fastLoad); | ||
434 | } | ||
435 | } | ||
436 | |||
437 | void ImageViewer::switchSizeToScreen() | ||
438 | { | ||
439 | isSized=!isSized; | ||
440 | sss->setOn(isSized); | ||
441 | updateImage(); | ||
442 | } | ||
443 | |||
444 | void ImageViewer::updateImage() | ||
445 | { | ||
446 | if ( isSized ) { | ||
447 | imagePanel->setPixmap(pmScaled); | ||
448 | } else { | ||
449 | imagePanel->setPixmap(pm); | ||
450 | } | ||
451 | } | ||
452 | |||
453 | void ImageViewer::switchThumbView() | ||
454 | { | ||
455 | |||
456 | showThumbView=!showThumbView; | ||
457 | viewMenuFile->setItemChecked ( SHOW_THUMBNAILS, showThumbView ); | ||
458 | fileSelector->switchView(); | ||
459 | |||
460 | } | ||
461 | |||
462 | void ImageViewer::switchToFileSelector() | ||
463 | { | ||
464 | stack->raiseWidget(fileSelector); | ||
465 | menuBar->clear(); | ||
466 | menuBar->insertItem( tr("File"), fileMenuFile ); | ||
467 | menuBar->insertItem( tr("View"), viewMenuFile ); | ||
468 | menuBar->insertItem( tr("Options"), optionsMenuFile ); | ||
469 | iconToolBar->hide(); | ||
470 | imagePanel->disable(); | ||
471 | slideShow(false); | ||
472 | |||
473 | } | ||
474 | |||
475 | void ImageViewer::switchToImageView() | ||
476 | { | ||
477 | stack->raiseWidget(imagePanel); | ||
478 | |||
479 | menuBar->clear(); | ||
480 | menuBar->insertItem( tr("File"), fileMenuView ); | ||
481 | menuBar->insertItem( tr("View"), viewMenuView ); | ||
482 | viewMenuView->setItemEnabled(BLACKANDWHITE,true); | ||
483 | iconToolBar->show(); | ||
484 | |||
485 | imagePanel->setPosition(0,0); | ||
486 | |||
487 | } | ||
488 | |||
489 | |||
490 | void ImageViewer::setDocument(const QString& fileref) | ||
491 | { | ||
492 | delayLoad = fileref; | ||
493 | switchToImageView(); | ||
494 | QTimer::singleShot( 0, this, SLOT(doDelayedLoad()) ); | ||
495 | } | ||
496 | |||
497 | void ImageViewer::doDelayedLoad() | ||
498 | { | ||
499 | show(delayLoad); | ||
500 | } | ||
501 | |||
502 | void ImageViewer::show() | ||
503 | { | ||
504 | normalView(); | ||
505 | QMainWindow::show(); | ||
506 | } | ||
507 | |||
508 | void ImageViewer::show(const QString& fileref) | ||
509 | { | ||
510 | // odebug << "Show "+fileref << oendl; | ||
511 | bFromDocView = TRUE; | ||
512 | closeFileSelector(); | ||
513 | DocLnk link(fileref); | ||
514 | if ( link.isValid() ) { | ||
515 | openFile(link); | ||
516 | } else { | ||
517 | filename = fileref; | ||
518 | updateCaption( fileref ); | ||
519 | loadImage( fileref ); | ||
520 | } | ||
521 | } | ||
522 | |||
523 | void ImageViewer::openFile() { | ||
524 | MimeTypes types; | ||
525 | QStringList image; | ||
526 | image << "image/*"; | ||
527 | types.insert("Images", image); | ||
528 | |||
529 | QString str = OFileDialog::getOpenFileName( 1,QPEApplication::documentDir(),"", types, 0 ); | ||
530 | DocLnk link(str); | ||
531 | // if ( link.isValid() ) | ||
532 | openFile(link); | ||
533 | |||
534 | } | ||
535 | |||
536 | void ImageViewer::openFile( const DocLnk &link ) | ||
537 | { | ||
538 | closeFileSelector(); | ||
539 | // DocLnk link(file); | ||
540 | odebug << "open "+link.name() << oendl; | ||
541 | updateCaption( link.name() ); | ||
542 | loadImage( link.file() ); | ||
543 | if (slideTimer->isActive()) { | ||
544 | slideTimer->start(slideDelay * 1000, FALSE); | ||
545 | } | ||
546 | |||
547 | } | ||
548 | |||
549 | void ImageViewer::open() | ||
550 | { | ||
551 | switchToFileSelector(); | ||
552 | } | ||
553 | |||
554 | void ImageViewer::closeFileSelector() | ||
555 | { | ||
556 | switchToImageView(); | ||
557 | } | ||
558 | |||
559 | void ImageViewer::updateCaption( QString name ) | ||
560 | { | ||
561 | int sep = name.findRev( '/' ); | ||
562 | if ( sep >= 0 ) | ||
563 | name = name.mid( sep+1 ); | ||
564 | setCaption( name + tr(" - Image Viewer") ); | ||
565 | } | ||
566 | |||
567 | /* | ||
568 | This function loads an image from a file. | ||
569 | */ | ||
570 | |||
571 | void ImageViewer::loadImage( const char *fileName ) | ||
572 | { | ||
573 | filename = fileName; | ||
574 | if ( filename ) { | ||
575 | QApplication::setOverrideCursor( waitCursor ); // this might take time | ||
576 | //imagePanel->statusLabel()->setText( tr("Loading image...") ); | ||
577 | qApp->processEvents(); | ||
578 | bool ok = image.load(filename, 0); | ||
579 | if ( ok ) { | ||
580 | ok = reconvertImage(); | ||
581 | updateImageInfo(filename); | ||
582 | } | ||
583 | if ( !ok ) { | ||
584 | pm.resize(0,0); // couldn't load image | ||
585 | update(); | ||
586 | } | ||
587 | QApplication::restoreOverrideCursor(); // restore original cursor | ||
588 | } | ||
589 | |||
590 | // fastLoad ? ", Fast" : "", | ||
591 | // fastLoad ? QMAX(imagewidth/maxsize, imageheight/maxsize) : 1); | ||
592 | |||
593 | |||
594 | // matrix.reset(); | ||
595 | rotated90 = FALSE; | ||
596 | |||
597 | if (rotateOnLoad) { | ||
598 | rotated90 = TRUE; | ||
599 | rot90(); | ||
600 | // matrix.rotate( -90.0 ); | ||
601 | } | ||
602 | |||
603 | switchToImageView(); | ||
604 | updateImage(); | ||
605 | |||
606 | } | ||
607 | |||
608 | bool ImageViewer::loadSelected() | ||
609 | { | ||
610 | bool ok = false; | ||
611 | if ( stack->visibleWidget() == fileSelector ) | ||
612 | { | ||
613 | const DocLnk *link = fileSelector->selected(); | ||
614 | if ( link ) | ||
615 | { | ||
616 | if ( link->file() != filename ) | ||
617 | { | ||
618 | updateCaption( link->name() ); | ||
619 | filename = link->file(); | ||
620 | qApp->processEvents(); | ||
621 | ok = image.load(filename, 0); | ||
622 | if ( ok ) | ||
623 | { | ||
624 | updateImageInfo(filename); | ||
625 | ok = reconvertImage(); | ||
626 | } | ||
627 | if ( !ok ) | ||
628 | pm.resize(0,0); | ||
629 | } | ||
630 | } | ||
631 | } | ||
632 | if ( !image.isNull() ) | ||
633 | { | ||
634 | ok = true; | ||
635 | closeFileSelector(); | ||
636 | } | ||
637 | |||
638 | return ok; | ||
639 | } | ||
640 | |||
641 | bool ImageViewer::reconvertImage() | ||
642 | { | ||
643 | bool success = FALSE; | ||
644 | |||
645 | if ( image.isNull() ) return FALSE; | ||
646 | |||
647 | QApplication::setOverrideCursor( waitCursor ); // this might take time | ||
648 | if ( pm.convertFromImage(image /*, conversion_flags */ ) ) | ||
649 | { | ||
650 | pmScaled = QPixmap(); | ||
651 | scale(); | ||
652 | success = TRUE; // load successful | ||
653 | } | ||
654 | else | ||
655 | { | ||
656 | pm.resize(0,0); // couldn't load image | ||
657 | } | ||
658 | QApplication::restoreOverrideCursor(); // restore original cursor | ||
659 | |||
660 | return success; // TRUE if loaded OK | ||
661 | } | ||
662 | |||
663 | |||
664 | int ImageViewer::calcHeight() | ||
665 | { | ||
666 | if ( !isFullScreen ) | ||
667 | return imagePanel->paneHeight(); | ||
668 | else | ||
669 | return qApp->desktop()->height(); | ||
670 | } | ||
671 | /* | ||
672 | This functions scales the pixmap in the member variable "pm" to fit the | ||
673 | widget size and puts the resulting pixmap in the member variable "pmScaled". | ||
674 | */ | ||
675 | void ImageViewer::scale() | ||
676 | { | ||
677 | int h = calcHeight(); | ||
678 | if ( image.isNull() ) return; | ||
679 | |||
680 | QApplication::setOverrideCursor( waitCursor ); // this might take time | ||
681 | if ( imagePanel->paneWidth() == pm.width() && h == pm.height() ) | ||
682 | { // no need to scale if widget | ||
683 | pmScaled = pm; // size equals pixmap size | ||
684 | } | ||
685 | else | ||
686 | { | ||
687 | double hs = (double)h / (double)image.height(); | ||
688 | double ws = (double)imagePanel->paneWidth() / (double)image.width(); | ||
689 | double scaleFactor = (hs > ws) ? ws : hs; | ||
690 | int smoothW = (int)(scaleFactor * image.width()); | ||
691 | int smoothH = (int)(scaleFactor * image.height()); | ||
692 | |||
693 | pmScaled.convertFromImage( image.smoothScale( smoothW, smoothH ) /*, conversion_flags */ ); | ||
694 | } | ||
695 | QApplication::restoreOverrideCursor(); // restore original cursor | ||
696 | } | ||
697 | |||
698 | /* | ||
699 | The resize event handler, if a valid pixmap was loaded it will call | ||
700 | scale() to fit the pixmap to the new widget size. | ||
701 | */ | ||
702 | |||
703 | void ImageViewer::resizeEvent( QResizeEvent * ) | ||
704 | { | ||
705 | |||
706 | if ( pm.size() == QSize( 0, 0 ) ) // we couldn't load the image | ||
707 | return; | ||
708 | |||
709 | int h = calcHeight(); | ||
710 | |||
711 | if ( imagePanel->paneWidth() != pmScaled.width() || h != pmScaled.height() ) | ||
712 | { // if new size, | ||
713 | scale(); // scale pmScaled to window | ||
714 | } | ||
715 | if ( image.hasAlphaBuffer() ) | ||
716 | erase(); | ||
717 | } | ||
718 | |||
719 | |||
720 | void ImageViewer::hFlip() | ||
721 | { | ||
722 | // matrix.scale( -1.0, 1.0 ); | ||
723 | |||
724 | setImage(image.mirror(TRUE,FALSE)); | ||
725 | } | ||
726 | |||
727 | void ImageViewer::vFlip() | ||
728 | { | ||
729 | // matrix.scale( 1.0, -1.0 ); | ||
730 | setImage(image.mirror(FALSE,TRUE)); | ||
731 | } | ||
732 | |||
733 | void ImageViewer::rot180() | ||
734 | { | ||
735 | // matrix.rotate( 180.0 ); | ||
736 | setImage(image.mirror(TRUE,TRUE)); | ||
737 | } | ||
738 | |||
739 | void ImageViewer::rot90() | ||
740 | { | ||
741 | QImage oldimage; | ||
742 | oldimage = image.convertDepth(32); | ||
743 | // matrix.rotate( -90.0 ); | ||
744 | setImage(rotate(oldimage,Rotate90)); | ||
745 | |||
746 | } | ||
747 | void ImageViewer::rot270() | ||
748 | { | ||
749 | |||
750 | QImage oldimage; | ||
751 | oldimage = image.convertDepth(32); | ||
752 | // matrix.rotate(90.0); | ||
753 | setImage(rotate(oldimage,Rotate270)); | ||
754 | |||
755 | } | ||
756 | |||
757 | void ImageViewer::blackAndWhite() | ||
758 | { | ||
759 | |||
760 | viewMenuView->setItemEnabled(BLACKANDWHITE,false); | ||
761 | setImage(toGray(image,false)); | ||
762 | } | ||
763 | |||
764 | void ImageViewer::displayControlsDialog() | ||
765 | { | ||
766 | int w=80; | ||
767 | int h=w; | ||
768 | QImage small; | ||
769 | |||
770 | if ( image.width()<w ||image.height()<h ) | ||
771 | small=image.smoothScale(w,h); | ||
772 | else | ||
773 | small=image.copy(0,0,w,h); | ||
774 | |||
775 | int newB=0; | ||
776 | ControlsDialog *dlg=new ControlsDialog("Image Viewer",small,&newB,this); | ||
777 | dlg->exec(); | ||
778 | if ( newB ) { | ||
779 | intensity(image,(float)newB/100); | ||
780 | setImage(image); | ||
781 | } | ||
782 | |||
783 | } | ||
784 | |||
785 | |||
786 | void ImageViewer::displayInfoDialog() | ||
787 | { | ||
788 | |||
789 | QStringList ls; | ||
790 | |||
791 | for ( int i=0;i<LAST;i++ ) | ||
792 | ls.append(imageInfo[i]); | ||
793 | |||
794 | InfoDialog::displayInfo("Image Viewer",ls,this); | ||
795 | } | ||
796 | void ImageViewer::normalView() | ||
797 | { | ||
798 | if ( !imagePanel->parentWidget() ) | ||
799 | { | ||
800 | |||
801 | isFullScreen = FALSE; | ||
802 | stack->addWidget( imagePanel, 1 ); | ||
803 | switchToImageView(); | ||
804 | if ( isSized ) | ||
805 | scale(); | ||
806 | |||
807 | updateImage(); | ||
808 | |||
809 | } | ||
810 | } | ||
811 | |||
812 | void ImageViewer::stopSlideShow() { | ||
813 | if (slideTimer->isActive()) | ||
814 | slideTimer->stop(); | ||
815 | } | ||
816 | |||
817 | void ImageViewer::fullScreen() | ||
818 | { | ||
819 | // Full-screen option | ||
820 | // contributed by Robert Wittams <robert@wittams.com> | ||
821 | if ( imagePanel->parentWidget() && loadSelected() ) | ||
822 | { | ||
823 | isFullScreen = TRUE; | ||
824 | imagePanel->reparent(0,QPoint(0,0)); | ||
825 | imagePanel->resize(qApp->desktop()->width(), qApp->desktop()->height()); | ||
826 | |||
827 | if ( isSized ) | ||
828 | scale(); | ||
829 | updateImage(); | ||
830 | imagePanel->showFullScreen(); | ||
831 | } | ||
832 | } | ||
833 | |||
834 | void ImageViewer::setImage(const QImage& newimage) | ||
835 | { | ||
836 | image = newimage; | ||
837 | reconvertImage(); | ||
838 | updateImage(); | ||
839 | } | ||
840 | |||
841 | void ImageViewer::updateImageInfo(QString &filePath) | ||
842 | { | ||
843 | |||
844 | for ( int i=0;i<LAST;i++ ) | ||
845 | { | ||
846 | imageInfo[i]=""; | ||
847 | } | ||
848 | |||
849 | imageInfo[FORMAT]=QImage::imageFormat (filePath ); | ||
850 | QFileInfo fi(filePath); | ||
851 | imageInfo[PATH]=fi.fileName(); | ||
852 | imageInfo[FILE_SIZE]=QString::number(fi.size())+" (bytes)"; | ||
853 | QString message("%1x%2"); | ||
854 | imageInfo[SIZE]=QString("%1x%2"); | ||
855 | imageInfo[SIZE]=imageInfo[SIZE].arg(image.width()).arg(image.height()); | ||
856 | if ( image.numColors() > 0 ) | ||
857 | { | ||
858 | imageInfo[COLORS]=tr("%1 colors").arg(image.numColors()); | ||
859 | } | ||
860 | else if ( image.depth() >= 16 ) | ||
861 | { | ||
862 | imageInfo[COLORS]=tr(" True color"); | ||
863 | } | ||
864 | if ( image.hasAlphaBuffer() ) | ||
865 | { | ||
866 | if ( image.depth() == 8 ) | ||
867 | { | ||
868 | int i; | ||
869 | bool alpha[256]; | ||
870 | int nalpha=0; | ||
871 | |||
872 | for ( i=0; i<256; i++ ) | ||
873 | alpha[i] = FALSE; | ||
874 | |||
875 | for ( i=0; i<image.numColors(); i++ ) | ||
876 | { | ||
877 | int alevel = image.color(i) >> 24; | ||
878 | if ( !alpha[alevel] ) | ||
879 | { | ||
880 | alpha[alevel] = TRUE; | ||
881 | nalpha++; | ||
882 | } | ||
883 | } | ||
884 | imageInfo[ALPHA]=tr("%1 alpha levels").arg(nalpha); | ||
885 | } | ||
886 | else | ||
887 | { | ||
888 | imageInfo[ALPHA]=tr("8-bit alpha channel"); | ||
889 | } | ||
890 | } | ||
891 | |||
892 | } | ||
893 | |||
894 | void ImageViewer::closeEvent( QCloseEvent *e ) | ||
895 | { | ||
896 | if ( stack->visibleWidget() == imagePanel && !bFromDocView ) | ||
897 | { | ||
898 | e->ignore(); | ||
899 | open(); | ||
900 | } | ||
901 | else | ||
902 | { | ||
903 | bFromDocView = FALSE; | ||
904 | e->accept(); | ||
905 | } | ||
906 | } | ||
907 | |||
908 | // Intensity,toGray and rotate code courtesy of KDE project. | ||
909 | |||
910 | |||
911 | QImage& ImageViewer::intensity(QImage &image, float percent) | ||
912 | { | ||
913 | |||
914 | int segColors = image.depth() > 8 ? 256 : image.numColors(); | ||
915 | unsigned char *segTbl = new unsigned char[segColors]; | ||
916 | int pixels = image.depth() > 8 ? image.width()*image.height() : | ||
917 | image.numColors(); | ||
918 | unsigned int *data = image.depth() > 8 ? (unsigned int *)image.bits() : | ||
919 | (unsigned int *)image.colorTable(); | ||
920 | |||
921 | bool brighten = (percent >= 0); | ||
922 | if ( percent < 0 ) | ||
923 | percent = -percent; | ||
924 | |||
925 | if ( brighten ) | ||
926 | { // keep overflow check out of loops | ||
927 | for ( int i=0; i < segColors; ++i ) | ||
928 | { | ||
929 | int tmp = (int)(i*percent); | ||
930 | if ( tmp > 255 ) | ||
931 | tmp = 255; | ||
932 | segTbl[i] = tmp; | ||
933 | } | ||
934 | } | ||
935 | else | ||
936 | { | ||
937 | for ( int i=0; i < segColors; ++i ) | ||
938 | { | ||
939 | int tmp = (int)(i*percent); | ||
940 | if ( tmp < 0 ) | ||
941 | tmp = 0; | ||
942 | segTbl[i] = tmp; | ||
943 | } | ||
944 | } | ||
945 | |||
946 | if ( brighten ) | ||
947 | { // same here | ||
948 | for ( int i=0; i < pixels; ++i ) | ||
949 | { | ||
950 | int r = qRed(data[i]); | ||
951 | int g = qGreen(data[i]); | ||
952 | int b = qBlue(data[i]); | ||
953 | int a = qAlpha(data[i]); | ||
954 | r = r + segTbl[r] > 255 ? 255 : r + segTbl[r]; | ||
955 | g = g + segTbl[g] > 255 ? 255 : g + segTbl[g]; | ||
956 | b = b + segTbl[b] > 255 ? 255 : b + segTbl[b]; | ||
957 | data[i] = qRgba(r, g, b,a); | ||
958 | } | ||
959 | } | ||
960 | else | ||
961 | { | ||
962 | for ( int i=0; i < pixels; ++i ) | ||
963 | { | ||
964 | int r = qRed(data[i]); | ||
965 | int g = qGreen(data[i]); | ||
966 | int b = qBlue(data[i]); | ||
967 | int a = qAlpha(data[i]); | ||
968 | r = r - segTbl[r] < 0 ? 0 : r - segTbl[r]; | ||
969 | g = g - segTbl[g] < 0 ? 0 : g - segTbl[g]; | ||
970 | b = b - segTbl[b] < 0 ? 0 : b - segTbl[b]; | ||
971 | data[i] = qRgba(r, g, b, a); | ||
972 | } | ||
973 | } | ||
974 | delete [] segTbl; | ||
975 | |||
976 | return image; | ||
977 | } | ||
978 | |||
979 | QImage& ImageViewer::toGray(QImage &img, bool fast) | ||
980 | { | ||
981 | if ( img.width() == 0 || img.height() == 0 ) | ||
982 | return img; | ||
983 | |||
984 | if ( fast ) | ||
985 | { | ||
986 | if ( img.depth() == 32 ) | ||
987 | { | ||
988 | register uchar * r(img.bits()); | ||
989 | register uchar * g(img.bits() + 1); | ||
990 | register uchar * b(img.bits() + 2); | ||
991 | |||
992 | uchar * end(img.bits() + img.numBytes()); | ||
993 | |||
994 | while ( r != end ) | ||
995 | { | ||
996 | |||
997 | *r = *g = *b = (((*r + *g) >> 1) + *b) >> 1; // (r + b + g) / 3 | ||
998 | |||
999 | r += 4; | ||
1000 | g += 4; | ||
1001 | b += 4; | ||
1002 | } | ||
1003 | } | ||
1004 | else | ||
1005 | { | ||
1006 | for ( int i = 0; i < img.numColors(); i++ ) | ||
1007 | { | ||
1008 | register uint r = qRed(img.color(i)); | ||
1009 | register uint g = qGreen(img.color(i)); | ||
1010 | register uint b = qBlue(img.color(i)); | ||
1011 | |||
1012 | register uint gray = (((r + g) >> 1) + b) >> 1; | ||
1013 | img.setColor(i, qRgba(gray, gray, gray, qAlpha(img.color(i)))); | ||
1014 | } | ||
1015 | } | ||
1016 | } | ||
1017 | else | ||
1018 | { | ||
1019 | int pixels = img.depth() > 8 ? img.width()*img.height() : | ||
1020 | img.numColors(); | ||
1021 | unsigned int *data = img.depth() > 8 ? (unsigned int *)img.bits() : | ||
1022 | (unsigned int *)img.colorTable(); | ||
1023 | int val, i; | ||
1024 | for ( i=0; i < pixels; ++i ) | ||
1025 | { | ||
1026 | val = qGray(data[i]); | ||
1027 | data[i] = qRgba(val, val, val, qAlpha(data[i])); | ||
1028 | } | ||
1029 | } | ||
1030 | return img; | ||
1031 | } | ||
1032 | |||
1033 | |||
1034 | QImage ImageViewer::rotate(QImage &img, RotateDirection r) | ||
1035 | { | ||
1036 | QImage dest; | ||
1037 | int x, y; | ||
1038 | if ( img.depth() > 8 ) | ||
1039 | { | ||
1040 | unsigned int *srcData, *destData; | ||
1041 | switch ( r ) | ||
1042 | { | ||
1043 | case Rotate90: | ||
1044 | dest.create(img.height(), img.width(), img.depth()); | ||
1045 | for ( y=0; y < img.height(); ++y ) | ||
1046 | { | ||
1047 | srcData = (unsigned int *)img.scanLine(y); | ||
1048 | for ( x=0; x < img.width(); ++x ) | ||
1049 | { | ||
1050 | destData = (unsigned int *)dest.scanLine(x); | ||
1051 | destData[img.height()-y-1] = srcData[x]; | ||
1052 | } | ||
1053 | } | ||
1054 | break; | ||
1055 | case Rotate180: | ||
1056 | dest.create(img.width(), img.height(), img.depth()); | ||
1057 | for ( y=0; y < img.height(); ++y ) | ||
1058 | { | ||
1059 | srcData = (unsigned int *)img.scanLine(y); | ||
1060 | destData = (unsigned int *)dest.scanLine(img.height()-y-1); | ||
1061 | for ( x=0; x < img.width(); ++x ) | ||
1062 | destData[img.width()-x-1] = srcData[x]; | ||
1063 | } | ||
1064 | break; | ||
1065 | case Rotate270: | ||
1066 | dest.create(img.height(), img.width(), img.depth()); | ||
1067 | for ( y=0; y < img.height(); ++y ) | ||
1068 | { | ||
1069 | srcData = (unsigned int *)img.scanLine(y); | ||
1070 | for ( x=0; x < img.width(); ++x ) | ||
1071 | { | ||
1072 | destData = (unsigned int *)dest.scanLine(img.width()-x-1); | ||
1073 | destData[y] = srcData[x]; | ||
1074 | } | ||
1075 | } | ||
1076 | break; | ||
1077 | default: | ||
1078 | dest = img; | ||
1079 | break; | ||
1080 | } | ||
1081 | } | ||
1082 | else | ||
1083 | { | ||
1084 | unsigned char *srcData, *destData; | ||
1085 | unsigned int *srcTable, *destTable; | ||
1086 | switch ( r ) | ||
1087 | { | ||
1088 | case Rotate90: | ||
1089 | dest.create(img.height(), img.width(), img.depth()); | ||
1090 | dest.setNumColors(img.numColors()); | ||
1091 | srcTable = (unsigned int *)img.colorTable(); | ||
1092 | destTable = (unsigned int *)dest.colorTable(); | ||
1093 | for ( x=0; x < img.numColors(); ++x ) | ||
1094 | destTable[x] = srcTable[x]; | ||
1095 | for ( y=0; y < img.height(); ++y ) | ||
1096 | { | ||
1097 | srcData = (unsigned char *)img.scanLine(y); | ||
1098 | for ( x=0; x < img.width(); ++x ) | ||
1099 | { | ||
1100 | destData = (unsigned char *)dest.scanLine(x); | ||
1101 | destData[img.height()-y-1] = srcData[x]; | ||
1102 | } | ||
1103 | } | ||
1104 | break; | ||
1105 | case Rotate180: | ||
1106 | dest.create(img.width(), img.height(), img.depth()); | ||
1107 | dest.setNumColors(img.numColors()); | ||
1108 | srcTable = (unsigned int *)img.colorTable(); | ||
1109 | destTable = (unsigned int *)dest.colorTable(); | ||
1110 | for ( x=0; x < img.numColors(); ++x ) | ||
1111 | destTable[x] = srcTable[x]; | ||
1112 | for ( y=0; y < img.height(); ++y ) | ||
1113 | { | ||
1114 | srcData = (unsigned char *)img.scanLine(y); | ||
1115 | destData = (unsigned char *)dest.scanLine(img.height()-y-1); | ||
1116 | for ( x=0; x < img.width(); ++x ) | ||
1117 | destData[img.width()-x-1] = srcData[x]; | ||
1118 | } | ||
1119 | break; | ||
1120 | case Rotate270: | ||
1121 | dest.create(img.height(), img.width(), img.depth()); | ||
1122 | dest.setNumColors(img.numColors()); | ||
1123 | srcTable = (unsigned int *)img.colorTable(); | ||
1124 | destTable = (unsigned int *)dest.colorTable(); | ||
1125 | for ( x=0; x < img.numColors(); ++x ) | ||
1126 | destTable[x] = srcTable[x]; | ||
1127 | for ( y=0; y < img.height(); ++y ) | ||
1128 | { | ||
1129 | srcData = (unsigned char *)img.scanLine(y); | ||
1130 | for ( x=0; x < img.width(); ++x ) | ||
1131 | { | ||
1132 | destData = (unsigned char *)dest.scanLine(img.width()-x-1); | ||
1133 | destData[y] = srcData[x]; | ||
1134 | } | ||
1135 | } | ||
1136 | break; | ||
1137 | default: | ||
1138 | dest = img; | ||
1139 | break; | ||
1140 | } | ||
1141 | |||
1142 | } | ||
1143 | return (dest); | ||
1144 | } | ||
1145 | |||
1146 | void ImageViewer::slideShow( bool on ) | ||
1147 | { | ||
1148 | if (on) { | ||
1149 | if (!imageList.isEmpty()) { | ||
1150 | slideTimer->start(slideDelay * 1000, FALSE); | ||
1151 | filename = ""; // force restart | ||
1152 | slideReverse ? prevImage() : nextImage(); | ||
1153 | } | ||
1154 | } else { | ||
1155 | slideTimer->stop(); | ||
1156 | slideAction->setOn( false); | ||
1157 | } | ||
1158 | } | ||
1159 | |||
1160 | void ImageViewer::slideUpdate() | ||
1161 | { | ||
1162 | bool final_image = slideReverse ? prevImage() : nextImage(); | ||
1163 | |||
1164 | if (final_image && !slideRepeat) { | ||
1165 | slideTimer->stop(); | ||
1166 | slideAction->setOn(FALSE); | ||
1167 | } | ||
1168 | } | ||
1169 | |||
1170 | // | ||
1171 | // Display the image after the current one in the image list. | ||
1172 | // Return TRUE if the next call to nextImage() will wrap around to the | ||
1173 | // first image in the list (ie. we're now viewing the last image in the list). | ||
1174 | // | ||
1175 | bool ImageViewer::nextImage(void) | ||
1176 | { | ||
1177 | int idx = 0; | ||
1178 | |||
1179 | if (imageList.count() > 0) { | ||
1180 | idx = imageIndex(); | ||
1181 | if (idx != -1) { | ||
1182 | if (idx == int(imageList.count() - 1)) { | ||
1183 | idx = 0; | ||
1184 | } else { | ||
1185 | idx++; | ||
1186 | } | ||
1187 | } else { | ||
1188 | idx = 0; | ||
1189 | } | ||
1190 | openFile(imageList[idx]); | ||
1191 | } | ||
1192 | |||
1193 | return idx == int(imageList.count() - 1) ? TRUE : FALSE; | ||
1194 | } | ||
1195 | |||
1196 | // | ||
1197 | // Display the image preceeding the current one in the image list. | ||
1198 | // Return TRUE if the next call to prevImage() will wrap around to the last | ||
1199 | // image in the list (ie. we're now viewing the first image in the list). | ||
1200 | // | ||
1201 | bool ImageViewer::prevImage(void) | ||
1202 | { | ||
1203 | int idx = -1; | ||
1204 | |||
1205 | if (imageList.count() > 0) { | ||
1206 | idx = imageIndex(); | ||
1207 | if (idx != -1) { | ||
1208 | if (idx == 0) { | ||
1209 | idx = imageList.count() - 1; | ||
1210 | } else { | ||
1211 | idx--; | ||
1212 | } | ||
1213 | } else { | ||
1214 | idx = imageList.count() - 1; | ||
1215 | } | ||
1216 | openFile(imageList[idx]); | ||
1217 | } | ||
1218 | |||
1219 | return idx == 0 ? TRUE : FALSE; | ||
1220 | } | ||
1221 | |||
1222 | // | ||
1223 | // Return the index into the imageList of the currently viewed | ||
1224 | // image (ie. ImageViewer::filename in ImageViewer::imageList). | ||
1225 | // | ||
1226 | int ImageViewer::imageIndex(void) | ||
1227 | { | ||
1228 | QValueListConstIterator<DocLnk> i; | ||
1229 | int index; | ||
1230 | |||
1231 | if (imageList.count() == 0) { | ||
1232 | return -1; | ||
1233 | } | ||
1234 | |||
1235 | for (index = 0, i = imageList.begin(); i != imageList.end(); ++i, index++) { | ||
1236 | if ((*i).file() == filename) { | ||
1237 | return index; | ||
1238 | } | ||
1239 | } | ||
1240 | |||
1241 | return -1; | ||
1242 | } | ||