📄 presentationwidget.cpp.svn-base
字号:
/*************************************************************************** * Copyright (C) 2004 by Enrico Ros <eros.kde@email.it> * * * * 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. * ***************************************************************************/// qt/kde includes#include <qevent.h>#include <qfontmetrics.h>#include <kicon.h>#include <qtimer.h>#include <qimage.h>#include <qlineedit.h>#include <qpainter.h>#include <qtooltip.h>#include <qvalidator.h>#include <qapplication.h>#include <qdesktopwidget.h>#include <kcursor.h>#include <krandom.h>#include <qtoolbar.h>#include <kaction.h>#include <kactioncollection.h>#include <klocale.h>#include <kiconloader.h>#include <kmessagebox.h>#include <kshortcut.h>// system includes#include <stdlib.h>#include <math.h>// local includes#include "presentationwidget.h"#include "pagepainter.h"#include "core/generator.h"#include "core/page.h"#include "core/link.h"#include "settings.h"// comment this to disable the top-right progress indicator#define ENABLE_PROGRESS_OVERLAY// a frame contains a pointer to the page object, its geometry and the// transition effect to the next framestruct PresentationFrame{ const KPDFPage * page; QRect geometry;};PresentationWidget::PresentationWidget( QWidget * parent, KPDFDocument * doc ) : QDialog( parent, Qt::FramelessWindowHint ), m_pressedLink( 0 ), m_handCursor( false ), m_document( doc ), m_frameIndex( -1 ), m_topBar( 0 ), m_pagesEdit( 0 ){ setModal( true ); setAttribute( Qt::WA_DeleteOnClose ); setAttribute( Qt::WA_OpaquePaintEvent ); setObjectName( "presentationWidget" ); m_width = -1; // show widget and take control showFullScreen(); // misc stuff setMouseTracking( true ); m_transitionTimer = new QTimer( this ); m_transitionTimer->setSingleShot( true ); connect( m_transitionTimer, SIGNAL( timeout() ), this, SLOT( slotTransitionStep() ) ); m_overlayHideTimer = new QTimer( this ); m_overlayHideTimer->setSingleShot( true ); connect( m_overlayHideTimer, SIGNAL( timeout() ), this, SLOT( slotHideOverlay() ) ); // handle cursor appearance as specified in configuration if ( KpdfSettings::slidesCursor() == KpdfSettings::EnumSlidesCursor::HiddenDelay ) { KCursor::setAutoHideCursor( this, true ); KCursor::setHideCursorDelay( 3000 ); } else if ( KpdfSettings::slidesCursor() == KpdfSettings::EnumSlidesCursor::Hidden ) { setCursor( KCursor::blankCursor() ); } QTimer::singleShot( 0, this, SLOT( slotDelayedEvents() ) );}PresentationWidget::~PresentationWidget(){ // remove this widget from document observer m_document->removeObserver( this ); // set a new viewport in document if page number differs if ( m_frameIndex != -1 && m_frameIndex != m_document->viewport().pageNumber ) m_document->setViewportPage( m_frameIndex/*, PRESENTATION_ID*/ ); // delete frames QVector< PresentationFrame * >::iterator fIt = m_frames.begin(), fEnd = m_frames.end(); for ( ; fIt != fEnd; ++fIt ) delete *fIt;}void PresentationWidget::notifySetup( const QVector< KPDFPage * > & pageSet, bool /*documentChanged*/ ){ // delete previous frames (if any (shouldn't be)) QVector< PresentationFrame * >::iterator fIt = m_frames.begin(), fEnd = m_frames.end(); for ( ; fIt != fEnd; ++fIt ) delete *fIt; if ( !m_frames.isEmpty() ) kWarning() << "Frames setup changed while a Presentation is in progress." << endl; m_frames.clear(); // create the new frames QVector< KPDFPage * >::const_iterator setIt = pageSet.begin(), setEnd = pageSet.end(); float screenRatio = (float)m_height / (float)m_width; for ( ; setIt != setEnd; ++setIt ) { PresentationFrame * frame = new PresentationFrame(); frame->page = *setIt; // calculate frame geometry keeping constant aspect ratio float pageRatio = frame->page->ratio(); int pageWidth = m_width, pageHeight = m_height; if ( pageRatio > screenRatio ) pageWidth = (int)( (float)pageHeight / pageRatio ); else pageHeight = (int)( (float)pageWidth * pageRatio ); frame->geometry.setRect( (m_width - pageWidth) / 2, (m_height - pageHeight) / 2, pageWidth, pageHeight ); // add the frame to the vector m_frames.push_back( frame ); } // get metadata from the document m_metaStrings.clear(); const DocumentInfo * info = m_document->documentInfo(); if ( info ) { if ( !info->get( "title" ).isNull() ) m_metaStrings += i18n( "Title: %1", info->get( "title" ) ); if ( !info->get( "author" ).isNull() ) m_metaStrings += i18n( "Author: %1", info->get( "author" ) ); } m_metaStrings += i18n( "Pages: %1", m_document->pages() ); m_metaStrings += i18n( "Click to begin" );}void PresentationWidget::notifyViewportChanged( bool /*smoothMove*/ ){ // discard notifications if displaying the summary if ( m_frameIndex == -1 && KpdfSettings::slidesShowSummary() ) return; // display the current page changePage( m_document->viewport().pageNumber ); // auto advance to the next page if set if ( KpdfSettings::slidesAdvance() ) QTimer::singleShot( KpdfSettings::slidesAdvanceTime() * 1000, this, SLOT( slotNextPage() ) );}void PresentationWidget::notifyPageChanged( int pageNumber, int changedFlags ){ // check if it's the last requested pixmap. if so update the widget. if ( (changedFlags & DocumentObserver::Pixmap) && pageNumber == m_frameIndex ) generatePage();}bool PresentationWidget::canUnloadPixmap( int pageNumber ){ // can unload all pixmaps except for the currently visible one return pageNumber != m_frameIndex;}void PresentationWidget::setupActions( KActionCollection * collection ){ m_ac = collection;}// <widget events>bool PresentationWidget::event( QEvent * e ){ if ( e->type() == QEvent::ToolTip ) { QHelpEvent * he = (QHelpEvent*)e; const KPDFLink * link = getLink( he->x(), he->y(), 0 ); if ( link ) { QString tip = link->linkTip(); if ( !tip.isEmpty() ) QToolTip::showText( he->globalPos(), tip, this ); } e->accept(); return true; } else // do not stop the event return QDialog::event( e );}void PresentationWidget::keyPressEvent( QKeyEvent * e ){ if (m_width == -1) return; if ( e->key() == m_ac->action( "previous_page" )->shortcut().keyQt() || e->key() == Qt::Key_Left || e->key() == Qt::Key_Backspace || e->key() == Qt::Key_PageUp ) slotPrevPage(); else if ( e->key() == m_ac->action( "next_page" )->shortcut().keyQt() || e->key() == Qt::Key_Right || e->key() == Qt::Key_Space || e->key() == Qt::Key_PageDown ) slotNextPage(); else if ( e->key() == m_ac->action( "first_page" )->shortcut().keyQt() || e->key() == Qt::Key_Home ) slotFirstPage(); else if ( e->key() == m_ac->action( "last_page" )->shortcut().keyQt() || e->key() == Qt::Key_End ) slotLastPage(); else if ( e->key() == Qt::Key_Escape ) { if ( !m_topBar->isHidden() ) m_topBar->hide(); else close(); }}void PresentationWidget::wheelEvent( QWheelEvent * e ){ // performance note: don't remove the clipping int div = e->delta() / 120; if ( div > 0 ) { if ( div > 3 ) div = 3; while ( div-- ) slotPrevPage(); } else if ( div < 0 ) { if ( div < -3 ) div = -3; while ( div++ ) slotNextPage(); }}void PresentationWidget::mousePressEvent( QMouseEvent * e ){ // pressing left button if ( e->button() == Qt::LeftButton ) { // if pressing on a link, skip other checks if ( ( m_pressedLink = getLink( e->x(), e->y() ) ) ) return; // handle clicking on top-right overlay if ( m_overlayGeometry.contains( e->pos() ) ) { overlayClick( e->pos() ); return; } // if no other actions, go to next page slotNextPage(); } // pressing right button else if ( e->button() == Qt::RightButton ) slotPrevPage();}void PresentationWidget::mouseReleaseEvent( QMouseEvent * e ){ // if releasing on the same link we pressed over, execute it if ( m_pressedLink && e->button() == Qt::LeftButton ) { const KPDFLink * link = getLink( e->x(), e->y() ); if ( link == m_pressedLink ) m_document->processLink( link ); m_pressedLink = 0; }}void PresentationWidget::mouseMoveEvent( QMouseEvent * e ){ // safety check if ( m_width == -1 ) return; // update cursor and tooltip if hovering a link if ( KpdfSettings::slidesCursor() != KpdfSettings::EnumSlidesCursor::Hidden ) testCursorOnLink( e->x(), e->y() ); if ( !m_topBar->isHidden() ) { // hide a shown bar when exiting the area if ( e->y() > ( m_topBar->height() + 1 ) ) { m_topBar->hide(); setFocus( Qt::OtherFocusReason ); } } else { // show the bar if reaching top 2 pixels if ( e->y() <= (geometry().top() + 1) ) m_topBar->show(); // handle "dragging the wheel" if clicking on its geometry else if ( ( QApplication::mouseButtons() & Qt::LeftButton ) && m_overlayGeometry.contains( e->pos() ) ) overlayClick( e->pos() ); }}void PresentationWidget::paintEvent( QPaintEvent * pe ){ if (m_width == -1) { QRect d = KGlobalSettings::desktopGeometry(this); m_width = d.width(); m_height = d.height(); // create top toolbar m_topBar = new QToolBar( this ); m_topBar->setObjectName( "presentationBar" ); m_topBar->setIconSize( QSize( 32, 32 ) ); m_topBar->addAction( KIcon("1leftarrow"), i18n("Previous Page"), this, SLOT( slotPrevPage() ) ); m_pagesEdit = new QLineEdit( m_topBar ); QSizePolicy sp = m_pagesEdit->sizePolicy(); sp.setHorizontalPolicy( QSizePolicy::Minimum ); m_pagesEdit->setSizePolicy( sp ); QFontMetrics fm( m_pagesEdit->font() ); m_pagesEdit->setMaximumWidth( fm.width( QString::number( m_document->pages() ) + "00" ) ); QIntValidator *validator = new QIntValidator( 1, m_document->pages(), m_pagesEdit );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -