📄 showimg.cpp
字号:
/************************************************************************ Copyright (C) 2000-2002 Trolltech AS. All rights reserved.**** This file is part of the Qtopia Environment.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************///// Full-screen and rotation options contributed by Robert Wittams <robert@wittams.com>//#include "showimg.h"#include "settingsdialog.h"#include <qtopia/qpeapplication.h>#include <qtopia/resource.h>#include <qtopia/storage.h>#include <qtopia/fileselector.h>#include <qtopia/applnk.h>#include <qtopia/qpemenubar.h>#include <qtopia/qpetoolbar.h>#include <qtopia/config.h>#include <qwidgetstack.h>#include <qaction.h>#include <qfiledialog.h>#include <qmessagebox.h>#include <qpopupmenu.h>#include <qlabel.h>#include <qpainter.h>#include <qapplication.h>#include <qtimer.h>#include <qcopchannel_qws.h>#include <qtopia/docproperties.h>//===========================================================================/* Contains the scaled image area and the status label*/ImagePane::ImagePane( QWidget *parent ) : QWidget( parent ), vb(0){ image = new ImageWidget( this ); connect( image, SIGNAL( clicked() ), this, SIGNAL( clicked() ) ); status = new QLabel( this ); status->setFixedHeight( fontMetrics().height() + 4 ); showStatus(); imageWidth = imageHeight = 0;}void ImagePane::setPixmap( const QPixmap &pm ){ image->setPixmap( pm ); image->repaint( false ); imageWidth = pm.width(); imageHeight = pm.height();}void ImagePane::showBusy(){ image->showBusy();}void ImagePane::showStatus(){ delete vb; vb = new QVBoxLayout( this ); vb->addWidget( image ); status->show(); vb->addWidget( status );}void ImagePane::hideStatus(){ delete vb; vb = new QVBoxLayout( this ); vb->addWidget( image ); status->hide();}void ImagePane::keyPressEvent(QKeyEvent *e){ emit keypress(e->key());}void ImagePane::closeEvent(QCloseEvent *e){ e->ignore();}//===========================================================================/* Draws the portion of the scaled pixmap that needs to be updated*/void ImageWidget::paintEvent( QPaintEvent *e ){ QPainter painter(this); painter.setClipRect(e->rect()); painter.setBrush( black ); painter.drawRect( 0, 0, width(), height() ); if ( pixmap.size() != QSize( 0, 0 ) ) { // is an image loaded? painter.drawPixmap((width() - pixmap.width()) / 2, (height() - pixmap.height()) / 2, pixmap); }}/* Shows a busy indicator */void ImageWidget::showBusy(){ QPainter painter(this); painter.setBrush( white ); QPixmap wait = Resource::loadPixmap( "wait" ); int pw = wait.width(); int ph = wait.height(); int w = pw * 3/2; int h = ph * 3/2; painter.drawEllipse( 0, 0, w, h ); painter.drawPixmap( (w-pw)/2+1, (h-ph)/2+1, wait ); }void ImageWidget::mouseReleaseEvent(QMouseEvent *){ emit clicked();}//===========================================================================/* The main window with toolbars and fileselector. The image pane is shown inside it.*/ImageViewer::ImageViewer( QWidget *parent, const char *name, int wFlags ) : QMainWindow( parent, name, wFlags | Qt::WResizeNoErase ), filename( 0 ), doc(NULL), bFromDocView( FALSE ){ setCaption( tr("Image Viewer") ); setIcon( Resource::loadPixmap( "ImageViewer" ) ); setBackgroundMode( PaletteButton ); needPmScaled0 = TRUE; needPmScaled90 = TRUE; rotated90 = FALSE; isFullScreen = FALSE; setToolBarsMovable( FALSE ); toolBar = new QPEToolBar( this ); toolBar->setHorizontalStretchable( TRUE ); menubar = new QPEMenuBar( toolBar ); stack = new QWidgetStack( this ); stack->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) ); setCentralWidget( stack ); imagePanel = new ImagePane( stack ); connect(imagePanel, SIGNAL(clicked()), this, SLOT(toggleFullscreen())); connect(imagePanel, SIGNAL(keypress(int)), this, SLOT(handleKeypress(int))); connect(this, SIGNAL(keypress(int)), this, SLOT(handleKeypress(int))); fileSelector = new FileSelector("image/*", stack, "fs", FALSE, FALSE); connect( fileSelector, SIGNAL( closeMe() ), this, SLOT( closeFileSelector() ) ); connect( fileSelector, SIGNAL( fileSelected( const DocLnk &) ), this, SLOT( openFile( const DocLnk & ) ) ); connect(fileSelector, SIGNAL(categoryChanged()), this, SLOT(docsChanged())); connect(fileSelector, SIGNAL(typeChanged()), this, SLOT(docsChanged())); edit = new QPopupMenu( menubar ); QPopupMenu *view = new QPopupMenu( menubar ); menubar->insertItem( tr("Image"), edit ); menubar->insertItem( tr("View"), view ); toolBar = new QPEToolBar( this ); openAction = new QAction( tr( "Open" ), Resource::loadIconSet( "fileopen" ), QString::null, 0, this, 0 ); connect( openAction, SIGNAL( activated() ), this, SLOT( open() ) ); openAction->addTo( toolBar ); openAction->addTo( edit ); edit->insertSeparator(); hflip_id = edit->insertItem(tr("Horizontal flip"), this, SLOT(hFlip()), 0); vflip_id = edit->insertItem(tr("Vertical flip"), this, SLOT(vFlip()), 0); flipAction = new QAction( tr( "Rotate 180" ), Resource::loadIconSet( "repeat" ), QString::null, 0, this, 0 ); connect( flipAction, SIGNAL( activated() ), this, SLOT( rot180() ) ); flipAction->addTo( toolBar ); flipAction->addTo( edit ); rotateAction = new QAction( tr( "Rotate 90"), Resource::loadIconSet( "rotate90" ), QString::null, 0, this, 0); connect( rotateAction, SIGNAL( activated() ), this, SLOT( rot90() ) ); rotateAction->addTo( toolBar ); rotateAction->addTo( edit ); edit->insertSeparator(); propAction = new QAction(tr("Properties..."), QIconSet(), QString::null, 0, this, 0); connect(propAction, SIGNAL( activated() ), this, SLOT(properties())); propAction->addTo(edit); //edit->insertItem(tr("Properties..."), this, SLOT(properties()), 0); fullscreenAction = new QAction( tr( "Fullscreen" ), Resource::loadIconSet( "fullscreen" ), QString::null, 0, this, 0 ); connect( fullscreenAction, SIGNAL( activated() ), this, SLOT( fullScreen() ) ); fullscreenAction->addTo( toolBar ); fullscreenAction->addTo( view); slideAction = new QAction( tr( "Slide show" ), Resource::loadIconSet( "slideshow" ), QString::null, 0, this, 0 ); slideAction->setToggleAction( TRUE ); connect( slideAction, SIGNAL( toggled(bool) ), this, SLOT( slideShow(bool) ) ); slideAction->addTo( view); slideAction->addTo( toolBar ); slideAction->setEnabled( FALSE ); prevImageAction = new QAction(tr("Previous"), Resource::loadIconSet("back"), QString::null, 0, this, 0); connect(prevImageAction, SIGNAL(activated()), this, SLOT(prevImage())); prevImageAction->addTo(toolBar); prevImageAction->addTo(view); nextImageAction = new QAction(tr("Next"), Resource::loadIconSet("forward"), QString::null, 0, this, 0); connect(nextImageAction, SIGNAL(activated()), this, SLOT(nextImage())); nextImageAction->addTo(toolBar); nextImageAction->addTo(view); view->insertSeparator(); view->insertItem(tr("Settings..."), this, SLOT(settings()), 0); stack->raiseWidget( fileSelector ); openAction->setEnabled( FALSE ); setMouseTracking( TRUE ); slideTimer = new QTimer( this ); connect( slideTimer, SIGNAL(timeout()), this, SLOT(slideUpdate()) ); Config config( "ImageViewer" ); config.setGroup( "SlideShow" ); slideDelay = config.readNumEntry( "Delay", 5 ); slideRepeat = config.readBoolEntry( "Repeat", FALSE ); slideReverse = config.readBoolEntry("Reverse", FALSE); config.setGroup("Default"); rotateOnLoad = config.readBoolEntry("Rotate", FALSE); rotateClockwise = config.readBoolEntry("Clockwise", TRUE); fastLoad = config.readBoolEntry("FastLoad", TRUE); smallScale = config.readBoolEntry("SmallScale", FALSE); storage = new StorageInfo( this ); connect(storage, SIGNAL(disksChanged()), this, SLOT(updateDocs())); connect(qApp, SIGNAL(linkChanged(const QString&)), this, SLOT(updateDocs())); setControls(); updateDocs();}void ImageViewer::updateDocs(){ QTimer::singleShot(1000, this, SLOT(docsChanged()));}ImageViewer::~ImageViewer(){ if (doc != NULL) { delete doc; } if ( isFullScreen) delete imagePanel; // when fullScreen, it is reparented off the QWidgetStack}//// Popup image properties dialog.//voidImageViewer::properties(void){ if (stack->visibleWidget() == fileSelector) { if (doc == NULL) { doc = new DocLnk(); } *doc = fileSelector->selectedDocument(); } if (doc) { // pause slideshow if on bool on = slideTimer->isActive(); if (on) slideTimer->stop(); DocPropertiesDialog *dp = new DocPropertiesDialog(doc, this); QPEApplication::execDialog( dp ); delete dp; // if link is changed in the properties dialog, // we get a linkChanged message to handle if (on) slideTimer->start(slideDelay * 1000, FALSE); }}void ImageViewer::docsChanged(void){ // Avoid causing the fileSelector to scan until needed. It's okay if // we have already caused it to scan in which case imageList is not // empty, or we need it to scan because we are viewing the file selector. if ( fileSelector->isVisible() || !imageList.isEmpty() ) { imageList.clear(); imageList = fileSelector->fileList(); setControls(); }}void ImageViewer::settings(){ SettingsDialog dlg( this, 0, TRUE ); dlg.setDelay( slideDelay ); dlg.setRepeat( slideRepeat ); dlg.setReverse( slideReverse ); dlg.setRotate(rotateOnLoad); dlg.setClockwise(rotateClockwise); dlg.setFastLoad(fastLoad); dlg.setSmallScale(smallScale); if ( QPEApplication::execDialog(&dlg) == QDialog::Accepted ) { slideDelay = dlg.delay(); slideRepeat = dlg.repeat(); slideReverse = dlg.reverse(); rotateOnLoad = dlg.rotate(); rotateClockwise = dlg.clockwise(); fastLoad = dlg.fastLoad(); smallScale = dlg.smallScale(); Config config( "ImageViewer" ); config.setGroup( "SlideShow" ); config.writeEntry( "Delay", slideDelay ); config.writeEntry( "Repeat", slideRepeat ); config.writeEntry("Reverse", slideReverse); config.setGroup("Default"); config.writeEntry("Clockwise", rotateClockwise); config.writeEntry("Rotate", rotateOnLoad); config.writeEntry("FastLoad", fastLoad); config.writeEntry("SmallScale", smallScale); } // // Reload current image in case viewing options have changed. // if (stack->visibleWidget() != fileSelector) { loadFilename(filename); }}void ImageViewer::setDocument(const QString& fileref){ bFromDocView = TRUE; DocLnk link( fileref ); delete doc; doc = new DocLnk(fileref); if ( link.isValid() ) openFile( link.name(), link.file() ); else openFile( fileref, fileref );}void ImageViewer::show(){ QMainWindow::show(); normalView();}void ImageViewer::openFile( const DocLnk &file ){ delete doc; doc = new DocLnk(file); openFile( file.name(), file.file() );}void ImageViewer::openFile( const QString &name, const QString &file ){ if (stack->visibleWidget() == fileSelector) { imagePanel->setPixmap(QPixmap()); } closeFileSelector(); updateCaption( name ); loadFilename( file ); setControls(); if (slideTimer->isActive()) { slideTimer->start(slideDelay * 1000, FALSE); }}void ImageViewer::open(){ slideAction->setOn( FALSE ); stack->raiseWidget(fileSelector); fileSelector->setFocus(); openAction->setEnabled( FALSE ); updateCaption(); updateDocs();}void ImageViewer::closeFileSelector(){ stack->raiseWidget(imagePanel); openAction->setEnabled( TRUE );}void ImageViewer::updateCaption( QString name ){ if ( name.isEmpty() || stack->visibleWidget() == fileSelector ) { setCaption( tr("Image Viewer") ); } else { int sep = name.findRev( '/' ); if ( sep >= 0 ) name = name.mid( sep+1 ); setCaption( name + tr(" - Image Viewer") ); }}void ImageViewer::loadFilename( const QString &file ) { if ( file ) { filename = file; if ( !slideTimer->isActive() ) imagePanel->showBusy(); imagePanel->statusLabel()->setText( tr("Loading image...") ); qApp->processEvents(); QString param; QImageIO iio; iio.setFileName(filename); iio.setParameters("GetHeaderInformation");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -