📄 thumbnaillist.cpp.svn-base
字号:
/*************************************************************************** * Copyright (C) 2004-2006 by Albert Astals Cid <tsdgeos@terra.es> * * * * 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 <qlayout.h>#include <qtimer.h>#include <qpainter.h>#include <qscrollbar.h>#include <qsizepolicy.h>#include <klocale.h>#include <kurl.h>#include <kaction.h>#include <kiconloader.h>#include <kactioncollection.h>#include <kicon.h>// system includes#include <math.h>// local includes#include "thumbnaillist.h"#include "pagepainter.h"#include "core/area.h"#include "core/document.h"#include "core/generator.h"#include "core/page.h"#include "settings.h"// ThumbnailWidget represents a single thumbnail in the ThumbnailListclass ThumbnailWidget : public QWidget{ public: ThumbnailWidget( QWidget * parent, const KPDFPage * page, ThumbnailList * tl ); // set internal parameters to fit the page in the given width void resizeFitWidth( int width ); // set thumbnail's selected state void setSelected( bool selected ); // set the visible rect of the current page void setVisibleRect( const NormalizedRect & rect ); // query methods int heightHint() const { return m_pixmapHeight + m_labelHeight + m_margin; } int pixmapWidth() const { return m_pixmapWidth; } int pixmapHeight() const { return m_pixmapHeight; } int pageNumber() const { return m_page->number(); } const KPDFPage * page() const { return m_page; } QSize sizeHint() const; protected: void mouseReleaseEvent( QMouseEvent * e ); void contextMenuEvent( QContextMenuEvent * e ); void paintEvent(QPaintEvent *); private: // the margin around the widget static int const m_margin = 16; // used to access 'forwardClick( .. )' and 'getBookmarkOverlay()' ThumbnailList * m_tl; const KPDFPage * m_page; bool m_selected; int m_pixmapWidth, m_pixmapHeight; int m_labelHeight, m_labelNumber; NormalizedRect m_visibleRect;};/** ThumbnailList implementation **/ThumbnailList::ThumbnailList( QWidget *parent, KPDFDocument *document ) : QScrollArea( parent ), m_document( document ), m_selected( 0 ), m_delayTimer( 0 ), m_bookmarkOverlay( 0 ){ setObjectName( "okular::Thumbnails" ); // set scrollbars setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOn ); setAttribute( Qt::WA_StaticContents ); setAcceptDrops( true ); QPalette pal = palette(); // set contents background to the 'base' color QPalette viewportPal = viewport()->palette(); viewportPal.setColor( viewport()->backgroundRole(), pal.color( QPalette::Base ) ); viewport()->setPalette( viewportPal ); m_pagesWidget = new QWidget(); setWidget( m_pagesWidget ); // widget setup: can be focused by tab and mouse click (not wheel) m_pagesWidget->setFocusPolicy( Qt::StrongFocus ); m_pagesWidget->show(); QPalette widgetPal = m_pagesWidget->palette(); widgetPal.setColor( m_pagesWidget->backgroundRole(), pal.color( QPalette::Base ) ); m_pagesWidget->setPalette( widgetPal ); m_pagesLayout = new QVBoxLayout( m_pagesWidget ); m_pagesLayout->setMargin( 0 ); m_pagesLayout->setSpacing( 4 ); setFrameStyle( StyledPanel | Raised ); connect( verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(slotRequestVisiblePixmaps(int)) );}ThumbnailList::~ThumbnailList(){ m_document->removeObserver( this ); delete m_bookmarkOverlay;}//BEGIN DocumentObserver inherited methodsvoid ThumbnailList::notifySetup( const QVector< KPDFPage * > & pages, bool documentChanged ){ // if there was a widget selected, save its pagenumber to restore // its selection (if available in the new set of pages) int prevPage = -1; if ( !documentChanged && m_selected ) { prevPage = m_selected->page()->number(); } // delete all the Thumbnails QVector<ThumbnailWidget *>::iterator tIt = m_thumbnails.begin(), tEnd = m_thumbnails.end(); for ( ; tIt != tEnd; ++tIt ) delete *tIt; m_thumbnails.clear(); m_visibleThumbnails.clear(); m_selected = 0; if ( pages.count() < 1 ) { m_pagesWidget->resize( 0, 0 ); return; } // show pages containing hilighted text or bookmarked ones //RESTORE THIS int flags = KpdfSettings::filterBookmarks() ? KPDFPage::Bookmark : KPDFPage::Highlight; // if no page matches filter rule, then display all pages QVector< KPDFPage * >::const_iterator pIt = pages.begin(), pEnd = pages.end(); bool skipCheck = true; for ( ; pIt != pEnd ; ++pIt ) //if ( (*pIt)->attributes() & flags ) if ( (*pIt)->hasHighlights( SW_SEARCH_ID ) ) skipCheck = false; // generate Thumbnails for the given set of pages int width = viewport()->width(); int height = 0; for ( pIt = pages.begin(); pIt != pEnd ; ++pIt ) //if ( skipCheck || (*pIt)->attributes() & flags ) if ( skipCheck || (*pIt)->hasHighlights( SW_SEARCH_ID ) ) { ThumbnailWidget * t = new ThumbnailWidget( widget(), *pIt, this ); t->setFocusProxy( this ); // add to the scrollview m_pagesLayout->addWidget( t ); // add to the internal queue m_thumbnails.push_back( t ); // update total height (asking widget its own height) t->resizeFitWidth( width ); // restoring the previous selected page, if any if ( (*pIt)->number() == prevPage ) { m_selected = t; m_selected->setSelected( true ); } t->show(); height += t->height() + m_pagesLayout->spacing(); } // update scrollview's contents size (sets scrollbars limits) height -= m_pagesLayout->spacing(); m_pagesWidget->resize( width, height ); // request for thumbnail generation delayedRequestVisiblePixmaps( 200 );}void ThumbnailList::notifyViewportChanged( bool /*smoothMove*/ ){ // skip notifies for the current page (already selected) int newPage = m_document->viewport().pageNumber; if ( m_selected && m_selected->pageNumber() == newPage ) return; // deselect previous thumbnail if ( m_selected ) m_selected->setSelected( false ); m_selected = 0; // select the page with viewport and ensure it's centered in the view m_vectorIndex = 0; QVector<ThumbnailWidget *>::iterator tIt = m_thumbnails.begin(), tEnd = m_thumbnails.end(); for ( ; tIt != tEnd; ++tIt ) { if ( (*tIt)->pageNumber() == newPage ) { m_selected = *tIt; m_selected->setSelected( true ); if ( KpdfSettings::syncThumbnailsViewport() ) { int yOffset = qMax( viewport()->height() / 4, m_selected->height() / 2 ); ensureVisible( 0, m_selected->pos().y() + m_selected->height()/2, 0, yOffset ); } break; } m_vectorIndex++; }}void ThumbnailList::notifyPageChanged( int pageNumber, int /*changedFlags*/ ){ // only handle pixmap changed notifies (the only defined for now) //if ( !(changedFlags & DocumentObserver::Pixmap) ) // return; // iterate over visible items: if page(pageNumber) is one of them, repaint it QList<ThumbnailWidget *>::iterator vIt = m_visibleThumbnails.begin(), vEnd = m_visibleThumbnails.end(); for ( ; vIt != vEnd; ++vIt ) if ( (*vIt)->pageNumber() == pageNumber ) { (*vIt)->update(); break; }}void ThumbnailList::notifyContentsCleared( int changedFlags ){ // if pixmaps were cleared, re-ask them if ( changedFlags & DocumentObserver::Pixmap ) slotRequestVisiblePixmaps();}void ThumbnailList::notifyVisibleRectsChanged(){ bool found = false; const QVector<VisiblePageRect *> & visibleRects = m_document->visiblePageRects(); QVector<ThumbnailWidget *>::iterator tIt = m_thumbnails.begin(), tEnd = m_thumbnails.end(); QVector<VisiblePageRect *>::const_iterator vEnd = visibleRects.end(); for ( ; tIt != tEnd; ++tIt ) { found = false; QVector<VisiblePageRect *>::const_iterator vIt = visibleRects.begin(); for ( ; ( vIt != vEnd ) && !found; ++vIt ) { if ( (*tIt)->pageNumber() == (*vIt)->pageNumber ) { (*tIt)->setVisibleRect( (*vIt)->rect ); found = true; } } if ( !found ) { (*tIt)->setVisibleRect( NormalizedRect() ); } }}bool ThumbnailList::canUnloadPixmap( int pageNumber ){ // if the thubnail 'pageNumber' is one of the visible ones, forbid unloading QList<ThumbnailWidget *>::iterator vIt = m_visibleThumbnails.begin(), vEnd = m_visibleThumbnails.end(); for ( ; vIt != vEnd; ++vIt ) if ( (*vIt)->pageNumber() == pageNumber ) return false; // if hidden permit unloading return true;}//END DocumentObserver inherited methods void ThumbnailList::updateWidgets(){ // find all widgets that intersects the viewport and update them QRect viewportRect = viewport()->rect().translated( viewport()->pos() ); QList<ThumbnailWidget *>::iterator vIt = m_visibleThumbnails.begin(), vEnd = m_visibleThumbnails.end(); for ( ; vIt != vEnd; ++vIt ) { ThumbnailWidget * t = *vIt; QRect thumbRect = t->rect().translated( m_pagesWidget->mapToParent( t->pos() ) ); // update only the exposed area of the widget (saves pixels..) QRect relativeRect = thumbRect.intersect( viewport()->rect() ); if ( !relativeRect.isValid() ) continue; t->update( relativeRect ); }}void ThumbnailList::forwardClick( const KPDFPage * p, const QPoint & t, Qt::MouseButton button ){ if ( button == Qt::RightButton ) emit rightClick( p, t ); else if ( button == Qt::LeftButton ) { if ( m_document->viewport().pageNumber != p->number() ) m_document->setViewportPage( p->number() ); }}const QPixmap * ThumbnailList::getBookmarkOverlay() const{ return m_bookmarkOverlay;}void ThumbnailList::slotFilterBookmarks( bool filterOn ){ // save state KpdfSettings::setFilterBookmarks( filterOn ); KpdfSettings::writeConfig(); // ask for the 'notifySetup' with a little trick (on reinsertion the // document sends the list again) m_document->removeObserver( this ); m_document->addObserver( this );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -