📄 showimg.cpp
字号:
/************************************************************************ Copyright (C) 2000-2005 Trolltech AS. All rights reserved.**** This file is part of the Qtopia Environment.** ** This program is free software; you can redistribute it and/or modify it** under the terms of the GNU General Public License as published by the** Free Software Foundation; either version 2 of the License, or (at your** option) any later version.** ** A copy of the GNU GPL license version 2 is included in this package as ** LICENSE.GPL.**** This program is distributed in the hope that it will be useful, but** WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ** See the GNU General Public License for more details.**** In addition, as a special exception Trolltech gives permission to link** the code of this program with Qtopia applications copyrighted, developed** and distributed by Trolltech under the terms of the Qtopia Personal Use** License Agreement. You must comply with the GNU General Public License** in all respects for all of the code used other than the applications** licensed under the Qtopia Personal Use License Agreement. If you modify** this file, you may extend this exception to your version of the file,** but you are not obligated to do so. If you do not wish to do so, delete** this exception statement from your version.** ** 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 <qtopia/global.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>#ifdef QTOPIA_PHONE# include <qtopia/contextmenu.h># include <qtopia/contextbar.h>#endif//===========================================================================/* 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();}#ifdef QTOPIA_PHONEvoid ImagePane::keyPressEvent(QKeyEvent *e){ if( !Global::mousePreferred() ) { QWidget::keyPressEvent(e); if (!e->isAccepted()) { e->accept(); emit keypress(e->key()); } }}#endifvoid ImagePane::closeEvent(QCloseEvent *e){ e->ignore();}ImageWidget::ImageWidget(QWidget *parent) : QWidget( parent ), pixmap( 0 ){ QIconSet waitset = Resource::loadIconSet("wait"); wait = waitset.pixmap();}//===========================================================================/* 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); }// QTOPIA_PROFILE("drawn image");}/* Shows a busy indicator */void ImageWidget::showBusy(){ QPainter painter(this); painter.setBrush( white ); 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 ), edit(0){ setCaption( tr("Image Viewer") ); setIcon( Resource::loadPixmap( "ImageViewer" ) ); setBackgroundMode( PaletteButton ); needPmScaled0 = TRUE; needPmScaled90 = TRUE; rotated90 = FALSE; isFullScreen = FALSE; 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())); openAction = new QAction( tr( "Open" ), Resource::loadIconSet( "fileopen" ), QString::null, 0, this, 0 ); connect( openAction, SIGNAL( activated() ), this, SLOT( open() ) ); flipAction = new QAction( tr( "Rotate 180" ), Resource::loadIconSet( "repeat" ), QString::null, 0, this, 0 ); connect( flipAction, SIGNAL( activated() ), this, SLOT( rot180() ) ); rotateAction = new QAction( tr( "Rotate 90"), Resource::loadIconSet( "rotate90" ), QString::null, 0, this, 0); connect( rotateAction, SIGNAL( activated() ), this, SLOT( rot90() ) ); propAction = new QAction(tr("Properties..."), QIconSet(), QString::null, 0, this, 0); connect(propAction, SIGNAL( activated() ), this, SLOT(properties())); fullscreenAction = new QAction( tr( "Fullscreen" ), Resource::loadIconSet( "fullscreen" ), QString::null, 0, this, 0 ); connect( fullscreenAction, SIGNAL( activated() ), this, SLOT( fullScreen() ) ); 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->setEnabled( FALSE ); prevImageAction = new QAction(tr("Previous"), Resource::loadIconSet("back"), QString::null, 0, this, 0); connect(prevImageAction, SIGNAL(activated()), this, SLOT(prevImage())); nextImageAction = new QAction(tr("Next"), Resource::loadIconSet("forward"), QString::null, 0, this, 0); connect(nextImageAction, SIGNAL(activated()), this, SLOT(nextImage()));#ifndef QTOPIA_PHONE setToolBarsMovable( FALSE ); toolBar = new QPEToolBar( this ); toolBar->setHorizontalStretchable( TRUE ); menubar = new QPEMenuBar( toolBar ); edit = new QPopupMenu( menubar ); QPopupMenu *view = new QPopupMenu( menubar ); menubar->insertItem( tr("Image"), edit ); menubar->insertItem( tr("View"), view ); toolBar = new QPEToolBar( this ); 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->addTo( toolBar ); flipAction->addTo( edit ); rotateAction->addTo( toolBar ); rotateAction->addTo( edit ); edit->insertSeparator(); propAction->addTo(edit); fullscreenAction->addTo( toolBar ); fullscreenAction->addTo( view); slideAction->addTo( view); slideAction->addTo( toolBar ); prevImageAction->addTo(toolBar); prevImageAction->addTo(view); nextImageAction->addTo(toolBar); nextImageAction->addTo(view); view->insertSeparator(); view->insertItem(tr("Settings..."), this, SLOT(settings()), 0);#else contextMenu = new ContextMenu(this); fullscreenAction->addTo(contextMenu); slideAction->addTo(contextMenu); contextMenu->insertItem(tr("Settings..."), this, SLOT(settings()), 0); ContextBar::setLabel(this, Key_Select, ContextBar::NoLabel);#endif 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"); rot = RotationDirection(config.readNumEntry("Rotate")); 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(0, 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(); fileSelector->reread(); imageList = fileSelector->fileList(); setControls(); }}void ImageViewer::settings(){ SettingsDialog dlg( this, 0, TRUE ); dlg.setDelay( slideDelay ); dlg.setRepeat( slideRepeat ); dlg.setReverse( slideReverse ); dlg.setRotation(rot); dlg.setFastLoad(fastLoad); dlg.setSmallScale(smallScale); if ( QPEApplication::execDialog(&dlg) == QDialog::Accepted ) { slideDelay = dlg.delay(); slideRepeat = dlg.repeat(); slideReverse = dlg.reverse(); rot = dlg.rotation(); 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("Rotate", rot); 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();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -